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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt118
-rw-r--r--SConstruct222
-rwxr-xr-xbuild_files/build_environment/install_deps.sh878
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py5
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py8
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py8
-rw-r--r--build_files/buildbot/config/user-config-glibc27-i686.py149
-rw-r--r--build_files/buildbot/config/user-config-glibc27-x86_64.py149
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py4
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py4
-rw-r--r--build_files/buildbot/config/user-config-player-glibc27-i686.py114
-rw-r--r--build_files/buildbot/config/user-config-player-glibc27-x86_64.py114
-rw-r--r--build_files/buildbot/master.cfg16
-rw-r--r--build_files/buildbot/slave_compile.py53
-rw-r--r--build_files/buildbot/slave_pack.py12
-rw-r--r--build_files/buildbot/slave_rsync.py2
-rw-r--r--build_files/cmake/Modules/FindOpenCOLLADA.cmake1
-rwxr-xr-xbuild_files/cmake/cmake_consistency_check.py4
-rw-r--r--build_files/cmake/cmake_consistency_check_config.py21
-rwxr-xr-xbuild_files/cmake/cmake_netbeans_project.py4
-rwxr-xr-xbuild_files/cmake/cmake_qtcreator_project.py3
-rw-r--r--build_files/cmake/cmake_static_check_clang_array.py2
-rw-r--r--build_files/cmake/cmake_static_check_cppcheck.py2
-rw-r--r--build_files/cmake/cmake_static_check_smatch.py3
-rw-r--r--build_files/cmake/cmake_static_check_sparse.py2
-rw-r--r--build_files/cmake/cmake_static_check_splint.py2
-rw-r--r--build_files/cmake/config/blender_headless.cmake22
-rw-r--r--build_files/cmake/config/blender_lite.cmake86
-rw-r--r--build_files/cmake/config/bpy_module.cmake32
-rw-r--r--build_files/cmake/macros.cmake13
-rwxr-xr-xbuild_files/cmake/project_info.py13
-rw-r--r--build_files/cmake/project_source_info.py8
-rw-r--r--build_files/package_spec/rpm/blender.spec.in1
-rw-r--r--build_files/scons/config/Modules/FindPython.py10
-rw-r--r--build_files/scons/config/darwin-config.py6
-rw-r--r--build_files/scons/config/linux-config.py71
-rw-r--r--build_files/scons/config/win32-mingw-config.py2
-rw-r--r--build_files/scons/config/win32-vc-config.py4
-rw-r--r--build_files/scons/config/win64-mingw-config.py2
-rw-r--r--build_files/scons/config/win64-vc-config.py4
-rw-r--r--build_files/scons/tools/Blender.py11
-rw-r--r--build_files/scons/tools/btools.py22
-rw-r--r--doc/license/bf-members.txt100
-rw-r--r--doc/manpage/blender.124
-rw-r--r--doc/python_api/examples/bpy.props.5.py89
-rw-r--r--doc/python_api/examples/bpy.types.AddonPreferences.1.py72
-rw-r--r--doc/python_api/examples/bpy.types.UIList.py90
-rw-r--r--doc/python_api/rst/bge.events.rst4
-rw-r--r--doc/python_api/rst/bge.logic.rst14
-rw-r--r--doc/python_api/rst/bge.types.rst5261
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_ActionActuator.rst78
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_ArmatureActuator.rst61
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_ArmatureBone.rst105
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_ArmatureChannel.rst278
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_ArmatureConstraint.rst129
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_ArmatureObject.rst34
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_Shader.rst220
-rw-r--r--doc/python_api/rst/bge_types/bge.types.BL_ShapeActionActuator.rst72
-rw-r--r--doc/python_api/rst/bge_types/bge.types.CListValue.rst72
-rw-r--r--doc/python_api/rst/bge_types/bge.types.CPropValue.rst11
-rw-r--r--doc/python_api/rst/bge_types/bge.types.CValue.rst17
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_ArmatureSensor.rst36
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst77
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_Camera.rst284
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_CameraActuator.rst47
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst45
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_ConstraintActuator.rst78
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_ConstraintWrapper.rst18
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_FontObject.rst12
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_GameActuator.rst23
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst839
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_IpoActuator.rst65
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_LibLoadStatus.rst45
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst90
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_MeshProxy.rst134
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst66
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_NavMeshObject.rst47
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_NearSensor.rst23
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageActuator.rst35
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageSensor.rst38
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_ObjectActuator.rst129
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_ParentActuator.rst38
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_PolyProxy.rst139
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_PolygonMaterial.rst250
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_RadarSensor.rst44
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_RaySensor.rst72
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_SCA_AddObjectActuator.rst55
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_SCA_DynamicActuator.rst29
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_SCA_EndObjectActuator.rst13
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_SCA_ReplaceMeshActuator.rst89
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_Scene.rst172
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_SceneActuator.rst49
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_SoundActuator.rst115
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_StateActuator.rst29
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_SteeringActuator.rst71
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_TouchSensor.rst41
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst39
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst161
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst209
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_VisibilityActuator.rst29
-rw-r--r--doc/python_api/rst/bge_types/bge.types.PyObjectPlus.rst21
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_2DFilterActuator.rst49
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_ANDController.rst13
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_ActuatorSensor.rst19
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_AlwaysSensor.rst11
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_DelaySensor.rst39
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_IActuator.rst11
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_IController.rst55
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_ILogicBrick.rst29
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_IObject.rst11
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_ISensor.rst95
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_JoystickSensor.rst133
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_KeyboardSensor.rst64
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_MouseSensor.rst39
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_NANDController.rst13
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_NORController.rst13
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_ORController.rst13
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PropertyActuator.rst29
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PropertySensor.rst41
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst48
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PythonJoystick.rst75
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst37
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PythonMouse.rst35
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_RandomActuator.rst127
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_RandomSensor.rst23
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_XNORController.rst13
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_XORController.rst13
-rw-r--r--doc/python_api/rst/change_log.rst430
-rw-r--r--doc/python_api/rst/info_tutorial_addon.rst18
-rw-r--r--doc/python_api/rst_from_bmesh_opdefines.py50
-rw-r--r--doc/python_api/sphinx_doc_gen.py32
-rwxr-xr-xdoc/python_api/sphinx_doc_gen.sh8
-rw-r--r--doc/python_api/sphinx_doc_gen_monkeypatch.py47
-rw-r--r--extern/CMakeLists.txt5
-rw-r--r--extern/SConscript1
-rw-r--r--extern/bullet2/CMakeLists.txt5
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h98
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp8
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp35
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h27
-rw-r--r--extern/carve/lib/intersect_face_division.cpp4
-rw-r--r--extern/libmv/CMakeLists.txt12
-rw-r--r--extern/libmv/ChangeLog930
-rw-r--r--extern/libmv/SConscript23
-rwxr-xr-xextern/libmv/bundle.sh44
-rw-r--r--extern/libmv/files.txt5
-rw-r--r--extern/libmv/libmv-capi.cpp2
-rw-r--r--extern/libmv/libmv-capi.h1
-rw-r--r--extern/libmv/libmv/multiview/homography.cc15
-rw-r--r--extern/libmv/libmv/multiview/homography.h8
-rw-r--r--extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc16
-rw-r--r--extern/libmv/libmv/simple_pipeline/tracks.cc26
-rw-r--r--extern/libmv/libmv/simple_pipeline/tracks.h8
-rw-r--r--extern/libmv/third_party/ceres/CMakeLists.txt34
-rw-r--r--extern/libmv/third_party/ceres/ChangeLog730
-rwxr-xr-xextern/libmv/third_party/ceres/bundle.sh4
-rw-r--r--extern/libmv/third_party/ceres/files.txt33
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h71
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/ceres.h8
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h752
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/crs_matrix.h32
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h215
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/fpclassify.h2
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/gradient_checker.h222
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h158
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h6
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/macros.h12
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h29
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h199
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h15
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/variadic_evaluate.h182
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/iteration_callback.h43
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h374
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h346
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/ordered_groups.h176
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/problem.h156
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/rotation.h196
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h30
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/solver.h313
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/types.h110
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/array_utils.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc20
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h29
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h6
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc34
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h15
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/collections_port.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h9
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc236
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h88
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/corrector.cc17
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc10
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/cxsparse.h5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h11
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc13
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc29
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc16
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h1
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.cc18
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.h4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/evaluator.h17
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/execution_summary.h90
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/file.cc3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/graph.h25
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc64
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h12
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt_strategy.h5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search.cc211
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search.h212
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc145
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_direction.h (renamed from extern/libmv/third_party/ceres/internal/ceres/polynomial_solver.h)55
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc283
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.h77
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc72
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/linear_solver.h56
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.cc109
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.h99
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/map_util.h1
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/minimizer.cc67
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/minimizer.h24
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/mutex.h6
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/parameter_block.h61
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc (renamed from extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc)29
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h (renamed from extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h)16
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/polynomial.cc (renamed from extern/libmv/third_party/ceres/internal/ceres/polynomial_solver.cc)141
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/polynomial.h134
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc63
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/preconditioner.h148
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/problem.cc64
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc567
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/problem_impl.h62
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h28
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/residual_block.cc6
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/residual_block.h21
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc49
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h6
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc145
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h110
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver.cc331
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc1029
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver_impl.h95
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc36
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/split.cc3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/split.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/stl_util.h16
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/stringprintf.h6
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc7
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/suitesparse.h4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc238
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.h12
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.cc32
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/types.cc208
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility.cc3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc73
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h79
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/wall_time.cc96
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/wall_time.h88
-rw-r--r--extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch13
-rw-r--r--extern/libmv/third_party/ceres/patches/msvc_glog_fix.patch50
-rw-r--r--extern/libmv/third_party/ceres/patches/no_previous_declaration_fix.patch199
-rw-r--r--extern/libmv/third_party/ceres/patches/series3
-rw-r--r--extern/libmv/third_party/gflags/README.libmv2
-rw-r--r--extern/libmv/third_party/glog/README.libmv1
-rw-r--r--extern/lzo/minilzo/COPYING29
-rw-r--r--extern/lzo/minilzo/README.LZO27
-rw-r--r--extern/lzo/minilzo/lzoconf.h79
-rw-r--r--extern/lzo/minilzo/lzodefs.h179
-rw-r--r--extern/lzo/minilzo/minilzo.c1195
-rw-r--r--extern/lzo/minilzo/minilzo.h8
-rw-r--r--extern/rangetree/CMakeLists.txt31
-rw-r--r--extern/rangetree/README.org13
-rw-r--r--extern/rangetree/SConscript9
-rw-r--r--extern/rangetree/range_tree.hh228
-rw-r--r--extern/rangetree/range_tree_c_api.cc86
-rw-r--r--extern/rangetree/range_tree_c_api.h60
-rw-r--r--intern/CMakeLists.txt8
-rw-r--r--intern/SConscript34
-rw-r--r--intern/audaspace/CMakeLists.txt8
-rw-r--r--intern/audaspace/FX/AUD_BandpassCalculator.cpp5
-rw-r--r--intern/audaspace/FX/AUD_BandpassCalculator.h10
-rw-r--r--intern/audaspace/FX/AUD_ButterworthCalculator.cpp38
-rw-r--r--intern/audaspace/FX/AUD_ButterworthCalculator.h20
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp37
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h9
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h3
-rw-r--r--intern/audaspace/FX/AUD_HighpassCalculator.cpp27
-rw-r--r--intern/audaspace/FX/AUD_HighpassCalculator.h25
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp26
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h12
-rw-r--r--intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h2
-rw-r--r--intern/audaspace/FX/AUD_LowpassCalculator.cpp27
-rw-r--r--intern/audaspace/FX/AUD_LowpassCalculator.h25
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp27
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h12
-rw-r--r--intern/audaspace/SConscript23
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp13
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp15
-rw-r--r--intern/bsp/SConscript28
-rw-r--r--intern/bsp/intern/CSG_BooleanOps.cpp20
-rw-r--r--intern/container/SConscript28
-rw-r--r--intern/cycles/CMakeLists.txt13
-rw-r--r--intern/cycles/SConscript59
-rw-r--r--intern/cycles/app/cycles_server.cpp23
-rw-r--r--intern/cycles/app/cycles_xml.cpp16
-rw-r--r--intern/cycles/blender/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/addon/__init__.py40
-rw-r--r--intern/cycles/blender/addon/engine.py9
-rw-r--r--intern/cycles/blender/addon/enums.py63
-rw-r--r--intern/cycles/blender/addon/osl.py17
-rw-r--r--intern/cycles/blender/addon/properties.py290
-rw-r--r--intern/cycles/blender/addon/ui.py383
-rw-r--r--intern/cycles/blender/blender_curves.cpp1175
-rw-r--r--intern/cycles/blender/blender_mesh.cpp65
-rw-r--r--intern/cycles/blender/blender_object.cpp35
-rw-r--r--intern/cycles/blender/blender_python.cpp15
-rw-r--r--intern/cycles/blender/blender_session.cpp164
-rw-r--r--intern/cycles/blender/blender_session.h5
-rw-r--r--intern/cycles/blender/blender_shader.cpp65
-rw-r--r--intern/cycles/blender/blender_sync.cpp34
-rw-r--r--intern/cycles/blender/blender_sync.h9
-rw-r--r--intern/cycles/blender/blender_util.h66
-rw-r--r--intern/cycles/bvh/bvh.cpp153
-rw-r--r--intern/cycles/bvh/bvh.h9
-rw-r--r--intern/cycles/bvh/bvh_build.cpp65
-rw-r--r--intern/cycles/bvh/bvh_build.h2
-rw-r--r--intern/cycles/bvh/bvh_params.h5
-rw-r--r--intern/cycles/bvh/bvh_sort.cpp2
-rw-r--r--intern/cycles/bvh/bvh_split.cpp55
-rw-r--r--intern/cycles/device/CMakeLists.txt7
-rw-r--r--intern/cycles/device/device.h1
-rw-r--r--intern/cycles/device/device_cpu.cpp53
-rw-r--r--intern/cycles/device/device_cuda.cpp88
-rw-r--r--intern/cycles/device/device_network.cpp543
-rw-r--r--intern/cycles/device/device_network.h111
-rw-r--r--intern/cycles/device/device_opencl.cpp2
-rw-r--r--intern/cycles/kernel/CMakeLists.txt13
-rw-r--r--intern/cycles/kernel/SConscript28
-rw-r--r--intern/cycles/kernel/closure/bsdf.h379
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h2
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h8
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h96
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h28
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h2
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h9
-rw-r--r--intern/cycles/kernel/closure/bsdf_toon.h206
-rw-r--r--intern/cycles/kernel/closure/bsdf_util.h137
-rw-r--r--intern/cycles/kernel/closure/bsdf_ward.h6
-rw-r--r--intern/cycles/kernel/closure/bsdf_westin.h10
-rw-r--r--intern/cycles/kernel/closure/emissive.h7
-rw-r--r--intern/cycles/kernel/closure/volume.h7
-rw-r--r--intern/cycles/kernel/kernel.h13
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h63
-rw-r--r--intern/cycles/kernel/kernel_attribute.h50
-rw-r--r--intern/cycles/kernel/kernel_bvh.h673
-rw-r--r--intern/cycles/kernel/kernel_camera.h3
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h4
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h1
-rw-r--r--intern/cycles/kernel/kernel_compat_opencl.h1
-rw-r--r--intern/cycles/kernel/kernel_curve.h141
-rw-r--r--intern/cycles/kernel/kernel_displace.h4
-rw-r--r--intern/cycles/kernel/kernel_emission.h80
-rw-r--r--intern/cycles/kernel/kernel_light.h477
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h16
-rw-r--r--intern/cycles/kernel/kernel_object.h28
-rw-r--r--intern/cycles/kernel/kernel_passes.h13
-rw-r--r--intern/cycles/kernel/kernel_path.h106
-rw-r--r--intern/cycles/kernel/kernel_primitive.h185
-rw-r--r--intern/cycles/kernel/kernel_shader.h280
-rw-r--r--intern/cycles/kernel/kernel_sse2.cpp60
-rw-r--r--intern/cycles/kernel/kernel_sse3.cpp (renamed from intern/cycles/kernel/kernel_optimized.cpp)6
-rw-r--r--intern/cycles/kernel/kernel_textures.h6
-rw-r--r--intern/cycles/kernel/kernel_triangle.h77
-rw-r--r--intern/cycles/kernel/kernel_types.h105
-rw-r--r--intern/cycles/kernel/osl/CMakeLists.txt2
-rw-r--r--intern/cycles/kernel/osl/SConscript28
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp115
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp4
-rw-r--r--intern/cycles/kernel/osl/bsdf_toon.cpp179
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp2
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp37
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h18
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h11
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp120
-rw-r--r--intern/cycles/kernel/osl/osl_services.h10
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp162
-rw-r--r--intern/cycles/kernel/osl/osl_shader.h14
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt3
-rw-r--r--intern/cycles/kernel/shaders/SConscript28
-rw-r--r--intern/cycles/kernel/shaders/node_add_closure.osl6
-rw-r--r--intern/cycles/kernel/shaders/node_ambient_occlusion.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_attribute.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_background.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_brick_texture.osl8
-rw-r--r--intern/cycles/kernel/shaders/node_brightness.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_checker_texture.osl6
-rw-r--r--intern/cycles/kernel/shaders/node_combine_rgb.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_diffuse_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_emission.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_environment_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_gamma.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_geometry.osl3
-rw-r--r--intern/cycles/kernel/shaders/node_glass_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_glossy_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_gradient_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_hair_info.osl32
-rw-r--r--intern/cycles/kernel/shaders/node_hsv.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_invert.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_magic_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_mapping.osl3
-rw-r--r--intern/cycles/kernel/shaders/node_mix.osl6
-rw-r--r--intern/cycles/kernel/shaders/node_mix_closure.osl6
-rw-r--r--intern/cycles/kernel/shaders/node_musgrave_texture.osl26
-rw-r--r--intern/cycles/kernel/shaders/node_noise_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_normal_map.osl20
-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_refraction_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_curves.osl53
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_ramp.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_separate_rgb.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_texture.h21
-rw-r--r--intern/cycles/kernel/shaders/node_translucent_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_transparent_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_value.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_vector_curves.osl53
-rw-r--r--intern/cycles/kernel/shaders/node_velvet_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_voronoi_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_ward_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_wave_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h19
-rw-r--r--intern/cycles/kernel/svm/svm.h9
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h35
-rw-r--r--intern/cycles/kernel/svm/svm_bsdf.h268
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h49
-rw-r--r--intern/cycles/kernel/svm/svm_math.h67
-rw-r--r--intern/cycles/kernel/svm/svm_noise.h15
-rw-r--r--intern/cycles/kernel/svm/svm_ramp.h25
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h34
-rw-r--r--intern/cycles/kernel/svm/svm_types.h14
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/attribute.cpp205
-rw-r--r--intern/cycles/render/attribute.h46
-rw-r--r--intern/cycles/render/buffers.cpp1
-rw-r--r--intern/cycles/render/camera.cpp4
-rw-r--r--intern/cycles/render/camera.h2
-rw-r--r--intern/cycles/render/curves.cpp210
-rw-r--r--intern/cycles/render/curves.h139
-rw-r--r--intern/cycles/render/graph.cpp3
-rw-r--r--intern/cycles/render/graph.h3
-rw-r--r--intern/cycles/render/image.cpp175
-rw-r--r--intern/cycles/render/image.h10
-rw-r--r--intern/cycles/render/light.cpp120
-rw-r--r--intern/cycles/render/light.h1
-rw-r--r--intern/cycles/render/mesh.cpp439
-rw-r--r--intern/cycles/render/mesh.h28
-rw-r--r--intern/cycles/render/mesh_displace.cpp28
-rw-r--r--intern/cycles/render/nodes.cpp134
-rw-r--r--intern/cycles/render/nodes.h23
-rw-r--r--intern/cycles/render/object.cpp98
-rw-r--r--intern/cycles/render/object.h1
-rw-r--r--intern/cycles/render/osl.cpp90
-rw-r--r--intern/cycles/render/osl.h19
-rw-r--r--intern/cycles/render/scene.cpp28
-rw-r--r--intern/cycles/render/scene.h12
-rw-r--r--intern/cycles/render/session.cpp35
-rw-r--r--intern/cycles/render/session.h1
-rw-r--r--intern/cycles/render/shader.h2
-rw-r--r--intern/cycles/render/svm.cpp12
-rw-r--r--intern/cycles/render/svm.h2
-rw-r--r--intern/cycles/render/tile.cpp60
-rw-r--r--intern/cycles/render/tile.h20
-rw-r--r--intern/cycles/subd/subd_dice.cpp2
-rw-r--r--intern/cycles/util/CMakeLists.txt2
-rw-r--r--intern/cycles/util/util_attribute.cpp51
-rw-r--r--intern/cycles/util/util_boundbox.h13
-rw-r--r--intern/cycles/util/util_cache.h8
-rw-r--r--intern/cycles/util/util_cuda.cpp40
-rw-r--r--intern/cycles/util/util_cuda.h6
-rw-r--r--intern/cycles/util/util_dynlib.cpp2
-rw-r--r--intern/cycles/util/util_math.h193
-rw-r--r--intern/cycles/util/util_system.cpp15
-rw-r--r--intern/cycles/util/util_system.h3
-rw-r--r--intern/cycles/util/util_task.cpp7
-rw-r--r--intern/cycles/util/util_task.h1
-rw-r--r--intern/cycles/util/util_transform.h2
-rw-r--r--intern/cycles/util/util_types.h20
-rw-r--r--intern/dualcon/SConscript28
-rw-r--r--intern/dualcon/intern/MemoryAllocator.h2
-rw-r--r--intern/elbeem/SConscript28
-rw-r--r--intern/elbeem/intern/ntl_world.cpp8
-rw-r--r--intern/elbeem/intern/ntl_world.h1
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h59
-rw-r--r--intern/ghost/CMakeLists.txt3
-rw-r--r--intern/ghost/GHOST_C-api.h24
-rw-r--r--intern/ghost/GHOST_ISystem.h32
-rw-r--r--intern/ghost/GHOST_IWindow.h7
-rw-r--r--intern/ghost/GHOST_Types.h1
-rw-r--r--intern/ghost/SConscript30
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp25
-rw-r--r--intern/ghost/intern/GHOST_Debug.h17
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp11
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerSDL.cpp2
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.cpp32
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.cpp168
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.mm2
-rw-r--r--intern/ghost/intern/GHOST_System.cpp44
-rw-r--r--intern/ghost/intern/GHOST_System.h10
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp6
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.h7
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h8
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm136
-rw-r--r--intern/ghost/intern/GHOST_SystemNULL.h22
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp14
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp29
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h9
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp519
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h112
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp4
-rw-r--r--intern/ghost/intern/GHOST_Window.h13
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.cpp3
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h9
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm101
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.cpp3
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp60
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h6
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp370
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h35
-rw-r--r--intern/guardedalloc/SConscript27
-rw-r--r--intern/guardedalloc/intern/mallocn.c62
-rw-r--r--intern/iksolver/SConscript28
-rw-r--r--intern/iksolver/extern/IK_solver.h2
-rw-r--r--intern/itasc/SConscript28
-rw-r--r--intern/itasc/kdl/chain.hpp2
-rw-r--r--intern/itasc/kdl/tree.hpp4
-rw-r--r--intern/locale/SConscript27
-rw-r--r--intern/locale/boost_locale_wrapper.cpp89
-rw-r--r--intern/locale/boost_locale_wrapper.h3
-rw-r--r--intern/memutil/SConscript28
-rw-r--r--intern/mikktspace/SConscript28
-rw-r--r--intern/moto/SConscript28
-rw-r--r--intern/opencl/CMakeLists.txt (renamed from source/blender/opencl/CMakeLists.txt)2
-rw-r--r--intern/opencl/OCL_opencl.h (renamed from source/blender/opencl/OCL_opencl.h)0
-rw-r--r--intern/opencl/SConscript34
-rw-r--r--intern/opencl/intern/OCL_opencl.c (renamed from source/blender/opencl/intern/OCL_opencl.c)0
-rw-r--r--intern/opencl/intern/clew.c (renamed from source/blender/opencl/intern/clew.c)0
-rw-r--r--intern/opencl/intern/clew.h (renamed from source/blender/opencl/intern/clew.h)0
-rw-r--r--intern/opencolorio/SConscript27
-rw-r--r--intern/opencolorio/fallback_impl.cc2
-rw-r--r--intern/opencolorio/ocio_capi.cc4
-rw-r--r--intern/opencolorio/ocio_capi.h4
-rw-r--r--intern/opencolorio/ocio_impl.cc2
-rw-r--r--intern/opennl/SConscript28
-rw-r--r--intern/raskter/SConscript27
-rw-r--r--intern/rigidbody/CMakeLists.txt (renamed from source/gameengine/Physics/common/CMakeLists.txt)31
-rw-r--r--intern/rigidbody/RBI_api.h315
-rw-r--r--intern/rigidbody/SConscript42
-rw-r--r--intern/rigidbody/rb_bullet_api.cpp995
-rw-r--r--intern/smoke/CMakeLists.txt2
-rw-r--r--intern/smoke/SConscript28
-rw-r--r--intern/smoke/intern/FFT_NOISE.h6
-rw-r--r--intern/smoke/intern/FLUID_3D.cpp6
-rw-r--r--intern/smoke/intern/WAVELET_NOISE.h2
-rw-r--r--intern/string/SConscript28
-rw-r--r--intern/utfconv/SConscript28
-rw-r--r--intern/utfconv/utf_winfunc.c2
-rw-r--r--release/darwin/blender.app/Contents/Info.plist2
-rw-r--r--release/darwin/blender.app/Contents/MacOS/blender2
-rw-r--r--release/darwin/blenderplayer.app/Contents/Info.plist2
-rw-r--r--release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer2
-rw-r--r--release/datafiles/blender_icons.pngbin189744 -> 0 bytes
-rwxr-xr-xrelease/datafiles/blender_icons.sh5
-rw-r--r--release/datafiles/blender_icons.svg84948
-rw-r--r--release/datafiles/blender_icons16.pngbin0 -> 238718 bytes
-rw-r--r--release/datafiles/blender_icons32.pngbin0 -> 599721 bytes
-rw-r--r--release/datafiles/fonts/droidsans.ttf.gzbin2347305 -> 2617436 bytes
-rw-r--r--release/datafiles/matcaps/license.txt3
-rw-r--r--release/datafiles/matcaps/mc01.jpgbin0 -> 20830 bytes
-rw-r--r--release/datafiles/matcaps/mc02.jpgbin0 -> 23428 bytes
-rw-r--r--release/datafiles/matcaps/mc03.jpgbin0 -> 17550 bytes
-rw-r--r--release/datafiles/matcaps/mc04.jpgbin0 -> 29197 bytes
-rw-r--r--release/datafiles/matcaps/mc05.jpgbin0 -> 25454 bytes
-rw-r--r--release/datafiles/matcaps/mc06.jpgbin0 -> 19864 bytes
-rw-r--r--release/datafiles/matcaps/mc07.jpgbin0 -> 59262 bytes
-rw-r--r--release/datafiles/matcaps/mc08.jpgbin0 -> 24133 bytes
-rw-r--r--release/datafiles/matcaps/mc09.jpgbin0 -> 31101 bytes
-rw-r--r--release/datafiles/matcaps/mc10.jpgbin0 -> 28973 bytes
-rw-r--r--release/datafiles/matcaps/mc11.jpgbin0 -> 21395 bytes
-rw-r--r--release/datafiles/matcaps/mc12.jpgbin0 -> 23797 bytes
-rw-r--r--release/datafiles/matcaps/mc13.jpgbin0 -> 45661 bytes
-rw-r--r--release/datafiles/matcaps/mc14.jpgbin0 -> 44762 bytes
-rw-r--r--release/datafiles/matcaps/mc15.jpgbin0 -> 27456 bytes
-rw-r--r--release/datafiles/matcaps/mc16.jpgbin0 -> 33401 bytes
-rw-r--r--release/datafiles/matcaps/mc17.jpgbin0 -> 49292 bytes
-rw-r--r--release/datafiles/matcaps/mc18.jpgbin0 -> 40254 bytes
-rw-r--r--release/datafiles/matcaps/mc19.jpgbin0 -> 46330 bytes
-rw-r--r--release/datafiles/matcaps/mc20.jpgbin0 -> 52893 bytes
-rw-r--r--release/datafiles/matcaps/mc21.jpgbin0 -> 28717 bytes
-rw-r--r--release/datafiles/matcaps/mc22.jpgbin0 -> 33801 bytes
-rw-r--r--release/datafiles/matcaps/mc23.jpgbin0 -> 26688 bytes
-rw-r--r--release/datafiles/matcaps/mc24.jpgbin0 -> 14149 bytes
-rw-r--r--release/datafiles/preview_cycles.blendbin0 -> 1326220 bytes
-rwxr-xr-xrelease/datafiles/prvicons.sh4
-rw-r--r--release/datafiles/prvicons.svg19741
-rw-r--r--release/datafiles/splash.pngbin330539 -> 128911 bytes
-rw-r--r--release/datafiles/splash_template.xcfbin0 -> 21898 bytes
-rw-r--r--release/datafiles/startup.blendbin415348 -> 410988 bytes
-rw-r--r--release/scripts/modules/addon_utils.py63
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_extract_messages.py899
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_process_msg.py524
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/check_po.py119
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/clean_po.py27
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/import_po_from_branches.py56
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/languages_menu_utils.py96
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/merge_po.py105
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/rtl_utils.py (renamed from release/scripts/modules/bl_i18n_utils/rtl_preprocess.py)72
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py319
-rw-r--r--release/scripts/modules/bl_i18n_utils/spell_check_utils.py1030
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_branches.py39
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_languages_menu.py148
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_mo.py10
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_po.py113
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_pot.py79
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_trunk.py28
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils.py1609
-rw-r--r--release/scripts/modules/bpy/__init__.py1
-rw-r--r--release/scripts/modules/bpy/path.py8
-rw-r--r--release/scripts/modules/bpy/utils.py60
-rw-r--r--release/scripts/modules/bpy_extras/anim_utils.py190
-rw-r--r--release/scripts/modules/bpy_extras/io_utils.py32
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py15
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py10
-rw-r--r--release/scripts/modules/bpy_extras/view3d_utils.py4
-rw-r--r--release/scripts/modules/bpy_restrict_state.py66
-rw-r--r--release/scripts/modules/bpy_types.py42
-rw-r--r--release/scripts/modules/console/intellisense.py2
-rw-r--r--release/scripts/modules/console_python.py4
-rw-r--r--release/scripts/modules/rna_prop_ui.py9
-rw-r--r--release/scripts/modules/rna_xml.py10
-rw-r--r--release/scripts/presets/interface_theme/back_to_black.xml204
-rw-r--r--release/scripts/presets/interface_theme/blender_24x.xml204
-rw-r--r--release/scripts/presets/interface_theme/elsyiun.xml204
-rw-r--r--release/scripts/presets/interface_theme/hexagon.xml204
-rw-r--r--release/scripts/presets/interface_theme/ubuntu_ambiance.xml204
-rw-r--r--release/scripts/presets/keyconfig/maya.py14
-rw-r--r--release/scripts/presets/operator/wm.collada_export/second_life_rigged.py1
-rw-r--r--release/scripts/presets/operator/wm.collada_export/second_life_static.py1
-rw-r--r--release/scripts/startup/bl_operators/__init__.py1
-rw-r--r--release/scripts/startup/bl_operators/add_mesh_torus.py5
-rw-r--r--release/scripts/startup/bl_operators/anim.py19
-rw-r--r--release/scripts/startup/bl_operators/node.py80
-rw-r--r--release/scripts/startup/bl_operators/object.py31
-rw-r--r--release/scripts/startup/bl_operators/object_align.py22
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py8
-rw-r--r--release/scripts/startup/bl_operators/object_randomize_transform.py8
-rw-r--r--release/scripts/startup/bl_operators/presets.py12
-rw-r--r--release/scripts/startup/bl_operators/rigidbody.py292
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_follow_active.py93
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py18
-rw-r--r--release/scripts/startup/bl_operators/vertexpaint_dirt.py24
-rw-r--r--release/scripts/startup/bl_operators/wm.py68
-rw-r--r--release/scripts/startup/bl_ui/__init__.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py81
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py126
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py26
-rw-r--r--release/scripts/startup/bl_ui/properties_mask_common.py22
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py32
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_object_constraint.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py40
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py97
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py44
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py26
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody.py132
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py233
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_smoke.py24
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py46
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py220
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py60
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py32
-rw-r--r--release/scripts/startup/bl_ui/space_console.py4
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py8
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py4
-rw-r--r--release/scripts/startup/bl_ui/space_image.py12
-rw-r--r--release/scripts/startup/bl_ui/space_info.py15
-rw-r--r--release/scripts/startup/bl_ui/space_node.py1
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py27
-rw-r--r--release/scripts/startup/bl_ui/space_text.py38
-rw-r--r--release/scripts/startup/bl_ui/space_time.py1
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py141
-rw-r--r--release/scripts/startup/bl_ui/space_userpref_keymap.py21
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py80
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py94
-rw-r--r--release/scripts/startup/keyingsets_builtins.py98
-rw-r--r--release/scripts/templates_osl/empty_shader.osl6
-rw-r--r--release/scripts/templates_osl/noise.osl18
-rw-r--r--release/scripts/templates_osl/wireframe.osl11
-rw-r--r--release/scripts/templates_py/addon_add_object.py (renamed from release/scripts/templates/addon_add_object.py)2
-rw-r--r--release/scripts/templates_py/background_job.py (renamed from release/scripts/templates/background_job.py)0
-rw-r--r--release/scripts/templates_py/batch_export.py (renamed from release/scripts/templates/batch_export.py)0
-rw-r--r--release/scripts/templates_py/bmesh_simple.py (renamed from release/scripts/templates/bmesh_simple.py)0
-rw-r--r--release/scripts/templates_py/bmesh_simple_editmode.py (renamed from release/scripts/templates/bmesh_simple_editmode.py)0
-rw-r--r--release/scripts/templates_py/builtin_keyingset.py (renamed from release/scripts/templates/builtin_keyingset.py)0
-rw-r--r--release/scripts/templates_py/driver_functions.py (renamed from release/scripts/templates/driver_functions.py)0
-rw-r--r--release/scripts/templates_py/gamelogic.py (renamed from release/scripts/templates/gamelogic.py)0
-rw-r--r--release/scripts/templates_py/gamelogic_module.py (renamed from release/scripts/templates/gamelogic_module.py)0
-rw-r--r--release/scripts/templates_py/gamelogic_simple.py (renamed from release/scripts/templates/gamelogic_simple.py)0
-rw-r--r--release/scripts/templates_py/operator_file_export.py (renamed from release/scripts/templates/operator_file_export.py)0
-rw-r--r--release/scripts/templates_py/operator_file_import.py (renamed from release/scripts/templates/operator_file_import.py)0
-rw-r--r--release/scripts/templates_py/operator_mesh_add.py (renamed from release/scripts/templates/operator_mesh_add.py)0
-rw-r--r--release/scripts/templates_py/operator_modal.py (renamed from release/scripts/templates/operator_modal.py)0
-rw-r--r--release/scripts/templates_py/operator_modal_draw.py (renamed from release/scripts/templates/operator_modal_draw.py)8
-rw-r--r--release/scripts/templates_py/operator_modal_timer.py (renamed from release/scripts/templates/operator_modal_timer.py)2
-rw-r--r--release/scripts/templates_py/operator_modal_view3d.py (renamed from release/scripts/templates/operator_modal_view3d.py)0
-rw-r--r--release/scripts/templates_py/operator_modal_view3d_raycast.py (renamed from release/scripts/templates/operator_modal_view3d_raycast.py)7
-rw-r--r--release/scripts/templates_py/operator_node.py (renamed from release/scripts/templates/operator_node.py)0
-rw-r--r--release/scripts/templates_py/operator_simple.py (renamed from release/scripts/templates/operator_simple.py)0
-rw-r--r--release/scripts/templates_py/operator_uv.py (renamed from release/scripts/templates/operator_uv.py)0
-rw-r--r--release/scripts/templates_py/script_stub.py (renamed from release/scripts/templates/script_stub.py)0
-rw-r--r--release/scripts/templates_py/ui_list.py79
-rw-r--r--release/scripts/templates_py/ui_menu.py (renamed from release/scripts/templates/ui_menu.py)0
-rw-r--r--release/scripts/templates_py/ui_menu_simple.py (renamed from release/scripts/templates/ui_menu_simple.py)0
-rw-r--r--release/scripts/templates_py/ui_panel.py (renamed from release/scripts/templates/ui_panel.py)0
-rw-r--r--release/scripts/templates_py/ui_panel_simple.py (renamed from release/scripts/templates/ui_panel_simple.py)0
-rw-r--r--release/text/readme.html10
-rw-r--r--source/SConscript28
-rw-r--r--source/blender/CMakeLists.txt2
-rw-r--r--source/blender/SConscript31
-rw-r--r--source/blender/avi/SConscript28
-rw-r--r--source/blender/avi/intern/avi.c11
-rw-r--r--source/blender/avi/intern/avi_endian.c2
-rw-r--r--source/blender/avi/intern/avi_intern.h24
-rw-r--r--source/blender/avi/intern/avi_mjpeg.c23
-rw-r--r--source/blender/blenfont/BLF_api.h2
-rw-r--r--source/blender/blenfont/BLF_translation.h98
-rw-r--r--source/blender/blenfont/CMakeLists.txt1
-rw-r--r--source/blender/blenfont/SConscript32
-rw-r--r--source/blender/blenfont/intern/blf.c11
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c32
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h2
-rw-r--r--source/blender/blenfont/intern/blf_lang.c135
-rw-r--r--source/blender/blenfont/intern/blf_translation.c50
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h14
-rw-r--r--source/blender/blenkernel/BKE_action.h5
-rw-r--r--source/blender/blenkernel/BKE_addon.h (renamed from source/gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp)35
-rw-r--r--source/blender/blenkernel/BKE_armature.h24
-rw-r--r--source/blender/blenkernel/BKE_blender.h20
-rw-r--r--source/blender/blenkernel/BKE_bmesh.h3
-rw-r--r--source/blender/blenkernel/BKE_bpath.h (renamed from source/blender/blenlib/BLI_bpath.h)40
-rw-r--r--source/blender/blenkernel/BKE_brush.h8
-rw-r--r--source/blender/blenkernel/BKE_camera.h3
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h4
-rw-r--r--source/blender/blenkernel/BKE_colortools.h8
-rw-r--r--source/blender/blenkernel/BKE_constraint.h48
-rw-r--r--source/blender/blenkernel/BKE_context.h1
-rw-r--r--source/blender/blenkernel/BKE_curve.h3
-rw-r--r--source/blender/blenkernel/BKE_customdata.h7
-rw-r--r--source/blender/blenkernel/BKE_deform.h5
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h25
-rw-r--r--source/blender/blenkernel/BKE_displist.h2
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h3
-rw-r--r--source/blender/blenkernel/BKE_fluidsim.h2
-rw-r--r--source/blender/blenkernel/BKE_global.h4
-rw-r--r--source/blender/blenkernel/BKE_group.h3
-rw-r--r--source/blender/blenkernel/BKE_idprop.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h25
-rw-r--r--source/blender/blenkernel/BKE_key.h2
-rw-r--r--source/blender/blenkernel/BKE_lamp.h3
-rw-r--r--source/blender/blenkernel/BKE_lattice.h10
-rw-r--r--source/blender/blenkernel/BKE_library.h7
-rw-r--r--source/blender/blenkernel/BKE_main.h10
-rw-r--r--source/blender/blenkernel/BKE_mask.h2
-rw-r--r--source/blender/blenkernel/BKE_material.h2
-rw-r--r--source/blender/blenkernel/BKE_mball.h3
-rw-r--r--source/blender/blenkernel/BKE_mesh.h41
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h14
-rw-r--r--source/blender/blenkernel/BKE_object.h26
-rw-r--r--source/blender/blenkernel/BKE_packedFile.h8
-rw-r--r--source/blender/blenkernel/BKE_paint.h12
-rw-r--r--source/blender/blenkernel/BKE_particle.h42
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h (renamed from source/blender/blenlib/BLI_pbvh.h)174
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h7
-rw-r--r--source/blender/blenkernel/BKE_property.h3
-rw-r--r--source/blender/blenkernel/BKE_report.h6
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h96
-rw-r--r--source/blender/blenkernel/BKE_scene.h6
-rw-r--r--source/blender/blenkernel/BKE_screen.h19
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h4
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h14
-rw-r--r--source/blender/blenkernel/BKE_speaker.h4
-rw-r--r--source/blender/blenkernel/BKE_suggestions.h2
-rw-r--r--source/blender/blenkernel/BKE_tessmesh.h7
-rw-r--r--source/blender/blenkernel/BKE_text.h14
-rw-r--r--source/blender/blenkernel/BKE_texture.h3
-rw-r--r--source/blender/blenkernel/BKE_tracking.h3
-rw-r--r--source/blender/blenkernel/BKE_world.h3
-rw-r--r--source/blender/blenkernel/CMakeLists.txt22
-rw-r--r--source/blender/blenkernel/SConscript31
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c49
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c161
-rw-r--r--source/blender/blenkernel/intern/action.c20
-rw-r--r--source/blender/blenkernel/intern/addon.c85
-rw-r--r--source/blender/blenkernel/intern/anim.c75
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c10
-rw-r--r--source/blender/blenkernel/intern/armature.c59
-rw-r--r--source/blender/blenkernel/intern/blender.c281
-rw-r--r--source/blender/blenkernel/intern/bmfont.c4
-rw-r--r--source/blender/blenkernel/intern/booleanops_mesh.c24
-rw-r--r--source/blender/blenkernel/intern/bpath.c (renamed from source/blender/blenlib/intern/bpath.c)68
-rw-r--r--source/blender/blenkernel/intern/brush.c610
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c2
-rw-r--r--source/blender/blenkernel/intern/camera.c7
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c201
-rw-r--r--source/blender/blenkernel/intern/cloth.c4
-rw-r--r--source/blender/blenkernel/intern/collision.c16
-rw-r--r--source/blender/blenkernel/intern/colortools.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c122
-rw-r--r--source/blender/blenkernel/intern/context.c73
-rw-r--r--source/blender/blenkernel/intern/curve.c179
-rw-r--r--source/blender/blenkernel/intern/customdata.c127
-rw-r--r--source/blender/blenkernel/intern/deform.c103
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c201
-rw-r--r--source/blender/blenkernel/intern/displist.c124
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c97
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c444
-rw-r--r--source/blender/blenkernel/intern/effect.c10
-rw-r--r--source/blender/blenkernel/intern/fcurve.c22
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c141
-rw-r--r--source/blender/blenkernel/intern/font.c6
-rw-r--r--source/blender/blenkernel/intern/gpencil.c4
-rw-r--r--source/blender/blenkernel/intern/group.c4
-rw-r--r--source/blender/blenkernel/intern/icons.c6
-rw-r--r--source/blender/blenkernel/intern/idprop.c16
-rw-r--r--source/blender/blenkernel/intern/image.c440
-rw-r--r--source/blender/blenkernel/intern/ipo.c4
-rw-r--r--source/blender/blenkernel/intern/key.c34
-rw-r--r--source/blender/blenkernel/intern/lamp.c4
-rw-r--r--source/blender/blenkernel/intern/lattice.c80
-rw-r--r--source/blender/blenkernel/intern/library.c92
-rw-r--r--source/blender/blenkernel/intern/mask.c8
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c6
-rw-r--r--source/blender/blenkernel/intern/material.c36
-rw-r--r--source/blender/blenkernel/intern/mball.c87
-rw-r--r--source/blender/blenkernel/intern/mesh.c455
-rw-r--r--source/blender/blenkernel/intern/modifier.c10
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c78
-rw-r--r--source/blender/blenkernel/intern/movieclip.c16
-rw-r--r--source/blender/blenkernel/intern/multires.c8
-rw-r--r--source/blender/blenkernel/intern/nla.c6
-rw-r--r--source/blender/blenkernel/intern/node.c58
-rw-r--r--source/blender/blenkernel/intern/object.c310
-rw-r--r--source/blender/blenkernel/intern/ocean.c359
-rw-r--r--source/blender/blenkernel/intern/packedFile.c121
-rw-r--r--source/blender/blenkernel/intern/paint.c27
-rw-r--r--source/blender/blenkernel/intern/particle.c33
-rw-r--r--source/blender/blenkernel/intern/particle_system.c489
-rw-r--r--source/blender/blenkernel/intern/pbvh.c (renamed from source/blender/blenlib/intern/pbvh.c)385
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c1423
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h186
-rw-r--r--source/blender/blenkernel/intern/pointcache.c237
-rw-r--r--source/blender/blenkernel/intern/property.c2
-rw-r--r--source/blender/blenkernel/intern/report.c43
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c1335
-rw-r--r--source/blender/blenkernel/intern/sca.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c130
-rw-r--r--source/blender/blenkernel/intern/screen.c16
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c579
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c22
-rw-r--r--source/blender/blenkernel/intern/sequencer.c204
-rw-r--r--source/blender/blenkernel/intern/smoke.c39
-rw-r--r--source/blender/blenkernel/intern/softbody.c40
-rw-r--r--source/blender/blenkernel/intern/speaker.c5
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c135
-rw-r--r--source/blender/blenkernel/intern/suggestions.c8
-rw-r--r--source/blender/blenkernel/intern/text.c57
-rw-r--r--source/blender/blenkernel/intern/texture.c7
-rw-r--r--source/blender/blenkernel/intern/tracking.c160
-rw-r--r--source/blender/blenkernel/intern/unit.c8
-rw-r--r--source/blender/blenkernel/intern/world.c4
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c58
-rw-r--r--source/blender/blenlib/BLI_array.h154
-rw-r--r--source/blender/blenlib/BLI_buffer.h90
-rw-r--r--source/blender/blenlib/BLI_listbase.h8
-rw-r--r--source/blender/blenlib/BLI_math_base.h28
-rw-r--r--source/blender/blenlib/BLI_math_color.h9
-rw-r--r--source/blender/blenlib/BLI_math_geom.h20
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h17
-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_mempool.h12
-rw-r--r--source/blender/blenlib/BLI_path_util.h14
-rw-r--r--source/blender/blenlib/BLI_rect.h2
-rw-r--r--source/blender/blenlib/BLI_scanfill.h7
-rw-r--r--source/blender/blenlib/BLI_string_cursor_utf8.h2
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h1
-rw-r--r--source/blender/blenlib/BLI_utildefines.h41
-rw-r--r--source/blender/blenlib/CMakeLists.txt11
-rw-r--r--source/blender/blenlib/SConscript32
-rw-r--r--source/blender/blenlib/intern/BLI_array.c97
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c37
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c2
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c4
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c75
-rw-r--r--source/blender/blenlib/intern/buffer.c81
-rw-r--r--source/blender/blenlib/intern/endian_switch.c2
-rw-r--r--source/blender/blenlib/intern/fileops.c6
-rw-r--r--source/blender/blenlib/intern/freetypefont.c2
-rw-r--r--source/blender/blenlib/intern/jitter.c2
-rw-r--r--source/blender/blenlib/intern/listbase.c142
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c36
-rw-r--r--source/blender/blenlib/intern/math_color.c4
-rw-r--r--source/blender/blenlib/intern/math_color_inline.c96
-rw-r--r--source/blender/blenlib/intern/math_geom.c436
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c27
-rw-r--r--source/blender/blenlib/intern/math_matrix.c219
-rw-r--r--source/blender/blenlib/intern/math_rotation.c199
-rw-r--r--source/blender/blenlib/intern/math_vector.c58
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c9
-rw-r--r--source/blender/blenlib/intern/noise.c24
-rw-r--r--source/blender/blenlib/intern/path_util.c37
-rw-r--r--source/blender/blenlib/intern/rct.c32
-rw-r--r--source/blender/blenlib/intern/scanfill.c271
-rw-r--r--source/blender/blenlib/intern/string.c17
-rw-r--r--source/blender/blenlib/intern/string_cursor_utf8.c16
-rw-r--r--source/blender/blenlib/intern/string_utf8.c32
-rw-r--r--source/blender/blenlib/intern/threads.c6
-rw-r--r--source/blender/blenlib/intern/winstuff.c2
-rw-r--r--source/blender/blenloader/BLO_readfile.h21
-rw-r--r--source/blender/blenloader/CMakeLists.txt1
-rw-r--r--source/blender/blenloader/SConscript28
-rw-r--r--source/blender/blenloader/intern/readblenentry.c4
-rw-r--r--source/blender/blenloader/intern/readfile.c786
-rw-r--r--source/blender/blenloader/intern/readfile.h6
-rw-r--r--source/blender/blenloader/intern/runtime.c5
-rw-r--r--source/blender/blenloader/intern/versioning_250.c4
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c12
-rw-r--r--source/blender/blenloader/intern/writefile.c103
-rw-r--r--source/blender/bmesh/CMakeLists.txt12
-rw-r--r--source/blender/bmesh/SConscript32
-rw-r--r--source/blender/bmesh/bmesh.h5
-rw-r--r--source/blender/bmesh/bmesh_class.h23
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c122
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c191
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h21
-rw-r--r--source/blender/bmesh/intern/bmesh_error.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_inline.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c75
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c8
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators_inline.h58
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c984
-rw-r--r--source/blender/bmesh/intern/bmesh_log.h102
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c311
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h36
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c186
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c183
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h8
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_validate.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_validate.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c178
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.h24
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c58
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h18
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h10
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c317
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c324
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h10
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c425
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h57
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c70
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.h16
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c75
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_private.h6
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c5
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c17
-rw-r--r--source/blender/bmesh/operators/bmo_create.c42
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c55
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c10
-rw-r--r--source/blender/bmesh/operators/bmo_edgesplit.c136
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c123
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c32
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c32
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c33
-rw-r--r--source/blender/bmesh/operators/bmo_mesh_conv.c16
-rw-r--r--source/blender/bmesh/operators/bmo_mirror.c10
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c44
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c17
-rw-r--r--source/blender/bmesh/operators/bmo_similar.c52
-rw-r--r--source/blender/bmesh/operators/bmo_slide.c113
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c14
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c32
-rw-r--r--source/blender/bmesh/operators/bmo_symmetrize.c37
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c66
-rw-r--r--source/blender/bmesh/operators/bmo_unsubdivide.c2
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c43
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c36
-rw-r--r--source/blender/bmesh/tools/BME_bevel.c44
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c770
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.h6
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate.h8
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c110
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c12
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c44
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.c170
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.h (renamed from source/gameengine/Physics/common/PHY_IMotionState.cpp)21
-rw-r--r--source/blender/bmesh/tools/bmesh_triangulate.c87
-rw-r--r--source/blender/bmesh/tools/bmesh_triangulate.h36
-rw-r--r--source/blender/collada/AnimationExporter.cpp275
-rw-r--r--source/blender/collada/AnimationExporter.h30
-rw-r--r--source/blender/collada/AnimationImporter.cpp15
-rw-r--r--source/blender/collada/ArmatureExporter.cpp445
-rw-r--r--source/blender/collada/ArmatureExporter.h31
-rw-r--r--source/blender/collada/ArmatureImporter.cpp285
-rw-r--r--source/blender/collada/ArmatureImporter.h22
-rw-r--r--source/blender/collada/CMakeLists.txt7
-rw-r--r--source/blender/collada/CameraExporter.cpp3
-rw-r--r--source/blender/collada/ControllerExporter.cpp604
-rw-r--r--source/blender/collada/ControllerExporter.h127
-rw-r--r--source/blender/collada/DocumentExporter.cpp11
-rw-r--r--source/blender/collada/DocumentImporter.cpp247
-rw-r--r--source/blender/collada/DocumentImporter.h15
-rw-r--r--source/blender/collada/ExportSettings.h1
-rw-r--r--source/blender/collada/ExtraHandler.cpp1
-rw-r--r--source/blender/collada/ExtraHandler.h1
-rw-r--r--source/blender/collada/GeometryExporter.cpp88
-rw-r--r--source/blender/collada/GeometryExporter.h5
-rw-r--r--source/blender/collada/ImageExporter.cpp2
-rw-r--r--source/blender/collada/ImportSettings.cpp (renamed from intern/cycles/util/util_attribute.h)22
-rw-r--r--source/blender/collada/ImportSettings.h (renamed from source/gameengine/Physics/common/PHY_IController.cpp)25
-rw-r--r--source/blender/collada/MeshImporter.cpp47
-rw-r--r--source/blender/collada/MeshImporter.h31
-rw-r--r--source/blender/collada/SConscript7
-rw-r--r--source/blender/collada/SceneExporter.cpp42
-rw-r--r--source/blender/collada/SceneExporter.h2
-rw-r--r--source/blender/collada/SkinInfo.cpp7
-rw-r--r--source/blender/collada/SkinInfo.h2
-rw-r--r--source/blender/collada/TransformReader.cpp55
-rw-r--r--source/blender/collada/TransformReader.h10
-rw-r--r--source/blender/collada/TransformWriter.cpp25
-rw-r--r--source/blender/collada/TransformWriter.h2
-rw-r--r--source/blender/collada/collada.cpp16
-rw-r--r--source/blender/collada/collada.h7
-rw-r--r--source/blender/collada/collada_internal.cpp38
-rw-r--r--source/blender/collada/collada_internal.h19
-rw-r--r--source/blender/collada/collada_utils.cpp100
-rw-r--r--source/blender/collada/collada_utils.h7
-rw-r--r--source/blender/compositor/CMakeLists.txt12
-rw-r--r--source/blender/compositor/SConscript30
-rw-r--r--source/blender/compositor/intern/COM_CompositorContext.h3
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.h28
-rw-r--r--source/blender/compositor/intern/COM_Node.h6
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cpp1
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h8
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.cpp8
-rw-r--r--source/blender/compositor/nodes/COM_CompositorNode.cpp1
-rw-r--r--source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp8
-rw-r--r--source/blender/compositor/nodes/COM_GroupNode.cpp5
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp44
-rw-r--r--source/blender/compositor/nodes/COM_PixelateNode.cpp4
-rw-r--r--source/blender/compositor/nodes/COM_ScaleNode.cpp22
-rw-r--r--source/blender/compositor/nodes/COM_SetAlphaNode.cpp6
-rw-r--r--source/blender/compositor/nodes/COM_SocketProxyNode.cpp18
-rw-r--r--source/blender/compositor/nodes/COM_SocketProxyNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_TranslateNode.cpp27
-rw-r--r--source/blender/compositor/nodes/COM_ViewerNode.cpp1
-rw-r--r--source/blender/compositor/operations/COM_ChannelMatteOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.cpp20
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.cpp (renamed from source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp)10
-rw-r--r--source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.h (renamed from source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h)8
-rw-r--r--source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.cpp (renamed from source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp)10
-rw-r--r--source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.h (renamed from source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h)8
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cpp292
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_MovieClipOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MovieDistortionOperation.cpp32
-rw-r--r--source/blender/compositor/operations/COM_MovieDistortionOperation.h3
-rw-r--r--source/blender/compositor/operations/COM_MultilayerImageOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_OpenCLKernels.cl3
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp10
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.h1
-rw-r--r--source/blender/compositor/operations/COM_TrackPositionOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_TranslateOperation.cpp32
-rw-r--r--source/blender/compositor/operations/COM_TranslateOperation.h10
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.cpp1
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cpp11
-rw-r--r--source/blender/compositor/operations/COM_WrapOperation.cpp117
-rw-r--r--source/blender/compositor/operations/COM_WrapOperation.h47
-rw-r--r--source/blender/datatoc/datatoc.c4
-rw-r--r--source/blender/editors/SConscript28
-rw-r--r--source/blender/editors/animation/SConscript28
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c55
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c265
-rw-r--r--source/blender/editors/animation/anim_draw.c26
-rw-r--r--source/blender/editors/animation/anim_filter.c18
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c8
-rw-r--r--source/blender/editors/animation/anim_markers.c29
-rw-r--r--source/blender/editors/animation/anim_ops.c30
-rw-r--r--source/blender/editors/animation/drivers.c4
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c95
-rw-r--r--source/blender/editors/animation/keyframes_draw.c6
-rw-r--r--source/blender/editors/animation/keyframes_edit.c9
-rw-r--r--source/blender/editors/animation/keyframing.c211
-rw-r--r--source/blender/editors/animation/keyingsets.c7
-rw-r--r--source/blender/editors/armature/BIF_generate.h5
-rw-r--r--source/blender/editors/armature/SConscript28
-rw-r--r--source/blender/editors/armature/editarmature.c152
-rw-r--r--source/blender/editors/armature/editarmature_generate.c5
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c12
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c22
-rw-r--r--source/blender/editors/armature/poselib.c10
-rw-r--r--source/blender/editors/armature/poseobject.c10
-rw-r--r--source/blender/editors/armature/reeb.c2
-rw-r--r--source/blender/editors/curve/CMakeLists.txt5
-rw-r--r--source/blender/editors/curve/SConscript37
-rw-r--r--source/blender/editors/curve/editcurve.c110
-rw-r--r--source/blender/editors/curve/editfont.c15
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt31
-rw-r--r--source/blender/editors/datafiles/SConscript58
-rw-r--r--source/blender/editors/gpencil/SConscript28
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c21
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c25
-rw-r--r--source/blender/editors/include/BIF_gl.h8
-rw-r--r--source/blender/editors/include/BIF_glutil.h8
-rw-r--r--source/blender/editors/include/ED_anim_api.h27
-rw-r--r--source/blender/editors/include/ED_armature.h2
-rw-r--r--source/blender/editors/include/ED_datafiles.h88
-rw-r--r--source/blender/editors/include/ED_gpencil.h1
-rw-r--r--source/blender/editors/include/ED_mball.h4
-rw-r--r--source/blender/editors/include/ED_mesh.h19
-rw-r--r--source/blender/editors/include/ED_object.h9
-rw-r--r--source/blender/editors/include/ED_physics.h13
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/include/ED_sequencer.h2
-rw-r--r--source/blender/editors/include/ED_transform.h3
-rw-r--r--source/blender/editors/include/ED_view3d.h31
-rw-r--r--source/blender/editors/include/UI_icons.h34
-rw-r--r--source/blender/editors/include/UI_interface.h43
-rw-r--r--source/blender/editors/include/UI_interface_icons.h6
-rw-r--r--source/blender/editors/include/UI_resources.h24
-rw-r--r--source/blender/editors/include/UI_view2d.h9
-rw-r--r--source/blender/editors/interface/SConscript28
-rw-r--r--source/blender/editors/interface/interface.c161
-rw-r--r--source/blender/editors/interface/interface_anim.c17
-rw-r--r--source/blender/editors/interface/interface_draw.c16
-rw-r--r--source/blender/editors/interface/interface_handlers.c758
-rw-r--r--source/blender/editors/interface/interface_icons.c299
-rw-r--r--source/blender/editors/interface/interface_intern.h26
-rw-r--r--source/blender/editors/interface/interface_layout.c93
-rw-r--r--source/blender/editors/interface/interface_ops.c222
-rw-r--r--source/blender/editors/interface/interface_panel.c172
-rw-r--r--source/blender/editors/interface/interface_regions.c249
-rw-r--r--source/blender/editors/interface/interface_style.c42
-rw-r--r--source/blender/editors/interface/interface_templates.c769
-rw-r--r--source/blender/editors/interface/interface_utils.c2
-rw-r--r--source/blender/editors/interface/interface_widgets.c321
-rw-r--r--source/blender/editors/interface/resources.c190
-rw-r--r--source/blender/editors/interface/view2d.c509
-rw-r--r--source/blender/editors/interface/view2d_ops.c53
-rw-r--r--source/blender/editors/io/CMakeLists.txt4
-rw-r--r--source/blender/editors/io/SConscript30
-rw-r--r--source/blender/editors/io/io_collada.c53
-rw-r--r--source/blender/editors/mask/SConscript28
-rw-r--r--source/blender/editors/mask/mask_add.c2
-rw-r--r--source/blender/editors/mask/mask_draw.c2
-rw-r--r--source/blender/editors/mask/mask_edit.c20
-rw-r--r--source/blender/editors/mask/mask_ops.c4
-rw-r--r--source/blender/editors/mask/mask_relationships.c5
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt1
-rw-r--r--source/blender/editors/mesh/SConscript28
-rw-r--r--source/blender/editors/mesh/editface.c37
-rw-r--r--source/blender/editors/mesh/editmesh_add.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c158
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c118
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c9
-rw-r--r--source/blender/editors/mesh/editmesh_select.c111
-rw-r--r--source/blender/editors/mesh/editmesh_slide.c793
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c460
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c241
-rw-r--r--source/blender/editors/mesh/mesh_data.c32
-rw-r--r--source/blender/editors/mesh/mesh_intern.h1
-rw-r--r--source/blender/editors/mesh/mesh_navmesh.c77
-rw-r--r--source/blender/editors/mesh/mesh_ops.c20
-rw-r--r--source/blender/editors/mesh/meshtools.c144
-rw-r--r--source/blender/editors/metaball/SConscript28
-rw-r--r--source/blender/editors/metaball/mball_edit.c24
-rw-r--r--source/blender/editors/metaball/mball_ops.c7
-rw-r--r--source/blender/editors/object/CMakeLists.txt5
-rw-r--r--source/blender/editors/object/SConscript33
-rw-r--r--source/blender/editors/object/object_add.c179
-rw-r--r--source/blender/editors/object/object_bake.c925
-rw-r--r--source/blender/editors/object/object_constraint.c209
-rw-r--r--source/blender/editors/object/object_edit.c49
-rw-r--r--source/blender/editors/object/object_group.c17
-rw-r--r--source/blender/editors/object/object_hook.c77
-rw-r--r--source/blender/editors/object/object_intern.h5
-rw-r--r--source/blender/editors/object/object_lattice.c10
-rw-r--r--source/blender/editors/object/object_modifier.c35
-rw-r--r--source/blender/editors/object/object_ops.c20
-rw-r--r--source/blender/editors/object/object_relations.c118
-rw-r--r--source/blender/editors/object/object_select.c50
-rw-r--r--source/blender/editors/object/object_transform.c45
-rw-r--r--source/blender/editors/object/object_vgroup.c225
-rw-r--r--source/blender/editors/physics/CMakeLists.txt10
-rw-r--r--source/blender/editors/physics/SConscript29
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c11
-rw-r--r--source/blender/editors/physics/particle_boids.c14
-rw-r--r--source/blender/editors/physics/particle_edit.c110
-rw-r--r--source/blender/editors/physics/particle_object.c36
-rw-r--r--source/blender/editors/physics/physics_fluid.c12
-rw-r--r--source/blender/editors/physics/physics_intern.h20
-rw-r--r--source/blender/editors/physics/physics_ops.c16
-rw-r--r--source/blender/editors/physics/physics_pointcache.c26
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c199
-rw-r--r--source/blender/editors/physics/rigidbody_object.c621
-rw-r--r--source/blender/editors/physics/rigidbody_world.c210
-rw-r--r--source/blender/editors/render/SConscript28
-rw-r--r--source/blender/editors/render/render_internal.c12
-rw-r--r--source/blender/editors/render/render_opengl.c24
-rw-r--r--source/blender/editors/render/render_preview.c260
-rw-r--r--source/blender/editors/render/render_shading.c11
-rw-r--r--source/blender/editors/render/render_update.c82
-rw-r--r--source/blender/editors/render/render_view.c13
-rw-r--r--source/blender/editors/screen/SConscript28
-rw-r--r--source/blender/editors/screen/area.c528
-rw-r--r--source/blender/editors/screen/glutil.c20
-rw-r--r--source/blender/editors/screen/screen_edit.c63
-rw-r--r--source/blender/editors/screen/screen_intern.h13
-rw-r--r--source/blender/editors/screen/screen_ops.c223
-rw-r--r--source/blender/editors/screen/screendump.c18
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt1
-rw-r--r--source/blender/editors/sculpt_paint/SConscript28
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c83
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c102
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c199
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c560
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h12
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c25
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c16
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c690
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c1103
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h28
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c278
-rw-r--r--source/blender/editors/sound/SConscript28
-rw-r--r--source/blender/editors/sound/sound_ops.c4
-rw-r--r--source/blender/editors/space_action/SConscript28
-rw-r--r--source/blender/editors/space_action/action_draw.c16
-rw-r--r--source/blender/editors/space_action/action_edit.c5
-rw-r--r--source/blender/editors/space_action/action_select.c36
-rw-r--r--source/blender/editors/space_action/space_action.c9
-rw-r--r--source/blender/editors/space_api/SConscript28
-rw-r--r--source/blender/editors/space_buttons/SConscript28
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c7
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c5
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c16
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c16
-rw-r--r--source/blender/editors/space_clip/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_clip/SConscript31
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c84
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c31
-rw-r--r--source/blender/editors/space_clip/clip_draw.c24
-rw-r--r--source/blender/editors/space_clip/clip_editor.c24
-rw-r--r--source/blender/editors/space_clip/clip_intern.h10
-rw-r--r--source/blender/editors/space_clip/clip_ops.c13
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c37
-rw-r--r--source/blender/editors/space_clip/space_clip.c29
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c10
-rw-r--r--source/blender/editors/space_clip/tracking_select.c14
-rw-r--r--source/blender/editors/space_console/SConscript28
-rw-r--r--source/blender/editors/space_console/console_draw.c31
-rw-r--r--source/blender/editors/space_console/console_intern.h2
-rw-r--r--source/blender/editors/space_console/console_ops.c42
-rw-r--r--source/blender/editors/space_console/space_console.c2
-rw-r--r--source/blender/editors/space_file/SConscript28
-rw-r--r--source/blender/editors/space_file/file_draw.c42
-rw-r--r--source/blender/editors/space_file/file_ops.c5
-rw-r--r--source/blender/editors/space_file/filesel.c49
-rw-r--r--source/blender/editors/space_file/fsmenu.c2
-rw-r--r--source/blender/editors/space_file/space_file.c3
-rw-r--r--source/blender/editors/space_graph/SConscript28
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c5
-rw-r--r--source/blender/editors/space_graph/graph_draw.c2
-rw-r--r--source/blender/editors/space_graph/graph_edit.c9
-rw-r--r--source/blender/editors/space_graph/space_graph.c6
-rw-r--r--source/blender/editors/space_image/SConscript28
-rw-r--r--source/blender/editors/space_image/image_buttons.c39
-rw-r--r--source/blender/editors/space_image/image_draw.c151
-rw-r--r--source/blender/editors/space_image/image_edit.c11
-rw-r--r--source/blender/editors/space_image/image_ops.c37
-rw-r--r--source/blender/editors/space_image/space_image.c39
-rw-r--r--source/blender/editors/space_info/SConscript28
-rw-r--r--source/blender/editors/space_info/info_draw.c12
-rw-r--r--source/blender/editors/space_info/info_intern.h5
-rw-r--r--source/blender/editors/space_info/info_ops.c160
-rw-r--r--source/blender/editors/space_info/info_report.c9
-rw-r--r--source/blender/editors/space_info/info_stats.c93
-rw-r--r--source/blender/editors/space_info/space_info.c6
-rw-r--r--source/blender/editors/space_info/textview.c67
-rw-r--r--source/blender/editors/space_info/textview.h3
-rw-r--r--source/blender/editors/space_logic/SConscript28
-rw-r--r--source/blender/editors/space_logic/logic_buttons.c2
-rw-r--r--source/blender/editors/space_logic/logic_ops.c56
-rw-r--r--source/blender/editors/space_logic/logic_window.c44
-rw-r--r--source/blender/editors/space_logic/space_logic.c4
-rw-r--r--source/blender/editors/space_nla/SConscript28
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c12
-rw-r--r--source/blender/editors/space_nla/nla_draw.c38
-rw-r--r--source/blender/editors/space_nla/nla_edit.c4
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_node/SConscript28
-rw-r--r--source/blender/editors/space_node/drawnode.c99
-rw-r--r--source/blender/editors/space_node/node_add.c16
-rw-r--r--source/blender/editors/space_node/node_buttons.c1
-rw-r--r--source/blender/editors/space_node/node_draw.c125
-rw-r--r--source/blender/editors/space_node/node_edit.c30
-rw-r--r--source/blender/editors/space_node/node_group.c30
-rw-r--r--source/blender/editors/space_node/node_header.c4
-rw-r--r--source/blender/editors/space_node/node_intern.h52
-rw-r--r--source/blender/editors/space_node/node_ops.c2
-rw-r--r--source/blender/editors/space_node/node_relationships.c2
-rw-r--r--source/blender/editors/space_node/node_select.c8
-rw-r--r--source/blender/editors/space_node/node_templates.c3
-rw-r--r--source/blender/editors/space_node/node_toolbar.c92
-rw-r--r--source/blender/editors/space_node/node_view.c23
-rw-r--r--source/blender/editors/space_node/space_node.c69
-rw-r--r--source/blender/editors/space_outliner/SConscript28
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c178
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c30
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h5
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c16
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c124
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c17
-rw-r--r--source/blender/editors/space_script/SConscript28
-rw-r--r--source/blender/editors/space_script/script_edit.c2
-rw-r--r--source/blender/editors/space_sequencer/SConscript28
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c33
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c72
-rw-r--r--source/blender/editors/space_sequencer/sequencer_modifier.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c4
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c2
-rw-r--r--source/blender/editors/space_text/CMakeLists.txt7
-rw-r--r--source/blender/editors/space_text/SConscript28
-rw-r--r--source/blender/editors/space_text/space_text.c34
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c557
-rw-r--r--source/blender/editors/space_text/text_draw.c518
-rw-r--r--source/blender/editors/space_text/text_format.c227
-rw-r--r--source/blender/editors/space_text/text_format.h109
-rw-r--r--source/blender/editors/space_text/text_format_lua.c318
-rw-r--r--source/blender/editors/space_text/text_format_osl.c336
-rw-r--r--source/blender/editors/space_text/text_format_py.c325
-rw-r--r--source/blender/editors/space_text/text_header.c35
-rw-r--r--source/blender/editors/space_text/text_intern.h28
-rw-r--r--source/blender/editors/space_text/text_ops.c96
-rw-r--r--source/blender/editors/space_text/text_python.c361
-rw-r--r--source/blender/editors/space_time/SConscript28
-rw-r--r--source/blender/editors/space_time/space_time.c14
-rw-r--r--source/blender/editors/space_userpref/SConscript28
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c8
-rw-r--r--source/blender/editors/space_view3d/SConscript28
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c33
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c8
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c76
-rw-r--r--source/blender/editors/space_view3d/drawobject.c304
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c71
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c102
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c191
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c472
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c321
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h9
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c56
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c103
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c242
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c15
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c39
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c196
-rw-r--r--source/blender/editors/transform/SConscript28
-rw-r--r--source/blender/editors/transform/transform.c1255
-rw-r--r--source/blender/editors/transform/transform.h90
-rw-r--r--source/blender/editors/transform/transform_constraints.c39
-rw-r--r--source/blender/editors/transform/transform_conversions.c189
-rw-r--r--source/blender/editors/transform/transform_generics.c62
-rw-r--r--source/blender/editors/transform/transform_input.c42
-rw-r--r--source/blender/editors/transform/transform_manipulator.c113
-rw-r--r--source/blender/editors/transform/transform_ops.c68
-rw-r--r--source/blender/editors/transform/transform_orientations.c105
-rw-r--r--source/blender/editors/transform/transform_snap.c25
-rw-r--r--source/blender/editors/util/SConscript28
-rw-r--r--source/blender/editors/util/ed_util.c22
-rw-r--r--source/blender/editors/util/undo.c45
-rw-r--r--source/blender/editors/uvedit/CMakeLists.txt5
-rw-r--r--source/blender/editors/uvedit/SConscript37
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c10
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c207
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h8
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c378
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c56
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c1399
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c257
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/GPU_buffers.h14
-rw-r--r--source/blender/gpu/GPU_draw.h2
-rw-r--r--source/blender/gpu/GPU_extensions.h5
-rw-r--r--source/blender/gpu/GPU_material.h10
-rw-r--r--source/blender/gpu/SConscript30
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c270
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c50
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c166
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c67
-rw-r--r--source/blender/gpu/intern/gpu_material.c62
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl39
-rw-r--r--source/blender/ikplugin/SConscript28
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c6
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp61
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h3
-rw-r--r--source/blender/imbuf/IMB_imbuf.h13
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h16
-rw-r--r--source/blender/imbuf/IMB_thumbs.h2
-rw-r--r--source/blender/imbuf/SConscript28
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h2
-rw-r--r--source/blender/imbuf/intern/IMB_filter.h3
-rw-r--r--source/blender/imbuf/intern/IMB_metadata.h2
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c2
-rw-r--r--source/blender/imbuf/intern/anim_movie.c4
-rw-r--r--source/blender/imbuf/intern/cineon/SConscript28
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c3
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c3
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c3
-rw-r--r--source/blender/imbuf/intern/colormanagement.c226
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h2
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.h2
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp6
-rw-r--r--source/blender/imbuf/intern/dds/SConscript28
-rw-r--r--source/blender/imbuf/intern/dds/Stream.cpp10
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp10
-rw-r--r--source/blender/imbuf/intern/divers.c122
-rw-r--r--source/blender/imbuf/intern/filter.c68
-rw-r--r--source/blender/imbuf/intern/imageprocess.c60
-rw-r--r--source/blender/imbuf/intern/indexer.c18
-rw-r--r--source/blender/imbuf/intern/iris.c2
-rw-r--r--source/blender/imbuf/intern/jp2.c227
-rw-r--r--source/blender/imbuf/intern/jpeg.c4
-rw-r--r--source/blender/imbuf/intern/openexr/SConscript28
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp9
-rw-r--r--source/blender/imbuf/intern/png.c228
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c3
-rw-r--r--source/blender/imbuf/intern/readimage.c35
-rw-r--r--source/blender/imbuf/intern/rectop.c6
-rw-r--r--source/blender/imbuf/intern/scaling.c66
-rw-r--r--source/blender/imbuf/intern/thumbs.c2
-rw-r--r--source/blender/imbuf/intern/tiff.c52
-rw-r--r--source/blender/imbuf/intern/util.c6
-rw-r--r--source/blender/makesdna/DNA_ID.h10
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h7
-rw-r--r--source/blender/makesdna/DNA_armature_types.h4
-rw-r--r--source/blender/makesdna/DNA_brush_types.h17
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_genfile.h10
-rw-r--r--source/blender/makesdna/DNA_image_types.h16
-rw-r--r--source/blender/makesdna/DNA_listBase.h7
-rw-r--r--source/blender/makesdna/DNA_material_types.h4
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h21
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h13
-rw-r--r--source/blender/makesdna/DNA_meta_types.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h85
-rw-r--r--source/blender/makesdna/DNA_node_types.h21
-rw-r--r--source/blender/makesdna/DNA_object_types.h42
-rw-r--r--source/blender/makesdna/DNA_particle_types.h17
-rw-r--r--source/blender/makesdna/DNA_rigidbody_types.h294
-rw-r--r--source/blender/makesdna/DNA_scene_types.h108
-rw-r--r--source/blender/makesdna/DNA_screen_types.h48
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h13
-rw-r--r--source/blender/makesdna/DNA_space_types.h21
-rw-r--r--source/blender/makesdna/DNA_text_types.h8
-rw-r--r--source/blender/makesdna/DNA_texture_types.h2
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h26
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h80
-rw-r--r--source/blender/makesdna/DNA_view2d_types.h6
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h22
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h18
-rw-r--r--source/blender/makesdna/DNA_world_types.h3
-rw-r--r--source/blender/makesdna/SConscript30
-rw-r--r--source/blender/makesdna/intern/SConscript28
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c394
-rw-r--r--source/blender/makesdna/intern/makesdna.c33
-rw-r--r--source/blender/makesrna/RNA_access.h22
-rw-r--r--source/blender/makesrna/RNA_define.h15
-rw-r--r--source/blender/makesrna/RNA_enum_types.h12
-rw-r--r--source/blender/makesrna/RNA_types.h44
-rw-r--r--source/blender/makesrna/SConscript32
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt9
-rw-r--r--source/blender/makesrna/intern/SConscript34
-rw-r--r--source/blender/makesrna/intern/makesrna.c160
-rw-r--r--source/blender/makesrna/intern/rna_ID.c2
-rw-r--r--source/blender/makesrna/intern/rna_access.c379
-rw-r--r--source/blender/makesrna/intern/rna_action.c6
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c17
-rw-r--r--source/blender/makesrna/intern/rna_animation.c35
-rw-r--r--source/blender/makesrna/intern/rna_armature.c5
-rw-r--r--source/blender/makesrna/intern/rna_boid.c4
-rw-r--r--source/blender/makesrna/intern/rna_brush.c23
-rw-r--r--source/blender/makesrna/intern/rna_camera.c19
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c4
-rw-r--r--source/blender/makesrna/intern/rna_color.c21
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c16
-rw-r--r--source/blender/makesrna/intern/rna_curve.c4
-rw-r--r--source/blender/makesrna/intern/rna_define.c276
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c24
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c108
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c115
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c4
-rw-r--r--source/blender/makesrna/intern/rna_internal.h8
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h56
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c4
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c315
-rw-r--r--source/blender/makesrna/intern/rna_material.c2
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c80
-rw-r--r--source/blender/makesrna/intern/rna_meta.c2
-rw-r--r--source/blender/makesrna/intern/rna_meta_api.c60
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c334
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c2
-rw-r--r--source/blender/makesrna/intern/rna_nla.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c179
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h76
-rw-r--r--source/blender/makesrna/intern/rna_object.c98
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c312
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c15
-rw-r--r--source/blender/makesrna/intern/rna_particle.c502
-rw-r--r--source/blender/makesrna/intern/rna_pose.c20
-rw-r--r--source/blender/makesrna/intern/rna_render.c9
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c1150
-rw-r--r--source/blender/makesrna/intern/rna_rna.c46
-rw-r--r--source/blender/makesrna/intern/rna_scene.c215
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c12
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c94
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c37
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c84
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c148
-rw-r--r--source/blender/makesrna/intern/rna_speaker.c1
-rw-r--r--source/blender/makesrna/intern/rna_text.c3
-rw-r--r--source/blender/makesrna/intern/rna_texture.c15
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c63
-rw-r--r--source/blender/makesrna/intern/rna_ui.c198
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c431
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c452
-rw-r--r--source/blender/makesrna/intern/rna_wm.c40
-rw-r--r--source/blender/makesrna/intern/rna_world.c20
-rw-r--r--source/blender/modifiers/CMakeLists.txt11
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h2
-rw-r--r--source/blender/modifiers/SConscript67
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c58
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c8
-rw-r--r--source/blender/modifiers/intern/MOD_boolean_util.c9
-rw-r--r--source/blender/modifiers/intern/MOD_build.c20
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c2
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c6
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c29
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c2
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c2
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c158
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c344
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_mdd.c301
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c277
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.c71
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.h67
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c37
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c8
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c11
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c11
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c16
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c2
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c4
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c10
-rw-r--r--source/blender/modifiers/intern/MOD_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c268
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c2
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c6
-rw-r--r--source/blender/nodes/CMakeLists.txt13
-rw-r--r--source/blender/nodes/NOD_shader.h1
-rw-r--r--source/blender/nodes/SConscript31
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c436
-rw-r--r--source/blender/nodes/composite/node_composite_util.c1412
-rw-r--r--source/blender/nodes/composite/node_composite_util.h149
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_alphaOver.c103
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bilateralblur.c219
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_blur.c684
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bokehblur.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bokehimage.c3
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_boxmask.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_brightness.c52
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_channelMatte.c155
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_chromaMatte.c134
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorMatte.c75
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorSpill.c279
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorbalance.c135
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorcorrection.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_common.c180
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_composite.c65
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_crop.c66
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_curves.c102
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_defocus.c828
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_despeckle.c13
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_diffMatte.c89
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_dilate.c110
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_directionalblur.c88
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_displace.c143
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_distanceMatte.c145
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c1237
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_ellipsemask.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_filter.c184
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_flip.c53
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_gamma.c40
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_glare.c440
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_hueSatVal.c57
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_huecorrect.c105
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_idMask.c70
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c381
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_inpaint.c13
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_invert.c80
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_keying.c11
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_keyingscreen.c138
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_lensdist.c147
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_levels.c272
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_lummaMatte.c59
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mapRange.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mapUV.c126
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mapValue.c42
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mask.c48
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_math.c159
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mixrgb.c46
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_movieclip.c104
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_moviedistortion.c67
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_normal.c42
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_normalize.c67
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_outputFile.c181
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_pixelate.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_premulkey.c25
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_rgb.c17
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_rotate.c85
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_scale.c145
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c112
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c89
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c233
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c113
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_setalpha.c39
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_splitViewer.c110
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_stabilize2d.c30
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_switch.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_texture.c106
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_tonemap.c112
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_trackpos.c13
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_transform.c87
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_translate.c23
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_valToRgb.c80
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_value.c17
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_vecBlur.c46
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_viewer.c90
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_zcombine.c181
-rw-r--r--source/blender/nodes/intern/node_common.c10
-rw-r--r--source/blender/nodes/intern/node_exec.c41
-rw-r--r--source/blender/nodes/intern/node_exec.h4
-rw-r--r--source/blender/nodes/intern/node_util.h10
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c10
-rw-r--r--source/blender/nodes/shader/node_shader_util.c49
-rw-r--r--source/blender/nodes/shader/node_shader_util.h12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_brightness.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.c10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hair_info.c53
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_material.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c8
-rw-r--r--source/blender/nodes/texture/node_texture_util.h13
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_common.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_compose.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_decompose.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_proc.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_texture.c2
-rw-r--r--source/blender/opencl/SConscript8
-rw-r--r--source/blender/python/BPY_extern.h7
-rw-r--r--source/blender/python/SConscript124
-rw-r--r--source/blender/python/bmesh/bmesh_py_api.c25
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c11
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c163
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.h2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c12
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.c14
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.c22
-rw-r--r--source/blender/python/generic/bpy_internal_import.c2
-rw-r--r--source/blender/python/generic/bpy_internal_import.h6
-rw-r--r--source/blender/python/generic/idprop_py_api.c11
-rw-r--r--source/blender/python/generic/py_capi_utils.c69
-rw-r--r--source/blender/python/generic/py_capi_utils.h7
-rw-r--r--source/blender/python/intern/CMakeLists.txt132
-rw-r--r--source/blender/python/intern/bpy.c36
-rw-r--r--source/blender/python/intern/bpy_app.c11
-rw-r--r--source/blender/python/intern/bpy_app_build_options.c303
-rw-r--r--source/blender/python/intern/bpy_app_build_options.h (renamed from source/gameengine/Physics/common/PHY_IGraphicController.cpp)20
-rw-r--r--source/blender/python/intern/bpy_app_ffmpeg.c12
-rw-r--r--source/blender/python/intern/bpy_app_translations.c808
-rw-r--r--source/blender/python/intern/bpy_app_translations.h (renamed from source/gameengine/Physics/common/PHY_IPhysicsController.cpp)20
-rw-r--r--source/blender/python/intern/bpy_driver.c6
-rw-r--r--source/blender/python/intern/bpy_interface.c94
-rw-r--r--source/blender/python/intern/bpy_interface_atexit.c4
-rw-r--r--source/blender/python/intern/bpy_intern_string.c3
-rw-r--r--source/blender/python/intern/bpy_intern_string.h1
-rw-r--r--source/blender/python/intern/bpy_library.c2
-rw-r--r--source/blender/python/intern/bpy_operator.c26
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c80
-rw-r--r--source/blender/python/intern/bpy_path.c67
-rw-r--r--source/blender/python/intern/bpy_path.h33
-rw-r--r--source/blender/python/intern/bpy_props.c1943
-rw-r--r--source/blender/python/intern/bpy_rna.c275
-rw-r--r--source/blender/python/intern/bpy_rna.h11
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c50
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c185
-rw-r--r--source/blender/python/intern/bpy_rna_callback.h5
-rw-r--r--source/blender/python/intern/bpy_util.c10
-rw-r--r--source/blender/python/intern/bpy_util.h2
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c83
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c83
-rw-r--r--source/blender/quicktime/SConscript28
-rw-r--r--source/blender/quicktime/apple/qtkit_export.m6
-rw-r--r--source/blender/quicktime/apple/quicktime_export.c2
-rw-r--r--source/blender/quicktime/quicktime_export.h6
-rw-r--r--source/blender/render/CMakeLists.txt3
-rw-r--r--source/blender/render/SConscript28
-rw-r--r--source/blender/render/extern/include/RE_engine.h5
-rw-r--r--source/blender/render/extern/include/RE_multires_bake.h62
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h6
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h3
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h12
-rw-r--r--source/blender/render/intern/include/envmap.h3
-rw-r--r--source/blender/render/intern/include/pixelblending.h4
-rw-r--r--source/blender/render/intern/include/pixelshading.h2
-rw-r--r--source/blender/render/intern/include/rayobject.h4
-rw-r--r--source/blender/render/intern/include/render_result.h2
-rw-r--r--source/blender/render/intern/include/render_types.h14
-rw-r--r--source/blender/render/intern/include/rendercore.h2
-rw-r--r--source/blender/render/intern/include/renderdatabase.h12
-rw-r--r--source/blender/render/intern/include/strand.h4
-rw-r--r--source/blender/render/intern/include/texture.h7
-rw-r--r--source/blender/render/intern/include/zbuf.h14
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp5
-rw-r--r--source/blender/render/intern/raytrace/rayobject_instance.cpp6
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp150
-rw-r--r--source/blender/render/intern/raytrace/rayobject_vbvh.cpp4
-rw-r--r--source/blender/render/intern/source/bake.c1117
-rw-r--r--source/blender/render/intern/source/convertblender.c116
-rw-r--r--source/blender/render/intern/source/envmap.c62
-rw-r--r--source/blender/render/intern/source/external_engine.c99
-rw-r--r--source/blender/render/intern/source/imagetexture.c112
-rw-r--r--source/blender/render/intern/source/initrender.c2
-rw-r--r--source/blender/render/intern/source/multires_bake.c1298
-rw-r--r--source/blender/render/intern/source/occlusion.c16
-rw-r--r--source/blender/render/intern/source/pipeline.c279
-rw-r--r--source/blender/render/intern/source/pixelblending.c6
-rw-r--r--source/blender/render/intern/source/pixelshading.c2
-rw-r--r--source/blender/render/intern/source/pointdensity.c2
-rw-r--r--source/blender/render/intern/source/rayshade.c40
-rw-r--r--source/blender/render/intern/source/render_result.c27
-rw-r--r--source/blender/render/intern/source/render_texture.c145
-rw-r--r--source/blender/render/intern/source/rendercore.c822
-rw-r--r--source/blender/render/intern/source/renderdatabase.c74
-rw-r--r--source/blender/render/intern/source/shadbuf.c55
-rw-r--r--source/blender/render/intern/source/shadeinput.c10
-rw-r--r--source/blender/render/intern/source/shadeoutput.c2
-rw-r--r--source/blender/render/intern/source/strand.c22
-rw-r--r--source/blender/render/intern/source/volume_precache.c6
-rw-r--r--source/blender/render/intern/source/voxeldata.c2
-rw-r--r--source/blender/render/intern/source/zbuf.c73
-rw-r--r--source/blender/windowmanager/SConscript28
-rw-r--r--source/blender/windowmanager/WM_api.h50
-rw-r--r--source/blender/windowmanager/WM_keymap.h3
-rw-r--r--source/blender/windowmanager/WM_types.h10
-rw-r--r--source/blender/windowmanager/intern/wm.c83
-rw-r--r--source/blender/windowmanager/intern/wm_apple.c2
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c22
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c87
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c217
-rw-r--r--source/blender/windowmanager/intern/wm_files.c110
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c17
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c39
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c33
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c358
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c3
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c19
-rw-r--r--source/blender/windowmanager/intern/wm_window.c321
-rw-r--r--source/blender/windowmanager/wm_event_system.h20
-rw-r--r--source/blender/windowmanager/wm_event_types.h41
-rw-r--r--source/blender/windowmanager/wm_files.h8
-rw-r--r--source/blender/windowmanager/wm_subwindow.h2
-rw-r--r--source/blender/windowmanager/wm_window.h9
-rw-r--r--source/blenderplayer/CMakeLists.txt3
-rw-r--r--source/blenderplayer/bad_level_call_stubs/SConscript28
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c31
-rw-r--r--source/creator/CMakeLists.txt20
-rw-r--r--source/creator/creator.c255
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp21
-rw-r--r--source/gameengine/BlenderRoutines/CMakeLists.txt9
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp22
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.h12
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp58
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.h1
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp24
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp26
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp10
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h7
-rw-r--r--source/gameengine/BlenderRoutines/SConscript28
-rw-r--r--source/gameengine/CMakeLists.txt1
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp5
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp899
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.h5
-rw-r--r--source/gameengine/Converter/CMakeLists.txt8
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp214
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h36
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp6
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp6
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp7
-rw-r--r--source/gameengine/Converter/KX_LibLoadStatus.cpp252
-rw-r--r--source/gameengine/Converter/KX_LibLoadStatus.h85
-rw-r--r--source/gameengine/Converter/KX_SoftBodyDeformer.cpp2
-rw-r--r--source/gameengine/Converter/SConscript30
-rw-r--r--source/gameengine/Expressions/EmptyValue.cpp28
-rw-r--r--source/gameengine/Expressions/InputParser.cpp16
-rw-r--r--source/gameengine/Expressions/InputParser.h2
-rw-r--r--source/gameengine/Expressions/Operator2Expr.cpp83
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp36
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h224
-rw-r--r--source/gameengine/Expressions/SConscript28
-rw-r--r--source/gameengine/GameLogic/CMakeLists.txt2
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp16
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.h5
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h2
-rw-r--r--source/gameengine/GameLogic/SCA_IInputDevice.h25
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h2
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.h8
-rw-r--r--source/gameengine/GameLogic/SCA_PythonJoystick.cpp188
-rw-r--r--source/gameengine/GameLogic/SCA_PythonJoystick.h56
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp20
-rw-r--r--source/gameengine/GameLogic/SConscript28
-rw-r--r--source/gameengine/GamePlayer/SConscript28
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.cpp10
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.h1
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RawImage.cpp1
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp72
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.h6
-rw-r--r--source/gameengine/GamePlayer/common/SConscript28
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp65
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.h36
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp145
-rw-r--r--source/gameengine/GamePlayer/ghost/SConscript28
-rw-r--r--source/gameengine/Ketsji/BL_Action.cpp84
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp12
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp39
-rw-r--r--source/gameengine/Ketsji/BL_Material.h10
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp16
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt6
-rw-r--r--source/gameengine/Ketsji/KXNetwork/SConscript28
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp64
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h19
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp21
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h7
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_CharacterWrapper.cpp53
-rw-r--r--source/gameengine/Ketsji/KX_CharacterWrapper.h5
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h2
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp21
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h6
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h3
-rw-r--r--source/gameengine/Ketsji/KX_ISceneConverter.h10
-rw-r--r--source/gameengine/Ketsji/KX_IpoConvert.cpp (renamed from source/gameengine/Converter/KX_IpoConvert.cpp)235
-rw-r--r--source/gameengine/Ketsji/KX_IpoConvert.h (renamed from source/gameengine/Converter/KX_IpoConvert.h)47
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp143
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h2
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_Light.h2
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp45
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h8
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h2
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp58
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_RayCast.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp61
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp15
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.h1
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp86
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h2
-rw-r--r--source/gameengine/Ketsji/SConscript30
-rw-r--r--source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h4
-rw-r--r--source/gameengine/Network/LoopBackNetwork/SConscript28
-rw-r--r--source/gameengine/Network/NG_NetworkDeviceInterface.h18
-rw-r--r--source/gameengine/Network/NG_NetworkMessage.h4
-rw-r--r--source/gameengine/Network/SConscript28
-rw-r--r--source/gameengine/Physics/Bullet/CMakeLists.txt6
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.cpp2
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.h2
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp145
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h42
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp45
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h6
-rw-r--r--source/gameengine/Physics/Bullet/SConscript30
-rw-r--r--source/gameengine/Physics/Dummy/CMakeLists.txt1
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp2
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h6
-rw-r--r--source/gameengine/Physics/Dummy/SConscript30
-rw-r--r--source/gameengine/Physics/common/PHY_DynamicTypes.h71
-rw-r--r--source/gameengine/Physics/common/PHY_ICharacter.h9
-rw-r--r--source/gameengine/Physics/common/PHY_IController.h10
-rw-r--r--source/gameengine/Physics/common/PHY_IGraphicController.h13
-rw-r--r--source/gameengine/Physics/common/PHY_IMotionState.h8
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h20
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h25
-rw-r--r--source/gameengine/Physics/common/PHY_IVehicle.cpp10
-rw-r--r--source/gameengine/Physics/common/PHY_IVehicle.h8
-rw-r--r--source/gameengine/Physics/common/SConscript14
-rw-r--r--source/gameengine/Rasterizer/CMakeLists.txt1
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp5
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp21
-rw-r--r--source/gameengine/Rasterizer/RAS_ICanvas.h14
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h6
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h6
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.h16
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp7
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp5
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h3
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt9
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h (renamed from source/blender/blenloader/BLO_soundfile.h)39
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp38
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h7
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp313
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h17
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp310
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h68
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp320
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h (renamed from source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h)53
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp259
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h100
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp382
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.cpp87
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.h32
-rw-r--r--source/gameengine/Rasterizer/RAS_texmatrix.cpp6
-rw-r--r--source/gameengine/Rasterizer/SConscript53
-rw-r--r--source/gameengine/SConscript29
-rw-r--r--source/gameengine/SceneGraph/SConscript27
-rw-r--r--source/gameengine/SceneGraph/SG_ParentRelation.h4
-rw-r--r--source/gameengine/VideoTexture/SConscript28
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp6
-rw-r--r--source/icons/SConscript28
-rw-r--r--source/tests/batch_import.py5
-rw-r--r--source/tests/bl_load_addons.py45
-rw-r--r--source/tests/bl_load_py_modules.py24
-rw-r--r--source/tests/bl_mesh_modifiers.py6
-rw-r--r--source/tests/bl_mesh_validate.py4
-rw-r--r--source/tests/bl_rst_completeness.py6
-rw-r--r--source/tests/bl_run_operators.py173
-rw-r--r--source/tests/check_deprecated.py4
-rw-r--r--source/tests/pep8.py8
-rw-r--r--source/tests/rna_info_dump.py2
-rw-r--r--source/tests/rst_to_doctree_mini.py2
2032 files changed, 203344 insertions, 51802 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3e1c8fec02a..b174fa2ac34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -124,16 +124,21 @@ mark_as_advanced(WITH_PYTHON_SECURITY) # some distributions see this as a secur
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)
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_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_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_PLAYER "Build Player" OFF)
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON)
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
-option(WITH_COMPOSITOR_LEGACY "Enable legacy compositor" OFF)
# GHOST Windowing Library Options
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
@@ -149,6 +154,9 @@ mark_as_advanced(WITH_HEADLESS)
option(WITH_AUDASPACE "Build with blenders audio library (only disable if you know what you're doing!)" ON)
mark_as_advanced(WITH_AUDASPACE)
+option(WITH_BOOL_COMPAT "Continue defining \"TRUE\" and \"FALSE\" until these can be replaced with \"true\" and \"false\" from stdbool.h" ON)
+mark_as_advanced(WITH_BOOL_COMPAT)
+
# (unix defaults to OpenMP On)
if((UNIX AND NOT APPLE) OR (MINGW))
@@ -235,6 +243,10 @@ option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the rayt
if(UNIX AND NOT APPLE)
option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
+ if(WITH_STATIC_LIBS)
+ option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF)
+ mark_as_advanced(WITH_BOOST_ICU)
+ endif()
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
@@ -246,7 +258,7 @@ option(WITH_CYCLES "Enable cycles Render Engine" ON)
option(WITH_CYCLES_TEST "Build cycles test application" OFF)
option(WITH_CYCLES_OSL "Build Cycles with OSL support" OFF)
option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
-set(CYCLES_CUDA_BINARIES_ARCH sm_13 sm_20 sm_21 sm_30 CACHE STRING "CUDA architectures to build binaries for")
+set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)
@@ -264,6 +276,8 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC)
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF)
mark_as_advanced(WITH_ASSERT_ABORT)
+option(WITH_BOOST "Enable features depending no boost" ON)
+
if(APPLE)
cmake_minimum_required(VERSION 2.8.8)
@@ -392,9 +406,22 @@ if(WITH_CYCLES)
set(WITH_OPENIMAGEIO ON)
endif()
-# auto enable boost for cycles, booleans, audaspace or i18n
-if(WITH_CYCLES OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
- set(WITH_BOOST ON)
+# enable boost for cycles, booleans, audaspace or i18n
+# otherwise if the user disabled
+if(NOT WITH_BOOST)
+ # Explicitly disabled. so disable all deps.
+ set(WITH_CYCLES OFF)
+ set(WITH_MOD_BOOLEAN OFF)
+ set(WITH_AUDASPACE OFF)
+ set(WITH_INTERNATIONAL OFF)
+
+ set(WITH_OPENAL OFF) # depends on AUDASPACE
+ set(WITH_GAMEENGINE OFF) # depends on AUDASPACE
+elseif(WITH_CYCLES OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
+ # Keep enabled
+else()
+ # Enabled but we don't need it
+ set(WITH_BOOST OFF)
endif()
# auto enable llvm for cycles_osl
@@ -423,6 +450,13 @@ endif()
TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
+TEST_STDBOOL_SUPPORT()
+if(HAVE_STDBOOL_H)
+ add_definitions(-DHAVE_STDBOOL_H)
+endif()
+if(WITH_BOOL_COMPAT)
+ add_definitions(-DWITH_BOOL_COMPAT)
+endif()
#-----------------------------------------------------------------------------
# Check for valid directories
@@ -644,21 +678,16 @@ if(UNIX AND NOT APPLE)
if(WITH_BOOST)
# uses in build instructions to override include and library variables
if(NOT BOOST_CUSTOM)
- # XXX No more lib dir, is this multithread stuff still needed?
if(${WITH_STATIC_LIBS})
set(Boost_USE_STATIC_LIBS ON)
endif()
- if(NOT BOOST_ROOT)
- set(Boost_USE_MULTITHREADED OFF)
- else()
- set(Boost_USE_MULTITHREADED ON)
- endif()
+ set(Boost_USE_MULTITHREADED ON)
set(__boost_packages filesystem regex system thread date_time)
if (WITH_INTERNATIONAL)
list(APPEND __boost_packages locale)
endif()
- find_package(Boost 1.34 COMPONENTS ${__boost_packages})
- if(Boost_USE_STATIC_LIBS AND Boost_USE_ICU)
+ find_package(Boost 1.48 COMPONENTS ${__boost_packages})
+ if(Boost_USE_STATIC_LIBS AND WITH_BOOST_ICU)
find_package(IcuLinux)
endif()
mark_as_advanced(Boost_DIR) # why doesnt boost do this?
@@ -792,7 +821,11 @@ if(UNIX AND NOT APPLE)
set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_X11_LIB}")
if(WITH_X11_XINPUT)
- set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}")
+ if(X11_Xinput_LIB)
+ set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}")
+ else()
+ set(WITH_X11_XINPUT OFF)
+ endif()
endif()
if(WITH_X11_XF86VMODE)
@@ -1092,14 +1125,16 @@ elseif(WIN32)
if(WITH_PYTHON)
# normally cached but not since we include them with blender
if(MSVC10)
- set(PYTHON_VERSION 3.2) # CACHE STRING)
+ set(PYTHON_VERSION 3.3) # CACHE STRING)
else()
set(PYTHON_VERSION 3.3) # CACHE STRING)
endif()
set_lib_path(PYTHON "python")
STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
- set(PYTHON_LIBRARY ${PYTHON}/lib/python${_PYTHON_VERSION_NO_DOTS}.lib) #CACHE FILEPATH
+ # Use shared libs for vc2008 and vc2010 until we actually have vc2010 libs
+ set(PYTHON_LIBRARY ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}.lib)
+ # set(PYTHON_LIBRARY ${PYTHON}/lib/python${_PYTHON_VERSION_NO_DOTS}.lib) #CACHE FILEPATH
unset(_PYTHON_VERSION_NO_DOTS)
#Shared includes for both vc2008 and vc2010
@@ -1129,11 +1164,16 @@ elseif(WIN32)
debug libboost_date_time-${BOOST_DEBUG_POSTFIX} debug libboost_filesystem-${BOOST_DEBUG_POSTFIX}
debug libboost_regex-${BOOST_DEBUG_POSTFIX}
debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX})
+ if(WITH_CYCLES_OSL)
+ set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
+ optimized libboost_wave-${BOOST_POSTFIX}
+ debug libboost_wave-${BOOST_DEBUG_POSTFIX})
+ endif()
if(WITH_INTERNATIONAL)
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
optimized libboost_locale-${BOOST_POSTFIX}
debug libboost_locale-${BOOST_DEBUG_POSTFIX})
- endif(WITH_INTERNATIONAL)
+ endif()
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
endif()
@@ -1319,6 +1359,11 @@ elseif(WIN32)
optimized boost_locale-${BOOST_POSTFIX}
debug boost_locale-${BOOST_DEBUG_POSTFIX})
endif()
+ if(WITH_CYCLES_OSL)
+ set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
+ optimized boost_wave-${BOOST_POSTFIX}
+ debug boost_wave-${BOOST_DEBUG_POSTFIX})
+ endif()
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB -DBOOST_THREAD_USE_LIB ")
endif()
@@ -1420,11 +1465,10 @@ elseif(APPLE)
endif()
if(WITH_PYTHON)
- if(NOT WITH_PYTHON_MODULE)
- # we use precompiled libraries for py 3.3 and up by default
-
+ # we use precompiled libraries for py 3.3 and up by default
+ set(PYTHON_VERSION 3.3)
+ if(NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
# normally cached but not since we include them with blender
- set(PYTHON_VERSION 3.3)
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}m")
# set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet
set(PYTHON_LIBRARY python${PYTHON_VERSION}m)
@@ -1432,13 +1476,10 @@ elseif(APPLE)
# set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
else()
# module must be compiled against Python framework
-
- # normally cached but not since we include them with blender
- set(PYTHON_VERSION 3.2)
set(PYTHON_INCLUDE_DIR "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/include/python${PYTHON_VERSION}m")
set(PYTHON_BINARY "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/bin/python${PYTHON_VERSION}")
#set(PYTHON_LIBRARY python${PYTHON_VERSION})
- set(PYTHON_LIBPATH "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config-3.2m")
+ set(PYTHON_LIBPATH "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config-${PYTHON_VERSION}m")
#set(PYTHON_LINKFLAGS "-u _PyMac_Error -framework Python") # won't build with this enabled
endif()
@@ -1521,7 +1562,8 @@ elseif(APPLE)
endif()
if(WITH_INPUT_NDOF)
- set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient")
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework 3DconnexionClient")
+ set(NDOF_INCLUDE_DIRS /Library/Frameworks/3DconnexionClient.framework/Headers )
endif()
endif()
@@ -1535,8 +1577,8 @@ elseif(APPLE)
set(WITH_INPUT_NDOF OFF) # unsupported
endif()
- if(WITH_PYTHON_MODULE)
- set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/python")# force cmake to link right framework
+ if(WITH_PYTHON_MODULE OR WITH_PYTHON_FRAMEWORK)
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/Python")# force cmake to link right framework
endif()
if(WITH_OPENCOLLADA)
@@ -1837,6 +1879,20 @@ else()
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include")
endif()
+
+#-----------------------------------------------------------------------------
+# Configure Bullet
+
+if(WITH_BULLET AND WITH_SYSTEM_BULLET)
+ find_package(Bullet)
+ if(NOT BULLET_FOUND)
+ set(WITH_BULLET OFF)
+ endif()
+else()
+ set(BULLET_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/bullet2/src")
+ # set(BULLET_LIBRARIES "")
+endif()
+
#-----------------------------------------------------------------------------
# Configure Python.
@@ -2130,6 +2186,9 @@ if(FIRST_RUN)
info_cfg_option(WITH_PYTHON_INSTALL_NUMPY)
info_cfg_option(WITH_PYTHON_MODULE)
info_cfg_option(WITH_PYTHON_SAFETY)
+ if(APPLE)
+ info_cfg_option(WITH_PYTHON_FRAMEWORK)
+ endif()
info_cfg_text("Modifiers:")
info_cfg_option(WITH_MOD_BOOLEAN)
@@ -2137,6 +2196,9 @@ if(FIRST_RUN)
info_cfg_option(WITH_MOD_FLUID)
info_cfg_option(WITH_MOD_OCEANSIM)
+ # debug
+ message(STATUS "HAVE_STDBOOL_H = ${HAVE_STDBOOL_H}")
+
info_cfg_text("")
message("${_config_msg}")
diff --git a/SConstruct b/SConstruct
index c2bae0459ca..3f17c1c2887 100644
--- a/SConstruct
+++ b/SConstruct
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# All rights reserved.
@@ -275,6 +275,11 @@ if 'blenderlite' in B.targets:
if k not in B.arguments:
env[k] = v
+if 'cudakernels' in B.targets:
+ env['WITH_BF_CYCLES'] = True
+ env['WITH_BF_CYCLES_CUDA_BINARIES'] = True
+ env['WITH_BF_PYTHON'] = False
+
# Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY and JAckOSX detection for OSX
if env['OURPLATFORM']=='darwin':
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
@@ -294,7 +299,8 @@ if env['OURPLATFORM']=='darwin':
print "3D_CONNEXION_CLIENT_LIBRARY not found, disabling WITH_BF_3DMOUSE" # avoid build errors !
env['WITH_BF_3DMOUSE'] = 0
else:
- env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','3DconnexionClient'])
+ env.Append(LINKFLAGS=['-F/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','3DconnexionClient'])
+ env['BF_3DMOUSE_INC'] = '/Library/Frameworks/3DconnexionClient.framework/Headers'
# for now, Mac builders must download and install the JackOSX framework
# necessary header file lives here when installed:
@@ -304,7 +310,7 @@ if env['OURPLATFORM']=='darwin':
print "JackOSX install not found, disabling WITH_BF_JACK" # avoid build errors !
env['WITH_BF_JACK'] = 0
else:
- env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','Jackmp'])
+ env.Append(LINKFLAGS=['-L/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','Jackmp'])
if env['WITH_BF_CYCLES_OSL'] == 1:
OSX_OSL_LIBPATH = Dir(env.subst(env['BF_OSL_LIBPATH'])).abspath
@@ -372,9 +378,10 @@ if btools.ENDIAN == "big":
else:
env['CPPFLAGS'].append('-D__LITTLE_ENDIAN__')
-# TODO, make optional
+# TODO, make optional (as with CMake)
env['CPPFLAGS'].append('-DWITH_AUDASPACE')
env['CPPFLAGS'].append('-DWITH_AVI')
+env['CPPFLAGS'].append('-DWITH_BOOL_COMPAT')
# lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
B.root_build_dir = env['BF_BUILDDIR']
@@ -441,11 +448,12 @@ if env['WITH_BF_PYTHON']:
found_pyconfig_h = True
if not (found_python_h and found_pyconfig_h):
- print("\nMissing: Python.h and/or pyconfig.h in\"" + env.subst('${BF_PYTHON_INC}') + "\",\n"
- " Set 'BF_PYTHON_INC' to point "
- "to valid python include path(s).\n Containing "
- "Python.h and pyconfig.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
+ print("""\nMissing: Python.h and/or pyconfig.h in "%s"
+ Set 'BF_PYTHON_INC' to point to valid include path(s),
+ containing Python.h and pyconfig.h for Python version "%s".
+ Example: python scons/scons.py BF_PYTHON_INC=../Python/include
+ """ % (env.subst('${BF_PYTHON_INC}'), env.subst('${BF_PYTHON_VERSION}')))
Exit()
@@ -509,61 +517,89 @@ def data_to_c_simple(FILE_FROM):
data_to_c(FILE_FROM, FILE_TO, VAR_NAME)
-data_to_c("source/blender/compositor/operations/COM_OpenCLKernels.cl",
- B.root_build_dir + "data_headers/COM_OpenCLKernels.cl.h",
- "datatoc_COM_OpenCLKernels_cl")
-
-data_to_c_simple("release/datafiles/startup.blend")
-data_to_c_simple("release/datafiles/preview.blend")
-
-# --- glsl ---
-data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
-data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
-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_material.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")
-
-# --- blender ---
-data_to_c_simple("release/datafiles/bfont.pfb")
-data_to_c_simple("release/datafiles/bfont.ttf")
-data_to_c_simple("release/datafiles/bmonofont.ttf")
-
-data_to_c_simple("release/datafiles/splash.png")
-data_to_c_simple("release/datafiles/blender_icons.png")
-data_to_c_simple("release/datafiles/prvicons.png")
-
-data_to_c_simple("release/datafiles/brushicons/add.png")
-data_to_c_simple("release/datafiles/brushicons/blob.png")
-data_to_c_simple("release/datafiles/brushicons/blur.png")
-data_to_c_simple("release/datafiles/brushicons/clay.png")
-data_to_c_simple("release/datafiles/brushicons/claystrips.png")
-data_to_c_simple("release/datafiles/brushicons/clone.png")
-data_to_c_simple("release/datafiles/brushicons/crease.png")
-data_to_c_simple("release/datafiles/brushicons/darken.png")
-data_to_c_simple("release/datafiles/brushicons/draw.png")
-data_to_c_simple("release/datafiles/brushicons/fill.png")
-data_to_c_simple("release/datafiles/brushicons/flatten.png")
-data_to_c_simple("release/datafiles/brushicons/grab.png")
-data_to_c_simple("release/datafiles/brushicons/inflate.png")
-data_to_c_simple("release/datafiles/brushicons/layer.png")
-data_to_c_simple("release/datafiles/brushicons/lighten.png")
-data_to_c_simple("release/datafiles/brushicons/mask.png")
-data_to_c_simple("release/datafiles/brushicons/mix.png")
-data_to_c_simple("release/datafiles/brushicons/multiply.png")
-data_to_c_simple("release/datafiles/brushicons/nudge.png")
-data_to_c_simple("release/datafiles/brushicons/pinch.png")
-data_to_c_simple("release/datafiles/brushicons/scrape.png")
-data_to_c_simple("release/datafiles/brushicons/smear.png")
-data_to_c_simple("release/datafiles/brushicons/smooth.png")
-data_to_c_simple("release/datafiles/brushicons/snake_hook.png")
-data_to_c_simple("release/datafiles/brushicons/soften.png")
-data_to_c_simple("release/datafiles/brushicons/subtract.png")
-data_to_c_simple("release/datafiles/brushicons/texdraw.png")
-data_to_c_simple("release/datafiles/brushicons/thumb.png")
-data_to_c_simple("release/datafiles/brushicons/twist.png")
-data_to_c_simple("release/datafiles/brushicons/vertexdraw.png")
+if B.targets != ['cudakernels']:
+ data_to_c("source/blender/compositor/operations/COM_OpenCLKernels.cl",
+ B.root_build_dir + "data_headers/COM_OpenCLKernels.cl.h",
+ "datatoc_COM_OpenCLKernels_cl")
+
+ data_to_c_simple("release/datafiles/startup.blend")
+ data_to_c_simple("release/datafiles/preview.blend")
+ data_to_c_simple("release/datafiles/preview_cycles.blend")
+
+ # --- glsl ---
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
+ 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_material.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")
+
+ # --- blender ---
+ data_to_c_simple("release/datafiles/bfont.pfb")
+ data_to_c_simple("release/datafiles/bfont.ttf")
+ data_to_c_simple("release/datafiles/bmonofont.ttf")
+
+ data_to_c_simple("release/datafiles/splash.png")
+ data_to_c_simple("release/datafiles/blender_icons16.png")
+ data_to_c_simple("release/datafiles/blender_icons32.png")
+ data_to_c_simple("release/datafiles/prvicons.png")
+
+ data_to_c_simple("release/datafiles/brushicons/add.png")
+ data_to_c_simple("release/datafiles/brushicons/blob.png")
+ data_to_c_simple("release/datafiles/brushicons/blur.png")
+ data_to_c_simple("release/datafiles/brushicons/clay.png")
+ data_to_c_simple("release/datafiles/brushicons/claystrips.png")
+ data_to_c_simple("release/datafiles/brushicons/clone.png")
+ data_to_c_simple("release/datafiles/brushicons/crease.png")
+ data_to_c_simple("release/datafiles/brushicons/darken.png")
+ data_to_c_simple("release/datafiles/brushicons/draw.png")
+ data_to_c_simple("release/datafiles/brushicons/fill.png")
+ data_to_c_simple("release/datafiles/brushicons/flatten.png")
+ data_to_c_simple("release/datafiles/brushicons/grab.png")
+ data_to_c_simple("release/datafiles/brushicons/inflate.png")
+ data_to_c_simple("release/datafiles/brushicons/layer.png")
+ data_to_c_simple("release/datafiles/brushicons/lighten.png")
+ data_to_c_simple("release/datafiles/brushicons/mask.png")
+ data_to_c_simple("release/datafiles/brushicons/mix.png")
+ data_to_c_simple("release/datafiles/brushicons/multiply.png")
+ data_to_c_simple("release/datafiles/brushicons/nudge.png")
+ data_to_c_simple("release/datafiles/brushicons/pinch.png")
+ data_to_c_simple("release/datafiles/brushicons/scrape.png")
+ data_to_c_simple("release/datafiles/brushicons/smear.png")
+ data_to_c_simple("release/datafiles/brushicons/smooth.png")
+ data_to_c_simple("release/datafiles/brushicons/snake_hook.png")
+ data_to_c_simple("release/datafiles/brushicons/soften.png")
+ data_to_c_simple("release/datafiles/brushicons/subtract.png")
+ data_to_c_simple("release/datafiles/brushicons/texdraw.png")
+ data_to_c_simple("release/datafiles/brushicons/thumb.png")
+ data_to_c_simple("release/datafiles/brushicons/twist.png")
+ data_to_c_simple("release/datafiles/brushicons/vertexdraw.png")
+
+ data_to_c_simple("release/datafiles/matcaps/mc01.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc02.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc03.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc04.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc05.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc06.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc07.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc08.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc09.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc10.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc11.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc12.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc13.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc14.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc15.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc16.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc17.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc18.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc19.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc20.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc21.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc22.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc23.jpg")
+ data_to_c_simple("release/datafiles/matcaps/mc24.jpg")
##### END DATAFILES ##########
@@ -647,6 +683,7 @@ datafileslist = []
datafilestargetlist = []
dottargetlist = []
scriptinstall = []
+cubininstall = []
if env['OURPLATFORM']!='darwin':
dotblenderinstall = []
@@ -736,29 +773,30 @@ if env['OURPLATFORM']!='darwin':
source=['intern/cycles/doc/license/'+s for s in source]
scriptinstall.append(env.Install(dir=dir,source=source))
- # cuda binaries
- if env['WITH_BF_CYCLES_CUDA_BINARIES']:
- dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib')
- for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
- kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel')
- cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
- scriptinstall.append(env.Install(dir=dir,source=cubin_file))
+ if env['WITH_BF_CYCLES']:
+ # cuda binaries
+ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib')
+ for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
+ kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel')
+ cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
+ cubininstall.append(env.Install(dir=dir,source=cubin_file))
- # osl shaders
- if env['WITH_BF_CYCLES_OSL']:
- dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader')
+ # osl shaders
+ if env['WITH_BF_CYCLES_OSL']:
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader')
- osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path
- oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders')
+ osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path
+ oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders')
- headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split()
- source=['intern/cycles/kernel/shaders/'+s for s in headers]
- scriptinstall.append(env.Install(dir=dir,source=source))
+ headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split()
+ source=['intern/cycles/kernel/shaders/'+s for s in headers]
+ scriptinstall.append(env.Install(dir=dir,source=source))
- for f in os.listdir(osl_source_dir):
- if f.endswith('.osl'):
- oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso'))
- scriptinstall.append(env.Install(dir=dir,source=oso_file))
+ for f in os.listdir(osl_source_dir):
+ if f.endswith('.osl'):
+ oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso'))
+ scriptinstall.append(env.Install(dir=dir,source=oso_file))
if env['WITH_BF_OCIO']:
colormanagement = os.path.join('release', 'datafiles', 'colormanagement')
@@ -827,6 +865,8 @@ if env['OURPLATFORM']=='linux':
td, tf = os.path.split(targetdir)
iconinstall.append(env.Install(dir=td, source=srcfile))
+ scriptinstall.append(env.Install(dir=env['BF_INSTALLDIR'], source='release/bin/blender-thumbnailer.py'))
+
# dlls for linuxcross
# TODO - add more libs, for now this lets blenderlite run
if env['OURPLATFORM']=='linuxcross':
@@ -853,9 +893,9 @@ textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
if env['OURPLATFORM']=='darwin':
allinstall = [blenderinstall, textinstall]
elif env['OURPLATFORM']=='linux':
- allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall]
+ allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall, cubininstall]
else:
- allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall]
+ allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, cubininstall]
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources = []
@@ -985,6 +1025,20 @@ buildslave_alias = env.Alias('buildslave', buildslave_cmd)
Depends(buildslave_cmd, allinstall)
+cudakernels_action = env.Action(btools.cudakernels, btools.cudakernels_print)
+cudakernels_cmd = env.Command('cudakernels_exec', None, cudakernels_action)
+cudakernels_alias = env.Alias('cudakernels', cudakernels_cmd)
+
+cudakernel_dir = os.path.join(os.path.abspath(os.path.normpath(B.root_build_dir)), 'intern/cycles/kernel')
+cuda_kernels = []
+
+for x in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
+ cubin = os.path.join(cudakernel_dir, 'kernel_' + x + '.cubin')
+ cuda_kernels.append(cubin)
+
+Depends(cudakernels_cmd, cuda_kernels)
+Depends(cudakernels_cmd, cubininstall)
+
Default(B.program_list)
if not env['WITHOUT_BF_INSTALL']:
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 072e999d827..490c976655d 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -1,16 +1,37 @@
-#!/bin/bash
+#!/usr/bin/env bash
+# ##### 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 #####
+
+# A shell script installing/building all needed dependencies to build Blender, for some Linux distributions.
# Parse command line!
ARGS=$( \
getopt \
-o s:i:t:h \
---long source:,install:,threads:,help,with-all,with-osl,all-static,force-all,force-python,\
-force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-ffmpeg,\
-skip-python,skip-boost,skip-ocio,skip-oiio,skip-llvm,skip-osl,skip-ffmpeg \
+--long source:,install:,threads:,help,with-all,with-osl,with-opencollada,all-static,force-all,\
+force-python,force-numpy,force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-opencollada,\
+force-ffmpeg,skip-python,skip-numpy,skip-boost,skip-ocio,skip-oiio,skip-llvm,skip-osl,skip-ffmpeg,\
+skip-opencollada \
-- "$@" \
)
DISTRO=""
+RPM=""
SRC="$HOME/src/blender-deps"
INST="/opt/lib"
CWD=$PWD
@@ -21,6 +42,9 @@ WITH_ALL=false
# Do not yet enable osl, use --with-osl (or --with-all) option to try it.
WITH_OSL=false
+# Do not yet enable opencollada, use --with-opencollada (or --with-all) option to try it.
+WITH_OPENCOLLADA=false
+
# Try to link everything statically. Use this to produce portable versions of blender.
ALL_STATIC=false
@@ -37,8 +61,12 @@ or use --source/--install options, if you want to use other paths!
Number of threads for building: \$THREADS (automatically detected, use --threads=<nbr> to override it).
Full install: \$WITH_ALL (use --with-all option to enable it).
Building OSL: \$WITH_OSL (use --with-osl option to enable it).
+Building OpenCOLLADA: \$WITH_OPENCOLLADA (use --with-opencollada option to enable it).
All static linking: \$ALL_STATIC (use --all-static option to enable it).
+Example:
+Full install without OpenCOLLADA: --with-all --skip-opencollada
+
Use --help to show all available options!\""
ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
@@ -64,6 +92,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
Try to install or build the OpenShadingLanguage libraries (and their dependencies).
Still experimental!
+ --with-opencollada
+ Build and install the OpenCOLLADA libraries.
+
--all-static
Build libraries as statically as possible, to create static builds of Blender.
@@ -73,6 +104,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--force-python
Force the rebuild of Python.
+ --force-numpy
+ Force the rebuild of NumPy.
+
--force-boost
Force the rebuild of Boost.
@@ -88,6 +122,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--force-osl
Force the rebuild of OpenShadingLanguage.
+ --force-opencollada
+ Force the rebuild of OpenCOLLADA.
+
--force-ffmpeg
Force the rebuild of FFMpeg.
@@ -101,6 +138,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--skip-python
Unconditionally skip Python installation/building.
+ --skip-numpy
+ Unconditionally skip NumPy installation/building.
+
--skip-boost
Unconditionally skip Boost installation/building.
@@ -116,6 +156,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--skip-osl
Unconditionally skip OpenShadingLanguage installation/building.
+ --skip-opencollada
+ Unconditionally skip OpenCOLLADA installation/building.
+
--skip-ffmpeg
Unconditionally skip FFMpeg installation/building.\""
@@ -125,6 +168,13 @@ PYTHON_SOURCE="http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSI
PYTHON_FORCE_REBUILD=false
PYTHON_SKIP=false
+#Could not get numpy-1.6.2 to compile with python-3.3
+NUMPY_VERSION="1.7.0rc1"
+NUMPY_VERSION_MIN="1.7"
+NUMPY_SOURCE="http://sourceforge.net/projects/numpy/files/NumPy/$NUMPY_VERSION/numpy-$NUMPY_VERSION.tar.gz"
+NUMPY_FORCE_REBUILD=false
+NUMPY_SKIP=false
+
BOOST_VERSION="1.51.0"
_boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'`
BOOST_SOURCE="http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION/boost_$_boost_version_nodots.tar.bz2/download"
@@ -138,7 +188,7 @@ OCIO_VERSION_MIN="1.0"
OCIO_FORCE_REBUILD=false
OCIO_SKIP=false
-OIIO_VERSION="1.1.1"
+OIIO_VERSION="1.1.7"
OIIO_SOURCE="https://github.com/OpenImageIO/oiio/tarball/Release-$OIIO_VERSION"
OIIO_VERSION_MIN="1.1"
OIIO_FORCE_REBUILD=false
@@ -153,11 +203,17 @@ LLVM_FORCE_REBUILD=false
LLVM_SKIP=false
# OSL needs to be compiled for now!
-OSL_VERSION="1.2.0"
-OSL_SOURCE="https://github.com/mont29/OpenShadingLanguage/archive/blender-fixes.tar.gz"
+OSL_VERSION="1.3.0"
+OSL_SOURCE="https://github.com/imageworks/OpenShadingLanguage/archive/Release-1.3.0.tar.gz"
OSL_FORCE_REBUILD=false
OSL_SKIP=false
+# Version??
+OPENCOLLADA_VERSION="1.3"
+OPENCOLLADA_SOURCE="https://github.com/KhronosGroup/OpenCOLLADA.git"
+OPENCOLLADA_FORCE_REBUILD=false
+OPENCOLLADA_SKIP=false
+
FFMPEG_VERSION="1.0"
FFMPEG_SOURCE="http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2"
FFMPEG_VERSION_MIN="0.7.6"
@@ -236,22 +292,30 @@ while true; do
--with-osl)
WITH_OSL=true; shift; continue
;;
+ --with-opencollada)
+ WITH_OPENCOLLADA=true; shift; continue
+ ;;
--all-static)
ALL_STATIC=true; shift; continue
;;
--force-all)
PYTHON_FORCE_REBUILD=true
+ NUMPY_FORCE_REBUILD=true
BOOST_FORCE_REBUILD=true
OCIO_FORCE_REBUILD=true
OIIO_FORCE_REBUILD=true
LLVM_FORCE_REBUILD=true
OSL_FORCE_REBUILD=true
+ OPENCOLLADA_FORCE_REBUILD=true
FFMPEG_FORCE_REBUILD=true
shift; continue
;;
--force-python)
PYTHON_FORCE_REBUILD=true; shift; continue
;;
+ --force-numpy)
+ NUMPY_FORCE_REBUILD=true; shift; continue
+ ;;
--force-boost)
BOOST_FORCE_REBUILD=true; shift; continue
;;
@@ -267,12 +331,18 @@ while true; do
--force-osl)
OSL_FORCE_REBUILD=true; shift; continue
;;
+ --force-opencollada)
+ OPENCOLLADA_FORCE_REBUILD=true; shift; continue
+ ;;
--force-ffmpeg)
FFMPEG_FORCE_REBUILD=true; shift; continue
;;
--skip-python)
PYTHON_SKIP=true; shift; continue
;;
+ --skip-numpy)
+ NUMPY_SKIP=true; shift; continue
+ ;;
--skip-boost)
BOOST_SKIP=true; shift; continue
;;
@@ -288,6 +358,9 @@ while true; do
--skip-osl)
OSL_SKIP=true; shift; continue
;;
+ --skip-opencollada)
+ OPENCOLLADA_SKIP=true; shift; continue
+ ;;
--skip-ffmpeg)
FFMPEG_SKIP=true; shift; continue
;;
@@ -308,6 +381,7 @@ done
if $WITH_ALL; then
WITH_OSL=true
+ WITH_OPENCOLLADA=true
fi
# Return 0 if $1 = $2 (i.e. 1.01.0 = 1.1, but 1.1.1 != 1.1), else 1.
@@ -397,10 +471,22 @@ version_match() {
detect_distro() {
if [ -f /etc/debian_version ]; then
DISTRO="DEB"
- elif [ -f /etc/redhat-release ]; then
+ elif [ -f /etc/redhat-release -o /etc/SuSE-release ]; then
DISTRO="RPM"
+ elif [ -f /etc/arch-release ]; then
+ DISTRO="ARCH"
+ fi
+}
+
+rpm_flavour() {
+ if [ -f /etc/redhat-release ]; then
+ if [ "`grep '6\.' /etc/redhat-release`" ]; then
+ RPM="RHEL"
+ else
+ RPM="FEDORA"
+ fi
elif [ -f /etc/SuSE-release ]; then
- DISTRO="SUSE"
+ RPM="SUSE"
fi
}
@@ -483,6 +569,56 @@ compile_Python() {
fi
}
+compile_Numpy() {
+ # To be changed each time we make edits that would modify the compiled result!
+ py_magic=0
+
+ _src=$SRC/numpy-$NUMPY_VERSION
+ _inst=$INST/numpy-$NUMPY_VERSION
+ _python=$INST/python-$PYTHON_VERSION
+ _site=lib/python3.3/site-packages
+
+ # Clean install if needed!
+ magic_compile_check numpy-$NUMPY_VERSION $py_magic
+ if [ $? -eq 1 -o $NUMPY_FORCE_REBUILD == true ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building Numpy-$NUMPY_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ mkdir -p $SRC
+ wget -c $NUMPY_SOURCE -O $_src.tar.gz
+
+ INFO "Unpacking Numpy-$NUMPY_VERSION"
+ tar -C $SRC -xf $_src.tar.gz
+ fi
+
+ cd $_src
+
+ $_python/bin/python3 setup.py install --prefix=$_inst
+
+ if [ -d $_inst ]; then
+ rm -f $_python/$_site/numpy
+ ln -s $_inst/$_site/numpy $_python/$_site/numpy
+ else
+ ERROR "Numpy-$NUMPY_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set numpy-$NUMPY_VERSION $py_magic
+
+ cd $CWD
+ INFO "Done compiling Numpy-$NUMPY_VERSION!"
+ else
+ INFO "Own Numpy-$NUMPY_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, use the --force-numpy option."
+ fi
+}
+
compile_Boost() {
# To be changed each time we make edits that would modify the compiled result!
boost_magic=7
@@ -620,7 +756,7 @@ compile_OCIO() {
compile_OIIO() {
# To be changed each time we make edits that would modify the compiled result!
- oiio_magic=6
+ oiio_magic=7
_src=$SRC/OpenImageIO-$OIIO_VERSION
_inst=$INST/oiio-$OIIO_VERSION
@@ -644,27 +780,6 @@ compile_OIIO() {
tar -C $SRC --transform "s,(.*/?)OpenImageIO-oiio[^/]*(.*),\1OpenImageIO-$OIIO_VERSION\2,x" \
-xf $_src.tar.gz
- cd $_src
-
- # XXX Ugly patching hack!
- cat << EOF | patch -p1
-diff --git a/src/libutil/SHA1.cpp b/src/libutil/SHA1.cpp
-index b9e6c8b..c761185 100644
---- a/src/libutil/SHA1.cpp
-+++ b/src/libutil/SHA1.cpp
-@@ -8,9 +8,9 @@
-
- // If compiling with MFC, you might want to add #include "StdAfx.h"
-
-+#include "SHA1.h"
- #include "hash.h"
- #include "dassert.h"
--#include "SHA1.h"
-
- #ifdef SHA1_UTILITY_FUNCTIONS
- #define SHA1_MAX_FILE_BUFFER 8000
-EOF
-
cd $CWD
fi
@@ -681,6 +796,11 @@ EOF
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D BUILDSTATIC=ON"
+
+ # Optional tests and cmd tools
+ cmake_d="$cmake_d -D USE_QT=OFF"
+ cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=OFF"
+ cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF"
# linking statically could give issues on Debian/Ubuntu (and probably other distros
# which doesn't like static linking) when linking shared oiio library due to missing
@@ -797,6 +917,7 @@ EOF
cmake_d="-D CMAKE_BUILD_TYPE=Release"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D LLVM_ENABLE_FFI=ON"
+ cmake_d="$cmake_d -D LLVM_TARGETS_TO_BUILD=X86"
if [ -d $_FFI_INCLUDE_DIR ]; then
cmake_d="$cmake_d -D FFI_INCLUDE_DIR=$_FFI_INCLUDE_DIR"
@@ -876,6 +997,7 @@ compile_OSL() {
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D BUILDSTATIC=ON"
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
+ cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
if [ -d $INST/boost ]; then
cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON"
@@ -919,6 +1041,70 @@ compile_OSL() {
fi
}
+compile_OpenCOLLADA() {
+ # To be changed each time we make edits that would modify the compiled results!
+ opencollada_magic=5
+
+ _src=$SRC/OpenCOLLADA-$OPENCOLLADA_VERSION
+ _inst=$INST/opencollada-$OPENCOLLADA_VERSION
+
+ # Clean install if needed!
+ magic_compile_check opencollada-$OPENCOLLADA_VERSION $opencollada_magic
+ if [ $? -eq 1 -o $OPENCOLLADA_FORCE_REBUILD == true ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building OpenCOLLADA-$OPENCOLLADA_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ mkdir -p $SRC
+ git clone $OPENCOLLADA_SOURCE $_src
+ fi
+
+ cd $_src
+
+ # XXX For now, always update from latest repo...
+ git pull origin
+
+ # Always refresh the whole build!
+ if [ -d build ]; then
+ rm -rf build
+ fi
+ mkdir build
+ cd build
+
+ cmake_d="-D CMAKE_BUILD_TYPE=Release"
+ cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
+ cmake_d="$cmake_d -D USE_EXPAT=OFF"
+ cmake_d="$cmake_d -D USE_LIBXML=ON"
+ cmake_d="$cmake_d -D USE_STATIC=ON"
+
+ cmake $cmake_d ../
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/opencollada
+ ln -s opencollada-$OPENCOLLADA_VERSION $INST/opencollada
+ else
+ ERROR "OpenCOLLADA-$OPENCOLLADA_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set opencollada-$OPENCOLLADA_VERSION $opencollada_magic
+
+ cd $CWD
+ INFO "Done compiling OpenCOLLADA-$OPENCOLLADA_VERSION!"
+ else
+ INFO "Own OpenCOLLADA-$OPENCOLLADA_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, use the --force-opencollada option."
+ fi
+}
+
compile_FFmpeg() {
# To be changed each time we make edits that would modify the compiled result!
ffmpeg_magic=3
@@ -991,9 +1177,9 @@ compile_FFmpeg() {
--enable-avfilter --disable-vdpau \
--disable-bzlib --disable-libgsm --disable-libspeex \
--enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \
- --disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
- --disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \
- --disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
+ --disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
+ --disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \
+ --disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
--disable-outdev=alsa --disable-indev=sdl --disable-indev=alsa --disable-indev=jack \
--disable-indev=lavfi $extra
@@ -1018,6 +1204,8 @@ compile_FFmpeg() {
fi
}
+
+
get_package_version_DEB() {
dpkg-query -W -f '${Version}' $1 | sed -r 's/.*:\s*([0-9]+:)(([0-9]+\.?)+).*/\2/'
}
@@ -1055,7 +1243,7 @@ check_package_version_ge_DEB() {
}
install_packages_DEB() {
- sudo apt-get install -y $@
+ sudo apt-get install -y --force-yes $@
if [ $? -ge 1 ]; then
ERROR "apt-get failed to install requested packages, exiting."
exit 1
@@ -1069,6 +1257,9 @@ install_DEB() {
INFO "`eval _echo "$COMMON_INFO"`"
INFO ""
+ read -p "Do you want to continue (Y/n)?"
+ [ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" != "y" ] && exit
+
if [ ! -z "`cat /etc/debian_version | grep ^6`" ]; then
if [ -z "`cat /etc/apt/sources.list | grep backports.debian.org`" ]; then
INFO "Looks like you're using Debian Squeeze which does have broken CMake"
@@ -1094,27 +1285,37 @@ install_DEB() {
fi
sudo apt-get update
-# XXX Why in hell? Let's let this stuff to the user's responsability!!!
-# sudo apt-get -y upgrade
# These libs should always be available in debian/ubuntu official repository...
OPENJPEG_DEV="libopenjpeg-dev"
- SCHRO_DEV="libschroedinger-dev"
VORBIS_DEV="libvorbis-dev"
THEORA_DEV="libtheora-dev"
- _packages="gawk cmake scons build-essential libjpeg-dev libpng-dev libtiff-dev \
+ _packages="gawk cmake cmake-curses-gui scons build-essential libjpeg-dev libpng-dev \
libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev \
libncurses5-dev libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV \
- libopenexr-dev libopenal-dev libglew-dev yasm $THEORA_DEV \
- $VORBIS_DEV libsdl1.2-dev libfftw3-dev python-dev patch bzip2"
+ libopenexr-dev libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV \
+ libsdl1.2-dev libfftw3-dev patch bzip2"
+
OPENJPEG_USE=true
VORBIS_USE=true
THEORA_USE=true
+ # Install newest libtiff-dev in debian/ubuntu.
+ TIFF="libtiff5"
+ check_package_DEB $TIFF
+ if [ $? -eq 0 ]; then
+ _packages="$_packages $TIFF-dev"
+ else
+ TIFF="libtiff"
+ check_package_DEB $TIFF
+ if [ $? -eq 0 ]; then
+ _packages="$_packages $TIFF-dev"
+ fi
+ fi
+
if $WITH_ALL; then
- _packages="$_packages $SCHRO_DEV libjack0 libjack-dev"
- SCHRO_USE=true
+ _packages="$_packages libspnav-dev libjack-dev"
fi
INFO ""
@@ -1131,6 +1332,7 @@ install_DEB() {
if $WITH_ALL; then
INFO ""
# Grmpf, debian is libxvidcore-dev and ubuntu libxvidcore4-dev!
+ # Note: not since ubuntu 10.04
XVID_DEV="libxvidcore-dev"
check_package_DEB $XVID_DEV
if [ $? -eq 0 ]; then
@@ -1162,9 +1364,11 @@ install_DEB() {
fi
INFO ""
- check_package_DEB libspnav-dev
+ SCHRO_DEV="libschroedinger-dev"
+ check_package_DEB $SCHRO_DEV
if [ $? -eq 0 ]; then
- install_packages_DEB libspnav-dev
+ install_packages_DEB $SCHRO_DEV
+ SCHRO_USE=true
fi
fi
@@ -1172,11 +1376,28 @@ install_DEB() {
if $PYTHON_SKIP; then
INFO "WARNING! Skipping Python installation, as requested..."
else
- check_package_DEB python3.3-dev
+ check_package_DEB python$PYTHON_VERSION_MIN-dev
if [ $? -eq 0 ]; then
- install_packages_DEB python3.3-dev
+ install_packages_DEB python$PYTHON_VERSION_MIN-dev
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ check_package_DEB python$PYTHON_VERSION_MIN-numpy
+ if [ $? -eq 0 ]; then
+ install_packages_DEB python$PYTHON_VERSION_MIN-numpy
+ else
+ INFO "WARNING! Sorry, using python package but no numpy package available!"
+ fi
+ fi
else
compile_Python
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ compile_Numpy
+ fi
fi
fi
@@ -1236,17 +1457,19 @@ install_DEB() {
INFO ""
check_package_DEB llvm-$LLVM_VERSION-dev
if [ $? -eq 0 ]; then
- install_packages_DEB llvm-$LLVM_VERSION-dev
+ install_packages_DEB llvm-$LLVM_VERSION-dev clang
have_llvm=true
LLVM_VERSION_FOUND=$LLVM_VERSION
else
check_package_DEB llvm-$LLVM_VERSION_MIN-dev
if [ $? -eq 0 ]; then
- install_packages_DEB llvm-$LLVM_VERSION_MIN-dev
+ install_packages_DEB llvm-$LLVM_VERSION_MIN-dev clang
have_llvm=true
LLVM_VERSION_FOUND=$LLVM_VERSION_MIN
else
install_packages_DEB libffi-dev
+ # LLVM can't find the debian ffi header dir
+ _FFI_INCLUDE_DIR=`dpkg -L libffi-dev | grep -e ".*/ffi.h" | sed -r 's/(.*)\/ffi.h/\1/'`
INFO ""
compile_LLVM
have_llvm=true
@@ -1256,12 +1479,11 @@ install_DEB() {
fi
if $OSL_SKIP; then
- INFO ""
INFO "WARNING! Skipping OpenShadingLanguage installation, as requested..."
else
if $have_llvm; then
INFO ""
- install_packages_DEB clang flex bison libtbb-dev git
+ install_packages_DEB flex bison libtbb-dev git
# No package currently!
INFO ""
compile_OSL
@@ -1269,6 +1491,19 @@ install_DEB() {
fi
fi
+ if $WITH_OPENCOLLADA; then
+ if $OPENCOLLADA_SKIP; then
+ INFO "WARNING! Skipping OpenCOLLADA installation, as requested..."
+ else
+ INFO ""
+ install_packages_DEB git libpcre3-dev libxml2-dev
+ # Find path to libxml shared lib...
+ _XML2_LIB=`dpkg -L libxml2-dev | grep -e ".*/libxml2.so"`
+ # No package
+ INFO ""
+ compile_OpenCOLLADA
+ fi
+ fi
INFO ""
if $FFMPEG_SKIP; then
@@ -1293,12 +1528,24 @@ install_DEB() {
fi
}
+
+
get_package_version_RPM() {
- yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+ rpm_flavour
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+ elif [ $RPM = "SUSE" ]; then
+ zypper info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+ fi
}
check_package_RPM() {
- r=`yum info $1 | grep -c 'Summary'`
+ rpm_flavour
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ r=`yum info $1 | grep -c 'Summary'`
+ elif [ $RPM = "SUSE" ]; then
+ r=`zypper info $1 | grep -c 'Summary'`
+ fi
if [ $r -ge 1 ]; then
return 0
@@ -1330,10 +1577,20 @@ check_package_version_ge_RPM() {
}
install_packages_RPM() {
- sudo yum install -y $@
- if [ $? -ge 1 ]; then
- ERROR "yum failed to install requested packages, exiting."
- exit 1
+ rpm_flavour
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ sudo yum install -y $@
+ if [ $? -ge 1 ]; then
+ ERROR "yum failed to install requested packages, exiting."
+ exit 1
+ fi
+
+ elif [ $RPM = "SUSE" ]; then
+ sudo zypper --non-interactive install --auto-agree-with-licenses $@
+ if [ $? -ge 1 ]; then
+ ERROR "zypper failed to install requested packages, exiting."
+ exit 1
+ fi
fi
}
@@ -1344,49 +1601,139 @@ install_RPM() {
INFO "`eval _echo "$COMMON_INFO"`"
INFO ""
- sudo yum -y update
+ read -p "Do you want to continue (Y/n)?"
+ [ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" != "y" ] && exit
- # These libs should always be available in debian/ubuntu official repository...
+ # Enable non-free repositories for all flavours
+ rpm_flavour
+ if [ $RPM = "FEDORA" ]; then
+ sudo yum -y localinstall --nogpgcheck \
+ http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm \
+ http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm
+
+ sudo yum -y update
+
+ # Install cmake now because of difference with RHEL
+ sudo yum -y install cmake
+
+ elif [ $RPM = "RHEL" ]; then
+ sudo yum -y localinstall --nogpgcheck \
+ http://download.fedoraproject.org/pub/epel/6/$(uname -i)/epel-release-6-8.noarch.rpm \
+ http://download1.rpmfusion.org/free/el/updates/6/$(uname -i)/rpmfusion-free-release-6-1.noarch.rpm \
+ http://download1.rpmfusion.org/nonfree/el/updates/6/$(uname -i)/rpmfusion-nonfree-release-6-1.noarch.rpm
+
+ sudo yum -y update
+
+ # Install cmake 2.8 from other repo
+ mkdir -p $SRC
+ if [ -f $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm ]; then
+ INFO ""
+ INFO "Special cmake already installed"
+ else
+ curl -O ftp://ftp.pbone.net/mirror/atrpms.net/el6-$(uname -i)/atrpms/testing/cmake-2.8.8-4.el6.$(uname -m).rpm
+ mv cmake-2.8.8-4.el6.$(uname -m).rpm $SRC/
+ sudo rpm -ihv $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm
+ fi
+
+ elif [ $RPM = "SUSE" ]; then
+ _suse_rel="`grep VERSION /etc/SuSE-release | gawk '{print $3}'`"
+ sudo zypper ar -f http://packman.inode.at/suse/openSUSE_$_suse_rel/ packman
+
+ sudo zypper --non-interactive --gpg-auto-import-keys update --auto-agree-with-licenses
+ fi
+
+ # These libs should always be available in fedora/suse official repository...
OPENJPEG_DEV="openjpeg-devel"
- SCHRO_DEV="schroedinger-devel"
VORBIS_DEV="libvorbis-devel"
THEORA_DEV="libtheora-devel"
- _packages="gawk gcc gcc-c++ cmake scons libpng-devel libtiff-devel freetype-devel \
- libX11-devel libXi-devel wget libsqlite3x-devel ncurses-devel \
- readline-devel $OPENJPEG_DEV openexr-devel openal-soft-devel \
+ _packages="gcc gcc-c++ make scons libpng-devel libtiff-devel \
+ freetype-devel libX11-devel libXi-devel wget ncurses-devel \
+ readline-devel $OPENJPEG_DEV openal-soft-devel \
glew-devel yasm $THEORA_DEV $VORBIS_DEV SDL-devel fftw-devel \
- lame-libs libjpeg-devel patch python-devel"
+ libjpeg-devel patch"
+
OPENJPEG_USE=true
VORBIS_USE=true
THEORA_USE=true
- if $WITH_ALL; then
- _packages="$_packages $SCHRO_DEV jack-audio-connection-kit-devel libspnav-devel"
- SCHRO_USE=true
- fi
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
- INFO ""
- install_packages_RPM $_packages
+ _packages="$_packages libsqlite3-devel openexr-devel"
- INFO ""
- X264_DEV="x264-devel"
- check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN
- if [ $? -eq 0 ]; then
- install_packages_RPM $X264_DEV
- X264_USE=true
- fi
+ if $WITH_ALL; then
+ _packages="$_packages jack-audio-connection-kit-devel libspnav-devel"
+ fi
+
+ INFO ""
+ install_packages_RPM $_packages
- if $WITH_ALL; then
INFO ""
- XVID_DEV="xvidcore-devel"
- check_package_RPM $XVID_DEV
+ X264_DEV="x264-devel"
+ check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN
if [ $? -eq 0 ]; then
- install_packages_RPM $XVID_DEV
- XVID_USE=true
+ install_packages_RPM $X264_DEV
+ X264_USE=true
+ fi
+
+ if $WITH_ALL; then
+ INFO ""
+ XVID_DEV="xvidcore-devel"
+ check_package_RPM $XVID_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $XVID_DEV
+ XVID_USE=true
+ fi
+
+ INFO ""
+ MP3LAME_DEV="lame-devel"
+ check_package_RPM $MP3LAME_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $MP3LAME_DEV
+ MP3LAME_USE=true
+ fi
+ fi
+
+ elif [ $RPM = "SUSE" ]; then
+
+ _packages="$_packages cmake sqlite3-devel libopenexr-devel"
+
+ if $WITH_ALL; then
+ _packages="$_packages libjack-devel libspnav-devel"
fi
INFO ""
+ install_packages_RPM $_packages
+
+ INFO ""
+ X264_DEV="libx264-devel"
+ check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $X264_DEV
+ X264_USE=true
+ fi
+
+ if $WITH_ALL; then
+ INFO ""
+ XVID_DEV="libxvidcore-devel"
+ check_package_RPM $XVID_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $XVID_DEV
+ XVID_USE=true
+ fi
+
+ INFO ""
+ MP3LAME_DEV="libmp3lame-devel"
+ check_package_RPM $MP3LAME_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $MP3LAME_DEV
+ MP3LAME_USE=true
+ fi
+ fi
+ fi
+
+ if $WITH_ALL; then
+ INFO ""
VPX_DEV="libvpx-devel"
check_package_version_ge_RPM $VPX_DEV $VPX_VERSION_MIN
if [ $? -eq 0 ]; then
@@ -1395,14 +1742,14 @@ install_RPM() {
fi
INFO ""
- MP3LAME_DEV="lame-devel"
- check_package_RPM $MP3LAME_DEV
+ SCHRO_DEV="schroedinger-devel"
+ check_package_RPM $SCHRO_DEV
if [ $? -eq 0 ]; then
- install_packages_RPM $MP3LAME_DEV
- MP3LAME_USE=true
+ install_packages_RPM $SCHRO_DEV
+ SCHRO_USE=true
fi
fi
-
+
INFO ""
if $PYTHON_SKIP; then
INFO "WARNING! Skipping Python installation, as requested..."
@@ -1410,8 +1757,25 @@ install_RPM() {
check_package_version_match_RPM python3-devel $PYTHON_VERSION_MIN
if [ $? -eq 0 ]; then
install_packages_RPM python3-devel
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ check_package_version_match_RPM python3-numpy $NUMPY_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ install_packages_RPM python3-numpy
+ else
+ INFO "WARNING! Sorry, using python package but no numpy package available!"
+ fi
+ fi
else
compile_Python
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ compile_Numpy
+ fi
fi
fi
@@ -1419,7 +1783,7 @@ install_RPM() {
if $BOOST_SKIP; then
INFO "WARNING! Skipping Boost installation, as requested..."
else
- check_package_version_ge_RPM boost-devel $BOOST_VERSION_MIN
+ check_package_version_ge_RPM boost-devel $BOOST_VERSION
if [ $? -eq 0 ]; then
install_packages_RPM boost-devel
else
@@ -1460,25 +1824,15 @@ install_RPM() {
else
check_package_RPM llvm-$LLVM_VERSION-devel
if [ $? -eq 0 ]; then
- install_packages_RPM llvm-$LLVM_VERSION-devel
+ install_packages_RPM llvm-$LLVM_VERSION-devel clang
have_llvm=true
LLVM_VERSION_FOUND=$LLVM_VERSION
else
-# check_package_RPM llvm-$LLVM_VERSION_MIN-devel
-# if [ $? -eq 0 ]; then
-# install_packages_RPM llvm-$LLVM_VERSION_MIN-devel
-# have_llvm=true
-# LLVM_VERSION_FOUND=$LLVM_VERSION_MIN
-# else
-# check_package_version_ge_RPM llvm-devel $LLVM_VERSION_MIN
-# if [ $? -eq 0 ]; then
-# install_packages_RPM llvm-devel
-# have_llvm=true
-# LLVM_VERSION_FOUND=`get_package_version_RPM llvm-devel`
-# fi
-# fi
+ #
+ # Better to compile it than use minimum version from repo...
+ #
install_packages_RPM libffi-devel
- # XXX Stupid fedora puts ffi header into a darn stupid dir!
+ # LLVM can't find the fedora ffi header dir...
_FFI_INCLUDE_DIR=`rpm -ql libffi-devel | grep -e ".*/ffi.h" | sed -r 's/(.*)\/ffi.h/\1/'`
INFO ""
compile_LLVM
@@ -1492,211 +1846,29 @@ install_RPM() {
INFO "WARNING! Skipping OpenShadingLanguage installation, as requested..."
else
if $have_llvm; then
- INFO ""
- install_packages_RPM flex bison clang tbb-devel git
# No package currently!
INFO ""
+ install_packages_RPM flex bison git
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ install_packages_RPM tbb-devel
+ fi
+ INFO ""
compile_OSL
fi
fi
fi
- INFO ""
- if $FFMPEG_SKIP; then
- INFO "WARNING! Skipping FFMpeg installation, as requested..."
- else
- # Always for now, not sure which packages should be installed
- compile_FFmpeg
- fi
-}
-
-get_package_version_SUSE() {
- zypper info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
-}
-
-check_package_SUSE() {
- r=`zypper info $1 | grep -c 'Summary'`
-
- if [ $r -ge 1 ]; then
- return 0
- else
- return 1
- fi
-}
-
-check_package_version_match_SUSE() {
- v=`get_package_version_SUSE $1`
-
- if [ -z "$v" ]; then
- return 1
- fi
-
- version_match $v $2
- return $?
-}
-
-check_package_version_ge_SUSE() {
- v=`get_package_version_SUSE $1`
-
- if [ -z "$v" ]; then
- return 1
- fi
-
- version_ge $v $2
- return $?
-}
-
-install_packages_SUSE() {
- sudo zypper --non-interactive install --auto-agree-with-licenses $@
- if [ $? -ge 1 ]; then
- ERROR "zypper failed to install requested packages, exiting."
- exit 1
- fi
-}
-
-
-install_SUSE() {
- INFO ""
- INFO "Installing dependencies for SuSE-based distribution"
- INFO ""
- INFO "`eval _echo "$COMMON_INFO"`"
- INFO ""
-
- sudo zypper --non-interactive update --auto-agree-with-licenses
-
- # These libs should always be available in debian/ubuntu official repository...
- OPENJPEG_DEV="openjpeg-devel"
- SCHRO_DEV="schroedinger-devel"
- VORBIS_DEV="libvorbis-devel"
- THEORA_DEV="libtheora-devel"
-
- _packages="gawk gcc gcc-c++ cmake scons libpng12-devel libtiff-devel freetype-devel \
- libX11-devel libXi-devel wget sqlite3-devel ncurses-devel \
- readline-devel $OPENJPEG_DEV libopenexr-devel openal-soft-devel \
- glew-devel yasm $THEORA_DEV $VORBIS_DEV libSDL-devel fftw3-devel \
- libjpeg62-devel patch python-devel"
- OPENJPEG_USE=true
- VORBIS_USE=true
- THEORA_USE=true
-
- if $WITH_ALL; then
- _packages="$_packages $SCHRO_DEV libjack-devel libspnav-devel"
- SCHRO_USE=true
- fi
-
- INFO ""
- install_packages_SUSE $_packages
-
- OPENJPEG_USE=true
- SCHRO_USE=true
- VORBIS_USE=true
- THEORA_USE=true
-
- INFO ""
- X264_DEV="x264-devel"
- check_package_version_ge_SUSE $X264_DEV $X264_VERSION_MIN
- if [ $? -eq 0 ]; then
- install_packages_SUSE $X264_DEV
- X264_USE=true
- fi
-
- if $WITH_ALL; then
- INFO ""
- XVID_DEV="xvidcore-devel"
- check_package_SUSE $XVID_DEV
- if [ $? -eq 0 ]; then
- install_packages_SUSE $XVID_DEV
- XVID_USE=true
- fi
-
- INFO ""
- VPX_DEV="libvpx-devel"
- check_package_version_ge_SUSE $VPX_DEV $VPX_VERSION_MIN
- if [ $? -eq 0 ]; then
- install_packages_SUSE $VPX_DEV
- VPX_USE=true
- fi
-
- INFO ""
- # No mp3 in suse, it seems.
- MP3LAME_DEV="lame-devel"
- check_package_SUSE $MP3LAME_DEV
- if [ $? -eq 0 ]; then
- install_packages_SUSE $MP3LAME_DEV
- MP3LAME_USE=true
- fi
- fi
-
- INFO ""
- if $PYTHON_SKIP; then
- INFO "WARNING! Skipping Python installation, as requested..."
- else
- check_package_version_match_SUSE python3-devel 3.3.
- if [ $? -eq 0 ]; then
- install_packages_SUSE python3-devel
- else
- compile_Python
- fi
- fi
-
- INFO ""
- if $BOOST_SKIP; then
- INFO "WARNING! Skipping Boost installation, as requested..."
- else
- # No boost_locale currently available, so let's build own boost.
- compile_Boost
- fi
-
- INFO ""
- if $OCIO_SKIP; then
- INFO "WARNING! Skipping OpenColorIO installation, as requested..."
- else
- # No ocio currently available, so let's build own boost.
- compile_OCIO
- fi
-
- INFO ""
- if $OIIO_SKIP; then
- INFO "WARNING! Skipping OpenImageIO installation, as requested..."
- else
- # No oiio currently available, so let's build own boost.
- compile_OIIO
- fi
-
- if $WITH_OSL; then
- have_llvm=false
-
- INFO ""
- if $LLVM_SKIP; then
- INFO "WARNING! Skipping LLVM installation, as requested (this also implies skipping OSL!)..."
+ if $WITH_OPENCOLLADA; then
+ if $OPENCOLLADA_SKIP; then
+ INFO "WARNING! Skipping OpenCOLLADA installation, as requested..."
else
- # Suse llvm package *_$SUCKS$_* (tm) !!!
-# check_package_version_ge_SUSE llvm-devel $LLVM_VERSION_MIN
-# if [ $? -eq 0 ]; then
-# install_packages_SUSE llvm-devel
-# have_llvm=true
-# LLVM_VERSION_FOUND=`get_package_version_SUSE llvm-devel`
-# fi
-
- install_packages_SUSE libffi47-devel
INFO ""
- compile_LLVM
- have_llvm=true
- LLVM_VERSION_FOUND=$LLVM_VERSION
- fi
-
- if $OSL_SKIP; then
+ install_packages_RPM pcre-devel libxml2-devel git
+ # Find path to libxml shared lib...
+ _XML2_LIB=`rpm -ql libxml2-devel | grep -e ".*/libxml2.so"`
+ # No package...
INFO ""
- INFO "WARNING! Skipping OpenShaderLanguage installation, as requested..."
- else
- if $have_llvm; then
- INFO ""
- # XXX No tbb lib!
- install_packages_SUSE flex bison git
- # No package currently!
- INFO ""
- compile_OSL
- fi
+ compile_OpenCOLLADA
fi
fi
@@ -1704,11 +1876,13 @@ install_SUSE() {
if $FFMPEG_SKIP; then
INFO "WARNING! Skipping FFMpeg installation, as requested..."
else
- # No ffmpeg currently available, so let's build own boost.
+ # Always for now, not sure which packages should be installed
compile_FFmpeg
fi
}
+
+
print_info_ffmpeglink_DEB() {
if $ALL_STATIC; then
dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
@@ -1718,19 +1892,12 @@ print_info_ffmpeglink_DEB() {
}
print_info_ffmpeglink_RPM() {
- if $ALL_STATIC; then
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
- else
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
- fi
-}
-
-print_info_ffmpeglink_SUSE() {
- if $ALL_STATIC; then
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
- else
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
- fi
+# # XXX No static libs...
+# if $ALL_STATIC; then
+# rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
+# else
+ rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
+# fi
}
print_info_ffmpeglink() {
@@ -1771,8 +1938,7 @@ print_info_ffmpeglink() {
_packages="$_packages $OPENJPEG_DEV"
fi
- # XXX At least under Debian, static schro gives problem at blender linking time... :/
- if $SCHRO_USE && ! $ALL_STATIC; then
+ if $SCHRO_USE; then
_packages="$_packages $SCHRO_DEV"
fi
@@ -1780,8 +1946,8 @@ print_info_ffmpeglink() {
print_info_ffmpeglink_DEB
elif [ "$DISTRO" = "RPM" ]; then
print_info_ffmpeglink_RPM
- elif [ "$DISTRO" = "SUSE" ]; then
- print_info_ffmpeglink_SUSE
+# elif [ "$DISTRO" = "ARCH" ]; then
+# print_info_ffmpeglink_ARCH
# XXX TODO!
else INFO "<Could not determine additional link libraries needed for ffmpeg, replace this by valid list of libs...>"
fi
@@ -1791,38 +1957,76 @@ print_info() {
INFO ""
INFO "If you're using CMake add this to your configuration flags:"
+ _buildargs=""
+
if $ALL_STATIC; then
- INFO " -D WITH_STATIC_LIBS=ON"
+ _1="-D WITH_STATIC_LIBS=ON"
+ # XXX Force linking with shared SDL lib!
+ _2="-D SDL_LIBRARY='libSDL.so;-lpthread'"
+ INFO " $_1"
+ INFO " $_2"
+ _buildargs="$_buildargs $_1 $_2"
fi
if [ -d $INST/boost ]; then
- INFO " -D BOOST_ROOT=$INST/boost"
- INFO " -D Boost_NO_SYSTEM_PATHS=ON"
+ _1="-D BOOST_ROOT=$INST/boost"
+ _2="-D Boost_NO_SYSTEM_PATHS=ON"
+ INFO " $_1"
+ INFO " $_2"
+ _buildargs="$_buildargs $_1 $_2"
elif $ALL_STATIC; then
- INFO " -D Boost_USE_ICU=ON"
+ _1="-D WITH_BOOST_ICU=ON"
+ INFO " $_1"
+ _buildargs="$_buildargs $_1"
fi
if [ -d $INST/osl -a $WITH_OSL == true ]; then
- INFO " -D CYCLES_OSL=$INST/osl"
- INFO " -D WITH_CYCLES_OSL=ON"
- INFO " -D LLVM_VERSION=$LLVM_VERSION_FOUND"
+ _1="-D CYCLES_OSL=$INST/osl"
+ _2="-D WITH_CYCLES_OSL=ON"
+ _3="-D LLVM_VERSION=$LLVM_VERSION_FOUND"
+ INFO " $_1"
+ INFO " $_2"
+ INFO " $_3"
+ _buildargs="$_buildargs $_1 $_2 $_3"
if [ -d $INST/llvm ]; then
- INFO " -D LLVM_DIRECTORY=$INST/llvm"
- INFO " -D LLVM_STATIC=ON"
+ _1="-D LLVM_DIRECTORY=$INST/llvm"
+ _2="-D LLVM_STATIC=ON"
+ INFO " $_1"
+ INFO " $_2"
+ _buildargs="$_buildargs $_1 $_2"
+ fi
+ fi
+
+ if [ -d $INST/opencollada -a $WITH_OPENCOLLADA == true ]; then
+ _1="-D WITH_OPENCOLLADA=ON"
+ INFO " $_1"
+ _buildargs="$_buildargs $_1"
+ if $ALL_STATIC; then
+ _1="-D XML2_LIBRARY=$_XML2_LIB"
+ INFO " $_1"
+ _buildargs="$_buildargs $_1"
fi
fi
if [ -d $INST/ffmpeg ]; then
- INFO " -D WITH_CODEC_FFMPEG=ON"
- INFO " -D FFMPEG=$INST/ffmpeg"
- INFO " -D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
+ _1="-D WITH_CODEC_FFMPEG=ON"
+ _2="-D FFMPEG=$INST/ffmpeg"
+ _3="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
+ INFO " $_1"
+ INFO " $_2"
+ INFO " $_3"
+ _buildargs="$_buildargs $_1 $_2 $_3"
fi
INFO ""
+ INFO "Or even simpler, just run (in your blender-source dir):"
+ INFO " make -j$THREADS BUILD_CMAKE_ARGS=\"$_buildargs\""
+
+ INFO ""
INFO "If you're using SCons add this to your user-config:"
- if [ -d $INST/python-3.3 ]; then
- INFO "BF_PYTHON = '$INST/python-3.3'"
+ if [ -d $INST/python-$PYTHON_VERSION_MIN ]; then
+ INFO "BF_PYTHON = '$INST/python-$PYTHON_VERSION_MIN'"
INFO "BF_PYTHON_ABI_FLAGS = 'm'"
fi
@@ -1834,8 +2038,13 @@ print_info() {
INFO "BF_OIIO = '$INST/oiio'"
fi
+ if [ -d $INST/osl ]; then
+ INFO "BF_OSL = '$INST/osl'"
+ fi
+
if [ -d $INST/boost ]; then
INFO "BF_BOOST = '$INST/boost'"
+ INFO "WITH_BF_BOOST = True"
fi
if [ -d $INST/ffmpeg ]; then
@@ -1864,11 +2073,14 @@ elif [ "$DISTRO" = "DEB" ]; then
install_DEB
elif [ "$DISTRO" = "RPM" ]; then
install_RPM
-elif [ "$DISTRO" = "SUSE" ]; then
- install_SUSE
+#elif [ "$DISTRO" = "ARCH" ]; then
+# install_ARCH
fi
-print_info
+print_info | tee BUILD_NOTES.txt
+INFO ""
+INFO "This information has been written to BUILD_NOTES.txt"
+INFO ""
# Switch back to user language.
LANG=LANG_BACK
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
new file mode 100644
index 00000000000..0e56c4326f9
--- /dev/null
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
@@ -0,0 +1,5 @@
+BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
+BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
+BF_NUMJOBS = 1
+
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
new file mode 100644
index 00000000000..59725522e18
--- /dev/null
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
@@ -0,0 +1,5 @@
+BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
+BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
+BF_NUMJOBS = 1
+
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index e665657d91e..540416ee1fb 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -1,6 +1,7 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
+WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,14 +104,13 @@ WITH_BF_FFTW3 = True
WITH_BF_STATICFFTW3 = True
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+WITH_BF_CYCLES_CUDA_BINARIES = False
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py
index 420d9ed4db9..c0ba8060712 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -1,6 +1,7 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
+WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,14 +104,13 @@ WITH_BF_FFTW3 = True
WITH_BF_STATICFFTW3 = True
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+WITH_BF_CYCLES_CUDA_BINARIES = False
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py
deleted file mode 100644
index b36196fd835..00000000000
--- a/build_files/buildbot/config/user-config-glibc27-i686.py
+++ /dev/null
@@ -1,149 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-i686'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-i686'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = True
-BF_OPENCOLLADA = '/opt/opencollada'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib32'
-BF_PCRE_LIB = ''
-BF_EXPAT_LIB = ''
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = True
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = True
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Blender player (would be enabled in it's own config)
-WITH_BF_PLAYER = False
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
-
-# FFT
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-
-# JACK
-WITH_BF_JACK = True
-
-# Cycles
-WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-
-WITH_BF_OIIO = True
-WITH_BF_STATICOIIO = True
-BF_OIIO = '/opt/oiio'
-BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
-BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
-
-WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
-BF_OSL = '/opt/osl'
-BF_OSL_INC = '${BF_OSL}/include'
-# note oslexec would passed via program linkflags, which is needed to
-# make llvm happy with osl_allocate_closure_component
-BF_OSL_LIB = 'oslcomp oslexec oslquery'
-BF_OSL_LIBPATH = '${BF_OSL}/lib'
-BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
-
-WITH_BF_LLVM = True
-WITH_BF_STATICLLVM = False
-BF_LLVM = '/opt/llvm-3.1'
-BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
- 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
- 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
-BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# Ocean Simulation
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py
deleted file mode 100644
index 7359e155586..00000000000
--- a/build_files/buildbot/config/user-config-glibc27-x86_64.py
+++ /dev/null
@@ -1,149 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = True
-BF_OPENCOLLADA = '/opt/opencollada'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib64'
-BF_PCRE_LIB = ''
-BF_EXPAT_LIB = ''
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = True
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = True
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Blender player (would be enabled in it's own config)
-WITH_BF_PLAYER = False
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
-
-# FFT
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-
-# JACK
-WITH_BF_JACK = True
-
-# Cycles
-WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-
-WITH_BF_OIIO = True
-WITH_BF_STATICOIIO = True
-BF_OIIO = '/opt/oiio'
-BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
-BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
-
-WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
-BF_OSL = '/opt/osl'
-BF_OSL_INC = '${BF_OSL}/include'
-# note oslexec would passed via program linkflags, which is needed to
-# make llvm happy with osl_allocate_closure_component
-BF_OSL_LIB = 'oslcomp oslexec oslquery'
-BF_OSL_LIBPATH = '${BF_OSL}/lib'
-BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
-
-WITH_BF_LLVM = True
-WITH_BF_STATICLLVM = False
-BF_LLVM = '/opt/llvm-3.1'
-BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
- 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
- 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
-BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# Ocean Simulation
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py
index 96f201235c4..a99337f03e6 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -1,6 +1,6 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,7 +103,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
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 75979d0bcfe..c17cff2893d 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
@@ -1,6 +1,6 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,7 +103,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
diff --git a/build_files/buildbot/config/user-config-player-glibc27-i686.py b/build_files/buildbot/config/user-config-player-glibc27-i686.py
deleted file mode 100644
index 82b105c4527..00000000000
--- a/build_files/buildbot/config/user-config-player-glibc27-i686.py
+++ /dev/null
@@ -1,114 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-i686'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-i686'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = False
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = False
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = False
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = False
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Do not build blender when building blenderplayer
-WITH_BF_NOBLENDER = True
-WITH_BF_PLAYER = True
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# JACK
-WITH_BF_JACK = True
-
-# Motion Tracking
-WITH_BF_LIBMV = False
-
-# Ocean Simulation
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
diff --git a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
deleted file mode 100644
index 1e6aa4af802..00000000000
--- a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
+++ /dev/null
@@ -1,114 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = False
-
-# FFMPEG configuration
-WITH_BF_FFMPEG = True
-WITH_BF_STATICFFMPEG = True
-
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
-BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64'
-BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-
-# Don't depend on system's libstdc++
-WITH_BF_STATICCXX = True
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = False
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = False
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = False
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Do not build blender when building blenderplayer
-WITH_BF_NOBLENDER = True
-WITH_BF_PLAYER = True
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-WITH_BF_STATICJEMALLOC = True
-BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
-BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
-
-# Use 3d mouse library
-WITH_BF_3DMOUSE = True
-WITH_BF_STATIC3DMOUSE = True
-BF_3DMOUSE = '/home/sources/staticlibs/spnav'
-BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# JACK
-WITH_BF_JACK = True
-
-# Motion Tracking
-WITH_BF_LIBMV = False
-
-# Ocean Simulation
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg
index 90f0c805f58..3cfea2a3abd 100644
--- a/build_files/buildbot/master.cfg
+++ b/build_files/buildbot/master.cfg
@@ -28,8 +28,8 @@ c['slavePortnum'] = 9989
from buildbot.changes.svnpoller import SVNPoller
c['change_source'] = SVNPoller(
- 'https://svn.blender.org/svnroot/bf-blender/trunk/',
- pollinterval=1200)
+ 'https://svn.blender.org/svnroot/bf-blender/trunk/',
+ pollinterval=1200)
# BUILDERS
#
@@ -74,9 +74,11 @@ def svn_step(branch=''):
else:
return SVN(baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/blender', mode='update', defaultBranch='trunk', workdir='blender')
+
def lib_svn_step(dir):
return SVN(name='lib svn', baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir, mode='update', defaultBranch='trunk', workdir='lib/' + dir)
+
def rsync_step(id, branch, rsync_script):
return ShellCommand(name='rsync', command=['python', rsync_script, id, branch], description='uploading', descriptionDone='uploaded', workdir='install')
@@ -116,10 +118,10 @@ add_builder(c, 'mac_x86_64_10_5_scons', '', generic_builder, '', True)
add_builder(c, 'mac_i386_scons', 'darwin-9.x.universal', generic_builder)
add_builder(c, 'mac_ppc_scons', 'darwin-9.x.universal', generic_builder)
#add_builder(c, 'linux_x86_64_cmake', '', generic_builder)
-add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder)
+#add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder)
add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder)
#add_builder(c, 'salad_linux_i386_scons', '', generic_builder, 'soc-2011-salad')
-add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder)
+#add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder)
add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder)
#add_builder(c, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad')
add_builder(c, 'win32_scons', 'windows', generic_builder)
@@ -155,9 +157,9 @@ for i in range(0, schedule_cycle):
print(names)
c['schedulers'].append(timed.Nightly(name='nightly' + str(i),
- builderNames=names,
- hour=3+i,
- minute=0))
+ builderNames=names,
+ hour=3 + i,
+ minute=0))
# STATUS TARGETS
#
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index bedada93a5a..dab8a8e6483 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -60,6 +60,27 @@ else:
if builder.find('linux') != -1:
import shutil
+ configs = []
+ if builder.endswith('linux_glibc211_x86_64_scons'):
+ configs = ['user-config-player-glibc211-x86_64.py',
+ 'user-config-cuda-glibc211-x86_64.py',
+ 'user-config-glibc211-x86_64.py'
+ ]
+ chroot_name = 'buildbot_squeeze_x86_64'
+ cuda_chroot = 'buildbot_squeeze_x86_64'
+ elif builder.endswith('linux_glibc211_i386_scons'):
+ configs = ['user-config-player-glibc211-i686.py',
+ 'user-config-cuda-glibc211-i686.py',
+ 'user-config-glibc211-i686.py']
+ chroot_name = 'buildbot_squeeze_i686'
+
+ # use 64bit cuda toolkit, so there'll be no memory limit issues
+ cuda_chroot = 'buildbot_squeeze_x86_64'
+
+ # Compilation will happen inside of chroot environment
+ prog_scons_cmd = ['schroot', '-c', chroot_name, '--'] + scons_cmd
+ cuda_scons_cmd = ['schroot', '-c', cuda_chroot, '--'] + scons_cmd
+
# We're using the same rules as release builder, so tweak
# build and install dirs
build_dir = os.path.join('..', 'build', builder)
@@ -74,20 +95,6 @@ else:
buildbot_dir = os.path.dirname(os.path.realpath(__file__))
config_dir = os.path.join(buildbot_dir, 'config')
- configs = []
- if builder.endswith('linux_glibc27_x86_64_scons'):
- configs = ['user-config-player-glibc27-x86_64.py',
- 'user-config-glibc27-x86_64.py']
- elif builder.endswith('linux_glibc27_i386_scons'):
- configs = ['user-config-player-glibc27-i686.py',
- 'user-config-glibc27-i686.py']
- if builder.endswith('linux_glibc211_x86_64_scons'):
- configs = ['user-config-player-glibc211-x86_64.py',
- 'user-config-glibc211-x86_64.py']
- elif builder.endswith('linux_glibc211_i386_scons'):
- configs = ['user-config-player-glibc211-i686.py',
- 'user-config-glibc211-i686.py']
-
for config in configs:
config_fpath = os.path.join(config_dir, config)
@@ -100,14 +107,24 @@ else:
scons_options += common_options
- if config.find('player') == -1:
- scons_options.append('blender')
- else:
+ if config.find('player') != -1:
scons_options.append('blenderplayer')
+ cur_scons_cmd = prog_scons_cmd
+ elif config.find('cuda') != -1:
+ scons_options.append('cudakernels')
+ cur_scons_cmd = cuda_scons_cmd
+
+ if config.find('i686') != -1:
+ scons_options.append('BF_BITNESS=32')
+ elif config.find('x86_64') != -1:
+ scons_options.append('BF_BITNESS=64')
+ else:
+ scons_options.append('blender')
+ cur_scons_cmd = prog_scons_cmd
scons_options.append('BF_CONFIG=' + config_fpath)
- retcode = subprocess.call(scons_cmd + scons_options)
+ retcode = subprocess.call(cur_scons_cmd + scons_options)
if retcode != 0:
print('Error building rules wuth config ' + config)
sys.exit(retcode)
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index b7775ef872f..3d4f423be9c 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -57,17 +57,13 @@ if builder.find('scons') != -1:
config = None
bits = None
- if builder.endswith('linux_glibc27_x86_64_scons'):
- config = 'user-config-glibc27-x86_64.py'
- bits = 64
- elif builder.endswith('linux_glibc27_i386_scons'):
- config = 'user-config-glibc27-i686.py'
- bits = 32
if builder.endswith('linux_glibc211_x86_64_scons'):
config = 'user-config-glibc211-x86_64.py'
+ chroot_name = 'buildbot_squeeze_x86_64'
bits = 64
elif builder.endswith('linux_glibc211_i386_scons'):
config = 'user-config-glibc211-i686.py'
+ chroot_name = 'buildbot_squeeze_i686'
bits = 32
if config is not None:
@@ -76,7 +72,7 @@ if builder.find('scons') != -1:
blender = os.path.join(install_dir, 'blender')
blenderplayer = os.path.join(install_dir, 'blenderplayer')
- subprocess.call(['strip', '--strip-all', blender, blenderplayer])
+ subprocess.call(['schroot', '-c', chroot_name, '--', 'strip', '--strip-all', blender, blenderplayer])
extra = '/' + os.path.join('home', 'sources', 'release-builder', 'extra')
mesalibs = os.path.join(extra, 'mesalibs' + str(bits) + '.tar.bz2')
@@ -86,7 +82,7 @@ if builder.find('scons') != -1:
os.system('cp %s %s' % (software_gl, install_dir))
os.system('chmod 755 %s' % (os.path.join(install_dir, 'blender-softwaregl')))
- retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
+ retcode = subprocess.call(['schroot', '-c', chroot_name, '--', 'python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
else:
diff --git a/build_files/buildbot/slave_rsync.py b/build_files/buildbot/slave_rsync.py
index aea1b65e333..6936232a495 100644
--- a/build_files/buildbot/slave_rsync.py
+++ b/build_files/buildbot/slave_rsync.py
@@ -41,5 +41,3 @@ print(command)
ret = os.system(command)
sys.exit(ret)
-
-
diff --git a/build_files/cmake/Modules/FindOpenCOLLADA.cmake b/build_files/cmake/Modules/FindOpenCOLLADA.cmake
index 169d3a82fc7..84aead58b60 100644
--- a/build_files/cmake/Modules/FindOpenCOLLADA.cmake
+++ b/build_files/cmake/Modules/FindOpenCOLLADA.cmake
@@ -66,6 +66,7 @@ SET(_opencollada_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/opencollada
)
SET(_opencollada_INCLUDES)
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index b13b0ddb424..665bc600efa 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -75,12 +75,12 @@ def is_cmake(filename):
def is_c_header(filename):
ext = splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_c(filename):
ext = splitext(filename)[1]
- return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"))
+ return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"})
def is_c_any(filename):
diff --git a/build_files/cmake/cmake_consistency_check_config.py b/build_files/cmake/cmake_consistency_check_config.py
index 6b82e224a32..55bad251a53 100644
--- a/build_files/cmake/cmake_consistency_check_config.py
+++ b/build_files/cmake/cmake_consistency_check_config.py
@@ -29,6 +29,22 @@ IGNORE = (
"extern/recastnavigation/Recast/Source/RecastTimer.cpp",
"intern/audaspace/SRC/AUD_SRCResampleFactory.cpp",
"intern/audaspace/SRC/AUD_SRCResampleReader.cpp",
+ "intern/cycles/render/film_response.cpp",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc",
+ "extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h",
@@ -47,6 +63,11 @@ IGNORE = (
"extern/recastnavigation/Recast/Include/RecastTimer.h",
"intern/audaspace/SRC/AUD_SRCResampleFactory.h",
"intern/audaspace/SRC/AUD_SRCResampleReader.h",
+ "intern/cycles/render/film_response.h",
+ "extern/carve/include/carve/config.h",
+ "extern/carve/include/carve/external/boost/random.hpp",
+ "extern/carve/patches/files/config.h",
+ "extern/carve/patches/files/random.hpp",
)
UTF8_CHECK = True
diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py
index 2f36cad4d24..17490e36bb3 100755
--- a/build_files/cmake/cmake_netbeans_project.py
+++ b/build_files/cmake/cmake_netbeans_project.py
@@ -56,6 +56,10 @@ def create_nb_project_main():
pass
else:
includes, defines = cmake_advanced_info()
+
+ if (includes, defines) == (None, None):
+ return
+
# for some reason it doesnt give all internal includes
includes = list(set(includes) | set(dirname(f) for f in files if is_c_header(f)))
includes.sort()
diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py
index 86201da23de..4cf854aad77 100755
--- a/build_files/cmake/cmake_qtcreator_project.py
+++ b/build_files/cmake/cmake_qtcreator_project.py
@@ -81,6 +81,9 @@ def create_qtc_project_main():
else:
includes, defines = cmake_advanced_info()
+ if (includes, defines) == (None, None):
+ return
+
# for some reason it doesnt give all internal includes
includes = list(set(includes) | set(os.path.dirname(f)
for f in files_rel if is_c_header(f)))
diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py
index 7f45cc6aadc..448454c2177 100644
--- a/build_files/cmake/cmake_static_check_clang_array.py
+++ b/build_files/cmake/cmake_static_check_clang_array.py
@@ -50,7 +50,7 @@ def main():
check_commands = []
for c, inc_dirs, defs in source_info:
cmd = ([CHECKER_BIN] +
- CHECKER_ARGS +
+ CHECKER_ARGS +
[c] +
[("-I%s" % i) for i in inc_dirs] +
[("-D%s" % d) for d in defs]
diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py
index d79145f8586..2f7ffa5c240 100644
--- a/build_files/cmake/cmake_static_check_cppcheck.py
+++ b/build_files/cmake/cmake_static_check_cppcheck.py
@@ -56,7 +56,7 @@ def main():
check_commands = []
for c, inc_dirs, defs in source_info:
cmd = ([CHECKER_BIN] +
- CHECKER_ARGS +
+ CHECKER_ARGS +
[c] +
[("-I%s" % i) for i in inc_dirs] +
[("-D%s" % d) for d in defs]
diff --git a/build_files/cmake/cmake_static_check_smatch.py b/build_files/cmake/cmake_static_check_smatch.py
index 7535f1cc55a..2cf07b093fb 100644
--- a/build_files/cmake/cmake_static_check_smatch.py
+++ b/build_files/cmake/cmake_static_check_smatch.py
@@ -41,6 +41,7 @@ import os
USE_QUIET = (os.environ.get("QUIET", None) is not None)
+
def main():
source_info = project_source_info.build_info(use_cxx=False, ignore_prefix_list=CHECKER_IGNORE_PREFIX)
@@ -48,7 +49,7 @@ def main():
for c, inc_dirs, defs in source_info:
cmd = ([CHECKER_BIN] +
- CHECKER_ARGS +
+ CHECKER_ARGS +
[c] +
[("-I%s" % i) for i in inc_dirs] +
[("-D%s" % d) for d in defs]
diff --git a/build_files/cmake/cmake_static_check_sparse.py b/build_files/cmake/cmake_static_check_sparse.py
index 06bef1a1327..8a3fb477239 100644
--- a/build_files/cmake/cmake_static_check_sparse.py
+++ b/build_files/cmake/cmake_static_check_sparse.py
@@ -47,7 +47,7 @@ def main():
for c, inc_dirs, defs in source_info:
cmd = ([CHECKER_BIN] +
- CHECKER_ARGS +
+ CHECKER_ARGS +
[c] +
[("-I%s" % i) for i in inc_dirs] +
[("-D%s" % d) for d in defs]
diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py
index 5b1207543f5..6ad03f2bdca 100644
--- a/build_files/cmake/cmake_static_check_splint.py
+++ b/build_files/cmake/cmake_static_check_splint.py
@@ -79,7 +79,7 @@ def main():
check_commands = []
for c, inc_dirs, defs in source_info:
cmd = ([CHECKER_BIN] +
- CHECKER_ARGS +
+ CHECKER_ARGS +
[c] +
[("-I%s" % i) for i in inc_dirs] +
[("-D%s" % d) for d in defs]
diff --git a/build_files/cmake/config/blender_headless.cmake b/build_files/cmake/config/blender_headless.cmake
index c4d64125744..cfde86aac6d 100644
--- a/build_files/cmake/config/blender_headless.cmake
+++ b/build_files/cmake/config/blender_headless.cmake
@@ -5,19 +5,19 @@
# cmake -C../blender/build_files/cmake/config/blender_headless.cmake ../blender
#
-set(WITH_HEADLESS ON CACHE FORCE BOOL)
-set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
+set(WITH_HEADLESS ON CACHE BOOL "" FORCE)
+set(WITH_GAMEENGINE OFF CACHE BOOL "" FORCE)
# disable audio, its possible some devs may want this but for now disable
# so the python module doesnt hold the audio device and loads quickly.
-set(WITH_AUDASPACE OFF CACHE FORCE BOOL)
-set(WITH_FFTW3 OFF CACHE FORCE BOOL)
-set(WITH_JACK OFF CACHE FORCE BOOL)
-set(WITH_SDL OFF CACHE FORCE BOOL)
-set(WITH_OPENAL OFF CACHE FORCE BOOL)
-set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
-set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
+set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
+set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
+set(WITH_JACK OFF CACHE BOOL "" FORCE)
+set(WITH_SDL OFF CACHE BOOL "" FORCE)
+set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
+set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
+set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
# other features which are not especially useful as a python module
-set(WITH_X11_XINPUT OFF CACHE FORCE BOOL)
-set(WITH_INPUT_NDOF OFF CACHE FORCE BOOL)
+set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
+set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake
index e74d1adcb1b..f7778ac214d 100644
--- a/build_files/cmake/config/blender_lite.cmake
+++ b/build_files/cmake/config/blender_lite.cmake
@@ -5,47 +5,47 @@
# cmake -C../blender/build_files/cmake/config/blender_lite.cmake ../blender
#
-set(WITH_INSTALL_PORTABLE ON CACHE FORCE BOOL)
-set(WITH_SYSTEM_GLEW ON CACHE FORCE BOOL)
+set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE)
+set(WITH_SYSTEM_GLEW ON CACHE BOOL "" FORCE)
-set(WITH_BUILDINFO OFF CACHE FORCE BOOL)
-set(WITH_BULLET OFF CACHE FORCE BOOL)
-set(WITH_CODEC_AVI OFF CACHE FORCE BOOL)
-set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
-set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
-set(WITH_CYCLES OFF CACHE FORCE BOOL)
-set(WITH_FFTW3 OFF CACHE FORCE BOOL)
-set(WITH_LIBMV OFF CACHE FORCE BOOL)
-set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
-set(WITH_COMPOSITOR OFF CACHE FORCE BOOL)
-set(WITH_GHOST_XDND OFF CACHE FORCE BOOL)
-set(WITH_IK_SOLVER OFF CACHE FORCE BOOL)
-set(WITH_IK_ITASC OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_CINEON OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_DDS OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_FRAMESERVER OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_HDR OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_OPENEXR OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_OPENJPEG OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_REDCODE OFF CACHE FORCE BOOL)
-set(WITH_IMAGE_TIFF OFF CACHE FORCE BOOL)
-set(WITH_INPUT_NDOF OFF CACHE FORCE BOOL)
-set(WITH_INTERNATIONAL OFF CACHE FORCE BOOL)
-set(WITH_JACK OFF CACHE FORCE BOOL)
-set(WITH_LZMA OFF CACHE FORCE BOOL)
-set(WITH_LZO OFF CACHE FORCE BOOL)
-set(WITH_MOD_BOOLEAN OFF CACHE FORCE BOOL)
-set(WITH_MOD_FLUID OFF CACHE FORCE BOOL)
-set(WITH_MOD_REMESH OFF CACHE FORCE BOOL)
-set(WITH_MOD_SMOKE OFF CACHE FORCE BOOL)
-set(WITH_MOD_OCEANSIM OFF CACHE FORCE BOOL)
-set(WITH_AUDASPACE OFF CACHE FORCE BOOL)
-set(WITH_OPENAL OFF CACHE FORCE BOOL)
-set(WITH_OPENCOLLADA OFF CACHE FORCE BOOL)
-set(WITH_OPENCOLORIO OFF CACHE FORCE BOOL)
-set(WITH_OPENMP OFF CACHE FORCE BOOL)
-set(WITH_PYTHON_INSTALL OFF CACHE FORCE BOOL)
-set(WITH_RAYOPTIMIZATION OFF CACHE FORCE BOOL)
-set(WITH_SDL OFF CACHE FORCE BOOL)
-set(WITH_X11_XINPUT OFF CACHE FORCE BOOL)
-set(WITH_X11_XF86VMODE OFF CACHE FORCE BOOL)
+set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
+set(WITH_BULLET OFF CACHE BOOL "" FORCE)
+set(WITH_CODEC_AVI OFF CACHE BOOL "" FORCE)
+set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
+set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
+set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
+set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
+set(WITH_LIBMV OFF CACHE BOOL "" FORCE)
+set(WITH_GAMEENGINE OFF CACHE BOOL "" FORCE)
+set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
+set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
+set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
+set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_DDS OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_FRAMESERVER OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_HDR OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_REDCODE OFF CACHE BOOL "" FORCE)
+set(WITH_IMAGE_TIFF OFF CACHE BOOL "" FORCE)
+set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
+set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
+set(WITH_JACK OFF CACHE BOOL "" FORCE)
+set(WITH_LZMA OFF CACHE BOOL "" FORCE)
+set(WITH_LZO OFF CACHE BOOL "" FORCE)
+set(WITH_MOD_BOOLEAN OFF CACHE BOOL "" FORCE)
+set(WITH_MOD_FLUID OFF CACHE BOOL "" FORCE)
+set(WITH_MOD_REMESH OFF CACHE BOOL "" FORCE)
+set(WITH_MOD_SMOKE OFF CACHE BOOL "" FORCE)
+set(WITH_MOD_OCEANSIM OFF CACHE BOOL "" FORCE)
+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_OPENMP OFF CACHE BOOL "" FORCE)
+set(WITH_PYTHON_INSTALL OFF CACHE BOOL "" FORCE)
+set(WITH_RAYOPTIMIZATION OFF CACHE BOOL "" FORCE)
+set(WITH_SDL OFF CACHE BOOL "" FORCE)
+set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
+set(WITH_X11_XF86VMODE OFF CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/config/bpy_module.cmake b/build_files/cmake/config/bpy_module.cmake
index 6279f06214f..b5b13b40987 100644
--- a/build_files/cmake/config/bpy_module.cmake
+++ b/build_files/cmake/config/bpy_module.cmake
@@ -4,30 +4,30 @@
# cmake -C../blender/build_files/cmake/config/bpy_module.cmake ../blender
#
-set(WITH_PYTHON_MODULE ON CACHE FORCE BOOL)
+set(WITH_PYTHON_MODULE ON CACHE BOOL "" FORCE)
# install into the systems python dir
-set(WITH_INSTALL_PORTABLE OFF CACHE FORCE BOOL)
+set(WITH_INSTALL_PORTABLE OFF CACHE BOOL "" FORCE)
# no point int copying python into python
-set(WITH_PYTHON_INSTALL OFF CACHE FORCE BOOL)
+set(WITH_PYTHON_INSTALL OFF CACHE BOOL "" FORCE)
# dont build the game engine
-set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
+set(WITH_GAMEENGINE OFF CACHE BOOL "" FORCE)
# disable audio, its possible some devs may want this but for now disable
# so the python module doesnt hold the audio device and loads quickly.
-set(WITH_AUDASPACE OFF CACHE FORCE BOOL)
-set(WITH_FFTW3 OFF CACHE FORCE BOOL)
-set(WITH_JACK OFF CACHE FORCE BOOL)
-set(WITH_SDL OFF CACHE FORCE BOOL)
-set(WITH_OPENAL OFF CACHE FORCE BOOL)
-set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
-set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
+set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
+set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
+set(WITH_JACK OFF CACHE BOOL "" FORCE)
+set(WITH_SDL OFF CACHE BOOL "" FORCE)
+set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
+set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
+set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
# other features which are not especially useful as a python module
-set(WITH_X11_XINPUT OFF CACHE FORCE BOOL)
-set(WITH_INPUT_NDOF OFF CACHE FORCE BOOL)
-set(WITH_OPENCOLLADA OFF CACHE FORCE BOOL)
-set(WITH_INTERNATIONAL OFF CACHE FORCE BOOL)
-set(WITH_BULLET OFF CACHE FORCE BOOL)
+set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
+set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
+set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
+set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
+set(WITH_BULLET OFF CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index efa258aa9dc..bdd82a4f438 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -282,7 +282,9 @@ macro(setup_liblinks
if(WITH_SYSTEM_GLEW)
target_link_libraries(${target} ${GLEW_LIBRARY})
endif()
-
+ if(WITH_BULLET AND WITH_SYSTEM_BULLET)
+ target_link_libraries(${target} ${BULLET_LIBRARIES})
+ endif()
if(WITH_OPENAL)
target_link_libraries(${target} ${OPENAL_LIBRARY})
endif()
@@ -441,6 +443,15 @@ macro(TEST_SSE_SUPPORT
unset(CMAKE_REQUIRED_FLAGS)
endmacro()
+macro(TEST_STDBOOL_SUPPORT)
+ # This program will compile correctly if and only if
+ # this C compiler supports C99 stdbool.
+ check_c_source_runs("
+ #include <stdbool.h>
+ int main(void) { return (int)false; }"
+ HAVE_STDBOOL_H)
+endmacro()
+
# when we have warnings as errors applied globally this
# needs to be removed for some external libs which we dont maintain.
diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py
index 34f378a58dd..73648be3f15 100755
--- a/build_files/cmake/project_info.py
+++ b/build_files/cmake/project_info.py
@@ -97,7 +97,7 @@ def is_cmake(filename):
def is_c_header(filename):
ext = splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_py(filename):
@@ -141,7 +141,7 @@ def cmake_advanced_info():
if sys.platform == "win32":
cmd = 'cmake "%s" -G"Eclipse CDT4 - MinGW Makefiles"' % CMAKE_DIR
else:
- if make_exe_basename.startswith("make"):
+ if make_exe_basename.startswith(("make", "gmake")):
cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR
elif make_exe_basename.startswith("ninja"):
cmd = 'cmake "%s" -G"Eclipse CDT4 - Ninja"' % CMAKE_DIR
@@ -149,14 +149,19 @@ def cmake_advanced_info():
raise Exception("Unknown make program %r" % make_exe)
os.system(cmd)
+ return join(CMAKE_DIR, ".cproject")
includes = []
defines = []
- create_eclipse_project()
+ project_path = create_eclipse_project()
+
+ if not exists(project_path):
+ print("Generating Eclipse Prokect File Failed: %r not found" % project_path)
+ return None, None
from xml.dom.minidom import parse
- tree = parse(join(CMAKE_DIR, ".cproject"))
+ tree = parse(project_path)
# to check on nicer xml
# f = open(".cproject_pretty", 'w')
diff --git a/build_files/cmake/project_source_info.py b/build_files/cmake/project_source_info.py
index 10bc36ba1a8..90e240c35ef 100644
--- a/build_files/cmake/project_source_info.py
+++ b/build_files/cmake/project_source_info.py
@@ -43,7 +43,7 @@ SOURCE_DIR = abspath(SOURCE_DIR)
def is_c_header(filename):
ext = os.path.splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_c(filename):
@@ -86,15 +86,15 @@ def makefile_log():
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
make_exe_basename = os.path.basename(make_exe)
- if make_exe_basename.startswith("make"):
+ if make_exe_basename.startswith(("make", "gmake")):
print("running 'make' with --dry-run ...")
process = subprocess.Popen([make_exe, "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"],
- stdout=subprocess.PIPE,
+ stdout=subprocess.PIPE,
)
elif make_exe_basename.startswith("ninja"):
print("running 'ninja' with -t commands ...")
process = subprocess.Popen([make_exe, "-t", "commands"],
- stdout=subprocess.PIPE,
+ stdout=subprocess.PIPE,
)
while process.poll():
diff --git a/build_files/package_spec/rpm/blender.spec.in b/build_files/package_spec/rpm/blender.spec.in
index a95fce80103..e75cc8ec7a6 100644
--- a/build_files/package_spec/rpm/blender.spec.in
+++ b/build_files/package_spec/rpm/blender.spec.in
@@ -77,6 +77,7 @@ fi || :
%{_bindir}/%{name}
%{_datadir}/%{name}/%{blender_api}/datafiles/fonts
%{_datadir}/%{name}/%{blender_api}/datafiles/colormanagement
+%{_datadir}/%{name}/%{blender_api}/datafiles/locale/languages
%{_datadir}/%{name}/%{blender_api}/scripts
%{_datadir}/icons/hicolor/*/apps/%{name}.*
%{_datadir}/applications/%{name}.desktop
diff --git a/build_files/scons/config/Modules/FindPython.py b/build_files/scons/config/Modules/FindPython.py
index c93a10351d5..01215753cf7 100644
--- a/build_files/scons/config/Modules/FindPython.py
+++ b/build_files/scons/config/Modules/FindPython.py
@@ -15,6 +15,13 @@ def FindPython():
abi_flags = cur_flags
break
+ # Find config.h. In some distros, such as ubuntu 12.10 they are not in standard include dir.
+ incconf64 = os.path.join(include, "x86_64-linux-gnu", "python" + version + cur_flags, "pyconfig.h")
+ if os.path.exists(incconf64):
+ incconf = os.path.join(include, "x86_64-linux-gnu", "python" + version + cur_flags)
+ else:
+ incconf = ''
+
# Determine whether python is in /usr/lib or /usr/lib64
lib32 = os.path.join(python, "lib", "python" + version, "sysconfig.py")
lib64 = os.path.join(python, "lib64", "python" + version, "sysconfig.py")
@@ -29,4 +36,5 @@ def FindPython():
return {'PYTHON': python,
"VERSION": version,
'LIBPATH': libpath,
- 'ABI_FLAGS': abi_flags}
+ 'ABI_FLAGS': abi_flags,
+ 'CONFIG': incconf}
diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py
index 252a1b1b37e..267505bc449 100644
--- a/build_files/scons/config/darwin-config.py
+++ b/build_files/scons/config/darwin-config.py
@@ -137,7 +137,7 @@ else:
BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}m'
BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
#BF_PYTHON_LIB = ''
- BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-3.2m'
+ BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-${BF_PYTHON_VERSION}m'
WITH_BF_OPENAL = True
#different lib must be used following version of gcc
@@ -165,7 +165,7 @@ BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
WITH_BF_JACK = True
BF_JACK = '/Library/Frameworks/Jackmp.framework'
BF_JACK_INC = '${BF_JACK}/headers'
-BF_JACK_LIB = 'jack'
+#BF_JACK_LIB = 'jack' # not used due framework
BF_JACK_LIBPATH = '${BF_JACK}'
WITH_BF_SNDFILE = True
@@ -315,7 +315,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_13', 'sm_20', 'sm_21']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
#Ray trace optimization
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'i386':
diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py
index 038a9bc421d..bef34727014 100644
--- a/build_files/scons/config/linux-config.py
+++ b/build_files/scons/config/linux-config.py
@@ -1,23 +1,14 @@
-# find library directory
-import platform
-import os
from Modules.FindPython import FindPython
-bitness = platform.architecture()[0]
-if bitness == '64bit':
- LCGDIR = '../lib/linux64'
-else:
- LCGDIR = '../lib/linux'
-LIBDIR = "#${LCGDIR}"
-
py = FindPython()
BF_PYTHON_ABI_FLAGS = py['ABI_FLAGS']
BF_PYTHON = py['PYTHON']
BF_PYTHON_LIBPATH = py['LIBPATH']
+BF_PYTHON_CONFIG = py['CONFIG']
BF_PYTHON_VERSION = py['VERSION']
WITH_BF_STATICPYTHON = False
-BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
+BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS} ' + BF_PYTHON_CONFIG
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}' # BF_PYTHON+'/lib/python'+BF_PYTHON_VERSION+'/config/libpython'+BF_PYTHON_VERSION+'.a'
BF_PYTHON_LINKFLAGS = ['-Xlinker', '-export-dynamic']
@@ -113,7 +104,7 @@ BF_QUICKTIME = '/usr/local'
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
WITH_BF_ICONV = False
-BF_ICONV = LIBDIR + "/iconv"
+BF_ICONV = "/usr"
BF_ICONV_INC = '${BF_ICONV}/include'
BF_ICONV_LIB = 'iconv'
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
@@ -122,18 +113,7 @@ WITH_BF_BINRELOC = True
# enable ffmpeg support
WITH_BF_FFMPEG = True
-BF_FFMPEG = LIBDIR + '/ffmpeg'
-if os.path.exists(LCGDIR + '/ffmpeg'):
- WITH_BF_STATICFFMPEG = True
- BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
- '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
- '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
- '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
- '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
- '${BF_FFMPEG_LIBPATH}/libfaad.a'
-else:
- BF_FFMPEG = '/usr'
+BF_FFMPEG = '/usr'
BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice'
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
@@ -198,34 +178,30 @@ BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib'
BF_JEMALLOC_LIB = 'jemalloc'
BF_JEMALLOC_LIB_STATIC = '${BF_JEMALLOC_LIBPATH}/libjemalloc.a'
-WITH_BF_OIIO = True
+WITH_BF_OIIO = False
WITH_BF_STATICOIIO = False
-BF_OIIO = LIBDIR + '/oiio'
-if not os.path.exists(LCGDIR + '/oiio'):
- WITH_BF_OIIO = False
- BF_OIIO = '/usr'
+BF_OIIO = '/usr'
BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB = 'OpenImageIO'
+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'
-WITH_BF_OCIO = True
+WITH_BF_OCIO = False
WITH_BF_STATICOCIO = False
-BF_OCIO = LIBDIR + '/ocio'
-if not os.path.exists(LCGDIR + '/ocio'):
- WITH_BF_OCIO = False
- BF_OCIO = '/usr'
+BF_OCIO = '/usr'
BF_OCIO_INC = '${BF_OCIO}/include'
BF_OCIO_LIB = 'OpenColorIO yaml-cpp tinyxml'
+BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
WITH_BF_BOOST = True
WITH_BF_STATICBOOST = False
-BF_BOOST = LIBDIR + '/boost'
-if not os.path.exists(LCGDIR + '/boost'):
- WITH_BF_BOOST = False
- BF_BOOST = '/usr'
+BF_BOOST = '/usr'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread'
+BF_BOOST_LIB = 'boost_filesystem boost_regex boost_system boost_thread boost_date_time'
+BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
+ '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a' + \
+ '${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
@@ -233,7 +209,7 @@ WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
WITH_BF_OPENMP = True
@@ -253,8 +229,6 @@ BF_3DMOUSE_LIB_STATIC = '${BF_3DMOUSE_LIBPATH}/libspnav.a'
##
CC = 'gcc'
CXX = 'g++'
-##ifeq ($CPU),alpha)
-## CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -mieee
CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE']
CXXFLAGS = []
@@ -268,22 +242,12 @@ if WITH_BF_FFMPEG:
REL_CFLAGS = []
REL_CXXFLAGS = []
REL_CCFLAGS = ['-DNDEBUG', '-O2']
-##BF_DEPEND = True
-##
-##AR = ar
-##ARFLAGS = ruv
-##ARFLAGSQUIET = ru
-##
+
C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wunused-parameter', '-Wstrict-prototypes', '-Werror=declaration-after-statement', '-Werror=implicit-function-declaration', '-Werror=return-type']
CC_WARN = ['-Wall']
CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
-
-##FIX_STUBS_WARNINGS = -Wno-unused
-
LLIBS = ['util', 'c', 'm', 'dl', 'pthread', 'stdc++']
-##LOPTS = --dynamic
-##DYNLDFLAGS = -shared $(LDFLAGS)
BF_PROFILE = False
BF_PROFILE_CCFLAGS = ['-pg','-g']
@@ -301,4 +265,3 @@ PLATFORM_LINKFLAGS = ['-pthread']
#Fix for LLVM conflict with Mesa llvmpipe
if WITH_BF_LLVM:
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 391421609d2..b5bcbc92665 100644
--- a/build_files/scons/config/win32-mingw-config.py
+++ b/build_files/scons/config/win32-mingw-config.py
@@ -174,7 +174,7 @@ BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
##
CC = 'gcc'
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index 21488e75f7e..8d17c777b0f 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -182,14 +182,14 @@ WITH_BF_STATICOCIO = True
WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
+BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49 libboost_wave-vc90-mt-s-1_49'
BF_BOOST_LIB_INTERNATIONAL = 'libboost_locale-vc90-mt-s-1_49'
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_13', 'sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py
index d00e7a3ffa7..0a604b0f861 100644
--- a/build_files/scons/config/win64-mingw-config.py
+++ b/build_files/scons/config/win64-mingw-config.py
@@ -146,7 +146,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index c0ea7972aeb..4e763343fe6 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -178,14 +178,14 @@ WITH_BF_STATICOCIO = True
WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
+BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49 libboost_wave-vc90-mt-s-1_49'
BF_BOOST_LIB_INTERNATIONAL = ' libboost_locale-vc90-mt-s-1_49'
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_13', 'sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index 94a9f1d9c24..3688a829a4d 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -29,6 +29,7 @@ from SCons.Script.SConscript import SConsEnvironment
import SCons.Action
import SCons.Util
import SCons.Builder
+import SCons.Subst
import SCons.Tool
import bcolors
bc = bcolors.bcolors()
@@ -234,10 +235,6 @@ def setup_staticlibs(lenv):
if lenv['WITH_BF_STATICLLVM']:
statlibs += Split(lenv['BF_LLVM_LIB_STATIC'])
- # setting this last so any overriding of manually libs could be handled
- if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross', 'win64-mingw'):
- libincs.append('/usr/lib')
-
if lenv['WITH_BF_JEMALLOC']:
libincs += Split(lenv['BF_JEMALLOC_LIBPATH'])
if lenv['WITH_BF_STATICJEMALLOC']:
@@ -249,6 +246,12 @@ def setup_staticlibs(lenv):
if lenv['WITH_BF_STATIC3DMOUSE']:
statlibs += Split(lenv['BF_3DMOUSE_LIB_STATIC'])
+ # setting this last so any overriding of manually libs could be handled
+ if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross', 'win64-mingw'):
+ # We must remove any previous items defining this path, for same reason stated above!
+ libincs = [e for e in libincs if SCons.Subst.scons_subst(e, lenv, gvars=lenv.Dictionary()) != "/usr/lib"]
+ libincs.append('/usr/lib')
+
return statlibs, libincs
def setup_syslibs(lenv):
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 19f4ac9a1de..ee6dd20ecc0 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -47,10 +47,10 @@ def get_version():
if (ver_base is not None) and (ver_char is not None) and (ver_cycle is not None):
# eg '2.56a-beta'
- if ver_cycle:
+ if ver_cycle != "release":
ver_display = "%s%s-%s" % (ver_base, ver_char, ver_cycle)
else:
- ver_display = "%s%s" % (ver_base, ver_char) # assume release
+ ver_display = "%s%s" % (ver_base, ver_char)
return ver_base, ver_display, ver_cycle
@@ -108,7 +108,7 @@ def validate_arguments(args, bc):
'WITH_BF_STATICFFMPEG', 'BF_FFMPEG_LIB_STATIC',
'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
'WITH_BF_FRAMESERVER',
- 'WITH_BF_COMPOSITOR', 'WITH_BF_COMPOSITOR_LEGACY',
+ 'WITH_BF_COMPOSITOR',
'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH', 'WITH_BF_STATICJPEG', 'BF_JPEG_LIB_STATIC',
'WITH_BF_OPENJPEG', 'BF_OPENJPEG', 'BF_OPENJPEG_INC', 'BF_OPENJPEG_LIB', 'BF_OPENJPEG_LIBPATH',
'WITH_BF_REDCODE', 'BF_REDCODE', 'BF_REDCODE_INC', 'BF_REDCODE_LIB', 'BF_REDCODE_LIBPATH',
@@ -215,7 +215,8 @@ def print_targets(targs, bc):
def validate_targets(targs, bc):
valid_list = ['.', 'blender', 'blenderstatic', 'blenderplayer', 'webplugin',
'blendernogame', 'blenderstaticnogame', 'blenderlite', 'release',
- 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave']
+ 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave',
+ 'cudakernels']
oklist = []
for t in targs:
if t in valid_list:
@@ -598,7 +599,6 @@ def read_opts(env, cfg, args):
('BF_BOOST_LIB_STATIC', 'Boost static library', ''),
(BoolVariable('WITH_GHOST_XDND', 'Build with drag-n-drop support on Linux platforms using XDND protocol', True)),
- (BoolVariable('WITH_BF_COMPOSITOR_LEGACY', 'Enable the legacy compositor', False)),
(BoolVariable('WITH_BF_CYCLES_OSL', 'Build with OSL sypport in Cycles', False)),
(BoolVariable('WITH_BF_STATICOSL', 'Staticly link to OSL', False)),
@@ -826,6 +826,18 @@ def NSIS_Installer(target=None, source=None, env=None):
print data.strip().split("\n")[-1]
return rv
+def cudakernels_print(target, source, env):
+ return "Running cudakernels target"
+
+def cudakernels(target=None, source=None, env=None):
+ """
+ Builder for cuda kernels compilation. Used by release build environment only
+ """
+
+ # Currently nothing to do, everything is handled by a dependency resolver
+
+ pass
+
def check_environ():
problematic_envvars = ""
for i in os.environ:
diff --git a/doc/license/bf-members.txt b/doc/license/bf-members.txt
index 41aad8b7264..d2f71a56ad5 100644
--- a/doc/license/bf-members.txt
+++ b/doc/license/bf-members.txt
@@ -35,7 +35,7 @@ Eric Van Hensbergen
Christian Reichlin
brian moore
Anthony Walker
-Carsten Hšfer
+Carsten Höfer
Raymond Fordham
David Megginson
Jason Schmidt
@@ -78,7 +78,7 @@ Ken Payne
DEBEUX Sylvain
Douglas Philips
Lai Che Hung
-Johan Bolmsjš
+Johan Bolmsjö
Aaron Mitchell
Teinye Horsfall
Martin Marbach
@@ -98,7 +98,7 @@ lukas schroeder
Dan Lyke
Mark Thorpe
A.D. Arul Nirai Selvan
-Herbert Pštzl
+Herbert Pötzl
Andy Payne
LAFFITTE Benoit (KenjForce)
James Ertle
@@ -148,7 +148,7 @@ Kendall Dugger
Brice Due
Simon Vogl
Bernd Koestler
-clŽment CORDIER
+clément CORDIER
CreationAnimation.com
Pete Carss
HERSEN Antoine
@@ -197,9 +197,9 @@ cadic jean-yves
Ralf Pietersz
KAZY
serge Jadot
-HervŽ LOUINET
+Hervé LOUINET
Tom Houtman
-Magnus Kššhler
+Magnus Kööhler
Martin Sinnaeve
Kevin Yank
Tomoichi Iriyama
@@ -221,12 +221,12 @@ Gianluigi Belli
Naoki Abe
NOTTE Jean-Pierre
Jack Way
-Bjšrn Westlin
+Björn Westlin
Mitch Magee
wizoptic
Jake Edge
David Hoover
-Xabier Go–i
+Xabier Goñi
Daniel Fort
Erik Noteboom
Pavel Vostatek
@@ -234,7 +234,7 @@ Javier Belanche Alonso
Jeffrey Blank
Nathan Ryan
Peter Wrangell
-Josef Sie§
+Josef Sieß
Timm Krumnack
Steve Martin
Shigeru Matsumoto
@@ -261,7 +261,7 @@ Colin Foster
Sascha Adler
Stuart Duncan
Brendon Smith
-SŽbastien COLLETTE
+Sébastien COLLETTE
Clemens Auer
Kay Fricke
Fabian Fagerholm
@@ -282,7 +282,7 @@ STEMax
Jeff Cox
Trevor Ratliff
Matt Henley
-Franois VALETTE
+François VALETTE
Rob Saunders
Mike Luethi
Rami Aubourg-Kaires
@@ -290,9 +290,9 @@ Matthew Thomas
Allan Jacobsen
Adam Lowe
David Hostetler
-Lo•c Vigneras
+Loïc Vigneras
Dan Reiland
-Pedro D’az del Arco
+Pedro Díaz del Arco
Pierre Beyssac
Chris Davey
YOSHIAKI Nishino
@@ -385,7 +385,7 @@ Kiernan Holland
Holger Malessa
Masanori Okuda
Andrea Maracci
-Kai-Peter BŠckman
+Kai-Peter Bäckman
Gregg Patton
Luis M Ibarra
Julian Green
@@ -394,7 +394,7 @@ Mark Winkelman
Ebbe L. Nielsen
Carlos Orozco
magnetHead
-KrŸckel Oliver
+Krückel Oliver
Thomas Ingham
Wes Devauld
Uwe Steinmann
@@ -417,7 +417,7 @@ Steve Mackay
NDNWarrior
Christopher Gray
Darius Clarke (Socinian)
-Jean-SŽbastien SEVESTRE
+Jean-Sébastien SEVESTRE
Douglas Fellows
Craig Symons
Quincin Gonjon
@@ -447,7 +447,7 @@ Markus Q. Roberts
Christoher Bartak
Peter Truog
Eric Dynowski
-Philipp GŸhring
+Philipp Gühring
Pierre-Yves RANNO
Jason Nollan (Cluh)
Launay Jean-Claude
@@ -465,7 +465,7 @@ TROJANI Cedric
David Polston
Patrick Mullen
Tetsuya Okuno
-Bodo JŠger
+Bodo Jäger
Leon Brooks
Cedric Adjih
Michael L. Fisher
@@ -521,7 +521,7 @@ Vincent Stoessel
Adrian Virnig
Chris Dixon
Travis Cole
-MŒrten MŒrtensson
+MÃ¥rten MÃ¥rtensson
Evan Scott
Mark Coletti
Ken Burke
@@ -541,7 +541,7 @@ Iain Russell
Thomas Bleicher
Anthony Zishka
Jefferson Dubrule
-Esa PiirilŠ
+Esa Piirilä
Bill Thiede
William Anderson
Alexander Kittel
@@ -561,7 +561,7 @@ John DiLauro
John Miller
Frederic Crozat
Matt Welland
-Paul CalcŽ
+Paul Calcé
Joe Prochilo
Justin Shafer
Joe Croft
@@ -571,7 +571,7 @@ Alain Gallo
Phuoc Ngo
Krabat
Derek Harmison
-SŽbastien Devine
+Sébastien Devine
Kenneth P. Stox
Wade Felde
Kai Groshert
@@ -603,7 +603,7 @@ Martin Forisch
Guillermina Manon
Randal D. Adams
Kevin Reagh (kevin3D)
-Wolfgang KŸhn
+Wolfgang Kühn
BEAUSOLEIL Arnaud
Stan Jakubek
Klaus Brand
@@ -628,7 +628,7 @@ Samuel Seay
Mike Schaudies
Robert Sherwood
Fernando Villalon Panzano
-Jšrg Roschke
+Jörg Roschke
Carl Symons
Peter Pichler
Alan Heckart
@@ -714,7 +714,7 @@ Rau, Bernhard
Stephen Uithoven
Ken Beyer
Matjaz Jakopec
-Eckhard M. JŠger
+Eckhard M. Jäger
Mike Siebach
John Harger
Justin W. Carper
@@ -747,7 +747,7 @@ Karl Bartel
Ralph Howes
Matthew J. Stott
Omar Priego
-ke Westerstršm
+Åke Westerström
Imago Viva
James E Hill
Rune Myrland
@@ -785,7 +785,7 @@ Claude Bilat
Mario Palomo
Neipi
Grethus Bode
-Jan MŸller
+Jan Müller
Mark Pearson
Stanislav Osicka
DataCare Solutions AG
@@ -804,9 +804,9 @@ Aaron Bredon
Hideki Suzuki
josef radinger
Robert Friemer
-Jšrg Zastrau
+Jörg Zastrau
Burton Bicksler
-Kimmo Mšsš
+Kimmo Mösö
Robert F Johnson
Mark Johnson
Avi Bercovich
@@ -821,21 +821,21 @@ Duffaud
Marco Ardito
Simon Suter
Tobias Huelsdau
-Winfried EnglŠnder
+Winfried Engländer
Stephen Groundwater
Joel Ray Holveck
Mag. Tibor Rudas
Hartmut Wolf
Douglas Jones
brett hartshorn
-Beat MŠgert
+Beat Mägert
Javon Prince
bri
James Klicman
Harvey Fong
jeroen v.d. Meulen
Wim Vandersmissen
-Carlos Moreno Rodr’guez
+Carlos Moreno Rodríguez
Trausti Kristjansson
Larry Snyder
olivier
@@ -887,7 +887,7 @@ Fred Roberts
Njin-Zu Chen
GUILLON Marc
Felix Klock
-Ernesto Salas Rodr’guez
+Ernesto Salas Rodríguez
Pavel Roskin
Jaap
Stefan Maass
@@ -911,7 +911,7 @@ delerue
Dirk Behrens
Doc Holiday
Wouter Kerkhoven
-Andreas BŸttner
+Andreas Büttner
James Black
Nicholas Ward
David Oberbeck
@@ -940,7 +940,7 @@ Ian Whitworth
Ruud H.G. van Tol
Pierre Lo Cicero
Srinivas Digumarty
-digitalvelocity¨
+digitalvelocity®
Alan J Booth
Tony OBrien
Douglas Toltzman
@@ -957,12 +957,12 @@ Craig Spitzer
Jeffrey Van Ness
Lucas Vergnettes
Wolfgang Michaelis
-Luis JimŽnez Linares
+Luis Jiménez Linares
Julian Eden
Ms Lilo von Hanffstengel
Kurt B. Kaiser
Mark Ping
-CombŽe
+Combée
Diego Matho
MELIN Philippe
Damian Sobieralski
@@ -1028,7 +1028,7 @@ evolutie
Stephane Portha
Robert Gentner
David B. Camhy
-RenŽ Foucart
+René Foucart
Coyok Drio
Mark Ng
klein michael
@@ -1094,14 +1094,14 @@ Stuart MacKinnon
Dietrich Dietz - the IMaGiNation project (IMGN)
Tina Hirsch
John R Thorp
-FrŽdŽric Bouvier
+Frédéric Bouvier
LINETTE
Felix Rabe
Chay Adamou
nick harron
stephen john ford
Kino
-Daniel Sjšlie
+Daniel Sjölie
Matthias Derer
Alain VALLETON
Kervin Pierre
@@ -1142,13 +1142,13 @@ Satoshi Yamasaki
Rolf-Dieter Klein
J. Deetman
Helge Walter
-Roland StrŒlberg
+Roland Strålberg
Nicolas Morenas (Caronte)
Simon Clarke
Maigrot Michel
Rod Robinson
Kevin Cozens
-Germ‡n Alonso (taz)
+Germán Alonso (taz)
Martin Stegeman
Henrik Jordfald Olsen
Mitchell Skinner
@@ -1157,7 +1157,7 @@ Spiridon G. Kontarakis
Bas Denissen
Loic Dachary
Michael Rutter
-Thorsten SchlŸter
+Thorsten Schlüter
hijothema
Andreas Hauser
Holger Haase
@@ -1232,9 +1232,9 @@ Starr Kline
John Lullie
Chiffi Cosimo
Morgan McMillian
-Stefan HŸbner
+Stefan Hübner
Loic de MONTAIGNAC
-AndrŽs Castillo
+Andrés Castillo
Francesco Anselmo
Ingo Guenther
James C. Davis, Jr.
@@ -1314,7 +1314,7 @@ Luke Titley
marinus meijers
Henry Kaminski
Alistair Riddoch
-Daniel NŸmm
+Daniel Nümm
Matthew Meadows
Bjoern Paschen
Paul Fredrickson
@@ -1325,7 +1325,7 @@ Thomas Muldowney
Cheyenne Cloud, LLC
Helmut A. Goettl
Martin A. Boegelund
-Beno”t Cousson
+Benoît Cousson
Scott Brooks
Ferlet Patrice
Aaron Porterfield
@@ -1335,13 +1335,13 @@ Rui Paulo Sanguinheira Diogo
Jason Saville
Active-Websight GbR
Bryon Roche
-Gustavo Mu–oz
+Gustavo Muñoz
Christopher Gillanders
Phil Frost Tate
Gilles Gonon
Kay
James C. Franklin
-Luis Enrique Caama–o Navas
+Luis Enrique Caamaño Navas
Alexander "estartu" Felder
Marc Ledermann
vrijschrift.org
@@ -1371,7 +1371,7 @@ Maurizio Sibaud
Ron Bolger
Nathan Parton
Andrew Fry
-VINCENT StŽphane
+VINCENT Stéphane
Yan Yan
Justin L Graham
Wade Beasley
diff --git a/doc/manpage/blender.1 b/doc/manpage/blender.1
index 2addb60c5f7..9cefe7a2b24 100644
--- a/doc/manpage/blender.1
+++ b/doc/manpage/blender.1
@@ -1,4 +1,4 @@
-.TH "BLENDER" "1" "December 04, 2012" "Blender Blender 2\&.65"
+.TH "BLENDER" "1" "February 14, 2013" "Blender Blender 2\&.66"
.SH NAME
blender \- a 3D modelling and rendering package
@@ -15,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business
http://www.blender.org
.SH OPTIONS
-Blender 2.65
+Blender 2.66
Usage: blender [args ...] [file] [args ...]
.br
.SS "Render Options:"
@@ -218,6 +218,12 @@ Turn debugging on
Enable floating point exceptions
.br
+.TP
+.B \-\-disable\-crash\-handler
+.br
+Disable the crash handler
+.br
+
.IP
.TP
@@ -301,7 +307,13 @@ Disable automatic python script execution (pydrivers & startup scripts)
.TP
.B \-P or \-\-python <filename>
.br
-Run the given Python script (filename or Blender Text)
+Run the given Python script file
+.br
+
+.TP
+.B \-\-python\-text <name>
+.br
+Run the given Python script text block
.br
.TP
@@ -398,6 +410,12 @@ Register .blend extension, then exit (Windows only)
Silently register .blend extension, then exit (Windows only)
.br
+.TP
+.B \-\-no\-native\-pixels
+.br
+Do not use native pixel size, for high resolution displays (MacBook 'Retina')
+.br
+
.SS "Argument Parsing:"
arguments must be separated by white space. eg
diff --git a/doc/python_api/examples/bpy.props.5.py b/doc/python_api/examples/bpy.props.5.py
new file mode 100644
index 00000000000..1f61e33c30f
--- /dev/null
+++ b/doc/python_api/examples/bpy.props.5.py
@@ -0,0 +1,89 @@
+"""
+Get/Set Example
+++++++++++++++
+
+Get/Set functions can be used for boolean, int, float, string and enum properties.
+If these callbacks are defined the property will not be stored in the ID properties
+automatically, instead the get/set functions will be called when the property is
+read or written from the API.
+"""
+
+import bpy
+
+
+# Simple property reading/writing from ID properties.
+# This is what the RNA would do internally.
+def get_float(self):
+ return self["testprop"]
+
+
+def set_float(self, value):
+ self["testprop"] = value
+
+bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float)
+
+
+# Read-only string property, returns the current date
+def get_date(self):
+ import datetime
+ return str(datetime.datetime.now())
+
+bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date)
+
+
+# Boolean array. Set function stores a single boolean value, returned as the second component.
+# Array getters must return a list or tuple
+# Array size must match the property vector size exactly
+def get_array(self):
+ return (True, self["somebool"])
+
+
+def set_array(self, values):
+ self["somebool"] = values[0] and values[1]
+
+bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array)
+
+
+# Enum property.
+# Note: the getter/setter callback must use integer identifiers!
+test_items = [
+ ("RED", "Red", "", 1),
+ ("GREEN", "Red", "", 2),
+ ("BLUE", "Red", "", 3),
+ ("YELLOW", "Red", "", 4),
+ ]
+
+
+def get_enum(self):
+ import random
+ return random.randint(1, 4)
+
+
+def set_enum(self, value):
+ print("setting value", value)
+
+bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum)
+
+
+# Testing
+
+scene = bpy.context.scene
+
+scene.test_float = 12.34
+print(scene.test_float)
+
+scene.test_array = (True, False)
+print([x for x in scene.test_array])
+
+#scene.test_date = "blah" # this would fail, property is read-only
+print(scene.test_date)
+
+scene.test_enum = 'BLUE'
+print(scene.test_enum)
+
+
+# >>> 12.34000015258789
+# >>> [True, False]
+# >>> 2013-01-05 16:33:52.135340
+# >>> setting value 3
+# >>> GREEN
diff --git a/doc/python_api/examples/bpy.types.AddonPreferences.1.py b/doc/python_api/examples/bpy.types.AddonPreferences.1.py
new file mode 100644
index 00000000000..73f90acb3fa
--- /dev/null
+++ b/doc/python_api/examples/bpy.types.AddonPreferences.1.py
@@ -0,0 +1,72 @@
+bl_info = {
+ "name": "Example Addon Preferences",
+ "author": "Your Name Here",
+ "version": (1, 0),
+ "blender": (2, 65, 0),
+ "location": "SpaceBar Search -> Addon Preferences Example",
+ "description": "Example Addon",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+import bpy
+from bpy.types import Operator, AddonPreferences
+from bpy.props import StringProperty, IntProperty, BoolProperty
+
+
+class ExampleAddonPreferences(AddonPreferences):
+ # this must match the addon name, use '__package__'
+ # when defining this in a submodule of a python package.
+ bl_idname = __name__
+
+ filepath = StringProperty(
+ name="Example File Path",
+ subtype='FILE_PATH',
+ )
+ number = IntProperty(
+ name="Example Number",
+ default=4,
+ )
+ boolean = BoolProperty(
+ name="Example Boolean",
+ default=False,
+ )
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label(text="This is a preferences view for our addon")
+ layout.prop(self, "filepath")
+ layout.prop(self, "number")
+ layout.prop(self, "boolean")
+
+
+class OBJECT_OT_addon_prefs_example(Operator):
+ """Display example preferences"""
+ bl_idname = "object.addon_prefs_example"
+ bl_label = "Addon Preferences Example"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ user_preferences = context.user_preferences
+ addon_prefs = user_preferences.addons[__name__].preferences
+
+ info = ("Path: %s, Number: %d, Boolean %r" %
+ (addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean))
+
+ self.report({'INFO'}, info)
+ print(info)
+
+ return {'FINISHED'}
+
+
+# Registration
+def register():
+ bpy.utils.register_class(OBJECT_OT_addon_prefs_example)
+ bpy.utils.register_class(ExampleAddonPreferences)
+
+
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_addon_prefs_example)
+ bpy.utils.unregister_class(ExampleAddonPreferences)
diff --git a/doc/python_api/examples/bpy.types.UIList.py b/doc/python_api/examples/bpy.types.UIList.py
new file mode 100644
index 00000000000..0f4ae0703cc
--- /dev/null
+++ b/doc/python_api/examples/bpy.types.UIList.py
@@ -0,0 +1,90 @@
+"""
+Basic UIList Example
++++++++++++++++++++
+This script is the UIList subclass used to show material slots, with a bunch of additional commentaries.
+
+Notice the name of the class, this naming convention is similar as the one for panels or menus.
+
+.. note::
+
+ UIList subclasses must be registered for blender to use them.
+"""
+import bpy
+
+
+class MATERIAL_UL_matslots_example(bpy.types.UIList):
+ # The draw_item function is called for each item of the collection that is visible in the list.
+ # data is the RNA object containing the collection,
+ # item is the current drawn item of the collection,
+ # icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
+ # have custom icons ID, which are not available as enum items).
+ # active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
+ # active item of the collection).
+ # active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
+ # index is index of the current item in the collection.
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ ob = data
+ slot = item
+ ma = slot.material
+ # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ # You should always start your row layout by a label (icon + text), this will also make the row easily
+ # selectable in the list!
+ # We use icon_value of label, as our given icon is an integer value, not an enum ID.
+ # Note "data" names should never be translated!
+ layout.label(text=ma.name if ma else "", translate=False, icon_value=icon)
+ # And now we can add other UI stuff...
+ # Here, we add nodes info if this material uses (old!) shading nodes.
+ if ma and not context.scene.render.use_shading_nodes:
+ manode = ma.active_node_material
+ if manode:
+ # The static method UILayout.icon returns the integer value of the icon ID "computed" for the given
+ # RNA object.
+ layout.label(text="Node %s" % manode.name, translate=False, icon_value=layout.icon(manode))
+ elif ma.use_nodes:
+ layout.label(text="Node <none>", translate=False)
+ else:
+ layout.label(text="")
+ # 'GRID' layout type should be as compact as possible (typically a single icon!).
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
+# And now we can use this list everywhere in Blender. Here is a small example panel.
+class UIListPanelExample(bpy.types.Panel):
+ """Creates a Panel in the Object properties window"""
+ bl_label = "UIList Panel"
+ bl_idname = "OBJECT_PT_ui_list_example"
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "object"
+
+ def draw(self, context):
+ layout = self.layout
+
+ obj = context.object
+
+ # template_list now takes two new args.
+ # The first one is the identifier of the registered UIList to use (if you want only the default list,
+ # with no custom draw code, use "UI_UL_list").
+ layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index")
+
+ # The second one can usually be left as an empty string. It's an additional ID used to distinguish lists in case you
+ # use the same list several times in a given area.
+ layout.template_list("MATERIAL_UL_matslots_example", "compact", obj, "material_slots",
+ obj, "active_material_index", type='COMPACT')
+
+
+def register():
+ bpy.utils.register_class(MATERIAL_UL_matslots_example)
+ bpy.utils.register_class(UIListPanelExample)
+
+
+def unregister():
+ bpy.utils.unregister_class(MATERIAL_UL_matslots_example)
+ bpy.utils.unregister_class(UIListPanelExample)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/doc/python_api/rst/bge.events.rst b/doc/python_api/rst/bge.events.rst
index 074e928f0d8..2238faea242 100644
--- a/doc/python_api/rst/bge.events.rst
+++ b/doc/python_api/rst/bge.events.rst
@@ -69,7 +69,7 @@ Functions
Return the string name of a key event. Will raise a ValueError error if its invalid.
- :arg event: key event from bge.keys or the keyboard sensor.
+ :arg event: key event constant from :mod:`bge.events` or the keyboard sensor.
:type event: int
:rtype: string
@@ -78,7 +78,7 @@ Functions
Return the string name of a key event. Returns an empty string if the event cant be represented as a character.
:type event: int
- :arg event: key event from :mod:`bge.keys` or the keyboard sensor.
+ :arg event: key event constant from :mod:`bge.events` or the keyboard sensor.
:type shift: bool
:arg shift: set to true if shift is held.
:rtype: string
diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst
index 7d20aa31a36..944b1ca06a0 100644
--- a/doc/python_api/rst/bge.logic.rst
+++ b/doc/python_api/rst/bge.logic.rst
@@ -125,6 +125,10 @@ Variables
The current mouse wrapped in an :class:`~bge.types.SCA_PythonMouse` object.
+.. data:: joysticks
+
+ A list of attached joysticks. The list size it he maximum number of supported joysticks. If no joystick is available for a given slot, the slot is set to None.
+
*****************
General functions
*****************
@@ -172,7 +176,7 @@ General functions
Restarts the current game by reloading the .blend file (the last saved version, not what is currently running).
-.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True)
+.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True, async=False)
Converts the all of the datablocks of the given type from the given blend.
@@ -187,7 +191,13 @@ General functions
:arg verbose: Whether or not to print debugging information (e.g., "SceneName: Scene")
:type verbose: bool
:arg load_scripts: Whether or not to load text datablocks as well (can be disabled for some extra security)
- :type load_scripts: bool
+ :type load_scripts: bool
+ :arg async: Whether or not to do the loading asynchronously (in another thread). Only the "Scene" type is currently supported for this feature.
+ :type async: bool
+
+ :rtype: :class:`bge.types.KX_LibLoadStatus`
+
+ .. note:: Asynchronously loaded libraries will not be available immediately after LibLoad() returns. Use the returned KX_LibLoadStatus to figure out when the libraries are ready.
.. function:: LibNew(name, type, data)
diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst
index 8cf9ccb794c..f24cc3f998c 100644
--- a/doc/python_api/rst/bge.types.rst
+++ b/doc/python_api/rst/bge.types.rst
@@ -31,5263 +31,8 @@ a :class:`SCA_PythonController` logic brick.
Types
*****
-.. class:: PyObjectPlus
+.. toctree::
+ :glob:
- PyObjectPlus base class of most other types in the Game Engine.
+ bge.types.*
- .. attribute:: invalid
-
- Test if the object has been freed by the game engine and is no longer valid.
-
- Normally this is not a problem but when storing game engine data in the GameLogic module,
- KX_Scenes or other KX_GameObjects its possible to hold a reference to invalid data.
- Calling an attribute or method on an invalid object will raise a SystemError.
-
- The invalid attribute allows testing for this case without exception handling.
-
- :type: boolean
-
-.. class:: CValue(PyObjectPlus)
-
- This class is a basis for other classes.
-
- .. attribute:: name
-
- The name of this CValue derived object (read-only).
-
- :type: string
-
-.. class:: CPropValue(CValue)
-
- This class has no python functions
-
-.. class:: SCA_ILogicBrick(CValue)
-
- Base class for all logic bricks.
-
- .. attribute:: executePriority
-
- This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first).
-
- :type: executePriority: int
-
- .. attribute:: owner
-
- The game object this logic brick is attached to (read-only).
-
- :type: :class:`KX_GameObject` or None in exceptional cases.
-
- .. attribute:: name
-
- The name of this logic brick (read-only).
-
- :type: string
-
-.. class:: SCA_PythonKeyboard(PyObjectPlus)
-
- The current keyboard.
-
- .. attribute:: events
-
- A dictionary containing the status of each keyboard event or key. (read-only).
-
- :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
-
- .. attribute:: active_events
-
- A dictionary containing the status of only the active keyboard events or keys. (read-only).
-
- :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
-
-
- .. function:: getClipboard()
-
- Gets the clipboard text.
-
- :rtype: string
-
- .. function:: setClipboard(text)
-
- Sets the clipboard text.
-
- :arg text: New clipboard text
- :type text: string
-
-.. class:: SCA_PythonMouse(PyObjectPlus)
-
- The current mouse.
-
- .. attribute:: events
-
- a dictionary containing the status of each mouse event. (read-only).
-
- :type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
-
- .. attribute:: active_events
-
- a dictionary containing the status of only the active mouse events. (read-only).
-
- :type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
-
- .. attribute:: position
-
- The normalized x and y position of the mouse cursor.
-
- :type: list [x, y]
-
- .. attribute:: visible
-
- The visibility of the mouse cursor.
-
- :type: boolean
-
-.. class:: SCA_IObject(CValue)
-
- This class has no python functions
-
-.. class:: SCA_ISensor(SCA_ILogicBrick)
-
- Base class for all sensor logic bricks.
-
- .. attribute:: usePosPulseMode
-
- Flag to turn positive pulse mode on and off.
-
- :type: boolean
-
- .. attribute:: useNegPulseMode
-
- Flag to turn negative pulse mode on and off.
-
- :type: boolean
-
- .. attribute:: frequency
-
- The frequency for pulse mode sensors.
-
- :type: integer
-
- .. attribute:: level
-
- level Option whether to detect level or edge transition when entering a state.
- It makes a difference only in case of logic state transition (state actuator).
- A level detector will immediately generate a pulse, negative or positive
- depending on the sensor condition, as soon as the state is activated.
- A edge detector will wait for a state change before generating a pulse.
- note: mutually exclusive with :data:`tap`, enabling will disable :data:`tap`.
-
- :type: boolean
-
- .. attribute:: tap
-
- When enabled only sensors that are just activated will send a positive event,
- after this they will be detected as negative by the controllers.
- This will make a key thats held act as if its only tapped for an instant.
- note: mutually exclusive with :data:`level`, enabling will disable :data:`level`.
-
- :type: boolean
-
- .. attribute:: invert
-
- Flag to set if this sensor activates on positive or negative events.
-
- :type: boolean
-
- .. attribute:: triggered
-
- True if this sensor brick is in a positive state. (read-only).
-
- :type: boolean
-
- .. attribute:: positive
-
- True if this sensor brick is in a positive state. (read-only).
-
- :type: boolean
-
- .. attribute:: pos_ticks
-
- The number of ticks since the last positive pulse (read-only).
-
- :type: int
-
- .. attribute:: neg_ticks
-
- The number of ticks since the last negative pulse (read-only).
-
- :type: int
-
- .. attribute:: status
-
- The status of the sensor (read-only): can be one of :ref:`these constants<sensor-status>`.
-
- :type: int
-
- .. note::
-
- This convenient attribute combines the values of triggered and positive attributes.
-
- .. method:: reset()
-
- Reset sensor internal state, effect depends on the type of sensor and settings.
-
- The sensor is put in its initial state as if it was just activated.
-
-.. class:: SCA_IController(SCA_ILogicBrick)
-
- Base class for all controller logic bricks.
-
- .. attribute:: state
-
- The controllers state bitmask. This can be used with the GameObject's state to test if the controller is active.
-
- :type: int bitmask
-
- .. attribute:: sensors
-
- A list of sensors linked to this controller.
-
- :type: sequence supporting index/string lookups and iteration.
-
- .. note::
-
- The sensors are not necessarily owned by the same object.
-
- .. note::
-
- When objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
-
- .. attribute:: actuators
-
- A list of actuators linked to this controller.
-
- :type: sequence supporting index/string lookups and iteration.
-
- .. note::
-
- The sensors are not necessarily owned by the same object.
-
- .. note::
-
- When objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
-
- .. attribute:: useHighPriority
-
- When set the controller executes always before all other controllers that dont have this set.
-
- :type: boolen
-
- .. note::
-
- Order of execution between high priority controllers is not guaranteed.
-
-.. class:: SCA_IActuator(SCA_ILogicBrick)
-
- Base class for all actuator logic bricks.
-
-.. class:: BL_ActionActuator(SCA_IActuator)
-
- Action Actuators apply an action to an actor.
-
- .. attribute:: action
-
- The name of the action to set as the current action.
-
- :type: string
-
- .. attribute:: frameStart
-
- Specifies the starting frame of the animation.
-
- :type: float
-
- .. attribute:: frameEnd
-
- Specifies the ending frame of the animation.
-
- :type: float
-
- .. attribute:: blendIn
-
- Specifies the number of frames of animation to generate when making transitions between actions.
-
- :type: float
-
- .. attribute:: priority
-
- Sets the priority of this actuator. Actuators will lower priority numbers will override actuators with higher numbers.
-
- :type: integer
-
- .. attribute:: frame
-
- Sets the current frame for the animation.
-
- :type: float
-
- .. attribute:: propName
-
- Sets the property to be used in FromProp playback mode.
-
- :type: string
-
- .. attribute:: blendTime
-
- Sets the internal frame timer. This property must be in the range from 0.0 to blendIn.
-
- :type: float
-
- .. attribute:: mode
-
- The operation mode of the actuator. Can be one of :ref:`these constants<action-actuator>`.
-
- :type: integer
-
- .. attribute:: useContinue
-
- The actions continue option, True or False. When True, the action will always play from where last left off,
- otherwise negative events to this actuator will reset it to its start frame.
-
- :type: boolean
-
- .. attribute:: framePropName
-
- The name of the property that is set to the current frame number.
-
- :type: string
-
-.. class:: BL_Shader(PyObjectPlus)
-
- BL_Shader GLSL shaders.
-
- TODO - Description
-
- .. method:: setUniformfv(name, fList)
-
- Set a uniform with a list of float values
-
- :arg name: the uniform name
- :type name: string
- :arg fList: a list (2, 3 or 4 elements) of float values
- :type fList: list[float]
-
- .. method:: delSource()
-
- Clear the shader. Use this method before the source is changed with :data:`setSource`.
-
- .. method:: getFragmentProg()
-
- Returns the fragment program.
-
- :return: The fragment program.
- :rtype: string
-
- .. method:: getVertexProg()
-
- Get the vertex program.
-
- :return: The vertex program.
- :rtype: string
-
- .. method:: isValid()
-
- Check if the shader is valid.
-
- :return: True if the shader is valid
- :rtype: boolean
-
- .. method:: setAttrib(enum)
-
- Set attribute location. (The parameter is ignored a.t.m. and the value of "tangent" is always used.)
-
- :arg enum: attribute location value
- :type enum: integer
-
- .. method:: setNumberOfPasses( max_pass )
-
- Set the maximum number of passes. Not used a.t.m.
-
- :arg max_pass: the maximum number of passes
- :type max_pass: integer
-
- .. method:: setSampler(name, index)
-
- Set uniform texture sample index.
-
- :arg name: Uniform name
- :type name: string
- :arg index: Texture sample index.
- :type index: integer
-
- .. method:: setSource(vertexProgram, fragmentProgram)
-
- Set the vertex and fragment programs
-
- :arg vertexProgram: Vertex program
- :type vertexProgram: string
- :arg fragmentProgram: Fragment program
- :type fragmentProgram: string
-
- .. method:: setUniform1f(name, fx)
-
- Set a uniform with 1 float value.
-
- :arg name: the uniform name
- :type name: string
- :arg fx: Uniform value
- :type fx: float
-
- .. method:: setUniform1i(name, ix)
-
- Set a uniform with an integer value.
-
- :arg name: the uniform name
- :type name: string
- :arg ix: the uniform value
- :type ix: integer
-
- .. method:: setUniform2f(name, fx, fy)
-
- Set a uniform with 2 float values
-
- :arg name: the uniform name
- :type name: string
- :arg fx: first float value
- :type fx: float
-
- :arg fy: second float value
- :type fy: float
-
- .. method:: setUniform2i(name, ix, iy)
-
- Set a uniform with 2 integer values
-
- :arg name: the uniform name
- :type name: string
- :arg ix: first integer value
- :type ix: integer
- :arg iy: second integer value
- :type iy: integer
-
- .. method:: setUniform3f(name, fx, fy, fz)
-
- Set a uniform with 3 float values.
-
- :arg name: the uniform name
- :type name: string
- :arg fx: first float value
- :type fx: float
- :arg fy: second float value
- :type fy: float
- :arg fz: third float value
- :type fz: float
-
- .. method:: setUniform3i(name, ix, iy, iz)
-
- Set a uniform with 3 integer values
-
- :arg name: the uniform name
- :type name: string
- :arg ix: first integer value
- :type ix: integer
- :arg iy: second integer value
- :type iy: integer
- :arg iz: third integer value
- :type iz: integer
-
- .. method:: setUniform4f(name, fx, fy, fz, fw)
-
- Set a uniform with 4 float values.
-
- :arg name: the uniform name
- :type name: string
- :arg fx: first float value
- :type fx: float
- :arg fy: second float value
- :type fy: float
- :arg fz: third float value
- :type fz: float
- :arg fw: fourth float value
- :type fw: float
-
- .. method:: setUniform4i(name, ix, iy, iz, iw)
-
- Set a uniform with 4 integer values
-
- :arg name: the uniform name
- :type name: string
- :arg ix: first integer value
- :type ix: integer
- :arg iy: second integer value
- :type iy: integer
- :arg iz: third integer value
- :type iz: integer
- :arg iw: fourth integer value
- :type iw: integer
-
- .. method:: setUniformDef(name, type)
-
- Define a new uniform
-
- :arg name: the uniform name
- :type name: string
- :arg type: uniform type
- :type type: UNI_NONE, UNI_INT, UNI_FLOAT, UNI_INT2, UNI_FLOAT2, UNI_INT3, UNI_FLOAT3, UNI_INT4, UNI_FLOAT4, UNI_MAT3, UNI_MAT4, UNI_MAX
-
- .. method:: setUniformMatrix3(name, mat, transpose)
-
- Set a uniform with a 3x3 matrix value
-
- :arg name: the uniform name
- :type name: string
- :arg mat: A 3x3 matrix [[f, f, f], [f, f, f], [f, f, f]]
- :type mat: 3x3 matrix
- :arg transpose: set to True to transpose the matrix
- :type transpose: boolean
-
- .. method:: setUniformMatrix4(name, mat, transpose)
-
- Set a uniform with a 4x4 matrix value
-
- :arg name: the uniform name
- :type name: string
- :arg mat: A 4x4 matrix [[f, f, f, f], [f, f, f, f], [f, f, f, f], [f, f, f, f]]
- :type mat: 4x4 matrix
- :arg transpose: set to True to transpose the matrix
- :type transpose: boolean
-
- .. method:: setUniformiv(name, iList)
-
- Set a uniform with a list of integer values
-
- :arg name: the uniform name
- :type name: string
- :arg iList: a list (2, 3 or 4 elements) of integer values
- :type iList: list[integer]
-
- .. method:: validate()
-
- Validate the shader object.
-
-.. class:: BL_ShapeActionActuator(SCA_IActuator)
-
- ShapeAction Actuators apply an shape action to an mesh object.
-
- .. attribute:: action
-
- The name of the action to set as the current shape action.
-
- :type: string
-
- .. attribute:: frameStart
-
- Specifies the starting frame of the shape animation.
-
- :type: float
-
- .. attribute:: frameEnd
-
- Specifies the ending frame of the shape animation.
-
- :type: float
-
- .. attribute:: blendIn
-
- Specifies the number of frames of animation to generate when making transitions between actions.
-
- :type: float
-
- .. attribute:: priority
-
- Sets the priority of this actuator. Actuators will lower priority numbers will override actuators with higher numbers.
-
- :type: integer
-
- .. attribute:: frame
-
- Sets the current frame for the animation.
-
- :type: float
-
- .. attribute:: propName
-
- Sets the property to be used in FromProp playback mode.
-
- :type: string
-
- .. attribute:: blendTime
-
- Sets the internal frame timer. This property must be in the range from 0.0 to blendin.
-
- :type: float
-
- .. attribute:: mode
-
- The operation mode of the actuator. Can be one of :ref:`these constants<shape-action-actuator>`.
-
- :type: integer
-
- .. attribute:: framePropName
-
- The name of the property that is set to the current frame number.
-
- :type: string
-
-
-.. class:: KX_SteeringActuator(SCA_IActuator)
-
- Steering Actuator for navigation.
-
- .. attribute:: behavior
-
- The steering behavior to use.
-
- :type: one of :ref:`these constants <logic-steering-actuator>`
-
- .. attribute:: velocity
-
- Velocity magnitude
-
- :type: float
-
- .. attribute:: acceleration
-
- Max acceleration
-
- :type: float
-
- .. attribute:: turnspeed
-
- Max turn speed
-
- :type: float
-
- .. attribute:: distance
-
- Relax distance
-
- :type: float
-
- .. attribute:: target
-
- Target object
-
- :type: :class:`KX_GameObject`
-
- .. attribute:: navmesh
-
- Navigation mesh
-
- :type: :class:`KX_GameObject`
-
- .. attribute:: selfterminated
-
- Terminate when target is reached
-
- :type: boolean
-
- .. attribute:: enableVisualization
-
- Enable debug visualization
-
- :type: boolean
-
- .. attribute:: pathUpdatePeriod
-
- Path update period
-
- :type: int
-
-.. class:: CListValue(CPropValue)
-
- This is a list like object used in the game engine internally that behaves similar to a python list in most ways.
-
- As well as the normal index lookup (``val= clist[i]``), CListValue supports string lookups (``val= scene.objects["Cube"]``)
-
- Other operations such as ``len(clist)``, ``list(clist)``, ``clist[0:10]`` are also supported.
-
- .. method:: append(val)
-
- Add an item to the list (like pythons append)
-
- .. warning::
-
- Appending values to the list can cause crashes when the list is used internally by the game engine.
-
- .. method:: count(val)
-
- Count the number of instances of a value in the list.
-
- :return: number of instances
- :rtype: integer
-
- .. method:: index(val)
-
- Return the index of a value in the list.
-
- :return: The index of the value in the list.
- :rtype: integer
-
- .. method:: reverse()
-
- Reverse the order of the list.
-
- .. method:: get(key, default=None)
-
- Return the value matching key, or the default value if its not found.
-
- :return: The key value or a default.
-
- .. method:: from_id(id)
-
- This is a funtion especially for the game engine to return a value with a spesific id.
-
- Since object names are not always unique, the id of an object can be used to get an object from the CValueList.
-
- Example:
-
- .. code-block:: python
-
- myObID=id(gameObject)
- ob= scene.objects.from_id(myObID)
-
- Where ``myObID`` is an int or long from the id function.
-
- This has the advantage that you can store the id in places you could not store a gameObject.
-
- .. warning::
-
- The id is derived from a memory location and will be different each time the game engine starts.
-
- .. warning::
-
- The id can't be stored as an integer in game object properties, as those only have a limited range that the id may not be contained in. Instead an id can be stored as a string game property and converted back to an integer for use in from_id lookups.
-
-.. class:: KX_BlenderMaterial(PyObjectPlus)
-
- KX_BlenderMaterial
-
- .. attribute:: shader
-
- The materials shader.
-
- :type: :class:`BL_Shader`
-
- .. attribute:: blending
-
- Ints used for pixel blending, (src, dst), matching the setBlending method.
-
- :type: (integer, integer)
-
- .. attribute:: material_index
-
- The material's index.
-
- :type: integer
-
- .. method:: getShader()
-
- Returns the material's shader.
-
- :return: the material's shader
- :rtype: :class:`BL_Shader`
-
- .. method:: setBlending(src, dest)
-
- Set the pixel color arithmetic functions.
-
- :arg src: Specifies how the red, green, blue, and alpha source blending factors are computed.
- :type src: Value in...
-
- * GL_ZERO,
- * GL_ONE,
- * GL_SRC_COLOR,
- * GL_ONE_MINUS_SRC_COLOR,
- * GL_DST_COLOR,
- * GL_ONE_MINUS_DST_COLOR,
- * GL_SRC_ALPHA,
- * GL_ONE_MINUS_SRC_ALPHA,
- * GL_DST_ALPHA,
- * GL_ONE_MINUS_DST_ALPHA,
- * GL_SRC_ALPHA_SATURATE
-
- :arg dest: Specifies how the red, green, blue, and alpha destination blending factors are computed.
- :type dest: Value in...
-
- * GL_ZERO
- * GL_ONE
- * GL_SRC_COLOR
- * GL_ONE_MINUS_SRC_COLOR
- * GL_DST_COLOR
- * GL_ONE_MINUS_DST_COLOR
- * GL_SRC_ALPHA
- * GL_ONE_MINUS_SRC_ALPHA
- * GL_DST_ALPHA
- * GL_ONE_MINUS_DST_ALPHA
- * GL_SRC_ALPHA_SATURATE
-
- .. method:: getMaterialIndex()
-
- Returns the material's index.
-
- :return: the material's index
- :rtype: integer
-
-.. class:: KX_CameraActuator(SCA_IActuator)
-
- Applies changes to a camera.
-
- .. attribute:: damping
-
- strength of of the camera following movement.
-
- :type: float
-
- .. attribute:: axis
-
- The camera axis (0, 1, 2) for positive ``XYZ``, (3, 4, 5) for negative ``XYZ``.
-
- :type: int
-
- .. attribute:: min
-
- minimum distance to the target object maintained by the actuator.
-
- :type: float
-
- .. attribute:: max
-
- maximum distance to stay from the target object.
-
- :type: float
-
- .. attribute:: height
-
- height to stay above the target object.
-
- :type: float
-
- .. attribute:: object
-
- the object this actuator tracks.
-
- :type: :class:`KX_GameObject` or None
-
-.. class:: KX_ConstraintActuator(SCA_IActuator)
-
- A constraint actuator limits the position, rotation, distance or orientation of an object.
-
- .. attribute:: damp
-
- Time constant of the constraint expressed in frame (not use by Force field constraint).
-
- :type: integer
-
- .. attribute:: rotDamp
-
- Time constant for the rotation expressed in frame (only for the distance constraint), 0 = use damp for rotation as well.
-
- :type: integer
-
- .. attribute:: direction
-
- The reference direction in world coordinate for the orientation constraint.
-
- :type: 3-tuple of float: (x, y, z)
-
- .. attribute:: option
-
- Binary combination of :ref:`these constants <constraint-actuator-option>`
-
- :type: integer
-
- .. attribute:: time
-
- activation time of the actuator. The actuator disables itself after this many frame. If set to 0, the actuator is not limited in time.
-
- :type: integer
-
- .. attribute:: propName
-
- the name of the property or material for the ray detection of the distance constraint.
-
- :type: string
-
- .. attribute:: min
-
- The lower bound of the constraint. For the rotation and orientation constraint, it represents radiant.
-
- :type: float
-
- .. attribute:: distance
-
- the target distance of the distance constraint.
-
- :type: float
-
- .. attribute:: max
-
- the upper bound of the constraint. For rotation and orientation constraints, it represents radiant.
-
- :type: float
-
- .. attribute:: rayLength
-
- the length of the ray of the distance constraint.
-
- :type: float
-
- .. attribute:: limit
-
- type of constraint. Use one of the :ref:`these constants <constraint-actuator-limit>`
-
- :type: integer.
-
-
-.. class:: KX_ConstraintWrapper(PyObjectPlus)
-
- KX_ConstraintWrapper
-
- .. method:: getConstraintId(val)
-
- Returns the contraint's ID
-
- :return: the constraint's ID
- :rtype: integer
-
-.. class:: KX_GameActuator(SCA_IActuator)
-
- The game actuator loads a new .blend file, restarts the current .blend file or quits the game.
-
- .. attribute:: fileName
-
- the new .blend file to load.
-
- :type: string
-
- .. attribute:: mode
-
- The mode of this actuator. Can be on of :ref:`these constants <game-actuator>`
-
- :type: Int
-
-.. class:: KX_GameObject(SCA_IObject)
-
- All game objects are derived from this class.
-
- Properties assigned to game objects are accessible as attributes of this class.
-
- .. note::
-
- Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError,
- if an object may have been removed since last accessing it use the :data:`invalid` attribute to check.
-
- KX_GameObject can be subclassed to extend functionality. For example:
-
- .. code-block:: python
-
- import bge
-
- class CustomGameObject(bge.types.KX_GameObject):
- RATE = 0.05
-
- def __init__(self, old_owner):
- # "old_owner" can just be ignored. At this point, "self" is
- # already the object in the scene, and "old_owner" has been
- # destroyed.
-
- # New attributes can be defined - but we could also use a game
- # property, like "self['rate']".
- self.rate = CustomGameObject.RATE
-
- def update(self):
- self.worldPosition.z += self.rate
-
- # switch direction
- if self.worldPosition.z > 1.0:
- self.rate = -CustomGameObject.RATE
- elif self.worldPosition.z < 0.0:
- self.rate = CustomGameObject.RATE
-
- # Called first
- def mutate(cont):
- old_object = cont.owner
- mutated_object = CustomGameObject(cont.owner)
-
- # After calling the constructor above, references to the old object
- # should not be used.
- assert(old_object is not mutated_object)
- assert(old_object.invalid)
- assert(mutated_object is cont.owner)
-
- # Called later - note we are now working with the mutated object.
- def update(cont):
- cont.owner.update()
-
- When subclassing objects other than empties and meshes, the specific type
- should be used - e.g. inherit from :class:`BL_ArmatureObject` when the object
- to mutate is an armature.
-
- .. attribute:: name
-
- The object's name. (read-only).
-
- :type: string
-
- .. attribute:: mass
-
- The object's mass
-
- :type: float
-
- .. note::
-
- The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0.
-
- .. attribute:: linVelocityMin
-
- Enforces the object keeps moving at a minimum velocity.
-
- :type: float
-
- .. note::
-
- Applies to dynamic and rigid body objects only.
-
- .. note::
-
- A value of 0.0 disables this option.
-
- .. note::
-
- While objects are stationary the minimum velocity will not be applied.
-
- .. attribute:: linVelocityMax
-
- Clamp the maximum linear velocity to prevent objects moving beyond a set speed.
-
- :type: float
-
- .. note::
-
- Applies to dynamic and rigid body objects only.
-
- .. note::
-
- A value of 0.0 disables this option (rather then setting it stationary).
-
- .. attribute:: localInertia
-
- the object's inertia vector in local coordinates. Read only.
-
- :type: list [ix, iy, iz]
-
- .. attribute:: parent
-
- The object's parent object. (read-only).
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: groupMembers
-
- Returns the list of group members if the object is a group object, 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.
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: scene
-
- The object's scene. (read-only).
-
- :type: :class:`KX_Scene` or None
-
- .. attribute:: visible
-
- visibility flag.
-
- :type: boolean
-
- .. note::
-
- Game logic will still run for invisible objects.
-
- .. attribute:: color
-
- The object color of the object. [r, g, b, a]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: occlusion
-
- occlusion capability flag.
-
- :type: boolean
-
- .. attribute:: position
-
- The object's position. [x, y, z] On write: local position, on read: world position
-
- .. deprecated:: use :data:`localPosition` and :data:`worldPosition`.
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: orientation
-
- The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. On write: local orientation, on read: world orientation
-
- .. deprecated:: use :data:`localOrientation` and :data:`worldOrientation`.
-
- :type: :class:`mathutils.Matrix`
-
- .. attribute:: scaling
-
- The object's scaling factor. [sx, sy, sz] On write: local scaling, on read: world scaling
-
- .. deprecated:: use :data:`localScale` and :data:`worldScale`.
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: localOrientation
-
- The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector.
-
- :type: :class:`mathutils.Matrix`
-
- .. attribute:: worldOrientation
-
- The object's world orientation. 3x3 Matrix.
-
- :type: :class:`mathutils.Matrix`
-
- .. attribute:: localScale
-
- The object's local scaling factor. [sx, sy, sz]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: worldScale
-
- The object's world scaling factor. [sx, sy, sz]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: localPosition
-
- The object's local position. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: worldPosition
-
- The object's world position. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: localTransform
-
- The object's local space transform matrix. 4x4 Matrix.
-
- :type: :class:`mathutils.Matrix`
-
- .. attribute:: worldTransform
-
- The object's world space transform matrix. 4x4 Matrix.
-
- :type: :class:`mathutils.Matrix`
-
- .. attribute:: localLinearVelocity
-
- The object's local linear velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: worldLinearVelocity
-
- The object's world linear velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: localAngularVelocity
-
- The object's local angular velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: worldAngularVelocity
-
- The object's world angular velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
- .. attribute:: timeOffset
-
- adjust the slowparent delay at runtime.
-
- :type: float
-
- .. attribute:: state
-
- the game object's state bitmask, using the first 30 bits, one bit must always be set.
-
- :type: int
-
- .. attribute:: meshes
-
- a list meshes for this object.
-
- :type: list of :class:`KX_MeshProxy`
-
- .. note::
-
- Most objects use only 1 mesh.
-
- .. note::
-
- Changes to this list will not update the KX_GameObject.
-
- .. attribute:: sensors
-
- a sequence of :class:`SCA_ISensor` objects with string/index lookups and iterator support.
-
- :type: list
-
- .. note::
-
- This attribute is experemental and may be removed (but probably wont be).
-
- .. note::
-
- Changes to this list will not update the KX_GameObject.
-
- .. attribute:: controllers
-
- a sequence of :class:`SCA_IController` objects with string/index lookups and iterator support.
-
- :type: list of :class:`SCA_ISensor`
-
- .. note::
-
- This attribute is experemental and may be removed (but probably wont be).
-
- .. note::
-
- Changes to this list will not update the KX_GameObject.
-
- .. attribute:: actuators
-
- a list of :class:`SCA_IActuator` with string/index lookups and iterator support.
-
- :type: list
-
- .. note::
-
- This attribute is experemental and may be removed (but probably wont be).
-
- .. note::
-
- Changes to this list will not update the KX_GameObject.
-
- .. attribute:: attrDict
-
- get the objects internal python attribute dictionary for direct (faster) access.
-
- :type: dict
-
- .. attribute:: children
-
- direct children of this object, (read-only).
-
- :type: :class:`CListValue` of :class:`KX_GameObject`'s
-
- .. attribute:: childrenRecursive
-
- all children of this object including childrens children, (read-only).
-
- :type: :class:`CListValue` of :class:`KX_GameObject`'s
-
- .. attribute:: life
-
- The number of seconds until the object ends, assumes 50fps.
- (when added with an add object actuator), (read-only).
-
- :type: float
-
- .. method:: endObject()
-
- Delete this object, can be used in place of the EndObject Actuator.
-
- The actual removal of the object from the scene is delayed.
-
- .. method:: replaceMesh(mesh, useDisplayMesh=True, usePhysicsMesh=False)
-
- Replace the mesh of this object with a new mesh. This works the same was as the actuator.
-
- :arg mesh: mesh to replace or the meshes name.
- :type mesh: :class:`MeshProxy` or string
- :arg useDisplayMesh: when enabled the display mesh will be replaced (optional argument).
- :type useDisplayMesh: boolean
- :arg usePhysicsMesh: when enabled the physics mesh will be replaced (optional argument).
- :type usePhysicsMesh: boolean
-
- .. method:: setVisible(visible, recursive)
-
- Sets the game object's visible flag.
-
- :arg visible: the visible state to set.
- :type visible: boolean
- :arg recursive: optional argument to set all childrens visibility flag too.
- :type recursive: boolean
-
- .. method:: setOcclusion(occlusion, recursive)
-
- Sets the game object's occlusion capability.
-
- :arg occlusion: the state to set the occlusion to.
- :type occlusion: boolean
- :arg recursive: optional argument to set all childrens occlusion flag too.
- :type recursive: boolean
-
- .. method:: alignAxisToVect(vect, axis=2, factor=1.0)
-
- Aligns any of the game object's axis along the given vector.
-
-
- :arg vect: a vector to align the axis.
- :type vect: 3D vector
- :arg axis: The axis you want to align
-
- * 0: X axis
- * 1: Y axis
- * 2: Z axis
-
- :type axis: integer
- :arg factor: Only rotate a feaction of the distance to the target vector (0.0 - 1.0)
- :type factor: float
-
- .. method:: getAxisVect(vect)
-
- Returns the axis vector rotates by the objects worldspace orientation.
- This is the equivalent of multiplying the vector by the orientation matrix.
-
- :arg vect: a vector to align the axis.
- :type vect: 3D Vector
- :return: The vector in relation to the objects rotation.
- :rtype: 3d vector.
-
- .. method:: applyMovement(movement, local=False)
-
- Sets the game object's movement.
-
- :arg movement: movement vector.
- :type movement: 3D Vector
- :arg local:
- * False: you get the "global" movement ie: relative to world orientation.
- * True: you get the "local" movement ie: relative to object orientation.
- :arg local: boolean
-
- .. method:: applyRotation(rotation, local=False)
-
- Sets the game object's rotation.
-
- :arg rotation: rotation vector.
- :type rotation: 3D Vector
- :arg local:
- * False: you get the "global" rotation ie: relative to world orientation.
- * True: you get the "local" rotation ie: relative to object orientation.
- :arg local: boolean
-
- .. method:: applyForce(force, local=False)
-
- Sets the game object's force.
-
- This requires a dynamic object.
-
- :arg force: force vector.
- :type force: 3D Vector
- :arg local:
- * False: you get the "global" force ie: relative to world orientation.
- * True: you get the "local" force ie: relative to object orientation.
- :type local: boolean
-
- .. method:: applyTorque(torque, local=False)
-
- Sets the game object's torque.
-
- This requires a dynamic object.
-
- :arg torque: torque vector.
- :type torque: 3D Vector
- :arg local:
- * False: you get the "global" torque ie: relative to world orientation.
- * True: you get the "local" torque ie: relative to object orientation.
- :type local: boolean
-
- .. method:: getLinearVelocity(local=False)
-
- Gets the game object's linear velocity.
-
- This method returns the game object's velocity through it's centre of mass, ie no angular velocity component.
-
- :arg local:
- * False: you get the "global" velocity ie: relative to world orientation.
- * 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]
-
- .. method:: setLinearVelocity(velocity, local=False)
-
- Sets the game object's linear velocity.
-
- This method sets game object's velocity through it's centre of mass,
- ie no angular velocity component.
-
- This requires a dynamic object.
-
- :arg velocity: linear velocity vector.
- :type velocity: 3D Vector
- :arg local:
- * False: you get the "global" velocity ie: relative to world orientation.
- * True: you get the "local" velocity ie: relative to object orientation.
- :type local: boolean
-
- .. method:: getAngularVelocity(local=False)
-
- Gets the game object's angular velocity.
-
- :arg local:
- * False: you get the "global" velocity ie: relative to world orientation.
- * 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]
-
- .. method:: setAngularVelocity(velocity, local=False)
-
- Sets the game object's angular velocity.
-
- This requires a dynamic object.
-
- :arg velocity: angular velocity vector.
- :type velocity: boolean
- :arg local:
- * False: you get the "global" velocity ie: relative to world orientation.
- * True: you get the "local" velocity ie: relative to object orientation.
-
- .. method:: getVelocity(point=(0, 0, 0))
-
- Gets the game object's velocity at the specified point.
-
- Gets the game object's velocity at the specified point, including angular
- components.
-
- :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]
-
- .. method:: getReactionForce()
-
- Gets the game object's reaction force.
-
- The reaction force is the force applied to this object over the last simulation timestep.
- This also includes impulses, eg from collisions.
-
- :return: the reaction force of this object.
- :rtype: list [fx, fy, fz]
-
- .. note::
-
- This is not implimented at the moment.
-
- .. method:: applyImpulse(point, impulse)
-
- Applies an impulse to the game object.
-
- This will apply the specified impulse to the game object at the specified point.
- If point != position, applyImpulse will also change the object's angular momentum.
- Otherwise, only linear momentum will change.
-
- :arg point: the point to apply the impulse to (in world coordinates)
- :type point: the point to apply the impulse to (in world coordinates)
-
- .. method:: suspendDynamics()
-
- Suspends physics for this object.
-
- .. method:: restoreDynamics()
-
- Resumes physics for this object.
-
- .. note::
-
- The objects linear velocity will be applied from when the dynamics were suspended.
-
- .. method:: enableRigidBody()
-
- Enables rigid body physics for this object.
-
- Rigid body physics allows the object to roll on collisions.
-
- .. method:: disableRigidBody()
-
- Disables rigid body physics for this object.
-
- .. method:: setParent(parent, compound=True, ghost=True)
-
- Sets this object's parent.
- Control the shape status with the optional compound and ghost parameters:
-
- In that case you can control if it should be ghost or not:
-
- :arg parent: new parent object.
- :type parent: :class:`KX_GameObject`
- :arg compound: whether the shape should be added to the parent compound shape.
-
- * True: the object shape should be added to the parent compound shape.
- * False: the object should keep its individual shape.
-
- :type compound: boolean
- :arg ghost: whether the object should be ghost while parented.
-
- * True: if the object should be made ghost while parented.
- * False: if the object should be solid while parented.
-
- :type ghost: boolean
-
- .. note::
-
- If the object type is sensor, it stays ghost regardless of ghost parameter
-
- .. method:: removeParent()
-
- Removes this objects parent.
-
- .. method:: getPhysicsId()
-
- Returns the user data object associated with this game object's physics controller.
-
- .. method:: getPropertyNames()
-
- Gets a list of all property names.
-
- :return: All property names for this object.
- :rtype: list
-
- .. method:: getDistanceTo(other)
-
- :arg other: a point or another :class:`KX_GameObject` to measure the distance to.
- :type other: :class:`KX_GameObject` or list [x, y, z]
- :return: distance to another object or point.
- :rtype: float
-
- .. method:: getVectTo(other)
-
- Returns the vector and the distance to another object or point.
- The vector is normalized unless the distance is 0, in which a zero length vector is returned.
-
- :arg other: a point or another :class:`KX_GameObject` to get the vector and distance to.
- :type other: :class:`KX_GameObject` or list [x, y, z]
- :return: (distance, globalVector(3), localVector(3))
- :rtype: 3-tuple (float, 3-tuple (x, y, z), 3-tuple (x, y, z))
-
- .. method:: rayCastTo(other, dist, prop)
-
- Look towards another point/object and find first object hit within dist that matches prop.
-
- The ray is always casted from the center of the object, ignoring the object itself.
- The ray is casted towards the center of another object or an explicit [x, y, z] point.
- Use rayCast() if you need to retrieve the hit point
-
- :arg other: [x, y, z] or object towards which the ray is casted
- :type other: :class:`KX_GameObject` or 3-tuple
- :arg dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other
- :type dist: float
- :arg prop: property name that object must have; can be omitted => detect any object
- :type prop: string
- :return: the first object hit or None if no object or object does not match prop
- :rtype: :class:`KX_GameObject`
-
- .. method:: rayCast(objto, objfrom, dist, prop, face, xray, poly)
-
- Look from a point/object to another point/object and find first object hit within dist that matches prop.
- if poly is 0, returns a 3-tuple with object reference, hit point and hit normal or (None, None, None) if no hit.
- if poly is 1, returns a 4-tuple with in addition a :class:`KX_PolyProxy` as 4th element.
- if poly is 2, returns a 5-tuple with in addition a 2D vector with the UV mapping of the hit point as 5th element.
-
- .. code-block:: python
-
- # shoot along the axis gun-gunAim (gunAim should be collision-free)
- obj, point, normal = gun.rayCast(gunAim, None, 50)
- if obj:
- # do something
- pass
-
- The face paremeter determines the orientation of the normal.
-
- * 0 => hit normal is always oriented towards the ray origin (as if you casted the ray from outside)
- * 1 => hit normal is the real face normal (only for mesh object, otherwise face has no effect)
-
- The ray has X-Ray capability if xray parameter is 1, otherwise the first object hit (other than self object) stops the ray.
- The prop and xray parameters interact as follow.
-
- * prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray.
- * prop off, xray on : idem.
- * prop on, xray off: return closest hit if it matches prop, no hit otherwise.
- * prop on, xray on : return closest hit matching prop or no hit if there is no object matching prop on the full extend of the ray.
-
- The :class:`KX_PolyProxy` 4th element of the return tuple when poly=1 allows to retrieve information on the polygon hit by the ray.
- If there is no hit or the hit object is not a static mesh, None is returned as 4th element.
-
- The ray ignores collision-free objects and faces that dont have the collision flag enabled, you can however use ghost objects.
-
- :arg objto: [x, y, z] or object to which the ray is casted
- :type objto: :class:`KX_GameObject` or 3-tuple
- :arg objfrom: [x, y, z] or object from which the ray is casted; None or omitted => use self object center
- :type objfrom: :class:`KX_GameObject` or 3-tuple or None
- :arg dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to
- :type dist: float
- :arg prop: property name that object must have; can be omitted or "" => detect any object
- :type prop: string
- :arg face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin
- :type face: integer
- :arg xray: X-ray option: 1=>skip objects that don't match prop; 0 or omitted => stop on first object
- :type xray: integer
- :arg poly: polygon option: 0, 1 or 2 to return a 3-, 4- or 5-tuple with information on the face hit.
-
- * 0 or omitted: return value is a 3-tuple (object, hitpoint, hitnormal) or (None, None, None) if no hit
- * 1: return value is a 4-tuple and the 4th element is a :class:`KX_PolyProxy` or None if no hit or the object doesn't use a mesh collision shape.
- * 2: return value is a 5-tuple and the 5th element is a 2-tuple (u, v) with the UV mapping of the hit point or None if no hit, or the object doesn't use a mesh collision shape, or doesn't have a UV mapping.
-
- :type poly: integer
- :return: (object, hitpoint, hitnormal) or (object, hitpoint, hitnormal, polygon) or (object, hitpoint, hitnormal, polygon, hituv).
-
- * object, hitpoint and hitnormal are None if no hit.
- * polygon is valid only if the object is valid and is a static object, a dynamic object using mesh collision shape or a soft body object, otherwise it is None
- * hituv is valid only if polygon is valid and the object has a UV mapping, otherwise it is None
-
- :rtype:
-
- * 3-tuple (:class:`KX_GameObject`, 3-tuple (x, y, z), 3-tuple (nx, ny, nz))
- * or 4-tuple (:class:`KX_GameObject`, 3-tuple (x, y, z), 3-tuple (nx, ny, nz), :class:`PolyProxy`)
- * or 5-tuple (:class:`KX_GameObject`, 3-tuple (x, y, z), 3-tuple (nx, ny, nz), :class:`PolyProxy`, 2-tuple (u, v))
-
- .. note::
-
- The ray ignores the object on which the method is called. It is casted from/to object center or explicit [x, y, z] points.
-
- .. method:: setCollisionMargin(margin)
-
- Set the objects collision margin.
-
- :arg margin: the collision margin distance in blender units.
- :type margin: float
-
- .. note::
-
- If this object has no physics controller (a physics ID of zero), this function will raise RuntimeError.
-
- .. method:: sendMessage(subject, body="", to="")
-
- Sends a message.
-
- :arg subject: The subject of the message
- :type subject: string
- :arg body: The body of the message (optional)
- :type body: string
- :arg to: The name of the object to send the message to (optional)
- :type to: string
-
- .. method:: reinstancePhysicsMesh(gameObject, meshObject)
-
- Updates the physics system with the changed mesh.
-
- If no arguments are given the physics mesh will be re-created from the first mesh assigned to the game object.
-
- :arg gameObject: optional argument, set the physics shape from this gameObjets mesh.
- :type gameObject: string, :class:`KX_GameObject` or None
- :arg meshObject: optional argument, set the physics shape from this mesh.
- :type meshObject: string, :class:`MeshProxy` or None
-
- :return: True if reinstance succeeded, False if it failed.
- :rtype: boolean
-
- .. note::
-
- If this object has instances the other instances will be updated too.
-
- .. note::
-
- The gameObject argument has an advantage that it can convert from a mesh with modifiers applied (such as subsurf).
-
- .. warning::
-
- Only triangle mesh type objects are supported currently (not convex hull)
-
- .. warning::
-
- If the object is a part of a combound object it will fail (parent or child)
-
- .. warning::
-
- Rebuilding the physics mesh can be slow, running many times per second will give a performance hit.
-
- .. method:: get(key, default=None)
-
- Return the value matching key, or the default value if its not found.
- :return: The key value or a default.
-
- .. method:: playAction(name, start_frame, end_frame, layer=0, priority=0, blendin=0, play_mode=ACT_MODE_PLAY, layer_weight=0.0, ipo_flags=0, speed=1.0)
-
- Plays an action.
-
- :arg name: the name of the action
- :type name: string
- :arg start: the start frame of the action
- :type start: float
- :arg end: the end frame of the action
- :type end: float
- :arg layer: the layer the action will play in (actions in different layers are added/blended together)
- :type layer: integer
- :arg priority: only play this action if there isn't an action currently playing in this layer with a higher (lower number) priority
- :type priority: integer
- :arg blendin: the amount of blending between this animation and the previous one on this layer
- :type blendin: float
- :arg play_mode: the play mode
- :type play_mode: one of :ref:`these constants <gameobject-playaction-mode>`
- :arg layer_weight: how much of the previous layer to use for blending (0 = add)
- :type layer_weight: float
- :arg ipo_flags: flags for the old IPO behaviors (force, etc)
- :type ipo_flags: int bitfield
- :arg speed: the playback speed of the action as a factor (1.0 = normal speed, 2.0 = 2x speed, etc)
- :type speed: float
-
- .. method:: stopAction(layer=0)
-
- Stop playing the action on the given layer.
-
- :arg layer: The layer to stop playing.
- :type layer: integer
-
- .. method:: getActionFrame(layer=0)
-
- Gets the current frame of the action playing in the supplied layer.
-
- :arg layer: The layer that you want to get the frame from.
- :type layer: integer
-
- :return: The current frame of the action
- :rtype: float
-
- .. method:: setActionFrame(frame, layer=0)
-
- Set the current frame of the action playing in the supplied layer.
-
- :arg layer: The layer where you want to set the frame
- :type layer: integer
- :arg frame: The frame to set the action to
- :type frame: float
-
- .. method:: isPlayingAction(layer=0)
-
- Checks to see if there is an action playing in the given layer.
-
- :arg layer: The layer to check for a playing action.
- :type layer: integer
-
- :return: Whether or not the action is playing
- :rtype: boolean
-
-.. class:: KX_IpoActuator(SCA_IActuator)
-
- IPO actuator activates an animation.
-
- .. attribute:: frameStart
-
- Start frame.
-
- :type: float
-
- .. attribute:: frameEnd
-
- End frame.
-
- :type: float
-
- .. attribute:: propName
-
- Use this property to define the Ipo position.
-
- :type: string
-
- .. attribute:: framePropName
-
- Assign this property this action current frame number.
-
- :type: string
-
- .. attribute:: mode
-
- Play mode for the ipo. Can be on of :ref:`these constants <ipo-actuator>`
-
- :type: integer
-
- .. attribute:: useIpoAsForce
-
- Apply Ipo as a global or local force depending on the local option (dynamic objects only).
-
- :type: boolean
-
- .. attribute:: useIpoAdd
-
- Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag.
-
- :type: boolean
-
- .. attribute:: useIpoLocal
-
- Let the ipo acts in local coordinates, used in Force and Add mode.
-
- :type: boolean
-
- .. attribute:: useChildren
-
- Update IPO on all children Objects as well.
-
- :type: boolean
-
-.. class:: KX_LightObject(KX_GameObject)
-
- A Light object.
-
- .. code-block:: python
-
- # Turn on a red alert light.
- import bge
-
- co = bge.logic.getCurrentController()
- light = co.owner
-
- light.energy = 1.0
- light.color = [1.0, 0.0, 0.0]
-
- .. data:: SPOT
-
- A spot light source. See attribute :data:`type`
-
- .. data:: SUN
-
- A point light source with no attenuation. See attribute :data:`type`
-
- .. data:: NORMAL
-
- A point light source. See attribute :data:`type`
-
- .. attribute:: type
-
- The type of light - must be SPOT, SUN or NORMAL
-
- .. attribute:: layer
-
- The layer mask that this light affects object on.
-
- :type: bitfield
-
- .. attribute:: energy
-
- The brightness of this light.
-
- :type: float
-
- .. attribute:: distance
-
- The maximum distance this light can illuminate. (SPOT and NORMAL lights only).
-
- :type: float
-
- .. attribute:: color
-
- The color of this light. Black = [0.0, 0.0, 0.0], White = [1.0, 1.0, 1.0].
-
- :type: list [r, g, b]
-
- .. attribute:: lin_attenuation
-
- The linear component of this light's attenuation. (SPOT and NORMAL lights only).
-
- :type: float
-
- .. attribute:: quad_attenuation
-
- The quadratic component of this light's attenuation (SPOT and NORMAL lights only).
-
- :type: float
-
- .. attribute:: spotsize
-
- The cone angle of the spot light, in degrees (SPOT lights only).
-
- :type: float in [0 - 180].
-
- .. attribute:: spotblend
-
- Specifies the intensity distribution of the spot light (SPOT lights only).
-
- :type: float in [0 - 1]
-
- .. note::
-
- Higher values result in a more focused light source.
-
-.. class:: KX_MeshProxy(SCA_IObject)
-
- A mesh object.
-
- You can only change the vertex properties of a mesh object, not the mesh topology.
-
- To use mesh objects effectively, you should know a bit about how the game engine handles them.
-
- #. Mesh Objects are converted from Blender at scene load.
- #. The Converter groups polygons by Material. This means they can be sent to the renderer efficiently. A material holds:
-
- #. The texture.
- #. The Blender material.
- #. The Tile properties
- #. The face properties - (From the "Texture Face" panel)
- #. Transparency & z sorting
- #. Light layer
- #. Polygon shape (triangle/quad)
- #. Game Object
-
- #. Vertices will be split by face if necessary. Vertices can only be shared between faces if:
-
- #. They are at the same position
- #. UV coordinates are the same
- #. Their normals are the same (both polygons are "Set Smooth")
- #. They are the same color, for example: a cube has 24 vertices: 6 faces with 4 vertices per face.
-
- The correct method of iterating over every :class:`KX_VertexProxy` in a game object
-
- .. code-block:: python
-
- from bge import logic
-
- cont = logic.getCurrentController()
- object = cont.owner
-
- for mesh in object.meshes:
- for m_index in range(len(mesh.materials)):
- for v_index in range(mesh.getVertexArrayLength(m_index)):
- vertex = mesh.getVertex(m_index, v_index)
- # Do something with vertex here...
- # ... eg: color the vertex red.
- vertex.color = [1.0, 0.0, 0.0, 1.0]
-
- .. attribute:: materials
-
- :type: list of :class:`KX_BlenderMaterial` or :class:`KX_PolygonMaterial` types
-
- .. attribute:: numPolygons
-
- :type: integer
-
- .. attribute:: numMaterials
-
- :type: integer
-
- .. method:: getMaterialName(matid)
-
- Gets the name of the specified material.
-
- :arg matid: the specified material.
- :type matid: integer
- :return: the attached material name.
- :rtype: string
-
- .. method:: getTextureName(matid)
-
- Gets the name of the specified material's texture.
-
- :arg matid: the specified material
- :type matid: integer
- :return: the attached material's texture name.
- :rtype: string
-
- .. method:: getVertexArrayLength(matid)
-
- Gets the length of the vertex array associated with the specified material.
-
- There is one vertex array for each material.
-
- :arg matid: the specified material
- :type matid: integer
- :return: the number of verticies in the vertex array.
- :rtype: integer
-
- .. method:: getVertex(matid, index)
-
- Gets the specified vertex from the mesh object.
-
- :arg matid: the specified material
- :type matid: integer
- :arg index: the index into the vertex array.
- :type index: integer
- :return: a vertex object.
- :rtype: :class:`KX_VertexProxy`
-
- .. method:: getPolygon(index)
-
- Gets the specified polygon from the mesh.
-
- :arg index: polygon number
- :type index: integer
- :return: a polygon object.
- :rtype: :class:`PolyProxy`
-
- .. method:: transform(matid, matrix)
-
- Transforms the vertices of a mesh.
-
- :arg matid: material index, -1 transforms all.
- :type matid: integer
- :arg matrix: transformation matrix.
- :type matrix: 4x4 matrix [[float]]
-
- .. method:: transformUV(matid, matrix, uv_index=-1, uv_index_from=-1)
-
- Transforms the vertices UV's of a mesh.
-
- :arg matid: material index, -1 transforms all.
- :type matid: integer
- :arg matrix: transformation matrix.
- :type matrix: 4x4 matrix [[float]]
- :arg uv_index: optional uv index, -1 for all, otherwise 0 or 1.
- :type uv_index: integer
- :arg uv_index_from: optional uv index to copy from, -1 to transform the current uv.
- :type uv_index_from: integer
-
-.. class:: SCA_MouseSensor(SCA_ISensor)
-
- Mouse Sensor logic brick.
-
- .. attribute:: position
-
- current [x, y] coordinates of the mouse, in frame coordinates (pixels).
-
- :type: [integer, interger]
-
- .. attribute:: mode
-
- sensor mode.
-
- :type: integer
-
- * KX_MOUSESENSORMODE_LEFTBUTTON(1)
- * KX_MOUSESENSORMODE_MIDDLEBUTTON(2)
- * KX_MOUSESENSORMODE_RIGHTBUTTON(3)
- * KX_MOUSESENSORMODE_WHEELUP(4)
- * KX_MOUSESENSORMODE_WHEELDOWN(5)
- * KX_MOUSESENSORMODE_MOVEMENT(6)
-
- .. method:: getButtonStatus(button)
-
- Get the mouse button status.
-
- :arg button: The code that represents the key you want to get the state of, use one of :ref:`these constants<mouse-keys>`
- :type button: int
- :return: The state of the given key, can be one of :ref:`these constants<input-status>`
- :rtype: int
-
-.. class:: KX_MouseFocusSensor(SCA_MouseSensor)
-
- The mouse focus sensor detects when the mouse is over the current game object.
-
- The mouse focus sensor works by transforming the mouse coordinates from 2d device
- space to 3d space then raycasting away from the camera.
-
- .. attribute:: raySource
-
- The worldspace source of the ray (the view position).
-
- :type: list (vector of 3 floats)
-
- .. attribute:: rayTarget
-
- The worldspace target of the ray.
-
- :type: list (vector of 3 floats)
-
- .. attribute:: rayDirection
-
- The :data:`rayTarget` - :class:`raySource` normalized.
-
- :type: list (normalized vector of 3 floats)
-
- .. attribute:: hitObject
-
- the last object the mouse was over.
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: hitPosition
-
- The worldspace position of the ray intersecton.
-
- :type: list (vector of 3 floats)
-
- .. attribute:: hitNormal
-
- the worldspace normal from the face at point of intersection.
-
- :type: list (normalized vector of 3 floats)
-
- .. attribute:: hitUV
-
- the UV coordinates at the point of intersection.
-
- :type: list (vector of 2 floats)
-
- If the object has no UV mapping, it returns [0, 0].
-
- The UV coordinates are not normalized, they can be < 0 or > 1 depending on the UV mapping.
-
- .. attribute:: usePulseFocus
-
- When enabled, moving the mouse over a different object generates a pulse. (only used when the 'Mouse Over Any' sensor option is set).
-
- :type: boolean
-
-.. class:: KX_TouchSensor(SCA_ISensor)
-
- Touch sensor detects collisions between objects.
-
- .. attribute:: propName
-
- The property or material to collide with.
-
- :type: string
-
- .. attribute:: useMaterial
-
- Determines if the sensor is looking for a property or material. KX_True = Find material; KX_False = Find property.
-
- :type: boolean
-
- .. attribute:: usePulseCollision
-
- When enabled, changes to the set of colliding objects generate a pulse.
-
- :type: boolean
-
- .. attribute:: hitObject
-
- The last collided object. (read-only).
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: hitObjectList
-
- A list of colliding objects. (read-only).
-
- :type: :class:`CListValue` of :class:`KX_GameObject`
-
-.. class:: KX_NearSensor(KX_TouchSensor)
-
- A near sensor is a specialised form of touch sensor.
-
- .. attribute:: distance
-
- The near sensor activates when an object is within this distance.
-
- :type: float
-
- .. attribute:: resetDistance
-
- The near sensor deactivates when the object exceeds this distance.
-
- :type: float
-
-.. class:: KX_NetworkMessageActuator(SCA_IActuator)
-
- Message Actuator
-
- .. attribute:: propName
-
- Messages will only be sent to objects with the given property name.
-
- :type: string
-
- .. attribute:: subject
-
- The subject field of the message.
-
- :type: string
-
- .. attribute:: body
-
- The body of the message.
-
- :type: string
-
- .. attribute:: usePropBody
-
- Send a property instead of a regular body message.
-
- :type: boolean
-
-.. class:: KX_NetworkMessageSensor(SCA_ISensor)
-
- The Message Sensor logic brick.
-
- Currently only loopback (local) networks are supported.
-
- .. attribute:: subject
-
- The subject the sensor is looking for.
-
- :type: string
-
- .. attribute:: frameMessageCount
-
- The number of messages received since the last frame. (read-only).
-
- :type: integer
-
- .. attribute:: subjects
-
- The list of message subjects received. (read-only).
-
- :type: list of strings
-
- .. attribute:: bodies
-
- The list of message bodies received. (read-only).
-
- :type: list of strings
-
-
-.. class:: KX_FontObject(KX_GameObject)
-
- TODO.
-
-
-.. class:: KX_NavMeshObject(KX_GameObject)
-
- Python interface for using and controlling navigation meshes.
-
- .. method:: findPath(start, goal)
-
- Finds the path from start to goal points.
-
- :arg start: the start point
- :arg start: 3D Vector
- :arg goal: the goal point
- :arg start: 3D Vector
- :return: a path as a list of points
- :rtype: list of points
-
- .. method:: raycast(start, goal)
-
- Raycast from start to goal points.
-
- :arg start: the start point
- :arg start: 3D Vector
- :arg goal: the goal point
- :arg start: 3D Vector
- :return: the hit factor
- :rtype: float
-
- .. method:: draw(mode)
-
- Draws a debug mesh for the navigation mesh.
-
- :arg mode: the drawing mode (one of :ref:`these constants <navmesh-draw-mode>`)
- :arg mode: integer
- :return: None
-
- .. method:: rebuild()
-
- Rebuild the navigation mesh.
-
- :return: None
-
-.. class:: KX_ObjectActuator(SCA_IActuator)
-
- The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement,
- velocity, or angular velocity to an object.
- Servo control allows to regulate force to achieve a certain speed target.
-
- .. attribute:: force
-
- The force applied by the actuator.
-
- :type: list [x, y, z]
-
- .. attribute:: useLocalForce
-
- A flag specifying if the force is local.
-
- :type: boolean
-
- .. attribute:: torque
-
- The torque applied by the actuator.
-
- :type: list [x, y, z]
-
- .. attribute:: useLocalTorque
-
- A flag specifying if the torque is local.
-
- :type: boolean
-
- .. attribute:: dLoc
-
- The displacement vector applied by the actuator.
-
- :type: list [x, y, z]
-
- .. attribute:: useLocalDLoc
-
- A flag specifying if the dLoc is local.
-
- :type: boolean
-
- .. attribute:: dRot
-
- The angular displacement vector applied by the actuator
-
- :type: list [x, y, z]
-
- .. note::
-
- Since the displacement is applied every frame, you must adjust the displacement based on the frame rate, or you game experience will depend on the player's computer speed.
-
- .. attribute:: useLocalDRot
-
- A flag specifying if the dRot is local.
-
- :type: boolean
-
- .. attribute:: linV
-
- The linear velocity applied by the actuator.
-
- :type: list [x, y, z]
-
- .. attribute:: useLocalLinV
-
- A flag specifying if the linear velocity is local.
-
- :type: boolean
-
- .. note::
-
- This is the target speed for servo controllers.
-
- .. attribute:: angV
-
- The angular velocity applied by the actuator.
-
- :type: list [x, y, z]
-
- .. attribute:: useLocalAngV
-
- A flag specifying if the angular velocity is local.
-
- :type: boolean
-
- .. attribute:: damping
-
- The damping parameter of the servo controller.
-
- :type: short
-
- .. attribute:: forceLimitX
-
- The min/max force limit along the X axis and activates or deactivates the limits in the servo controller.
-
- :type: list [min(float), max(float), bool]
-
- .. attribute:: forceLimitY
-
- The min/max force limit along the Y axis and activates or deactivates the limits in the servo controller.
-
- :type: list [min(float), max(float), bool]
-
- .. attribute:: forceLimitZ
-
- The min/max force limit along the Z axis and activates or deactivates the limits in the servo controller.
-
- :type: list [min(float), max(float), bool]
-
- .. attribute:: pid
-
- The PID coefficients of the servo controller.
-
- :type: list of floats [proportional, integral, derivate]
-
- .. attribute:: reference
-
- The object that is used as reference to compute the velocity for the servo controller.
-
- :type: :class:`KX_GameObject` or None
-
-.. class:: KX_ParentActuator(SCA_IActuator)
-
- The parent actuator can set or remove an objects parent object.
-
- .. attribute:: object
-
- the object this actuator sets the parent too.
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: mode
-
- The mode of this actuator.
-
- :type: integer from 0 to 1.
-
- .. attribute:: compound
-
- Whether the object shape should be added to the parent compound shape when parenting.
-
- Effective only if the parent is already a compound shape.
-
- :type: boolean
-
- .. attribute:: ghost
-
- Whether the object should be made ghost when parenting
- Effective only if the shape is not added to the parent compound shape.
-
- :type: boolean
-
-.. class:: KX_PolyProxy(SCA_IObject)
-
- A polygon holds the index of the vertex forming the poylgon.
-
- Note:
- The polygon attributes are read-only, you need to retrieve the vertex proxy if you want
- to change the vertex settings.
-
- .. attribute:: material_name
-
- The name of polygon material, empty if no material.
-
- :type: string
-
- .. attribute:: material
-
- The material of the polygon.
-
- :type: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
-
- .. attribute:: texture_name
-
- The texture name of the polygon.
-
- :type: string
-
- .. attribute:: material_id
-
- The material index of the polygon, use this to retrieve vertex proxy from mesh proxy.
-
- :type: integer
-
- .. attribute:: v1
-
- vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy.
-
- :type: integer
-
- .. attribute:: v2
-
- vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy.
-
- :type: integer
-
- .. attribute:: v3
-
- vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy.
-
- :type: integer
-
- .. attribute:: v4
-
- Vertex index of the fourth vertex of the polygon, 0 if polygon has only 3 vertex
- Use this to retrieve vertex proxy from mesh proxy.
-
- :type: integer
-
- .. attribute:: visible
-
- visible state of the polygon: 1=visible, 0=invisible.
-
- :type: integer
-
- .. attribute:: collide
-
- collide state of the polygon: 1=receives collision, 0=collision free.
-
- :type: integer
-
- .. method:: getMaterialName()
-
- Returns the polygon material name with MA prefix
-
- :return: material name
- :rtype: string
-
- .. method:: getMaterial()
-
- :return: The polygon material
- :rtype: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
-
- .. method:: getTextureName()
-
- :return: The texture name
- :rtype: string
-
- .. method:: getMaterialIndex()
-
- Returns the material bucket index of the polygon.
- This index and the ones returned by getVertexIndex() are needed to retrieve the vertex proxy from :class:`MeshProxy`.
-
- :return: the material index in the mesh
- :rtype: integer
-
- .. method:: getNumVertex()
-
- Returns the number of vertex of the polygon.
-
- :return: number of vertex, 3 or 4.
- :rtype: integer
-
- .. method:: isVisible()
-
- Returns whether the polygon is visible or not
-
- :return: 0=invisible, 1=visible
- :rtype: boolean
-
- .. method:: isCollider()
-
- Returns whether the polygon is receives collision or not
-
- :return: 0=collision free, 1=receives collision
- :rtype: integer
-
- .. method:: getVertexIndex(vertex)
-
- Returns the mesh vertex index of a polygon vertex
- This index and the one returned by getMaterialIndex() are needed to retrieve the vertex proxy from :class:`MeshProxy`.
-
- :arg vertex: index of the vertex in the polygon: 0->3
- :arg vertex: integer
- :return: mesh vertex index
- :rtype: integer
-
- .. method:: getMesh()
-
- Returns a mesh proxy
-
- :return: mesh proxy
- :rtype: :class:`MeshProxy`
-
-.. class:: KX_PolygonMaterial(PyObjectPlus)
-
- This is the interface to materials in the game engine.
-
- Materials define the render state to be applied to mesh objects.
-
- .. warning::
-
- Some of the methods/variables are CObjects. If you mix these up, you will crash blender.
-
- .. code-block:: python
-
- from bge import logic
-
- vertex_shader = """
-
- void main(void)
- {
- // original vertex position, no changes
- gl_Position = ftransform();
- // coordinate of the 1st texture channel
- gl_TexCoord[0] = gl_MultiTexCoord0;
- // coordinate of the 2nd texture channel
- gl_TexCoord[1] = gl_MultiTexCoord1;
- }
- """
-
- fragment_shader ="""
-
- uniform sampler2D color_0;
- uniform sampler2D color_1;
- uniform float factor;
-
- void main(void)
- {
- vec4 color_0 = texture2D(color_0, gl_TexCoord[0].st);
- vec4 color_1 = texture2D(color_1, gl_TexCoord[1].st);
- gl_FragColor = mix(color_0, color_1, factor);
- }
- """
-
- object = logic.getCurrentController().owner
- object = cont.owner
- for mesh in object.meshes:
- for material in mesh.materials:
- shader = material.getShader()
- if shader != None:
- if not shader.isValid():
- shader.setSource(vertex_shader, fragment_shader, True)
-
- # get the first texture channel of the material
- shader.setSampler('color_0', 0)
- # get the second texture channel of the material
- shader.setSampler('color_1', 1)
- # pass another uniform to the shader
- shader.setUniform1f('factor', 0.3)
-
-
- .. attribute:: texture
-
- Texture name.
-
- :type: string (read-only)
-
- .. attribute:: gl_texture
-
- OpenGL texture handle (eg for glBindTexture(GL_TEXTURE_2D, gl_texture).
-
- :type: integer (read-only)
-
- .. attribute:: material
-
- Material name.
-
- :type: string (read-only)
-
- .. attribute:: tface
-
- Texture face properties.
-
- :type: CObject (read-only)
-
- .. attribute:: tile
-
- Texture is tiling.
-
- :type: boolean
-
- .. attribute:: tilexrep
-
- Number of tile repetitions in x direction.
-
- :type: integer
-
- .. attribute:: tileyrep
-
- Number of tile repetitions in y direction.
-
- :type: integer
-
- .. attribute:: drawingmode
-
- Drawing mode for the material.
- - 2 (drawingmode & 4) Textured
- - 4 (drawingmode & 16) Light
- - 14 (drawingmode & 16384) 3d Polygon Text.
-
- :type: bitfield
-
- .. attribute:: transparent
-
- This material is transparent. All meshes with this
- material will be rendered after non transparent meshes from back
- to front.
-
- :type: boolean
-
- .. attribute:: zsort
-
- Transparent polygons in meshes with this material will be sorted back to
- front before rendering.
- Non-Transparent polygons will be sorted front to back before rendering.
-
- :type: boolean
-
- .. attribute:: diffuse
-
- The diffuse color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
-
- :type: list [r, g, b]
-
- .. attribute:: specular
-
- The specular color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
-
- :type: list [r, g, b]
-
- .. attribute:: shininess
-
- The shininess (specular exponent) of the material. 0.0 <= shininess <= 128.0.
-
- :type: float
-
- .. attribute:: specularity
-
- The amount of specular of the material. 0.0 <= specularity <= 1.0.
-
- :type: float
-
- .. method:: updateTexture(tface, rasty)
-
- Updates a realtime animation.
-
- :arg tface: Texture face (eg mat.tface)
- :type tface: CObject
- :arg rasty: Rasterizer
- :type rasty: CObject
-
- .. method:: setTexture(tface)
-
- Sets texture render state.
-
- :arg tface: Texture face
- :type tface: CObject
-
- .. code-block:: python
-
- mat.setTexture(mat.tface)
-
- .. method:: activate(rasty, cachingInfo)
-
- Sets material parameters for this object for rendering.
-
- Material Parameters set:
-
- #. Texture
- #. Backface culling
- #. Line drawing
- #. Specular Colour
- #. Shininess
- #. Diffuse Colour
- #. Polygon Offset.
-
- :arg rasty: Rasterizer instance.
- :type rasty: CObject
- :arg cachingInfo: Material cache instance.
- :type cachingInfo: CObject
-
- .. method:: setCustomMaterial(material)
-
- Sets the material state setup object.
-
- Using this method, you can extend or completely replace the gameengine material
- to do your own advanced multipass effects.
-
- Use this method to register your material class. Instead of the normal material,
- your class's activate method will be called just before rendering the mesh.
- This should setup the texture, material, and any other state you would like.
- It should return True to render the mesh, or False if you are finished. You should
- clean up any state Blender does not set before returning False.
-
- Activate Method Definition:
-
- .. code-block:: python
-
- def activate(self, rasty, cachingInfo, material):
-
- :arg material: The material object.
- :type material: instance
-
- .. code-block:: python
-
- class PyMaterial:
- def __init__(self):
- self.pass_no = -1
-
- def activate(self, rasty, cachingInfo, material):
- # Activate the material here.
- #
- # The activate method will be called until it returns False.
- # Every time the activate method returns True the mesh will
- # be rendered.
- #
- # rasty is a CObject for passing to material.updateTexture()
- # and material.activate()
- # cachingInfo is a CObject for passing to material.activate()
- # material is the KX_PolygonMaterial instance this material
- # was added to
-
- # default material properties:
- self.pass_no += 1
- if self.pass_no == 0:
- material.activate(rasty, cachingInfo)
- # Return True to do this pass
- return True
-
- # clean up and return False to finish.
- self.pass_no = -1
- return False
-
- # Create a new Python Material and pass it to the renderer.
- mat.setCustomMaterial(PyMaterial())
-
-.. class:: KX_RadarSensor(KX_NearSensor)
-
- Radar sensor is a near sensor with a conical sensor object.
-
- .. attribute:: coneOrigin
-
- The origin of the cone with which to test. The origin is in the middle of the cone. (read-only).
-
- :type: list of floats [x, y, z]
-
- .. attribute:: coneTarget
-
- The center of the bottom face of the cone with which to test. (read-only).
-
- :type: list of floats [x, y, z]
-
- .. attribute:: distance
-
- The height of the cone with which to test.
-
- :type: float
-
- .. attribute:: angle
-
- The angle of the cone (in degrees) with which to test.
-
- :type: float
-
- .. attribute:: axis
-
- The axis on which the radar cone is cast.
-
- :type: integer from 0 to 5
-
- KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z,
- KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z
-
-.. class:: KX_RaySensor(SCA_ISensor)
-
- A ray sensor detects the first object in a given direction.
-
- .. attribute:: propName
-
- The property the ray is looking for.
-
- :type: string
-
- .. attribute:: range
-
- The distance of the ray.
-
- :type: float
-
- .. attribute:: useMaterial
-
- Whether or not to look for a material (false = property).
-
- :type: boolean
-
- .. attribute:: useXRay
-
- Whether or not to use XRay.
-
- :type: boolean
-
- .. attribute:: hitObject
-
- The game object that was hit by the ray. (read-only).
-
- :type: :class:`KX_GameObject`
-
- .. attribute:: hitPosition
-
- The position (in worldcoordinates) where the object was hit by the ray. (read-only).
-
- :type: list [x, y, z]
-
- .. attribute:: hitNormal
-
- The normal (in worldcoordinates) of the object at the location where the object was hit by the ray. (read-only).
-
- :type: list [x, y, z]
-
- .. attribute:: rayDirection
-
- The direction from the ray (in worldcoordinates). (read-only).
-
- :type: list [x, y, z]
-
- .. attribute:: axis
-
- The axis the ray is pointing on.
-
- :type: integer from 0 to 5
-
- * KX_RAY_AXIS_POS_X
- * KX_RAY_AXIS_POS_Y
- * KX_RAY_AXIS_POS_Z
- * KX_RAY_AXIS_NEG_X
- * KX_RAY_AXIS_NEG_Y
- * KX_RAY_AXIS_NEG_Z
-
-.. class:: KX_SCA_AddObjectActuator(SCA_IActuator)
-
- Edit Object Actuator (in Add Object Mode)
-
- .. warning::
-
- An Add Object actuator will be ignored if at game start, the linked object doesn't exist (or is empty) or the linked object is in an active layer.
-
- .. code-block:: none
-
- Error: GameObject 'Name' has a AddObjectActuator 'ActuatorName' without object (in 'nonactive' layer)
-
- .. attribute:: object
-
- the object this actuator adds.
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: objectLastCreated
-
- the last added object from this actuator (read-only).
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: time
-
- the lifetime of added objects, in frames. Set to 0 to disable automatic deletion.
-
- :type: integer
-
- .. attribute:: linearVelocity
-
- the initial linear velocity of added objects.
-
- :type: list [vx, vy, vz]
-
- .. attribute:: angularVelocity
-
- the initial angular velocity of added objects.
-
- :type: list [vx, vy, vz]
-
- .. method:: instantAddObject()
-
- adds the object without needing to calling SCA_PythonController.activate()
-
- .. note:: Use objectLastCreated to get the newly created object.
-
-.. class:: KX_SCA_DynamicActuator(SCA_IActuator)
-
- Dynamic Actuator.
-
- .. attribute:: mode
-
- :type: integer
-
- the type of operation of the actuator, 0-4
-
- * KX_DYN_RESTORE_DYNAMICS(0)
- * KX_DYN_DISABLE_DYNAMICS(1)
- * KX_DYN_ENABLE_RIGID_BODY(2)
- * KX_DYN_DISABLE_RIGID_BODY(3)
- * KX_DYN_SET_MASS(4)
-
- .. attribute:: mass
-
- the mass value for the KX_DYN_SET_MASS operation.
-
- :type: float
-
-.. class:: KX_SCA_EndObjectActuator(SCA_IActuator)
-
- Edit Object Actuator (in End Object mode)
-
- This actuator has no python methods.
-
-.. class:: KX_SCA_ReplaceMeshActuator(SCA_IActuator)
-
- Edit Object actuator, in Replace Mesh mode.
-
- .. warning::
-
- Replace mesh actuators will be ignored if at game start, the named mesh doesn't exist.
-
- This will generate a warning in the console
-
- .. code-block:: none
-
- Error: GameObject 'Name' ReplaceMeshActuator 'ActuatorName' without object
-
- .. code-block:: python
-
- # Level-of-detail
- # Switch a game object's mesh based on its depth in the camera view.
- # +----------+ +-----------+ +-------------------------------------+
- # | Always +-----+ Python +-----+ Edit Object (Replace Mesh) LOD.Mesh |
- # +----------+ +-----------+ +-------------------------------------+
- from bge import logic
-
- # List detail meshes here
- # Mesh (name, near, far)
- # Meshes overlap so that they don't 'pop' when on the edge of the distance.
- meshes = ((".Hi", 0.0, -20.0),
- (".Med", -15.0, -50.0),
- (".Lo", -40.0, -100.0)
- )
-
- cont = logic.getCurrentController()
- object = cont.owner
- actuator = cont.actuators["LOD." + obj.name]
- camera = logic.getCurrentScene().active_camera
-
- def Depth(pos, plane):
- return pos[0]*plane[0] + pos[1]*plane[1] + pos[2]*plane[2] + plane[3]
-
- # Depth is negative and decreasing further from the camera
- depth = Depth(object.position, camera.world_to_camera[2])
-
- newmesh = None
- curmesh = None
- # Find the lowest detail mesh for depth
- for mesh in meshes:
- if depth < mesh[1] and depth > mesh[2]:
- newmesh = mesh
- if "ME" + object.name + mesh[0] == actuator.getMesh():
- curmesh = mesh
-
- if newmesh != None and "ME" + object.name + newmesh[0] != actuator.mesh:
- # The mesh is a different mesh - switch it.
- # Check the current mesh is not a better fit.
- if curmesh == None or curmesh[1] < depth or curmesh[2] > depth:
- actuator.mesh = object.name + newmesh[0]
- cont.activate(actuator)
-
- .. attribute:: mesh
-
- :class:`MeshProxy` or the name of the mesh that will replace the current one.
-
- Set to None to disable actuator.
-
- :type: :class:`MeshProxy` or None if no mesh is set
-
- .. attribute:: useDisplayMesh
-
- when true the displayed mesh is replaced.
-
- :type: boolean
-
- .. attribute:: usePhysicsMesh
-
- when true the physics mesh is replaced.
-
- :type: boolean
-
- .. method:: instantReplaceMesh()
-
- Immediately replace mesh without delay.
-
-.. class:: KX_Scene(PyObjectPlus)
-
- An active scene that gives access to objects, cameras, lights and scene attributes.
-
- The activity culling stuff is supposed to disable logic bricks when their owner gets too far
- from the active camera. It was taken from some code lurking at the back of KX_Scene - who knows
- what it does!
-
- .. code-block:: python
-
- from bge import logic
-
- # get the scene
- scene = logic.getCurrentScene()
-
- # print all the objects in the scene
- for object in scene.objects:
- print(object.name)
-
- # get an object named 'Cube'
- object = scene.objects["Cube"]
-
- # get the first object in the scene.
- object = scene.objects[0]
-
- .. code-block:: python
-
- # Get the depth of an object in the camera view.
- from bge import logic
-
- object = logic.getCurrentController().owner
- cam = logic.getCurrentScene().active_camera
-
- # Depth is negative and decreasing further from the camera
- depth = object.position[0]*cam.world_to_camera[2][0] + object.position[1]*cam.world_to_camera[2][1] + object.position[2]*cam.world_to_camera[2][2] + cam.world_to_camera[2][3]
-
- @bug: All attributes are read only at the moment.
-
- .. attribute:: name
-
- The scene's name, (read-only).
-
- :type: string
-
- .. attribute:: objects
-
- A list of objects in the scene, (read-only).
-
- :type: :class:`CListValue` of :class:`KX_GameObject`
-
- .. attribute:: objectsInactive
-
- A list of objects on background layers (used for the addObject actuator), (read-only).
-
- :type: :class:`CListValue` of :class:`KX_GameObject`
-
- .. attribute:: lights
-
- A list of lights in the scene, (read-only).
-
- :type: :class:`CListValue` of :class:`KX_LightObject`
-
- .. attribute:: cameras
-
- A list of cameras in the scene, (read-only).
-
- :type: :class:`CListValue` of :class:`KX_Camera`
-
- .. attribute:: active_camera
-
- The current active camera.
-
- :type: :class:`KX_Camera`
-
- .. note::
-
- This can be set directly from python to avoid using the :class:`KX_SceneActuator`.
-
- .. attribute:: suspended
-
- True if the scene is suspended, (read-only).
-
- :type: boolean
-
- .. attribute:: activity_culling
-
- True if the scene is activity culling.
-
- :type: boolean
-
- .. attribute:: activity_culling_radius
-
- The distance outside which to do activity culling. Measured in manhattan distance.
-
- :type: float
-
- .. attribute:: dbvt_culling
-
- True when Dynamic Bounding box Volume Tree is set (read-only).
-
- :type: boolean
-
- .. attribute:: pre_draw
-
- A list of callables to be run before the render step.
-
- :type: list
-
- .. attribute:: post_draw
-
- A list of callables to be run after the render step.
-
- :type: list
-
- .. attribute:: gravity
-
- The scene gravity using the world x, y and z axis.
-
- :type: list [fx, fy, fz]
-
- .. method:: addObject(object, other, time=0)
-
- Adds an object to the scene like the Add Object Actuator would.
-
- :arg object: The object to add
- :type object: :class:`KX_GameObject` or string
- :arg other: The object's center to use when adding the object
- :type other: :class:`KX_GameObject` or string
- :arg time: The lifetime of the added object, in frames. A time of 0 means the object will last forever.
- :type time: integer
- :return: The newly added object.
- :rtype: :class:`KX_GameObject`
-
- .. method:: end()
-
- Removes the scene from the game.
-
- .. method:: restart()
-
- Restarts the scene.
-
- .. method:: replace(scene)
-
- Replaces this scene with another one.
-
- :arg scene: The name of the scene to replace this scene with.
- :type scene: string
-
- .. method:: suspend()
-
- Suspends this scene.
-
- .. method:: resume()
-
- Resume this scene.
-
- .. method:: get(key, default=None)
-
- Return the value matching key, or the default value if its not found.
- :return: The key value or a default.
-
- .. method:: drawObstacleSimulation()
-
- Draw debug visualization of obstacle simulation.
-
-.. class:: KX_SceneActuator(SCA_IActuator)
-
- Scene Actuator logic brick.
-
- .. warning::
-
- Scene actuators that use a scene name will be ignored if at game start, the named scene doesn't exist or is empty
-
- This will generate a warning in the console:
-
- .. code-block:: none
-
- Error: GameObject 'Name' has a SceneActuator 'ActuatorName' (SetScene) without scene
-
- .. attribute:: scene
-
- the name of the scene to change to/overlay/underlay/remove/suspend/resume.
-
- :type: string
-
- .. attribute:: camera
-
- the camera to change to.
-
- :type: :class:`KX_Camera` on read, string or :class:`KX_Camera` on write
-
- .. note::
-
- When setting the attribute, you can use either a :class:`KX_Camera` or the name of the camera.
-
- .. attribute:: useRestart
-
- Set flag to True to restart the sene.
-
- :type: boolean
-
- .. attribute:: mode
-
- The mode of the actuator.
-
- :type: integer from 0 to 5.
-
-.. class:: KX_SoundActuator(SCA_IActuator)
-
- Sound Actuator.
-
- The :data:`startSound`, :data:`pauseSound` and :data:`stopSound` do not require the actuator to be activated - they act instantly provided that the actuator has been activated once at least.
-
- .. attribute:: volume
-
- The volume (gain) of the sound.
-
- :type: float
-
- .. attribute:: time
-
- The current position in the audio stream (in seconds).
-
- :type: float
-
- .. attribute:: pitch
-
- The pitch of the sound.
-
- :type: float
-
- .. attribute:: mode
-
- The operation mode of the actuator. Can be one of :ref:`these constants<logic-sound-actuator>`
-
- :type: integer
-
- .. attribute:: sound
-
- The sound the actuator should play.
-
- :type: Audaspace factory
-
- .. attribute:: is3D
-
- Whether or not the actuator should be using 3D sound. (read-only)
-
- :type: boolean
-
- .. attribute:: volume_maximum
-
- The maximum gain of the sound, no matter how near it is.
-
- :type: float
-
- .. attribute:: volume_minimum
-
- The minimum gain of the sound, no matter how far it is away.
-
- :type: float
-
- .. attribute:: distance_reference
-
- The distance where the sound has a gain of 1.0.
-
- :type: float
-
- .. attribute:: distance_maximum
-
- The maximum distance at which you can hear the sound.
-
- :type: float
-
- .. attribute:: attenuation
-
- The influence factor on volume depending on distance.
-
- :type: float
-
- .. attribute:: cone_angle_inner
-
- The angle of the inner cone.
-
- :type: float
-
- .. attribute:: cone_angle_outer
-
- The angle of the outer cone.
-
- :type: float
-
- .. attribute:: cone_volume_outer
-
- The gain outside the outer cone (the gain in the outer cone will be interpolated between this value and the normal gain in the inner cone).
-
- :type: float
-
- .. method:: startSound()
-
- Starts the sound.
-
- :return: None
-
- .. method:: pauseSound()
-
- Pauses the sound.
-
- :return: None
-
- .. method:: stopSound()
-
- Stops the sound.
-
- :return: None
-
-.. class:: KX_StateActuator(SCA_IActuator)
-
- State actuator changes the state mask of parent object.
-
- .. attribute:: operation
-
- Type of bit operation to be applied on object state mask.
-
- You can use one of :ref:`these constants <state-actuator-operation>`
-
- :type: integer
-
- .. attribute:: mask
-
- Value that defines the bits that will be modified by the operation.
-
- The bits that are 1 in the mask will be updated in the object state.
-
- The bits that are 0 are will be left unmodified expect for the Copy operation which copies the mask to the object state.
-
- :type: integer
-
-.. class:: KX_TrackToActuator(SCA_IActuator)
-
- Edit Object actuator in Track To mode.
-
- .. warning::
-
- Track To Actuators will be ignored if at game start, the object to track to is invalid.
-
- This will generate a warning in the console:
-
- .. code-block:: none
-
- GameObject 'Name' no object in EditObjectActuator 'ActuatorName'
-
- .. attribute:: object
-
- the object this actuator tracks.
-
- :type: :class:`KX_GameObject` or None
-
- .. attribute:: time
-
- the time in frames with which to delay the tracking motion.
-
- :type: integer
-
- .. attribute:: use3D
-
- the tracking motion to use 3D.
-
- :type: boolean
-
-.. class:: KX_VehicleWrapper(PyObjectPlus)
-
- KX_VehicleWrapper
-
- TODO - description
-
- .. method:: addWheel(wheel, attachPos, attachDir, 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 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.
- :type axleDir: vector of 3 floats
- :arg suspensionRestLength: TODO - Description
- :type suspensionRestLength: float
- :arg wheelRadius: The size of the wheel.
- :type wheelRadius: float
-
- .. method:: applyBraking(force, wheelIndex)
-
- Apply a braking force to the specified wheel
-
- :arg force: the brake force
- :type force: float
-
- :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
-
- :arg force: the engine force
- :type force: float
-
- :arg wheelIndex: index of the wheel where the force needs to be applied
- :type wheelIndex: integer
-
- .. method:: getConstraintId()
-
- Get the constraint ID
-
- :return: the constraint id
- :rtype: integer
-
- .. method:: getConstraintType()
-
- Returns the constraint type.
-
- :return: constraint type
- :rtype: integer
-
- .. method:: getNumWheels()
-
- Returns the number of wheels.
-
- :return: the number of wheels for this vehicle
- :rtype: integer
-
- .. method:: getWheelOrientationQuaternion(wheelIndex)
-
- Returns the wheel orientation as a quaternion.
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
- :return: TODO Description
- :rtype: TODO - type should be quat as per method name but from the code it looks like a matrix
-
- .. method:: getWheelPosition(wheelIndex)
-
- Returns the position of the specified wheel
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
- :return: position vector
- :rtype: list[x, y, z]
-
- .. method:: getWheelRotation(wheelIndex)
-
- Returns the rotation of the specified wheel
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
- :return: the wheel rotation
- :rtype: float
-
- .. method:: setRollInfluence(rollInfluece, wheelIndex)
-
- Set the specified wheel's roll influence.
- The higher the roll influence the more the vehicle will tend to roll over in corners.
-
- :arg rollInfluece: the wheel roll influence
- :type rollInfluece: float
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
- .. method:: setSteeringValue(steering, wheelIndex)
-
- Set the specified wheel's steering
-
- :arg steering: the wheel steering
- :type steering: float
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
- .. method:: setSuspensionCompression(compression, wheelIndex)
-
- Set the specified wheel's compression
-
- :arg compression: the wheel compression
- :type compression: float
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
- .. method:: setSuspensionDamping(damping, wheelIndex)
-
- Set the specified wheel's damping
-
- :arg damping: the wheel damping
- :type damping: float
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
- .. method:: setSuspensionStiffness(stiffness, wheelIndex)
-
- Set the specified wheel's stiffness
-
- :arg stiffness: the wheel stiffness
- :type stiffness: float
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
- .. method:: setTyreFriction(friction, wheelIndex)
-
- Set the specified wheel's tyre friction
-
- :arg friction: the tyre friction
- :type friction: float
-
- :arg wheelIndex: the wheel index
- :type wheelIndex: integer
-
-.. class:: KX_CharacterWrapper(PyObjectPlus)
-
- A wrapper to expose character physics options.
-
- .. attribute:: onGround
-
- Whether or not the character is on the ground. (read-only)
-
- :type: boolean
-
- .. attribute:: gravity
-
- The gravity value used for the character.
-
- :type: float
-
- .. method:: jump()
-
- The character jumps based on it's jump speed.
-
-.. class:: KX_VertexProxy(SCA_IObject)
-
- A vertex holds position, UV, color and normal information.
-
- Note:
- The physics simulation is NOT currently updated - physics will not respond
- to changes in the vertex position.
-
- .. attribute:: XYZ
-
- The position of the vertex.
-
- :type: list [x, y, z]
-
- .. attribute:: UV
-
- The texture coordinates of the vertex.
-
- :type: list [u, v]
-
- .. attribute:: normal
-
- The normal of the vertex.
-
- :type: list [nx, ny, nz]
-
- .. attribute:: color
-
- The color of the vertex.
-
- :type: list [r, g, b, a]
-
- Black = [0.0, 0.0, 0.0, 1.0], White = [1.0, 1.0, 1.0, 1.0]
-
- .. attribute:: x
-
- The x coordinate of the vertex.
-
- :type: float
-
- .. attribute:: y
-
- The y coordinate of the vertex.
-
- :type: float
-
- .. attribute:: z
-
- The z coordinate of the vertex.
-
- :type: float
-
- .. attribute:: u
-
- The u texture coordinate of the vertex.
-
- :type: float
-
- .. attribute:: v
-
- The v texture coordinate of the vertex.
-
- :type: float
-
- .. attribute:: u2
-
- The second u texture coordinate of the vertex.
-
- :type: float
-
- .. attribute:: v2
-
- The second v texture coordinate of the vertex.
-
- :type: float
-
- .. attribute:: r
-
- The red component of the vertex color. 0.0 <= r <= 1.0.
-
- :type: float
-
- .. attribute:: g
-
- The green component of the vertex color. 0.0 <= g <= 1.0.
-
- :type: float
-
- .. attribute:: b
-
- The blue component of the vertex color. 0.0 <= b <= 1.0.
-
- :type: float
-
- .. attribute:: a
-
- The alpha component of the vertex color. 0.0 <= a <= 1.0.
-
- :type: float
-
- .. method:: getXYZ()
-
- Gets the position of this vertex.
-
- :return: this vertexes position in local coordinates.
- :rtype: list [x, y, z]
-
- .. method:: setXYZ(pos)
-
- Sets the position of this vertex.
-
- :type: list [x, y, z]
-
- :arg pos: the new position for this vertex in local coordinates.
-
- .. method:: getUV()
-
- Gets the UV (texture) coordinates of this vertex.
-
- :return: this vertexes UV (texture) coordinates.
- :rtype: list [u, v]
-
- .. method:: setUV(uv)
-
- Sets the UV (texture) coordinates of this vertex.
-
- :type: list [u, v]
-
- .. method:: getUV2()
-
- Gets the 2nd UV (texture) coordinates of this vertex.
-
- :return: this vertexes UV (texture) coordinates.
- :rtype: list [u, v]
-
- .. method:: setUV2(uv, unit)
-
- Sets the 2nd UV (texture) coordinates of this vertex.
-
- :type: list [u, v]
-
- :arg unit: optional argument, FLAT==1, SECOND_UV==2, defaults to SECOND_UV
- :arg unit: integer
-
- .. method:: getRGBA()
-
- Gets the color of this vertex.
-
- The color is represented as four bytes packed into an integer value. The color is
- packed as RGBA.
-
- Since Python offers no way to get each byte without shifting, you must use the struct module to
- access color in an machine independent way.
-
- Because of this, it is suggested you use the r, g, b and a attributes or the color attribute instead.
-
- .. code-block:: python
-
- import struct;
- col = struct.unpack('4B', struct.pack('I', v.getRGBA()))
- # col = (r, g, b, a)
- # black = ( 0, 0, 0, 255)
- # white = (255, 255, 255, 255)
-
- :return: packed color. 4 byte integer with one byte per color channel in RGBA format.
- :rtype: integer
-
- .. method:: setRGBA(col)
-
- Sets the color of this vertex.
-
- See getRGBA() for the format of col, and its relevant problems. Use the r, g, b and a attributes
- or the color attribute instead.
-
- setRGBA() also accepts a four component list as argument col. The list represents the color as [r, g, b, a]
- with black = [0.0, 0.0, 0.0, 1.0] and white = [1.0, 1.0, 1.0, 1.0]
-
- .. code-block:: python
-
- v.setRGBA(0xff0000ff) # Red
- v.setRGBA(0xff00ff00) # Green on little endian, transparent purple on big endian
- v.setRGBA([1.0, 0.0, 0.0, 1.0]) # Red
- v.setRGBA([0.0, 1.0, 0.0, 1.0]) # Green on all platforms.
-
- :arg col: the new color of this vertex in packed RGBA format.
- :type col: integer or list [r, g, b, a]
-
- .. method:: getNormal()
-
- Gets the normal vector of this vertex.
-
- :return: normalized normal vector.
- :rtype: list [nx, ny, nz]
-
- .. method:: setNormal(normal)
-
- Sets the normal vector of this vertex.
-
- :type: sequence of floats [r, g, b]
-
- :arg normal: the new normal of this vertex.
-
-.. class:: KX_VisibilityActuator(SCA_IActuator)
-
- Visibility Actuator.
-
- .. attribute:: visibility
-
- whether the actuator makes its parent object visible or invisible.
-
- :type: boolean
-
- .. attribute:: useOcclusion
-
- whether the actuator makes its parent object an occluder or not.
-
- :type: boolean
-
- .. attribute:: useRecursion
-
- whether the visibility/occlusion should be propagated to all children of the object.
-
- :type: boolean
-
-.. class:: SCA_2DFilterActuator(SCA_IActuator)
-
- Create, enable and disable 2D filters
-
- The following properties don't have an immediate effect.
- You must active the actuator to get the result.
- The actuator is not persistent: it automatically stops itself after setting up the filter
- but the filter remains active. To stop a filter you must activate the actuator with 'type'
- set to :data:`~bge.logic.RAS_2DFILTER_DISABLED` or :data:`~bge.logic.RAS_2DFILTER_NOFILTER`.
-
- .. attribute:: shaderText
-
- shader source code for custom shader.
-
- :type: string
-
- .. attribute:: disableMotionBlur
-
- action on motion blur: 0=enable, 1=disable.
-
- :type: integer
-
- .. attribute:: mode
-
- Type of 2D filter, use one of :ref:`these constants <Two-D-FilterActuator-mode>`
-
- :type: integer
-
- .. attribute:: passNumber
-
- order number of filter in the stack of 2D filters. Filters are executed in increasing order of passNb.
-
- Only be one filter can be defined per passNb.
-
- :type: integer (0-100)
-
- .. attribute:: value
-
- argument for motion blur filter.
-
- :type: float (0.0-100.0)
-
-.. class:: SCA_ANDController(SCA_IController)
-
- An AND controller activates only when all linked sensors are activated.
-
- There are no special python methods for this controller.
-
-.. class:: SCA_ActuatorSensor(SCA_ISensor)
-
- Actuator sensor detect change in actuator state of the parent object.
- It generates a positive pulse if the corresponding actuator is activated
- and a negative pulse if the actuator is deactivated.
-
- .. attribute:: actuator
-
- the name of the actuator that the sensor is monitoring.
-
- :type: string
-
-.. class:: SCA_AlwaysSensor(SCA_ISensor)
-
- This sensor is always activated.
-
-.. class:: SCA_DelaySensor(SCA_ISensor)
-
- The Delay sensor generates positive and negative triggers at precise time,
- expressed in number of frames. The delay parameter defines the length of the initial OFF period. A positive trigger is generated at the end of this period.
-
- The duration parameter defines the length of the ON period following the OFF period.
- There is a negative trigger at the end of the ON period. If duration is 0, the sensor stays ON and there is no negative trigger.
-
- The sensor runs the OFF-ON cycle once unless the repeat option is set: the OFF-ON cycle repeats indefinately (or the OFF cycle if duration is 0).
-
- Use :class:`SCA_ISensor.reset` at any time to restart sensor.
-
- .. attribute:: delay
-
- length of the initial OFF period as number of frame, 0 for immediate trigger.
-
- :type: integer.
-
- .. attribute:: duration
-
- length of the ON period in number of frame after the initial OFF period.
-
- If duration is greater than 0, a negative trigger is sent at the end of the ON pulse.
-
- :type: integer
-
- .. attribute:: repeat
-
- 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once.
-
- :type: integer
-
-.. class:: SCA_JoystickSensor(SCA_ISensor)
-
- This sensor detects player joystick events.
-
- .. attribute:: axisValues
-
- The state of the joysticks axis as a list of values :data:`numAxis` long. (read-only).
-
- :type: list of ints.
-
- Each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing.
- The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls.
-
- * left:[-32767, 0, ...]
- * right:[32767, 0, ...]
- * up:[0, -32767, ...]
- * down:[0, 32767, ...]
-
- .. attribute:: axisSingle
-
- like :data:`axisValues` but returns a single axis value that is set by the sensor. (read-only).
-
- :type: integer
-
- .. note::
-
- Only use this for "Single Axis" type sensors otherwise it will raise an error.
-
- .. attribute:: hatValues
-
- The state of the joysticks hats as a list of values :data:`numHats` long. (read-only).
-
- :type: list of ints
-
- Each spesifying the direction of the hat from 1 to 12, 0 when inactive.
-
- Hat directions are as follows...
-
- * 0:None
- * 1:Up
- * 2:Right
- * 4:Down
- * 8:Left
- * 3:Up - Right
- * 6:Down - Right
- * 12:Down - Left
- * 9:Up - Left
-
- .. attribute:: hatSingle
-
- Like :data:`hatValues` but returns a single hat direction value that is set by the sensor. (read-only).
-
- :type: integer
-
- .. attribute:: numAxis
-
- The number of axes for the joystick at this index. (read-only).
-
- :type: integer
-
- .. attribute:: numButtons
-
- The number of buttons for the joystick at this index. (read-only).
-
- :type: integer
-
- .. attribute:: numHats
-
- The number of hats for the joystick at this index. (read-only).
-
- :type: integer
-
- .. attribute:: connected
-
- True if a joystick is connected at this joysticks index. (read-only).
-
- :type: boolean
-
- .. attribute:: index
-
- The joystick index to use (from 0 to 7). The first joystick is always 0.
-
- :type: integer
-
- .. attribute:: threshold
-
- Axis threshold. Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive.
-
- :type: integer
-
- .. attribute:: button
-
- The button index the sensor reacts to (first button = 0). When the "All Events" toggle is set, this option has no effect.
-
- :type: integer
-
- .. attribute:: axis
-
- The axis this sensor reacts to, as a list of two values [axisIndex, axisDirection]
-
- * axisIndex: the axis index to use when detecting axis movement, 1=primary directional control, 2=secondary directional control.
- * axisDirection: 0=right, 1=up, 2=left, 3=down.
-
- :type: [integer, integer]
-
- .. attribute:: hat
-
- The hat the sensor reacts to, as a list of two values: [hatIndex, hatDirection]
-
- * hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat (4 max).
- * hatDirection: 1-12.
-
- :type: [integer, integer]
-
- .. method:: getButtonActiveList()
-
- :return: A list containing the indicies of the currently pressed buttons.
- :rtype: list
-
- .. method:: getButtonStatus(buttonIndex)
-
- :arg buttonIndex: the button index, 0=first button
- :type buttonIndex: integer
- :return: The current pressed state of the specified button.
- :rtype: boolean
-
-.. class:: SCA_KeyboardSensor(SCA_ISensor)
-
- A keyboard sensor detects player key presses.
-
- See module :mod:`bge.keys` for keycode values.
-
- .. attribute:: key
-
- The key code this sensor is looking for.
-
- :type: keycode from :mod:`bge.keys` module
-
- .. attribute:: hold1
-
- The key code for the first modifier this sensor is looking for.
-
- :type: keycode from :mod:`bge.keys` module
-
- .. attribute:: hold2
-
- The key code for the second modifier this sensor is looking for.
-
- :type: keycode from :mod:`bge.keys` module
-
- .. attribute:: toggleProperty
-
- The name of the property that indicates whether or not to log keystrokes as a string.
-
- :type: string
-
- .. attribute:: targetProperty
-
- The name of the property that receives keystrokes in case in case a string is logged.
-
- :type: string
-
- .. attribute:: useAllKeys
-
- Flag to determine whether or not to accept all keys.
-
- :type: boolean
-
- .. attribute:: events
-
- a list of pressed keys that have either been pressed, or just released, or are active this frame. (read-only).
-
- :type: list [[:ref:`keycode<keyboard-keys>`, :ref:`status<input-status>`], ...]
-
- .. method:: getKeyStatus(keycode)
-
- Get the status of a key.
-
- :arg keycode: The code that represents the key you want to get the state of, use one of :ref:`these constants<keyboard-keys>`
- :type keycode: integer
- :return: The state of the given key, can be one of :ref:`these constants<input-status>`
- :rtype: int
-
-.. class:: SCA_NANDController(SCA_IController)
-
- An NAND controller activates when all linked sensors are not active.
-
- There are no special python methods for this controller.
-
-.. class:: SCA_NORController(SCA_IController)
-
- An NOR controller activates only when all linked sensors are de-activated.
-
- There are no special python methods for this controller.
-
-.. class:: SCA_ORController(SCA_IController)
-
- An OR controller activates when any connected sensor activates.
-
- There are no special python methods for this controller.
-
-.. class:: SCA_PropertyActuator(SCA_IActuator)
-
- Property Actuator
-
- .. attribute:: propName
-
- the property on which to operate.
-
- :type: string
-
- .. attribute:: value
-
- the value with which the actuator operates.
-
- :type: string
-
- .. attribute:: mode
-
- TODO - add constants to game logic dict!.
-
- :type: integer
-
-.. class:: SCA_PropertySensor(SCA_ISensor)
-
- Activates when the game object property matches.
-
- .. attribute:: mode
-
- Type of check on the property. Can be one of :ref:`these constants <logic-property-sensor>`
-
- :type: integer.
-
- .. attribute:: propName
-
- the property the sensor operates.
-
- :type: string
-
- .. attribute:: value
-
- the value with which the sensor compares to the value of the property.
-
- :type: string
-
- .. attribute:: min
-
- the minimum value of the range used to evaluate the property when in interval mode.
-
- :type: string
-
- .. attribute:: max
-
- the maximum value of the range used to evaluate the property when in interval mode.
-
- :type: string
-
-.. class:: SCA_PythonController(SCA_IController)
-
- A Python controller uses a Python script to activate it's actuators,
- based on it's sensors.
-
- .. attribute:: script
-
- The value of this variable depends on the execution methid.
-
- * When 'Script' execution mode is set this value contains the entire python script as a single string (not the script name as you might expect) which can be modified to run different scripts.
- * When 'Module' execution mode is set this value will contain a single line string - module name and function "module.func" or "package.modile.func" where the module names are python textblocks or external scripts.
-
- :type: string
-
- .. note::
-
- Once this is set the script name given for warnings will remain unchanged.
-
- .. attribute:: mode
-
- the execution mode for this controller (read-only).
-
- * Script: 0, Execite the :data:`script` as a python code.
- * Module: 1, Execite the :data:`script` as a module and function.
-
- :type: integer
-
- .. method:: activate(actuator)
-
- Activates an actuator attached to this controller.
-
- :arg actuator: The actuator to operate on.
- :type actuator: actuator or the actuator name as a string
-
- .. method:: deactivate(actuator)
-
- Deactivates an actuator attached to this controller.
-
- :arg actuator: The actuator to operate on.
- :type actuator: actuator or the actuator name as a string
-
-.. class:: SCA_RandomActuator(SCA_IActuator)
-
- Random Actuator
-
- .. attribute:: seed
-
- Seed of the random number generator.
-
- :type: integer.
-
- Equal seeds produce equal series. If the seed is 0, the generator will produce the same value on every call.
-
- .. attribute:: para1
-
- the first parameter of the active distribution.
-
- :type: float, read-only.
-
- Refer to the documentation of the generator types for the meaning of this value.
-
- .. attribute:: para2
-
- the second parameter of the active distribution.
-
- :type: float, read-only
-
- Refer to the documentation of the generator types for the meaning of this value.
-
- .. attribute:: distribution
-
- Distribution type. (read-only). Can be one of :ref:`these constants <logic-random-distributions>`
-
- :type: integer
-
- .. attribute:: propName
-
- the name of the property to set with the random value.
-
- :type: string
-
- If the generator and property types do not match, the assignment is ignored.
-
- .. method:: setBoolConst(value)
-
- Sets this generator to produce a constant boolean value.
-
- :arg value: The value to return.
- :type value: boolean
-
- .. method:: setBoolUniform()
-
- Sets this generator to produce a uniform boolean distribution.
-
- The generator will generate True or False with 50% chance.
-
- .. method:: setBoolBernouilli(value)
-
- Sets this generator to produce a Bernouilli distribution.
-
- :arg value: Specifies the proportion of False values to produce.
-
- * 0.0: Always generate True
- * 1.0: Always generate False
- :type value: float
-
- .. method:: setIntConst(value)
-
- Sets this generator to always produce the given value.
-
- :arg value: the value this generator produces.
- :type value: integer
-
- .. method:: setIntUniform(lower_bound, upper_bound)
-
- Sets this generator to produce a random value between the given lower and
- upper bounds (inclusive).
-
- :type lower_bound: integer
- :type upper_bound: integer
-
- .. method:: setIntPoisson(value)
-
- Generate a Poisson-distributed number.
-
- This performs a series of Bernouilli tests with parameter value.
- It returns the number of tries needed to achieve succes.
-
- :type value: float
-
- .. method:: setFloatConst(value)
-
- Always generate the given value.
-
- :type value: float
-
- .. method:: setFloatUniform(lower_bound, upper_bound)
-
- Generates a random float between lower_bound and upper_bound with a
- uniform distribution.
-
- :type lower_bound: float
- :type upper_bound: float
-
- .. method:: setFloatNormal(mean, standard_deviation)
-
- Generates a random float from the given normal distribution.
-
- :arg mean: The mean (average) value of the generated numbers
- :type mean: float
- :arg standard_deviation: The standard deviation of the generated numbers.
- :type standard_deviation: float
-
- .. method:: setFloatNegativeExponential(half_life)
-
- Generate negative-exponentially distributed numbers.
-
- The half-life 'time' is characterized by half_life.
-
- :type half_life: float
-
-.. class:: SCA_RandomSensor(SCA_ISensor)
-
- This sensor activates randomly.
-
- .. attribute:: lastDraw
-
- The seed of the random number generator.
-
- :type: integer
-
- .. attribute:: seed
-
- The seed of the random number generator.
-
- :type: integer
-
-.. class:: SCA_XNORController(SCA_IController)
-
- An XNOR controller activates when all linked sensors are the same (activated or inative).
-
- There are no special python methods for this controller.
-
-.. class:: SCA_XORController(SCA_IController)
-
- An XOR controller activates when there is the input is mixed, but not when all are on or off.
-
- There are no special python methods for this controller.
-
-.. class:: KX_Camera(KX_GameObject)
-
- A Camera object.
-
- .. data:: INSIDE
-
- See :data:`sphereInsideFrustum` and :data:`boxInsideFrustum`
-
- .. data:: INTERSECT
-
- See :data:`sphereInsideFrustum` and :data:`boxInsideFrustum`
-
- .. data:: OUTSIDE
-
- See :data:`sphereInsideFrustum` and :data:`boxInsideFrustum`
-
- .. attribute:: lens
-
- The camera's lens value.
-
- :type: float
-
- .. attribute:: ortho_scale
-
- The camera's view scale when in orthographic mode.
-
- :type: float
-
- .. attribute:: near
-
- The camera's near clip distance.
-
- :type: float
-
- .. attribute:: far
-
- The camera's far clip distance.
-
- :type: float
-
- .. attribute:: perspective
-
- True if this camera has a perspective transform, False for an orthographic projection.
-
- :type: boolean
-
- .. attribute:: frustum_culling
-
- True if this camera is frustum culling.
-
- :type: boolean
-
- .. attribute:: projection_matrix
-
- This camera's 4x4 projection matrix.
-
- .. note::
-
- This is the identity matrix prior to rendering the first frame (any Python done on frame 1).
-
- :type: 4x4 Matrix [[float]]
-
- .. attribute:: modelview_matrix
-
- This camera's 4x4 model view matrix. (read-only).
-
- :type: 4x4 Matrix [[float]]
-
- .. note::
-
- This matrix is regenerated every frame from the camera's position and orientation. Also, this is the identity matrix prior to rendering the first frame (any Python done on frame 1).
-
- .. attribute:: camera_to_world
-
- This camera's camera to world transform. (read-only).
-
- :type: 4x4 Matrix [[float]]
-
- .. note::
-
- This matrix is regenerated every frame from the camera's position and orientation.
-
- .. attribute:: world_to_camera
-
- This camera's world to camera transform. (read-only).
-
- :type: 4x4 Matrix [[float]]
-
- .. note::
-
- Regenerated every frame from the camera's position and orientation.
-
- .. note::
-
- This is camera_to_world inverted.
-
- .. attribute:: useViewport
-
- True when the camera is used as a viewport, set True to enable a viewport for this camera.
-
- :type: boolean
-
- .. method:: sphereInsideFrustum(centre, radius)
-
- Tests the given sphere against the view frustum.
-
- :arg centre: The centre of the sphere (in world coordinates.)
- :type centre: list [x, y, z]
- :arg radius: the radius of the sphere
- :type radius: float
- :return: :data:`~bge.types.KX_Camera.INSIDE`, :data:`~bge.types.KX_Camera.OUTSIDE` or :data:`~bge.types.KX_Camera.INTERSECT`
- :rtype: integer
-
- .. note::
-
- When the camera is first initialized the result will be invalid because the projection matrix has not been set.
-
- .. code-block:: python
-
- from bge import logic
- cont = logic.getCurrentController()
- cam = cont.owner
-
- # A sphere of radius 4.0 located at [x, y, z] = [1.0, 1.0, 1.0]
- if (cam.sphereInsideFrustum([1.0, 1.0, 1.0], 4) != cam.OUTSIDE):
- # Sphere is inside frustum !
- # Do something useful !
- else:
- # Sphere is outside frustum
-
- .. method:: boxInsideFrustum(box)
-
- Tests the given box against the view frustum.
-
- :arg box: Eight (8) corner points of the box (in world coordinates.)
- :type box: list of lists
- :return: :data:`~bge.types.KX_Camera.INSIDE`, :data:`~bge.types.KX_Camera.OUTSIDE` or :data:`~bge.types.KX_Camera.INTERSECT`
-
- .. note::
-
- When the camera is first initialized the result will be invalid because the projection matrix has not been set.
-
- .. code-block:: python
-
- from bge import logic
- cont = logic.getCurrentController()
- cam = cont.owner
-
- # Box to test...
- box = []
- box.append([-1.0, -1.0, -1.0])
- box.append([-1.0, -1.0, 1.0])
- box.append([-1.0, 1.0, -1.0])
- box.append([-1.0, 1.0, 1.0])
- box.append([ 1.0, -1.0, -1.0])
- box.append([ 1.0, -1.0, 1.0])
- box.append([ 1.0, 1.0, -1.0])
- box.append([ 1.0, 1.0, 1.0])
-
- if (cam.boxInsideFrustum(box) != cam.OUTSIDE):
- # Box is inside/intersects frustum !
- # Do something useful !
- else:
- # Box is outside the frustum !
-
- .. method:: pointInsideFrustum(point)
-
- Tests the given point against the view frustum.
-
- :arg point: The point to test (in world coordinates.)
- :type point: 3D Vector
- :return: True if the given point is inside this camera's viewing frustum.
- :rtype: boolean
-
- .. note::
-
- When the camera is first initialized the result will be invalid because the projection matrix has not been set.
-
- .. code-block:: python
-
- from bge import logic
- cont = logic.getCurrentController()
- cam = cont.owner
-
- # Test point [0.0, 0.0, 0.0]
- if (cam.pointInsideFrustum([0.0, 0.0, 0.0])):
- # Point is inside frustum !
- # Do something useful !
- else:
- # Box is outside the frustum !
-
- .. method:: getCameraToWorld()
-
- Returns the camera-to-world transform.
-
- :return: the camera-to-world transform matrix.
- :rtype: matrix (4x4 list)
-
- .. method:: getWorldToCamera()
-
- Returns the world-to-camera transform.
-
- This returns the inverse matrix of getCameraToWorld().
-
- :return: the world-to-camera transform matrix.
- :rtype: matrix (4x4 list)
-
- .. method:: setOnTop()
-
- Set this cameras viewport ontop of all other viewport.
-
- .. method:: setViewport(left, bottom, right, top)
-
- Sets the region of this viewport on the screen in pixels.
-
- Use :data:`bge.render.getWindowHeight` and :data:`bge.render.getWindowWidth` to calculate values relative to the entire display.
-
- :arg left: left pixel coordinate of this viewport
- :type left: integer
- :arg bottom: bottom pixel coordinate of this viewport
- :type bottom: integer
- :arg right: right pixel coordinate of this viewport
- :type right: integer
- :arg top: top pixel coordinate of this viewport
- :type top: integer
-
- .. method:: getScreenPosition(object)
-
- Gets the position of an object projected on screen space.
-
- .. code-block:: python
-
- # For an object in the middle of the screen, coord = [0.5, 0.5]
- coord = camera.getScreenPosition(object)
-
- :arg object: object name or list [x, y, z]
- :type object: :class:`KX_GameObject` or 3D Vector
- :return: the object's position in screen coordinates.
- :rtype: list [x, y]
-
- .. method:: getScreenVect(x, y)
-
- Gets the vector from the camera position in the screen coordinate direction.
-
- :arg x: X Axis
- :type x: float
- :arg y: Y Axis
- :type y: float
- :rtype: 3D Vector
- :return: The vector from screen coordinate.
-
- .. code-block:: python
-
- # Gets the vector of the camera front direction:
- m_vect = camera.getScreenVect(0.5, 0.5)
-
- .. method:: getScreenRay(x, y, dist=inf, property=None)
-
- Look towards a screen coordinate (x, y) and find first object hit within dist that matches prop.
- The ray is similar to KX_GameObject->rayCastTo.
-
- :arg x: X Axis
- :type x: float
- :arg y: Y Axis
- :type y: float
- :arg dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other
- :type dist: float
- :arg property: property name that object must have; can be omitted => detect any object
- :type property: string
- :rtype: :class:`KX_GameObject`
- :return: the first object hit or None if no object or object does not match prop
-
- .. code-block:: python
-
- # Gets an object with a property "wall" in front of the camera within a distance of 100:
- target = camera.getScreenRay(0.5, 0.5, 100, "wall")
-
-.. class:: BL_ArmatureObject(KX_GameObject)
-
- An armature object.
-
- .. attribute:: constraints
-
- The list of armature constraint defined on this armature.
- Elements of the list can be accessed by index or string.
- The key format for string access is '<bone_name>:<constraint_name>'.
-
- :type: list of :class:`BL_ArmatureConstraint`
-
- .. attribute:: channels
-
- The list of armature channels.
- Elements of the list can be accessed by index or name the bone.
-
- :type: list of :class:`BL_ArmatureChannel`
-
- .. method:: update()
-
- Ensures that the armature will be updated on next graphic frame.
-
- This action is unecessary if a KX_ArmatureActuator with mode run is active
- or if an action is playing. Use this function in other cases. It must be called
- on each frame to ensure that the armature is updated continously.
-
-.. class:: BL_ArmatureActuator(SCA_IActuator)
-
- Armature Actuators change constraint condition on armatures.
-
- .. attribute:: type
-
- The type of action that the actuator executes when it is active.
-
- Can be one of :ref:`these constants <armatureactuator-constants-type>`
-
- :type: integer
-
- .. attribute:: constraint
-
- The constraint object this actuator is controlling.
-
- :type: :class:`BL_ArmatureConstraint`
-
- .. attribute:: target
-
- The object that this actuator will set as primary target to the constraint it controls.
-
- :type: :class:`KX_GameObject`
-
- .. attribute:: subtarget
-
- The object that this actuator will set as secondary target to the constraint it controls.
-
- :type: :class:`KX_GameObject`.
-
- .. note::
-
- Currently, the only secondary target is the pole target for IK constraint.
-
- .. attribute:: weight
-
- The weight this actuator will set on the constraint it controls.
-
- :type: float.
-
- .. note::
-
- Currently only the IK constraint has a weight. It must be a value between 0 and 1.
-
- .. note::
-
- A weight of 0 disables a constraint while still updating constraint runtime values (see :class:`BL_ArmatureConstraint`)
-
- .. attribute:: influence
-
- The influence this actuator will set on the constraint it controls.
-
- :type: float.
-
-.. class:: KX_ArmatureSensor(SCA_ISensor)
-
- Armature sensor detect conditions on armatures.
-
- .. attribute:: type
-
- The type of measurement that the sensor make when it is active.
-
- Can be one of :ref:`these constants <armaturesensor-type>`
-
- :type: integer.
-
- .. attribute:: constraint
-
- The constraint object this sensor is watching.
-
- :type: :class:`BL_ArmatureConstraint`
-
- .. attribute:: value
-
- The threshold used in the comparison with the constraint error
- The linear error is only updated on CopyPose/Distance IK constraint with iTaSC solver
- The rotation error is only updated on CopyPose+rotation IK constraint with iTaSC solver
- The linear error on CopyPose is always >= 0: it is the norm of the distance between the target and the bone
- The rotation error on CopyPose is always >= 0: it is the norm of the equivalent rotation vector between the bone and the target orientations
- The linear error on Distance can be positive if the distance between the bone and the target is greater than the desired distance, and negative if the distance is smaller.
-
- :type: float
-
-.. class:: BL_ArmatureConstraint(PyObjectPlus)
-
- Proxy to Armature Constraint. Allows to change constraint on the fly.
- Obtained through :class:`BL_ArmatureObject`.constraints.
-
- .. note::
-
- Not all armature constraints are supported in the GE.
-
-
- .. attribute:: type
-
- Type of constraint, (read-only).
-
- Use one of :ref:`these constants<armatureconstraint-constants-type>`.
-
- :type: integer, one of CONSTRAINT_TYPE_* constants
-
- .. attribute:: name
-
- Name of constraint constructed as <bone_name>:<constraint_name>. constraints list.
-
- :type: string
-
- This name is also the key subscript on :class:`BL_ArmatureObject`.
-
- .. attribute:: enforce
-
- fraction of constraint effect that is enforced. Between 0 and 1.
-
- :type: float
-
- .. attribute:: headtail
-
- Position of target between head and tail of the target bone: 0=head, 1=tail.
-
- :type: float.
-
- .. note::
-
- Only used if the target is a bone (i.e target object is an armature.
-
- .. attribute:: lin_error
-
- runtime linear error (in Blender units) on constraint at the current frame.
-
- This is a runtime value updated on each frame by the IK solver. Only available on IK constraint and iTaSC solver.
-
- :type: float
-
- .. attribute:: rot_error
-
- Runtime rotation error (in radiant) on constraint at the current frame.
-
- :type: float.
-
- This is a runtime value updated on each frame by the IK solver. Only available on IK constraint and iTaSC solver.
-
- It is only set if the constraint has a rotation part, for example, a CopyPose+Rotation IK constraint.
-
- .. attribute:: target
-
- Primary target object for the constraint. The position of this object in the GE will be used as target for the constraint.
-
- :type: :class:`KX_GameObject`.
-
- .. attribute:: subtarget
-
- Secondary target object for the constraint. The position of this object in the GE will be used as secondary target for the constraint.
-
- :type: :class:`KX_GameObject`.
-
- Currently this is only used for pole target on IK constraint.
-
- .. attribute:: active
-
- True if the constraint is active.
-
- :type: boolean
-
- .. note::
-
- An inactive constraint does not update lin_error and rot_error.
-
- .. attribute:: ik_weight
-
- Weight of the IK constraint between 0 and 1.
-
- Only defined for IK constraint.
-
- :type: float
-
- .. attribute:: ik_type
-
- Type of IK constraint, (read-only).
-
- Use one of :ref:`these constants<armatureconstraint-constants-ik-type>`.
-
- :type: integer.
-
- .. attribute:: ik_flag
-
- Combination of IK constraint option flags, read-only.
-
- Use one of :ref:`these constants<armatureconstraint-constants-ik-flag>`.
-
- :type: integer
-
- .. attribute:: ik_dist
-
- Distance the constraint is trying to maintain with target, only used when ik_type=CONSTRAINT_IK_DISTANCE.
-
- :type: float
-
- .. attribute:: ik_mode
-
- Use one of :ref:`these constants<armatureconstraint-constants-ik-mode>`.
-
- Additional mode for IK constraint. Currently only used for Distance constraint:
-
- :type: integer
-
-.. class:: BL_ArmatureChannel(PyObjectPlus)
-
- Proxy to armature pose channel. Allows to read and set armature pose.
- The attributes are identical to RNA attributes, but mostly in read-only mode.
-
- .. attribute:: name
-
- channel name (=bone name), read-only.
-
- :type: string
-
- .. attribute:: bone
-
- return the bone object corresponding to this pose channel, read-only.
-
- :type: :class:`BL_ArmatureBone`
-
- .. attribute:: parent
-
- return the parent channel object, None if root channel, read-only.
-
- :type: :class:`BL_ArmatureChannel`
-
- .. attribute:: has_ik
-
- true if the bone is part of an active IK chain, read-only.
- This flag is not set when an IK constraint is defined but not enabled (miss target information for example).
-
- :type: boolean
-
- .. attribute:: ik_dof_x
-
- true if the bone is free to rotation in the X axis, read-only.
-
- :type: boolean
-
- .. attribute:: ik_dof_y
-
- true if the bone is free to rotation in the Y axis, read-only.
-
- :type: boolean
-
- .. attribute:: ik_dof_z
-
- true if the bone is free to rotation in the Z axis, read-only.
-
- :type: boolean
-
- .. attribute:: ik_limit_x
-
- true if a limit is imposed on X rotation, read-only.
-
- :type: boolean
-
- .. attribute:: ik_limit_y
-
- true if a limit is imposed on Y rotation, read-only.
-
- :type: boolean
-
- .. attribute:: ik_limit_z
-
- true if a limit is imposed on Z rotation, read-only.
-
- :type: boolean
-
- .. attribute:: ik_rot_control
-
- true if channel rotation should applied as IK constraint, read-only.
-
- :type: boolean
-
- .. attribute:: ik_lin_control
-
- true if channel size should applied as IK constraint, read-only.
-
- :type: boolean
-
- .. attribute:: location
-
- displacement of the bone head in armature local space, read-write.
-
- :type: vector [X, Y, Z].
-
- .. note::
-
- You can only move a bone if it is unconnected to its parent. An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
-
- .. note::
-
- Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`).
-
- .. attribute:: scale
-
- scale of the bone relative to its parent, read-write.
-
- :type: vector [sizeX, sizeY, sizeZ].
-
- .. note::
-
- An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
-
- .. note::
-
- Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`)
-
- .. attribute:: rotation_quaternion
-
- rotation of the bone relative to its parent expressed as a quaternion, read-write.
-
- :type: vector [qr, qi, qj, qk].
-
- .. note::
-
- This field is only used if rotation_mode is 0. An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
-
- .. note::
-
- Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`)
-
- .. attribute:: rotation_euler
-
- rotation of the bone relative to its parent expressed as a set of euler angles, read-write.
-
- :type: vector [X, Y, Z].
-
- .. note::
-
- This field is only used if rotation_mode is > 0. You must always pass the angles in [X, Y, Z] order; the order of applying the angles to the bone depends on rotation_mode. An action playing on the armature may change this field. An IK chain does not update this value, see joint_rotation.
-
- .. note::
-
- Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`)
-
- .. attribute:: rotation_mode
-
- Method of updating the bone rotation, read-write.
-
- :type: integer (one of :ref:`these constants <armaturechannel-constants-rotation-mode>`)
-
- .. attribute:: channel_matrix
-
- pose matrix in bone space (deformation of the bone due to action, constraint, etc), Read-only.
- This field is updated after the graphic render, it represents the current pose.
-
- :type: matrix [4][4]
-
- .. attribute:: pose_matrix
-
- pose matrix in armature space, read-only,
- This field is updated after the graphic render, it represents the current pose.
-
- :type: matrix [4][4]
-
- .. attribute:: pose_head
-
- position of bone head in armature space, read-only.
-
- :type: vector [x, y, z]
-
- .. attribute:: pose_tail
-
- position of bone tail in armature space, read-only.
-
- :type: vector [x, y, z]
-
- .. attribute:: ik_min_x
-
- minimum value of X rotation in degree (<= 0) when X rotation is limited (see ik_limit_x), read-only.
-
- :type: float
-
- .. attribute:: ik_max_x
-
- maximum value of X rotation in degree (>= 0) when X rotation is limited (see ik_limit_x), read-only.
-
- :type: float
-
- .. attribute:: ik_min_y
-
- minimum value of Y rotation in degree (<= 0) when Y rotation is limited (see ik_limit_y), read-only.
-
- :type: float
-
- .. attribute:: ik_max_y
-
- maximum value of Y rotation in degree (>= 0) when Y rotation is limited (see ik_limit_y), read-only.
-
- :type: float
-
- .. attribute:: ik_min_z
-
- minimum value of Z rotation in degree (<= 0) when Z rotation is limited (see ik_limit_z), read-only.
-
- :type: float
-
- .. attribute:: ik_max_z
-
- maximum value of Z rotation in degree (>= 0) when Z rotation is limited (see ik_limit_z), read-only.
-
- :type: float
-
- .. attribute:: ik_stiffness_x
-
- bone rotation stiffness in X axis, read-only.
-
- :type: float between 0 and 1
-
- .. attribute:: ik_stiffness_y
-
- bone rotation stiffness in Y axis, read-only.
-
- :type: float between 0 and 1
-
- .. attribute:: ik_stiffness_z
-
- bone rotation stiffness in Z axis, read-only.
-
- :type: float between 0 and 1
-
- .. attribute:: ik_stretch
-
- ratio of scale change that is allowed, 0=bone can't change size, read-only.
-
- :type: float
-
- .. attribute:: ik_rot_weight
-
- weight of rotation constraint when ik_rot_control is set, read-write.
-
- :type: float between 0 and 1
-
- .. attribute:: ik_lin_weight
-
- weight of size constraint when ik_lin_control is set, read-write.
-
- :type: float between 0 and 1
-
- .. attribute:: joint_rotation
-
- Control bone rotation in term of joint angle (for robotic applications), read-write.
-
- When writing to this attribute, you pass a [x, y, z] vector and an appropriate set of euler angles or quaternion is calculated according to the rotation_mode.
-
- When you read this attribute, the current pose matrix is converted into a [x, y, z] vector representing the joint angles.
-
- The value and the meaning of the x, y, z depends on the ik_dof_x/ik_dof_y/ik_dof_z attributes:
-
- * 1DoF joint X, Y or Z: the corresponding x, y, or z value is used an a joint angle in radiant
- * 2DoF joint X+Y or Z+Y: treated as 2 successive 1DoF joints: first X or Z, then Y. The x or z value is used as a joint angle in radiant along the X or Z axis, followed by a rotation along the new Y axis of y radiants.
- * 2DoF joint X+Z: treated as a 2DoF joint with rotation axis on the X/Z plane. The x and z values are used as the coordinates of the rotation vector in the X/Z plane.
- * 3DoF joint X+Y+Z: treated as a revolute joint. The [x, y, z] vector represents the equivalent rotation vector to bring the joint from the rest pose to the new pose.
-
- :type: vector [x, y, z]
-
- .. note::
-
- The bone must be part of an IK chain if you want to set the ik_dof_x/ik_dof_y/ik_dof_z attributes via the UI, but this will interfere with this attribute since the IK solver will overwrite the pose. You can stay in control of the armature if you create an IK constraint but do not finalize it (e.g. don't set a target) the IK solver will not run but the IK panel will show up on the UI for each bone in the chain.
-
- .. note::
-
- [0, 0, 0] always corresponds to the rest pose.
-
- .. note::
-
- You must request the armature pose to update and wait for the next graphic frame to see the effect of setting this attribute (see :data:`BL_ArmatureObject.update`).
-
- .. note::
-
- You can read the result of the calculation in rotation or euler_rotation attributes after setting this attribute.
-
-.. class:: BL_ArmatureBone(PyObjectPlus)
-
- Proxy to Blender bone structure. All fields are read-only and comply to RNA names.
- All space attribute correspond to the rest pose.
-
- .. attribute:: name
-
- bone name.
-
- :type: string
-
- .. attribute:: connected
-
- true when the bone head is struck to the parent's tail.
-
- :type: boolean
-
- .. attribute:: hinge
-
- true when bone doesn't inherit rotation or scale from parent bone.
-
- :type: boolean
-
- .. attribute:: inherit_scale
-
- true when bone inherits scaling from parent bone.
-
- :type: boolean
-
- .. attribute:: bbone_segments
-
- number of B-bone segments.
-
- :type: integer
-
- .. attribute:: roll
-
- bone rotation around head-tail axis.
-
- :type: float
-
- .. attribute:: head
-
- location of head end of the bone in parent bone space.
-
- :type: vector [x, y, z]
-
- .. attribute:: tail
-
- location of head end of the bone in parent bone space.
-
- :type: vector [x, y, z]
-
- .. attribute:: length
-
- bone length.
-
- :type: float
-
- .. attribute:: arm_head
-
- location of head end of the bone in armature space.
-
- :type: vector [x, y, z]
-
- .. attribute:: arm_tail
-
- location of tail end of the bone in armature space.
-
- :type: vector [x, y, z]
-
- .. attribute:: arm_mat
-
- matrix of the bone head in armature space.
-
- :type: matrix [4][4]
-
- .. note::
-
- This matrix has no scale part.
-
- .. attribute:: bone_mat
-
- rotation matrix of the bone in parent bone space.
-
- :type: matrix [3][3]
-
- .. attribute:: parent
-
- parent bone, or None for root bone.
-
- :type: :class:`BL_ArmatureBone`
-
- .. attribute:: children
-
- list of bone's children.
-
- :type: list of :class:`BL_ArmatureBone`
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_ActionActuator.rst b/doc/python_api/rst/bge_types/bge.types.BL_ActionActuator.rst
new file mode 100644
index 00000000000..9b95a5ba611
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_ActionActuator.rst
@@ -0,0 +1,78 @@
+BL_ActionActuator(SCA_IActuator)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: BL_ActionActuator(SCA_IActuator)
+
+ Action Actuators apply an action to an actor.
+
+ .. attribute:: action
+
+ The name of the action to set as the current action.
+
+ :type: string
+
+ .. attribute:: frameStart
+
+ Specifies the starting frame of the animation.
+
+ :type: float
+
+ .. attribute:: frameEnd
+
+ Specifies the ending frame of the animation.
+
+ :type: float
+
+ .. attribute:: blendIn
+
+ Specifies the number of frames of animation to generate when making transitions between actions.
+
+ :type: float
+
+ .. attribute:: priority
+
+ Sets the priority of this actuator. Actuators will lower priority numbers will override actuators with higher numbers.
+
+ :type: integer
+
+ .. attribute:: frame
+
+ Sets the current frame for the animation.
+
+ :type: float
+
+ .. attribute:: propName
+
+ Sets the property to be used in FromProp playback mode.
+
+ :type: string
+
+ .. attribute:: blendTime
+
+ Sets the internal frame timer. This property must be in the range from 0.0 to blendIn.
+
+ :type: float
+
+ .. attribute:: mode
+
+ The operation mode of the actuator. Can be one of :ref:`these constants<action-actuator>`.
+
+ :type: integer
+
+ .. attribute:: useContinue
+
+ The actions continue option, True or False. When True, the action will always play from where last left off,
+ otherwise negative events to this actuator will reset it to its start frame.
+
+ :type: boolean
+
+ .. attribute:: framePropName
+
+ The name of the property that is set to the current frame number.
+
+ :type: string
+
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_ArmatureActuator.rst b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureActuator.rst
new file mode 100644
index 00000000000..579186ac1d6
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureActuator.rst
@@ -0,0 +1,61 @@
+BL_ArmatureActuator(SCA_IActuator)
+==================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: BL_ArmatureActuator(SCA_IActuator)
+
+ Armature Actuators change constraint condition on armatures.
+
+ .. attribute:: type
+
+ The type of action that the actuator executes when it is active.
+
+ Can be one of :ref:`these constants <armatureactuator-constants-type>`
+
+ :type: integer
+
+ .. attribute:: constraint
+
+ The constraint object this actuator is controlling.
+
+ :type: :class:`BL_ArmatureConstraint`
+
+ .. attribute:: target
+
+ The object that this actuator will set as primary target to the constraint it controls.
+
+ :type: :class:`KX_GameObject`
+
+ .. attribute:: subtarget
+
+ The object that this actuator will set as secondary target to the constraint it controls.
+
+ :type: :class:`KX_GameObject`.
+
+ .. note::
+
+ Currently, the only secondary target is the pole target for IK constraint.
+
+ .. attribute:: weight
+
+ The weight this actuator will set on the constraint it controls.
+
+ :type: float.
+
+ .. note::
+
+ Currently only the IK constraint has a weight. It must be a value between 0 and 1.
+
+ .. note::
+
+ A weight of 0 disables a constraint while still updating constraint runtime values (see :class:`BL_ArmatureConstraint`)
+
+ .. attribute:: influence
+
+ The influence this actuator will set on the constraint it controls.
+
+ :type: float.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_ArmatureBone.rst b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureBone.rst
new file mode 100644
index 00000000000..14a9ebe9ef3
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureBone.rst
@@ -0,0 +1,105 @@
+BL_ArmatureBone(PyObjectPlus)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: BL_ArmatureBone(PyObjectPlus)
+
+ Proxy to Blender bone structure. All fields are read-only and comply to RNA names.
+ All space attribute correspond to the rest pose.
+
+ .. attribute:: name
+
+ bone name.
+
+ :type: string
+
+ .. attribute:: connected
+
+ true when the bone head is struck to the parent's tail.
+
+ :type: boolean
+
+ .. attribute:: hinge
+
+ true when bone doesn't inherit rotation or scale from parent bone.
+
+ :type: boolean
+
+ .. attribute:: inherit_scale
+
+ true when bone inherits scaling from parent bone.
+
+ :type: boolean
+
+ .. attribute:: bbone_segments
+
+ number of B-bone segments.
+
+ :type: integer
+
+ .. attribute:: roll
+
+ bone rotation around head-tail axis.
+
+ :type: float
+
+ .. attribute:: head
+
+ location of head end of the bone in parent bone space.
+
+ :type: vector [x, y, z]
+
+ .. attribute:: tail
+
+ location of head end of the bone in parent bone space.
+
+ :type: vector [x, y, z]
+
+ .. attribute:: length
+
+ bone length.
+
+ :type: float
+
+ .. attribute:: arm_head
+
+ location of head end of the bone in armature space.
+
+ :type: vector [x, y, z]
+
+ .. attribute:: arm_tail
+
+ location of tail end of the bone in armature space.
+
+ :type: vector [x, y, z]
+
+ .. attribute:: arm_mat
+
+ matrix of the bone head in armature space.
+
+ :type: matrix [4][4]
+
+ .. note::
+
+ This matrix has no scale part.
+
+ .. attribute:: bone_mat
+
+ rotation matrix of the bone in parent bone space.
+
+ :type: matrix [3][3]
+
+ .. attribute:: parent
+
+ parent bone, or None for root bone.
+
+ :type: :class:`BL_ArmatureBone`
+
+ .. attribute:: children
+
+ list of bone's children.
+
+ :type: list of :class:`BL_ArmatureBone`
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_ArmatureChannel.rst b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureChannel.rst
new file mode 100644
index 00000000000..07220534b28
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureChannel.rst
@@ -0,0 +1,278 @@
+BL_ArmatureChannel(PyObjectPlus)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: BL_ArmatureChannel(PyObjectPlus)
+
+ Proxy to armature pose channel. Allows to read and set armature pose.
+ The attributes are identical to RNA attributes, but mostly in read-only mode.
+
+ .. attribute:: name
+
+ channel name (=bone name), read-only.
+
+ :type: string
+
+ .. attribute:: bone
+
+ return the bone object corresponding to this pose channel, read-only.
+
+ :type: :class:`BL_ArmatureBone`
+
+ .. attribute:: parent
+
+ return the parent channel object, None if root channel, read-only.
+
+ :type: :class:`BL_ArmatureChannel`
+
+ .. attribute:: has_ik
+
+ true if the bone is part of an active IK chain, read-only.
+ This flag is not set when an IK constraint is defined but not enabled (miss target information for example).
+
+ :type: boolean
+
+ .. attribute:: ik_dof_x
+
+ true if the bone is free to rotation in the X axis, read-only.
+
+ :type: boolean
+
+ .. attribute:: ik_dof_y
+
+ true if the bone is free to rotation in the Y axis, read-only.
+
+ :type: boolean
+
+ .. attribute:: ik_dof_z
+
+ true if the bone is free to rotation in the Z axis, read-only.
+
+ :type: boolean
+
+ .. attribute:: ik_limit_x
+
+ true if a limit is imposed on X rotation, read-only.
+
+ :type: boolean
+
+ .. attribute:: ik_limit_y
+
+ true if a limit is imposed on Y rotation, read-only.
+
+ :type: boolean
+
+ .. attribute:: ik_limit_z
+
+ true if a limit is imposed on Z rotation, read-only.
+
+ :type: boolean
+
+ .. attribute:: ik_rot_control
+
+ true if channel rotation should applied as IK constraint, read-only.
+
+ :type: boolean
+
+ .. attribute:: ik_lin_control
+
+ true if channel size should applied as IK constraint, read-only.
+
+ :type: boolean
+
+ .. attribute:: location
+
+ displacement of the bone head in armature local space, read-write.
+
+ :type: vector [X, Y, Z].
+
+ .. note::
+
+ You can only move a bone if it is unconnected to its parent. An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
+
+ .. note::
+
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`).
+
+ .. attribute:: scale
+
+ scale of the bone relative to its parent, read-write.
+
+ :type: vector [sizeX, sizeY, sizeZ].
+
+ .. note::
+
+ An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
+
+ .. note::
+
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`)
+
+ .. attribute:: rotation_quaternion
+
+ rotation of the bone relative to its parent expressed as a quaternion, read-write.
+
+ :type: vector [qr, qi, qj, qk].
+
+ .. note::
+
+ This field is only used if rotation_mode is 0. An action playing on the armature may change the value. An IK chain does not update this value, see joint_rotation.
+
+ .. note::
+
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`)
+
+ .. attribute:: rotation_euler
+
+ rotation of the bone relative to its parent expressed as a set of euler angles, read-write.
+
+ :type: vector [X, Y, Z].
+
+ .. note::
+
+ This field is only used if rotation_mode is > 0. You must always pass the angles in [X, Y, Z] order; the order of applying the angles to the bone depends on rotation_mode. An action playing on the armature may change this field. An IK chain does not update this value, see joint_rotation.
+
+ .. note::
+
+ Changing this field has no immediate effect, the pose is updated when the armature is updated during the graphic render (see :data:`BL_ArmatureObject.update`)
+
+ .. attribute:: rotation_mode
+
+ Method of updating the bone rotation, read-write.
+
+ :type: integer (one of :ref:`these constants <armaturechannel-constants-rotation-mode>`)
+
+ .. attribute:: channel_matrix
+
+ pose matrix in bone space (deformation of the bone due to action, constraint, etc), Read-only.
+ This field is updated after the graphic render, it represents the current pose.
+
+ :type: matrix [4][4]
+
+ .. attribute:: pose_matrix
+
+ pose matrix in armature space, read-only,
+ This field is updated after the graphic render, it represents the current pose.
+
+ :type: matrix [4][4]
+
+ .. attribute:: pose_head
+
+ position of bone head in armature space, read-only.
+
+ :type: vector [x, y, z]
+
+ .. attribute:: pose_tail
+
+ position of bone tail in armature space, read-only.
+
+ :type: vector [x, y, z]
+
+ .. attribute:: ik_min_x
+
+ minimum value of X rotation in degree (<= 0) when X rotation is limited (see ik_limit_x), read-only.
+
+ :type: float
+
+ .. attribute:: ik_max_x
+
+ maximum value of X rotation in degree (>= 0) when X rotation is limited (see ik_limit_x), read-only.
+
+ :type: float
+
+ .. attribute:: ik_min_y
+
+ minimum value of Y rotation in degree (<= 0) when Y rotation is limited (see ik_limit_y), read-only.
+
+ :type: float
+
+ .. attribute:: ik_max_y
+
+ maximum value of Y rotation in degree (>= 0) when Y rotation is limited (see ik_limit_y), read-only.
+
+ :type: float
+
+ .. attribute:: ik_min_z
+
+ minimum value of Z rotation in degree (<= 0) when Z rotation is limited (see ik_limit_z), read-only.
+
+ :type: float
+
+ .. attribute:: ik_max_z
+
+ maximum value of Z rotation in degree (>= 0) when Z rotation is limited (see ik_limit_z), read-only.
+
+ :type: float
+
+ .. attribute:: ik_stiffness_x
+
+ bone rotation stiffness in X axis, read-only.
+
+ :type: float between 0 and 1
+
+ .. attribute:: ik_stiffness_y
+
+ bone rotation stiffness in Y axis, read-only.
+
+ :type: float between 0 and 1
+
+ .. attribute:: ik_stiffness_z
+
+ bone rotation stiffness in Z axis, read-only.
+
+ :type: float between 0 and 1
+
+ .. attribute:: ik_stretch
+
+ ratio of scale change that is allowed, 0=bone can't change size, read-only.
+
+ :type: float
+
+ .. attribute:: ik_rot_weight
+
+ weight of rotation constraint when ik_rot_control is set, read-write.
+
+ :type: float between 0 and 1
+
+ .. attribute:: ik_lin_weight
+
+ weight of size constraint when ik_lin_control is set, read-write.
+
+ :type: float between 0 and 1
+
+ .. attribute:: joint_rotation
+
+ Control bone rotation in term of joint angle (for robotic applications), read-write.
+
+ When writing to this attribute, you pass a [x, y, z] vector and an appropriate set of euler angles or quaternion is calculated according to the rotation_mode.
+
+ When you read this attribute, the current pose matrix is converted into a [x, y, z] vector representing the joint angles.
+
+ The value and the meaning of the x, y, z depends on the ik_dof_x/ik_dof_y/ik_dof_z attributes:
+
+ * 1DoF joint X, Y or Z: the corresponding x, y, or z value is used an a joint angle in radiant
+ * 2DoF joint X+Y or Z+Y: treated as 2 successive 1DoF joints: first X or Z, then Y. The x or z value is used as a joint angle in radiant along the X or Z axis, followed by a rotation along the new Y axis of y radiants.
+ * 2DoF joint X+Z: treated as a 2DoF joint with rotation axis on the X/Z plane. The x and z values are used as the coordinates of the rotation vector in the X/Z plane.
+ * 3DoF joint X+Y+Z: treated as a revolute joint. The [x, y, z] vector represents the equivalent rotation vector to bring the joint from the rest pose to the new pose.
+
+ :type: vector [x, y, z]
+
+ .. note::
+
+ The bone must be part of an IK chain if you want to set the ik_dof_x/ik_dof_y/ik_dof_z attributes via the UI, but this will interfere with this attribute since the IK solver will overwrite the pose. You can stay in control of the armature if you create an IK constraint but do not finalize it (e.g. don't set a target) the IK solver will not run but the IK panel will show up on the UI for each bone in the chain.
+
+ .. note::
+
+ [0, 0, 0] always corresponds to the rest pose.
+
+ .. note::
+
+ You must request the armature pose to update and wait for the next graphic frame to see the effect of setting this attribute (see :data:`BL_ArmatureObject.update`).
+
+ .. note::
+
+ You can read the result of the calculation in rotation or euler_rotation attributes after setting this attribute.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_ArmatureConstraint.rst b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureConstraint.rst
new file mode 100644
index 00000000000..1a4370945c1
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureConstraint.rst
@@ -0,0 +1,129 @@
+BL_ArmatureConstraint(PyObjectPlus)
+===================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: BL_ArmatureConstraint(PyObjectPlus)
+
+ Proxy to Armature Constraint. Allows to change constraint on the fly.
+ Obtained through :class:`BL_ArmatureObject`.constraints.
+
+ .. note::
+
+ Not all armature constraints are supported in the GE.
+
+
+ .. attribute:: type
+
+ Type of constraint, (read-only).
+
+ Use one of :ref:`these constants<armatureconstraint-constants-type>`.
+
+ :type: integer, one of CONSTRAINT_TYPE_* constants
+
+ .. attribute:: name
+
+ Name of constraint constructed as <bone_name>:<constraint_name>. constraints list.
+
+ :type: string
+
+ This name is also the key subscript on :class:`BL_ArmatureObject`.
+
+ .. attribute:: enforce
+
+ fraction of constraint effect that is enforced. Between 0 and 1.
+
+ :type: float
+
+ .. attribute:: headtail
+
+ Position of target between head and tail of the target bone: 0=head, 1=tail.
+
+ :type: float.
+
+ .. note::
+
+ Only used if the target is a bone (i.e target object is an armature.
+
+ .. attribute:: lin_error
+
+ runtime linear error (in Blender units) on constraint at the current frame.
+
+ This is a runtime value updated on each frame by the IK solver. Only available on IK constraint and iTaSC solver.
+
+ :type: float
+
+ .. attribute:: rot_error
+
+ Runtime rotation error (in radiant) on constraint at the current frame.
+
+ :type: float.
+
+ This is a runtime value updated on each frame by the IK solver. Only available on IK constraint and iTaSC solver.
+
+ It is only set if the constraint has a rotation part, for example, a CopyPose+Rotation IK constraint.
+
+ .. attribute:: target
+
+ Primary target object for the constraint. The position of this object in the GE will be used as target for the constraint.
+
+ :type: :class:`KX_GameObject`.
+
+ .. attribute:: subtarget
+
+ Secondary target object for the constraint. The position of this object in the GE will be used as secondary target for the constraint.
+
+ :type: :class:`KX_GameObject`.
+
+ Currently this is only used for pole target on IK constraint.
+
+ .. attribute:: active
+
+ True if the constraint is active.
+
+ :type: boolean
+
+ .. note::
+
+ An inactive constraint does not update lin_error and rot_error.
+
+ .. attribute:: ik_weight
+
+ Weight of the IK constraint between 0 and 1.
+
+ Only defined for IK constraint.
+
+ :type: float
+
+ .. attribute:: ik_type
+
+ Type of IK constraint, (read-only).
+
+ Use one of :ref:`these constants<armatureconstraint-constants-ik-type>`.
+
+ :type: integer.
+
+ .. attribute:: ik_flag
+
+ Combination of IK constraint option flags, read-only.
+
+ Use one of :ref:`these constants<armatureconstraint-constants-ik-flag>`.
+
+ :type: integer
+
+ .. attribute:: ik_dist
+
+ Distance the constraint is trying to maintain with target, only used when ik_type=CONSTRAINT_IK_DISTANCE.
+
+ :type: float
+
+ .. attribute:: ik_mode
+
+ Use one of :ref:`these constants<armatureconstraint-constants-ik-mode>`.
+
+ Additional mode for IK constraint. Currently only used for Distance constraint:
+
+ :type: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_ArmatureObject.rst b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureObject.rst
new file mode 100644
index 00000000000..8389affe8a9
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_ArmatureObject.rst
@@ -0,0 +1,34 @@
+BL_ArmatureObject(KX_GameObject)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`KX_GameObject`
+
+.. class:: BL_ArmatureObject(KX_GameObject)
+
+ An armature object.
+
+ .. attribute:: constraints
+
+ The list of armature constraint defined on this armature.
+ Elements of the list can be accessed by index or string.
+ The key format for string access is '<bone_name>:<constraint_name>'.
+
+ :type: list of :class:`BL_ArmatureConstraint`
+
+ .. attribute:: channels
+
+ The list of armature channels.
+ Elements of the list can be accessed by index or name the bone.
+
+ :type: list of :class:`BL_ArmatureChannel`
+
+ .. method:: update()
+
+ Ensures that the armature will be updated on next graphic frame.
+
+ This action is unecessary if a KX_ArmatureActuator with mode run is active
+ or if an action is playing. Use this function in other cases. It must be called
+ on each frame to ensure that the armature is updated continously.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_Shader.rst b/doc/python_api/rst/bge_types/bge.types.BL_Shader.rst
new file mode 100644
index 00000000000..f4f5c0d62ba
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_Shader.rst
@@ -0,0 +1,220 @@
+BL_Shader(PyObjectPlus)
+=======================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: BL_Shader(PyObjectPlus)
+
+ BL_Shader GLSL shaders.
+
+ TODO - Description
+
+ .. method:: setUniformfv(name, fList)
+
+ Set a uniform with a list of float values
+
+ :arg name: the uniform name
+ :type name: string
+ :arg fList: a list (2, 3 or 4 elements) of float values
+ :type fList: list[float]
+
+ .. method:: delSource()
+
+ Clear the shader. Use this method before the source is changed with :data:`setSource`.
+
+ .. method:: getFragmentProg()
+
+ Returns the fragment program.
+
+ :return: The fragment program.
+ :rtype: string
+
+ .. method:: getVertexProg()
+
+ Get the vertex program.
+
+ :return: The vertex program.
+ :rtype: string
+
+ .. method:: isValid()
+
+ Check if the shader is valid.
+
+ :return: True if the shader is valid
+ :rtype: boolean
+
+ .. method:: setAttrib(enum)
+
+ Set attribute location. (The parameter is ignored a.t.m. and the value of "tangent" is always used.)
+
+ :arg enum: attribute location value
+ :type enum: integer
+
+ .. method:: setNumberOfPasses( max_pass )
+
+ Set the maximum number of passes. Not used a.t.m.
+
+ :arg max_pass: the maximum number of passes
+ :type max_pass: integer
+
+ .. method:: setSampler(name, index)
+
+ Set uniform texture sample index.
+
+ :arg name: Uniform name
+ :type name: string
+ :arg index: Texture sample index.
+ :type index: integer
+
+ .. method:: setSource(vertexProgram, fragmentProgram)
+
+ Set the vertex and fragment programs
+
+ :arg vertexProgram: Vertex program
+ :type vertexProgram: string
+ :arg fragmentProgram: Fragment program
+ :type fragmentProgram: string
+
+ .. method:: setUniform1f(name, fx)
+
+ Set a uniform with 1 float value.
+
+ :arg name: the uniform name
+ :type name: string
+ :arg fx: Uniform value
+ :type fx: float
+
+ .. method:: setUniform1i(name, ix)
+
+ Set a uniform with an integer value.
+
+ :arg name: the uniform name
+ :type name: string
+ :arg ix: the uniform value
+ :type ix: integer
+
+ .. method:: setUniform2f(name, fx, fy)
+
+ Set a uniform with 2 float values
+
+ :arg name: the uniform name
+ :type name: string
+ :arg fx: first float value
+ :type fx: float
+
+ :arg fy: second float value
+ :type fy: float
+
+ .. method:: setUniform2i(name, ix, iy)
+
+ Set a uniform with 2 integer values
+
+ :arg name: the uniform name
+ :type name: string
+ :arg ix: first integer value
+ :type ix: integer
+ :arg iy: second integer value
+ :type iy: integer
+
+ .. method:: setUniform3f(name, fx, fy, fz)
+
+ Set a uniform with 3 float values.
+
+ :arg name: the uniform name
+ :type name: string
+ :arg fx: first float value
+ :type fx: float
+ :arg fy: second float value
+ :type fy: float
+ :arg fz: third float value
+ :type fz: float
+
+ .. method:: setUniform3i(name, ix, iy, iz)
+
+ Set a uniform with 3 integer values
+
+ :arg name: the uniform name
+ :type name: string
+ :arg ix: first integer value
+ :type ix: integer
+ :arg iy: second integer value
+ :type iy: integer
+ :arg iz: third integer value
+ :type iz: integer
+
+ .. method:: setUniform4f(name, fx, fy, fz, fw)
+
+ Set a uniform with 4 float values.
+
+ :arg name: the uniform name
+ :type name: string
+ :arg fx: first float value
+ :type fx: float
+ :arg fy: second float value
+ :type fy: float
+ :arg fz: third float value
+ :type fz: float
+ :arg fw: fourth float value
+ :type fw: float
+
+ .. method:: setUniform4i(name, ix, iy, iz, iw)
+
+ Set a uniform with 4 integer values
+
+ :arg name: the uniform name
+ :type name: string
+ :arg ix: first integer value
+ :type ix: integer
+ :arg iy: second integer value
+ :type iy: integer
+ :arg iz: third integer value
+ :type iz: integer
+ :arg iw: fourth integer value
+ :type iw: integer
+
+ .. method:: setUniformDef(name, type)
+
+ Define a new uniform
+
+ :arg name: the uniform name
+ :type name: string
+ :arg type: uniform type
+ :type type: UNI_NONE, UNI_INT, UNI_FLOAT, UNI_INT2, UNI_FLOAT2, UNI_INT3, UNI_FLOAT3, UNI_INT4, UNI_FLOAT4, UNI_MAT3, UNI_MAT4, UNI_MAX
+
+ .. method:: setUniformMatrix3(name, mat, transpose)
+
+ Set a uniform with a 3x3 matrix value
+
+ :arg name: the uniform name
+ :type name: string
+ :arg mat: A 3x3 matrix [[f, f, f], [f, f, f], [f, f, f]]
+ :type mat: 3x3 matrix
+ :arg transpose: set to True to transpose the matrix
+ :type transpose: boolean
+
+ .. method:: setUniformMatrix4(name, mat, transpose)
+
+ Set a uniform with a 4x4 matrix value
+
+ :arg name: the uniform name
+ :type name: string
+ :arg mat: A 4x4 matrix [[f, f, f, f], [f, f, f, f], [f, f, f, f], [f, f, f, f]]
+ :type mat: 4x4 matrix
+ :arg transpose: set to True to transpose the matrix
+ :type transpose: boolean
+
+ .. method:: setUniformiv(name, iList)
+
+ Set a uniform with a list of integer values
+
+ :arg name: the uniform name
+ :type name: string
+ :arg iList: a list (2, 3 or 4 elements) of integer values
+ :type iList: list[integer]
+
+ .. method:: validate()
+
+ Validate the shader object.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.BL_ShapeActionActuator.rst b/doc/python_api/rst/bge_types/bge.types.BL_ShapeActionActuator.rst
new file mode 100644
index 00000000000..d08a761ed95
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.BL_ShapeActionActuator.rst
@@ -0,0 +1,72 @@
+BL_ShapeActionActuator(SCA_IActuator)
+=====================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: BL_ShapeActionActuator(SCA_IActuator)
+
+ ShapeAction Actuators apply an shape action to an mesh object.
+
+ .. attribute:: action
+
+ The name of the action to set as the current shape action.
+
+ :type: string
+
+ .. attribute:: frameStart
+
+ Specifies the starting frame of the shape animation.
+
+ :type: float
+
+ .. attribute:: frameEnd
+
+ Specifies the ending frame of the shape animation.
+
+ :type: float
+
+ .. attribute:: blendIn
+
+ Specifies the number of frames of animation to generate when making transitions between actions.
+
+ :type: float
+
+ .. attribute:: priority
+
+ Sets the priority of this actuator. Actuators will lower priority numbers will override actuators with higher numbers.
+
+ :type: integer
+
+ .. attribute:: frame
+
+ Sets the current frame for the animation.
+
+ :type: float
+
+ .. attribute:: propName
+
+ Sets the property to be used in FromProp playback mode.
+
+ :type: string
+
+ .. attribute:: blendTime
+
+ Sets the internal frame timer. This property must be in the range from 0.0 to blendin.
+
+ :type: float
+
+ .. attribute:: mode
+
+ The operation mode of the actuator. Can be one of :ref:`these constants<shape-action-actuator>`.
+
+ :type: integer
+
+ .. attribute:: framePropName
+
+ The name of the property that is set to the current frame number.
+
+ :type: string
+
+
diff --git a/doc/python_api/rst/bge_types/bge.types.CListValue.rst b/doc/python_api/rst/bge_types/bge.types.CListValue.rst
new file mode 100644
index 00000000000..ca4cdc44bf5
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.CListValue.rst
@@ -0,0 +1,72 @@
+CListValue(CPropValue)
+======================
+
+.. module:: bge.types
+
+base class --- :class:`CPropValue`
+
+.. class:: CListValue(CPropValue)
+
+ This is a list like object used in the game engine internally that behaves similar to a python list in most ways.
+
+ As well as the normal index lookup (``val= clist[i]``), CListValue supports string lookups (``val= scene.objects["Cube"]``)
+
+ Other operations such as ``len(clist)``, ``list(clist)``, ``clist[0:10]`` are also supported.
+
+ .. method:: append(val)
+
+ Add an item to the list (like pythons append)
+
+ .. warning::
+
+ Appending values to the list can cause crashes when the list is used internally by the game engine.
+
+ .. method:: count(val)
+
+ Count the number of instances of a value in the list.
+
+ :return: number of instances
+ :rtype: integer
+
+ .. method:: index(val)
+
+ Return the index of a value in the list.
+
+ :return: The index of the value in the list.
+ :rtype: integer
+
+ .. method:: reverse()
+
+ Reverse the order of the list.
+
+ .. method:: get(key, default=None)
+
+ Return the value matching key, or the default value if its not found.
+
+ :return: The key value or a default.
+
+ .. method:: from_id(id)
+
+ This is a funtion especially for the game engine to return a value with a spesific id.
+
+ Since object names are not always unique, the id of an object can be used to get an object from the CValueList.
+
+ Example:
+
+ .. code-block:: python
+
+ myObID=id(gameObject)
+ ob= scene.objects.from_id(myObID)
+
+ Where ``myObID`` is an int or long from the id function.
+
+ This has the advantage that you can store the id in places you could not store a gameObject.
+
+ .. warning::
+
+ The id is derived from a memory location and will be different each time the game engine starts.
+
+ .. warning::
+
+ The id can't be stored as an integer in game object properties, as those only have a limited range that the id may not be contained in. Instead an id can be stored as a string game property and converted back to an integer for use in from_id lookups.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.CPropValue.rst b/doc/python_api/rst/bge_types/bge.types.CPropValue.rst
new file mode 100644
index 00000000000..7be28c1e006
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.CPropValue.rst
@@ -0,0 +1,11 @@
+CPropValue(CValue)
+==================
+
+.. module:: bge.types
+
+base class --- :class:`CValue`
+
+.. class:: CPropValue(CValue)
+
+ This class has no python functions
+
diff --git a/doc/python_api/rst/bge_types/bge.types.CValue.rst b/doc/python_api/rst/bge_types/bge.types.CValue.rst
new file mode 100644
index 00000000000..52906de5576
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.CValue.rst
@@ -0,0 +1,17 @@
+CValue(PyObjectPlus)
+====================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: CValue(PyObjectPlus)
+
+ This class is a basis for other classes.
+
+ .. attribute:: name
+
+ The name of this CValue derived object (read-only).
+
+ :type: string
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_ArmatureSensor.rst b/doc/python_api/rst/bge_types/bge.types.KX_ArmatureSensor.rst
new file mode 100644
index 00000000000..a7123eb5c9d
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_ArmatureSensor.rst
@@ -0,0 +1,36 @@
+KX_ArmatureSensor(SCA_ISensor)
+==============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: KX_ArmatureSensor(SCA_ISensor)
+
+ Armature sensor detect conditions on armatures.
+
+ .. attribute:: type
+
+ The type of measurement that the sensor make when it is active.
+
+ Can be one of :ref:`these constants <armaturesensor-type>`
+
+ :type: integer.
+
+ .. attribute:: constraint
+
+ The constraint object this sensor is watching.
+
+ :type: :class:`BL_ArmatureConstraint`
+
+ .. attribute:: value
+
+ The threshold used in the comparison with the constraint error
+ The linear error is only updated on CopyPose/Distance IK constraint with iTaSC solver
+ The rotation error is only updated on CopyPose+rotation IK constraint with iTaSC solver
+ The linear error on CopyPose is always >= 0: it is the norm of the distance between the target and the bone
+ The rotation error on CopyPose is always >= 0: it is the norm of the equivalent rotation vector between the bone and the target orientations
+ The linear error on Distance can be positive if the distance between the bone and the target is greater than the desired distance, and negative if the distance is smaller.
+
+ :type: float
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst b/doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst
new file mode 100644
index 00000000000..0dfc7a10d13
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_BlenderMaterial.rst
@@ -0,0 +1,77 @@
+KX_BlenderMaterial(PyObjectPlus)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: KX_BlenderMaterial(PyObjectPlus)
+
+ KX_BlenderMaterial
+
+ .. attribute:: shader
+
+ The materials shader.
+
+ :type: :class:`BL_Shader`
+
+ .. attribute:: blending
+
+ Ints used for pixel blending, (src, dst), matching the setBlending method.
+
+ :type: (integer, integer)
+
+ .. attribute:: material_index
+
+ The material's index.
+
+ :type: integer
+
+ .. method:: getShader()
+
+ Returns the material's shader.
+
+ :return: the material's shader
+ :rtype: :class:`BL_Shader`
+
+ .. method:: setBlending(src, dest)
+
+ Set the pixel color arithmetic functions.
+
+ :arg src: Specifies how the red, green, blue, and alpha source blending factors are computed.
+ :type src: Value in...
+
+ * GL_ZERO,
+ * GL_ONE,
+ * GL_SRC_COLOR,
+ * GL_ONE_MINUS_SRC_COLOR,
+ * GL_DST_COLOR,
+ * GL_ONE_MINUS_DST_COLOR,
+ * GL_SRC_ALPHA,
+ * GL_ONE_MINUS_SRC_ALPHA,
+ * GL_DST_ALPHA,
+ * GL_ONE_MINUS_DST_ALPHA,
+ * GL_SRC_ALPHA_SATURATE
+
+ :arg dest: Specifies how the red, green, blue, and alpha destination blending factors are computed.
+ :type dest: Value in...
+
+ * GL_ZERO
+ * GL_ONE
+ * GL_SRC_COLOR
+ * GL_ONE_MINUS_SRC_COLOR
+ * GL_DST_COLOR
+ * GL_ONE_MINUS_DST_COLOR
+ * GL_SRC_ALPHA
+ * GL_ONE_MINUS_SRC_ALPHA
+ * GL_DST_ALPHA
+ * GL_ONE_MINUS_DST_ALPHA
+ * GL_SRC_ALPHA_SATURATE
+
+ .. method:: getMaterialIndex()
+
+ Returns the material's index.
+
+ :return: the material's index
+ :rtype: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_Camera.rst b/doc/python_api/rst/bge_types/bge.types.KX_Camera.rst
new file mode 100644
index 00000000000..baf60ec0c97
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_Camera.rst
@@ -0,0 +1,284 @@
+KX_Camera(KX_GameObject)
+========================
+
+.. module:: bge.types
+
+base class --- :class:`KX_GameObject`
+
+.. class:: KX_Camera(KX_GameObject)
+
+ A Camera object.
+
+ .. data:: INSIDE
+
+ See :data:`sphereInsideFrustum` and :data:`boxInsideFrustum`
+
+ .. data:: INTERSECT
+
+ See :data:`sphereInsideFrustum` and :data:`boxInsideFrustum`
+
+ .. data:: OUTSIDE
+
+ See :data:`sphereInsideFrustum` and :data:`boxInsideFrustum`
+
+ .. attribute:: lens
+
+ The camera's lens value.
+
+ :type: float
+
+ .. attribute:: ortho_scale
+
+ The camera's view scale when in orthographic mode.
+
+ :type: float
+
+ .. attribute:: near
+
+ The camera's near clip distance.
+
+ :type: float
+
+ .. attribute:: far
+
+ The camera's far clip distance.
+
+ :type: float
+
+ .. attribute:: perspective
+
+ True if this camera has a perspective transform, False for an orthographic projection.
+
+ :type: boolean
+
+ .. attribute:: frustum_culling
+
+ True if this camera is frustum culling.
+
+ :type: boolean
+
+ .. attribute:: projection_matrix
+
+ This camera's 4x4 projection matrix.
+
+ .. note::
+
+ This is the identity matrix prior to rendering the first frame (any Python done on frame 1).
+
+ :type: 4x4 Matrix [[float]]
+
+ .. attribute:: modelview_matrix
+
+ This camera's 4x4 model view matrix. (read-only).
+
+ :type: 4x4 Matrix [[float]]
+
+ .. note::
+
+ This matrix is regenerated every frame from the camera's position and orientation. Also, this is the identity matrix prior to rendering the first frame (any Python done on frame 1).
+
+ .. attribute:: camera_to_world
+
+ This camera's camera to world transform. (read-only).
+
+ :type: 4x4 Matrix [[float]]
+
+ .. note::
+
+ This matrix is regenerated every frame from the camera's position and orientation.
+
+ .. attribute:: world_to_camera
+
+ This camera's world to camera transform. (read-only).
+
+ :type: 4x4 Matrix [[float]]
+
+ .. note::
+
+ Regenerated every frame from the camera's position and orientation.
+
+ .. note::
+
+ This is camera_to_world inverted.
+
+ .. attribute:: useViewport
+
+ True when the camera is used as a viewport, set True to enable a viewport for this camera.
+
+ :type: boolean
+
+ .. method:: sphereInsideFrustum(centre, radius)
+
+ Tests the given sphere against the view frustum.
+
+ :arg centre: The centre of the sphere (in world coordinates.)
+ :type centre: list [x, y, z]
+ :arg radius: the radius of the sphere
+ :type radius: float
+ :return: :data:`~bge.types.KX_Camera.INSIDE`, :data:`~bge.types.KX_Camera.OUTSIDE` or :data:`~bge.types.KX_Camera.INTERSECT`
+ :rtype: integer
+
+ .. note::
+
+ When the camera is first initialized the result will be invalid because the projection matrix has not been set.
+
+ .. code-block:: python
+
+ from bge import logic
+ cont = logic.getCurrentController()
+ cam = cont.owner
+
+ # A sphere of radius 4.0 located at [x, y, z] = [1.0, 1.0, 1.0]
+ if (cam.sphereInsideFrustum([1.0, 1.0, 1.0], 4) != cam.OUTSIDE):
+ # Sphere is inside frustum !
+ # Do something useful !
+ else:
+ # Sphere is outside frustum
+
+ .. method:: boxInsideFrustum(box)
+
+ Tests the given box against the view frustum.
+
+ :arg box: Eight (8) corner points of the box (in world coordinates.)
+ :type box: list of lists
+ :return: :data:`~bge.types.KX_Camera.INSIDE`, :data:`~bge.types.KX_Camera.OUTSIDE` or :data:`~bge.types.KX_Camera.INTERSECT`
+
+ .. note::
+
+ When the camera is first initialized the result will be invalid because the projection matrix has not been set.
+
+ .. code-block:: python
+
+ from bge import logic
+ cont = logic.getCurrentController()
+ cam = cont.owner
+
+ # Box to test...
+ box = []
+ box.append([-1.0, -1.0, -1.0])
+ box.append([-1.0, -1.0, 1.0])
+ box.append([-1.0, 1.0, -1.0])
+ box.append([-1.0, 1.0, 1.0])
+ box.append([ 1.0, -1.0, -1.0])
+ box.append([ 1.0, -1.0, 1.0])
+ box.append([ 1.0, 1.0, -1.0])
+ box.append([ 1.0, 1.0, 1.0])
+
+ if (cam.boxInsideFrustum(box) != cam.OUTSIDE):
+ # Box is inside/intersects frustum !
+ # Do something useful !
+ else:
+ # Box is outside the frustum !
+
+ .. method:: pointInsideFrustum(point)
+
+ Tests the given point against the view frustum.
+
+ :arg point: The point to test (in world coordinates.)
+ :type point: 3D Vector
+ :return: True if the given point is inside this camera's viewing frustum.
+ :rtype: boolean
+
+ .. note::
+
+ When the camera is first initialized the result will be invalid because the projection matrix has not been set.
+
+ .. code-block:: python
+
+ from bge import logic
+ cont = logic.getCurrentController()
+ cam = cont.owner
+
+ # Test point [0.0, 0.0, 0.0]
+ if (cam.pointInsideFrustum([0.0, 0.0, 0.0])):
+ # Point is inside frustum !
+ # Do something useful !
+ else:
+ # Box is outside the frustum !
+
+ .. method:: getCameraToWorld()
+
+ Returns the camera-to-world transform.
+
+ :return: the camera-to-world transform matrix.
+ :rtype: matrix (4x4 list)
+
+ .. method:: getWorldToCamera()
+
+ Returns the world-to-camera transform.
+
+ This returns the inverse matrix of getCameraToWorld().
+
+ :return: the world-to-camera transform matrix.
+ :rtype: matrix (4x4 list)
+
+ .. method:: setOnTop()
+
+ Set this cameras viewport ontop of all other viewport.
+
+ .. method:: setViewport(left, bottom, right, top)
+
+ Sets the region of this viewport on the screen in pixels.
+
+ Use :data:`bge.render.getWindowHeight` and :data:`bge.render.getWindowWidth` to calculate values relative to the entire display.
+
+ :arg left: left pixel coordinate of this viewport
+ :type left: integer
+ :arg bottom: bottom pixel coordinate of this viewport
+ :type bottom: integer
+ :arg right: right pixel coordinate of this viewport
+ :type right: integer
+ :arg top: top pixel coordinate of this viewport
+ :type top: integer
+
+ .. method:: getScreenPosition(object)
+
+ Gets the position of an object projected on screen space.
+
+ .. code-block:: python
+
+ # For an object in the middle of the screen, coord = [0.5, 0.5]
+ coord = camera.getScreenPosition(object)
+
+ :arg object: object name or list [x, y, z]
+ :type object: :class:`KX_GameObject` or 3D Vector
+ :return: the object's position in screen coordinates.
+ :rtype: list [x, y]
+
+ .. method:: getScreenVect(x, y)
+
+ Gets the vector from the camera position in the screen coordinate direction.
+
+ :arg x: X Axis
+ :type x: float
+ :arg y: Y Axis
+ :type y: float
+ :rtype: 3D Vector
+ :return: The vector from screen coordinate.
+
+ .. code-block:: python
+
+ # Gets the vector of the camera front direction:
+ m_vect = camera.getScreenVect(0.5, 0.5)
+
+ .. method:: getScreenRay(x, y, dist=inf, property=None)
+
+ Look towards a screen coordinate (x, y) and find first object hit within dist that matches prop.
+ The ray is similar to KX_GameObject->rayCastTo.
+
+ :arg x: X Axis
+ :type x: float
+ :arg y: Y Axis
+ :type y: float
+ :arg dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other
+ :type dist: float
+ :arg property: property name that object must have; can be omitted => detect any object
+ :type property: string
+ :rtype: :class:`KX_GameObject`
+ :return: the first object hit or None if no object or object does not match prop
+
+ .. code-block:: python
+
+ # Gets an object with a property "wall" in front of the camera within a distance of 100:
+ target = camera.getScreenRay(0.5, 0.5, 100, "wall")
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_CameraActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_CameraActuator.rst
new file mode 100644
index 00000000000..bc5efed4b08
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_CameraActuator.rst
@@ -0,0 +1,47 @@
+KX_CameraActuator(SCA_IActuator)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_CameraActuator(SCA_IActuator)
+
+ Applies changes to a camera.
+
+ .. attribute:: damping
+
+ strength of of the camera following movement.
+
+ :type: float
+
+ .. attribute:: axis
+
+ The camera axis (0, 1, 2) for positive ``XYZ``, (3, 4, 5) for negative ``XYZ``.
+
+ :type: int
+
+ .. attribute:: min
+
+ minimum distance to the target object maintained by the actuator.
+
+ :type: float
+
+ .. attribute:: max
+
+ maximum distance to stay from the target object.
+
+ :type: float
+
+ .. attribute:: height
+
+ height to stay above the target object.
+
+ :type: float
+
+ .. attribute:: object
+
+ the object this actuator tracks.
+
+ :type: :class:`KX_GameObject` or None
+
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
new file mode 100644
index 00000000000..32e5c3eaad8
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst
@@ -0,0 +1,45 @@
+KX_CharacterWrapper(PyObjectPlus)
+=================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: KX_CharacterWrapper(PyObjectPlus)
+
+ A wrapper to expose character physics options.
+
+ .. attribute:: onGround
+
+ Whether or not the character is on the ground. (read-only)
+
+ :type: boolean
+
+ .. attribute:: gravity
+
+ The gravity value used for the character.
+
+ :type: float
+
+ .. attribute:: maxJumps
+
+ The maximum number of jumps a character can perform before having to touch the ground. By default this is set to 1. 2 allows for a double jump, etc.
+
+ :type: int
+
+ .. attribute:: jumpCount
+
+ The current jump count. This can be used to have different logic for a single jump versus a double jump. For example, a different animation for the second jump.
+
+ :type: int
+
+ .. attribute:: walkDirection
+
+ 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]
+
+ .. method:: jump()
+
+ The character jumps based on it's jump speed.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_ConstraintActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_ConstraintActuator.rst
new file mode 100644
index 00000000000..498990449fe
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_ConstraintActuator.rst
@@ -0,0 +1,78 @@
+KX_ConstraintActuator(SCA_IActuator)
+====================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_ConstraintActuator(SCA_IActuator)
+
+ A constraint actuator limits the position, rotation, distance or orientation of an object.
+
+ .. attribute:: damp
+
+ Time constant of the constraint expressed in frame (not use by Force field constraint).
+
+ :type: integer
+
+ .. attribute:: rotDamp
+
+ Time constant for the rotation expressed in frame (only for the distance constraint), 0 = use damp for rotation as well.
+
+ :type: integer
+
+ .. attribute:: direction
+
+ The reference direction in world coordinate for the orientation constraint.
+
+ :type: 3-tuple of float: (x, y, z)
+
+ .. attribute:: option
+
+ Binary combination of :ref:`these constants <constraint-actuator-option>`
+
+ :type: integer
+
+ .. attribute:: time
+
+ activation time of the actuator. The actuator disables itself after this many frame. If set to 0, the actuator is not limited in time.
+
+ :type: integer
+
+ .. attribute:: propName
+
+ the name of the property or material for the ray detection of the distance constraint.
+
+ :type: string
+
+ .. attribute:: min
+
+ The lower bound of the constraint. For the rotation and orientation constraint, it represents radiant.
+
+ :type: float
+
+ .. attribute:: distance
+
+ the target distance of the distance constraint.
+
+ :type: float
+
+ .. attribute:: max
+
+ the upper bound of the constraint. For rotation and orientation constraints, it represents radiant.
+
+ :type: float
+
+ .. attribute:: rayLength
+
+ the length of the ray of the distance constraint.
+
+ :type: float
+
+ .. attribute:: limit
+
+ type of constraint. Use one of the :ref:`these constants <constraint-actuator-limit>`
+
+ :type: integer.
+
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_ConstraintWrapper.rst b/doc/python_api/rst/bge_types/bge.types.KX_ConstraintWrapper.rst
new file mode 100644
index 00000000000..c26675147ac
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_ConstraintWrapper.rst
@@ -0,0 +1,18 @@
+KX_ConstraintWrapper(PyObjectPlus)
+==================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: KX_ConstraintWrapper(PyObjectPlus)
+
+ KX_ConstraintWrapper
+
+ .. method:: getConstraintId(val)
+
+ Returns the contraint's ID
+
+ :return: the constraint's ID
+ :rtype: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_FontObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_FontObject.rst
new file mode 100644
index 00000000000..1961f5e3e92
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_FontObject.rst
@@ -0,0 +1,12 @@
+KX_FontObject(KX_GameObject)
+============================
+
+.. module:: bge.types
+
+base class --- :class:`KX_GameObject`
+
+.. class:: KX_FontObject(KX_GameObject)
+
+ TODO.
+
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_GameActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_GameActuator.rst
new file mode 100644
index 00000000000..54702c5318d
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_GameActuator.rst
@@ -0,0 +1,23 @@
+KX_GameActuator(SCA_IActuator)
+==============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_GameActuator(SCA_IActuator)
+
+ The game actuator loads a new .blend file, restarts the current .blend file or quits the game.
+
+ .. attribute:: fileName
+
+ the new .blend file to load.
+
+ :type: string
+
+ .. attribute:: mode
+
+ The mode of this actuator. Can be on of :ref:`these constants <game-actuator>`
+
+ :type: Int
+
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
new file mode 100644
index 00000000000..a9c91735f91
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
@@ -0,0 +1,839 @@
+KX_GameObject(SCA_IObject)
+==========================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IObject`
+
+.. class:: KX_GameObject(SCA_IObject)
+
+ All game objects are derived from this class.
+
+ Properties assigned to game objects are accessible as attributes of this class.
+
+ .. note::
+
+ Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError,
+ if an object may have been removed since last accessing it use the :data:`invalid` attribute to check.
+
+ KX_GameObject can be subclassed to extend functionality. For example:
+
+ .. code-block:: python
+
+ import bge
+
+ class CustomGameObject(bge.types.KX_GameObject):
+ RATE = 0.05
+
+ def __init__(self, old_owner):
+ # "old_owner" can just be ignored. At this point, "self" is
+ # already the object in the scene, and "old_owner" has been
+ # destroyed.
+
+ # New attributes can be defined - but we could also use a game
+ # property, like "self['rate']".
+ self.rate = CustomGameObject.RATE
+
+ def update(self):
+ self.worldPosition.z += self.rate
+
+ # switch direction
+ if self.worldPosition.z > 1.0:
+ self.rate = -CustomGameObject.RATE
+ elif self.worldPosition.z < 0.0:
+ self.rate = CustomGameObject.RATE
+
+ # Called first
+ def mutate(cont):
+ old_object = cont.owner
+ mutated_object = CustomGameObject(cont.owner)
+
+ # After calling the constructor above, references to the old object
+ # should not be used.
+ assert(old_object is not mutated_object)
+ assert(old_object.invalid)
+ assert(mutated_object is cont.owner)
+
+ # Called later - note we are now working with the mutated object.
+ def update(cont):
+ cont.owner.update()
+
+ When subclassing objects other than empties and meshes, the specific type
+ should be used - e.g. inherit from :class:`BL_ArmatureObject` when the object
+ to mutate is an armature.
+
+ .. attribute:: name
+
+ The object's name. (read-only).
+
+ :type: string
+
+ .. attribute:: mass
+
+ The object's mass
+
+ :type: float
+
+ .. note::
+
+ The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0.
+
+ .. attribute:: linVelocityMin
+
+ Enforces the object keeps moving at a minimum velocity.
+
+ :type: float
+
+ .. note::
+
+ Applies to dynamic and rigid body objects only.
+
+ .. note::
+
+ A value of 0.0 disables this option.
+
+ .. note::
+
+ While objects are stationary the minimum velocity will not be applied.
+
+ .. attribute:: linVelocityMax
+
+ Clamp the maximum linear velocity to prevent objects moving beyond a set speed.
+
+ :type: float
+
+ .. note::
+
+ Applies to dynamic and rigid body objects only.
+
+ .. note::
+
+ A value of 0.0 disables this option (rather then setting it stationary).
+
+ .. attribute:: localInertia
+
+ the object's inertia vector in local coordinates. Read only.
+
+ :type: list [ix, iy, iz]
+
+ .. attribute:: parent
+
+ The object's parent object. (read-only).
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: groupMembers
+
+ Returns the list of group members if the object is a group object, 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.
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: scene
+
+ The object's scene. (read-only).
+
+ :type: :class:`KX_Scene` or None
+
+ .. attribute:: visible
+
+ visibility flag.
+
+ :type: boolean
+
+ .. note::
+
+ Game logic will still run for invisible objects.
+
+ .. attribute:: color
+
+ The object color of the object. [r, g, b, a]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: occlusion
+
+ occlusion capability flag.
+
+ :type: boolean
+
+ .. attribute:: position
+
+ The object's position. [x, y, z] On write: local position, on read: world position
+
+ .. deprecated:: use :data:`localPosition` and :data:`worldPosition`.
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: orientation
+
+ The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector. On write: local orientation, on read: world orientation
+
+ .. deprecated:: use :data:`localOrientation` and :data:`worldOrientation`.
+
+ :type: :class:`mathutils.Matrix`
+
+ .. attribute:: scaling
+
+ The object's scaling factor. [sx, sy, sz] On write: local scaling, on read: world scaling
+
+ .. deprecated:: use :data:`localScale` and :data:`worldScale`.
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: localOrientation
+
+ The object's local orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector.
+
+ :type: :class:`mathutils.Matrix`
+
+ .. attribute:: worldOrientation
+
+ The object's world orientation. 3x3 Matrix.
+
+ :type: :class:`mathutils.Matrix`
+
+ .. attribute:: localScale
+
+ The object's local scaling factor. [sx, sy, sz]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: worldScale
+
+ The object's world scaling factor. [sx, sy, sz]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: localPosition
+
+ The object's local position. [x, y, z]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: worldPosition
+
+ The object's world position. [x, y, z]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: localTransform
+
+ The object's local space transform matrix. 4x4 Matrix.
+
+ :type: :class:`mathutils.Matrix`
+
+ .. attribute:: worldTransform
+
+ The object's world space transform matrix. 4x4 Matrix.
+
+ :type: :class:`mathutils.Matrix`
+
+ .. attribute:: localLinearVelocity
+
+ The object's local linear velocity. [x, y, z]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: worldLinearVelocity
+
+ The object's world linear velocity. [x, y, z]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: localAngularVelocity
+
+ The object's local angular velocity. [x, y, z]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: worldAngularVelocity
+
+ The object's world angular velocity. [x, y, z]
+
+ :type: :class:`mathutils.Vector`
+
+ .. attribute:: timeOffset
+
+ adjust the slowparent delay at runtime.
+
+ :type: float
+
+ .. attribute:: state
+
+ the game object's state bitmask, using the first 30 bits, one bit must always be set.
+
+ :type: int
+
+ .. attribute:: meshes
+
+ a list meshes for this object.
+
+ :type: list of :class:`KX_MeshProxy`
+
+ .. note::
+
+ Most objects use only 1 mesh.
+
+ .. note::
+
+ Changes to this list will not update the KX_GameObject.
+
+ .. attribute:: sensors
+
+ a sequence of :class:`SCA_ISensor` objects with string/index lookups and iterator support.
+
+ :type: list
+
+ .. note::
+
+ This attribute is experemental and may be removed (but probably wont be).
+
+ .. note::
+
+ Changes to this list will not update the KX_GameObject.
+
+ .. attribute:: controllers
+
+ a sequence of :class:`SCA_IController` objects with string/index lookups and iterator support.
+
+ :type: list of :class:`SCA_ISensor`
+
+ .. note::
+
+ This attribute is experemental and may be removed (but probably wont be).
+
+ .. note::
+
+ Changes to this list will not update the KX_GameObject.
+
+ .. attribute:: actuators
+
+ a list of :class:`SCA_IActuator` with string/index lookups and iterator support.
+
+ :type: list
+
+ .. note::
+
+ This attribute is experemental and may be removed (but probably wont be).
+
+ .. note::
+
+ Changes to this list will not update the KX_GameObject.
+
+ .. attribute:: attrDict
+
+ get the objects internal python attribute dictionary for direct (faster) access.
+
+ :type: dict
+
+ .. attribute:: children
+
+ direct children of this object, (read-only).
+
+ :type: :class:`CListValue` of :class:`KX_GameObject`'s
+
+ .. attribute:: childrenRecursive
+
+ all children of this object including childrens children, (read-only).
+
+ :type: :class:`CListValue` of :class:`KX_GameObject`'s
+
+ .. attribute:: life
+
+ The number of seconds until the object ends, assumes 50fps.
+ (when added with an add object actuator), (read-only).
+
+ :type: float
+
+ .. method:: endObject()
+
+ Delete this object, can be used in place of the EndObject Actuator.
+
+ The actual removal of the object from the scene is delayed.
+
+ .. method:: replaceMesh(mesh, useDisplayMesh=True, usePhysicsMesh=False)
+
+ Replace the mesh of this object with a new mesh. This works the same was as the actuator.
+
+ :arg mesh: mesh to replace or the meshes name.
+ :type mesh: :class:`MeshProxy` or string
+ :arg useDisplayMesh: when enabled the display mesh will be replaced (optional argument).
+ :type useDisplayMesh: boolean
+ :arg usePhysicsMesh: when enabled the physics mesh will be replaced (optional argument).
+ :type usePhysicsMesh: boolean
+
+ .. method:: setVisible(visible, recursive)
+
+ Sets the game object's visible flag.
+
+ :arg visible: the visible state to set.
+ :type visible: boolean
+ :arg recursive: optional argument to set all childrens visibility flag too.
+ :type recursive: boolean
+
+ .. method:: setOcclusion(occlusion, recursive)
+
+ Sets the game object's occlusion capability.
+
+ :arg occlusion: the state to set the occlusion to.
+ :type occlusion: boolean
+ :arg recursive: optional argument to set all childrens occlusion flag too.
+ :type recursive: boolean
+
+ .. method:: alignAxisToVect(vect, axis=2, factor=1.0)
+
+ Aligns any of the game object's axis along the given vector.
+
+
+ :arg vect: a vector to align the axis.
+ :type vect: 3D vector
+ :arg axis: The axis you want to align
+
+ * 0: X axis
+ * 1: Y axis
+ * 2: Z axis
+
+ :type axis: integer
+ :arg factor: Only rotate a feaction of the distance to the target vector (0.0 - 1.0)
+ :type factor: float
+
+ .. method:: getAxisVect(vect)
+
+ Returns the axis vector rotates by the objects worldspace orientation.
+ This is the equivalent of multiplying the vector by the orientation matrix.
+
+ :arg vect: a vector to align the axis.
+ :type vect: 3D Vector
+ :return: The vector in relation to the objects rotation.
+ :rtype: 3d vector.
+
+ .. method:: applyMovement(movement, local=False)
+
+ Sets the game object's movement.
+
+ :arg movement: movement vector.
+ :type movement: 3D Vector
+ :arg local:
+ * False: you get the "global" movement ie: relative to world orientation.
+ * True: you get the "local" movement ie: relative to object orientation.
+ :arg local: boolean
+
+ .. method:: applyRotation(rotation, local=False)
+
+ Sets the game object's rotation.
+
+ :arg rotation: rotation vector.
+ :type rotation: 3D Vector
+ :arg local:
+ * False: you get the "global" rotation ie: relative to world orientation.
+ * True: you get the "local" rotation ie: relative to object orientation.
+ :arg local: boolean
+
+ .. method:: applyForce(force, local=False)
+
+ Sets the game object's force.
+
+ This requires a dynamic object.
+
+ :arg force: force vector.
+ :type force: 3D Vector
+ :arg local:
+ * False: you get the "global" force ie: relative to world orientation.
+ * True: you get the "local" force ie: relative to object orientation.
+ :type local: boolean
+
+ .. method:: applyTorque(torque, local=False)
+
+ Sets the game object's torque.
+
+ This requires a dynamic object.
+
+ :arg torque: torque vector.
+ :type torque: 3D Vector
+ :arg local:
+ * False: you get the "global" torque ie: relative to world orientation.
+ * True: you get the "local" torque ie: relative to object orientation.
+ :type local: boolean
+
+ .. method:: getLinearVelocity(local=False)
+
+ Gets the game object's linear velocity.
+
+ This method returns the game object's velocity through it's centre of mass, ie no angular velocity component.
+
+ :arg local:
+ * False: you get the "global" velocity ie: relative to world orientation.
+ * 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]
+
+ .. method:: setLinearVelocity(velocity, local=False)
+
+ Sets the game object's linear velocity.
+
+ This method sets game object's velocity through it's centre of mass,
+ ie no angular velocity component.
+
+ This requires a dynamic object.
+
+ :arg velocity: linear velocity vector.
+ :type velocity: 3D Vector
+ :arg local:
+ * False: you get the "global" velocity ie: relative to world orientation.
+ * True: you get the "local" velocity ie: relative to object orientation.
+ :type local: boolean
+
+ .. method:: getAngularVelocity(local=False)
+
+ Gets the game object's angular velocity.
+
+ :arg local:
+ * False: you get the "global" velocity ie: relative to world orientation.
+ * 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]
+
+ .. method:: setAngularVelocity(velocity, local=False)
+
+ Sets the game object's angular velocity.
+
+ This requires a dynamic object.
+
+ :arg velocity: angular velocity vector.
+ :type velocity: boolean
+ :arg local:
+ * False: you get the "global" velocity ie: relative to world orientation.
+ * True: you get the "local" velocity ie: relative to object orientation.
+
+ .. method:: getVelocity(point=(0, 0, 0))
+
+ Gets the game object's velocity at the specified point.
+
+ Gets the game object's velocity at the specified point, including angular
+ components.
+
+ :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]
+
+ .. method:: getReactionForce()
+
+ Gets the game object's reaction force.
+
+ The reaction force is the force applied to this object over the last simulation timestep.
+ This also includes impulses, eg from collisions.
+
+ :return: the reaction force of this object.
+ :rtype: list [fx, fy, fz]
+
+ .. note::
+
+ This is not implimented at the moment.
+
+ .. method:: applyImpulse(point, impulse)
+
+ Applies an impulse to the game object.
+
+ This will apply the specified impulse to the game object at the specified point.
+ If point != position, applyImpulse will also change the object's angular momentum.
+ Otherwise, only linear momentum will change.
+
+ :arg point: the point to apply the impulse to (in world coordinates)
+ :type point: the point to apply the impulse to (in world coordinates)
+
+ .. method:: suspendDynamics()
+
+ Suspends physics for this object.
+
+ .. method:: restoreDynamics()
+
+ Resumes physics for this object.
+
+ .. note::
+
+ The objects linear velocity will be applied from when the dynamics were suspended.
+
+ .. method:: enableRigidBody()
+
+ Enables rigid body physics for this object.
+
+ Rigid body physics allows the object to roll on collisions.
+
+ .. method:: disableRigidBody()
+
+ Disables rigid body physics for this object.
+
+ .. method:: setParent(parent, compound=True, ghost=True)
+
+ Sets this object's parent.
+ Control the shape status with the optional compound and ghost parameters:
+
+ In that case you can control if it should be ghost or not:
+
+ :arg parent: new parent object.
+ :type parent: :class:`KX_GameObject`
+ :arg compound: whether the shape should be added to the parent compound shape.
+
+ * True: the object shape should be added to the parent compound shape.
+ * False: the object should keep its individual shape.
+
+ :type compound: boolean
+ :arg ghost: whether the object should be ghost while parented.
+
+ * True: if the object should be made ghost while parented.
+ * False: if the object should be solid while parented.
+
+ :type ghost: boolean
+
+ .. note::
+
+ If the object type is sensor, it stays ghost regardless of ghost parameter
+
+ .. method:: removeParent()
+
+ Removes this objects parent.
+
+ .. method:: getPhysicsId()
+
+ Returns the user data object associated with this game object's physics controller.
+
+ .. method:: getPropertyNames()
+
+ Gets a list of all property names.
+
+ :return: All property names for this object.
+ :rtype: list
+
+ .. method:: getDistanceTo(other)
+
+ :arg other: a point or another :class:`KX_GameObject` to measure the distance to.
+ :type other: :class:`KX_GameObject` or list [x, y, z]
+ :return: distance to another object or point.
+ :rtype: float
+
+ .. method:: getVectTo(other)
+
+ Returns the vector and the distance to another object or point.
+ The vector is normalized unless the distance is 0, in which a zero length vector is returned.
+
+ :arg other: a point or another :class:`KX_GameObject` to get the vector and distance to.
+ :type other: :class:`KX_GameObject` or list [x, y, z]
+ :return: (distance, globalVector(3), localVector(3))
+ :rtype: 3-tuple (float, 3-tuple (x, y, z), 3-tuple (x, y, z))
+
+ .. method:: rayCastTo(other, dist, prop)
+
+ Look towards another point/object and find first object hit within dist that matches prop.
+
+ The ray is always casted from the center of the object, ignoring the object itself.
+ The ray is casted towards the center of another object or an explicit [x, y, z] point.
+ Use rayCast() if you need to retrieve the hit point
+
+ :arg other: [x, y, z] or object towards which the ray is casted
+ :type other: :class:`KX_GameObject` or 3-tuple
+ :arg dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other
+ :type dist: float
+ :arg prop: property name that object must have; can be omitted => detect any object
+ :type prop: string
+ :return: the first object hit or None if no object or object does not match prop
+ :rtype: :class:`KX_GameObject`
+
+ .. method:: rayCast(objto, objfrom, dist, prop, face, xray, poly)
+
+ Look from a point/object to another point/object and find first object hit within dist that matches prop.
+ if poly is 0, returns a 3-tuple with object reference, hit point and hit normal or (None, None, None) if no hit.
+ if poly is 1, returns a 4-tuple with in addition a :class:`KX_PolyProxy` as 4th element.
+ if poly is 2, returns a 5-tuple with in addition a 2D vector with the UV mapping of the hit point as 5th element.
+
+ .. code-block:: python
+
+ # shoot along the axis gun-gunAim (gunAim should be collision-free)
+ obj, point, normal = gun.rayCast(gunAim, None, 50)
+ if obj:
+ # do something
+ pass
+
+ The face paremeter determines the orientation of the normal.
+
+ * 0 => hit normal is always oriented towards the ray origin (as if you casted the ray from outside)
+ * 1 => hit normal is the real face normal (only for mesh object, otherwise face has no effect)
+
+ The ray has X-Ray capability if xray parameter is 1, otherwise the first object hit (other than self object) stops the ray.
+ The prop and xray parameters interact as follow.
+
+ * prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray.
+ * prop off, xray on : idem.
+ * prop on, xray off: return closest hit if it matches prop, no hit otherwise.
+ * prop on, xray on : return closest hit matching prop or no hit if there is no object matching prop on the full extend of the ray.
+
+ The :class:`KX_PolyProxy` 4th element of the return tuple when poly=1 allows to retrieve information on the polygon hit by the ray.
+ If there is no hit or the hit object is not a static mesh, None is returned as 4th element.
+
+ The ray ignores collision-free objects and faces that dont have the collision flag enabled, you can however use ghost objects.
+
+ :arg objto: [x, y, z] or object to which the ray is casted
+ :type objto: :class:`KX_GameObject` or 3-tuple
+ :arg objfrom: [x, y, z] or object from which the ray is casted; None or omitted => use self object center
+ :type objfrom: :class:`KX_GameObject` or 3-tuple or None
+ :arg dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to
+ :type dist: float
+ :arg prop: property name that object must have; can be omitted or "" => detect any object
+ :type prop: string
+ :arg face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin
+ :type face: integer
+ :arg xray: X-ray option: 1=>skip objects that don't match prop; 0 or omitted => stop on first object
+ :type xray: integer
+ :arg poly: polygon option: 0, 1 or 2 to return a 3-, 4- or 5-tuple with information on the face hit.
+
+ * 0 or omitted: return value is a 3-tuple (object, hitpoint, hitnormal) or (None, None, None) if no hit
+ * 1: return value is a 4-tuple and the 4th element is a :class:`KX_PolyProxy` or None if no hit or the object doesn't use a mesh collision shape.
+ * 2: return value is a 5-tuple and the 5th element is a 2-tuple (u, v) with the UV mapping of the hit point or None if no hit, or the object doesn't use a mesh collision shape, or doesn't have a UV mapping.
+
+ :type poly: integer
+ :return: (object, hitpoint, hitnormal) or (object, hitpoint, hitnormal, polygon) or (object, hitpoint, hitnormal, polygon, hituv).
+
+ * object, hitpoint and hitnormal are None if no hit.
+ * polygon is valid only if the object is valid and is a static object, a dynamic object using mesh collision shape or a soft body object, otherwise it is None
+ * hituv is valid only if polygon is valid and the object has a UV mapping, otherwise it is None
+
+ :rtype:
+
+ * 3-tuple (:class:`KX_GameObject`, 3-tuple (x, y, z), 3-tuple (nx, ny, nz))
+ * or 4-tuple (:class:`KX_GameObject`, 3-tuple (x, y, z), 3-tuple (nx, ny, nz), :class:`PolyProxy`)
+ * or 5-tuple (:class:`KX_GameObject`, 3-tuple (x, y, z), 3-tuple (nx, ny, nz), :class:`PolyProxy`, 2-tuple (u, v))
+
+ .. note::
+
+ The ray ignores the object on which the method is called. It is casted from/to object center or explicit [x, y, z] points.
+
+ .. method:: setCollisionMargin(margin)
+
+ Set the objects collision margin.
+
+ :arg margin: the collision margin distance in blender units.
+ :type margin: float
+
+ .. note::
+
+ If this object has no physics controller (a physics ID of zero), this function will raise RuntimeError.
+
+ .. method:: sendMessage(subject, body="", to="")
+
+ Sends a message.
+
+ :arg subject: The subject of the message
+ :type subject: string
+ :arg body: The body of the message (optional)
+ :type body: string
+ :arg to: The name of the object to send the message to (optional)
+ :type to: string
+
+ .. method:: reinstancePhysicsMesh(gameObject, meshObject)
+
+ Updates the physics system with the changed mesh.
+
+ If no arguments are given the physics mesh will be re-created from the first mesh assigned to the game object.
+
+ :arg gameObject: optional argument, set the physics shape from this gameObjets mesh.
+ :type gameObject: string, :class:`KX_GameObject` or None
+ :arg meshObject: optional argument, set the physics shape from this mesh.
+ :type meshObject: string, :class:`MeshProxy` or None
+
+ :return: True if reinstance succeeded, False if it failed.
+ :rtype: boolean
+
+ .. note::
+
+ If this object has instances the other instances will be updated too.
+
+ .. note::
+
+ The gameObject argument has an advantage that it can convert from a mesh with modifiers applied (such as subsurf).
+
+ .. warning::
+
+ Only triangle mesh type objects are supported currently (not convex hull)
+
+ .. warning::
+
+ If the object is a part of a combound object it will fail (parent or child)
+
+ .. warning::
+
+ Rebuilding the physics mesh can be slow, running many times per second will give a performance hit.
+
+ .. method:: get(key, default=None)
+
+ Return the value matching key, or the default value if its not found.
+ :return: The key value or a default.
+
+ .. method:: playAction(name, start_frame, end_frame, layer=0, priority=0, blendin=0, play_mode=ACT_MODE_PLAY, layer_weight=0.0, ipo_flags=0, speed=1.0)
+
+ Plays an action.
+
+ :arg name: the name of the action
+ :type name: string
+ :arg start: the start frame of the action
+ :type start: float
+ :arg end: the end frame of the action
+ :type end: float
+ :arg layer: the layer the action will play in (actions in different layers are added/blended together)
+ :type layer: integer
+ :arg priority: only play this action if there isn't an action currently playing in this layer with a higher (lower number) priority
+ :type priority: integer
+ :arg blendin: the amount of blending between this animation and the previous one on this layer
+ :type blendin: float
+ :arg play_mode: the play mode
+ :type play_mode: one of :ref:`these constants <gameobject-playaction-mode>`
+ :arg layer_weight: how much of the previous layer to use for blending (0 = add)
+ :type layer_weight: float
+ :arg ipo_flags: flags for the old IPO behaviors (force, etc)
+ :type ipo_flags: int bitfield
+ :arg speed: the playback speed of the action as a factor (1.0 = normal speed, 2.0 = 2x speed, etc)
+ :type speed: float
+
+ .. method:: stopAction(layer=0)
+
+ Stop playing the action on the given layer.
+
+ :arg layer: The layer to stop playing.
+ :type layer: integer
+
+ .. method:: getActionFrame(layer=0)
+
+ Gets the current frame of the action playing in the supplied layer.
+
+ :arg layer: The layer that you want to get the frame from.
+ :type layer: integer
+
+ :return: The current frame of the action
+ :rtype: float
+
+ .. method:: setActionFrame(frame, layer=0)
+
+ Set the current frame of the action playing in the supplied layer.
+
+ :arg layer: The layer where you want to set the frame
+ :type layer: integer
+ :arg frame: The frame to set the action to
+ :type frame: float
+
+ .. method:: isPlayingAction(layer=0)
+
+ Checks to see if there is an action playing in the given layer.
+
+ :arg layer: The layer to check for a playing action.
+ :type layer: integer
+
+ :return: Whether or not the action is playing
+ :rtype: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_IpoActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_IpoActuator.rst
new file mode 100644
index 00000000000..2cae4fb3b1a
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_IpoActuator.rst
@@ -0,0 +1,65 @@
+KX_IpoActuator(SCA_IActuator)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_IpoActuator(SCA_IActuator)
+
+ IPO actuator activates an animation.
+
+ .. attribute:: frameStart
+
+ Start frame.
+
+ :type: float
+
+ .. attribute:: frameEnd
+
+ End frame.
+
+ :type: float
+
+ .. attribute:: propName
+
+ Use this property to define the Ipo position.
+
+ :type: string
+
+ .. attribute:: framePropName
+
+ Assign this property this action current frame number.
+
+ :type: string
+
+ .. attribute:: mode
+
+ Play mode for the ipo. Can be on of :ref:`these constants <ipo-actuator>`
+
+ :type: integer
+
+ .. attribute:: useIpoAsForce
+
+ Apply Ipo as a global or local force depending on the local option (dynamic objects only).
+
+ :type: boolean
+
+ .. attribute:: useIpoAdd
+
+ Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag.
+
+ :type: boolean
+
+ .. attribute:: useIpoLocal
+
+ Let the ipo acts in local coordinates, used in Force and Add mode.
+
+ :type: boolean
+
+ .. attribute:: useChildren
+
+ Update IPO on all children Objects as well.
+
+ :type: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_LibLoadStatus.rst b/doc/python_api/rst/bge_types/bge.types.KX_LibLoadStatus.rst
new file mode 100644
index 00000000000..a5b7aaf5dee
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_LibLoadStatus.rst
@@ -0,0 +1,45 @@
+KX_LibLoadStatus(PyObjectPlus)
+==============================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: KX_LibLoadStatus(PyObjectPlus)
+
+ An object providing information about a LibLoad() operation.
+
+ .. code-block:: python
+
+ # Print a message when an async LibLoad is done
+ import bge
+
+ def finished_cb(status):
+ print("Library (%s) loaded in %.2fms." % (status.libraryName, status.timeTaken))
+
+ bge.logic.LibLoad('myblend.blend', 'Scene', async=True).onFinish = finished_cb
+
+ .. attribute:: onFinish
+
+ A callback that gets called when the lib load is done.
+
+ :type: callable
+
+ .. attribute:: progress
+
+ The current progress of the lib load as a normalized value from 0.0 to 1.0.
+
+ :type: float
+
+ .. attribute:: libraryName
+
+ The name of the library being loaded (the first argument to LibLoad).
+
+ :type: string
+
+ .. attribute:: timeTaken
+
+ The amount of time, in seconds, the lib load took (0 until the operation is complete).
+
+ :type: float
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst
new file mode 100644
index 00000000000..2b2bdf76b4f
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst
@@ -0,0 +1,90 @@
+KX_LightObject(KX_GameObject)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`KX_GameObject`
+
+.. class:: KX_LightObject(KX_GameObject)
+
+ A Light object.
+
+ .. code-block:: python
+
+ # Turn on a red alert light.
+ import bge
+
+ co = bge.logic.getCurrentController()
+ light = co.owner
+
+ light.energy = 1.0
+ light.color = [1.0, 0.0, 0.0]
+
+ .. data:: SPOT
+
+ A spot light source. See attribute :data:`type`
+
+ .. data:: SUN
+
+ A point light source with no attenuation. See attribute :data:`type`
+
+ .. data:: NORMAL
+
+ A point light source. See attribute :data:`type`
+
+ .. attribute:: type
+
+ The type of light - must be SPOT, SUN or NORMAL
+
+ .. attribute:: layer
+
+ The layer mask that this light affects object on.
+
+ :type: bitfield
+
+ .. attribute:: energy
+
+ The brightness of this light.
+
+ :type: float
+
+ .. attribute:: distance
+
+ The maximum distance this light can illuminate. (SPOT and NORMAL lights only).
+
+ :type: float
+
+ .. attribute:: color
+
+ The color of this light. Black = [0.0, 0.0, 0.0], White = [1.0, 1.0, 1.0].
+
+ :type: list [r, g, b]
+
+ .. attribute:: lin_attenuation
+
+ The linear component of this light's attenuation. (SPOT and NORMAL lights only).
+
+ :type: float
+
+ .. attribute:: quad_attenuation
+
+ The quadratic component of this light's attenuation (SPOT and NORMAL lights only).
+
+ :type: float
+
+ .. attribute:: spotsize
+
+ The cone angle of the spot light, in degrees (SPOT lights only).
+
+ :type: float in [0 - 180].
+
+ .. attribute:: spotblend
+
+ Specifies the intensity distribution of the spot light (SPOT lights only).
+
+ :type: float in [0 - 1]
+
+ .. note::
+
+ Higher values result in a more focused light source.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_MeshProxy.rst b/doc/python_api/rst/bge_types/bge.types.KX_MeshProxy.rst
new file mode 100644
index 00000000000..2ec8b8ece5c
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_MeshProxy.rst
@@ -0,0 +1,134 @@
+KX_MeshProxy(SCA_IObject)
+=========================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IObject`
+
+.. class:: KX_MeshProxy(SCA_IObject)
+
+ A mesh object.
+
+ You can only change the vertex properties of a mesh object, not the mesh topology.
+
+ To use mesh objects effectively, you should know a bit about how the game engine handles them.
+
+ #. Mesh Objects are converted from Blender at scene load.
+ #. The Converter groups polygons by Material. This means they can be sent to the renderer efficiently. A material holds:
+
+ #. The texture.
+ #. The Blender material.
+ #. The Tile properties
+ #. The face properties - (From the "Texture Face" panel)
+ #. Transparency & z sorting
+ #. Light layer
+ #. Polygon shape (triangle/quad)
+ #. Game Object
+
+ #. Vertices will be split by face if necessary. Vertices can only be shared between faces if:
+
+ #. They are at the same position
+ #. UV coordinates are the same
+ #. Their normals are the same (both polygons are "Set Smooth")
+ #. They are the same color, for example: a cube has 24 vertices: 6 faces with 4 vertices per face.
+
+ The correct method of iterating over every :class:`KX_VertexProxy` in a game object
+
+ .. code-block:: python
+
+ from bge import logic
+
+ cont = logic.getCurrentController()
+ object = cont.owner
+
+ for mesh in object.meshes:
+ for m_index in range(len(mesh.materials)):
+ for v_index in range(mesh.getVertexArrayLength(m_index)):
+ vertex = mesh.getVertex(m_index, v_index)
+ # Do something with vertex here...
+ # ... eg: color the vertex red.
+ vertex.color = [1.0, 0.0, 0.0, 1.0]
+
+ .. attribute:: materials
+
+ :type: list of :class:`KX_BlenderMaterial` or :class:`KX_PolygonMaterial` types
+
+ .. attribute:: numPolygons
+
+ :type: integer
+
+ .. attribute:: numMaterials
+
+ :type: integer
+
+ .. method:: getMaterialName(matid)
+
+ Gets the name of the specified material.
+
+ :arg matid: the specified material.
+ :type matid: integer
+ :return: the attached material name.
+ :rtype: string
+
+ .. method:: getTextureName(matid)
+
+ Gets the name of the specified material's texture.
+
+ :arg matid: the specified material
+ :type matid: integer
+ :return: the attached material's texture name.
+ :rtype: string
+
+ .. method:: getVertexArrayLength(matid)
+
+ Gets the length of the vertex array associated with the specified material.
+
+ There is one vertex array for each material.
+
+ :arg matid: the specified material
+ :type matid: integer
+ :return: the number of verticies in the vertex array.
+ :rtype: integer
+
+ .. method:: getVertex(matid, index)
+
+ Gets the specified vertex from the mesh object.
+
+ :arg matid: the specified material
+ :type matid: integer
+ :arg index: the index into the vertex array.
+ :type index: integer
+ :return: a vertex object.
+ :rtype: :class:`KX_VertexProxy`
+
+ .. method:: getPolygon(index)
+
+ Gets the specified polygon from the mesh.
+
+ :arg index: polygon number
+ :type index: integer
+ :return: a polygon object.
+ :rtype: :class:`PolyProxy`
+
+ .. method:: transform(matid, matrix)
+
+ Transforms the vertices of a mesh.
+
+ :arg matid: material index, -1 transforms all.
+ :type matid: integer
+ :arg matrix: transformation matrix.
+ :type matrix: 4x4 matrix [[float]]
+
+ .. method:: transformUV(matid, matrix, uv_index=-1, uv_index_from=-1)
+
+ Transforms the vertices UV's of a mesh.
+
+ :arg matid: material index, -1 transforms all.
+ :type matid: integer
+ :arg matrix: transformation matrix.
+ :type matrix: 4x4 matrix [[float]]
+ :arg uv_index: optional uv index, -1 for all, otherwise 0 or 1.
+ :type uv_index: integer
+ :arg uv_index_from: optional uv index to copy from, -1 to transform the current uv.
+ :type uv_index_from: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst b/doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst
new file mode 100644
index 00000000000..dda73eadb52
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_MouseFocusSensor.rst
@@ -0,0 +1,66 @@
+KX_MouseFocusSensor(SCA_MouseSensor)
+====================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_MouseSensor`
+
+.. class:: KX_MouseFocusSensor(SCA_MouseSensor)
+
+ The mouse focus sensor detects when the mouse is over the current game object.
+
+ The mouse focus sensor works by transforming the mouse coordinates from 2d device
+ space to 3d space then raycasting away from the camera.
+
+ .. attribute:: raySource
+
+ The worldspace source of the ray (the view position).
+
+ :type: list (vector of 3 floats)
+
+ .. attribute:: rayTarget
+
+ The worldspace target of the ray.
+
+ :type: list (vector of 3 floats)
+
+ .. attribute:: rayDirection
+
+ The :data:`rayTarget` - :class:`raySource` normalized.
+
+ :type: list (normalized vector of 3 floats)
+
+ .. attribute:: hitObject
+
+ the last object the mouse was over.
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: hitPosition
+
+ The worldspace position of the ray intersecton.
+
+ :type: list (vector of 3 floats)
+
+ .. attribute:: hitNormal
+
+ the worldspace normal from the face at point of intersection.
+
+ :type: list (normalized vector of 3 floats)
+
+ .. attribute:: hitUV
+
+ the UV coordinates at the point of intersection.
+
+ :type: list (vector of 2 floats)
+
+ If the object has no UV mapping, it returns [0, 0].
+
+ The UV coordinates are not normalized, they can be < 0 or > 1 depending on the UV mapping.
+
+ .. attribute:: usePulseFocus
+
+ When enabled, moving the mouse over a different object generates a pulse. (only used when the 'Mouse Over Any' sensor option is set).
+
+ :type: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_NavMeshObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_NavMeshObject.rst
new file mode 100644
index 00000000000..5c73d0aa1d3
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_NavMeshObject.rst
@@ -0,0 +1,47 @@
+KX_NavMeshObject(KX_GameObject)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`KX_GameObject`
+
+.. class:: KX_NavMeshObject(KX_GameObject)
+
+ Python interface for using and controlling navigation meshes.
+
+ .. method:: findPath(start, goal)
+
+ Finds the path from start to goal points.
+
+ :arg start: the start point
+ :arg start: 3D Vector
+ :arg goal: the goal point
+ :arg start: 3D Vector
+ :return: a path as a list of points
+ :rtype: list of points
+
+ .. method:: raycast(start, goal)
+
+ Raycast from start to goal points.
+
+ :arg start: the start point
+ :arg start: 3D Vector
+ :arg goal: the goal point
+ :arg start: 3D Vector
+ :return: the hit factor
+ :rtype: float
+
+ .. method:: draw(mode)
+
+ Draws a debug mesh for the navigation mesh.
+
+ :arg mode: the drawing mode (one of :ref:`these constants <navmesh-draw-mode>`)
+ :arg mode: integer
+ :return: None
+
+ .. method:: rebuild()
+
+ Rebuild the navigation mesh.
+
+ :return: None
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_NearSensor.rst b/doc/python_api/rst/bge_types/bge.types.KX_NearSensor.rst
new file mode 100644
index 00000000000..995e645b979
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_NearSensor.rst
@@ -0,0 +1,23 @@
+KX_NearSensor(KX_TouchSensor)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`KX_TouchSensor`
+
+.. class:: KX_NearSensor(KX_TouchSensor)
+
+ A near sensor is a specialised form of touch sensor.
+
+ .. attribute:: distance
+
+ The near sensor activates when an object is within this distance.
+
+ :type: float
+
+ .. attribute:: resetDistance
+
+ The near sensor deactivates when the object exceeds this distance.
+
+ :type: float
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageActuator.rst
new file mode 100644
index 00000000000..b8dcd01fe43
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageActuator.rst
@@ -0,0 +1,35 @@
+KX_NetworkMessageActuator(SCA_IActuator)
+========================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_NetworkMessageActuator(SCA_IActuator)
+
+ Message Actuator
+
+ .. attribute:: propName
+
+ Messages will only be sent to objects with the given property name.
+
+ :type: string
+
+ .. attribute:: subject
+
+ The subject field of the message.
+
+ :type: string
+
+ .. attribute:: body
+
+ The body of the message.
+
+ :type: string
+
+ .. attribute:: usePropBody
+
+ Send a property instead of a regular body message.
+
+ :type: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageSensor.rst b/doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageSensor.rst
new file mode 100644
index 00000000000..a6b1082a4fe
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_NetworkMessageSensor.rst
@@ -0,0 +1,38 @@
+KX_NetworkMessageSensor(SCA_ISensor)
+====================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: KX_NetworkMessageSensor(SCA_ISensor)
+
+ The Message Sensor logic brick.
+
+ Currently only loopback (local) networks are supported.
+
+ .. attribute:: subject
+
+ The subject the sensor is looking for.
+
+ :type: string
+
+ .. attribute:: frameMessageCount
+
+ The number of messages received since the last frame. (read-only).
+
+ :type: integer
+
+ .. attribute:: subjects
+
+ The list of message subjects received. (read-only).
+
+ :type: list of strings
+
+ .. attribute:: bodies
+
+ The list of message bodies received. (read-only).
+
+ :type: list of strings
+
+
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
new file mode 100644
index 00000000000..f10f101a4cc
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_ObjectActuator.rst
@@ -0,0 +1,129 @@
+KX_ObjectActuator(SCA_IActuator)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_ObjectActuator(SCA_IActuator)
+
+ The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement,
+ velocity, or angular velocity to an object.
+ Servo control allows to regulate force to achieve a certain speed target.
+
+ .. attribute:: force
+
+ The force applied by the actuator.
+
+ :type: list [x, y, z]
+
+ .. attribute:: useLocalForce
+
+ A flag specifying if the force is local.
+
+ :type: boolean
+
+ .. attribute:: torque
+
+ The torque applied by the actuator.
+
+ :type: list [x, y, z]
+
+ .. attribute:: useLocalTorque
+
+ A flag specifying if the torque is local.
+
+ :type: boolean
+
+ .. attribute:: dLoc
+
+ The displacement vector applied by the actuator.
+
+ :type: list [x, y, z]
+
+ .. attribute:: useLocalDLoc
+
+ A flag specifying if the dLoc is local.
+
+ :type: boolean
+
+ .. attribute:: dRot
+
+ The angular displacement vector applied by the actuator
+
+ :type: list [x, y, z]
+
+ .. note::
+
+ Since the displacement is applied every frame, you must adjust the displacement based on the frame rate, or you game experience will depend on the player's computer speed.
+
+ .. attribute:: useLocalDRot
+
+ A flag specifying if the dRot is local.
+
+ :type: boolean
+
+ .. attribute:: linV
+
+ The linear velocity applied by the actuator.
+
+ :type: list [x, y, z]
+
+ .. attribute:: useLocalLinV
+
+ A flag specifying if the linear velocity is local.
+
+ :type: boolean
+
+ .. note::
+
+ This is the target speed for servo controllers.
+
+ .. attribute:: angV
+
+ The angular velocity applied by the actuator.
+
+ :type: list [x, y, z]
+
+ .. attribute:: useLocalAngV
+
+ A flag specifying if the angular velocity is local.
+
+ :type: boolean
+
+ .. attribute:: damping
+
+ The damping parameter of the servo controller.
+
+ :type: short
+
+ .. attribute:: forceLimitX
+
+ The min/max force limit along the X axis and activates or deactivates the limits in the servo controller.
+
+ :type: list [min(float), max(float), bool]
+
+ .. attribute:: forceLimitY
+
+ The min/max force limit along the Y axis and activates or deactivates the limits in the servo controller.
+
+ :type: list [min(float), max(float), bool]
+
+ .. attribute:: forceLimitZ
+
+ The min/max force limit along the Z axis and activates or deactivates the limits in the servo controller.
+
+ :type: list [min(float), max(float), bool]
+
+ .. attribute:: pid
+
+ The PID coefficients of the servo controller.
+
+ :type: list of floats [proportional, integral, derivate]
+
+ .. attribute:: reference
+
+ The object that is used as reference to compute the velocity for the servo controller.
+
+ :type: :class:`KX_GameObject` or None
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_ParentActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_ParentActuator.rst
new file mode 100644
index 00000000000..77dcb907d6a
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_ParentActuator.rst
@@ -0,0 +1,38 @@
+KX_ParentActuator(SCA_IActuator)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_ParentActuator(SCA_IActuator)
+
+ The parent actuator can set or remove an objects parent object.
+
+ .. attribute:: object
+
+ the object this actuator sets the parent too.
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: mode
+
+ The mode of this actuator.
+
+ :type: integer from 0 to 1.
+
+ .. attribute:: compound
+
+ Whether the object shape should be added to the parent compound shape when parenting.
+
+ Effective only if the parent is already a compound shape.
+
+ :type: boolean
+
+ .. attribute:: ghost
+
+ Whether the object should be made ghost when parenting
+ Effective only if the shape is not added to the parent compound shape.
+
+ :type: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_PolyProxy.rst b/doc/python_api/rst/bge_types/bge.types.KX_PolyProxy.rst
new file mode 100644
index 00000000000..534f6deedc0
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_PolyProxy.rst
@@ -0,0 +1,139 @@
+KX_PolyProxy(SCA_IObject)
+=========================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IObject`
+
+.. class:: KX_PolyProxy(SCA_IObject)
+
+ A polygon holds the index of the vertex forming the poylgon.
+
+ Note:
+ The polygon attributes are read-only, you need to retrieve the vertex proxy if you want
+ to change the vertex settings.
+
+ .. attribute:: material_name
+
+ The name of polygon material, empty if no material.
+
+ :type: string
+
+ .. attribute:: material
+
+ The material of the polygon.
+
+ :type: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
+
+ .. attribute:: texture_name
+
+ The texture name of the polygon.
+
+ :type: string
+
+ .. attribute:: material_id
+
+ The material index of the polygon, use this to retrieve vertex proxy from mesh proxy.
+
+ :type: integer
+
+ .. attribute:: v1
+
+ vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy.
+
+ :type: integer
+
+ .. attribute:: v2
+
+ vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy.
+
+ :type: integer
+
+ .. attribute:: v3
+
+ vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy.
+
+ :type: integer
+
+ .. attribute:: v4
+
+ Vertex index of the fourth vertex of the polygon, 0 if polygon has only 3 vertex
+ Use this to retrieve vertex proxy from mesh proxy.
+
+ :type: integer
+
+ .. attribute:: visible
+
+ visible state of the polygon: 1=visible, 0=invisible.
+
+ :type: integer
+
+ .. attribute:: collide
+
+ collide state of the polygon: 1=receives collision, 0=collision free.
+
+ :type: integer
+
+ .. method:: getMaterialName()
+
+ Returns the polygon material name with MA prefix
+
+ :return: material name
+ :rtype: string
+
+ .. method:: getMaterial()
+
+ :return: The polygon material
+ :rtype: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
+
+ .. method:: getTextureName()
+
+ :return: The texture name
+ :rtype: string
+
+ .. method:: getMaterialIndex()
+
+ Returns the material bucket index of the polygon.
+ This index and the ones returned by getVertexIndex() are needed to retrieve the vertex proxy from :class:`MeshProxy`.
+
+ :return: the material index in the mesh
+ :rtype: integer
+
+ .. method:: getNumVertex()
+
+ Returns the number of vertex of the polygon.
+
+ :return: number of vertex, 3 or 4.
+ :rtype: integer
+
+ .. method:: isVisible()
+
+ Returns whether the polygon is visible or not
+
+ :return: 0=invisible, 1=visible
+ :rtype: boolean
+
+ .. method:: isCollider()
+
+ Returns whether the polygon is receives collision or not
+
+ :return: 0=collision free, 1=receives collision
+ :rtype: integer
+
+ .. method:: getVertexIndex(vertex)
+
+ Returns the mesh vertex index of a polygon vertex
+ This index and the one returned by getMaterialIndex() are needed to retrieve the vertex proxy from :class:`MeshProxy`.
+
+ :arg vertex: index of the vertex in the polygon: 0->3
+ :arg vertex: integer
+ :return: mesh vertex index
+ :rtype: integer
+
+ .. method:: getMesh()
+
+ Returns a mesh proxy
+
+ :return: mesh proxy
+ :rtype: :class:`MeshProxy`
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_PolygonMaterial.rst b/doc/python_api/rst/bge_types/bge.types.KX_PolygonMaterial.rst
new file mode 100644
index 00000000000..3421e194d77
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_PolygonMaterial.rst
@@ -0,0 +1,250 @@
+KX_PolygonMaterial(PyObjectPlus)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: KX_PolygonMaterial(PyObjectPlus)
+
+ This is the interface to materials in the game engine.
+
+ Materials define the render state to be applied to mesh objects.
+
+ .. warning::
+
+ Some of the methods/variables are CObjects. If you mix these up, you will crash blender.
+
+ .. code-block:: python
+
+ from bge import logic
+
+ vertex_shader = """
+
+ void main(void)
+ {
+ // original vertex position, no changes
+ gl_Position = ftransform();
+ // coordinate of the 1st texture channel
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ // coordinate of the 2nd texture channel
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+ }
+ """
+
+ fragment_shader ="""
+
+ uniform sampler2D color_0;
+ uniform sampler2D color_1;
+ uniform float factor;
+
+ void main(void)
+ {
+ vec4 color_0 = texture2D(color_0, gl_TexCoord[0].st);
+ vec4 color_1 = texture2D(color_1, gl_TexCoord[1].st);
+ gl_FragColor = mix(color_0, color_1, factor);
+ }
+ """
+
+ object = logic.getCurrentController().owner
+ object = cont.owner
+ for mesh in object.meshes:
+ for material in mesh.materials:
+ shader = material.getShader()
+ if shader != None:
+ if not shader.isValid():
+ shader.setSource(vertex_shader, fragment_shader, True)
+
+ # get the first texture channel of the material
+ shader.setSampler('color_0', 0)
+ # get the second texture channel of the material
+ shader.setSampler('color_1', 1)
+ # pass another uniform to the shader
+ shader.setUniform1f('factor', 0.3)
+
+
+ .. attribute:: texture
+
+ Texture name.
+
+ :type: string (read-only)
+
+ .. attribute:: gl_texture
+
+ OpenGL texture handle (eg for glBindTexture(GL_TEXTURE_2D, gl_texture).
+
+ :type: integer (read-only)
+
+ .. attribute:: material
+
+ Material name.
+
+ :type: string (read-only)
+
+ .. attribute:: tface
+
+ Texture face properties.
+
+ :type: CObject (read-only)
+
+ .. attribute:: tile
+
+ Texture is tiling.
+
+ :type: boolean
+
+ .. attribute:: tilexrep
+
+ Number of tile repetitions in x direction.
+
+ :type: integer
+
+ .. attribute:: tileyrep
+
+ Number of tile repetitions in y direction.
+
+ :type: integer
+
+ .. attribute:: drawingmode
+
+ Drawing mode for the material.
+ - 2 (drawingmode & 4) Textured
+ - 4 (drawingmode & 16) Light
+ - 14 (drawingmode & 16384) 3d Polygon Text.
+
+ :type: bitfield
+
+ .. attribute:: transparent
+
+ This material is transparent. All meshes with this
+ material will be rendered after non transparent meshes from back
+ to front.
+
+ :type: boolean
+
+ .. attribute:: zsort
+
+ Transparent polygons in meshes with this material will be sorted back to
+ front before rendering.
+ Non-Transparent polygons will be sorted front to back before rendering.
+
+ :type: boolean
+
+ .. attribute:: diffuse
+
+ The diffuse color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
+
+ :type: list [r, g, b]
+
+ .. attribute:: specular
+
+ The specular color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
+
+ :type: list [r, g, b]
+
+ .. attribute:: shininess
+
+ The shininess (specular exponent) of the material. 0.0 <= shininess <= 128.0.
+
+ :type: float
+
+ .. attribute:: specularity
+
+ The amount of specular of the material. 0.0 <= specularity <= 1.0.
+
+ :type: float
+
+ .. method:: updateTexture(tface, rasty)
+
+ Updates a realtime animation.
+
+ :arg tface: Texture face (eg mat.tface)
+ :type tface: CObject
+ :arg rasty: Rasterizer
+ :type rasty: CObject
+
+ .. method:: setTexture(tface)
+
+ Sets texture render state.
+
+ :arg tface: Texture face
+ :type tface: CObject
+
+ .. code-block:: python
+
+ mat.setTexture(mat.tface)
+
+ .. method:: activate(rasty, cachingInfo)
+
+ Sets material parameters for this object for rendering.
+
+ Material Parameters set:
+
+ #. Texture
+ #. Backface culling
+ #. Line drawing
+ #. Specular Colour
+ #. Shininess
+ #. Diffuse Colour
+ #. Polygon Offset.
+
+ :arg rasty: Rasterizer instance.
+ :type rasty: CObject
+ :arg cachingInfo: Material cache instance.
+ :type cachingInfo: CObject
+
+ .. method:: setCustomMaterial(material)
+
+ Sets the material state setup object.
+
+ Using this method, you can extend or completely replace the gameengine material
+ to do your own advanced multipass effects.
+
+ Use this method to register your material class. Instead of the normal material,
+ your class's activate method will be called just before rendering the mesh.
+ This should setup the texture, material, and any other state you would like.
+ It should return True to render the mesh, or False if you are finished. You should
+ clean up any state Blender does not set before returning False.
+
+ Activate Method Definition:
+
+ .. code-block:: python
+
+ def activate(self, rasty, cachingInfo, material):
+
+ :arg material: The material object.
+ :type material: instance
+
+ .. code-block:: python
+
+ class PyMaterial:
+ def __init__(self):
+ self.pass_no = -1
+
+ def activate(self, rasty, cachingInfo, material):
+ # Activate the material here.
+ #
+ # The activate method will be called until it returns False.
+ # Every time the activate method returns True the mesh will
+ # be rendered.
+ #
+ # rasty is a CObject for passing to material.updateTexture()
+ # and material.activate()
+ # cachingInfo is a CObject for passing to material.activate()
+ # material is the KX_PolygonMaterial instance this material
+ # was added to
+
+ # default material properties:
+ self.pass_no += 1
+ if self.pass_no == 0:
+ material.activate(rasty, cachingInfo)
+ # Return True to do this pass
+ return True
+
+ # clean up and return False to finish.
+ self.pass_no = -1
+ return False
+
+ # Create a new Python Material and pass it to the renderer.
+ mat.setCustomMaterial(PyMaterial())
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_RadarSensor.rst b/doc/python_api/rst/bge_types/bge.types.KX_RadarSensor.rst
new file mode 100644
index 00000000000..4274c1142f4
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_RadarSensor.rst
@@ -0,0 +1,44 @@
+KX_RadarSensor(KX_NearSensor)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`KX_NearSensor`
+
+.. class:: KX_RadarSensor(KX_NearSensor)
+
+ Radar sensor is a near sensor with a conical sensor object.
+
+ .. attribute:: coneOrigin
+
+ The origin of the cone with which to test. The origin is in the middle of the cone. (read-only).
+
+ :type: list of floats [x, y, z]
+
+ .. attribute:: coneTarget
+
+ The center of the bottom face of the cone with which to test. (read-only).
+
+ :type: list of floats [x, y, z]
+
+ .. attribute:: distance
+
+ The height of the cone with which to test.
+
+ :type: float
+
+ .. attribute:: angle
+
+ The angle of the cone (in degrees) with which to test.
+
+ :type: float
+
+ .. attribute:: axis
+
+ The axis on which the radar cone is cast.
+
+ :type: integer from 0 to 5
+
+ KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z,
+ KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_RaySensor.rst b/doc/python_api/rst/bge_types/bge.types.KX_RaySensor.rst
new file mode 100644
index 00000000000..2ff989729f5
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_RaySensor.rst
@@ -0,0 +1,72 @@
+KX_RaySensor(SCA_ISensor)
+=========================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: KX_RaySensor(SCA_ISensor)
+
+ A ray sensor detects the first object in a given direction.
+
+ .. attribute:: propName
+
+ The property the ray is looking for.
+
+ :type: string
+
+ .. attribute:: range
+
+ The distance of the ray.
+
+ :type: float
+
+ .. attribute:: useMaterial
+
+ Whether or not to look for a material (false = property).
+
+ :type: boolean
+
+ .. attribute:: useXRay
+
+ Whether or not to use XRay.
+
+ :type: boolean
+
+ .. attribute:: hitObject
+
+ The game object that was hit by the ray. (read-only).
+
+ :type: :class:`KX_GameObject`
+
+ .. attribute:: hitPosition
+
+ The position (in worldcoordinates) where the object was hit by the ray. (read-only).
+
+ :type: list [x, y, z]
+
+ .. attribute:: hitNormal
+
+ The normal (in worldcoordinates) of the object at the location where the object was hit by the ray. (read-only).
+
+ :type: list [x, y, z]
+
+ .. attribute:: rayDirection
+
+ The direction from the ray (in worldcoordinates). (read-only).
+
+ :type: list [x, y, z]
+
+ .. attribute:: axis
+
+ The axis the ray is pointing on.
+
+ :type: integer from 0 to 5
+
+ * KX_RAY_AXIS_POS_X
+ * KX_RAY_AXIS_POS_Y
+ * KX_RAY_AXIS_POS_Z
+ * KX_RAY_AXIS_NEG_X
+ * KX_RAY_AXIS_NEG_Y
+ * KX_RAY_AXIS_NEG_Z
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_SCA_AddObjectActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_SCA_AddObjectActuator.rst
new file mode 100644
index 00000000000..fecc863909d
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_SCA_AddObjectActuator.rst
@@ -0,0 +1,55 @@
+KX_SCA_AddObjectActuator(SCA_IActuator)
+=======================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_SCA_AddObjectActuator(SCA_IActuator)
+
+ Edit Object Actuator (in Add Object Mode)
+
+ .. warning::
+
+ An Add Object actuator will be ignored if at game start, the linked object doesn't exist (or is empty) or the linked object is in an active layer.
+
+ .. code-block:: none
+
+ Error: GameObject 'Name' has a AddObjectActuator 'ActuatorName' without object (in 'nonactive' layer)
+
+ .. attribute:: object
+
+ the object this actuator adds.
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: objectLastCreated
+
+ the last added object from this actuator (read-only).
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: time
+
+ the lifetime of added objects, in frames. Set to 0 to disable automatic deletion.
+
+ :type: integer
+
+ .. attribute:: linearVelocity
+
+ the initial linear velocity of added objects.
+
+ :type: list [vx, vy, vz]
+
+ .. attribute:: angularVelocity
+
+ the initial angular velocity of added objects.
+
+ :type: list [vx, vy, vz]
+
+ .. method:: instantAddObject()
+
+ adds the object without needing to calling SCA_PythonController.activate()
+
+ .. note:: Use objectLastCreated to get the newly created object.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_SCA_DynamicActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_SCA_DynamicActuator.rst
new file mode 100644
index 00000000000..055c4098253
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_SCA_DynamicActuator.rst
@@ -0,0 +1,29 @@
+KX_SCA_DynamicActuator(SCA_IActuator)
+=====================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_SCA_DynamicActuator(SCA_IActuator)
+
+ Dynamic Actuator.
+
+ .. attribute:: mode
+
+ :type: integer
+
+ the type of operation of the actuator, 0-4
+
+ * KX_DYN_RESTORE_DYNAMICS(0)
+ * KX_DYN_DISABLE_DYNAMICS(1)
+ * KX_DYN_ENABLE_RIGID_BODY(2)
+ * KX_DYN_DISABLE_RIGID_BODY(3)
+ * KX_DYN_SET_MASS(4)
+
+ .. attribute:: mass
+
+ the mass value for the KX_DYN_SET_MASS operation.
+
+ :type: float
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_SCA_EndObjectActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_SCA_EndObjectActuator.rst
new file mode 100644
index 00000000000..8d9221febb0
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_SCA_EndObjectActuator.rst
@@ -0,0 +1,13 @@
+KX_SCA_EndObjectActuator(SCA_IActuator)
+=======================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_SCA_EndObjectActuator(SCA_IActuator)
+
+ Edit Object Actuator (in End Object mode)
+
+ This actuator has no python methods.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_SCA_ReplaceMeshActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_SCA_ReplaceMeshActuator.rst
new file mode 100644
index 00000000000..137c63ea829
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_SCA_ReplaceMeshActuator.rst
@@ -0,0 +1,89 @@
+KX_SCA_ReplaceMeshActuator(SCA_IActuator)
+=========================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_SCA_ReplaceMeshActuator(SCA_IActuator)
+
+ Edit Object actuator, in Replace Mesh mode.
+
+ .. warning::
+
+ Replace mesh actuators will be ignored if at game start, the named mesh doesn't exist.
+
+ This will generate a warning in the console
+
+ .. code-block:: none
+
+ Error: GameObject 'Name' ReplaceMeshActuator 'ActuatorName' without object
+
+ .. code-block:: python
+
+ # Level-of-detail
+ # Switch a game object's mesh based on its depth in the camera view.
+ # +----------+ +-----------+ +-------------------------------------+
+ # | Always +-----+ Python +-----+ Edit Object (Replace Mesh) LOD.Mesh |
+ # +----------+ +-----------+ +-------------------------------------+
+ from bge import logic
+
+ # List detail meshes here
+ # Mesh (name, near, far)
+ # Meshes overlap so that they don't 'pop' when on the edge of the distance.
+ meshes = ((".Hi", 0.0, -20.0),
+ (".Med", -15.0, -50.0),
+ (".Lo", -40.0, -100.0)
+ )
+
+ cont = logic.getCurrentController()
+ object = cont.owner
+ actuator = cont.actuators["LOD." + obj.name]
+ camera = logic.getCurrentScene().active_camera
+
+ def Depth(pos, plane):
+ return pos[0]*plane[0] + pos[1]*plane[1] + pos[2]*plane[2] + plane[3]
+
+ # Depth is negative and decreasing further from the camera
+ depth = Depth(object.position, camera.world_to_camera[2])
+
+ newmesh = None
+ curmesh = None
+ # Find the lowest detail mesh for depth
+ for mesh in meshes:
+ if depth < mesh[1] and depth > mesh[2]:
+ newmesh = mesh
+ if "ME" + object.name + mesh[0] == actuator.getMesh():
+ curmesh = mesh
+
+ if newmesh != None and "ME" + object.name + newmesh[0] != actuator.mesh:
+ # The mesh is a different mesh - switch it.
+ # Check the current mesh is not a better fit.
+ if curmesh == None or curmesh[1] < depth or curmesh[2] > depth:
+ actuator.mesh = object.name + newmesh[0]
+ cont.activate(actuator)
+
+ .. attribute:: mesh
+
+ :class:`MeshProxy` or the name of the mesh that will replace the current one.
+
+ Set to None to disable actuator.
+
+ :type: :class:`MeshProxy` or None if no mesh is set
+
+ .. attribute:: useDisplayMesh
+
+ when true the displayed mesh is replaced.
+
+ :type: boolean
+
+ .. attribute:: usePhysicsMesh
+
+ when true the physics mesh is replaced.
+
+ :type: boolean
+
+ .. method:: instantReplaceMesh()
+
+ Immediately replace mesh without delay.
+
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
new file mode 100644
index 00000000000..75630ae4d26
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
@@ -0,0 +1,172 @@
+KX_Scene(PyObjectPlus)
+======================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: KX_Scene(PyObjectPlus)
+
+ An active scene that gives access to objects, cameras, lights and scene attributes.
+
+ The activity culling stuff is supposed to disable logic bricks when their owner gets too far
+ from the active camera. It was taken from some code lurking at the back of KX_Scene - who knows
+ what it does!
+
+ .. code-block:: python
+
+ from bge import logic
+
+ # get the scene
+ scene = logic.getCurrentScene()
+
+ # print all the objects in the scene
+ for object in scene.objects:
+ print(object.name)
+
+ # get an object named 'Cube'
+ object = scene.objects["Cube"]
+
+ # get the first object in the scene.
+ object = scene.objects[0]
+
+ .. code-block:: python
+
+ # Get the depth of an object in the camera view.
+ from bge import logic
+
+ object = logic.getCurrentController().owner
+ cam = logic.getCurrentScene().active_camera
+
+ # Depth is negative and decreasing further from the camera
+ depth = object.position[0]*cam.world_to_camera[2][0] + object.position[1]*cam.world_to_camera[2][1] + object.position[2]*cam.world_to_camera[2][2] + cam.world_to_camera[2][3]
+
+ @bug: All attributes are read only at the moment.
+
+ .. attribute:: name
+
+ The scene's name, (read-only).
+
+ :type: string
+
+ .. attribute:: objects
+
+ A list of objects in the scene, (read-only).
+
+ :type: :class:`CListValue` of :class:`KX_GameObject`
+
+ .. attribute:: objectsInactive
+
+ A list of objects on background layers (used for the addObject actuator), (read-only).
+
+ :type: :class:`CListValue` of :class:`KX_GameObject`
+
+ .. attribute:: lights
+
+ A list of lights in the scene, (read-only).
+
+ :type: :class:`CListValue` of :class:`KX_LightObject`
+
+ .. attribute:: cameras
+
+ A list of cameras in the scene, (read-only).
+
+ :type: :class:`CListValue` of :class:`KX_Camera`
+
+ .. attribute:: active_camera
+
+ The current active camera.
+
+ :type: :class:`KX_Camera`
+
+ .. note::
+
+ This can be set directly from python to avoid using the :class:`KX_SceneActuator`.
+
+ .. attribute:: suspended
+
+ True if the scene is suspended, (read-only).
+
+ :type: boolean
+
+ .. attribute:: activity_culling
+
+ True if the scene is activity culling.
+
+ :type: boolean
+
+ .. attribute:: activity_culling_radius
+
+ The distance outside which to do activity culling. Measured in manhattan distance.
+
+ :type: float
+
+ .. attribute:: dbvt_culling
+
+ True when Dynamic Bounding box Volume Tree is set (read-only).
+
+ :type: boolean
+
+ .. attribute:: pre_draw
+
+ A list of callables to be run before the render step.
+
+ :type: list
+
+ .. attribute:: post_draw
+
+ A list of callables to be run after the render step.
+
+ :type: list
+
+ .. attribute:: gravity
+
+ The scene gravity using the world x, y and z axis.
+
+ :type: list [fx, fy, fz]
+
+ .. method:: addObject(object, other, time=0)
+
+ Adds an object to the scene like the Add Object Actuator would.
+
+ :arg object: The object to add
+ :type object: :class:`KX_GameObject` or string
+ :arg other: The object's center to use when adding the object
+ :type other: :class:`KX_GameObject` or string
+ :arg time: The lifetime of the added object, in frames. A time of 0 means the object will last forever.
+ :type time: integer
+ :return: The newly added object.
+ :rtype: :class:`KX_GameObject`
+
+ .. method:: end()
+
+ Removes the scene from the game.
+
+ .. method:: restart()
+
+ Restarts the scene.
+
+ .. method:: replace(scene)
+
+ Replaces this scene with another one.
+
+ :arg scene: The name of the scene to replace this scene with.
+ :type scene: string
+
+ .. method:: suspend()
+
+ Suspends this scene.
+
+ .. method:: resume()
+
+ Resume this scene.
+
+ .. method:: get(key, default=None)
+
+ Return the value matching key, or the default value if its not found.
+ :return: The key value or a default.
+
+ .. method:: drawObstacleSimulation()
+
+ Draw debug visualization of obstacle simulation.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_SceneActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_SceneActuator.rst
new file mode 100644
index 00000000000..9d073ff5b19
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_SceneActuator.rst
@@ -0,0 +1,49 @@
+KX_SceneActuator(SCA_IActuator)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_SceneActuator(SCA_IActuator)
+
+ Scene Actuator logic brick.
+
+ .. warning::
+
+ Scene actuators that use a scene name will be ignored if at game start, the named scene doesn't exist or is empty
+
+ This will generate a warning in the console:
+
+ .. code-block:: none
+
+ Error: GameObject 'Name' has a SceneActuator 'ActuatorName' (SetScene) without scene
+
+ .. attribute:: scene
+
+ the name of the scene to change to/overlay/underlay/remove/suspend/resume.
+
+ :type: string
+
+ .. attribute:: camera
+
+ the camera to change to.
+
+ :type: :class:`KX_Camera` on read, string or :class:`KX_Camera` on write
+
+ .. note::
+
+ When setting the attribute, you can use either a :class:`KX_Camera` or the name of the camera.
+
+ .. attribute:: useRestart
+
+ Set flag to True to restart the sene.
+
+ :type: boolean
+
+ .. attribute:: mode
+
+ The mode of the actuator.
+
+ :type: integer from 0 to 5.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_SoundActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_SoundActuator.rst
new file mode 100644
index 00000000000..aa85bd663b8
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_SoundActuator.rst
@@ -0,0 +1,115 @@
+KX_SoundActuator(SCA_IActuator)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_SoundActuator(SCA_IActuator)
+
+ Sound Actuator.
+
+ The :data:`startSound`, :data:`pauseSound` and :data:`stopSound` do not require the actuator to be activated - they act instantly provided that the actuator has been activated once at least.
+
+ .. attribute:: volume
+
+ The volume (gain) of the sound.
+
+ :type: float
+
+ .. attribute:: time
+
+ The current position in the audio stream (in seconds).
+
+ :type: float
+
+ .. attribute:: pitch
+
+ The pitch of the sound.
+
+ :type: float
+
+ .. attribute:: mode
+
+ The operation mode of the actuator. Can be one of :ref:`these constants<logic-sound-actuator>`
+
+ :type: integer
+
+ .. attribute:: sound
+
+ The sound the actuator should play.
+
+ :type: Audaspace factory
+
+ .. attribute:: is3D
+
+ Whether or not the actuator should be using 3D sound. (read-only)
+
+ :type: boolean
+
+ .. attribute:: volume_maximum
+
+ The maximum gain of the sound, no matter how near it is.
+
+ :type: float
+
+ .. attribute:: volume_minimum
+
+ The minimum gain of the sound, no matter how far it is away.
+
+ :type: float
+
+ .. attribute:: distance_reference
+
+ The distance where the sound has a gain of 1.0.
+
+ :type: float
+
+ .. attribute:: distance_maximum
+
+ The maximum distance at which you can hear the sound.
+
+ :type: float
+
+ .. attribute:: attenuation
+
+ The influence factor on volume depending on distance.
+
+ :type: float
+
+ .. attribute:: cone_angle_inner
+
+ The angle of the inner cone.
+
+ :type: float
+
+ .. attribute:: cone_angle_outer
+
+ The angle of the outer cone.
+
+ :type: float
+
+ .. attribute:: cone_volume_outer
+
+ The gain outside the outer cone (the gain in the outer cone will be interpolated between this value and the normal gain in the inner cone).
+
+ :type: float
+
+ .. method:: startSound()
+
+ Starts the sound.
+
+ :return: None
+
+ .. method:: pauseSound()
+
+ Pauses the sound.
+
+ :return: None
+
+ .. method:: stopSound()
+
+ Stops the sound.
+
+ :return: None
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_StateActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_StateActuator.rst
new file mode 100644
index 00000000000..c9d08457cc6
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_StateActuator.rst
@@ -0,0 +1,29 @@
+KX_StateActuator(SCA_IActuator)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_StateActuator(SCA_IActuator)
+
+ State actuator changes the state mask of parent object.
+
+ .. attribute:: operation
+
+ Type of bit operation to be applied on object state mask.
+
+ You can use one of :ref:`these constants <state-actuator-operation>`
+
+ :type: integer
+
+ .. attribute:: mask
+
+ Value that defines the bits that will be modified by the operation.
+
+ The bits that are 1 in the mask will be updated in the object state.
+
+ The bits that are 0 are will be left unmodified expect for the Copy operation which copies the mask to the object state.
+
+ :type: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_SteeringActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_SteeringActuator.rst
new file mode 100644
index 00000000000..f0ce248f069
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_SteeringActuator.rst
@@ -0,0 +1,71 @@
+KX_SteeringActuator(SCA_IActuator)
+==================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_SteeringActuator(SCA_IActuator)
+
+ Steering Actuator for navigation.
+
+ .. attribute:: behavior
+
+ The steering behavior to use.
+
+ :type: one of :ref:`these constants <logic-steering-actuator>`
+
+ .. attribute:: velocity
+
+ Velocity magnitude
+
+ :type: float
+
+ .. attribute:: acceleration
+
+ Max acceleration
+
+ :type: float
+
+ .. attribute:: turnspeed
+
+ Max turn speed
+
+ :type: float
+
+ .. attribute:: distance
+
+ Relax distance
+
+ :type: float
+
+ .. attribute:: target
+
+ Target object
+
+ :type: :class:`KX_GameObject`
+
+ .. attribute:: navmesh
+
+ Navigation mesh
+
+ :type: :class:`KX_GameObject`
+
+ .. attribute:: selfterminated
+
+ Terminate when target is reached
+
+ :type: boolean
+
+ .. attribute:: enableVisualization
+
+ Enable debug visualization
+
+ :type: boolean
+
+ .. attribute:: pathUpdatePeriod
+
+ Path update period
+
+ :type: int
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_TouchSensor.rst b/doc/python_api/rst/bge_types/bge.types.KX_TouchSensor.rst
new file mode 100644
index 00000000000..fd8f319f6f3
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_TouchSensor.rst
@@ -0,0 +1,41 @@
+KX_TouchSensor(SCA_ISensor)
+===========================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: KX_TouchSensor(SCA_ISensor)
+
+ Touch sensor detects collisions between objects.
+
+ .. attribute:: propName
+
+ The property or material to collide with.
+
+ :type: string
+
+ .. attribute:: useMaterial
+
+ Determines if the sensor is looking for a property or material. KX_True = Find material; KX_False = Find property.
+
+ :type: boolean
+
+ .. attribute:: usePulseCollision
+
+ When enabled, changes to the set of colliding objects generate a pulse.
+
+ :type: boolean
+
+ .. attribute:: hitObject
+
+ The last collided object. (read-only).
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: hitObjectList
+
+ A list of colliding objects. (read-only).
+
+ :type: :class:`CListValue` of :class:`KX_GameObject`
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst
new file mode 100644
index 00000000000..070243c6a05
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst
@@ -0,0 +1,39 @@
+KX_TrackToActuator(SCA_IActuator)
+=================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_TrackToActuator(SCA_IActuator)
+
+ Edit Object actuator in Track To mode.
+
+ .. warning::
+
+ Track To Actuators will be ignored if at game start, the object to track to is invalid.
+
+ This will generate a warning in the console:
+
+ .. code-block:: none
+
+ GameObject 'Name' no object in EditObjectActuator 'ActuatorName'
+
+ .. attribute:: object
+
+ the object this actuator tracks.
+
+ :type: :class:`KX_GameObject` or None
+
+ .. attribute:: time
+
+ the time in frames with which to delay the tracking motion.
+
+ :type: integer
+
+ .. attribute:: use3D
+
+ the tracking motion to use 3D.
+
+ :type: boolean
+
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
new file mode 100644
index 00000000000..9340d33f8a9
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst
@@ -0,0 +1,161 @@
+KX_VehicleWrapper(PyObjectPlus)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: KX_VehicleWrapper(PyObjectPlus)
+
+ KX_VehicleWrapper
+
+ TODO - description
+
+ .. method:: addWheel(wheel, attachPos, attachDir, 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 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.
+ :type axleDir: vector of 3 floats
+ :arg suspensionRestLength: TODO - Description
+ :type suspensionRestLength: float
+ :arg wheelRadius: The size of the wheel.
+ :type wheelRadius: float
+
+ .. method:: applyBraking(force, wheelIndex)
+
+ Apply a braking force to the specified wheel
+
+ :arg force: the brake force
+ :type force: float
+
+ :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
+
+ :arg force: the engine force
+ :type force: float
+
+ :arg wheelIndex: index of the wheel where the force needs to be applied
+ :type wheelIndex: integer
+
+ .. method:: getConstraintId()
+
+ Get the constraint ID
+
+ :return: the constraint id
+ :rtype: integer
+
+ .. method:: getConstraintType()
+
+ Returns the constraint type.
+
+ :return: constraint type
+ :rtype: integer
+
+ .. method:: getNumWheels()
+
+ Returns the number of wheels.
+
+ :return: the number of wheels for this vehicle
+ :rtype: integer
+
+ .. method:: getWheelOrientationQuaternion(wheelIndex)
+
+ Returns the wheel orientation as a quaternion.
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
+ :return: TODO Description
+ :rtype: TODO - type should be quat as per method name but from the code it looks like a matrix
+
+ .. method:: getWheelPosition(wheelIndex)
+
+ Returns the position of the specified wheel
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+ :return: position vector
+ :rtype: list[x, y, z]
+
+ .. method:: getWheelRotation(wheelIndex)
+
+ Returns the rotation of the specified wheel
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
+ :return: the wheel rotation
+ :rtype: float
+
+ .. method:: setRollInfluence(rollInfluece, wheelIndex)
+
+ Set the specified wheel's roll influence.
+ The higher the roll influence the more the vehicle will tend to roll over in corners.
+
+ :arg rollInfluece: the wheel roll influence
+ :type rollInfluece: float
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
+ .. method:: setSteeringValue(steering, wheelIndex)
+
+ Set the specified wheel's steering
+
+ :arg steering: the wheel steering
+ :type steering: float
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
+ .. method:: setSuspensionCompression(compression, wheelIndex)
+
+ Set the specified wheel's compression
+
+ :arg compression: the wheel compression
+ :type compression: float
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
+ .. method:: setSuspensionDamping(damping, wheelIndex)
+
+ Set the specified wheel's damping
+
+ :arg damping: the wheel damping
+ :type damping: float
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
+ .. method:: setSuspensionStiffness(stiffness, wheelIndex)
+
+ Set the specified wheel's stiffness
+
+ :arg stiffness: the wheel stiffness
+ :type stiffness: float
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
+ .. method:: setTyreFriction(friction, wheelIndex)
+
+ Set the specified wheel's tyre friction
+
+ :arg friction: the tyre friction
+ :type friction: float
+
+ :arg wheelIndex: the wheel index
+ :type wheelIndex: integer
+
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
new file mode 100644
index 00000000000..9c0d1169d49
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst
@@ -0,0 +1,209 @@
+KX_VertexProxy(SCA_IObject)
+===========================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IObject`
+
+.. class:: KX_VertexProxy(SCA_IObject)
+
+ A vertex holds position, UV, color and normal information.
+
+ Note:
+ The physics simulation is NOT currently updated - physics will not respond
+ to changes in the vertex position.
+
+ .. attribute:: XYZ
+
+ The position of the vertex.
+
+ :type: list [x, y, z]
+
+ .. attribute:: UV
+
+ The texture coordinates of the vertex.
+
+ :type: list [u, v]
+
+ .. attribute:: normal
+
+ The normal of the vertex.
+
+ :type: list [nx, ny, nz]
+
+ .. attribute:: color
+
+ The color of the vertex.
+
+ :type: list [r, g, b, a]
+
+ Black = [0.0, 0.0, 0.0, 1.0], White = [1.0, 1.0, 1.0, 1.0]
+
+ .. attribute:: x
+
+ The x coordinate of the vertex.
+
+ :type: float
+
+ .. attribute:: y
+
+ The y coordinate of the vertex.
+
+ :type: float
+
+ .. attribute:: z
+
+ The z coordinate of the vertex.
+
+ :type: float
+
+ .. attribute:: u
+
+ The u texture coordinate of the vertex.
+
+ :type: float
+
+ .. attribute:: v
+
+ The v texture coordinate of the vertex.
+
+ :type: float
+
+ .. attribute:: u2
+
+ The second u texture coordinate of the vertex.
+
+ :type: float
+
+ .. attribute:: v2
+
+ The second v texture coordinate of the vertex.
+
+ :type: float
+
+ .. attribute:: r
+
+ The red component of the vertex color. 0.0 <= r <= 1.0.
+
+ :type: float
+
+ .. attribute:: g
+
+ The green component of the vertex color. 0.0 <= g <= 1.0.
+
+ :type: float
+
+ .. attribute:: b
+
+ The blue component of the vertex color. 0.0 <= b <= 1.0.
+
+ :type: float
+
+ .. attribute:: a
+
+ The alpha component of the vertex color. 0.0 <= a <= 1.0.
+
+ :type: float
+
+ .. method:: getXYZ()
+
+ Gets the position of this vertex.
+
+ :return: this vertexes position in local coordinates.
+ :rtype: list [x, y, z]
+
+ .. method:: setXYZ(pos)
+
+ Sets the position of this vertex.
+
+ :type: list [x, y, z]
+
+ :arg pos: the new position for this vertex in local coordinates.
+
+ .. method:: getUV()
+
+ Gets the UV (texture) coordinates of this vertex.
+
+ :return: this vertexes UV (texture) coordinates.
+ :rtype: list [u, v]
+
+ .. method:: setUV(uv)
+
+ Sets the UV (texture) coordinates of this vertex.
+
+ :type: list [u, v]
+
+ .. method:: getUV2()
+
+ Gets the 2nd UV (texture) coordinates of this vertex.
+
+ :return: this vertexes UV (texture) coordinates.
+ :rtype: list [u, v]
+
+ .. method:: setUV2(uv, unit)
+
+ Sets the 2nd UV (texture) coordinates of this vertex.
+
+ :type: list [u, v]
+
+ :arg unit: optional argument, FLAT==1, SECOND_UV==2, defaults to SECOND_UV
+ :arg unit: integer
+
+ .. method:: getRGBA()
+
+ Gets the color of this vertex.
+
+ The color is represented as four bytes packed into an integer value. The color is
+ packed as RGBA.
+
+ Since Python offers no way to get each byte without shifting, you must use the struct module to
+ access color in an machine independent way.
+
+ Because of this, it is suggested you use the r, g, b and a attributes or the color attribute instead.
+
+ .. code-block:: python
+
+ import struct;
+ col = struct.unpack('4B', struct.pack('I', v.getRGBA()))
+ # col = (r, g, b, a)
+ # black = ( 0, 0, 0, 255)
+ # white = (255, 255, 255, 255)
+
+ :return: packed color. 4 byte integer with one byte per color channel in RGBA format.
+ :rtype: integer
+
+ .. method:: setRGBA(col)
+
+ Sets the color of this vertex.
+
+ See getRGBA() for the format of col, and its relevant problems. Use the r, g, b and a attributes
+ or the color attribute instead.
+
+ setRGBA() also accepts a four component list as argument col. The list represents the color as [r, g, b, a]
+ with black = [0.0, 0.0, 0.0, 1.0] and white = [1.0, 1.0, 1.0, 1.0]
+
+ .. code-block:: python
+
+ v.setRGBA(0xff0000ff) # Red
+ v.setRGBA(0xff00ff00) # Green on little endian, transparent purple on big endian
+ v.setRGBA([1.0, 0.0, 0.0, 1.0]) # Red
+ v.setRGBA([0.0, 1.0, 0.0, 1.0]) # Green on all platforms.
+
+ :arg col: the new color of this vertex in packed RGBA format.
+ :type col: integer or list [r, g, b, a]
+
+ .. method:: getNormal()
+
+ Gets the normal vector of this vertex.
+
+ :return: normalized normal vector.
+ :rtype: list [nx, ny, nz]
+
+ .. method:: setNormal(normal)
+
+ Sets the normal vector of this vertex.
+
+ :type: sequence of floats [r, g, b]
+
+ :arg normal: the new normal of this vertex.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_VisibilityActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_VisibilityActuator.rst
new file mode 100644
index 00000000000..4beb6539e0e
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.KX_VisibilityActuator.rst
@@ -0,0 +1,29 @@
+KX_VisibilityActuator(SCA_IActuator)
+====================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: KX_VisibilityActuator(SCA_IActuator)
+
+ Visibility Actuator.
+
+ .. attribute:: visibility
+
+ whether the actuator makes its parent object visible or invisible.
+
+ :type: boolean
+
+ .. attribute:: useOcclusion
+
+ whether the actuator makes its parent object an occluder or not.
+
+ :type: boolean
+
+ .. attribute:: useRecursion
+
+ whether the visibility/occlusion should be propagated to all children of the object.
+
+ :type: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.PyObjectPlus.rst b/doc/python_api/rst/bge_types/bge.types.PyObjectPlus.rst
new file mode 100644
index 00000000000..e035f457a96
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.PyObjectPlus.rst
@@ -0,0 +1,21 @@
+PyObjectPlus
+============
+
+.. module:: bge.types
+
+.. class:: PyObjectPlus
+
+ PyObjectPlus base class of most other types in the Game Engine.
+
+ .. attribute:: invalid
+
+ Test if the object has been freed by the game engine and is no longer valid.
+
+ Normally this is not a problem but when storing game engine data in the GameLogic module,
+ KX_Scenes or other KX_GameObjects its possible to hold a reference to invalid data.
+ Calling an attribute or method on an invalid object will raise a SystemError.
+
+ The invalid attribute allows testing for this case without exception handling.
+
+ :type: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_2DFilterActuator.rst b/doc/python_api/rst/bge_types/bge.types.SCA_2DFilterActuator.rst
new file mode 100644
index 00000000000..291ee8426cf
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_2DFilterActuator.rst
@@ -0,0 +1,49 @@
+SCA_2DFilterActuator(SCA_IActuator)
+===================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: SCA_2DFilterActuator(SCA_IActuator)
+
+ Create, enable and disable 2D filters
+
+ The following properties don't have an immediate effect.
+ You must active the actuator to get the result.
+ The actuator is not persistent: it automatically stops itself after setting up the filter
+ but the filter remains active. To stop a filter you must activate the actuator with 'type'
+ set to :data:`~bge.logic.RAS_2DFILTER_DISABLED` or :data:`~bge.logic.RAS_2DFILTER_NOFILTER`.
+
+ .. attribute:: shaderText
+
+ shader source code for custom shader.
+
+ :type: string
+
+ .. attribute:: disableMotionBlur
+
+ action on motion blur: 0=enable, 1=disable.
+
+ :type: integer
+
+ .. attribute:: mode
+
+ Type of 2D filter, use one of :ref:`these constants <Two-D-FilterActuator-mode>`
+
+ :type: integer
+
+ .. attribute:: passNumber
+
+ order number of filter in the stack of 2D filters. Filters are executed in increasing order of passNb.
+
+ Only be one filter can be defined per passNb.
+
+ :type: integer (0-100)
+
+ .. attribute:: value
+
+ argument for motion blur filter.
+
+ :type: float (0.0-100.0)
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_ANDController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_ANDController.rst
new file mode 100644
index 00000000000..0942f715231
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_ANDController.rst
@@ -0,0 +1,13 @@
+SCA_ANDController(SCA_IController)
+==================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IController`
+
+.. class:: SCA_ANDController(SCA_IController)
+
+ An AND controller activates only when all linked sensors are activated.
+
+ There are no special python methods for this controller.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_ActuatorSensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_ActuatorSensor.rst
new file mode 100644
index 00000000000..54916389298
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_ActuatorSensor.rst
@@ -0,0 +1,19 @@
+SCA_ActuatorSensor(SCA_ISensor)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_ActuatorSensor(SCA_ISensor)
+
+ Actuator sensor detect change in actuator state of the parent object.
+ It generates a positive pulse if the corresponding actuator is activated
+ and a negative pulse if the actuator is deactivated.
+
+ .. attribute:: actuator
+
+ the name of the actuator that the sensor is monitoring.
+
+ :type: string
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_AlwaysSensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_AlwaysSensor.rst
new file mode 100644
index 00000000000..a217b114d62
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_AlwaysSensor.rst
@@ -0,0 +1,11 @@
+SCA_AlwaysSensor(SCA_ISensor)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_AlwaysSensor(SCA_ISensor)
+
+ This sensor is always activated.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_DelaySensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_DelaySensor.rst
new file mode 100644
index 00000000000..ce2b8e52eec
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_DelaySensor.rst
@@ -0,0 +1,39 @@
+SCA_DelaySensor(SCA_ISensor)
+============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_DelaySensor(SCA_ISensor)
+
+ The Delay sensor generates positive and negative triggers at precise time,
+ expressed in number of frames. The delay parameter defines the length of the initial OFF period. A positive trigger is generated at the end of this period.
+
+ The duration parameter defines the length of the ON period following the OFF period.
+ There is a negative trigger at the end of the ON period. If duration is 0, the sensor stays ON and there is no negative trigger.
+
+ The sensor runs the OFF-ON cycle once unless the repeat option is set: the OFF-ON cycle repeats indefinately (or the OFF cycle if duration is 0).
+
+ Use :class:`SCA_ISensor.reset` at any time to restart sensor.
+
+ .. attribute:: delay
+
+ length of the initial OFF period as number of frame, 0 for immediate trigger.
+
+ :type: integer.
+
+ .. attribute:: duration
+
+ length of the ON period in number of frame after the initial OFF period.
+
+ If duration is greater than 0, a negative trigger is sent at the end of the ON pulse.
+
+ :type: integer
+
+ .. attribute:: repeat
+
+ 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once.
+
+ :type: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_IActuator.rst b/doc/python_api/rst/bge_types/bge.types.SCA_IActuator.rst
new file mode 100644
index 00000000000..1432d5166ef
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_IActuator.rst
@@ -0,0 +1,11 @@
+SCA_IActuator(SCA_ILogicBrick)
+==============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ILogicBrick`
+
+.. class:: SCA_IActuator(SCA_ILogicBrick)
+
+ Base class for all actuator logic bricks.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_IController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_IController.rst
new file mode 100644
index 00000000000..5eb225ed329
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_IController.rst
@@ -0,0 +1,55 @@
+SCA_IController(SCA_ILogicBrick)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ILogicBrick`
+
+.. class:: SCA_IController(SCA_ILogicBrick)
+
+ Base class for all controller logic bricks.
+
+ .. attribute:: state
+
+ The controllers state bitmask. This can be used with the GameObject's state to test if the controller is active.
+
+ :type: int bitmask
+
+ .. attribute:: sensors
+
+ A list of sensors linked to this controller.
+
+ :type: sequence supporting index/string lookups and iteration.
+
+ .. note::
+
+ The sensors are not necessarily owned by the same object.
+
+ .. note::
+
+ When objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
+
+ .. attribute:: actuators
+
+ A list of actuators linked to this controller.
+
+ :type: sequence supporting index/string lookups and iteration.
+
+ .. note::
+
+ The sensors are not necessarily owned by the same object.
+
+ .. note::
+
+ When objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
+
+ .. attribute:: useHighPriority
+
+ When set the controller executes always before all other controllers that dont have this set.
+
+ :type: boolen
+
+ .. note::
+
+ Order of execution between high priority controllers is not guaranteed.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_ILogicBrick.rst b/doc/python_api/rst/bge_types/bge.types.SCA_ILogicBrick.rst
new file mode 100644
index 00000000000..5ed44c4bb38
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_ILogicBrick.rst
@@ -0,0 +1,29 @@
+SCA_ILogicBrick(CValue)
+=======================
+
+.. module:: bge.types
+
+base class --- :class:`CValue`
+
+.. class:: SCA_ILogicBrick(CValue)
+
+ Base class for all logic bricks.
+
+ .. attribute:: executePriority
+
+ This determines the order controllers are evaluated, and actuators are activated (lower priority is executed first).
+
+ :type: executePriority: int
+
+ .. attribute:: owner
+
+ The game object this logic brick is attached to (read-only).
+
+ :type: :class:`KX_GameObject` or None in exceptional cases.
+
+ .. attribute:: name
+
+ The name of this logic brick (read-only).
+
+ :type: string
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_IObject.rst b/doc/python_api/rst/bge_types/bge.types.SCA_IObject.rst
new file mode 100644
index 00000000000..22065944542
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_IObject.rst
@@ -0,0 +1,11 @@
+SCA_IObject(CValue)
+===================
+
+.. module:: bge.types
+
+base class --- :class:`CValue`
+
+.. class:: SCA_IObject(CValue)
+
+ This class has no python functions
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_ISensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_ISensor.rst
new file mode 100644
index 00000000000..9efd2e2d63a
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_ISensor.rst
@@ -0,0 +1,95 @@
+SCA_ISensor(SCA_ILogicBrick)
+============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ILogicBrick`
+
+.. class:: SCA_ISensor(SCA_ILogicBrick)
+
+ Base class for all sensor logic bricks.
+
+ .. attribute:: usePosPulseMode
+
+ Flag to turn positive pulse mode on and off.
+
+ :type: boolean
+
+ .. attribute:: useNegPulseMode
+
+ Flag to turn negative pulse mode on and off.
+
+ :type: boolean
+
+ .. attribute:: frequency
+
+ The frequency for pulse mode sensors.
+
+ :type: integer
+
+ .. attribute:: level
+
+ level Option whether to detect level or edge transition when entering a state.
+ It makes a difference only in case of logic state transition (state actuator).
+ A level detector will immediately generate a pulse, negative or positive
+ depending on the sensor condition, as soon as the state is activated.
+ A edge detector will wait for a state change before generating a pulse.
+ note: mutually exclusive with :data:`tap`, enabling will disable :data:`tap`.
+
+ :type: boolean
+
+ .. attribute:: tap
+
+ When enabled only sensors that are just activated will send a positive event,
+ after this they will be detected as negative by the controllers.
+ This will make a key thats held act as if its only tapped for an instant.
+ note: mutually exclusive with :data:`level`, enabling will disable :data:`level`.
+
+ :type: boolean
+
+ .. attribute:: invert
+
+ Flag to set if this sensor activates on positive or negative events.
+
+ :type: boolean
+
+ .. attribute:: triggered
+
+ True if this sensor brick is in a positive state. (read-only).
+
+ :type: boolean
+
+ .. attribute:: positive
+
+ True if this sensor brick is in a positive state. (read-only).
+
+ :type: boolean
+
+ .. attribute:: pos_ticks
+
+ The number of ticks since the last positive pulse (read-only).
+
+ :type: int
+
+ .. attribute:: neg_ticks
+
+ The number of ticks since the last negative pulse (read-only).
+
+ :type: int
+
+ .. attribute:: status
+
+ The status of the sensor (read-only): can be one of :ref:`these constants<sensor-status>`.
+
+ :type: int
+
+ .. note::
+
+ This convenient attribute combines the values of triggered and positive attributes.
+
+ .. method:: reset()
+
+ Reset sensor internal state, effect depends on the type of sensor and settings.
+
+ The sensor is put in its initial state as if it was just activated.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_JoystickSensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_JoystickSensor.rst
new file mode 100644
index 00000000000..5b6628f60be
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_JoystickSensor.rst
@@ -0,0 +1,133 @@
+SCA_JoystickSensor(SCA_ISensor)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_JoystickSensor(SCA_ISensor)
+
+ This sensor detects player joystick events.
+
+ .. attribute:: axisValues
+
+ The state of the joysticks axis as a list of values :data:`numAxis` long. (read-only).
+
+ :type: list of ints.
+
+ Each specifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing.
+ The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls.
+
+ * left:[-32767, 0, ...]
+ * right:[32767, 0, ...]
+ * up:[0, -32767, ...]
+ * down:[0, 32767, ...]
+
+ .. attribute:: axisSingle
+
+ like :data:`axisValues` but returns a single axis value that is set by the sensor. (read-only).
+
+ :type: integer
+
+ .. note::
+
+ Only use this for "Single Axis" type sensors otherwise it will raise an error.
+
+ .. attribute:: hatValues
+
+ The state of the joysticks hats as a list of values :data:`numHats` long. (read-only).
+
+ :type: list of ints
+
+ Each specifying the direction of the hat from 1 to 12, 0 when inactive.
+
+ Hat directions are as follows...
+
+ * 0:None
+ * 1:Up
+ * 2:Right
+ * 4:Down
+ * 8:Left
+ * 3:Up - Right
+ * 6:Down - Right
+ * 12:Down - Left
+ * 9:Up - Left
+
+ .. attribute:: hatSingle
+
+ Like :data:`hatValues` but returns a single hat direction value that is set by the sensor. (read-only).
+
+ :type: integer
+
+ .. attribute:: numAxis
+
+ The number of axes for the joystick at this index. (read-only).
+
+ :type: integer
+
+ .. attribute:: numButtons
+
+ The number of buttons for the joystick at this index. (read-only).
+
+ :type: integer
+
+ .. attribute:: numHats
+
+ The number of hats for the joystick at this index. (read-only).
+
+ :type: integer
+
+ .. attribute:: connected
+
+ True if a joystick is connected at this joysticks index. (read-only).
+
+ :type: boolean
+
+ .. attribute:: index
+
+ The joystick index to use (from 0 to 7). The first joystick is always 0.
+
+ :type: integer
+
+ .. attribute:: threshold
+
+ Axis threshold. Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive.
+
+ :type: integer
+
+ .. attribute:: button
+
+ The button index the sensor reacts to (first button = 0). When the "All Events" toggle is set, this option has no effect.
+
+ :type: integer
+
+ .. attribute:: axis
+
+ The axis this sensor reacts to, as a list of two values [axisIndex, axisDirection]
+
+ * axisIndex: the axis index to use when detecting axis movement, 1=primary directional control, 2=secondary directional control.
+ * axisDirection: 0=right, 1=up, 2=left, 3=down.
+
+ :type: [integer, integer]
+
+ .. attribute:: hat
+
+ The hat the sensor reacts to, as a list of two values: [hatIndex, hatDirection]
+
+ * hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat (4 max).
+ * hatDirection: 1-12.
+
+ :type: [integer, integer]
+
+ .. method:: getButtonActiveList()
+
+ :return: A list containing the indicies of the currently pressed buttons.
+ :rtype: list
+
+ .. method:: getButtonStatus(buttonIndex)
+
+ :arg buttonIndex: the button index, 0=first button
+ :type buttonIndex: integer
+ :return: The current pressed state of the specified button.
+ :rtype: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_KeyboardSensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_KeyboardSensor.rst
new file mode 100644
index 00000000000..91613068ad0
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_KeyboardSensor.rst
@@ -0,0 +1,64 @@
+SCA_KeyboardSensor(SCA_ISensor)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_KeyboardSensor(SCA_ISensor)
+
+ A keyboard sensor detects player key presses.
+
+ See module :mod:`bge.events` for keycode values.
+
+ .. attribute:: key
+
+ The key code this sensor is looking for.
+
+ :type: keycode from :mod:`bge.events` module
+
+ .. attribute:: hold1
+
+ The key code for the first modifier this sensor is looking for.
+
+ :type: keycode from :mod:`bge.events` module
+
+ .. attribute:: hold2
+
+ The key code for the second modifier this sensor is looking for.
+
+ :type: keycode from :mod:`bge.events` module
+
+ .. attribute:: toggleProperty
+
+ The name of the property that indicates whether or not to log keystrokes as a string.
+
+ :type: string
+
+ .. attribute:: targetProperty
+
+ The name of the property that receives keystrokes in case in case a string is logged.
+
+ :type: string
+
+ .. attribute:: useAllKeys
+
+ Flag to determine whether or not to accept all keys.
+
+ :type: boolean
+
+ .. attribute:: events
+
+ a list of pressed keys that have either been pressed, or just released, or are active this frame. (read-only).
+
+ :type: list [[:ref:`keycode<keyboard-keys>`, :ref:`status<input-status>`], ...]
+
+ .. method:: getKeyStatus(keycode)
+
+ Get the status of a key.
+
+ :arg keycode: The code that represents the key you want to get the state of, use one of :ref:`these constants<keyboard-keys>`
+ :type keycode: integer
+ :return: The state of the given key, can be one of :ref:`these constants<input-status>`
+ :rtype: int
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_MouseSensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_MouseSensor.rst
new file mode 100644
index 00000000000..bbc695e4cbf
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_MouseSensor.rst
@@ -0,0 +1,39 @@
+SCA_MouseSensor(SCA_ISensor)
+============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_MouseSensor(SCA_ISensor)
+
+ Mouse Sensor logic brick.
+
+ .. attribute:: position
+
+ current [x, y] coordinates of the mouse, in frame coordinates (pixels).
+
+ :type: [integer, interger]
+
+ .. attribute:: mode
+
+ sensor mode.
+
+ :type: integer
+
+ * KX_MOUSESENSORMODE_LEFTBUTTON(1)
+ * KX_MOUSESENSORMODE_MIDDLEBUTTON(2)
+ * KX_MOUSESENSORMODE_RIGHTBUTTON(3)
+ * KX_MOUSESENSORMODE_WHEELUP(4)
+ * KX_MOUSESENSORMODE_WHEELDOWN(5)
+ * KX_MOUSESENSORMODE_MOVEMENT(6)
+
+ .. method:: getButtonStatus(button)
+
+ Get the mouse button status.
+
+ :arg button: The code that represents the key you want to get the state of, use one of :ref:`these constants<mouse-keys>`
+ :type button: int
+ :return: The state of the given key, can be one of :ref:`these constants<input-status>`
+ :rtype: int
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_NANDController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_NANDController.rst
new file mode 100644
index 00000000000..4bd67fb22ee
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_NANDController.rst
@@ -0,0 +1,13 @@
+SCA_NANDController(SCA_IController)
+===================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IController`
+
+.. class:: SCA_NANDController(SCA_IController)
+
+ An NAND controller activates when all linked sensors are not active.
+
+ There are no special python methods for this controller.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_NORController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_NORController.rst
new file mode 100644
index 00000000000..5a567c84ece
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_NORController.rst
@@ -0,0 +1,13 @@
+SCA_NORController(SCA_IController)
+==================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IController`
+
+.. class:: SCA_NORController(SCA_IController)
+
+ An NOR controller activates only when all linked sensors are de-activated.
+
+ There are no special python methods for this controller.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_ORController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_ORController.rst
new file mode 100644
index 00000000000..ed57b0dbaf2
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_ORController.rst
@@ -0,0 +1,13 @@
+SCA_ORController(SCA_IController)
+=================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IController`
+
+.. class:: SCA_ORController(SCA_IController)
+
+ An OR controller activates when any connected sensor activates.
+
+ There are no special python methods for this controller.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PropertyActuator.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PropertyActuator.rst
new file mode 100644
index 00000000000..36a4ea7fefe
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PropertyActuator.rst
@@ -0,0 +1,29 @@
+SCA_PropertyActuator(SCA_IActuator)
+===================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: SCA_PropertyActuator(SCA_IActuator)
+
+ Property Actuator
+
+ .. attribute:: propName
+
+ the property on which to operate.
+
+ :type: string
+
+ .. attribute:: value
+
+ the value with which the actuator operates.
+
+ :type: string
+
+ .. attribute:: mode
+
+ TODO - add constants to game logic dict!.
+
+ :type: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PropertySensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PropertySensor.rst
new file mode 100644
index 00000000000..3c41e4679db
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PropertySensor.rst
@@ -0,0 +1,41 @@
+SCA_PropertySensor(SCA_ISensor)
+===============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_PropertySensor(SCA_ISensor)
+
+ Activates when the game object property matches.
+
+ .. attribute:: mode
+
+ Type of check on the property. Can be one of :ref:`these constants <logic-property-sensor>`
+
+ :type: integer.
+
+ .. attribute:: propName
+
+ the property the sensor operates.
+
+ :type: string
+
+ .. attribute:: value
+
+ the value with which the sensor compares to the value of the property.
+
+ :type: string
+
+ .. attribute:: min
+
+ the minimum value of the range used to evaluate the property when in interval mode.
+
+ :type: string
+
+ .. attribute:: max
+
+ the maximum value of the range used to evaluate the property when in interval mode.
+
+ :type: string
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst
new file mode 100644
index 00000000000..a00e9c29ad4
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PythonController.rst
@@ -0,0 +1,48 @@
+SCA_PythonController(SCA_IController)
+=====================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IController`
+
+.. class:: SCA_PythonController(SCA_IController)
+
+ A Python controller uses a Python script to activate it's actuators,
+ based on it's sensors.
+
+ .. attribute:: script
+
+ The value of this variable depends on the execution methid.
+
+ * When 'Script' execution mode is set this value contains the entire python script as a single string (not the script name as you might expect) which can be modified to run different scripts.
+ * When 'Module' execution mode is set this value will contain a single line string - module name and function "module.func" or "package.modile.func" where the module names are python textblocks or external scripts.
+
+ :type: string
+
+ .. note::
+
+ Once this is set the script name given for warnings will remain unchanged.
+
+ .. attribute:: mode
+
+ the execution mode for this controller (read-only).
+
+ * Script: 0, Execite the :data:`script` as a python code.
+ * Module: 1, Execite the :data:`script` as a module and function.
+
+ :type: integer
+
+ .. method:: activate(actuator)
+
+ Activates an actuator attached to this controller.
+
+ :arg actuator: The actuator to operate on.
+ :type actuator: actuator or the actuator name as a string
+
+ .. method:: deactivate(actuator)
+
+ Deactivates an actuator attached to this controller.
+
+ :arg actuator: The actuator to operate on.
+ :type actuator: actuator or the actuator name as a string
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PythonJoystick.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PythonJoystick.rst
new file mode 100644
index 00000000000..2b97b5939e2
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PythonJoystick.rst
@@ -0,0 +1,75 @@
+SCA_PythonJoystick(PyObjectPlus)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: SCA_PythonJoystick(PyObjectPlus)
+
+ A Python interface to a joystick.
+
+ .. attribute:: name
+
+ The name assigned to the joystick by the operating system. (read-only)
+
+ :type: string
+
+ .. attribute:: activeButtons
+
+ A list of active button values. (read-only)
+
+ :type: list
+
+ .. attribute:: axisValues
+
+ The state of the joysticks axis as a list of values :data:`numAxis` long. (read-only).
+
+ :type: list of ints.
+
+ Each specifying the value of an axis between -1.0 and 1.0 depending on how far the axis is pushed, 0 for nothing.
+ The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls.
+
+ * left:[-1.0, 0.0, ...]
+ * right:[1.0, 0.0, ...]
+ * up:[0.0, -1.0, ...]
+ * down:[0.0, 1.0, ...]
+
+ .. attribute:: hatValues
+
+ The state of the joysticks hats as a list of values :data:`numHats` long. (read-only).
+
+ :type: list of ints
+
+ Each specifying the direction of the hat from 1 to 12, 0 when inactive.
+
+ Hat directions are as follows...
+
+ * 0:None
+ * 1:Up
+ * 2:Right
+ * 4:Down
+ * 8:Left
+ * 3:Up - Right
+ * 6:Down - Right
+ * 12:Down - Left
+ * 9:Up - Left
+
+ .. attribute:: numAxis
+
+ The number of axes for the joystick at this index. (read-only).
+
+ :type: integer
+
+ .. attribute:: numButtons
+
+ The number of buttons for the joystick at this index. (read-only).
+
+ :type: integer
+
+ .. attribute:: numHats
+
+ The number of hats for the joystick at this index. (read-only).
+
+ :type: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst
new file mode 100644
index 00000000000..6cfef2f80f1
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PythonKeyboard.rst
@@ -0,0 +1,37 @@
+SCA_PythonKeyboard(PyObjectPlus)
+================================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: SCA_PythonKeyboard(PyObjectPlus)
+
+ The current keyboard.
+
+ .. attribute:: events
+
+ A dictionary containing the status of each keyboard event or key. (read-only).
+
+ :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
+
+ .. attribute:: active_events
+
+ A dictionary containing the status of only the active keyboard events or keys. (read-only).
+
+ :type: dictionary {:ref:`keycode<keyboard-keys>`::ref:`status<input-status>`, ...}
+
+
+ .. function:: getClipboard()
+
+ Gets the clipboard text.
+
+ :rtype: string
+
+ .. function:: setClipboard(text)
+
+ Sets the clipboard text.
+
+ :arg text: New clipboard text
+ :type text: string
+
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
new file mode 100644
index 00000000000..b1c6e5d1487
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PythonMouse.rst
@@ -0,0 +1,35 @@
+SCA_PythonMouse(PyObjectPlus)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`PyObjectPlus`
+
+.. class:: SCA_PythonMouse(PyObjectPlus)
+
+ The current mouse.
+
+ .. attribute:: events
+
+ a dictionary containing the status of each mouse event. (read-only).
+
+ :type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
+
+ .. attribute:: active_events
+
+ a dictionary containing the status of only the active mouse events. (read-only).
+
+ :type: dictionary {:ref:`keycode<mouse-keys>`::ref:`status<input-status>`, ...}
+
+ .. attribute:: position
+
+ The normalized x and y position of the mouse cursor.
+
+ :type: list [x, y]
+
+ .. attribute:: visible
+
+ The visibility of the mouse cursor.
+
+ :type: boolean
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_RandomActuator.rst b/doc/python_api/rst/bge_types/bge.types.SCA_RandomActuator.rst
new file mode 100644
index 00000000000..68357229262
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_RandomActuator.rst
@@ -0,0 +1,127 @@
+SCA_RandomActuator(SCA_IActuator)
+=================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IActuator`
+
+.. class:: SCA_RandomActuator(SCA_IActuator)
+
+ Random Actuator
+
+ .. attribute:: seed
+
+ Seed of the random number generator.
+
+ :type: integer.
+
+ Equal seeds produce equal series. If the seed is 0, the generator will produce the same value on every call.
+
+ .. attribute:: para1
+
+ the first parameter of the active distribution.
+
+ :type: float, read-only.
+
+ Refer to the documentation of the generator types for the meaning of this value.
+
+ .. attribute:: para2
+
+ the second parameter of the active distribution.
+
+ :type: float, read-only
+
+ Refer to the documentation of the generator types for the meaning of this value.
+
+ .. attribute:: distribution
+
+ Distribution type. (read-only). Can be one of :ref:`these constants <logic-random-distributions>`
+
+ :type: integer
+
+ .. attribute:: propName
+
+ the name of the property to set with the random value.
+
+ :type: string
+
+ If the generator and property types do not match, the assignment is ignored.
+
+ .. method:: setBoolConst(value)
+
+ Sets this generator to produce a constant boolean value.
+
+ :arg value: The value to return.
+ :type value: boolean
+
+ .. method:: setBoolUniform()
+
+ Sets this generator to produce a uniform boolean distribution.
+
+ The generator will generate True or False with 50% chance.
+
+ .. method:: setBoolBernouilli(value)
+
+ Sets this generator to produce a Bernouilli distribution.
+
+ :arg value: Specifies the proportion of False values to produce.
+
+ * 0.0: Always generate True
+ * 1.0: Always generate False
+ :type value: float
+
+ .. method:: setIntConst(value)
+
+ Sets this generator to always produce the given value.
+
+ :arg value: the value this generator produces.
+ :type value: integer
+
+ .. method:: setIntUniform(lower_bound, upper_bound)
+
+ Sets this generator to produce a random value between the given lower and
+ upper bounds (inclusive).
+
+ :type lower_bound: integer
+ :type upper_bound: integer
+
+ .. method:: setIntPoisson(value)
+
+ Generate a Poisson-distributed number.
+
+ This performs a series of Bernouilli tests with parameter value.
+ It returns the number of tries needed to achieve succes.
+
+ :type value: float
+
+ .. method:: setFloatConst(value)
+
+ Always generate the given value.
+
+ :type value: float
+
+ .. method:: setFloatUniform(lower_bound, upper_bound)
+
+ Generates a random float between lower_bound and upper_bound with a
+ uniform distribution.
+
+ :type lower_bound: float
+ :type upper_bound: float
+
+ .. method:: setFloatNormal(mean, standard_deviation)
+
+ Generates a random float from the given normal distribution.
+
+ :arg mean: The mean (average) value of the generated numbers
+ :type mean: float
+ :arg standard_deviation: The standard deviation of the generated numbers.
+ :type standard_deviation: float
+
+ .. method:: setFloatNegativeExponential(half_life)
+
+ Generate negative-exponentially distributed numbers.
+
+ The half-life 'time' is characterized by half_life.
+
+ :type half_life: float
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_RandomSensor.rst b/doc/python_api/rst/bge_types/bge.types.SCA_RandomSensor.rst
new file mode 100644
index 00000000000..05e61ccf118
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_RandomSensor.rst
@@ -0,0 +1,23 @@
+SCA_RandomSensor(SCA_ISensor)
+=============================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_ISensor`
+
+.. class:: SCA_RandomSensor(SCA_ISensor)
+
+ This sensor activates randomly.
+
+ .. attribute:: lastDraw
+
+ The seed of the random number generator.
+
+ :type: integer
+
+ .. attribute:: seed
+
+ The seed of the random number generator.
+
+ :type: integer
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_XNORController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_XNORController.rst
new file mode 100644
index 00000000000..d0235f29a20
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_XNORController.rst
@@ -0,0 +1,13 @@
+SCA_XNORController(SCA_IController)
+===================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IController`
+
+.. class:: SCA_XNORController(SCA_IController)
+
+ An XNOR controller activates when all linked sensors are the same (activated or inative).
+
+ There are no special python methods for this controller.
+
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_XORController.rst b/doc/python_api/rst/bge_types/bge.types.SCA_XORController.rst
new file mode 100644
index 00000000000..98ccf142f63
--- /dev/null
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_XORController.rst
@@ -0,0 +1,13 @@
+SCA_XORController(SCA_IController)
+==================================
+
+.. module:: bge.types
+
+base class --- :class:`SCA_IController`
+
+.. class:: SCA_XORController(SCA_IController)
+
+ An XOR controller activates when there is the input is mixed, but not when all are on or off.
+
+ There are no special python methods for this controller.
+
diff --git a/doc/python_api/rst/change_log.rst b/doc/python_api/rst/change_log.rst
index c1f3c2e4267..7579070c258 100644
--- a/doc/python_api/rst/change_log.rst
+++ b/doc/python_api/rst/change_log.rst
@@ -3896,3 +3896,433 @@ Added
^^^^^
* :class:`bpy.types.LatticePoint.select`
+
+
+2.64 to 2.65
+============
+
+bpy.types.SmokeDomainSettings
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.SmokeDomainSettings.adapt_margin`
+* :class:`bpy.types.SmokeDomainSettings.adapt_threshold`
+* :class:`bpy.types.SmokeDomainSettings.additional_res`
+* :class:`bpy.types.SmokeDomainSettings.burning_rate`
+* :class:`bpy.types.SmokeDomainSettings.flame_ignition`
+* :class:`bpy.types.SmokeDomainSettings.flame_max_temp`
+* :class:`bpy.types.SmokeDomainSettings.flame_smoke`
+* :class:`bpy.types.SmokeDomainSettings.flame_smoke_color`
+* :class:`bpy.types.SmokeDomainSettings.flame_vorticity`
+* :class:`bpy.types.SmokeDomainSettings.use_adaptive_domain`
+
+Removed
+^^^^^^^
+
+* **scale**
+
+bpy.types.BezierSplinePoint
+---------------------------
+
+Renamed
+^^^^^^^
+
+* **weight** -> :class:`bpy.types.BezierSplinePoint.weight_softbody`
+
+bpy.types.Material
+------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Material.use_light_group_local`
+
+bpy.types.Curve
+---------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Curve.use_map_taper`
+
+bpy.types.EffectorWeights
+-------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.EffectorWeights.smokeflow`
+
+bpy.types.FieldSettings
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.FieldSettings.source_object`
+* :class:`bpy.types.FieldSettings.use_smoke_density`
+
+bpy.types.GPencilFrame
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GPencilFrame.clear`
+
+bpy.types.UserPreferencesView
+-----------------------------
+
+Renamed
+^^^^^^^
+
+* **quit_dialog** -> :class:`bpy.types.UserPreferencesView.use_quit_dialog`
+
+bpy.types.GreasePencilLayers
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GreasePencilLayers.new`
+* :class:`bpy.types.GreasePencilLayers.remove`
+
+bpy.types.PointCache
+--------------------
+
+Removed
+^^^^^^^
+
+* **use_quick_cache**
+
+bpy.types.KinematicConstraint
+-----------------------------
+
+Removed
+^^^^^^^
+
+* **use_target**
+
+bpy.types.DopeSheet
+-------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.DopeSheet.show_only_errors`
+
+bpy.types.UILayout
+------------------
+
+Renamed
+^^^^^^^
+
+* **template_color_wheel** -> :class:`bpy.types.UILayout.template_color_picker`
+
+bpy.types.GPencilStroke
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GPencilStroke.draw_mode`
+
+bpy.types.UserPreferencesEdit
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.UserPreferencesEdit.use_auto_keying_warning`
+
+bpy.types.MovieTrackingObject
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MovieTrackingObject.keyframe_a`
+* :class:`bpy.types.MovieTrackingObject.keyframe_b`
+
+bpy.types.ShrinkwrapModifier
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ShrinkwrapModifier.project_limit`
+
+bpy.types.FileSelectParams
+--------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.FileSelectParams.use_filter_backup`
+
+bpy.types.RenderSettings
+------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.RenderSettings.tile_x`
+* :class:`bpy.types.RenderSettings.tile_y`
+* :class:`bpy.types.RenderSettings.use_persistent_data`
+
+Removed
+^^^^^^^
+
+* **parts_x**
+* **parts_y**
+* **use_sequencer_gl_render**
+
+bpy.types.Sculpt
+----------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Sculpt.show_diffuse_color`
+
+bpy.types.SmokeFlowSettings
+---------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.SmokeFlowSettings.density_vertex_group`
+* :class:`bpy.types.SmokeFlowSettings.fuel_amount`
+* :class:`bpy.types.SmokeFlowSettings.noise_texture`
+* :class:`bpy.types.SmokeFlowSettings.smoke_color`
+* :class:`bpy.types.SmokeFlowSettings.smoke_flow_source`
+* :class:`bpy.types.SmokeFlowSettings.smoke_flow_type`
+* :class:`bpy.types.SmokeFlowSettings.surface_distance`
+* :class:`bpy.types.SmokeFlowSettings.texture_map_type`
+* :class:`bpy.types.SmokeFlowSettings.texture_offset`
+* :class:`bpy.types.SmokeFlowSettings.texture_size`
+* :class:`bpy.types.SmokeFlowSettings.use_texture`
+* :class:`bpy.types.SmokeFlowSettings.uv_layer`
+* :class:`bpy.types.SmokeFlowSettings.velocity_normal`
+* :class:`bpy.types.SmokeFlowSettings.velocity_random`
+* :class:`bpy.types.SmokeFlowSettings.volume_density`
+
+Removed
+^^^^^^^
+
+* **use_outflow**
+
+bpy.types.GameObjectSettings
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GameObjectSettings.collision_group`
+* :class:`bpy.types.GameObjectSettings.collision_mask`
+
+bpy.types.SpaceView3D
+---------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.SpaceView3D.grid_scale_unit`
+* :class:`bpy.types.SpaceView3D.render_border_max_x`
+* :class:`bpy.types.SpaceView3D.render_border_max_y`
+* :class:`bpy.types.SpaceView3D.render_border_min_x`
+* :class:`bpy.types.SpaceView3D.render_border_min_y`
+* :class:`bpy.types.SpaceView3D.use_render_border`
+
+bpy.types.DupliObject
+---------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.DupliObject.orco`
+* :class:`bpy.types.DupliObject.particle_system`
+* :class:`bpy.types.DupliObject.persistent_id`
+* :class:`bpy.types.DupliObject.type`
+* :class:`bpy.types.DupliObject.uv`
+
+Removed
+^^^^^^^
+
+* **particle_index**
+
+bpy.types.CyclesRenderSettings
+------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.CyclesRenderSettings.use_progressive_refine`
+
+bpy.types.MaterialTextureSlot
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MaterialTextureSlot.use_map_to_bounds`
+
+bpy.types.MovieSequence
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MovieSequence.colorspace_settings`
+
+bpy.types.GPencilLayer
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GPencilLayer.clear`
+
+bpy.types.CYCLES
+----------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.CYCLES.update_script_node`
+
+bpy.types.ImageSequence
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ImageSequence.colorspace_settings`
+
+bpy.types.LatticePoint
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.LatticePoint.weight_softbody`
+
+bpy.types.DecimateModifier
+--------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.DecimateModifier.angle_limit`
+* :class:`bpy.types.DecimateModifier.decimate_type`
+* :class:`bpy.types.DecimateModifier.invert_vertex_group`
+* :class:`bpy.types.DecimateModifier.iterations`
+* :class:`bpy.types.DecimateModifier.use_collapse_triangulate`
+* :class:`bpy.types.DecimateModifier.use_dissolve_boundaries`
+* :class:`bpy.types.DecimateModifier.vertex_group`
+
+bpy.types.UserPreferencesSystem
+-------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.UserPreferencesSystem.multi_sample`
+
+Removed
+^^^^^^^
+
+* **use_antialiasing**
+
+bpy.types.Text
+--------------
+
+Removed
+^^^^^^^
+
+* **markers**
+
+bpy.types.GreasePencil
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GreasePencil.clear`
+
+bpy.types.UserPreferencesFilePaths
+----------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.UserPreferencesFilePaths.hide_system_bookmarks`
+
+bpy.types.ToolSettings
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ToolSettings.snap_uv_element`
+
+bpy.types.ShaderNodeTexCoord
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ShaderNodeTexCoord.from_dupli`
+
+bpy.types.RenderEngine
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.RenderEngine.update_memory_stats`
+* :class:`bpy.types.RenderEngine.update_script_node`
+
+bpy.types.MovieTrackingSettings
+-------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MovieTrackingSettings.reconstruction_success_threshold`
+* :class:`bpy.types.MovieTrackingSettings.use_fallback_reconstruction`
+
+Removed
+^^^^^^^
+
+* **keyframe_a**
+* **keyframe_b**
+
+bpy.types.ThemeUserInterface
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ThemeUserInterface.axis_x`
+* :class:`bpy.types.ThemeUserInterface.axis_y`
+* :class:`bpy.types.ThemeUserInterface.axis_z`
+
+bpy.types.BlendDataGreasePencils
+--------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.BlendDataGreasePencils.new`
+* :class:`bpy.types.BlendDataGreasePencils.remove`
+
+bpy.types.Object
+----------------
+
+Function Arguments
+^^^^^^^^^^^^^^^^^^
+
+* :class:`bpy.types.Object.dupli_list_create` (scene, settings), *was (scene)*
diff --git a/doc/python_api/rst/info_tutorial_addon.rst b/doc/python_api/rst/info_tutorial_addon.rst
index 2a101041227..5637cf2f638 100644
--- a/doc/python_api/rst/info_tutorial_addon.rst
+++ b/doc/python_api/rst/info_tutorial_addon.rst
@@ -486,16 +486,14 @@ using :kbd:`Ctrl-Shift-Space` as the key shortcut to activate it.
kmi = km.keymap_items.new(ObjectCursorArray.bl_idname, 'SPACE', 'PRESS', ctrl=True, shift=True)
kmi.properties.total = 4
- addon_keymaps.append(km)
+ addon_keymaps.append((km, kmi))
def unregister():
# handle the keymap
- wm = bpy.context.window_manager
- for km in addon_keymaps:
- wm.keyconfigs.addon.keymaps.remove(km)
- # clear the list
+ for km, kmi in addon_keymaps:
+ km.keymap_items.remove(kmi)
addon_keymaps.clear()
@@ -568,18 +566,16 @@ Bringing it all together
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)
+ addon_keymaps.append((km, kmi))
def unregister():
bpy.utils.unregister_class(ObjectCursorArray)
bpy.types.VIEW3D_MT_object.remove(menu_func)
# handle the keymap
- wm = bpy.context.window_manager
- for km in addon_keymaps:
- wm.keyconfigs.addon.keymaps.remove(km)
- # clear the list
- del addon_keymaps[:]
+ for km, kmi in addon_keymaps:
+ km.keymap_items.remove(kmi)
+ addon_keymaps.clear()
if __name__ == "__main__":
diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py
index c1b6643389d..3776ef7ce56 100644
--- a/doc/python_api/rst_from_bmesh_opdefines.py
+++ b/doc/python_api/rst_from_bmesh_opdefines.py
@@ -65,10 +65,10 @@ def main():
fsrc = open(FILE_OP_DEFINES_C, 'r', encoding="utf-8")
blocks = []
-
+
is_block = False
is_comment = False # /* global comments only */
-
+
comment_ctx = None
block_ctx = None
@@ -82,7 +82,7 @@ def main():
elif l.strip().startswith("/*"):
is_comment = True
comment_ctx = []
-
+
if is_block:
if l.strip().startswith("//"):
pass
@@ -93,11 +93,11 @@ def main():
l = l[:cpp_comment]
block_ctx.append(l)
-
+
if l.strip() == "};":
is_block = False
comment_ctx = None
-
+
if is_comment:
c_comment_start = l.find("/*")
if c_comment_start != -1:
@@ -113,7 +113,6 @@ def main():
fsrc.close()
del fsrc
-
# namespace hack
vars = (
"BMO_OP_SLOT_ELEMENT_BUF",
@@ -124,7 +123,7 @@ def main():
"BMO_OP_SLOT_VEC",
"BMO_OP_SLOT_PTR",
"BMO_OP_SLOT_MAPPING",
-
+
"BMO_OP_SLOT_SUBTYPE_MAP_ELEM",
"BMO_OP_SLOT_SUBTYPE_MAP_BOOL",
"BMO_OP_SLOT_SUBTYPE_MAP_INT",
@@ -157,23 +156,23 @@ def main():
for comment, b in blocks:
# magic, translate into python
b[0] = b[0].replace("static BMOpDefine ", "")
-
+
for i, l in enumerate(b):
l = l.strip()
l = l.replace("{", "(")
l = l.replace("}", ")")
-
+
if l.startswith("/*"):
l = l.replace("/*", "'''own <")
else:
l = l.replace("/*", "'''inline <")
l = l.replace("*/", ">''',")
-
+
# exec func. eg: bmo_rotate_edges_exec,
if l.startswith("bmo_") and l.endswith("_exec,"):
l = "None,"
b[i] = l
-
+
#for l in b:
# print(l)
@@ -182,7 +181,7 @@ def main():
"__file__": "generated",
"__name__": "__main__",
}
-
+
global_namespace.update(vars_dict)
text_a, text_b = text.split("=", 1)
@@ -191,7 +190,6 @@ def main():
# print(global_namespace["result"])
blocks_py.append((comment, global_namespace["result"]))
-
# ---------------------
# Now convert into rst.
fout = open(OUT_RST, 'w', encoding="utf-8")
@@ -217,7 +215,7 @@ def main():
args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple]
fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index])))
-
+
# -- wash the comment
comment_washed = []
for i, l in enumerate(comment):
@@ -236,7 +234,6 @@ def main():
fw("\n")
# -- done
-
# get the args
def get_args_wash(args, args_index, is_ret):
args_wash = []
@@ -268,7 +265,7 @@ def main():
comment_next = comment_next[8:-1] # strip inline <...>
else:
comment_next = ""
-
+
comment = ""
if comment_prev:
comment += comment_prev.strip()
@@ -304,18 +301,21 @@ def main():
elif tp == BMO_OP_SLOT_ELEMENT_BUF:
assert(tp_sub is not None)
-
+
ls = []
- if tp_sub & BM_VERT: ls.append(":class:`bmesh.types.BMVert`")
- if tp_sub & BM_EDGE: ls.append(":class:`bmesh.types.BMEdge`")
- if tp_sub & BM_FACE: ls.append(":class:`bmesh.types.BMFace`")
+ if tp_sub & BM_VERT:
+ ls.append(":class:`bmesh.types.BMVert`")
+ if tp_sub & BM_EDGE:
+ ls.append(":class:`bmesh.types.BMEdge`")
+ if tp_sub & BM_FACE:
+ ls.append(":class:`bmesh.types.BMFace`")
assert(ls) # must be at least one
if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE:
tp_str = "/".join(ls)
else:
tp_str = ("list of (%s)" % ", ".join(ls))
-
+
del ls
elif tp == BMO_OP_SLOT_MAPPING:
if tp_sub & BMO_OP_SLOT_SUBTYPE_MAP_EMPTY:
@@ -356,21 +356,21 @@ def main():
fw(" :arg %s: %s\n" % (name, comment))
fw(" :type %s: %s\n" % (name, tp))
-
+
if args_out_wash:
fw(" :return:\n\n")
-
+
for (name, tp, comment) in args_out_wash:
assert(name.endswith(".out"))
name = name[:-4]
fw(" - ``%s``: %s\n\n" % (name, comment))
fw(" **type** %s\n" % tp)
-
+
fw("\n")
fw(" :rtype: dict with string keys\n")
fw("\n\n")
-
+
fout.close()
del fout
print(OUT_RST)
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 441a6c04efe..09e844adae3 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -612,6 +612,10 @@ def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
'''
function or class method to sphinx
'''
+
+ if type(py_func) == type(bpy.types.Space.draw_handler_add):
+ return
+
arg_str = inspect.formatargspec(*inspect.getargspec(py_func))
if not is_class:
@@ -692,6 +696,8 @@ def pyprop2sphinx(ident, fw, identifier, py_prop):
write_indented_lines(ident + " ", fw, py_prop.__doc__)
if py_prop.fset is None:
fw(ident + " (readonly)\n\n")
+ else:
+ fw("\n")
def pymodule2sphinx(basepath, module_name, module, title):
@@ -980,6 +986,7 @@ context_type_map = {
"world": ("World", False),
}
+
def pycontext2sphinx(basepath):
# Only use once. very irregular
@@ -1007,7 +1014,6 @@ def pycontext2sphinx(basepath):
"sequencer_context_dir",
)
-
unique = set()
blend_cdll = ctypes.CDLL("")
for ctx_str in context_strings:
@@ -1477,7 +1483,9 @@ def write_sphinx_conf_py(basepath):
def execfile(filepath):
global_namespace = {"__file__": filepath, "__name__": "__main__"}
- exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace)
+ file_handle = open(filepath)
+ exec(compile(file_handle.read(), filepath, 'exec'), global_namespace)
+ file_handle.close()
def write_rst_contents(basepath):
@@ -1704,7 +1712,6 @@ def copy_handwritten_rsts(basepath):
# TODO put this docs in blender's code and use import as per modules above
handwritten_modules = [
- "bge.types",
"bge.logic",
"bge.render",
"bge.texture",
@@ -1723,6 +1730,14 @@ def copy_handwritten_rsts(basepath):
# copy2 keeps time/date stamps
shutil.copy2(os.path.join(RST_DIR, "%s.rst" % mod_name), basepath)
+ if "bge.types" not in EXCLUDE_MODULES:
+ shutil.copy2(os.path.join(RST_DIR, "bge.types.rst"), basepath)
+
+ bge_types_dir = os.path.join(RST_DIR, "bge_types")
+
+ for i in os.listdir(bge_types_dir):
+ shutil.copy2(os.path.join(bge_types_dir, i), basepath)
+
# changelog
shutil.copy2(os.path.join(RST_DIR, "change_log.rst"), basepath)
@@ -1810,8 +1825,19 @@ def refactor_sphinx_log(sphinx_logfile):
refactored_logfile.write("%-12s %s\n %s\n" % log)
+def monkey_patch():
+ filepath = os.path.join(SCRIPT_DIR, "sphinx_doc_gen_monkeypatch.py")
+ global_namespace = {"__file__": filepath, "__name__": "__main__"}
+ file = open(filepath, 'rb')
+ exec(compile(file.read(), filepath, 'exec'), global_namespace)
+ file.close()
+
+
def main():
+ # first monkey patch to load in fake members
+ monkey_patch()
+
# eventually, create the dirs
for dir_path in [ARGS.output_dir, SPHINX_IN]:
if not os.path.exists(dir_path):
diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh
index 92461961920..14919f678be 100755
--- a/doc/python_api/sphinx_doc_gen.sh
+++ b/doc/python_api/sphinx_doc_gen.sh
@@ -32,8 +32,7 @@ blender_version_char=$(grep BLENDER_VERSION_CHAR $blender_srcdir/source/blender/
blender_version_cycle=$(grep BLENDER_VERSION_CYCLE $blender_srcdir/source/blender/blenkernel/BKE_blender.h | awk '{print $3}')
blender_subversion=$(grep BLENDER_SUBVERSION $blender_srcdir/source/blender/blenkernel/BKE_blender.h | awk '{print $3}')
-if [ "$blender_version_cycle" == "release" ]
-then
+if [ "$blender_version_cycle" == "release" ] ; then
BLENDER_VERSION=$(expr $blender_version / 100)_$(expr $blender_version % 100)$blender_version_char"_release"
else
BLENDER_VERSION=$(expr $blender_version / 100)_$(expr $blender_version % 100)_$blender_subversion
@@ -109,6 +108,11 @@ if $DO_UPLOAD ; then
# better redirect
ssh $SSH_USER@emo.blender.org 'echo "<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\" content=\"0;url=../blender_python_api_'$BLENDER_VERSION'/\"></head><body>Redirecting...</body></html>" > '$SSH_UPLOAD'/250PythonDoc/index.html'
+ # redirect for release only so wiki can point here
+ if [ "$blender_version_cycle" == "release" ] ; then
+ ssh $SSH_USER@emo.blender.org 'echo "<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\" content=\"0;url=../blender_python_api_'$BLENDER_VERSION'/\"></head><body>Redirecting...</body></html>" > '$SSH_UPLOAD'/blender_python_api/index.html'
+ fi
+
if $DO_OUT_PDF ; then
# rename so local PDF has matching name.
rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/blender_python_reference_$BLENDER_VERSION.pdf $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.pdf
diff --git a/doc/python_api/sphinx_doc_gen_monkeypatch.py b/doc/python_api/sphinx_doc_gen_monkeypatch.py
new file mode 100644
index 00000000000..1167ece05b7
--- /dev/null
+++ b/doc/python_api/sphinx_doc_gen_monkeypatch.py
@@ -0,0 +1,47 @@
+ # ***** BEGIN GPL LICENSE BLOCK *****
+ #
+ # This program is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU General Public License
+ # as published by the Free Software Foundation; either version 2
+ # of the License, or (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software Foundation,
+ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ #
+ # Contributor(s): Campbell Barton
+ #
+ # #**** END GPL LICENSE BLOCK #****
+
+# <pep8 compliant>
+
+bpy_types_Operator_bl_property__doc__ = (
+"""
+The name of a property to use as this operators primary property.
+Currently this is only used to select the default property when
+expanding an operator into a menu.
+:type: string
+""")
+
+
+def main():
+ import bpy
+ from bpy.types import Operator
+
+ def dummy_func(test):
+ pass
+
+ kw_dummy = dict(fget=dummy_func, fset=dummy_func, fdel=dummy_func)
+
+ # bpy registration handles this,
+ # but its only checked for and not existing in the base class.
+ Operator.bl_property = property(doc=bpy_types_Operator_bl_property__doc__, **kw_dummy)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 2640c528c94..6ad6bdc316f 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -27,9 +27,12 @@
remove_strict_flags()
add_subdirectory(colamd)
+add_subdirectory(rangetree)
if(WITH_BULLET)
- add_subdirectory(bullet2)
+ if(NOT WITH_SYSTEM_BULLET)
+ add_subdirectory(bullet2)
+ endif()
endif()
# now only available in a branch
diff --git a/extern/SConscript b/extern/SConscript
index 71998ee072c..6a0ffa3f588 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -4,6 +4,7 @@ Import('env')
SConscript(['glew/SConscript'])
SConscript(['colamd/SConscript'])
+SConscript(['rangetree/SConscript'])
if env['WITH_BF_GAMEENGINE']:
SConscript(['recastnavigation/SConscript'])
diff --git a/extern/bullet2/CMakeLists.txt b/extern/bullet2/CMakeLists.txt
index c57474f99f2..3d757947980 100644
--- a/extern/bullet2/CMakeLists.txt
+++ b/extern/bullet2/CMakeLists.txt
@@ -242,14 +242,15 @@ set(SRC
src/BulletCollision/CollisionShapes/btUniformScalingShape.h
src/BulletCollision/Gimpact/btBoxCollision.h
src/BulletCollision/Gimpact/btClipPolygon.h
+ src/BulletCollision/Gimpact/btCompoundFromGimpact.h
src/BulletCollision/Gimpact/btContactProcessing.h
- src/BulletCollision/Gimpact/btGenericPoolAllocator.h
- src/BulletCollision/Gimpact/btGeometryOperations.h
src/BulletCollision/Gimpact/btGImpactBvh.h
src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
src/BulletCollision/Gimpact/btGImpactMassUtil.h
src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
src/BulletCollision/Gimpact/btGImpactShape.h
+ src/BulletCollision/Gimpact/btGenericPoolAllocator.h
+ src/BulletCollision/Gimpact/btGeometryOperations.h
src/BulletCollision/Gimpact/btQuantization.h
src/BulletCollision/Gimpact/btTriangleShapeEx.h
src/BulletCollision/Gimpact/gim_array.h
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h
new file mode 100644
index 00000000000..8d4c35515b1
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h
@@ -0,0 +1,98 @@
+#ifndef BT_COMPOUND_FROM_GIMPACT
+#define BT_COMPOUND_FROM_GIMPACT
+
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
+#include "btGImpactShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
+
+struct MyCallback : public btTriangleRaycastCallback
+ {
+ int m_ignorePart;
+ int m_ignoreTriangleIndex;
+
+
+ MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex)
+ :btTriangleRaycastCallback(from,to),
+ m_ignorePart(ignorePart),
+ m_ignoreTriangleIndex(ignoreTriangleIndex)
+ {
+
+ }
+ virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
+ {
+ if (partId!=m_ignorePart || triangleIndex!=m_ignoreTriangleIndex)
+ {
+ if (hitFraction < m_hitFraction)
+ return hitFraction;
+ }
+
+ return m_hitFraction;
+ }
+ };
+ struct MyInternalTriangleIndexCallback :public btInternalTriangleIndexCallback
+ {
+ const btGImpactMeshShape* m_gimpactShape;
+ btCompoundShape* m_colShape;
+ btScalar m_depth;
+
+ MyInternalTriangleIndexCallback (btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth)
+ :m_colShape(colShape),
+ m_gimpactShape(meshShape),
+ m_depth(depth)
+ {
+ }
+
+ virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
+ {
+ btVector3 scale = m_gimpactShape->getLocalScaling();
+ btVector3 v0=triangle[0]*scale;
+ btVector3 v1=triangle[1]*scale;
+ btVector3 v2=triangle[2]*scale;
+
+ btVector3 centroid = (v0+v1+v2)/3;
+ btVector3 normal = (v1-v0).cross(v2-v0);
+ normal.normalize();
+ btVector3 rayFrom = centroid;
+ btVector3 rayTo = centroid-normal*m_depth;
+
+ MyCallback cb(rayFrom,rayTo,partId,triangleIndex);
+
+ m_gimpactShape->processAllTrianglesRay(&cb,rayFrom, rayTo);
+ if (cb.m_hitFraction<1)
+ {
+ rayTo.setInterpolate3(cb.m_from,cb.m_to,cb.m_hitFraction);
+ //rayTo = cb.m_from;
+ //rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction);
+ //gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0));
+ }
+
+
+
+
+ btConvexHullShape* tet = new btConvexHullShape();
+ tet->addPoint(v0);
+ tet->addPoint(v1);
+ tet->addPoint(v2);
+ tet->addPoint(rayTo);
+ btTransform ident;
+ ident.setIdentity();
+ m_colShape->addChildShape(ident,tet);
+ }
+ };
+
+btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth)
+{
+ btCompoundShape* colShape = new btCompoundShape();
+
+ btTransform tr;
+ tr.setIdentity();
+
+ MyInternalTriangleIndexCallback cb(colShape,gimpactMesh, depth);
+ btVector3 aabbMin,aabbMax;
+ gimpactMesh->getAabb(tr,aabbMin,aabbMax);
+ gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb,aabbMin,aabbMax);
+
+ return colShape;
+}
+
+#endif //BT_COMPOUND_FROM_GIMPACT \ No newline at end of file
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
index cd4dfdb60e9..4528758c370 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
@@ -384,7 +384,7 @@ bool btGImpactQuantizedBvh::rayQuery(
SIMD_FORCE_INLINE bool _quantized_node_collision(
- btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1,
+ const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
int node0 ,int node1, bool complete_primitive_tests)
{
@@ -402,7 +402,7 @@ SIMD_FORCE_INLINE bool _quantized_node_collision(
//stackless recursive collision routine
static void _find_quantized_collision_pairs_recursive(
- btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1,
+ const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
btPairSet * collision_pairs,
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
int node0, int node1, bool complete_primitive_tests)
@@ -501,8 +501,8 @@ static void _find_quantized_collision_pairs_recursive(
}
-void btGImpactQuantizedBvh::find_collision(btGImpactQuantizedBvh * boxset0, const btTransform & trans0,
- btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
+void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh * boxset0, const btTransform & trans0,
+ const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
btPairSet & collision_pairs)
{
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
index 9c990774739..e6e52fff4c0 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
@@ -363,8 +363,8 @@ public:
static float getAverageTreeCollisionTime();
#endif //TRI_COLLISION_PROFILING
- static void find_collision(btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
- btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
+ static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
+ const btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
btPairSet & collision_pairs);
};
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp
index cceace55e4b..ac8efdf3833 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp
@@ -25,6 +25,7 @@ subject to the following restrictions:
#define CALC_EXACT_INERTIA 1
+
void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
lockChildShapes();
@@ -144,6 +145,31 @@ void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayT
{
}
+void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
+{
+ lockChildShapes();
+
+ btAlignedObjectArray<int> collided;
+ btVector3 rayDir(rayTo - rayFrom);
+ rayDir.normalize();
+ m_box_set.rayQuery(rayDir, rayFrom, collided);
+
+ if(collided.size()==0)
+ {
+ unlockChildShapes();
+ return;
+ }
+
+ int part = (int)getPart();
+ btPrimitiveTriangle triangle;
+ int i = collided.size();
+ while(i--)
+ {
+ getPrimitiveTriangle(collided[i],triangle);
+ callback->processTriangle(triangle.m_vertices,part,collided[i]);
+ }
+ unlockChildShapes();
+}
void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
@@ -182,6 +208,15 @@ void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const
}
}
+void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
+{
+ int i = m_mesh_parts.size();
+ while(i--)
+ {
+ m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
+ }
+}
+
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
index 90015bb9ac0..3d1f48d4776 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
@@ -51,6 +51,7 @@ enum eGIMPACT_SHAPE_TYPE
};
+
//! Helper class for tetrahedrons
class btTetrahedronShapeEx:public btBU_Simplex1to4
{
@@ -192,7 +193,7 @@ public:
virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ;
//! gets boxset
- SIMD_FORCE_INLINE btGImpactBoxSet * getBoxSet()
+ SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const
{
return &m_box_set;
}
@@ -288,6 +289,15 @@ public:
(void) callback; (void) aabbMin; (void) aabbMax;
}
+ //! Function for retrieve triangles.
+ /*!
+ It gives the triangles in local space
+ */
+ virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/,const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const
+ {
+
+ }
+
//!@}
};
@@ -635,25 +645,25 @@ public:
return (int )numverts;
}
- SIMD_FORCE_INLINE void get_indices(int face_index,int &i0,int &i1,int &i2) const
+ SIMD_FORCE_INLINE void get_indices(int face_index,unsigned int &i0,unsigned int &i1,unsigned int &i2) const
{
if(indicestype == PHY_SHORT)
{
- short * s_indices = (short *)(indexbase + face_index*indexstride);
+ unsigned short* s_indices = (unsigned short *)(indexbase + face_index * indexstride);
i0 = s_indices[0];
i1 = s_indices[1];
i2 = s_indices[2];
}
else
{
- int * i_indices = (int *)(indexbase + face_index*indexstride);
+ unsigned int * i_indices = (unsigned int *)(indexbase + face_index*indexstride);
i0 = i_indices[0];
i1 = i_indices[1];
i2 = i_indices[2];
}
}
- SIMD_FORCE_INLINE void get_vertex(int vertex_index, btVector3 & vertex) const
+ SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3 & vertex) const
{
if(type == PHY_DOUBLE)
{
@@ -682,7 +692,7 @@ public:
virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
{
- int indices[3];
+ unsigned int indices[3];
get_indices(prim_index,indices[0],indices[1],indices[2]);
get_vertex(indices[0],triangle.m_vertices[0]);
get_vertex(indices[1],triangle.m_vertices[1]);
@@ -692,7 +702,7 @@ public:
SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const
{
- int indices[3];
+ unsigned int indices[3];
get_indices(prim_index,indices[0],indices[1],indices[2]);
get_vertex(indices[0],triangle.m_vertices1[0]);
get_vertex(indices[1],triangle.m_vertices1[1]);
@@ -885,6 +895,7 @@ public:
}
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ virtual void processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const;
};
@@ -1141,6 +1152,8 @@ public:
*/
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ virtual void processAllTrianglesRay (btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const;
+
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
diff --git a/extern/carve/lib/intersect_face_division.cpp b/extern/carve/lib/intersect_face_division.cpp
index c74b52dd557..c5d5d8c5152 100644
--- a/extern/carve/lib/intersect_face_division.cpp
+++ b/extern/carve/lib/intersect_face_division.cpp
@@ -719,6 +719,10 @@ namespace {
unassigned--;
}
}
+
+ if (!removed.size())
+ throw carve::exception("Failed to merge holes");
+
for (std::set<int>::iterator f = removed.begin(); f != removed.end(); ++f) {
for (unsigned i = 0; i < containing_faces.size(); ++i) {
containing_faces[i].erase(std::remove(containing_faces[i].begin(),
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
index ebc5953d956..0fc90fdd9b9 100644
--- a/extern/libmv/CMakeLists.txt
+++ b/extern/libmv/CMakeLists.txt
@@ -47,9 +47,9 @@ set(SRC
libmv/multiview/conditioning.cc
libmv/multiview/euclidean_resection.cc
libmv/multiview/fundamental.cc
+ libmv/multiview/homography.cc
libmv/multiview/projection.cc
libmv/multiview/triangulation.cc
- libmv/multiview/homography.cc
libmv/numeric/numeric.cc
libmv/numeric/poly.cc
libmv/simple_pipeline/bundle.cc
@@ -71,8 +71,8 @@ set(SRC
libmv/tracking/lmicklt_region_tracker.cc
libmv/tracking/pyramid_region_tracker.cc
libmv/tracking/retrack_region_tracker.cc
- libmv/tracking/trklt_region_tracker.cc
libmv/tracking/track_region.cc
+ libmv/tracking/trklt_region_tracker.cc
third_party/fast/fast_10.c
third_party/fast/fast_11.c
@@ -191,14 +191,6 @@ if(WIN32)
third_party/msinttypes
)
endif()
-
- if(MSVC)
- set(MSVC_OFLAGS O1 O2 Ox)
- foreach(FLAG ${MSVC_OFLAGS})
- string(REPLACE "${FLAG}" "Od" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "${FLAG}" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
- endforeach()
- endif()
else()
list(APPEND SRC
third_party/glog/src/demangle.cc
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
index 02b79c93ec2..222fc4eaa1f 100644
--- a/extern/libmv/ChangeLog
+++ b/extern/libmv/ChangeLog
@@ -1,3 +1,585 @@
+commit 575336f794841ada90aacd783285014081b8318c
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Mon Jan 7 15:58:40 2013 +0600
+
+ Fixed for keyframe selection
+
+ - Calculate residuals for GRIC in pixel space rather than
+ in normalized space.
+
+ This seems to be how it's intended to be used.
+
+ Algebraic H and F will still use normalized coordinates which
+ are more stable, after this matrices are converted to pixel
+ space and Ceres refinement happens in pixel space.
+
+ - Standard deviation calculation was wrong in GRIC. It shouldn't
+ be deviation of residuals, but as per Torr it should be deviation
+ of measurement error, which is constant (in our case 0.1)
+
+ Not sure if using squared cost function is correct for GRIC,
+ but cost function is indeed squared and in most papers cost
+ function is used for GRIC. After some further tests we could
+ switch GRIC residuals to non-squared distance.
+
+ - Bring back rho part of GRIC, in unit tests it doesn't make
+ sense whether it's enabled or not, lets see how it'll behave
+ in real-life footage.
+
+ - Added one more unit test based on elevator scene and manual
+ keyframe selection.
+
+commit 24117f3c3fc5531beb6497d79bb6f1780a998081
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Sun Jan 6 19:07:06 2013 +0600
+
+ Added test for keyframe selection based on manual selection
+
+ Additional changes:
+
+ - Reduce minimal correspondence to match real-world manually
+ tracked footage
+
+ - Returned back squares to SymmetricEpipolarDistance and
+ SymmetricGeometricDistance -- this is actually a cost
+ functions, not distances and they shall be squared.
+
+commit 770eb0293b881c4c419c587a6cdb062c47ab6e44
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Dec 21 00:43:30 2012 +0600
+
+ Improvements for keyframe selection
+
+ - Changed main keyframe selection cycle, so in cases there're no
+ more next keyframes for current keyframe could be found in the
+ image sequence, current keyframe would be moved forward and
+ search continues.
+
+ This helps in cases when there's poor motion in the beginning
+ of the sequence, then markers becomes occluded. There could be
+ good keyframes in the middle of the shot still.
+
+ - Extended keyframe_selection_test with real world cases.
+
+ - Moved correspondences constraint to the top, so no H/F estimation
+ happens if there's bad correspondence. Makes algorithm go a bit
+ faster.
+
+ Strangely, but using non-squared distances makes neighbor frames
+ test fail, using squared distances makes this tests pass.
+
+ However, using non-squared distances seems to be working better
+ in real tests i've been doing. So this requires more investigation/
+
+commit 7415c62fbda36c5bd1c291bc94d535a66da896d0
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 20 18:46:09 2012 +0600
+
+ Cosmetic change to correspondences reports in keyframe selection
+
+commit ceaf80c987ec0338e7e83965bc808411453eb755
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 20 18:08:03 2012 +0600
+
+ Various fixes:
+
+ - That was a typo in symmetric geometric cost functor, which
+ computed inverse distance in a wrong way.
+
+ - Fixed compilation of unit tests
+
+ - Added simple test for keyframe selection. Currently only
+ covers case that neighbor frames with only translation
+ (homography should be better than fundamental) are not
+ considered a keyframes.
+
+ Still need to be investigated why it only works if tracks
+ are in pixel space and why doesn't work in normalized space.
+
+commit cfabdfe48df2add3d1f30cf4370efd0b31990ab0
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 20 05:46:53 2012 +0600
+
+ Assorted fixes for keyframe selection:
+
+ - Biggest error was in cost functors used for F and H refirement,
+ they were just wrong.
+
+ - Use natural logarithms, since it's actually makes sense from
+ math papers point of view and error is somewhere else.
+
+ - Disabled rho for GRIC, for now use non-clamped error for tests.
+
+ - Made SymmetricEpipolarDistance returning non-squared distance
+ Keyframe selection is currently the only used of this function
+ and it seems using non-squared distance makes much more sense.
+
+ Also would think to append suffix "Squared" to functions which
+ returns squared distances.
+
+ - Removed templated version of SymmetricEpipolarDistance, since
+ it's not needed actually.
+
+ This is actually even worse working than previous implementation,
+ but commit it needed for further review.
+
+commit 35d8c57626ad74818f155e6e5960c663ea84e032
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 20 03:00:40 2012 +0600
+
+ Euclidean resection cost function didn't use correct constructor
+
+ It was storing a reference to initial rotation passed by value,
+ leading to pointer being pointing to a stack variable, leading to
+ wrong memory access in residuals computing.
+
+ Apparently was visible in optimized builds only with inline
+ substitution allowed.
+
+commit 0798d3162bb49cee7e1c423ceccbca1326ad5650
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 20 02:50:52 2012 +0600
+
+ Automatic keyframe selection based on Pollefeys's criteria
+
+ This commit implements automatic keyframe selection algorithm
+ based on Pollefeys's criteria (F-GRIC is smaller than H-GRIC
+ and correspondence ratio is more then 90%).
+
+ It is implemented as a part of simple pipeline and returns
+ vector of keyframe images for a given Tracks structure.
+
+ For simple pipeline reconstruction two best keyframes are
+ expected to be selected from all detected candidates.
+ Criteria for this selection could be reprojection error of
+ solution from two candidate keyfames.
+
+ Unfortunately, it's not fully workable yet, hopefully would
+ be fixed soon.
+
+commit e943985552f0598ae122252876f305d72c25c2f9
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 17:47:11 2012 +0600
+
+ Camera Tracking: allow fallback to reprojection resection
+ by user demand
+
+ This fixes some "regressions" introduced in previous commit
+ which lead to much worse solution in some cases. Now it's
+ possible to bring old behavior back.
+
+ Perhaps it's more like temporal solution for time being smarter
+ solution is found. But finding such a solution isn't so fast,
+ so let's bring manual control over reprojection usage.
+
+ But anyway, imo it's now nice to have a structure which could
+ be used to pass different settings to the solver.
+
+commit 5a23d01dd531d1e0798298d17ba42a3397effb82
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu Sep 20 18:55:44 2012 +0000
+
+ Make Euclidean resection "always" succeed.
+
+ The Euclidean resection code had a magical constant, 1e-3, used to
+ compare the results of solving an equation. This failure detection
+ was well-intended, trying to prevent poor solutions from getting
+ made without notifying the caller. Unfortunately in practice, this
+ threshold is too conservative. Furthermore, it is not clear the
+ threshold should exist at all; the purpose of the Euclidean
+ resection is to come up with the best solution it can; other
+ methods (e.g. reprojection error) should be used to compare
+ whether the method succeeded.
+
+ This commit changes the Euclidean EPnP code to always succeed,
+ causing the previous fallback to projective resection to never
+ run. In most cases, this will result in better reconstructions.
+
+ This should, in most cases, fix the dreaded "flipping" problem.
+
+commit 57dad861d2a7f9d058c6d8edde1a2d51d7225a51
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu Sep 20 02:27:34 2012 +0000
+
+ Fix variable naming in the planar tracker.
+
+commit e9392fd3b46f5668662935696e7d9afac3390ca4
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu Sep 20 02:10:33 2012 +0000
+
+ Add smarter tolerance checking in the planar tracker.
+
+ The planar tracker uses Ceres for the refinement stage. During
+ refinement, Ceres iteratively updates the parameters with the
+ latest best guess. If the change in the parameters falls below a
+ threshold, Ceres will abort successfully ("converged").
+
+ For the case of pure translation tracking, the parameters are
+ exactly the two pixel shifts (dx, dy), and measuring the change in
+ these parameters gives a meaningful termination criterion.
+ However, for all the other parameterizations like affine, where
+ the parameterization involves affine parameters that have no
+ physical interpretation, Ceres is left with no way to terminate
+ the solver early. With the existing code, often many iterations
+ are run long after Ceres has found a solution sufficiently
+ accurate for all tracking needs. No one needs tracking with
+ a quadrillionth of a pixel accuracy; that time is wasted.
+
+ This patch extends the existing iteration callback that is passed
+ in to Ceres to check if the pattern has fallen out of the search
+ window, to also check if the optimizer has made a tiny step. In
+ particular, if the maximum shift of any patch corner between two
+ successful optimizer steps is less than a threshold (currently
+ 0.005 pixels), the track is declared successful and tracking
+ is terminated.
+
+ This leads to dramatic speed increases in some cases, with little
+ to no loss in track quality. This is especially apparent when
+ tracking patches with affine or perspective motion models. For
+ example, on some tracking cases I tried, the iterations Ceres took
+ went from 50 to 3.
+
+commit 36729c19bf90cb767e9adb96ba7dd48a5ace2be1
+Author: Keir Mierle <mierle@gmail.com>
+Date: Wed Sep 19 22:25:02 2012 +0000
+
+ Detect too-small planar tracking patches.
+
+ The planar tracker did not detect very skinny patches which have
+ effectively zero area and are untrackable. This adds detection and
+ rejection of patterns with zero area. This fixes a crash found by
+ during Mango production.
+
+commit 5cf2bae255a5a0f2e36ea0516670782cb88b589d
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 17:33:53 2012 +0600
+
+ Real fix for previous commit from Keir. He's comment;
+
+ Cleanup for when trackers fall out of the search window.
+
+ Sergey originally left a TODO() here, but his fix is the correct
+ one. I removed the TODO and fixed some comment issues.
+
+commit a11533918720e5b43dc1e95895db0eb36c8c06aa
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 17:31:16 2012 +0600
+
+ Fix crash when tracking in planar motion model (and maybe some other)
+
+ It was an Abort() caused by check for solver result not equal to USER_ABORT.
+
+ In some cases solver returns USER_ABORT due to BoundaryCheckingCallback
+ detects coordinates does not belong to image.
+
+ Somehow this callback wasn't called in previous version of Ceres and
+ in the same case marker was jumping. Now when the callback is called
+ it seems we could simply return failure of tracking without aborting
+ Blender.
+
+ Probably this is in fact some issue somewhere else, would double
+ check with Keir about this.
+
+commit 4be2306bcc664b259aaf7068b9f32ab60124a509
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 17:29:39 2012 +0600
+
+ Resolved some compilation warnings (missed prototypes)
+
+ In some cases it was missed include of header file, in some other
+ cases symbol could be static.
+
+commit bef729ba5c12683d13584d2a728b8b6506b7ca90
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 17:27:17 2012 +0600
+
+ Code cleanup: silence some -Wnarrowing warnings from C++11
+
+commit add1415d896818367087c784a3013dd8f1bb2095
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 17:25:18 2012 +0600
+
+ Changes to SamplePlanarPatch to support mask input and
+ added output for pattern center.
+
+commit daa354c0735b954b0cd7725626e9a3d67416d46b
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sat Jun 9 19:22:39 2012 +0000
+
+ Change libmv's bilinear sampling to assume the same
+ pixel conventions as Blender. This fixes the preview
+ widget in Blender, and should make tracking slightly
+ more accurate.
+
+commit 99b6222873fbfbe248316316956720376a58f438
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sat Jun 9 18:58:51 2012 +0000
+
+ Add new warp regularization scheme for planar tracking.
+
+ This adds a new term to the tracking cost function that
+ restricts how much the optimizer can warp the patch (as
+ opposed to merely adjusting the translation). This should
+ reduce the "jumpiness" that is sometimes seen when doing
+ non-"Loc" tracks.
+
+ It is disabled in this commit; a subsequent commit will add
+ controls to the tracking dialog for this.
+
+commit a1c5a70badd11cba0470700bad2eac2b2bd30c86
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sat Jun 9 06:55:21 2012 +0000
+
+ Planar tracker polish.
+
+ - Fixes the correlation checking code that was broken in the
+ previous commit. The bug was a transpose error.
+ - Fixes a memory leak of the warp functor, found by Sameer.
+ - Various cleanups done at Sameer's suggestion.
+
+ Thanks to Sameer Agarwal for a code review.
+
+commit 2cb784caa854a77cdd43620ab133f26b87ed0d83
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri Jun 8 17:42:17 2012 +0000
+
+ Make planar tracking much faster.
+
+ - This makes planar tracking around 2-3x or more faster than
+ before, by rearranging how the sampling is done.
+ Previously, the source patch was sampled repeatedly on
+ every optimizer iteration; this was done for
+ implementation speed, but was wasteful in computation.
+
+ - This also contains some additions to Ceres to help
+ deailing with mixed numeric / automatic differentation. In
+ particular, there is now a "Chain::Rule" operator that
+ facilitates calling a function that takes Jet arguments,
+ yet does numeric derivatives internally. This is used to
+ mix the numeric differentation of the images with the warp
+ parameters, passed as jets by Ceres to the warp functor.
+
+ There is also a new "JetOps" object for doing operations
+ on types which may or may not be jets, such as scaling
+ the derivative part only, or extracting the scalar part
+ of a jet.
+
+ This patche is aimed at Ceres upstream.
+
+ - A new function for sampling a patch is now part of the
+ track_region.h API; this will get used to make the preview
+ widget properly show what is getting tracked. Currently
+ the preview widget does not handle perspective tracks.
+
+ Known issues:
+
+ This patch introduces a bug such that the "Minimum
+ Correlation" flag does not work; if it is enabled, tracking
+ aborts immediately. The workaround for now is to disable the
+ correlation checking, and examine your tracks carefully. A
+ fix will get added shortly.
+
+commit 81d028f13738ebe2304287dfce90e91bc782e2cf
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri May 18 20:04:43 2012 +0000
+
+ Remove an unnecessary template<> line in libmv. Convert debug logs to LG.
+
+commit 238aaba241ef99995d254aadc974db719da04b96
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri May 18 12:05:10 2012 +0000
+
+ Support normalization in the tracking prepass
+
+ The last tracker commit added normalized tracking. This makes
+ tracking patches undergoing uniform illumination change easier.
+ However, the prepass which computes a quick translation-only
+ estimate of the warp did not take this into account. This commit
+ fixes that.
+
+ This works reasonably well but in some examples the brute
+ initialization fails. I suspect this is due to the warped template
+ estimate in the current frame being too different from the
+ original, so there are multiple peaks in the normalized-SAD
+ correlation function.
+
+ The solution is to use the previous frame for the brute
+ initialization and the keyframe for refinement, but that requires
+ architecture changes.
+
+commit 981ca4f6a679cd9ac3d086eae3cd946ce72ca8a5
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri May 18 02:12:47 2012 +0000
+
+ Add light-normalized tracking to the planar tracker
+
+ This commit adds the ability to normalize patterns by their
+ average value while tracking, to make them invariant to global
+ illumination changes.
+
+ To see this in action, check out the "Lobby" scene from Hollywood
+ VFX. If you track the markers that are shadowed by the actress,
+ previously they would not track. With the scale adaption on, the
+ tracker would shrink the area to compensate for the changed
+ illumination, losing the track. With "Normalize" turned on, the
+ patch is correctly tracked and scale is maintained.
+
+ A remaining problem is that only the Ceres cost function is
+ updated to handle the normalization. The brute translation search
+ does not take this into account. Perhaps "Prepass" (see below)
+ should get disabled if normalization is enabled until I fix the
+ prepass to normalize as well.
+
+ There are a few other changes:
+
+ - Bail out of the sampling loop early if the mask is zero; this
+ saves expensive samples of the image derivatives.
+
+ - Fix a bug where the mask was ignored when sampling in the cost
+ functor.
+
+commit e9384b15fb2a6a5b81346d5758fa136f0911e945
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 17 23:53:32 2012 +0000
+
+ Implement support for affine tracking in the planar tracker; cleanups.
+
+commit 021d41eed8b4ce6a4e37786ccd357ed5dc83a13f
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 17 21:26:06 2012 +0000
+
+ For the planar tracker, initialize the warp from the four correspondences
+ after brute force translation search.
+
+commit 003d1bf6145cfd30938b35f6e10d43708dbf916c
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 16:56:01 2012 +0600
+
+ Correction to region tracker options initialization.
+
+ Based on patch from Keir to Blender:
+ https://svn.blender.org/svnroot/bf-blender/branches/soc-2011-tomato@46743
+
+commit 6af47b218cfdf5219f0ebb3cb95459817cf9abf2
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 17 02:31:52 2012 +0000
+
+ Add new planar tracker features and use the new planar API
+
+ This commit removes the use of the legacy RegionTracker API from
+ Blender, and replaces it with the new TrackRegion API. This also
+ adds several features to the planar tracker in libmv:
+
+ - Do a brute-force initialization of tracking similar to "Hybrid"
+ mode in the stable release, but using all floats. This is slower
+ but more accurate. It is still necessary to evaluate if the
+ performance loss is worth it. In particular, this change is
+ necessary to support high bit depth imagery.
+
+ - Add support for masks over the search window. This is a step
+ towards supporting user-defined tracker masks. The tracker masks
+ will make it easy for users to make a mask for e.g. a ball.
+
+ - Add Pearson product moment correlation coefficient checking (aka
+ "Correlation" in the UI. This causes tracking failure if the
+ tracked patch is not linearly related to the template.
+
+ - Add support for warping a few points in addition to the supplied
+ points. This is useful because the tracking code deliberately
+ does not expose the underlying warp representation. Instead,
+ warps are specified in an aparametric way via the correspondences.
+
+ - Remove the "num_samples_xy" concept and replace it with
+ automatic determination of the number of samples. This makes the
+ API easier for users.
+
+ - Fix various bugs in the parameterizations.
+
+ There remains a bug with subpixel precision tracking when in
+ "keyframe" mode; this will get fixed shortly.
+
+commit 16a46db104468cec80bd31ca9d5f8bffbe3e003e
+Author: Keir Mierle <mierle@gmail.com>
+Date: Mon May 14 12:15:38 2012 +0000
+
+ "Efficient Second-order Minimization" for the planar tracker
+
+ This implements the "Efficient Second-order Minimization"
+ scheme, as supported by the existing translation tracker.
+ This increases the amount of per-iteration work, but
+ decreases the number of iterations required to converge and
+ also increases the size of the basin of attraction for the
+ optimization.
+
+commit 23243b1b1f3e1ab3ef862b47bca06ee876ac2cf4
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sun May 13 23:08:56 2012 +0000
+
+ Add a planar tracking implementation to libmv
+
+ This adds a new planar tracking implementation to libmv. The
+ tracker is based on Ceres[1], the new nonlinear minimizer that
+ myself and Sameer released from Google as open source. Since
+ the motion model is more involved, the interface is
+ different than the RegionTracker interface used previously
+ in Blender.
+
+ The ESM tracker, also known as the KLT tracker in the UI, is
+ temporarily changed to use the new Ceres-based planar
+ tracker in translation-only mode. Currently it is a bit
+ slower than ESM and also doesn't have all the bells and
+ whistles implemented. Those will come soon. Longer term,
+ both trackers will remain since Ceres is unlikely to be as
+ fast as ESM for pure translation solving, due to its
+ generality.
+
+ The next step is to implement a new tracking UI. The current
+ UI assumes a translational motion model; the new one must
+ support arbitrary perspective transforms of the pattern
+ regions.
+
+ [1] http://code.google.com/p/ceres-solver
+
+commit 52be92b53eb4decb1a316690b162196f227cc441
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Dec 6 16:06:08 2012 +0600
+
+ Initial Ceres integration
+
+ Currently only put sources to src/third_party/ceres and made sure they're
+ not giving compilation issues.
+
+ Used Ceres upstream version 1.3.0.
+
+ Needed to make some modifications to it's CMakeLists.txt also to glog and
+ fglags. They're described in README.libmv of this libraries.
+
+ Basically:
+
+ - Added -fPIC to glog/gflags, so shared ceres library could be linked
+ statically against this libraries.
+
+ - Tweaked Ceres's build rules to use needed libraries from libmv's
+ third_party folder.
+
+commit b13f9d13122e091cb85855c2094386ccdef6e5a4
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Dec 5 19:05:34 2012 +0600
+
+ Update Eigen to version 3.1.2
+
+ Mainly because of lots of warnings generating by gcc-4.7 which are
+ resolved in newer eigen version.
+
+commit 1f0dd94e8e37d3fe2df89282ec16a6a685fdde0b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri May 25 16:36:44 2012 +0600
+
+ - Added avutil to qt-tracker linking when building with FFmpeg support.
+ On some platforms it seems to be required
+ - Synchronized QT Creator project for qt-tracker with changes in sources,
+ so no it might be compiled from QT Creator.
+
commit b813dbe3f46bbbc7e73ac791d4665622e4fc7ba5
Author: Sergey Sharybin <sergey.vfx@gmail.com>
Date: Wed May 9 19:01:10 2012 +0600
@@ -206,351 +788,3 @@ Author: Sergey Sharybin <sergey.vfx@gmail.com>
Date: Fri Feb 17 21:32:05 2012 +0600
Picky edits: corrected EOL
-
-commit 3f2a4205ec5adadcdfa306b161c705c868a7be93
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 21:30:07 2012 +0600
-
- Fixed incorrect access to ucontext on linux. Caused by incorrect merge conflict resolve.
-
-commit d360a21a5aa125cf9e83dd26b302508688ff7007
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 20:54:13 2012 +0600
-
- More Windows -> Unix EOL conversions
-
-commit 18aeda58bec9556140ba617724e31ada6f5b67c0
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 20:15:42 2012 +0600
-
- Looks like this debug output was removed accidentally.
-
-commit 189dc0cacdee3c1eab68c43263ecb038ed244c09
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 20:11:56 2012 +0600
-
- Made V3D verbose again by default
-
-commit 8b3422d3eec5e450d76243886bf07fb0a3e83a81
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 20:08:01 2012 +0600
-
- SAD tracker now can deal with pattern size any size,
- Very quick implementation came from Blender before Hybrid tracker was added.
- Better to be replaced with brute tracker.
-
-commit d547c9cfe37d5d3397d33c8b0e58471e1e1c1634
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 20:03:52 2012 +0600
-
- Just convert end of lines to unix style.
-
-commit eb73ddbaec5b9e1ad30331bbf858a6ebc266c4aa
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 20:02:20 2012 +0600
-
- Made some function static. Resolves possible linking issues when building with MinGW.
-
-commit 2930681fafd86e4f4a958054b1db8bfff29623d1
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 19:59:45 2012 +0600
-
- Missed this in commit with improvements in camera intrinsics.
-
-commit 8d31bc767019b05c5bf8c9f309f9545b3428afa1
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 19:57:51 2012 +0600
-
- Another step of syncing codebase with Blender.
- Mainly fixes for freebsd/osx compilation and aligned memory allocation.
-
-commit 3214a2df5bfd98021f25d0f1a626a86318bb245f
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 19:48:02 2012 +0600
-
- Support compilation on FreeBSD platform
-
-commit 0e5abe96f543687ccfb3a923ec639cb8f45d54f8
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 19:44:18 2012 +0600
-
- Implementation of basic system for progress reporting into callee stuff
-
- Implemented by using simple callbacks classes which are getting invoked from
- places where lots of calculation happens, so applications which are using
- libmv may display nice progress bar.
-
-commit c5e18fe35464618055e0e9761be8d22fae56db49
-Author: Keir Mierle <mierle@gmail.com>
-Date: Fri Feb 17 19:25:45 2012 +0600
-
- Add support for detecting tracking failure in the ESM tracker component of
- libmv. Since both KLT and Hybrid rely on ESM underneath, KLT and Hybrid now
- have a minimum correlation setting to match. With this fix, track failures
- should get detected quicker, with the issue that sometimes the tracker will
- give up too easily. That is fixable by reducing the required correlation (in
- the track properties).
-
-commit ea0fed736ecdcc8c020227aeef8ef4cd3be5e63d
-Author: Keir Mierle <mierle@gmail.com>
-Date: Fri Feb 17 19:23:50 2012 +0600
-
- Add a new hybrid region tracker for motion tracking to libmv, and
- add it as an option (under "Hybrid") in the tracking settings. The
- region tracker is a combination of brute force tracking for coarse
- alignment, then refinement with the ESM/KLT algorithm already in
- libmv that gives excellent subpixel precision (typically 1/50'th
- of a pixel)
-
- This also adds a new "brute force" region tracker which does a
- brute force search through every pixel position in the destination
- for the pattern in the first frame. It leverages SSE if available,
- similar to the SAD tracker, to do this quickly. Currently it does
- some unnecessary conversions to/from floating point that will get
- fixed later.
-
- The hybrid tracker glues the two trackers (brute & ESM) together
- to get an overall better tracker. The algorithm is simple:
-
- 1. Track from frame 1 to frame 2 with the brute force tracker.
- This tries every possible pixel position for the pattern from
- frame 1 in frame 2. The position with the smallest
- sum-of-absolute-differences is chosen. By definition, this
- position is only accurate up to 1 pixel or so.
- 2. Using the result from 1, initialize a track with ESM. This does
- a least-squares fit with subpixel precision.
- 3. If the ESM shift was more than 2 pixels, report failure.
- 4. If the ESM track shifted less than 2 pixels, then the track is
- good and we're done. The rationale here is that if the
- refinement stage shifts more than 1 pixel, then the brute force
- result likely found some random position that's not a good fit.
-
-commit a07fff8431621c01d81ae52595d8dd91a295a776
-Author: Keir Mierle <mierle@gmail.com>
-Date: Fri Feb 17 19:19:58 2012 +0600
-
- Assorted camera tracker improvements
-
- - Add support for refining the camera's intrinsic parameters
- during a solve. Currently, refining supports only the following
- combinations of intrinsic parameters:
-
- f
- f, cx, cy
- f, cx, cy, k1, k2
- f, k1
- f, k1, k2
-
- This is not the same as autocalibration, since the user must
- still make a reasonable initial guess about the focal length and
- other parameters, whereas true autocalibration would eliminate
- the need for the user specify intrinsic parameters at all.
-
- However, the solver works well with only rough guesses for the
- focal length, so perhaps full autocalibation is not that
- important.
-
- Adding support for the last two combinations, (f, k1) and (f,
- k1, k2) required changes to the library libmv depends on for
- bundle adjustment, SSBA. These changes should get ported
- upstream not just to libmv but to SSBA as well.
-
- - Improved the region of convergence for bundle adjustment by
- increasing the number of Levenberg-Marquardt iterations from 50
- to 500. This way, the solver is able to crawl out of the bad
- local minima it gets stuck in when changing from, for example,
- bundling k1 and k2 to just k1 and resetting k2 to 0.
-
- - Add several new region tracker implementations. A region tracker
- is a libmv concept, which refers to tracking a template image
- pattern through frames. The impact to end users is that tracking
- should "just work better". I am reserving a more detailed
- writeup, and maybe a paper, for later.
-
- - Other libmv tweaks, such as detecting that a tracker is headed
- outside of the image bounds.
-
- This includes several changes made directly to the libmv extern
- code rather expecting to get those changes through normal libmv
- channels, because I, the libmv BDFL, decided it was faster to work
- on libmv directly in Blender, then later reverse-port the libmv
- changes from Blender back into libmv trunk. The interesting part
- is that I added a full Levenberg-Marquardt loop to the region
- tracking code, which should lead to a more stable solutions. I
- also added a hacky implementation of "Efficient Second-Order
- Minimization" for tracking, which works nicely. A more detailed
- quantitative evaluation will follow.
-
-commit 0bf66c009d5022eacfc473d247884a73ffeefa8f
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 19:13:49 2012 +0600
-
- Rest of compilation fix with FAST library.
-
-commit 71b578ca2ba34c528363c514cd1fcc85791d01f3
-Author: Keir Mierle <mierle@gmail.com>
-Date: Fri Feb 17 19:00:28 2012 +0600
-
- Improve the KLT tracking behaviour and UI
-
- - Remove the overly-conservative use of libmv's re-track tracker. The re-track
- tracker would take a normal tracker such as TRKLT or KLT or pyramid KLT, and
- track from frame 1 to 2, then back from the position found in 2 back to 1.
- Then, when the reverse-track doesn't match the original track with high
- precision, the track is considered "failed". This is a good approach for
- fully automatic reconstruction, but is too conservative for supervised
- tracking.
-
- The retrack-tracker will return when fully automatic tracking is added.
-
- - Always solve for (dx, dy) in the TRKLT loop even if the linear system is
- ill-conditioned. The client (Blender in this case) can still use the solved
- position, even though it is less reliable.
-
-commit 7d8a8762f2bc2e36f95b0b6f4fb4ca996f9f0db7
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 18:46:24 2012 +0600
-
- Changes in camera intrinsics distortion/undistortion:
-
- - Distortion/undistortion of scaled images wasn't happening right,
- because camera intrinsics are calibrated on an original frame which
- has got some particular resolution and trying to apply this model on
- an image with another resolution gives totally wrong result.
- This is needed to be able to do post-prccessing of render, running
- distortion on a scene which might be rendered with higher resolution
- than footage itself and then be scaled down.
- - Fixed incorrect calculation/applying of precomputed grid when
- distortion is high high enough and produces pixel offset higher
- than 127 pixels. This might be still not very distorted image,
- but if it's a 4K footage "normal" camera will easily give such
- a distortion.
- - Added support of overscan distortion/undistortion.
-
-commit ed080785d63bb8e3a13dde51a2dc94fe59b059bb
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 18:38:51 2012 +0600
-
- Fast headers now can be included from C++ sources.
- Was needed to make it working fine when bundling in Blender but might also
- be needed to bundle into another applications.
-
-commit 5f5a7aa46a2d87b96c8098dfc8682f4d01b5cd40
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 18:36:16 2012 +0600
-
- Bring back FAST detector which seems to be working much nicer than Morravec.
- Both of them are available in API.
-
-commit 2cab13c18216fb684b270cec077f7300262584af
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 18:27:36 2012 +0600
-
- Revert "Make CameraIntrinsics (and thus Qt tracker) compilable without linking libmv."
-
- This reverts commit 81613ee0cc94b315f333c9632b18b95d426aad05.
-
- That commit made inverting intrinsics totally unworkable, so reverted this and
- made needed tweaks to qt-tracker project file to make it compilable (was needed
- to make it linking together with glog).
-
- Conflicts:
-
- src/ui/tracker/tracker.cc
- src/ui/tracker/tracker.pro
-
-commit ec46cae041401b17afb4fe4d9c9343d10797090f
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 17:59:55 2012 +0600
-
- Fix compilation error using official MinGW
-
-commit 6fbc370e922c47cfa35381662b6c439f4891ed74
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 17:38:20 2012 +0600
-
- Fix compilation error with MSVC 2010 which is more picky for "missed" STL headers
-
-commit be9e6b63691d83b551a085f0766878bd84220767
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 17:36:18 2012 +0600
-
- Fix compilation with MSVC where snprintf function is declared as unsafe and _snprintf should be used instead.
-
- Better to switch to own implementation will ensure string is correctly NULL-terminated.
-
-commit 1847d9e414ed763cd80668775d7d9f79575fc8ca
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 17:34:45 2012 +0600
-
- Fix compilation error on OSX caused by incorrect access to ucontext
-
-commit 90579b6ffad07672172a1c240499615b30b25549
-Merge: b9aac30 531c79b
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 17 18:32:52 2012 +0600
-
- Merge remote-tracking branch 'Matthias-Fauconneau/master' into devel
-
- Conflicts:
- src/libmv/tracking/CMakeLists.txt
-
-commit b9aac30a9ca6bc8362c09a0e191040964f7c6de2
-Merge: 198894e 6969e1a
-Author: Keir Mierle <mierle@gmail.com>
-Date: Sat Nov 5 17:38:30 2011 -0700
-
- Merge pull request #3 from nathanwiegand/master
-
- Just a few tiny cleanups
-
-commit 6969e1a9534291a982749baa5a3672c97bfa506d
-Author: Nathan Wiegand <nathanwiegand@gmail.com>
-Date: Sat Nov 5 14:26:54 2011 -0700
-
- I've added cleaned up a few style issues here an there. Also, I've updated the CMakeLists.txt file so that it can build the image_io library. Note, it's only been tested on OSX 10.6
-
-commit 4763f851299050140757bfaa069107a0cf639e56
-Author: Nathan Wiegand <nathanwiegand@gmail.com>
-Date: Fri Nov 4 23:59:08 2011 -0700
-
- Removed a superfulous comment
-
-commit a44577c0162e273681e4a9a3cc5f5b37d4315b67
-Author: Nathan Wiegand <nathanwiegand@gmail.com>
-Date: Fri Nov 4 23:55:52 2011 -0700
-
- Removed a duplicate entry for an author.
-
-commit 198894e4c4f51c2c1784ad7c02eb45d2d1ada9bc
-Merge: c4c67db 6e797d6
-Author: Keir Mierle <mierle@gmail.com>
-Date: Fri Nov 4 21:47:05 2011 -0700
-
- Merge pull request #2 from nathanwiegand/master
-
- CMake changes for OSX
-
-commit 6e797d678c4c19f6a9e21657d66183f412cc995b
-Author: Nathan Wiegand <nathanwiegand@gmail.com>
-Date: Fri Nov 4 21:43:28 2011 -0700
-
- Uncomment the GUI part of the CMake file
-
-commit 33ef88a33860345d8906f3c9dd22d8dbce3df53e
-Author: Nathan Wiegand <nathanwiegand@gmail.com>
-Date: Fri Nov 4 21:31:22 2011 -0700
-
- Fixed build error on OSX by adding 'glog' to the dependencies in the tracker CMake
-
-commit 531c79bf95fddaaa70707d1abcd4fdafda16bbf0
-Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
-Date: Sat Aug 20 00:00:42 2011 +0200
-
- Display warped pattern in marker preview.
-
-commit bb5c27e671b6f8eb56ddf490f0795d59bede591b
-Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
-Date: Fri Aug 19 18:37:48 2011 +0200
-
- Fix CMake build.
diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript
index b47086f3e91..8fd8c566e4d 100644
--- a/extern/libmv/SConscript
+++ b/extern/libmv/SConscript
@@ -11,10 +11,6 @@ Import('env')
defs = []
-cflags_libmv = Split(env['CFLAGS'])
-ccflags_libmv = Split(env['CCFLAGS'])
-cxxflags_libmv = Split(env['CXXFLAGS'])
-
defs.append('V3DLIB_ENABLE_SUITESPARSE')
defs.append('GOOGLE_GLOG_DLL_DECL=')
@@ -41,29 +37,12 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
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']
-
- if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
- cflags_libmv.append('/Od')
- ccflags_libmv.append('/Od')
- cxxflags_libmv.append('/Od')
-
- if not env['BF_DEBUG']:
- defs.append('NDEBUG')
- else:
- if not env['BF_DEBUG']:
- cflags_libmv += Split(env['REL_CFLAGS'])
- ccflags_libmv += Split(env['REL_CCFLAGS'])
- cxxflags_libmv += Split(env['REL_CXXFLAGS'])
else:
src += env.Glob("third_party/glog/src/*.cc")
incs += ' ./third_party/glog/src'
- if not env['BF_DEBUG']:
- cflags_libmv += Split(env['REL_CFLAGS'])
- ccflags_libmv += Split(env['REL_CCFLAGS'])
- cxxflags_libmv += Split(env['REL_CXXFLAGS'])
incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
-env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
+env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137] )
SConscript(['third_party/SConscript'])
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
index 1e386ec8096..53487cf020e 100755
--- a/extern/libmv/bundle.sh
+++ b/extern/libmv/bundle.sh
@@ -136,19 +136,6 @@ set(INC_SYS
\${ZLIB_INCLUDE_DIRS}
)
-
-# XXX - FIXME
-# this is a momentary hack to find unwind.h in 10.6.sdk
-if(APPLE)
- if(\${CMAKE_OSX_DEPLOYMENT_TARGET} STREQUAL "10.6")
- list(APPEND INC_SYS
- \${CMAKE_OSX_SYSROOT}/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include
- )
- endif()
-endif()
-# XXX - END
-
-
set(SRC
libmv-capi.cpp
${sources}
@@ -197,14 +184,6 @@ if(WIN32)
third_party/msinttypes
)
endif()
-
- if(MSVC)
- set(MSVC_OFLAGS O1 O2 Ox)
- foreach(FLAG \${MSVC_OFLAGS})
- string(REPLACE "\${FLAG}" "Od" CMAKE_CXX_FLAGS_RELEASE "\${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "\${FLAG}" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "\${CMAKE_C_FLAGS_RELWITHDEBINFO}")
- endforeach()
- endif()
else()
list(APPEND SRC
${third_glog_sources}
@@ -241,10 +220,6 @@ Import('env')
defs = []
-cflags_libmv = Split(env['CFLAGS'])
-ccflags_libmv = Split(env['CCFLAGS'])
-cxxflags_libmv = Split(env['CXXFLAGS'])
-
defs.append('V3DLIB_ENABLE_SUITESPARSE')
defs.append('GOOGLE_GLOG_DLL_DECL=')
@@ -262,30 +237,13 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
${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']
-
- if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
- cflags_libmv.append('/Od')
- ccflags_libmv.append('/Od')
- cxxflags_libmv.append('/Od')
-
- if not env['BF_DEBUG']:
- defs.append('NDEBUG')
- else:
- if not env['BF_DEBUG']:
- cflags_libmv += Split(env['REL_CFLAGS'])
- ccflags_libmv += Split(env['REL_CCFLAGS'])
- cxxflags_libmv += Split(env['REL_CXXFLAGS'])
else:
src += env.Glob("third_party/glog/src/*.cc")
incs += ' ./third_party/glog/src'
- if not env['BF_DEBUG']:
- cflags_libmv += Split(env['REL_CFLAGS'])
- ccflags_libmv += Split(env['REL_CCFLAGS'])
- cxxflags_libmv += Split(env['REL_CXXFLAGS'])
incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
-env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
+env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137] )
SConscript(['third_party/SConscript'])
EOF
diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt
index 85d09ce05b8..22c5226adbe 100644
--- a/extern/libmv/files.txt
+++ b/extern/libmv/files.txt
@@ -17,6 +17,9 @@ libmv/multiview/euclidean_resection.cc
libmv/multiview/euclidean_resection.h
libmv/multiview/fundamental.cc
libmv/multiview/fundamental.h
+libmv/multiview/homography.cc
+libmv/multiview/homography.h
+libmv/multiview/homography_parameterization.h
libmv/multiview/nviewtriangulation.h
libmv/multiview/projection.cc
libmv/multiview/projection.h
@@ -69,6 +72,8 @@ libmv/tracking/pyramid_region_tracker.h
libmv/tracking/region_tracker.h
libmv/tracking/retrack_region_tracker.cc
libmv/tracking/retrack_region_tracker.h
+libmv/tracking/track_region.cc
+libmv/tracking/track_region.h
libmv/tracking/trklt_region_tracker.cc
libmv/tracking/trklt_region_tracker.h
third_party/fast/fast_10.c
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index bc6b0e99834..4f00d7d68b4 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -259,7 +259,7 @@ static void saveBytesImage(const char *prefix, unsigned char *data, int width, i
}
{
- static int a= 0;
+ static int a = 0;
char buf[128];
snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
savePNGImage(row_pointers, width, height, 8, PNG_COLOR_TYPE_RGBA, buf);
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index ba737160047..588df8de440 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -31,7 +31,6 @@
extern "C" {
#endif
-struct libmv_RegionTracker;
struct libmv_Tracks;
struct libmv_Reconstruction;
struct libmv_Features;
diff --git a/extern/libmv/libmv/multiview/homography.cc b/extern/libmv/libmv/multiview/homography.cc
index b5c483998d8..538c62598c0 100644
--- a/extern/libmv/libmv/multiview/homography.cc
+++ b/extern/libmv/libmv/multiview/homography.cc
@@ -264,4 +264,19 @@ bool Homography3DFromCorrespondencesLinear(const Mat &x1,
return false;
}
}
+
+double SymmetricGeometricDistance(Mat3 &H, Vec2 &x1, Vec2 &x2) {
+ Vec3 x(x1(0), x1(1), 1.0);
+ Vec3 y(x2(0), x2(1), 1.0);
+
+ Vec3 H_x = H * x;
+ Vec3 Hinv_y = H.inverse() * y;
+
+ H_x /= H_x(2);
+ Hinv_y /= Hinv_y(2);
+
+ return (H_x.head<2>() - y.head<2>()).squaredNorm() +
+ (Hinv_y.head<2>() - x.head<2>()).squaredNorm();
+}
+
} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/homography.h b/extern/libmv/libmv/multiview/homography.h
index 786fd3df8ca..a295c4366b6 100644
--- a/extern/libmv/libmv/multiview/homography.h
+++ b/extern/libmv/libmv/multiview/homography.h
@@ -79,6 +79,14 @@ bool Homography3DFromCorrespondencesLinear(const Mat &x1,
Mat4 *H,
double expected_precision =
EigenDouble::dummy_precision());
+
+/**
+ * Calculate symmetric geometric cost:
+ *
+ * D(H * x1, x2)^2 + D(H^-1 * x2, x1)
+ */
+double SymmetricGeometricDistance(Mat3 &H, Vec2 &x1, Vec2 &x2);
+
} // namespace libmv
#endif // LIBMV_MULTIVIEW_HOMOGRAPHY_H_
diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
index 9c06d1ef4e6..84d143b77d6 100644
--- a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
+++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
@@ -31,22 +31,6 @@
namespace libmv {
namespace {
-void CoordinatesForMarkersInImage(const vector<Marker> &markers,
- int image,
- Mat *coordinates) {
- vector<Vec2> coords;
- for (int i = 0; i < markers.size(); ++i) {
- const Marker &marker = markers[i];
- if (markers[i].image == image) {
- coords.push_back(Vec2(marker.x, marker.y));
- }
- }
- coordinates->resize(2, coords.size());
- for (int i = 0; i < coords.size(); i++) {
- coordinates->col(i) = coords[i];
- }
-}
-
void GetImagesInMarkers(const vector<Marker> &markers,
int *image1, int *image2) {
if (markers.size() < 2) {
diff --git a/extern/libmv/libmv/simple_pipeline/tracks.cc b/extern/libmv/libmv/simple_pipeline/tracks.cc
index 3fb8ddbe513..620f6fc880a 100644
--- a/extern/libmv/libmv/simple_pipeline/tracks.cc
+++ b/extern/libmv/libmv/simple_pipeline/tracks.cc
@@ -72,6 +72,16 @@ vector<Marker> Tracks::MarkersForTrack(int track) const {
return markers;
}
+vector<Marker> Tracks::MarkersInBothImages(int image1, int image2) const {
+ vector<Marker> markers;
+ for (int i = 0; i < markers_.size(); ++i) {
+ int image = markers_[i].image;
+ if (image == image1 || image == image2)
+ markers.push_back(markers_[i]);
+ }
+ return markers;
+}
+
vector<Marker> Tracks::MarkersForTracksInBothImages(int image1, int image2) const {
std::vector<int> image1_tracks;
std::vector<int> image2_tracks;
@@ -156,4 +166,20 @@ int Tracks::NumMarkers() const {
return markers_.size();
}
+void CoordinatesForMarkersInImage(const vector<Marker> &markers,
+ int image,
+ Mat *coordinates) {
+ vector<Vec2> coords;
+ for (int i = 0; i < markers.size(); ++i) {
+ const Marker &marker = markers[i];
+ if (markers[i].image == image) {
+ coords.push_back(Vec2(marker.x, marker.y));
+ }
+ }
+ coordinates->resize(2, coords.size());
+ for (int i = 0; i < coords.size(); i++) {
+ coordinates->col(i) = coords[i];
+ }
+}
+
} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/tracks.h b/extern/libmv/libmv/simple_pipeline/tracks.h
index aa0fbaa6e4c..f9af3ada45b 100644
--- a/extern/libmv/libmv/simple_pipeline/tracks.h
+++ b/extern/libmv/libmv/simple_pipeline/tracks.h
@@ -22,6 +22,7 @@
#define LIBMV_SIMPLE_PIPELINE_TRACKS_H_
#include "libmv/base/vector.h"
+#include "libmv/numeric/numeric.h"
namespace libmv {
@@ -84,6 +85,9 @@ class Tracks {
/// Returns all the markers visible in \a image.
vector<Marker> MarkersInImage(int image) const;
+ /// Returns all the markers visible in \a image1 and \a image2.
+ vector<Marker> MarkersInBothImages(int image1, int image2) const;
+
/*!
Returns the markers in \a image1 and \a image2 which have a common track.
@@ -114,6 +118,10 @@ class Tracks {
vector<Marker> markers_;
};
+void CoordinatesForMarkersInImage(const vector<Marker> &markers,
+ int image,
+ Mat *coordinates);
+
} // namespace libmv
#endif // LIBMV_SIMPLE_PIPELINE_MARKERS_H_
diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt
index e2f06d74646..5e58c2964ce 100644
--- a/extern/libmv/third_party/ceres/CMakeLists.txt
+++ b/extern/libmv/third_party/ceres/CMakeLists.txt
@@ -31,6 +31,7 @@ set(INC
include
internal
../gflags
+ ../../
)
set(INC_SYS
@@ -53,6 +54,7 @@ set(SRC
internal/ceres/compressed_row_sparse_matrix.cc
internal/ceres/conditioned_cost_function.cc
internal/ceres/conjugate_gradients_solver.cc
+ internal/ceres/coordinate_descent_minimizer.cc
internal/ceres/corrector.cc
internal/ceres/cxsparse.cc
internal/ceres/dense_normal_cholesky_solver.cc
@@ -70,11 +72,18 @@ set(SRC
internal/ceres/linear_least_squares_problems.cc
internal/ceres/linear_operator.cc
internal/ceres/linear_solver.cc
+ internal/ceres/line_search.cc
+ internal/ceres/line_search_direction.cc
+ internal/ceres/line_search_minimizer.cc
internal/ceres/local_parameterization.cc
internal/ceres/loss_function.cc
+ internal/ceres/low_rank_inverse_hessian.cc
+ internal/ceres/minimizer.cc
internal/ceres/normal_prior.cc
+ internal/ceres/parameter_block_ordering.cc
internal/ceres/partitioned_matrix_view.cc
- internal/ceres/polynomial_solver.cc
+ internal/ceres/polynomial.cc
+ internal/ceres/preconditioner.cc
internal/ceres/problem.cc
internal/ceres/problem_impl.cc
internal/ceres/program.cc
@@ -83,7 +92,7 @@ set(SRC
internal/ceres/runtime_numeric_diff_cost_function.cc
internal/ceres/schur_complement_solver.cc
internal/ceres/schur_eliminator.cc
- internal/ceres/schur_ordering.cc
+ internal/ceres/schur_jacobi_preconditioner.cc
internal/ceres/scratch_evaluate_preparer.cc
internal/ceres/solver.cc
internal/ceres/solver_impl.cc
@@ -98,26 +107,34 @@ set(SRC
internal/ceres/types.cc
internal/ceres/visibility_based_preconditioner.cc
internal/ceres/visibility.cc
+ internal/ceres/wall_time.cc
include/ceres/autodiff_cost_function.h
include/ceres/ceres.h
include/ceres/conditioned_cost_function.h
include/ceres/cost_function.h
+ include/ceres/cost_function_to_functor.h
include/ceres/crs_matrix.h
+ include/ceres/dynamic_autodiff_cost_function.h
include/ceres/fpclassify.h
+ include/ceres/gradient_checker.h
include/ceres/internal/autodiff.h
include/ceres/internal/eigen.h
include/ceres/internal/fixed_array.h
include/ceres/internal/macros.h
include/ceres/internal/manual_constructor.h
+ include/ceres/internal/numeric_diff.h
include/ceres/internal/port.h
include/ceres/internal/scoped_ptr.h
+ include/ceres/internal/variadic_evaluate.h
include/ceres/iteration_callback.h
include/ceres/jet.h
include/ceres/local_parameterization.h
include/ceres/loss_function.h
include/ceres/normal_prior.h
include/ceres/numeric_diff_cost_function.h
+ include/ceres/numeric_diff_functor.h
+ include/ceres/ordered_groups.h
include/ceres/problem.h
include/ceres/rotation.h
include/ceres/sized_cost_function.h
@@ -140,6 +157,7 @@ set(SRC
internal/ceres/compressed_row_jacobian_writer.h
internal/ceres/compressed_row_sparse_matrix.h
internal/ceres/conjugate_gradients_solver.h
+ internal/ceres/coordinate_descent_minimizer.h
internal/ceres/corrector.h
internal/ceres/cxsparse.h
internal/ceres/dense_jacobian_writer.h
@@ -149,6 +167,7 @@ set(SRC
internal/ceres/detect_structure.h
internal/ceres/dogleg_strategy.h
internal/ceres/evaluator.h
+ internal/ceres/execution_summary.h
internal/ceres/file.h
internal/ceres/gradient_checking_cost_function.h
internal/ceres/graph_algorithms.h
@@ -160,13 +179,19 @@ set(SRC
internal/ceres/linear_least_squares_problems.h
internal/ceres/linear_operator.h
internal/ceres/linear_solver.h
+ internal/ceres/line_search_direction.h
+ internal/ceres/line_search.h
+ internal/ceres/line_search_minimizer.h
+ internal/ceres/low_rank_inverse_hessian.h
internal/ceres/map_util.h
internal/ceres/matrix_proto.h
internal/ceres/minimizer.h
internal/ceres/mutex.h
internal/ceres/parameter_block.h
+ internal/ceres/parameter_block_ordering.h
internal/ceres/partitioned_matrix_view.h
- internal/ceres/polynomial_solver.h
+ internal/ceres/polynomial.h
+ internal/ceres/preconditioner.h
internal/ceres/problem_impl.h
internal/ceres/program_evaluator.h
internal/ceres/program.h
@@ -177,7 +202,7 @@ set(SRC
internal/ceres/schur_complement_solver.h
internal/ceres/schur_eliminator.h
internal/ceres/schur_eliminator_impl.h
- internal/ceres/schur_ordering.h
+ internal/ceres/schur_jacobi_preconditioner.h
internal/ceres/scratch_evaluate_preparer.h
internal/ceres/solver_impl.h
internal/ceres/sparse_matrix.h
@@ -191,6 +216,7 @@ set(SRC
internal/ceres/trust_region_strategy.h
internal/ceres/visibility_based_preconditioner.h
internal/ceres/visibility.h
+ internal/ceres/wall_time.h
)
#if(FALSE)
diff --git a/extern/libmv/third_party/ceres/ChangeLog b/extern/libmv/third_party/ceres/ChangeLog
index 8b84328cf98..ebfb771be02 100644
--- a/extern/libmv/third_party/ceres/ChangeLog
+++ b/extern/libmv/third_party/ceres/ChangeLog
@@ -1,524 +1,572 @@
-commit 552f9f85bba89f00ca307bc18fbda1dff23bd0e4
+commit d2a5195b512164fec286c6a52b40d7766977caa3
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Aug 31 07:27:22 2012 -0700
+Date: Sun Feb 24 15:09:17 2013 -0800
- Various minor bug fixes to the solver logic.
+ Version history update.
- 1. CostFunction returning false is handled better.
- If only the cost is being evaluated, it is possible to
- use the false value as an infinite value signal/outside
- a region of validity. This allows a weak form of constraint
- handling. Useful for example in handling infinities.
+ Change-Id: I477ec05a78ca4cd735a525253c9b6adfa3bddea7
+
+commit 2160c5b757c44206c6face6ca62d381f1db7a291
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Sun Feb 24 14:15:45 2013 -0800
+
+ Minor release script fixes.
- 2. Changed the way how the slop around zero when model_cost
- is larger than the current cost. Relative instead of absolute
- tolerances are used. The same logic is propagated how the
- corresponding clamping of the model_cost is done.
+ Change-Id: Ifd0a7f4f584c85d4d9574eca46094b372a8d7aff
+
+commit b53c9667f508c125b8aa833e7a063fa44ef8a98e
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Mon Feb 25 01:14:26 2013 +0600
+
+ Solve No Previous Prototype GCC warning
- 3. Fixed a minor indexing bug in nist.cc.
+ In some cases there were missing includes of own
+ header files from implementation files.
- 4. Some minor logging fixes to nist.cc to make it more
- compatible with the rest of ceres.
+ In other cases moved function which are only used
+ within single file into an anonymous namespace.
- Together these changes, take the successful solve count from
- 41/54 to 46/54 and eliminate all NUMERICAL_FAILURE problems.
+ Change-Id: I2c6b411bcfbc521e2a5f21265dc8e009a548b1c8
+
+commit 267ccc45a3e875bf87832a8ad615be690b4926d3
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Mon Feb 25 01:04:16 2013 +0600
+
+ Fix for MinGW build on Windows
- Change-Id: If94170ea4731af5b243805c0200963dd31aa94a7
+ GG_LONGLONG and GG_ULONGLONG shall use LL and ULL suffixes,
+ since MinGW is actuall a GCC compiler.
+
+ Solved by checking whether compilation happens with MinGW
+ or not using standard MinGW's __MINGW32__ and __MINGW64__
+ definitions.
+
+ Change-Id: I789b34f6342a56ba42f4b280f7242700022ab7a1
-commit 0b776b5cc9634d3b88d623905b96006f7647ce3e
+commit 509f68cfe3fd13b794c4e67ff38c761407c858cf
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Aug 30 15:26:17 2012 -0700
+Date: Wed Feb 20 01:39:03 2013 -0800
- Update docs.
+ Problem::Evaluate implementation.
+
+ 1. Add Problem::Evaluate and tests.
+ 2. Remove Solver::Summary::initial/final_*
+ 3. Remove Solver::Options::return_* members.
+ 4. Various cpplint cleanups.
- Change-Id: I69d50bcd37aed3bea2190ca614f023e83172901b
+ Change-Id: I4266de53489896f72d9c6798c5efde6748d68a47
-commit 2d7176ad7c8fb7238ca8abd6de73415d95877494
-Author: Petter Strandmark <petter.strandmark@gmail.com>
-Date: Thu Aug 30 19:51:24 2012 -0700
+commit d4a0bf86d688d1b68e00ff302858de5a4e0d9727
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sun Feb 24 10:35:44 2013 -0800
- max_consecutive_nonmonotonic_steps should be int
+ Fix threading build on Windows.
+
+ On Windows, including the "windows.h" header defines an enormous number of
+ symbols; some of which are macros with common names. In particular, "ERROR" and
+ "min" and "max" get defined. This causes clashes when user code references
+ these names in a context other than the intended use in windows.h.
+
+ To deal with this, the Microsoft engineers added the ability to control the
+ definition of these symbols by adding extra defines. In particular, including
+ windows.h in the following way
- Found via Visual Studio warning.
+ #define NOGDI
+ #define NOMINMAX
- Change-Id: Id2cd7de562dfc8cd35df5d5f5220dd2d7350eb2c
+ will reduce the number of macros defined. This way they will not conflict with
+ other uses in Ceres. For example, numeric_limits<double>::max() is impossible
+ to call without defining NOMINMAX.
+
+ Change-Id: I166f5d3bb6dc0e2e4b2ebf800fb19e49206f7874
-commit 1a89bcc94e88933f89b20427a45bc40cdd23c056
+commit beb4505311011130a7e54632137b0fbb5824cc9b
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Aug 30 15:26:17 2012 -0700
+Date: Fri Feb 22 13:37:01 2013 -0800
- Better reporting on the NIST problems.
+ Minor fixes
+
+ Based on William Rucklidge's review, including
+ a nasty bug in parameter block removal.
- Change-Id: I7cf774ec3242c0612dbe52fc233c3fc6cff3f031
+ Change-Id: I3a692e589f600ff560ecae9fa85bb0b76063d403
-commit ea11704857a1e4a735e096896e4d775d83981499
+commit 9a88bd7c4b40e2a1e0cd9b0dc09a3517c467e04e
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Aug 29 18:18:48 2012 -0700
+Date: Tue Feb 19 13:09:12 2013 -0800
- Basic harness for testing NIST problems.
+ Minor bug fixes
- Change-Id: I5baaa24dbf0506ceedf4a9be4ed17c84974d71a1
+ Change-Id: I94e4521adf76a6c77db954c4a8955168e9d37b55
-commit 98bf14d2b95386c2c4a6c29154637943dae4c36c
+commit 956ed7e8f2054623615e6ae3601055d613897f26
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Aug 30 10:26:44 2012 -0700
+Date: Tue Feb 19 07:06:15 2013 -0800
- Miscellaneous fixes.
+ Various minor fixes.
+
+ 1. Unused variable warnings and fixes.
+ 2. Minor documentation update.
- Change-Id: I521e11f2d20bf24960bbc6b5dab4ec8bb1503d23
+ Change-Id: I815588a5806df1030a7c8750f4fb594c503f8998
-commit 1e3cbd9a4442cdd8fda43a7fb452f19dac8c74af
-Author: Petter Strandmark <strandmark@google.com>
-Date: Wed Aug 29 09:39:56 2012 -0700
+commit 3e2c4ef9ad35e94198f4f3367b99fd91e26996a1
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sun Feb 17 12:37:55 2013 -0800
- Caching the symbolic Cholesky factorization when using CXSparse
-
- Average factorization times for bundle adjustment test problem:
- SuiteSparse: 0.2794 s.
- CXSparse: 0.4039 s.
- CXSparse cached: 0.2399 s.
+ Add adapters for column/row-major matrices to rotation.h
- CXSparse will still be slower, though, because it has to compute
- the transpose and J^T * J.
+ This patch introduces a matrix wrapper (MatrixAdapter) that allows to
+ transparently pass pointers to row-major or column-major matrices
+ to the conversion functions.
- Change-Id: If9cdaa3dd520bee84b56e5fd4953b56a93db6bde
+ Change-Id: I7f1683a8722088cffcc542f593ce7eb46fca109b
-commit 8b64140878ccd1e183d3715c38942a81fdecefde
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Aug 29 05:41:22 2012 -0700
+commit 04938efe4bedec112083c5ceb227ba004f96bd01
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sun Feb 17 12:37:55 2013 -0800
- Documentation update
+ Add support for removing parameter and residual blocks.
- Change-Id: I271a0422e7f6f42bcfd1dc6b5dc10c7a18f6a179
-
-commit a5353acd85a9fd19370b3d74035d87b0f0bac230
-Author: Petter Strandmark <petter.strandmark@gmail.com>
-Date: Tue Aug 28 18:16:41 2012 -0700
-
- Adding gflags include to test_util.cc
+ This adds support for removing parameter and residual blocks.
+ There are two modes of operation: in the first, removals of
+ paremeter blocks are expensive, since each remove requires
+ scanning all residual blocks to find ones that depend on the
+ removed parameter. In the other, extra memory is sacrificed to
+ maintain a list of the residuals a parameter block depends on,
+ removing the need to scan. In both cases, removing residual blocks
+ is fast.
- test_util seems to need gflags.
+ As a caveat, any removals destroys the ordering of the parameters,
+ so the residuals or jacobian returned from Solver::Solve() is
+ meaningless. There is some debate on the best way to handle this;
+ the details remain for a future change.
- Change-Id: I0c4757960f8ac69ad599c138aea58e3c88a4ea28
-
-commit 87ca1b2ba28ec512752bbcf5fc994ce1434eb765
-Author: Petter Strandmark <petter.strandmark@gmail.com>
-Date: Tue Aug 28 18:05:20 2012 -0700
-
- Changing random.h to use cstdlib for Windows compability.
+ This also adds some overhead, even in the case that fast removals
+ are not requested:
- As discussed with Sameer today.
+ - 1 int32 to each residual, to track its position in the program.
+ - 1 pointer to each parameter, to store the dependent residuals.
- Change-Id: If3d0284830c6591c71cc77b8400cafb45c0da61f
+ Change-Id: I71dcac8656679329a15ee7fc12c0df07030c12af
-commit aeb00a07323808a0a1816e733ad18a87d5109ea3
-Author: Petter Strandmark <strandmark@google.com>
-Date: Mon Aug 27 22:22:57 2012 -0700
+commit fa21df8cd969bb257b87c9ef7c0147d8d5ea8725
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 18 08:48:52 2013 -0800
- Removing gomp for Visual Studio
+ Add script for building documentation.
+
+ Update make_release
- Linking currently fails in Visual Studio due to a missing library
- "gomp.lib". This is not needed in Visual Studio. OpenMP works
- without it.
+ Minor documentation fixes.
- Change-Id: I39e204a8dd4f1b7425df7d4b222d86a8bb961432
+ Change-Id: I1248ec3f58be66b5929aee6f2aa392c15d53ed83
-commit 6f362464ba99b800494d2f15c27768a342ddaa68
-Author: Markus Moll <markus.moll@esat.kuleuven.be>
-Date: Tue Aug 28 01:03:38 2012 +0200
+commit 290b975d1d4eba44205bbeb0fa6b3ce8a6fa4a0c
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Sun Feb 17 16:50:37 2013 -0800
- Add some tests for DoglegStrategy.
+ Preconditioner refactoring.
- Not necessarily a complete set.
+ 1. Added a Preconditioner interface.
+ 2. SCHUR_JACOBI is now its own class and is independent of
+ SuiteSparse.
- Change-Id: I14eb3a38c6fe976c8212f3934655411b6d1e0aa4
+ Change-Id: Id912ab19cf3736e61d1b90ddaf5bfba33e877ec4
-commit 122cf836a6dc9726489ce2fbecc6143bddc1caaf
+commit d010de543530001fa917501a13ba02879c8ea52f
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Aug 24 16:28:27 2012 -0700
+Date: Fri Feb 15 14:26:56 2013 -0800
- Documentation update.
+ Solver::Summary::FullReport() supports line search now.
- Change-Id: I0a3c5ae4bc981a8f5bdd5a8905f923dc5f09a024
+ Change-Id: Ib08d300198b85d9732cfb5785af4235ca4bd5226
-commit 69081719f73da8de2935774a42d237837a91952a
-Author: Keir Mierle <mierle@gmail.com>
-Date: Mon Aug 27 13:28:56 2012 -0700
+commit fbbea464d1c9575d8224220d3e61f92d93fe9739
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Fri Feb 15 11:25:03 2013 -0800
- Remove unnecessary overload for hash<>
+ Update documentation.
- The overload for pointers in hash tables was applied in normal
- usage of schur_ordering.cc. However, the tests did not include the
- overload since they only included collections_port.h. As a result,
- the routines in schur_ordering.cc were using a different hash
- function than that inside the tests.
-
- The fix is to remove the specialization. If this breaks one of the
- compiler configurations, we will find a workaround at that time.
-
- Change-Id: Idbf60415d5e2aec0c865b514ad0c577d21b91405
+ Change-Id: Idb03741fab9facbbbda85d5a82723f0b4c1c6c60
-commit 1762420b6ed76b1c4d30b913b2cac1927b666534
+commit 8e1f83c4c457fb7238eb342eab744c5570b73c4d
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Aug 22 10:01:31 2012 -0700
+Date: Fri Feb 15 08:35:40 2013 -0800
- Update changelog.
+ Speed up Problem construction and destruction.
- Change-Id: Idf5af69d5a9dbe35f58e30a8afcbfcd29bb7ebfe
+ Change-Id: I3147b0b60eedf40f8453d5a39ff04a572c445a2f
-commit 976ab7aca908309b8282cb40bc080ca859136854
-Author: Keir Mierle <mierle@gmail.com>
-Date: Thu Aug 23 18:21:36 2012 -0700
+commit efb47f39c31f0ef1bb9c015c8c0d114153df6379
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Feb 14 19:44:11 2013 -0800
- Remove Google-era vestigial unit test.
+ Documentation update
- Change-Id: Ia7a295a5c759a17c1675a3055d287d3e40e9e0fe
+ Change-Id: I0fec43bff4fe0ea6cd2d2a8b34dac2330a517da0
-commit 6ad6257de0e2152ac5e77dc003758de45187d6ea
-Author: Keir Mierle <mierle@gmail.com>
-Date: Wed Aug 22 11:10:31 2012 -0700
+commit be418a336cae5672111e0f6989e6d8d6c1fa24a6
+Author: Markus Moll <markus.moll@esat.kuleuven.be>
+Date: Fri Feb 15 17:19:28 2013 +0100
- Add a workaround for an Android NDK compiler bug.
-
- On certain NDK build configurations, one of the innermost
- parts of the Schur eliminator would get compiled
- incorrectly. The compiler changed a -= to a +=.
+ Fix evaluation of initial cost and corresponding test
- The normal Ceres unit tests caught the problem; however,
- since it is not possible to build the tests with the NDK
- (only with the standalone toolchain) this was difficult to
- track down. Finding the issue involved pasting the schur
- eliminator unit test inside of solver_impl.cc and other such
- hacks.
+ Commit f102a68e411d11b4864e17b69a2d781e9c2692ad seems to have introduced
+ a bug in both solver_impl.cc and solver_impl_test.cc
+ solver_impl_test showed 3 errors, where two were due to ceres NOT
+ failing when the test expected that, and one was due to the initial cost
+ being wrong (-1 instead of 0.5)
+ Ceres now does not attempt to evaluate the initial cost if
+ options.return_initial_xxx is not set. It therefore did not fail in
+ the tests.
+ It also seems that the CERES_EVALUATE macro erroneously always sets
+ final_cost, even when called with 'initial' as argument.
- Change-Id: Ie91bb545d74fe39f0c8cbd1a6eb69ee4d8b25fb2
+ Change-Id: Ia3c3eeb476e7023a3f80b201124010d6c67e9824
-commit aecb2dc92b4aa7f3bf77a1ac918e62953602392b
+commit 974513a41ff1ddc671d3dc6aa09ce708bbe447da
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Aug 22 10:08:17 2012 -0700
+Date: Tue Feb 12 14:22:40 2013 -0800
- Fix relative path bug in bibtex call.
+ Bug fix in DynamicAutoDiffCostFunction
+
+ Add handling of constant parameter blocks.
- Change-Id: I0d31786564320a6831259bcdf4c75a6b665c43ad
+ Change-Id: I8b2ea79f47e190604fc4bed27705798240689f71
-commit 1e2892009e591804df6286caebd5c960e7e3b099
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Aug 21 18:00:54 2012 -0700
+commit 3130b3cea4028c71d9ae18b7465d7627f29fef7d
+Author: Keir Mierle <mierle@gmail.com>
+Date: Mon Feb 11 19:39:29 2013 -0800
- Update Summary::FullReport to report dogleg type.
+ Add support for dynamic autodiff
- Change-Id: I0b4be8d7486c1c4b36b299693b3fe8b0d3426537
+ Change-Id: I17d573696172ab691a9653db99a620e4bc1bd0d0
-commit 295ade1122a86b83e1ea605d5ca394f315874717
+commit c58e6dc3ea550302c8151003b17e9bc2a1acc316
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Aug 22 06:51:22 2012 -0700
+Date: Mon Feb 11 16:41:06 2013 -0800
- Fix Eigen3 Row/Column Major storage issue.
-
- Eigen3 does not allow column vectors to be stored in row-major
- format. NumericDiffCostFunction by default stores its Jacobian
- matrices in row-major format. This works fine if the residual
- contains more than one variable. But if the residual block
- depends on one variable and has more than one residuals, the
- resulting Jacobian matrix is a column matrix in row-major format
- resulting in a compile time error.
+ More refined event logging in solver_impl.cc
- The fix is to check the template parameters and switch to column-major
- storage as needed.
-
- Thanks to Lena Gieseke for reporting this.
-
- Change-Id: Icc51c5b38e1f3609e0e1ecb3c4e4a02aecd72c3b
+ Change-Id: Ie3061c921c006d2600d16185c690f52ccf816f68
-commit 9ad27e8e9fb1bbd2054e2f6ae37623e01428f1c0
-Author: Arnaud Gelas <arnaudgelas@gmail.com>
-Date: Tue Aug 21 09:56:30 2012 +0200
+commit f102a68e411d11b4864e17b69a2d781e9c2692ad
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 11 15:08:40 2013 -0800
- Add one uninstall target to remove all installed files
+ Remove extraneous initial and final evals.
- Change-Id: Ifcf89a6c27b25f28403d95a50e29c093a525298f
+ Change-Id: I80ed87435f399cbf452c68be7ea1e7139696aa4a
-commit 0c3a748ee49e04fe334f8f5a433649d18003d550
-Author: Markus Moll <markus.moll@esat.kuleuven.be>
-Date: Tue Aug 21 14:44:59 2012 +0200
+commit 0593747ee09e21a9c0a2b604d51e21a6cdd21315
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 11 13:57:12 2013 -0800
- Allow equal lower and upper bound for diagonal scaling.
+ Fix a memory leak in cxsparse.cc
- This way, setting the lower and upper bound both to 1.0, one can disable
- the automatic trust region scaling.
+ Thanks to Alexander Mordvintsev for reporting it.
- Change-Id: Ifa317a6911b813a89c1cf7fdfde25af603705319
+ Change-Id: Ia872be42ce80209e46722fc16a928496cf97e256
-commit 3d644b76adefac6475b91dc53c3ae5e01c4f4d66
-Author: Arnaud Gelas <arnaudgelas@gmail.com>
-Date: Thu Aug 16 17:33:21 2012 +0200
+commit 0abfb8f46f534b05413bb4d64b960d6fd0a9befb
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 11 13:40:04 2013 -0800
- Install headers, libraries and pdf
+ Delete the tex documentation.
- Headers are installed in ${CMAKE_INSTALL_PREFIX}/include/ceres
- Libraries are installed in ${CMAKE_INSTALL_PREFIX}/lib
- pdf is installed in ${CMAKE_INSTALL_PREFIX}/share/ceres/docs
-
- Change-Id: Ic175f2c2f5fa86820a1e8c64c2ed171f4a302a68
+ Change-Id: I15c78a8b33c5fd94941238814ac023a8fb251a20
-commit d2fb5adea4d8c2aeb43c4289c6976798a54d3cf1
-Author: Arnaud Gelas <arnaudgelas@gmail.com>
-Date: Fri Aug 17 10:11:02 2012 +0200
+commit 085cd4a6641c404334d17e5ea38f9e5b68a06ba7
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Feb 6 14:31:07 2013 -0800
- Configure gerrit hook at CMake time
+ Rewrite of the tutorial.
- If the source directory is a clone, at CMake time the commit-msg hook gets
- downloaded and installed in the right location.
+ 1. Quicker starting point.
+ 2. Better discussion of derivatives.
+ 3. Better hyperlinking to code and class documentation.
+ 4. New robust estimation example.
+ 5. Better naming of example code.
+ 6. Removed dependency on gflags in all the core examples covered
+ in the tutorial.
- Change-Id: I5fee17d050ca22d8b92a49fdcc2a1cd6659f209b
+ Change-Id: Ibf3c7fe946fa2b4d22f8916a9366df267d34ca26
-commit 73166098fc4b1072adc30321c666188a3909c43c
-Author: Arnaud Gelas <arnaudgelas@gmail.com>
-Date: Mon Aug 20 15:40:41 2012 +0200
+commit c0fdc9753909fc37fed2cb5e0fcc02fc65789d68
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Feb 6 14:31:07 2013 -0800
- Add one CMake option to build the examples.
+ Update nist.cc to better evaluate results.
- Currently the examples are always built. For external projects, it is useful
- not to compile the examples.
+ Ceres beats Minpack and HBN handily.
- Change-Id: I41d3bde19c7e742818e60f78222d39c43992ca8b
+ Change-Id: I7df8a47b753202ed0b53ab128ce48466bf9f8083
-commit 86d4f1ba41ef14eb1b6b61a7936af83387b35eb2
-Author: Keir Mierle <mierle@gmail.com>
-Date: Mon Aug 20 11:52:04 2012 -0700
+commit d91b671798125fd4889914d92a29cf0f7a5fef21
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Feb 6 01:08:40 2013 -0800
- Add missing return statement.
+ More small changes
+ More small changes to the docs.
- Change-Id: I5eaf718318e27040e3c97e32ee46cf0a11176a37
-
-commit 51eb229da34187a4e8ce73ed9cc0e731998bb2be
-Author: Keir Mierle <mierle@gmail.com>
-Date: Mon Aug 20 11:46:12 2012 -0700
-
- Add Program::ToString() to aid debugging.
+ 1. Better landing page.
+ 2. Minor tweaks to the side bar.
+ 3. Reference to more example code.
+ 4. Local MathJax references.
- Change-Id: I0ab37ed2fe0947ca87a152919d4e7dc9b56dedc6
+ Change-Id: I39b9436dc2803732a875bbbee7f15802c4934031
-commit bcc7100635e2047dc2b77df19a4ded8a6ab4d4b9
-Author: Keir Mierle <mierle@gmail.com>
-Date: Mon Aug 20 11:45:04 2012 -0700
+commit 42a84b87fa5cc34551244a3b2b6a3e1f13a29514
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Fri Feb 1 12:22:53 2013 -0800
- Ignore minted.sty.
+ Expand reporting of timing information.
- Change-Id: I2467a6f801812b9007b51bf14b00757f026e4322
+ 1. Add an ExecutionSummary object to record execution
+ information about Ceres objects.
+ 2. Add an EventLogger object to log events in a function call.
+ 3. Add a ScopedExecutionTimer object to log times in ExecutionSummary.
+ 4. Instrument ProgramEvaluator and all the linear solvers
+ to report their timing statistics.
+ 5. Connect the timing statistics to Summary::FullReport.
+ 6. Add high precision timer on unix systems using
+ gettimeofday() call.
+ 7. Various minor clean ups all around.
+
+ Change-Id: I5e09804b730b09535484124be7dbc1c58eccd1d4
-commit 9705a736dd3d6fbead0d8a6ff77102c69bbcdc08
-Author: Keir Mierle <mierle@gmail.com>
-Date: Mon Aug 20 11:24:05 2012 -0700
+commit 08c891fcb6ea1bf66e6d4619273765a644605dfc
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 4 20:18:58 2013 -0800
- Add ParameterBlock::ToString() to aid debugging.
+ Various small changes.
- Change-Id: Id3f5cb27b855c536dd65a986f345bd8eb2799dfa
+ 1. Compact build instructions.
+ 2. Lots of small edits by Simon Fuhrmann.
+
+ Change-Id: I8c0c67922021041dcf7f4ecdb6c6e6dd2e2fd7e5
-commit 0c714a70e6123ceb68e5cfcd3cfbee0d09deb1db
+commit e2e857ad6be322e9cf750d4b11ccf10800e57d96
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Aug 20 11:18:16 2012 -0700
+Date: Mon Feb 4 19:40:45 2013 -0800
- Fix blanks before private in loss_function.h
+ Sidebar has global table of contents.
- Change-Id: I068bed6431bc7c9b7958af391655df61499000b2
+ Change-Id: I7fe9053868a4660b0db8d7607ee618fc30ddaefd
-commit 51cf7cbe3bac45c6807c2703a2fc3175d76a1b47
-Author: Markus Moll <markus.moll@esat.kuleuven.be>
-Date: Mon Aug 20 20:10:20 2012 +0200
+commit b9182147d96f865673c2756ced4cbb127ca082a3
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 4 17:55:25 2013 -0800
- Add the two-dimensional subspace search to DoglegStrategy
+ Change the theme to be closer to ReadTheDocs.org
- Change-Id: I5163744c100cdf07dd93343d0734ffe0e80364f3
+ Change-Id: I61a76f5b5e5c292b54fdf51b66940ce80bd1cd5f
-commit ad1f7b772e559a911ac3a3b078b0aee1836fe785
+commit 3d87b72c895835bbfc10965d50dc96608632114d
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Aug 20 11:10:34 2012 -0700
+Date: Sat Feb 2 00:49:31 2013 -0800
- Add ArcTanLoss, TolerantLoss and ComposedLossFunction.
+ Convert documentation from LaTeX to Sphinx.
- Based on work by James Roseborough.
+ A live version of the doc can be found at
- Change-Id: Idc4e0b099028f67702bfc7fe3e43dbd96b6f9256
+ http://homes.cs.washington.edu/~sagarwal/ceres-solver/
+
+ As it stands, the documentation has better hyperlinking
+ and coverage than the latex documentation now.
+
+ Change-Id: I7ede3aa83b9b9ef25104caf331e5727b4f5beae5
-commit 05292bf8fc5208b86b4a13544615b584f6efa936
+commit 71c8058478311ff9b3087360827e048dec5dd69a
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Aug 20 07:40:45 2012 -0700
+Date: Thu Jan 31 17:33:01 2013 -0800
- Add a TrustRegionStrategy::Summary object.
+ Remove ExecutionSummary from Evaluator and LinearSolver
- Change-Id: I7caee35a3408ee4a0ec16ba407410d822929340d
+ Change-Id: If4dbaf516a8b14e0a79e1a2116ce66a99ed4a592
-commit b12b906c4d21c3949f0dce62c4c0d083c8edecf1
-Author: Arnaud Gelas <arnaudgelas@gmail.com>
-Date: Wed Aug 15 16:27:38 2012 +0200
+commit fa1c31eee33051d6483bc90fa7b66c3664b23bf3
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Tue Jan 29 17:24:54 2013 -0800
- Add one option to generate the PDF from CMake at build time
+ Correct the documentation for crs_matrix.h
- Make sure pygmentize is installed
+ Thanks to Joydeep Biswas for reporting this.
- Change-Id: I068ba45c33a8e96acc906a464b12d10d58b3e231
+ Change-Id: Iae5fc2274644aab40f2f922a671f65da15ae71fc
-commit b9f15a59361c609ffc4a328aea9be3d265b5da81
+commit bdd87c03ed1cbac62990bf79aa6faed0a132bba9
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Sat Aug 18 13:06:19 2012 -0700
+Date: Tue Jan 29 16:24:31 2013 -0800
- Add a dense Cholesky factorization based linear solver.
+ Add an ExecutionSummary object that the Evaluator and LinearSolver can use to
+ report execution statistics of all kinds.
- For problems with a small number of variables, but a large
- number of residuals, it is sometimes beneficial to use the
- Cholesky factorization on the normal equations, instead of
- the dense QR factorization of the Jacobian, even though it
- is numerically the better thing to do.
+ Currently a single map which maps arbitrary strings to doubles is supported,
+ which allows for precise timing information to be communicated.
- Change-Id: I3506b006195754018deec964e6e190b7e8c9ac8f
+ Change-Id: Ibd930aca5c9e6cae89bcfeffe9b13e2887644881
-commit b3fa009435acf476cd373052e62988f6437970b1
-Author: Arnaud Gelas <arnaudgelas@gmail.com>
-Date: Fri Aug 17 10:31:41 2012 +0200
+commit a2fd9ca8beb5aa11fcc5d2b32e23f161edc93d28
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Tue Jan 29 16:02:41 2013 -0800
- Set CMAKE_*_OUTPUT_DIRECTORY
-
- Gather
- * all executables in ${CMAKE_BINARY_DIR}/bin
- * all libraries (static and dynamic) in ${CMAKE_BINARY_DIR}/lib
+ Fix Android.mk
- Change-Id: Ibc2fa1adfb6f0aea65d66d570259b79546bf3b07
+ Change-Id: I1093c2731283890d1f3792bf8e6741f448f1465d
-commit 1b8a4d5d11671ed83cf6077e363dd95333f08ef8
+commit 977be7cac37316524038fa0168cc5994a5654acd
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Aug 17 16:49:11 2012 -0700
+Date: Sat Jan 26 16:01:54 2013 -0800
- Fix a minor bug in detect_structure logging.
+ Add support for reporting linear solver and inner iteration
+ orderings.
- Change-Id: I117f7745e4c67595b3ff9244cde82b5b5b34ee4b
+ Change-Id: I0588a4285e0925ce689e47bd48ddcc61ce596a1f
-commit 31c1e784ab2cb9294c6e05414cf06aae2b3766de
-Author: Keir Mierle <mierle@gmail.com>
-Date: Fri Aug 17 16:16:32 2012 -0700
+commit 146b9acb4d5570da311fedb5222ad65fe12f233c
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Jan 21 16:16:58 2013 -0800
- Minor cleanups.
+ Update include/ceres.h to export headers.
+ Update the ABI version.
- Change-Id: Ida4866997deeaa1bc2cebd6b69313a05ac82e457
+ Change-Id: I5c1c4f110cddc816bbb5a737634f55b4cbea98e1
-commit e83f7879a8b21c6976e116958caf35bcdcf41cb0
+commit e837aeaf9e63936d745519fa53c726a2ca9d5822
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Aug 17 15:34:42 2012 -0700
+Date: Mon Jan 21 13:05:01 2013 -0800
- Fix SuiteSparse3 UFConfig.h detection really.
+ Documentation update.
- Change-Id: Id187102e755b7d778dff4363f22f9a4697ed12dd
+ Change-Id: Ica8681f4bb58c60349d0dae453c652f2522eebf6
-commit 96f25dc57658d296ee6b6633818b4f1e51d7d587
+commit 2f0d7249ccedac8183e6e5a9cb45ca7c51bb6b41
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Aug 17 15:34:42 2012 -0700
+Date: Fri Jan 18 13:11:32 2013 -0800
- Fix SuiteSparse3 UFConfig.h detection.
+ NumericDiffFunctor.
- Change-Id: Ia59aefdb0ad7f713f76ed79692f2db4fa2821e5b
-
-commit c497bd6cd9aa944f518aa491d3bc645851ff9594
-Author: Markus Moll <markus.moll@esat.kuleuven.be>
-Date: Fri Aug 17 14:40:13 2012 +0200
-
- Add UFconfig and/or SuiteSparse_config test to CMakeLists.txt
+ A wrapper class that takes a variadic functor evaluating a
+ function, numerically differentiates it and makes it available as a
+ templated functor so that it can be easily used as part of Ceres'
+ automatic differentiation framework.
- SuiteSparse 4 requires linking to libsuitesparseconfig.a.
- Both SuiteSparse 3 and SuiteSparse 4 require an additional header
- (either UFconfig.h or SuiteSparse_config.h) that is not found if it is
- in a separate path. Therefore, add explicit checks.
+ The tests for NumericDiffCostFunction and NumericDiffFunctor have
+ a lot of stuff that is common, so refactor them to reduce code.
- Change-Id: I699902b5db4f1b7f17134b5a54f9aa681445e294
+ Change-Id: I83b01e58b05e575fb2530d15cbd611928298646a
-commit 383c04f4236d92801c7c674892814362dedf7ad6
+commit 2fc0ed6143ad499d6dc82d621ff5ec69170beb52
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Aug 17 10:14:04 2012 -0700
+Date: Tue Jan 15 11:34:10 2013 -0800
- Fix QuaternionToAngleAxis to ensure rotations are between -pi and pi.
+ Change NumericDiffCostFunction to accept variadic functors.
+
+ The interface for NumericDiffCostFunction and AutoDiffCostFunction
+ are not comparable. They both accept variadic functors.
- Thanks to Guoxuan Zhang for reporting this.
+ The change is backward compatible, as it still supports numeric
+ differentiation of CostFunction objects.
- Change-Id: I2831ca3a04d5dc6467849c290461adbe23faaea3
+ Some refactoring of documentation and code in auto_diff_cost_function
+ and its relatives was also done to make things consistent.
+
+ Change-Id: Ib5f230a1d4a85738eb187803b9c1cd7166bb3b92
-commit dd2b17d7dd9750801ba4720bdece2062e59b7ae3
+commit 9c5acce674e3ec1ba08509123ff519f106cc4348
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Aug 16 19:34:57 2012 -0700
+Date: Sun Jan 13 22:14:12 2013 -0800
- CERES_DONT_HAVE_PROTOCOL_BUFFERS -> CERES_NO_PROTOCOL_BUFFERS.
+ Add CostFunctionToFunctor.
+
+ CostFunctionToFunctor wraps a CostFunction, and makes it available
+ as a templated functor that can be called from other templated
+ functors. This is useful for when one wants to mix automatic,
+ numeric and analytic differentiated functions.
+
+ Also a bug fix in autodiff.h
- Change-Id: I6c9f50e4c006faf4e75a8f417455db18357f3187
+ Change-Id: If8ba281a89fda976ef2ce10a5844a74c4ac7b84a
-commit 8b4cb7aa2c74a0da62c638b2023566aa242af995
+commit c89ea4b9de588e2e2e82c54cd1c30cddb11454c5
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Aug 16 19:26:55 2012 -0700
+Date: Wed Jan 9 16:09:35 2013 -0800
- Fix sparse linear algebra library logging in Summary::FullReport.
+ Minor corrections based on Jim Roseborough's comments
- Change-Id: Id2c902dc86c00954fde7749c7b4a67dd94215a31
+ Change-Id: I4a8c7a454ddf038a3ed2567c101f9aee582044bf
-commit 47d26bcd3b38b5ff53b34768c33b499d47b26bd0
-Author: Markus Moll <markus.moll@esat.kuleuven.be>
-Date: Thu Aug 16 00:23:38 2012 +0200
+commit 00c8a061929b912bda3cfd4615fb8688c246c969
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sat Dec 1 13:22:59 2012 -0800
- Do not implicitly negate the step in the TrustRegionMinimizer.
-
- In the TrustRegionMinimizer, the step is currently implicitly negated.
- This is done so that the linearized residual is |r - J*step|^2, which
- corresponds to J*step = r, so neither J nor r have to be modified.
- However, it leads to the rather unintuitive situation that the strategy
- returns a step in positive gradient direction, which you would expect to
- increase the function value. One way is to rename the "step" parameter in
- the strategy to "negative_step" and document it.
- This patch instead moves the negation inside the strategy, just around
- the linear solver call, so that it is done in a local context and easier
- to document.
+ Fix bug in DenseSparseMatrix::ToDenseMatrix().
- Change-Id: Idb258149a01f61c64e22128ea221c5a30cd89c89
+ Change-Id: I74a1a03149d74fbc4268ec3ce9d20e09746a7227
-commit 51da590c8457e6664f76fe9813425a0c71351497
-Author: Markus Moll <markus.moll@esat.kuleuven.be>
-Date: Fri Aug 17 12:56:09 2012 +0200
+commit bcac4de5b75cae210c5557c81239222176d2709a
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Fri Nov 30 23:11:26 2012 -0800
- Remove tmp file
+ Speedup corrector.cc
+
+ Add a specialization for the common case where the residual block
+ outputs exactly one residual.
- Change-Id: I07496fafae7b0c5c12cc26ae336e0db3b5592735
+ The matrix routines used by Corrector can be then specialized to
+ a scalar and be made considerably faster.
+
+ For denoising upto 400% speedup is observed.
+
+ Change-Id: I8e3f24b8ba41caa8e62ad97c5f5e96ab6ea47150
-commit 7006a1f2b1701b8d89b8d1525fc0101943802221
+commit 9883fc396b2913fbc597afa795c39d365229c299
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Aug 16 18:04:22 2012 -0700
+Date: Fri Nov 30 12:32:43 2012 -0800
- Correct example code in Powell's function example.
+ Refactoring of the LineSearchMinimizer.
- Thanks to Petter Strandmark for pointing this out.
+ 1. New LineSearchDirection interface, factory and instances.
+ 2. Cleanup of LineSearchMinimizer to use the State and Direction objects.
+ 3. LBFGS -> LowRankInverseHessian.
+ 4. Refactoring of the RunCallbacks function and share it across
+ LineSearchMinimizer and TrustRegionMinimizer.
- Change-Id: I967632235dccdb481396e94904bb911c9a1efe1e
+ Change-Id: I19354afc6f5d6567b28918710c2012dc30ef8f32
-commit 57a44b27bc6fc95b4e70fdc25c25c9925a2072a0
-Author: Keir Mierle <mierle@gmail.com>
-Date: Thu Aug 16 17:04:50 2012 -0700
+commit 2293cb5bc96a5b317ed4ca52aa3494cadecbc07c
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Nov 29 16:00:18 2012 -0800
- Remove unnecessary flags in NDK build.
+ Add missing documentation to solver.h
- Change-Id: Ib5b4d0b7f2d898671252734978c789b8171d96a8
+ Change-Id: I86e7c4f1f6cc1e15d5eb2cf23e73c32d94d458c1
-commit f21bee247251a8b2e836c215a84c4668c31d75cd
-Author: Keir Mierle <mierle@gmail.com>
-Date: Thu Aug 16 16:27:10 2012 -0700
+commit aed99615c017839df09c98f518dcc0a59a9819ec
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Nov 29 10:33:19 2012 -0800
- Fix for fpclassify.h NDK porting work.
+ Expose lbfgs rank in solver.h
- Change-Id: I69df1b4caf2941ed96a53e35e43ec54073f84f59
+ Change-Id: Ibc184b1a2f94a4057fa6569d539ca3a55d6d6098
-commit 8ceb02cb75b66602de44a35e413225386cb21c27
-Author: Keir Mierle <mierle@gmail.com>
-Date: Thu Aug 16 14:23:47 2012 -0700
+commit 1afd498f50ef520868c18a0f26b55409d8471ceb
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Nov 29 10:28:11 2012 -0800
- Add Android NDK build files.
+ String to and from enum conversion routines.
+
+ Update types.h/cc with stringication and unstringication
+ routines for the newly introduced enums.
- This adds a Android.mk build that builds a Ceres static library
- suitable for embetting in larger Android applications. This is
- useful when needing to build Ceres without GPL'd components, since
- the standalone toolchain (needed for the CMake Android build) does
- not work with STLPort.
+ Change-Id: I0fe2842b5b1c75ba351f4ab87ec9fa60af2f9ed2
+
+commit 3e8d192f2871bcf6d5f248c119c8a6eef19186d3
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Nov 28 17:20:22 2012 -0800
+
+ Add a rough implementation of LBFGS.
- Change-Id: I8d857237f6f82658741017d161b2e31d9a20e5a7
+ Change-Id: I2bc816adfe0c02773a23035ea31de3cddc1322a4
diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh
index ccf6d0aca16..b2c8330ec3e 100755
--- a/extern/libmv/third_party/ceres/bundle.sh
+++ b/extern/libmv/third_party/ceres/bundle.sh
@@ -9,7 +9,8 @@ fi
repo="https://ceres-solver.googlesource.com/ceres-solver"
branch="master"
-tag="1.3.0"
+#tag="1.4.0"
+tag=""
tmp=`mktemp -d`
checkout="$tmp/ceres"
@@ -120,6 +121,7 @@ set(INC
include
internal
../gflags
+ ../../
)
set(INC_SYS
diff --git a/extern/libmv/third_party/ceres/files.txt b/extern/libmv/third_party/ceres/files.txt
index 55083572977..8f4b7b97b50 100644
--- a/extern/libmv/third_party/ceres/files.txt
+++ b/extern/libmv/third_party/ceres/files.txt
@@ -2,21 +2,28 @@ include/ceres/autodiff_cost_function.h
include/ceres/ceres.h
include/ceres/conditioned_cost_function.h
include/ceres/cost_function.h
+include/ceres/cost_function_to_functor.h
include/ceres/crs_matrix.h
+include/ceres/dynamic_autodiff_cost_function.h
include/ceres/fpclassify.h
+include/ceres/gradient_checker.h
include/ceres/internal/autodiff.h
include/ceres/internal/eigen.h
include/ceres/internal/fixed_array.h
include/ceres/internal/macros.h
include/ceres/internal/manual_constructor.h
+include/ceres/internal/numeric_diff.h
include/ceres/internal/port.h
include/ceres/internal/scoped_ptr.h
+include/ceres/internal/variadic_evaluate.h
include/ceres/iteration_callback.h
include/ceres/jet.h
include/ceres/local_parameterization.h
include/ceres/loss_function.h
include/ceres/normal_prior.h
include/ceres/numeric_diff_cost_function.h
+include/ceres/numeric_diff_functor.h
+include/ceres/ordered_groups.h
include/ceres/problem.h
include/ceres/rotation.h
include/ceres/sized_cost_function.h
@@ -54,6 +61,8 @@ internal/ceres/compressed_row_sparse_matrix.h
internal/ceres/conditioned_cost_function.cc
internal/ceres/conjugate_gradients_solver.cc
internal/ceres/conjugate_gradients_solver.h
+internal/ceres/coordinate_descent_minimizer.cc
+internal/ceres/coordinate_descent_minimizer.h
internal/ceres/corrector.cc
internal/ceres/corrector.h
internal/ceres/cxsparse.cc
@@ -71,6 +80,7 @@ internal/ceres/dogleg_strategy.cc
internal/ceres/dogleg_strategy.h
internal/ceres/evaluator.cc
internal/ceres/evaluator.h
+internal/ceres/execution_summary.h
internal/ceres/file.cc
internal/ceres/file.h
internal/ceres/generated/schur_eliminator_2_2_2.cc
@@ -107,18 +117,31 @@ internal/ceres/linear_operator.cc
internal/ceres/linear_operator.h
internal/ceres/linear_solver.cc
internal/ceres/linear_solver.h
+internal/ceres/line_search.cc
+internal/ceres/line_search_direction.cc
+internal/ceres/line_search_direction.h
+internal/ceres/line_search.h
+internal/ceres/line_search_minimizer.cc
+internal/ceres/line_search_minimizer.h
internal/ceres/local_parameterization.cc
internal/ceres/loss_function.cc
+internal/ceres/low_rank_inverse_hessian.cc
+internal/ceres/low_rank_inverse_hessian.h
internal/ceres/map_util.h
internal/ceres/matrix_proto.h
+internal/ceres/minimizer.cc
internal/ceres/minimizer.h
internal/ceres/mutex.h
internal/ceres/normal_prior.cc
internal/ceres/parameter_block.h
+internal/ceres/parameter_block_ordering.cc
+internal/ceres/parameter_block_ordering.h
internal/ceres/partitioned_matrix_view.cc
internal/ceres/partitioned_matrix_view.h
-internal/ceres/polynomial_solver.cc
-internal/ceres/polynomial_solver.h
+internal/ceres/polynomial.cc
+internal/ceres/polynomial.h
+internal/ceres/preconditioner.cc
+internal/ceres/preconditioner.h
internal/ceres/problem.cc
internal/ceres/problem_impl.cc
internal/ceres/problem_impl.h
@@ -137,8 +160,8 @@ internal/ceres/schur_complement_solver.h
internal/ceres/schur_eliminator.cc
internal/ceres/schur_eliminator.h
internal/ceres/schur_eliminator_impl.h
-internal/ceres/schur_ordering.cc
-internal/ceres/schur_ordering.h
+internal/ceres/schur_jacobi_preconditioner.cc
+internal/ceres/schur_jacobi_preconditioner.h
internal/ceres/scratch_evaluate_preparer.cc
internal/ceres/scratch_evaluate_preparer.h
internal/ceres/solver.cc
@@ -166,3 +189,5 @@ internal/ceres/visibility_based_preconditioner.cc
internal/ceres/visibility_based_preconditioner.h
internal/ceres/visibility.cc
internal/ceres/visibility.h
+internal/ceres/wall_time.cc
+internal/ceres/wall_time.h
diff --git a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h
index da9ee2c7993..e758d3a2bd5 100644
--- a/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h
+++ b/extern/libmv/third_party/ceres/include/ceres/autodiff_cost_function.h
@@ -28,10 +28,10 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
//
-// Helpers for making CostFunctions as needed by the least squares framework,
-// with Jacobians computed via automatic differentiation. For more information
-// on automatic differentation, see the wikipedia article at
-// http://en.wikipedia.org/wiki/Automatic_differentiation
+// Create CostFunctions as needed by the least squares framework, with
+// Jacobians computed via automatic differentiation. For more
+// information on automatic differentation, see the wikipedia article
+// at http://en.wikipedia.org/wiki/Automatic_differentiation
//
// To get an auto differentiated cost function, you must define a class with a
// templated operator() (a functor) that computes the cost function in terms of
@@ -57,8 +57,8 @@
// To write an auto-differentiable cost function for the above model, first
// define the object
//
-// class MyScalarCostFunction {
-// MyScalarCostFunction(double k): k_(k) {}
+// class MyScalarCostFunctor {
+// MyScalarCostFunctor(double k): k_(k) {}
//
// template <typename T>
// bool operator()(const T* const x , const T* const y, T* e) const {
@@ -80,32 +80,32 @@
// it can be constructed as follows.
//
// CostFunction* cost_function
-// = new AutoDiffCostFunction<MyScalarCostFunction, 1, 2, 2>(
-// new MyScalarCostFunction(1.0)); ^ ^ ^
-// | | |
-// Dimension of residual ------+ | |
-// Dimension of x ----------------+ |
-// Dimension of y -------------------+
+// = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
+// new MyScalarCostFunctor(1.0)); ^ ^ ^
+// | | |
+// Dimension of residual -----+ | |
+// Dimension of x ---------------+ |
+// Dimension of y ------------------+
//
// In this example, there is usually an instance for each measumerent of k.
//
// In the instantiation above, the template parameters following
-// "MyScalarCostFunction", "1, 2, 2", describe the functor as computing a
+// "MyScalarCostFunctor", "1, 2, 2", describe the functor as computing a
// 1-dimensional output from two arguments, both 2-dimensional.
//
// The autodiff cost function also supports cost functions with a
// runtime-determined number of residuals. For example:
//
// CostFunction* cost_function
-// = new AutoDiffCostFunction<MyScalarCostFunction, DYNAMIC, 2, 2>(
-// new CostFunctionWithDynamicNumResiduals(1.0), ^ ^ ^
-// runtime_number_of_residuals); <----+ | | |
-// | | | |
-// | | | |
-// Actual number of residuals ------+ | | |
-// Indicate dynamic number of residuals ---------+ | |
-// Dimension of x -------------------------------------+ |
-// Dimension of y ----------------------------------------+
+// = new AutoDiffCostFunction<MyScalarCostFunctor, DYNAMIC, 2, 2>(
+// new CostFunctorWithDynamicNumResiduals(1.0), ^ ^ ^
+// runtime_number_of_residuals); <----+ | | |
+// | | | |
+// | | | |
+// Actual number of residuals ------+ | | |
+// Indicate dynamic number of residuals --------+ | |
+// Dimension of x ------------------------------------+ |
+// Dimension of y ---------------------------------------+
//
// The framework can currently accommodate cost functions of up to 6 independent
// variables, and there is no limit on the dimensionality of each of them.
@@ -119,7 +119,7 @@
// functions is to get the sizing wrong. In particular, there is a tendency to
// set the template parameters to (dimension of residual, number of parameters)
// instead of passing a dimension parameter for *every parameter*. In the
-// example above, that would be <MyScalarCostFunction, 1, 2>, which is missing
+// example above, that would be <MyScalarCostFunctor, 1, 2>, which is missing
// the last '2' argument. Please be careful when setting the size parameters.
#ifndef CERES_PUBLIC_AUTODIFF_COST_FUNCTION_H_
@@ -154,16 +154,21 @@ template <typename CostFunctor,
int N2 = 0, // Number of parameters in block 2.
int N3 = 0, // Number of parameters in block 3.
int N4 = 0, // Number of parameters in block 4.
- int N5 = 0> // Number of parameters in block 5.
-class AutoDiffCostFunction :
- public SizedCostFunction<M, N0, N1, N2, N3, N4, N5> {
+ int N5 = 0, // Number of parameters in block 5.
+ int N6 = 0, // Number of parameters in block 6.
+ int N7 = 0, // Number of parameters in block 7.
+ int N8 = 0, // Number of parameters in block 8.
+ int N9 = 0> // Number of parameters in block 9.
+class AutoDiffCostFunction : public SizedCostFunction<M,
+ N0, N1, N2, N3, N4,
+ N5, N6, N7, N8, N9> {
public:
// Takes ownership of functor. Uses the template-provided value for the
// number of residuals ("M").
explicit AutoDiffCostFunction(CostFunctor* functor)
: functor_(functor) {
CHECK_NE(M, DYNAMIC) << "Can't run the fixed-size constructor if the "
- << "number of residuals is set to ceres::DYNAMIC.";
+ << "number of residuals is set to ceres::DYNAMIC.";
}
// Takes ownership of functor. Ignores the template-provided number of
@@ -174,8 +179,9 @@ class AutoDiffCostFunction :
AutoDiffCostFunction(CostFunctor* functor, int num_residuals)
: functor_(functor) {
CHECK_EQ(M, DYNAMIC) << "Can't run the dynamic-size constructor if the "
- << "number of residuals is not ceres::DYNAMIC.";
- SizedCostFunction<M, N0, N1, N2, N3, N4, N5>::set_num_residuals(num_residuals);
+ << "number of residuals is not ceres::DYNAMIC.";
+ SizedCostFunction<M, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
+ ::set_num_residuals(num_residuals);
}
virtual ~AutoDiffCostFunction() {}
@@ -190,14 +196,15 @@ class AutoDiffCostFunction :
double** jacobians) const {
if (!jacobians) {
return internal::VariadicEvaluate<
- CostFunctor, double, N0, N1, N2, N3, N4, N5>
+ CostFunctor, double, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
::Call(*functor_, parameters, residuals);
}
return internal::AutoDiff<CostFunctor, double,
- N0, N1, N2, N3, N4, N5>::Differentiate(
+ N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::Differentiate(
*functor_,
parameters,
- SizedCostFunction<M, N0, N1, N2, N3, N4, N5>::num_residuals(),
+ SizedCostFunction<M, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>
+ ::num_residuals(),
residuals,
jacobians);
}
diff --git a/extern/libmv/third_party/ceres/include/ceres/ceres.h b/extern/libmv/third_party/ceres/include/ceres/ceres.h
index 22aaf8ff21a..7878806aa45 100644
--- a/extern/libmv/third_party/ceres/include/ceres/ceres.h
+++ b/extern/libmv/third_party/ceres/include/ceres/ceres.h
@@ -34,12 +34,20 @@
#ifndef CERES_PUBLIC_CERES_H_
#define CERES_PUBLIC_CERES_H_
+#define CERES_VERSION 1.5.0
+#define CERES_ABI_VERSION 1.5.0
+
#include "ceres/autodiff_cost_function.h"
#include "ceres/cost_function.h"
+#include "ceres/cost_function_to_functor.h"
+#include "ceres/crs_matrix.h"
#include "ceres/iteration_callback.h"
+#include "ceres/jet.h"
#include "ceres/local_parameterization.h"
#include "ceres/loss_function.h"
#include "ceres/numeric_diff_cost_function.h"
+#include "ceres/numeric_diff_functor.h"
+#include "ceres/ordered_groups.h"
#include "ceres/problem.h"
#include "ceres/sized_cost_function.h"
#include "ceres/solver.h"
diff --git a/extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h b/extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h
new file mode 100644
index 00000000000..b30ecd06983
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h
@@ -0,0 +1,752 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// CostFunctionToFunctor is an adapter class that allows users to use
+// CostFunction objects in templated functors which are to be used for
+// automatic differentiation. This allows the user to seamlessly mix
+// analytic, numeric and automatic differentiation.
+//
+// For example, let us assume that
+//
+// class IntrinsicProjection : public SizedCostFunction<2, 5, 3> {
+// public:
+// IntrinsicProjection(const double* observations);
+// virtual bool Evaluate(double const* const* parameters,
+// double* residuals,
+// double** jacobians) const;
+// };
+//
+// is a cost function that implements the projection of a point in its
+// local coordinate system onto its image plane and subtracts it from
+// the observed point projection. It can compute its residual and
+// either via analytic or numerical differentiation can compute its
+// jacobians.
+//
+// Now we would like to compose the action of this CostFunction with
+// the action of camera extrinsics, i.e., rotation and
+// translation. Say we have a templated function
+//
+// template<typename T>
+// void RotateAndTranslatePoint(const T* rotation,
+// const T* translation,
+// const T* point,
+// T* result);
+//
+// Then we can now do the following,
+//
+// struct CameraProjection {
+// CameraProjection(double* observation) {
+// intrinsic_projection_.reset(
+// new CostFunctionToFunctor<2, 5, 3>(
+// new IntrinsicProjection(observation_)));
+// }
+// template <typename T>
+// bool operator(const T* rotation,
+// const T* translation,
+// const T* intrinsics,
+// const T* point,
+// T* residual) const {
+// T transformed_point[3];
+// RotateAndTranslatePoint(rotation, translation, point, transformed_point);
+//
+// // Note that we call intrinsic_projection_, just like it was
+// // any other templated functor.
+//
+// return (*intrinsic_projection_)(intrinsics, transformed_point, residual);
+// }
+//
+// private:
+// scoped_ptr<CostFunctionToFunctor<2,5,3> > intrinsic_projection_;
+// };
+
+#ifndef CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
+#define CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
+
+#include <numeric>
+#include <vector>
+
+#include "ceres/cost_function.h"
+#include "ceres/internal/fixed_array.h"
+#include "ceres/internal/port.h"
+#include "ceres/internal/scoped_ptr.h"
+
+namespace ceres {
+
+template <int kNumResiduals,
+ int N0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
+ int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
+class CostFunctionToFunctor {
+ public:
+ explicit CostFunctionToFunctor(CostFunction* cost_function)
+ : cost_function_(cost_function) {
+ CHECK_NOTNULL(cost_function);
+
+ CHECK_GE(kNumResiduals, 0);
+ CHECK_EQ(cost_function->num_residuals(), kNumResiduals);
+
+ // This block breaks the 80 column rule to keep it somewhat readable.
+ CHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0)))
+ << "Zero block cannot precede a non-zero block. Block sizes are "
+ << "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
+ << N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
+ << N8 << ", " << N9;
+
+ const vector<int16>& parameter_block_sizes =
+ cost_function->parameter_block_sizes();
+ const int num_parameter_blocks =
+ (N0 > 0) + (N1 > 0) + (N2 > 0) + (N3 > 0) + (N4 > 0) +
+ (N5 > 0) + (N6 > 0) + (N7 > 0) + (N8 > 0) + (N9 > 0);
+ CHECK_EQ(parameter_block_sizes.size(), num_parameter_blocks);
+
+ CHECK_EQ(N0, parameter_block_sizes[0]);
+ if (parameter_block_sizes.size() > 1) CHECK_EQ(N1, parameter_block_sizes[1]); // NOLINT
+ if (parameter_block_sizes.size() > 2) CHECK_EQ(N2, parameter_block_sizes[2]); // NOLINT
+ if (parameter_block_sizes.size() > 3) CHECK_EQ(N3, parameter_block_sizes[3]); // NOLINT
+ if (parameter_block_sizes.size() > 4) CHECK_EQ(N4, parameter_block_sizes[4]); // NOLINT
+ if (parameter_block_sizes.size() > 5) CHECK_EQ(N5, parameter_block_sizes[5]); // NOLINT
+ if (parameter_block_sizes.size() > 6) CHECK_EQ(N6, parameter_block_sizes[6]); // NOLINT
+ if (parameter_block_sizes.size() > 7) CHECK_EQ(N7, parameter_block_sizes[7]); // NOLINT
+ if (parameter_block_sizes.size() > 8) CHECK_EQ(N8, parameter_block_sizes[8]); // NOLINT
+ if (parameter_block_sizes.size() > 9) CHECK_EQ(N9, parameter_block_sizes[9]); // NOLINT
+
+ CHECK_EQ(accumulate(parameter_block_sizes.begin(),
+ parameter_block_sizes.end(), 0),
+ N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9);
+ }
+
+ bool operator()(const double* x0, double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_EQ(N1, 0);
+ CHECK_EQ(N2, 0);
+ CHECK_EQ(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+
+ return cost_function_->Evaluate(&x0, residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_EQ(N2, 0);
+ CHECK_EQ(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(2);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_EQ(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(3);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(4);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ parameter_blocks[3] = x3;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(5);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ parameter_blocks[3] = x3;
+ parameter_blocks[4] = x4;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(6);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ parameter_blocks[3] = x3;
+ parameter_blocks[4] = x4;
+ parameter_blocks[5] = x5;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(7);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ parameter_blocks[3] = x3;
+ parameter_blocks[4] = x4;
+ parameter_blocks[5] = x5;
+ parameter_blocks[6] = x6;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ const double* x7,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_NE(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(8);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ parameter_blocks[3] = x3;
+ parameter_blocks[4] = x4;
+ parameter_blocks[5] = x5;
+ parameter_blocks[6] = x6;
+ parameter_blocks[7] = x7;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ const double* x7,
+ const double* x8,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_NE(N7, 0);
+ CHECK_NE(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(9);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ parameter_blocks[3] = x3;
+ parameter_blocks[4] = x4;
+ parameter_blocks[5] = x5;
+ parameter_blocks[6] = x6;
+ parameter_blocks[7] = x7;
+ parameter_blocks[8] = x8;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ const double* x7,
+ const double* x8,
+ const double* x9,
+ double* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_NE(N7, 0);
+ CHECK_NE(N8, 0);
+ CHECK_NE(N9, 0);
+ internal::FixedArray<const double*> parameter_blocks(10);
+ parameter_blocks[0] = x0;
+ parameter_blocks[1] = x1;
+ parameter_blocks[2] = x2;
+ parameter_blocks[3] = x3;
+ parameter_blocks[4] = x4;
+ parameter_blocks[5] = x5;
+ parameter_blocks[6] = x6;
+ parameter_blocks[7] = x7;
+ parameter_blocks[8] = x8;
+ parameter_blocks[9] = x9;
+ return cost_function_->Evaluate(parameter_blocks.get(), residuals, NULL);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0, JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_EQ(N1, 0);
+ CHECK_EQ(N2, 0);
+ CHECK_EQ(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ return EvaluateWithJets(&x0, residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_EQ(N2, 0);
+ CHECK_EQ(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(2);
+ jets[0] = x0;
+ jets[1] = x1;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_EQ(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(3);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ const JetT* x3,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_EQ(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(4);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ jets[3] = x3;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ const JetT* x3,
+ const JetT* x4,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_EQ(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(5);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ jets[3] = x3;
+ jets[4] = x4;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ const JetT* x3,
+ const JetT* x4,
+ const JetT* x5,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_EQ(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(6);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ jets[3] = x3;
+ jets[4] = x4;
+ jets[5] = x5;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ const JetT* x3,
+ const JetT* x4,
+ const JetT* x5,
+ const JetT* x6,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_EQ(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(7);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ jets[3] = x3;
+ jets[4] = x4;
+ jets[5] = x5;
+ jets[6] = x6;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ const JetT* x3,
+ const JetT* x4,
+ const JetT* x5,
+ const JetT* x6,
+ const JetT* x7,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_NE(N7, 0);
+ CHECK_EQ(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(8);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ jets[3] = x3;
+ jets[4] = x4;
+ jets[5] = x5;
+ jets[6] = x6;
+ jets[7] = x7;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ const JetT* x3,
+ const JetT* x4,
+ const JetT* x5,
+ const JetT* x6,
+ const JetT* x7,
+ const JetT* x8,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_NE(N7, 0);
+ CHECK_NE(N8, 0);
+ CHECK_EQ(N9, 0);
+ internal::FixedArray<const JetT*> jets(9);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ jets[3] = x3;
+ jets[4] = x4;
+ jets[5] = x5;
+ jets[6] = x6;
+ jets[7] = x7;
+ jets[8] = x8;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ template <typename JetT>
+ bool operator()(const JetT* x0,
+ const JetT* x1,
+ const JetT* x2,
+ const JetT* x3,
+ const JetT* x4,
+ const JetT* x5,
+ const JetT* x6,
+ const JetT* x7,
+ const JetT* x8,
+ const JetT* x9,
+ JetT* residuals) const {
+ CHECK_NE(N0, 0);
+ CHECK_NE(N1, 0);
+ CHECK_NE(N2, 0);
+ CHECK_NE(N3, 0);
+ CHECK_NE(N4, 0);
+ CHECK_NE(N5, 0);
+ CHECK_NE(N6, 0);
+ CHECK_NE(N7, 0);
+ CHECK_NE(N8, 0);
+ CHECK_NE(N9, 0);
+ internal::FixedArray<const JetT*> jets(10);
+ jets[0] = x0;
+ jets[1] = x1;
+ jets[2] = x2;
+ jets[3] = x3;
+ jets[4] = x4;
+ jets[5] = x5;
+ jets[6] = x6;
+ jets[7] = x7;
+ jets[8] = x8;
+ jets[9] = x9;
+ return EvaluateWithJets(jets.get(), residuals);
+ }
+
+ private:
+ template <typename JetT>
+ bool EvaluateWithJets(const JetT** inputs, JetT* output) const {
+ const int kNumParameters = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9;
+ const vector<int16>& parameter_block_sizes =
+ cost_function_->parameter_block_sizes();
+ const int num_parameter_blocks = parameter_block_sizes.size();
+ const int num_residuals = cost_function_->num_residuals();
+
+ internal::FixedArray<double> parameters(kNumParameters);
+ internal::FixedArray<double*> parameter_blocks(num_parameter_blocks);
+ internal::FixedArray<double> jacobians(num_residuals * kNumParameters);
+ internal::FixedArray<double*> jacobian_blocks(num_parameter_blocks);
+ internal::FixedArray<double> residuals(num_residuals);
+
+ // Build a set of arrays to get the residuals and jacobians from
+ // the CostFunction wrapped by this functor.
+ double* parameter_ptr = parameters.get();
+ double* jacobian_ptr = jacobians.get();
+ for (int i = 0; i < num_parameter_blocks; ++i) {
+ parameter_blocks[i] = parameter_ptr;
+ jacobian_blocks[i] = jacobian_ptr;
+ for (int j = 0; j < parameter_block_sizes[i]; ++j) {
+ *parameter_ptr++ = inputs[i][j].a;
+ }
+ jacobian_ptr += num_residuals * parameter_block_sizes[i];
+ }
+
+ if (!cost_function_->Evaluate(parameter_blocks.get(),
+ residuals.get(),
+ jacobian_blocks.get())) {
+ return false;
+ }
+
+ // Now that we have the incoming Jets, which are carrying the
+ // partial derivatives of each of the inputs w.r.t to some other
+ // underlying parameters. The derivative of the outputs of the
+ // cost function w.r.t to the same underlying parameters can now
+ // be computed by applying the chain rule.
+ //
+ // d output[i] d output[i] d input[j]
+ // -------------- = sum_j ----------- * ------------
+ // d parameter[k] d input[j] d parameter[k]
+ //
+ // d input[j]
+ // -------------- = inputs[j], so
+ // d parameter[k]
+ //
+ // outputJet[i] = sum_k jacobian[i][k] * inputJet[k]
+ //
+ // The following loop, iterates over the residuals, computing one
+ // output jet at a time.
+ for (int i = 0; i < num_residuals; ++i) {
+ output[i].a = residuals[i];
+ output[i].v.setZero();
+
+ for (int j = 0; j < num_parameter_blocks; ++j) {
+ const int16 block_size = parameter_block_sizes[j];
+ for (int k = 0; k < parameter_block_sizes[j]; ++k) {
+ output[i].v +=
+ jacobian_blocks[j][i * block_size + k] * inputs[j][k].v;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private:
+ internal::scoped_ptr<CostFunction> cost_function_;
+};
+
+} // namespace ceres
+
+#endif // CERES_PUBLIC_COST_FUNCTION_TO_FUNCTOR_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h b/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
index c9fe8f78b7c..8c470cd33f2 100644
--- a/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
+++ b/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
@@ -44,17 +44,35 @@ struct CRSMatrix {
int num_rows;
int num_cols;
- // A compressed row matrix stores its contents in three arrays.
- // The non-zero pattern of the i^th row is given by
+ // A compressed row matrix stores its contents in three arrays,
+ // rows, cols and values.
//
- // rows[cols[i] ... cols[i + 1]]
+ // rows is a num_rows + 1 sized array that points into the cols and
+ // values array. For each row i:
//
- // and the corresponding values by
+ // cols[rows[i]] ... cols[rows[i + 1] - 1] are the indices of the
+ // non-zero columns of row i.
//
- // values[cols[i] ... cols[i + 1]]
+ // values[rows[i]] .. values[rows[i + 1] - 1] are the values of the
+ // corresponding entries.
//
- // Thus, cols is a vector of size num_cols + 1, and rows and values
- // have as many entries as number of non-zeros in the matrix.
+ // cols and values contain as many entries as there are non-zeros in
+ // the matrix.
+ //
+ // e.g, consider the 3x4 sparse matrix
+ //
+ // [ 0 10 0 4 ]
+ // [ 0 2 -3 2 ]
+ // [ 1 2 0 0 ]
+ //
+ // The three arrays will be:
+ //
+ //
+ // -row0- ---row1--- -row2-
+ // rows = [ 0, 2, 5, 7]
+ // cols = [ 1, 3, 1, 2, 3, 0, 1]
+ // values = [10, 4, 2, -3, 2, 1, 2]
+
vector<int> cols;
vector<int> rows;
vector<double> values;
diff --git a/extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h
new file mode 100644
index 00000000000..861164a8253
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h
@@ -0,0 +1,215 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: mierle@gmail.com (Keir Mierle)
+// sameeragarwal@google.com (Sameer Agarwal)
+// thadh@gmail.com (Thad Hughes)
+//
+// This autodiff implementation differs from the one found in
+// autodiff_cost_function.h by supporting autodiff on cost functions with
+// variable numbers of parameters with variable sizes. With the other
+// implementation, all the sizes (both the number of parameter blocks and the
+// size of each block) must be fixed at compile time.
+//
+// The functor API differs slightly from the API for fixed size autodiff; the
+// expected interface for the cost functors is:
+//
+// struct MyCostFunctor {
+// template<typename T>
+// bool operator()(T const* const* parameters, T* residuals) const {
+// // Use parameters[i] to access the i'th parameter block.
+// }
+// }
+//
+// Since the sizing of the parameters is done at runtime, you must also specify
+// the sizes after creating the dynamic autodiff cost function. For example:
+//
+// DynamicAutoDiffCostFunction<MyCostFunctor, 3> cost_function(
+// new MyCostFunctor());
+// cost_function.AddParameterBlock(5);
+// cost_function.AddParameterBlock(10);
+// cost_function.SetNumResiduals(21);
+//
+// Under the hood, the implementation evaluates the cost function multiple
+// times, computing a small set of the derivatives (four by default, controlled
+// by the Stride template parameter) with each pass. There is a tradeoff with
+// the size of the passes; you may want to experiment with the stride.
+
+#ifndef CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
+#define CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
+
+#include <cmath>
+#include <numeric>
+#include <vector>
+
+#include "ceres/cost_function.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/jet.h"
+#include "glog/logging.h"
+
+namespace ceres {
+
+template <typename CostFunctor, int Stride = 4>
+class DynamicAutoDiffCostFunction : public CostFunction {
+ public:
+ explicit DynamicAutoDiffCostFunction(CostFunctor* functor)
+ : functor_(functor) {}
+
+ virtual ~DynamicAutoDiffCostFunction() {}
+
+ void AddParameterBlock(int size) {
+ mutable_parameter_block_sizes()->push_back(size);
+ }
+
+ void SetNumResiduals(int num_residuals) {
+ set_num_residuals(num_residuals);
+ }
+
+ virtual bool Evaluate(double const* const* parameters,
+ double* residuals,
+ double** jacobians) const {
+ CHECK_GT(num_residuals(), 0)
+ << "You must call DynamicAutoDiffCostFunction::SetNumResiduals() "
+ << "before DynamicAutoDiffCostFunction::Evaluate().";
+
+ if (jacobians == NULL) {
+ return (*functor_)(parameters, residuals);
+ }
+
+ // The difficulty with Jets, as implemented in Ceres, is that they were
+ // originally designed for strictly compile-sized use. At this point, there
+ // is a large body of code that assumes inside a cost functor it is
+ // acceptable to do e.g. T(1.5) and get an appropriately sized jet back.
+ //
+ // Unfortunately, it is impossible to communicate the expected size of a
+ // dynamically sized jet to the static instantiations that existing code
+ // depends on.
+ //
+ // To work around this issue, the solution here is to evaluate the
+ // jacobians in a series of passes, each one computing Stripe *
+ // num_residuals() derivatives. This is done with small, fixed-size jets.
+ const int num_parameter_blocks = parameter_block_sizes().size();
+ const int num_parameters = std::accumulate(parameter_block_sizes().begin(),
+ parameter_block_sizes().end(),
+ 0);
+
+ // Allocate scratch space for the strided evaluation.
+ vector<Jet<double, Stride> > input_jets(num_parameters);
+ vector<Jet<double, Stride> > output_jets(num_residuals());
+
+ // Make the parameter pack that is sent to the functor (reused).
+ vector<Jet<double, Stride>* > jet_parameters(num_parameter_blocks, NULL);
+ int num_active_parameters = 0;
+ int start_derivative_section = -1;
+ for (int i = 0, parameter_cursor = 0; i < num_parameter_blocks; ++i) {
+ jet_parameters[i] = &input_jets[parameter_cursor];
+
+ const int parameter_block_size = parameter_block_sizes()[i];
+ if (jacobians[i] != NULL) {
+ start_derivative_section =
+ (start_derivative_section == -1)
+ ? parameter_cursor
+ : start_derivative_section;
+ num_active_parameters += parameter_block_size;
+ }
+
+ for (int j = 0; j < parameter_block_size; ++j, parameter_cursor++) {
+ input_jets[parameter_cursor].a = parameters[i][j];
+ }
+ }
+
+ // Evaluate all of the strides. Each stride is a chunk of the derivative to
+ // evaluate, typically some size proportional to the size of the SIMD
+ // registers of the CPU.
+ int num_strides = static_cast<int>(ceil(num_active_parameters /
+ static_cast<float>(Stride)));
+
+ for (int pass = 0; pass < num_strides; ++pass) {
+ // Set most of the jet components to zero, except for
+ // non-constant #Stride parameters.
+ int active_parameter_count = 0;
+ int end_derivative_section = start_derivative_section;
+ for (int i = 0, parameter_cursor = 0; i < num_parameter_blocks; ++i) {
+ for (int j = 0; j < parameter_block_sizes()[i];
+ ++j, parameter_cursor++) {
+ input_jets[parameter_cursor].v.setZero();
+ if (parameter_cursor >= start_derivative_section &&
+ active_parameter_count < Stride) {
+ if (jacobians[i] != NULL) {
+ input_jets[parameter_cursor]
+ .v[parameter_cursor - start_derivative_section] = 1.0;
+ ++active_parameter_count;
+ }
+ ++end_derivative_section;
+ }
+ }
+ }
+
+ if (!(*functor_)(&jet_parameters[0], &output_jets[0])) {
+ return false;
+ }
+
+ // Copy the pieces of the jacobians into their final place.
+ active_parameter_count = 0;
+ for (int i = 0, parameter_cursor = 0; i < num_parameter_blocks; ++i) {
+ for (int j = 0; j < parameter_block_sizes()[i];
+ ++j, parameter_cursor++) {
+ if (parameter_cursor >= start_derivative_section &&
+ active_parameter_count < Stride) {
+ if (jacobians[i] != NULL) {
+ for (int k = 0; k < num_residuals(); ++k) {
+ jacobians[i][k * parameter_block_sizes()[i] + j] =
+ output_jets[k].v[parameter_cursor -
+ start_derivative_section];
+ }
+ ++active_parameter_count;
+ }
+ }
+ }
+ }
+
+ // Only copy the residuals over once (even though we compute them on
+ // every loop).
+ if (pass == num_strides - 1) {
+ for (int k = 0; k < num_residuals(); ++k) {
+ residuals[k] = output_jets[k].a;
+ }
+ }
+
+ start_derivative_section = end_derivative_section;
+ }
+ return true;
+ }
+
+ private:
+ internal::scoped_ptr<CostFunctor> functor_;
+};
+
+} // namespace ceres
+
+#endif // CERES_PUBLIC_DYNAMIC_AUTODIFF_COST_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/fpclassify.h b/extern/libmv/third_party/ceres/include/ceres/fpclassify.h
index 5a9ea1599d2..b730832fd4b 100644
--- a/extern/libmv/third_party/ceres/include/ceres/fpclassify.h
+++ b/extern/libmv/third_party/ceres/include/ceres/fpclassify.h
@@ -41,6 +41,8 @@
#include <float.h>
#endif
+#include <limits>
+
namespace ceres {
#if defined(_MSC_VER)
diff --git a/extern/libmv/third_party/ceres/include/ceres/gradient_checker.h b/extern/libmv/third_party/ceres/include/ceres/gradient_checker.h
new file mode 100644
index 00000000000..3ec8056a02d
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/gradient_checker.h
@@ -0,0 +1,222 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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.
+// Copyright 2007 Google Inc. All Rights Reserved.
+//
+// Author: wjr@google.com (William Rucklidge)
+//
+// This file contains a class that exercises a cost function, to make sure
+// that it is computing reasonable derivatives. It compares the Jacobians
+// computed by the cost function with those obtained by finite
+// differences.
+
+#ifndef CERES_PUBLIC_GRADIENT_CHECKER_H_
+#define CERES_PUBLIC_GRADIENT_CHECKER_H_
+
+#include <cstddef>
+#include <algorithm>
+#include <vector>
+
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/fixed_array.h"
+#include "ceres/internal/macros.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/numeric_diff_cost_function.h"
+#include "glog/logging.h"
+
+namespace ceres {
+
+// An object that exercises a cost function, to compare the answers that it
+// gives with derivatives estimated using finite differencing.
+//
+// The only likely usage of this is for testing.
+//
+// How to use: Fill in an array of pointers to parameter blocks for your
+// CostFunction, and then call Probe(). Check that the return value is
+// 'true'. See prober_test.cc for an example.
+//
+// This is templated similarly to NumericDiffCostFunction, as it internally
+// uses that.
+template <typename CostFunctionToProbe,
+ int M = 0, int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0>
+class GradientChecker {
+ public:
+ // Here we stash some results from the probe, for later
+ // inspection.
+ struct GradientCheckResults {
+ // Computed cost.
+ Vector cost;
+
+ // The sizes of these matrices are dictated by the cost function's
+ // parameter and residual block sizes. Each vector's length will
+ // term->parameter_block_sizes().size(), and each matrix is the
+ // Jacobian of the residual with respect to the corresponding parameter
+ // block.
+
+ // Derivatives as computed by the cost function.
+ vector<Matrix> term_jacobians;
+
+ // Derivatives as computed by finite differencing.
+ vector<Matrix> finite_difference_jacobians;
+
+ // Infinity-norm of term_jacobians - finite_difference_jacobians.
+ double error_jacobians;
+ };
+
+ // Checks the Jacobian computed by a cost function.
+ //
+ // probe_point: The parameter values at which to probe.
+ // error_tolerance: A threshold for the infinity-norm difference
+ // between the Jacobians. If the Jacobians differ by more than
+ // this amount, then the probe fails.
+ //
+ // term: The cost function to test. Not retained after this call returns.
+ //
+ // results: On return, the two Jacobians (and other information)
+ // will be stored here. May be NULL.
+ //
+ // Returns true if no problems are detected and the difference between the
+ // Jacobians is less than error_tolerance.
+ static bool Probe(double const* const* probe_point,
+ double error_tolerance,
+ CostFunctionToProbe *term,
+ GradientCheckResults* results) {
+ CHECK_NOTNULL(probe_point);
+ CHECK_NOTNULL(term);
+ LOG(INFO) << "-------------------- Starting Probe() --------------------";
+
+ // We need a GradientCheckeresults, whether or not they supplied one.
+ internal::scoped_ptr<GradientCheckResults> owned_results;
+ if (results == NULL) {
+ owned_results.reset(new GradientCheckResults);
+ results = owned_results.get();
+ }
+
+ // Do a consistency check between the term and the template parameters.
+ CHECK_EQ(M, term->num_residuals());
+ const int num_residuals = M;
+ const vector<int16>& block_sizes = term->parameter_block_sizes();
+ const int num_blocks = block_sizes.size();
+
+ CHECK_LE(num_blocks, 5) << "Unable to test functions that take more "
+ << "than 5 parameter blocks";
+ if (N0) {
+ CHECK_EQ(N0, block_sizes[0]);
+ CHECK_GE(num_blocks, 1);
+ } else {
+ CHECK_LT(num_blocks, 1);
+ }
+ if (N1) {
+ CHECK_EQ(N1, block_sizes[1]);
+ CHECK_GE(num_blocks, 2);
+ } else {
+ CHECK_LT(num_blocks, 2);
+ }
+ if (N2) {
+ CHECK_EQ(N2, block_sizes[2]);
+ CHECK_GE(num_blocks, 3);
+ } else {
+ CHECK_LT(num_blocks, 3);
+ }
+ if (N3) {
+ CHECK_EQ(N3, block_sizes[3]);
+ CHECK_GE(num_blocks, 4);
+ } else {
+ CHECK_LT(num_blocks, 4);
+ }
+ if (N4) {
+ CHECK_EQ(N4, block_sizes[4]);
+ CHECK_GE(num_blocks, 5);
+ } else {
+ CHECK_LT(num_blocks, 5);
+ }
+
+ results->term_jacobians.clear();
+ results->term_jacobians.resize(num_blocks);
+ results->finite_difference_jacobians.clear();
+ results->finite_difference_jacobians.resize(num_blocks);
+
+ internal::FixedArray<double*> term_jacobian_pointers(num_blocks);
+ internal::FixedArray<double*>
+ finite_difference_jacobian_pointers(num_blocks);
+ for (int i = 0; i < num_blocks; i++) {
+ results->term_jacobians[i].resize(num_residuals, block_sizes[i]);
+ term_jacobian_pointers[i] = results->term_jacobians[i].data();
+ results->finite_difference_jacobians[i].resize(
+ num_residuals, block_sizes[i]);
+ finite_difference_jacobian_pointers[i] =
+ results->finite_difference_jacobians[i].data();
+ }
+ results->cost.resize(num_residuals, 1);
+
+ CHECK(term->Evaluate(probe_point, results->cost.data(),
+ term_jacobian_pointers.get()));
+ NumericDiffCostFunction<CostFunctionToProbe, CENTRAL, M, N0, N1, N2, N3, N4>
+ numeric_term(term, DO_NOT_TAKE_OWNERSHIP);
+ CHECK(numeric_term.Evaluate(probe_point, results->cost.data(),
+ finite_difference_jacobian_pointers.get()));
+
+ results->error_jacobians = 0;
+ for (int i = 0; i < num_blocks; i++) {
+ Matrix jacobian_difference = results->term_jacobians[i] -
+ results->finite_difference_jacobians[i];
+ results->error_jacobians =
+ std::max(results->error_jacobians,
+ jacobian_difference.lpNorm<Eigen::Infinity>());
+ }
+
+ LOG(INFO) << "========== term-computed derivatives ==========";
+ for (int i = 0; i < num_blocks; i++) {
+ LOG(INFO) << "term_computed block " << i;
+ LOG(INFO) << "\n" << results->term_jacobians[i];
+ }
+
+ LOG(INFO) << "========== finite-difference derivatives ==========";
+ for (int i = 0; i < num_blocks; i++) {
+ LOG(INFO) << "finite_difference block " << i;
+ LOG(INFO) << "\n" << results->finite_difference_jacobians[i];
+ }
+
+ LOG(INFO) << "========== difference ==========";
+ for (int i = 0; i < num_blocks; i++) {
+ LOG(INFO) << "difference block " << i;
+ LOG(INFO) << (results->term_jacobians[i] -
+ results->finite_difference_jacobians[i]);
+ }
+
+ LOG(INFO) << "||difference|| = " << results->error_jacobians;
+
+ return results->error_jacobians < error_tolerance;
+ }
+
+ private:
+ CERES_DISALLOW_IMPLICIT_CONSTRUCTORS(GradientChecker);
+};
+
+} // namespace ceres
+
+#endif // CERES_PUBLIC_GRADIENT_CHECKER_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h b/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h
index 4f5081f8f66..011f2a05b65 100644
--- a/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/autodiff.h
@@ -146,6 +146,7 @@
#include "ceres/jet.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/fixed_array.h"
+#include "ceres/internal/variadic_evaluate.h"
namespace ceres {
namespace internal {
@@ -191,134 +192,71 @@ inline void Take1stOrderPart(const int M, const JetT *src, T *dst) {
DCHECK(src);
DCHECK(dst);
for (int i = 0; i < M; ++i) {
- Eigen::Map<Eigen::Matrix<T, N, 1> >(dst + N * i, N) = src[i].v.template segment<N>(N0);
+ Eigen::Map<Eigen::Matrix<T, N, 1> >(dst + N * i, N) =
+ src[i].v.template segment<N>(N0);
}
}
-// This block of quasi-repeated code calls the user-supplied functor, which may
-// take a variable number of arguments. This is accomplished by specializing the
-// struct based on the size of the trailing parameters; parameters with 0 size
-// are assumed missing.
-//
-// Supporting variadic functions is the primary source of complexity in the
-// autodiff implementation.
-
-template<typename Functor, typename T,
- int N0, int N1, int N2, int N3, int N4, int N5>
-struct VariadicEvaluate {
- static bool Call(const Functor& functor, T const *const *input, T* output) {
- return functor(input[0],
- input[1],
- input[2],
- input[3],
- input[4],
- input[5],
- output);
- }
-};
-
-template<typename Functor, typename T,
- int N0, int N1, int N2, int N3, int N4>
-struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, N4, 0> {
- static bool Call(const Functor& functor, T const *const *input, T* output) {
- return functor(input[0],
- input[1],
- input[2],
- input[3],
- input[4],
- output);
- }
-};
-
-template<typename Functor, typename T,
- int N0, int N1, int N2, int N3>
-struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, 0, 0> {
- static bool Call(const Functor& functor, T const *const *input, T* output) {
- return functor(input[0],
- input[1],
- input[2],
- input[3],
- output);
- }
-};
-
-template<typename Functor, typename T,
- int N0, int N1, int N2>
-struct VariadicEvaluate<Functor, T, N0, N1, N2, 0, 0, 0> {
- static bool Call(const Functor& functor, T const *const *input, T* output) {
- return functor(input[0],
- input[1],
- input[2],
- output);
- }
-};
-
-template<typename Functor, typename T,
- int N0, int N1>
-struct VariadicEvaluate<Functor, T, N0, N1, 0, 0, 0, 0> {
- static bool Call(const Functor& functor, T const *const *input, T* output) {
- return functor(input[0],
- input[1],
- output);
- }
-};
-
-template<typename Functor, typename T, int N0>
-struct VariadicEvaluate<Functor, T, N0, 0, 0, 0, 0, 0> {
- static bool Call(const Functor& functor, T const *const *input, T* output) {
- return functor(input[0],
- output);
- }
-};
-
-// This is in a struct because default template parameters on a function are not
-// supported in C++03 (though it is available in C++0x). N0 through N5 are the
-// dimension of the input arguments to the user supplied functor.
+// This is in a struct because default template parameters on a
+// function are not supported in C++03 (though it is available in
+// C++0x). N0 through N5 are the dimension of the input arguments to
+// the user supplied functor.
template <typename Functor, typename T,
- int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0, int N5=0>
+ int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
+ int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
struct AutoDiff {
static bool Differentiate(const Functor& functor,
T const *const *parameters,
int num_outputs,
T *function_value,
T **jacobians) {
- typedef Jet<T, N0 + N1 + N2 + N3 + N4 + N5> JetT;
-
- DCHECK_GT(N0, 0)
- << "Cost functions must have at least one parameter block.";
- DCHECK((!N1 && !N2 && !N3 && !N4 && !N5) ||
- ((N1 > 0) && !N2 && !N3 && !N4 && !N5) ||
- ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5) ||
- ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5) ||
- ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5) ||
- ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0)))
+ // This block breaks the 80 column rule to keep it somewhat readable.
+ DCHECK_GT(num_outputs, 0);
+ CHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0)))
<< "Zero block cannot precede a non-zero block. Block sizes are "
<< "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
- << N3 << ", " << N4 << ", " << N5;
-
- DCHECK_GT(num_outputs, 0);
+ << N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
+ << N8 << ", " << N9;
+ typedef Jet<T, N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9> JetT;
FixedArray<JetT, (256 * 7) / sizeof(JetT)> x(
- N0 + N1 + N2 + N3 + N4 + N5 + num_outputs);
+ N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9 + num_outputs);
- // It's ugly, but it works.
- const int jet0 = 0;
- const int jet1 = N0;
- const int jet2 = N0 + N1;
- const int jet3 = N0 + N1 + N2;
- const int jet4 = N0 + N1 + N2 + N3;
- const int jet5 = N0 + N1 + N2 + N3 + N4;
- const int jet6 = N0 + N1 + N2 + N3 + N4 + N5;
+ // These are the positions of the respective jets in the fixed array x.
+ const int jet0 = 0;
+ const int jet1 = N0;
+ const int jet2 = N0 + N1;
+ const int jet3 = N0 + N1 + N2;
+ const int jet4 = N0 + N1 + N2 + N3;
+ const int jet5 = N0 + N1 + N2 + N3 + N4;
+ const int jet6 = N0 + N1 + N2 + N3 + N4 + N5;
+ const int jet7 = N0 + N1 + N2 + N3 + N4 + N5 + N6;
+ const int jet8 = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7;
+ const int jet9 = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8;
- const JetT *unpacked_parameters[6] = {
+ const JetT *unpacked_parameters[10] = {
x.get() + jet0,
x.get() + jet1,
x.get() + jet2,
x.get() + jet3,
x.get() + jet4,
x.get() + jet5,
+ x.get() + jet6,
+ x.get() + jet7,
+ x.get() + jet8,
+ x.get() + jet9,
};
- JetT *output = x.get() + jet6;
+
+ JetT* output = x.get() + N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9;
#define CERES_MAKE_1ST_ORDER_PERTURBATION(i) \
if (N ## i) { \
@@ -333,10 +271,14 @@ struct AutoDiff {
CERES_MAKE_1ST_ORDER_PERTURBATION(3);
CERES_MAKE_1ST_ORDER_PERTURBATION(4);
CERES_MAKE_1ST_ORDER_PERTURBATION(5);
+ CERES_MAKE_1ST_ORDER_PERTURBATION(6);
+ CERES_MAKE_1ST_ORDER_PERTURBATION(7);
+ CERES_MAKE_1ST_ORDER_PERTURBATION(8);
+ CERES_MAKE_1ST_ORDER_PERTURBATION(9);
#undef CERES_MAKE_1ST_ORDER_PERTURBATION
if (!VariadicEvaluate<Functor, JetT,
- N0, N1, N2, N3, N4, N5>::Call(
+ N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::Call(
functor, unpacked_parameters, output)) {
return false;
}
@@ -359,6 +301,10 @@ struct AutoDiff {
CERES_TAKE_1ST_ORDER_PERTURBATION(3);
CERES_TAKE_1ST_ORDER_PERTURBATION(4);
CERES_TAKE_1ST_ORDER_PERTURBATION(5);
+ CERES_TAKE_1ST_ORDER_PERTURBATION(6);
+ CERES_TAKE_1ST_ORDER_PERTURBATION(7);
+ CERES_TAKE_1ST_ORDER_PERTURBATION(8);
+ CERES_TAKE_1ST_ORDER_PERTURBATION(9);
#undef CERES_TAKE_1ST_ORDER_PERTURBATION
return true;
}
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h b/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h
index ce777d22dc7..fa4a339d757 100644
--- a/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/fixed_array.h
@@ -168,11 +168,11 @@ inline FixedArray<T, S>::FixedArray(typename FixedArray<T, S>::size_type n)
array_((n <= kInlineElements
? reinterpret_cast<InnerContainer*>(inline_space_)
: new InnerContainer[n])) {
- DCHECK_GE(n, 0);
+ DCHECK_GE(n, size_t(0));
// Construct only the elements actually used.
if (array_ == reinterpret_cast<InnerContainer*>(inline_space_)) {
- for (int i = 0; i != size_; ++i) {
+ for (size_t i = 0; i != size_; ++i) {
inline_space_[i].Init();
}
}
@@ -183,7 +183,7 @@ inline FixedArray<T, S>::~FixedArray() {
if (array_ != reinterpret_cast<InnerContainer*>(inline_space_)) {
delete[] array_;
} else {
- for (int i = 0; i != size_; ++i) {
+ for (size_t i = 0; i != size_; ++i) {
inline_space_[i].Destroy();
}
}
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/macros.h b/extern/libmv/third_party/ceres/include/ceres/internal/macros.h
index 83ec31193e7..388cf30fe70 100644
--- a/extern/libmv/third_party/ceres/include/ceres/internal/macros.h
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/macros.h
@@ -132,16 +132,16 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
// - wan 2005-11-16
//
// Starting with Visual C++ 2005, WinNT.h includes ARRAYSIZE. However,
-// the definition comes from the over-broad windows.h header that
+// the definition comes from the over-broad windows.h header that
// introduces a macro, ERROR, that conflicts with the logging framework
// that Ceres uses. Instead, rename ARRAYSIZE to CERES_ARRAYSIZE.
-#define CERES_ARRAYSIZE(a) \
- ((sizeof(a) / sizeof(*(a))) / \
+#define CERES_ARRAYSIZE(a) \
+ ((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
-// Tell the compiler to warn about unused return values for functions declared
-// with this macro. The macro should be used on function declarations
-// following the argument list:
+// Tell the compiler to warn about unused return values for functions
+// declared with this macro. The macro should be used on function
+// declarations following the argument list:
//
// Sprocket* AllocateSprocket() MUST_USE_RESULT;
//
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h b/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h
index 174d35ee2bd..7ea723d2a83 100644
--- a/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/manual_constructor.h
@@ -110,56 +110,61 @@ class ManualConstructor {
inline Type& operator*() { return *get(); }
inline const Type& operator*() const { return *get(); }
+ // This is needed to get around the strict aliasing warning GCC generates.
+ inline void* space() {
+ return reinterpret_cast<void*>(space_);
+ }
+
// You can pass up to four constructor arguments as arguments of Init().
inline void Init() {
- new(space_) Type;
+ new(space()) Type;
}
template <typename T1>
inline void Init(const T1& p1) {
- new(space_) Type(p1);
+ new(space()) Type(p1);
}
template <typename T1, typename T2>
inline void Init(const T1& p1, const T2& p2) {
- new(space_) Type(p1, p2);
+ new(space()) Type(p1, p2);
}
template <typename T1, typename T2, typename T3>
inline void Init(const T1& p1, const T2& p2, const T3& p3) {
- new(space_) Type(p1, p2, p3);
+ new(space()) Type(p1, p2, p3);
}
template <typename T1, typename T2, typename T3, typename T4>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4) {
- new(space_) Type(p1, p2, p3, p4);
+ new(space()) Type(p1, p2, p3, p4);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5) {
- new(space_) Type(p1, p2, p3, p4, p5);
+ new(space()) Type(p1, p2, p3, p4, p5);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6) {
- new(space_) Type(p1, p2, p3, p4, p5, p6);
+ new(space()) Type(p1, p2, p3, p4, p5, p6);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7) {
- new(space_) Type(p1, p2, p3, p4, p5, p6, p7);
+ new(space()) Type(p1, p2, p3, p4, p5, p6, p7);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8) {
- new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8);
+ new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
@@ -167,7 +172,7 @@ class ManualConstructor {
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8,
const T9& p9) {
- new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
@@ -175,7 +180,7 @@ class ManualConstructor {
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8,
const T9& p9, const T10& p10) {
- new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+ new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
@@ -184,7 +189,7 @@ class ManualConstructor {
inline void Init(const T1& p1, const T2& p2, const T3& p3, const T4& p4,
const T5& p5, const T6& p6, const T7& p7, const T8& p8,
const T9& p9, const T10& p10, const T11& p11) {
- new(space_) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
+ new(space()) Type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
}
inline void Destroy() {
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h b/extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h
new file mode 100644
index 00000000000..4058366c4a1
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h
@@ -0,0 +1,199 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+// mierle@gmail.com (Keir Mierle)
+//
+// Finite differencing routine used by NumericDiffCostFunction.
+
+#ifndef CERES_PUBLIC_INTERNAL_NUMERIC_DIFF_H_
+#define CERES_PUBLIC_INTERNAL_NUMERIC_DIFF_H_
+
+#include <cstring>
+
+#include "Eigen/Dense"
+#include "ceres/cost_function.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/internal/variadic_evaluate.h"
+#include "ceres/types.h"
+#include "glog/logging.h"
+
+
+namespace ceres {
+namespace internal {
+
+// Helper templates that allow evaluation of a variadic functor or a
+// CostFunction object.
+template <typename CostFunctor,
+ int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6, int N7, int N8, int N9 >
+bool EvaluateImpl(const CostFunctor* functor,
+ double const* const* parameters,
+ double* residuals,
+ const void* /* NOT USED */) {
+ return VariadicEvaluate<CostFunctor,
+ double,
+ N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>::Call(
+ *functor,
+ parameters,
+ residuals);
+}
+
+template <typename CostFunctor,
+ int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6, int N7, int N8, int N9 >
+bool EvaluateImpl(const CostFunctor* functor,
+ double const* const* parameters,
+ double* residuals,
+ const CostFunction* /* NOT USED */) {
+ return functor->Evaluate(parameters, residuals, NULL);
+}
+
+// This is split from the main class because C++ doesn't allow partial template
+// specializations for member functions. The alternative is to repeat the main
+// class for differing numbers of parameters, which is also unfortunate.
+template <typename CostFunctor,
+ NumericDiffMethod kMethod,
+ int kNumResiduals,
+ int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6, int N7, int N8, int N9,
+ int kParameterBlock,
+ int kParameterBlockSize>
+struct NumericDiff {
+ // Mutates parameters but must restore them before return.
+ static bool EvaluateJacobianForParameterBlock(
+ const CostFunctor* functor,
+ double const* residuals_at_eval_point,
+ const double relative_step_size,
+ double **parameters,
+ double *jacobian) {
+ using Eigen::Map;
+ using Eigen::Matrix;
+ using Eigen::RowMajor;
+ using Eigen::ColMajor;
+
+ typedef Matrix<double, kNumResiduals, 1> ResidualVector;
+ typedef Matrix<double, kParameterBlockSize, 1> ParameterVector;
+ typedef Matrix<double, kNumResiduals, kParameterBlockSize,
+ (kParameterBlockSize == 1 &&
+ kNumResiduals > 1) ? ColMajor : RowMajor> JacobianMatrix;
+
+
+ Map<JacobianMatrix> parameter_jacobian(jacobian,
+ kNumResiduals,
+ kParameterBlockSize);
+
+ // Mutate 1 element at a time and then restore.
+ Map<ParameterVector> x_plus_delta(parameters[kParameterBlock],
+ kParameterBlockSize);
+ ParameterVector x(x_plus_delta);
+ ParameterVector step_size = x.array().abs() * relative_step_size;
+
+ // To handle cases where a parameter is exactly zero, instead use
+ // the mean step_size for the other dimensions. If all the
+ // parameters are zero, there's no good answer. Take
+ // relative_step_size as a guess and hope for the best.
+ const double fallback_step_size =
+ (step_size.sum() == 0)
+ ? relative_step_size
+ : step_size.sum() / step_size.rows();
+
+ // For each parameter in the parameter block, use finite differences to
+ // compute the derivative for that parameter.
+ for (int j = 0; j < kParameterBlockSize; ++j) {
+ const double delta =
+ (step_size(j) == 0.0) ? fallback_step_size : step_size(j);
+
+ x_plus_delta(j) = x(j) + delta;
+
+ double residuals[kNumResiduals]; // NOLINT
+
+ if (!EvaluateImpl<CostFunctor, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>(
+ functor, parameters, residuals, functor)) {
+ return false;
+ }
+
+ // Compute this column of the jacobian in 3 steps:
+ // 1. Store residuals for the forward part.
+ // 2. Subtract residuals for the backward (or 0) part.
+ // 3. Divide out the run.
+ parameter_jacobian.col(j) =
+ Map<const ResidualVector>(residuals, kNumResiduals);
+
+ double one_over_delta = 1.0 / delta;
+ if (kMethod == CENTRAL) {
+ // Compute the function on the other side of x(j).
+ x_plus_delta(j) = x(j) - delta;
+
+ if (!EvaluateImpl<CostFunctor, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>(
+ functor, parameters, residuals, functor)) {
+ return false;
+ }
+
+ parameter_jacobian.col(j) -=
+ Map<ResidualVector>(residuals, kNumResiduals, 1);
+ one_over_delta /= 2;
+ } else {
+ // Forward difference only; reuse existing residuals evaluation.
+ parameter_jacobian.col(j) -=
+ Map<const ResidualVector>(residuals_at_eval_point, kNumResiduals);
+ }
+ x_plus_delta(j) = x(j); // Restore x_plus_delta.
+
+ // Divide out the run to get slope.
+ parameter_jacobian.col(j) *= one_over_delta;
+ }
+ return true;
+ }
+};
+
+template <typename CostFunctor,
+ NumericDiffMethod kMethod,
+ int kNumResiduals,
+ int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6, int N7, int N8, int N9,
+ int kParameterBlock>
+struct NumericDiff<CostFunctor, kMethod, kNumResiduals,
+ N0, N1, N2, N3, N4, N5, N6, N7, N8, N9,
+ kParameterBlock, 0> {
+ // Mutates parameters but must restore them before return.
+ static bool EvaluateJacobianForParameterBlock(
+ const CostFunctor* functor,
+ double const* residuals_at_eval_point,
+ const double relative_step_size,
+ double **parameters,
+ double *jacobian) {
+ LOG(FATAL) << "Control should never reach here.";
+ return true;
+ }
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_PUBLIC_INTERNAL_NUMERIC_DIFF_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h b/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h
index 44f198b339d..5dfb551243c 100644
--- a/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/scoped_ptr.h
@@ -38,6 +38,7 @@
#include <assert.h>
#include <stdlib.h>
#include <cstddef>
+#include <algorithm>
namespace ceres {
namespace internal {
@@ -49,18 +50,17 @@ template <class C> class scoped_array;
template <class C>
scoped_ptr<C> make_scoped_ptr(C *);
-// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
-// automatically deletes the pointer it holds (if any). That is, scoped_ptr<T>
-// owns the T object that it points to. Like a T*, a scoped_ptr<T> may hold
-// either NULL or a pointer to a T object. Also like T*, scoped_ptr<T> is
-// thread-compatible, and once you dereference it, you get the threadsafety
-// guarantees of T.
+// A scoped_ptr<T> is like a T*, except that the destructor of
+// scoped_ptr<T> automatically deletes the pointer it holds (if
+// any). That is, scoped_ptr<T> owns the T object that it points
+// to. Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to
+// a T object. Also like T*, scoped_ptr<T> is thread-compatible, and
+// once you dereference it, you get the threadsafety guarantees of T.
//
// The size of a scoped_ptr is small: sizeof(scoped_ptr<C>) == sizeof(C*)
template <class C>
class scoped_ptr {
public:
-
// The element type
typedef C element_type;
@@ -193,7 +193,6 @@ scoped_ptr<C> make_scoped_ptr(C *p) {
template <class C>
class scoped_array {
public:
-
// The element type
typedef C element_type;
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/variadic_evaluate.h b/extern/libmv/third_party/ceres/include/ceres/internal/variadic_evaluate.h
new file mode 100644
index 00000000000..4b1e4bdc65a
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/variadic_evaluate.h
@@ -0,0 +1,182 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+// mierle@gmail.com (Keir Mierle)
+
+#ifndef CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
+#define CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
+
+#include <stddef.h>
+
+#include <glog/logging.h>
+#include "ceres/jet.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/fixed_array.h"
+
+namespace ceres {
+namespace internal {
+
+// This block of quasi-repeated code calls the user-supplied functor, which may
+// take a variable number of arguments. This is accomplished by specializing the
+// struct based on the size of the trailing parameters; parameters with 0 size
+// are assumed missing.
+template<typename Functor, typename T, int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6, int N7, int N8, int N9>
+struct VariadicEvaluate {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ input[3],
+ input[4],
+ input[5],
+ input[6],
+ input[7],
+ input[8],
+ input[9],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6, int N7, int N8>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, N4, N5, N6, N7, N8, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ input[3],
+ input[4],
+ input[5],
+ input[6],
+ input[7],
+ input[8],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6, int N7>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, N4, N5, N6, N7, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ input[3],
+ input[4],
+ input[5],
+ input[6],
+ input[7],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1, int N2, int N3, int N4,
+ int N5, int N6>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, N4, N5, N6, 0, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ input[3],
+ input[4],
+ input[5],
+ input[6],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1, int N2, int N3, int N4,
+ int N5>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, N4, N5, 0, 0, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ input[3],
+ input[4],
+ input[5],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1, int N2, int N3, int N4>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, N4, 0, 0, 0, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ input[3],
+ input[4],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1, int N2, int N3>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, N3, 0, 0, 0, 0, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ input[3],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1, int N2>
+struct VariadicEvaluate<Functor, T, N0, N1, N2, 0, 0, 0, 0, 0, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ input[2],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0, int N1>
+struct VariadicEvaluate<Functor, T, N0, N1, 0, 0, 0, 0, 0, 0, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ input[1],
+ output);
+ }
+};
+
+template<typename Functor, typename T, int N0>
+struct VariadicEvaluate<Functor, T, N0, 0, 0, 0, 0, 0, 0, 0, 0, 0> {
+ static bool Call(const Functor& functor, T const *const *input, T* output) {
+ return functor(input[0],
+ output);
+ }
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_PUBLIC_INTERNAL_VARIADIC_EVALUATE_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h b/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h
index 29157d380f2..0dc4c96b441 100644
--- a/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h
+++ b/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h
@@ -42,6 +42,23 @@ namespace ceres {
// This struct describes the state of the optimizer after each
// iteration of the minimization.
struct IterationSummary {
+ IterationSummary()
+ : iteration(0),
+ step_is_valid(false),
+ step_is_nonmonotonic(false),
+ step_is_successful(false),
+ cost(0.0),
+ cost_change(0.0),
+ gradient_max_norm(0.0),
+ step_norm(0.0),
+ eta(0.0),
+ step_size(0.0),
+ line_search_function_evaluations(0),
+ linear_solver_iterations(0),
+ iteration_time_in_seconds(0.0),
+ step_solver_time_in_seconds(0.0),
+ cumulative_time_in_seconds(0.0) {}
+
// Current iteration number.
int32 iteration;
@@ -51,7 +68,22 @@ struct IterationSummary {
// Note: step_is_valid is false when iteration = 0.
bool step_is_valid;
- // Whether or not the algorithm made progress in this iteration.
+ // Step did not reduce the value of the objective function
+ // sufficiently, but it was accepted because of the relaxed
+ // acceptance criterion used by the non-monotonic trust region
+ // algorithm.
+ //
+ // Note: step_is_nonmonotonic is false when iteration = 0;
+ bool step_is_nonmonotonic;
+
+ // Whether or not the minimizer accepted this step or not. If the
+ // ordinary trust region algorithm is used, this means that the
+ // relative reduction in the objective function value was greater
+ // than Solver::Options::min_relative_decrease. However, if the
+ // non-monotonic trust region algorithm is used
+ // (Solver::Options:use_nonmonotonic_steps = true), then even if the
+ // relative decrease is not sufficient, the algorithm may accept the
+ // step and the step is declared successful.
//
// Note: step_is_successful is false when iteration = 0.
bool step_is_successful;
@@ -60,8 +92,7 @@ struct IterationSummary {
double cost;
// Change in the value of the objective function in this
- // iteration. This can be positive or negative. Negative change
- // means that the step was not successful.
+ // iteration. This can be positive or negative.
double cost_change;
// Infinity norm of the gradient vector.
@@ -87,6 +118,12 @@ struct IterationSummary {
// ignore it.
double eta;
+ // Step sized computed by the line search algorithm.
+ double step_size;
+
+ // Number of function evaluations used by the line search algorithm.
+ int line_search_function_evaluations;
+
// Number of iterations taken by the linear solver to solve for the
// Newton step.
int linear_solver_iterations;
diff --git a/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h
index 8544e44d0bc..555bc3d073f 100644
--- a/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h
+++ b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_cost_function.h
@@ -27,19 +27,109 @@
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: keir@google.com (Keir Mierle)
+// sameeragarwal@google.com (Sameer Agarwal)
//
// Create CostFunctions as needed by the least squares framework with jacobians
// computed via numeric (a.k.a. finite) differentiation. For more details see
// http://en.wikipedia.org/wiki/Numerical_differentiation.
//
-// To get a numerically differentiated cost function, define a subclass of
-// CostFunction such that the Evaluate() function ignores the jacobian
-// parameter. The numeric differentiation wrapper will fill in the jacobian
-// parameter if nececssary by repeatedly calling the Evaluate() function with
-// small changes to the appropriate parameters, and computing the slope. For
-// performance, the numeric differentiation wrapper class is templated on the
-// concrete cost function, even though it could be implemented only in terms of
-// the virtual CostFunction interface.
+// To get an numerically differentiated cost function, you must define
+// a class with a operator() (a functor) that computes the residuals.
+//
+// The function must write the computed value in the last argument (the only
+// non-const one) and return true to indicate success.
+//
+// For example, consider a scalar error e = k - x'y, where both x and y are
+// two-dimensional column vector parameters, the prime sign indicates
+// transposition, and k is a constant. The form of this error, which is the
+// difference between a constant and an expression, is a common pattern in least
+// squares problems. For example, the value x'y might be the model expectation
+// for a series of measurements, where there is an instance of the cost function
+// for each measurement k.
+//
+// The actual cost added to the total problem is e^2, or (k - x'k)^2; however,
+// the squaring is implicitly done by the optimization framework.
+//
+// To write an numerically-differentiable cost function for the above model, first
+// define the object
+//
+// class MyScalarCostFunctor {
+// MyScalarCostFunctor(double k): k_(k) {}
+//
+// bool operator()(const double* const x,
+// const double* const y,
+// double* residuals) const {
+// residuals[0] = k_ - x[0] * y[0] + x[1] * y[1];
+// return true;
+// }
+//
+// private:
+// double k_;
+// };
+//
+// Note that in the declaration of operator() the input parameters x
+// and y come first, and are passed as const pointers to arrays of
+// doubles. If there were three input parameters, then the third input
+// parameter would come after y. The output is always the last
+// parameter, and is also a pointer to an array. In the example above,
+// the residual is a scalar, so only residuals[0] is set.
+//
+// Then given this class definition, the numerically differentiated
+// cost function with central differences used for computing the
+// derivative can be constructed as follows.
+//
+// CostFunction* cost_function
+// = new NumericDiffCostFunction<MyScalarCostFunctor, CENTRAL, 1, 2, 2>(
+// new MyScalarCostFunctor(1.0)); ^ ^ ^
+// | | | |
+// Finite Differencing Scheme -+ | | |
+// Dimension of residual ----------+ | |
+// Dimension of x --------------------+ |
+// Dimension of y -----------------------+
+//
+// In this example, there is usually an instance for each measumerent of k.
+//
+// In the instantiation above, the template parameters following
+// "MyScalarCostFunctor", "1, 2, 2", describe the functor as computing
+// a 1-dimensional output from two arguments, both 2-dimensional.
+//
+// The framework can currently accommodate cost functions of up to 10
+// independent variables, and there is no limit on the dimensionality
+// of each of them.
+//
+// The central difference method is considerably more accurate at the cost of
+// twice as many function evaluations than forward difference. Consider using
+// central differences begin with, and only after that works, trying forward
+// difference to improve performance.
+//
+// TODO(sameeragarwal): Add support for dynamic number of residuals.
+//
+// WARNING #1: A common beginner's error when first using
+// NumericDiffCostFunction is to get the sizing wrong. In particular,
+// there is a tendency to set the template parameters to (dimension of
+// residual, number of parameters) instead of passing a dimension
+// parameter for *every parameter*. In the example above, that would
+// be <MyScalarCostFunctor, 1, 2>, which is missing the last '2'
+// argument. Please be careful when setting the size parameters.
+//
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+//
+// ALTERNATE INTERFACE
+//
+// For a variety of reason, including compatibility with legacy code,
+// NumericDiffCostFunction can also take CostFunction objects as
+// input. The following describes how.
+//
+// To get a numerically differentiated cost function, define a
+// subclass of CostFunction such that the Evaluate() function ignores
+// the jacobian parameter. The numeric differentiation wrapper will
+// fill in the jacobian parameter if nececssary by repeatedly calling
+// the Evaluate() function with small changes to the appropriate
+// parameters, and computing the slope. For performance, the numeric
+// differentiation wrapper class is templated on the concrete cost
+// function, even though it could be implemented only in terms of the
+// virtual CostFunction interface.
//
// The numerically differentiated version of a cost function for a cost function
// can be constructed as follows:
@@ -51,233 +141,153 @@
// where MyCostFunction has 1 residual and 2 parameter blocks with sizes 4 and 8
// respectively. Look at the tests for a more detailed example.
//
-// The central difference method is considerably more accurate at the cost of
-// twice as many function evaluations than forward difference. Consider using
-// central differences begin with, and only after that works, trying forward
-// difference to improve performance.
-//
// TODO(keir): Characterize accuracy; mention pitfalls; provide alternatives.
#ifndef CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_
#define CERES_PUBLIC_NUMERIC_DIFF_COST_FUNCTION_H_
-#include <cstring>
#include <glog/logging.h>
#include "Eigen/Dense"
+#include "ceres/cost_function.h"
+#include "ceres/internal/numeric_diff.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/sized_cost_function.h"
#include "ceres/types.h"
namespace ceres {
-enum NumericDiffMethod {
- CENTRAL,
- FORWARD
-};
-
-// This is split from the main class because C++ doesn't allow partial template
-// specializations for member functions. The alternative is to repeat the main
-// class for differing numbers of parameters, which is also unfortunate.
-template <typename CostFunctionNoJacobian,
- int num_residuals,
- int parameter_block_size,
- int parameter_block,
- NumericDiffMethod method>
-struct Differencer {
- // Mutates parameters but must restore them before return.
- static bool EvaluateJacobianForParameterBlock(
- const CostFunctionNoJacobian *function,
- double const* residuals_at_eval_point,
- double **parameters,
- double **jacobians) {
- using Eigen::Map;
- using Eigen::Matrix;
- using Eigen::RowMajor;
- using Eigen::ColMajor;
-
- typedef Matrix<double, num_residuals, 1> ResidualVector;
- typedef Matrix<double, parameter_block_size, 1> ParameterVector;
- typedef Matrix<double, num_residuals, parameter_block_size,
- (parameter_block_size == 1 &&
- num_residuals > 1) ? ColMajor : RowMajor> JacobianMatrix;
-
- Map<JacobianMatrix> parameter_jacobian(jacobians[parameter_block],
- num_residuals,
- parameter_block_size);
-
- // Mutate 1 element at a time and then restore.
- Map<ParameterVector> x_plus_delta(parameters[parameter_block],
- parameter_block_size);
- ParameterVector x(x_plus_delta);
-
- // TODO(keir): Pick a smarter number! In theory a good choice is sqrt(eps) *
- // x, which for doubles means about 1e-8 * x. However, I have found this
- // number too optimistic. This number should be exposed for users to change.
- const double kRelativeStepSize = 1e-6;
-
- ParameterVector step_size = x.array().abs() * kRelativeStepSize;
-
- // To handle cases where a parameter is exactly zero, instead use the mean
- // step_size for the other dimensions.
- double fallback_step_size = step_size.sum() / step_size.rows();
- if (fallback_step_size == 0.0) {
- // If all the parameters are zero, there's no good answer. Take
- // kRelativeStepSize as a guess and hope for the best.
- fallback_step_size = kRelativeStepSize;
- }
-
- // For each parameter in the parameter block, use finite differences to
- // compute the derivative for that parameter.
- for (int j = 0; j < parameter_block_size; ++j) {
- if (step_size(j) == 0.0) {
- // The parameter is exactly zero, so compromise and use the mean
- // step_size from the other parameters. This can break in many cases,
- // but it's hard to pick a good number without problem specific
- // knowledge.
- step_size(j) = fallback_step_size;
- }
- x_plus_delta(j) = x(j) + step_size(j);
-
- double residuals[num_residuals]; // NOLINT
- if (!function->Evaluate(parameters, residuals, NULL)) {
- // Something went wrong; bail.
- return false;
- }
-
- // Compute this column of the jacobian in 3 steps:
- // 1. Store residuals for the forward part.
- // 2. Subtract residuals for the backward (or 0) part.
- // 3. Divide out the run.
- parameter_jacobian.col(j) =
- Map<const ResidualVector>(residuals, num_residuals);
-
- double one_over_h = 1 / step_size(j);
- if (method == CENTRAL) {
- // Compute the function on the other side of x(j).
- x_plus_delta(j) = x(j) - step_size(j);
-
- if (!function->Evaluate(parameters, residuals, NULL)) {
- // Something went wrong; bail.
- return false;
- }
- parameter_jacobian.col(j) -=
- Map<ResidualVector>(residuals, num_residuals, 1);
- one_over_h /= 2;
- } else {
- // Forward difference only; reuse existing residuals evaluation.
- parameter_jacobian.col(j) -=
- Map<const ResidualVector>(residuals_at_eval_point, num_residuals);
- }
- x_plus_delta(j) = x(j); // Restore x_plus_delta.
-
- // Divide out the run to get slope.
- parameter_jacobian.col(j) *= one_over_h;
- }
- return true;
- }
-};
-
-// Prevent invalid instantiations.
-template <typename CostFunctionNoJacobian,
- int num_residuals,
- int parameter_block,
- NumericDiffMethod method>
-struct Differencer<CostFunctionNoJacobian,
- num_residuals,
- 0 /* parameter_block_size */,
- parameter_block,
- method> {
- static bool EvaluateJacobianForParameterBlock(
- const CostFunctionNoJacobian *function,
- double const* residuals_at_eval_point,
- double **parameters,
- double **jacobians) {
- LOG(FATAL) << "Shouldn't get here.";
- return true;
- }
-};
-
-template <typename CostFunctionNoJacobian,
- NumericDiffMethod method = CENTRAL, int M = 0,
- int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0, int N5 = 0>
+template <typename CostFunctor,
+ NumericDiffMethod method = CENTRAL,
+ int kNumResiduals = 0, // Number of residuals, or ceres::DYNAMIC
+ int N0 = 0, // Number of parameters in block 0.
+ int N1 = 0, // Number of parameters in block 1.
+ int N2 = 0, // Number of parameters in block 2.
+ int N3 = 0, // Number of parameters in block 3.
+ int N4 = 0, // Number of parameters in block 4.
+ int N5 = 0, // Number of parameters in block 5.
+ int N6 = 0, // Number of parameters in block 6.
+ int N7 = 0, // Number of parameters in block 7.
+ int N8 = 0, // Number of parameters in block 8.
+ int N9 = 0> // Number of parameters in block 9.
class NumericDiffCostFunction
- : public SizedCostFunction<M, N0, N1, N2, N3, N4, N5> {
+ : public SizedCostFunction<kNumResiduals,
+ N0, N1, N2, N3, N4,
+ N5, N6, N7, N8, N9> {
public:
- NumericDiffCostFunction(CostFunctionNoJacobian* function,
- Ownership ownership)
- : function_(function), ownership_(ownership) {}
+ NumericDiffCostFunction(CostFunctor* functor,
+ const double relative_step_size = 1e-6)
+ :functor_(functor),
+ ownership_(TAKE_OWNERSHIP),
+ relative_step_size_(relative_step_size) {}
- virtual ~NumericDiffCostFunction() {
+ NumericDiffCostFunction(CostFunctor* functor,
+ Ownership ownership,
+ const double relative_step_size = 1e-6)
+ : functor_(functor),
+ ownership_(ownership),
+ relative_step_size_(relative_step_size) {}
+
+ ~NumericDiffCostFunction() {
if (ownership_ != TAKE_OWNERSHIP) {
- function_.release();
+ functor_.release();
}
}
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const {
+ using internal::FixedArray;
+ using internal::NumericDiff;
+
+ const int kNumParameters = N0 + N1 + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9;
+ const int kNumParameterBlocks =
+ (N0 > 0) + (N1 > 0) + (N2 > 0) + (N3 > 0) + (N4 > 0) +
+ (N5 > 0) + (N6 > 0) + (N7 > 0) + (N8 > 0) + (N9 > 0);
+
// Get the function value (residuals) at the the point to evaluate.
- bool success = function_->Evaluate(parameters, residuals, NULL);
- if (!success) {
- // Something went wrong; ignore the jacobian.
+ if (!internal::EvaluateImpl<CostFunctor,
+ N0, N1, N2, N3, N4, N5, N6, N7, N8, N9>(
+ functor_.get(),
+ parameters,
+ residuals,
+ functor_.get())) {
return false;
}
+
if (!jacobians) {
- // Nothing to do; just forward.
return true;
}
// Create a copy of the parameters which will get mutated.
- const int kParametersSize = N0 + N1 + N2 + N3 + N4 + N5;
- double parameters_copy[kParametersSize];
- double *parameters_references_copy[6];
- parameters_references_copy[0] = &parameters_copy[0];
- parameters_references_copy[1] = &parameters_copy[0] + N0;
- parameters_references_copy[2] = &parameters_copy[0] + N0 + N1;
- parameters_references_copy[3] = &parameters_copy[0] + N0 + N1 + N2;
- parameters_references_copy[4] = &parameters_copy[0] + N0 + N1 + N2 + N3;
- parameters_references_copy[5] =
- &parameters_copy[0] + N0 + N1 + N2 + N3 + N4;
+ FixedArray<double> parameters_copy(kNumParameters);
+ FixedArray<double*> parameters_reference_copy(kNumParameterBlocks);
+
+ parameters_reference_copy[0] = parameters_copy.get();
+ if (N1) parameters_reference_copy[1] = parameters_reference_copy[0] + N0;
+ if (N2) parameters_reference_copy[2] = parameters_reference_copy[1] + N1;
+ if (N3) parameters_reference_copy[3] = parameters_reference_copy[2] + N2;
+ if (N4) parameters_reference_copy[4] = parameters_reference_copy[3] + N3;
+ if (N5) parameters_reference_copy[5] = parameters_reference_copy[4] + N4;
+ if (N6) parameters_reference_copy[6] = parameters_reference_copy[5] + N5;
+ if (N7) parameters_reference_copy[7] = parameters_reference_copy[6] + N6;
+ if (N7) parameters_reference_copy[8] = parameters_reference_copy[7] + N7;
+ if (N8) parameters_reference_copy[9] = parameters_reference_copy[8] + N8;
+
+#define COPY_PARAMETER_BLOCK(block) \
+ if (N ## block) memcpy(parameters_reference_copy[block], \
+ parameters[block], \
+ sizeof(double) * N ## block); // NOLINT
-#define COPY_PARAMETER_BLOCK(block) \
- if (N ## block) memcpy(parameters_references_copy[block], \
- parameters[block], \
- sizeof(double) * N ## block); // NOLINT
COPY_PARAMETER_BLOCK(0);
COPY_PARAMETER_BLOCK(1);
COPY_PARAMETER_BLOCK(2);
COPY_PARAMETER_BLOCK(3);
COPY_PARAMETER_BLOCK(4);
COPY_PARAMETER_BLOCK(5);
+ COPY_PARAMETER_BLOCK(6);
+ COPY_PARAMETER_BLOCK(7);
+ COPY_PARAMETER_BLOCK(8);
+ COPY_PARAMETER_BLOCK(9);
+
#undef COPY_PARAMETER_BLOCK
-#define EVALUATE_JACOBIAN_FOR_BLOCK(block) \
- if (N ## block && jacobians[block]) { \
- if (!Differencer<CostFunctionNoJacobian, /* NOLINT */ \
- M, \
- N ## block, \
- block, \
- method>::EvaluateJacobianForParameterBlock( \
- function_.get(), \
- residuals, \
- parameters_references_copy, \
- jacobians)) { \
- return false; \
- } \
+#define EVALUATE_JACOBIAN_FOR_BLOCK(block) \
+ if (N ## block && jacobians[block] != NULL) { \
+ if (!NumericDiff<CostFunctor, \
+ method, \
+ kNumResiduals, \
+ N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, \
+ block, \
+ N ## block >::EvaluateJacobianForParameterBlock( \
+ functor_.get(), \
+ residuals, \
+ relative_step_size_, \
+ parameters_reference_copy.get(), \
+ jacobians[block])) { \
+ return false; \
+ } \
}
+
EVALUATE_JACOBIAN_FOR_BLOCK(0);
EVALUATE_JACOBIAN_FOR_BLOCK(1);
EVALUATE_JACOBIAN_FOR_BLOCK(2);
EVALUATE_JACOBIAN_FOR_BLOCK(3);
EVALUATE_JACOBIAN_FOR_BLOCK(4);
EVALUATE_JACOBIAN_FOR_BLOCK(5);
+ EVALUATE_JACOBIAN_FOR_BLOCK(6);
+ EVALUATE_JACOBIAN_FOR_BLOCK(7);
+ EVALUATE_JACOBIAN_FOR_BLOCK(8);
+ EVALUATE_JACOBIAN_FOR_BLOCK(9);
+
#undef EVALUATE_JACOBIAN_FOR_BLOCK
+
return true;
}
private:
- internal::scoped_ptr<CostFunctionNoJacobian> function_;
+ internal::scoped_ptr<CostFunctor> functor_;
Ownership ownership_;
+ const double relative_step_size_;
};
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h
new file mode 100644
index 00000000000..593c3718bf5
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h
@@ -0,0 +1,346 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// A wrapper class that takes a variadic functor evaluating a
+// function, numerically differentiates it and makes it available as a
+// templated functor so that it can be easily used as part of Ceres'
+// automatic differentiation framework.
+//
+// For example:
+//
+// For example, let us assume that
+//
+// struct IntrinsicProjection
+// IntrinsicProjection(const double* observations);
+// bool operator()(const double* calibration,
+// const double* point,
+// double* residuals);
+// };
+//
+// is a functor that implements the projection of a point in its local
+// coordinate system onto its image plane and subtracts it from the
+// observed point projection.
+//
+// Now we would like to compose the action of this functor with the
+// action of camera extrinsics, i.e., rotation and translation, which
+// is given by the following templated function
+//
+// template<typename T>
+// void RotateAndTranslatePoint(const T* rotation,
+// const T* translation,
+// const T* point,
+// T* result);
+//
+// To compose the extrinsics and intrinsics, we can construct a
+// CameraProjection functor as follows.
+//
+// struct CameraProjection {
+// typedef NumericDiffFunctor<IntrinsicProjection, CENTRAL, 2, 5, 3>
+// IntrinsicProjectionFunctor;
+//
+// CameraProjection(double* observation) {
+// intrinsic_projection_.reset(
+// new IntrinsicProjectionFunctor(observation)) {
+// }
+//
+// template <typename T>
+// bool operator(const T* rotation,
+// const T* translation,
+// const T* intrinsics,
+// const T* point,
+// T* residuals) const {
+// T transformed_point[3];
+// RotateAndTranslatePoint(rotation, translation, point, transformed_point);
+// return (*intrinsic_projection_)(intrinsics, transformed_point, residual);
+// }
+//
+// private:
+// scoped_ptr<IntrinsicProjectionFunctor> intrinsic_projection_;
+// };
+//
+// Here, we made the choice of using CENTRAL differences to compute
+// the jacobian of IntrinsicProjection.
+//
+// Now, we are ready to construct an automatically differentiated cost
+// function as
+//
+// CostFunction* cost_function =
+// new AutoDiffCostFunction<CameraProjection, 2, 3, 3, 5>(
+// new CameraProjection(observations));
+//
+// cost_function now seamlessly integrates automatic differentiation
+// of RotateAndTranslatePoint with a numerically differentiated
+// version of IntrinsicProjection.
+
+#ifndef CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
+#define CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
+
+#include "ceres/numeric_diff_cost_function.h"
+#include "ceres/types.h"
+#include "ceres/cost_function_to_functor.h"
+
+namespace ceres {
+
+template<typename Functor,
+ NumericDiffMethod kMethod = CENTRAL,
+ int kNumResiduals = 0,
+ int N0 = 0, int N1 = 0 , int N2 = 0, int N3 = 0, int N4 = 0,
+ int N5 = 0, int N6 = 0 , int N7 = 0, int N8 = 0, int N9 = 0>
+class NumericDiffFunctor {
+ public:
+ // relative_step_size controls the step size used by the numeric
+ // differentiation process.
+ explicit NumericDiffFunctor(double relative_step_size = 1e-6)
+ : functor_(
+ new NumericDiffCostFunction<Functor,
+ kMethod,
+ kNumResiduals,
+ N0, N1, N2, N3, N4,
+ N5, N6, N7, N8, N9>(new Functor,
+ relative_step_size)) {
+ }
+
+ NumericDiffFunctor(Functor* functor, double relative_step_size = 1e-6)
+ : functor_(new NumericDiffCostFunction<Functor,
+ kMethod,
+ kNumResiduals,
+ N0, N1, N2, N3, N4,
+ N5, N6, N7, N8, N9>(
+ functor, relative_step_size)) {
+ }
+
+ bool operator()(const double* x0, double* residuals) const {
+ return functor_(x0, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ double* residuals) const {
+ return functor_(x0, x1, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ double* residuals) const {
+ return functor_(x0, x1, x2, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ double* residuals) const {
+ return functor_(x0, x1, x2, x3, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ double* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ double* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ double* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ const double* x7,
+ double* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ const double* x7,
+ const double* x8,
+ double* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
+ }
+
+ bool operator()(const double* x0,
+ const double* x1,
+ const double* x2,
+ const double* x3,
+ const double* x4,
+ const double* x5,
+ const double* x6,
+ const double* x7,
+ const double* x8,
+ const double* x9,
+ double* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0, T* residuals) const {
+ return functor_(x0, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ T* residuals) const {
+ return functor_(x0, x1, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ T* residuals) const {
+ return functor_(x0, x1, x2, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ const T* x3,
+ T* residuals) const {
+ return functor_(x0, x1, x2, x3, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ const T* x3,
+ const T* x4,
+ T* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ const T* x3,
+ const T* x4,
+ const T* x5,
+ T* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ const T* x3,
+ const T* x4,
+ const T* x5,
+ const T* x6,
+ T* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ const T* x3,
+ const T* x4,
+ const T* x5,
+ const T* x6,
+ const T* x7,
+ T* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ const T* x3,
+ const T* x4,
+ const T* x5,
+ const T* x6,
+ const T* x7,
+ const T* x8,
+ T* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
+ }
+
+ template <typename T>
+ bool operator()(const T* x0,
+ const T* x1,
+ const T* x2,
+ const T* x3,
+ const T* x4,
+ const T* x5,
+ const T* x6,
+ const T* x7,
+ const T* x8,
+ const T* x9,
+ T* residuals) const {
+ return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
+ }
+
+
+ private:
+ CostFunctionToFunctor<kNumResiduals,
+ N0, N1, N2, N3, N4,
+ N5, N6, N7, N8, N9> functor_;
+};
+
+} // namespace ceres
+
+#endif // CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/ordered_groups.h b/extern/libmv/third_party/ceres/include/ceres/ordered_groups.h
new file mode 100644
index 00000000000..e373d35b9d7
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/ordered_groups.h
@@ -0,0 +1,176 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_PUBLIC_ORDERED_GROUPS_H_
+#define CERES_PUBLIC_ORDERED_GROUPS_H_
+
+#include <map>
+#include <set>
+#include "ceres/internal/port.h"
+
+namespace ceres {
+
+// A class for storing and manipulating an ordered collection of
+// groups/sets with the following semantics:
+//
+// Group ids are non-negative integer values. Elements are any type
+// that can serve as a key in a map or an element of a set.
+//
+// An element can only belong to one group at a time. A group may
+// contain an arbitrary number of elements.
+//
+// Groups are ordered by their group id.
+template <typename T>
+class OrderedGroups {
+ public:
+ // Add an element to a group. If a group with this id does not
+ // exist, one is created. This method can be called any number of
+ // times for the same element. Group ids should be non-negative
+ // numbers.
+ //
+ // Return value indicates if adding the element was a success.
+ bool AddElementToGroup(const T element, const int group) {
+ if (group < 0) {
+ return false;
+ }
+
+ typename map<T, int>::const_iterator it = element_to_group_.find(element);
+ if (it != element_to_group_.end()) {
+ if (it->second == group) {
+ // Element is already in the right group, nothing to do.
+ return true;
+ }
+
+ group_to_elements_[it->second].erase(element);
+ if (group_to_elements_[it->second].size() == 0) {
+ group_to_elements_.erase(it->second);
+ }
+ }
+
+ element_to_group_[element] = group;
+ group_to_elements_[group].insert(element);
+ return true;
+ }
+
+ void Clear() {
+ group_to_elements_.clear();
+ element_to_group_.clear();
+ }
+
+ // Remove the element, no matter what group it is in. If the element
+ // is not a member of any group, calling this method will result in
+ // a crash.
+ //
+ // Return value indicates if the element was actually removed.
+ bool Remove(const T element) {
+ const int current_group = GroupId(element);
+ if (current_group < 0) {
+ return false;
+ }
+
+ group_to_elements_[current_group].erase(element);
+
+ if (group_to_elements_[current_group].size() == 0) {
+ // If the group is empty, then get rid of it.
+ group_to_elements_.erase(current_group);
+ }
+
+ element_to_group_.erase(element);
+ return true;
+ }
+
+ // Reverse the order of the groups in place.
+ void Reverse() {
+ typename map<int, set<T> >::reverse_iterator it =
+ group_to_elements_.rbegin();
+ map<int, set<T> > new_group_to_elements;
+ new_group_to_elements[it->first] = it->second;
+
+ int new_group_id = it->first + 1;
+ for (++it; it != group_to_elements_.rend(); ++it) {
+ for (typename set<T>::const_iterator element_it = it->second.begin();
+ element_it != it->second.end();
+ ++element_it) {
+ element_to_group_[*element_it] = new_group_id;
+ }
+ new_group_to_elements[new_group_id] = it->second;
+ new_group_id++;
+ }
+
+ group_to_elements_.swap(new_group_to_elements);
+ }
+
+ // Return the group id for the element. If the element is not a
+ // member of any group, return -1.
+ int GroupId(const T element) const {
+ typename map<T, int>::const_iterator it = element_to_group_.find(element);
+ if (it == element_to_group_.end()) {
+ return -1;
+ }
+ return it->second;
+ }
+
+ bool IsMember(const T element) const {
+ typename map<T, int>::const_iterator it = element_to_group_.find(element);
+ return (it != element_to_group_.end());
+ }
+
+ // This function always succeeds, i.e., implicitly there exists a
+ // group for every integer.
+ int GroupSize(const int group) const {
+ typename map<int, set<T> >::const_iterator it =
+ group_to_elements_.find(group);
+ return (it == group_to_elements_.end()) ? 0 : it->second.size();
+ }
+
+ int NumElements() const {
+ return element_to_group_.size();
+ }
+
+ // Number of groups with one or more elements.
+ int NumGroups() const {
+ return group_to_elements_.size();
+ }
+
+ const map<int, set<T> >& group_to_elements() const {
+ return group_to_elements_;
+ }
+
+ private:
+ map<int, set<T> > group_to_elements_;
+ map<T, int> element_to_group_;
+};
+
+// Typedef for the most commonly used version of OrderedGroups.
+typedef OrderedGroups<double*> ParameterBlockOrdering;
+
+} // namespace ceres
+
+#endif // CERES_PUBLIC_ORDERED_GROUP_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/problem.h b/extern/libmv/third_party/ceres/include/ceres/problem.h
index 2b08c6723e8..bccb329dc55 100644
--- a/extern/libmv/third_party/ceres/include/ceres/problem.h
+++ b/extern/libmv/third_party/ceres/include/ceres/problem.h
@@ -39,11 +39,12 @@
#include <set>
#include <vector>
-#include <glog/logging.h>
#include "ceres/internal/macros.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
+#include "glog/logging.h"
+
namespace ceres {
@@ -51,6 +52,7 @@ class CostFunction;
class LossFunction;
class LocalParameterization;
class Solver;
+struct CRSMatrix;
namespace internal {
class Preprocessor;
@@ -59,10 +61,9 @@ class ParameterBlock;
class ResidualBlock;
} // namespace internal
-// A ResidualBlockId is a handle clients can use to delete residual
-// blocks after creating them. They are opaque for any purposes other
-// than that.
-typedef const internal::ResidualBlock* ResidualBlockId;
+// A ResidualBlockId is an opaque handle clients can use to remove residual
+// blocks from a Problem after adding them.
+typedef internal::ResidualBlock* ResidualBlockId;
// A class to represent non-linear least squares problems. Such
// problems have a cost function that is a sum of error terms (known
@@ -122,7 +123,9 @@ class Problem {
Options()
: cost_function_ownership(TAKE_OWNERSHIP),
loss_function_ownership(TAKE_OWNERSHIP),
- local_parameterization_ownership(TAKE_OWNERSHIP) {}
+ local_parameterization_ownership(TAKE_OWNERSHIP),
+ enable_fast_parameter_block_removal(false),
+ disable_all_safety_checks(false) {}
// These flags control whether the Problem object owns the cost
// functions, loss functions, and parameterizations passed into
@@ -134,6 +137,29 @@ class Problem {
Ownership cost_function_ownership;
Ownership loss_function_ownership;
Ownership local_parameterization_ownership;
+
+ // If true, trades memory for a faster RemoveParameterBlock() operation.
+ //
+ // RemoveParameterBlock() takes time proportional to the size of the entire
+ // Problem. If you only remove parameter blocks from the Problem
+ // occassionaly, this may be acceptable. However, if you are modifying the
+ // Problem frequently, and have memory to spare, then flip this switch to
+ // make RemoveParameterBlock() take time proportional to the number of
+ // residual blocks that depend on it. The increase in memory usage is an
+ // additonal hash set per parameter block containing all the residuals that
+ // depend on the parameter block.
+ bool enable_fast_parameter_block_removal;
+
+ // By default, Ceres performs a variety of safety checks when constructing
+ // the problem. There is a small but measurable performance penalty to
+ // these checks, typically around 5% of construction time. If you are sure
+ // your problem construction is correct, and 5% of the problem construction
+ // time is truly an overhead you want to avoid, then you can set
+ // disable_all_safety_checks to true.
+ //
+ // WARNING: Do not set this to true, unless you are absolutely sure of what
+ // you are doing.
+ bool disable_all_safety_checks;
};
// The default constructor is equivalent to the
@@ -208,6 +234,27 @@ class Problem {
LossFunction* loss_function,
double* x0, double* x1, double* x2,
double* x3, double* x4, double* x5);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6, double* x7);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8,
+ double* x9);
// Add a parameter block with appropriate size to the problem.
// Repeated calls with the same arguments are ignored. Repeated
@@ -223,6 +270,33 @@ class Problem {
int size,
LocalParameterization* local_parameterization);
+ // Remove a parameter block from the problem. The parameterization of the
+ // parameter block, if it exists, will persist until the deletion of the
+ // problem (similar to cost/loss functions in residual block removal). Any
+ // residual blocks that depend on the parameter are also removed, as
+ // described above in RemoveResidualBlock().
+ //
+ // If Problem::Options::enable_fast_parameter_block_removal is true, then the
+ // removal is fast (almost constant time). Otherwise, removing a parameter
+ // block will incur a scan of the entire Problem object.
+ //
+ // WARNING: Removing a residual or parameter block will destroy the implicit
+ // ordering, rendering the jacobian or residuals returned from the solver
+ // uninterpretable. If you depend on the evaluated jacobian, do not use
+ // remove! This may change in a future release.
+ void RemoveParameterBlock(double* values);
+
+ // Remove a residual block from the problem. Any parameters that the residual
+ // block depends on are not removed. The cost and loss functions for the
+ // residual block will not get deleted immediately; won't happen until the
+ // problem itself is deleted.
+ //
+ // WARNING: Removing a residual or parameter block will destroy the implicit
+ // ordering, rendering the jacobian or residuals returned from the solver
+ // uninterpretable. If you depend on the evaluated jacobian, do not use
+ // remove! This may change in a future release.
+ void RemoveResidualBlock(ResidualBlockId residual_block);
+
// Hold the indicated parameter block constant during optimization.
void SetParameterBlockConstant(double* values);
@@ -254,6 +328,76 @@ class Problem {
// sizes of all of the residual blocks.
int NumResiduals() const;
+ // Options struct to control Problem::Evaluate.
+ struct EvaluateOptions {
+ EvaluateOptions()
+ : num_threads(1) {
+ }
+
+ // The set of parameter blocks for which evaluation should be
+ // performed. This vector determines the order that parameter
+ // blocks occur in the gradient vector and in the columns of the
+ // jacobian matrix. If parameter_blocks is empty, then it is
+ // assumed to be equal to vector containing ALL the parameter
+ // blocks. Generally speaking the parameter blocks will occur in
+ // the order in which they were added to the problem. But, this
+ // may change if the user removes any parameter blocks from the
+ // problem.
+ //
+ // NOTE: This vector should contain the same pointers as the ones
+ // used to add parameter blocks to the Problem. These parmeter
+ // block should NOT point to new memory locations. Bad things will
+ // happen otherwise.
+ vector<double*> parameter_blocks;
+
+ // The set of residual blocks to evaluate. This vector determines
+ // the order in which the residuals occur, and how the rows of the
+ // jacobian are ordered. If residual_blocks is empty, then it is
+ // assumed to be equal to the vector containing all the residual
+ // blocks. If this vector is empty, then it is assumed to be equal
+ // to a vector containing ALL the residual blocks. Generally
+ // speaking the residual blocks will occur in the order in which
+ // they were added to the problem. But, this may change if the
+ // user removes any residual blocks from the problem.
+ vector<ResidualBlockId> residual_blocks;
+ int num_threads;
+ };
+
+ // Evaluate Problem. Any of the output pointers can be NULL. Which
+ // residual blocks and parameter blocks are used is controlled by
+ // the EvaluateOptions struct above.
+ //
+ // Note 1: The evaluation will use the values stored in the memory
+ // locations pointed to by the parameter block pointers used at the
+ // time of the construction of the problem. i.e.,
+ //
+ // Problem problem;
+ // double x = 1;
+ // problem.Add(new MyCostFunction, NULL, &x);
+ //
+ // double cost = 0.0;
+ // problem.Evaluate(Problem::EvaluateOptions(), &cost, NULL, NULL, NULL);
+ //
+ // The cost is evaluated at x = 1. If you wish to evaluate the
+ // problem at x = 2, then
+ //
+ // x = 2;
+ // problem.Evaluate(Problem::EvaluateOptions(), &cost, NULL, NULL, NULL);
+ //
+ // is the way to do so.
+ //
+ // Note 2: If no local parameterizations are used, then the size of
+ // the gradient vector (and the number of columns in the jacobian)
+ // is the sum of the sizes of all the parameter blocks. If a
+ // parameter block has a local parameterization, then it contributes
+ // "LocalSize" entries to the gradient vecto (and the number of
+ // columns in the jacobian).
+ bool Evaluate(const EvaluateOptions& options,
+ double* cost,
+ vector<double>* residuals,
+ vector<double>* gradient,
+ CRSMatrix* jacobian);
+
private:
friend class Solver;
internal::scoped_ptr<internal::ProblemImpl> problem_impl_;
diff --git a/extern/libmv/third_party/ceres/include/ceres/rotation.h b/extern/libmv/third_party/ceres/include/ceres/rotation.h
index 0d8a390d5d1..ffac4f1dc0c 100644
--- a/extern/libmv/third_party/ceres/include/ceres/rotation.h
+++ b/extern/libmv/third_party/ceres/include/ceres/rotation.h
@@ -51,6 +51,31 @@
namespace ceres {
+// Trivial wrapper to index linear arrays as matrices, given a fixed
+// column and row stride. When an array "T* array" is wrapped by a
+//
+// (const) MatrixAdapter<T, row_stride, col_stride> M"
+//
+// the expression M(i, j) is equivalent to
+//
+// arrary[i * row_stride + j * col_stride]
+//
+// Conversion functions to and from rotation matrices accept
+// MatrixAdapters to permit using row-major and column-major layouts,
+// and rotation matrices embedded in larger matrices (such as a 3x4
+// projection matrix).
+template <typename T, int row_stride, int col_stride>
+struct MatrixAdapter;
+
+// Convenience functions to create a MatrixAdapter that treats the
+// array pointed to by "pointer" as a 3x3 (contiguous) column-major or
+// row-major matrix.
+template <typename T>
+MatrixAdapter<T, 1, 3> ColumnMajorAdapter3x3(T* pointer);
+
+template <typename T>
+MatrixAdapter<T, 3, 1> RowMajorAdapter3x3(T* pointer);
+
// Convert a value in combined axis-angle representation to a quaternion.
// The value angle_axis is a triple whose norm is an angle in radians,
// and whose direction is aligned with the axis of rotation,
@@ -73,9 +98,20 @@ void QuaternionToAngleAxis(T const* quaternion, T* angle_axis);
// axis-angle rotation representations. Templated for use with
// autodifferentiation.
template <typename T>
-void RotationMatrixToAngleAxis(T const * R, T * angle_axis);
+void RotationMatrixToAngleAxis(T const* R, T* angle_axis);
+
+template <typename T, int row_stride, int col_stride>
+void RotationMatrixToAngleAxis(
+ const MatrixAdapter<const T, row_stride, col_stride>& R,
+ T* angle_axis);
+
template <typename T>
-void AngleAxisToRotationMatrix(T const * angle_axis, T * R);
+void AngleAxisToRotationMatrix(T const* angle_axis, T* R);
+
+template <typename T, int row_stride, int col_stride>
+void AngleAxisToRotationMatrix(
+ T const* angle_axis,
+ const MatrixAdapter<T, row_stride, col_stride>& R);
// Conversions between 3x3 rotation matrix (in row major order) and
// Euler angle (in degrees) rotation representations.
@@ -86,6 +122,11 @@ void AngleAxisToRotationMatrix(T const * angle_axis, T * R);
template <typename T>
void EulerAnglesToRotationMatrix(const T* euler, int row_stride, T* R);
+template <typename T, int row_stride, int col_stride>
+void EulerAnglesToRotationMatrix(
+ const T* euler,
+ const MatrixAdapter<T, row_stride, col_stride>& R);
+
// Convert a 4-vector to a 3x3 scaled rotation matrix.
//
// The choice of rotation is such that the quaternion [1 0 0 0] goes to an
@@ -108,11 +149,21 @@ void EulerAnglesToRotationMatrix(const T* euler, int row_stride, T* R);
template <typename T> inline
void QuaternionToScaledRotation(const T q[4], T R[3 * 3]);
+template <typename T, int row_stride, int col_stride> inline
+void QuaternionToScaledRotation(
+ const T q[4],
+ const MatrixAdapter<T, row_stride, col_stride>& R);
+
// Same as above except that the rotation matrix is normalized by the
// Frobenius norm, so that R * R' = I (and det(R) = 1).
template <typename T> inline
void QuaternionToRotation(const T q[4], T R[3 * 3]);
+template <typename T, int row_stride, int col_stride> inline
+void QuaternionToRotation(
+ const T q[4],
+ const MatrixAdapter<T, row_stride, col_stride>& R);
+
// Rotates a point pt by a quaternion q:
//
// result = R(q) * pt
@@ -146,6 +197,28 @@ void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3]);
// --- IMPLEMENTATION
+template<typename T, int row_stride, int col_stride>
+struct MatrixAdapter {
+ T* pointer_;
+ explicit MatrixAdapter(T* pointer)
+ : pointer_(pointer)
+ {}
+
+ T& operator()(int r, int c) const {
+ return pointer_[r * row_stride + c * col_stride];
+ }
+};
+
+template <typename T>
+MatrixAdapter<T, 1, 3> ColumnMajorAdapter3x3(T* pointer) {
+ return MatrixAdapter<T, 1, 3>(pointer);
+}
+
+template <typename T>
+MatrixAdapter<T, 3, 1> RowMajorAdapter3x3(T* pointer) {
+ return MatrixAdapter<T, 3, 1>(pointer);
+}
+
template<typename T>
inline void AngleAxisToQuaternion(const T* angle_axis, T* quaternion) {
const T& a0 = angle_axis[0];
@@ -228,17 +301,24 @@ inline void QuaternionToAngleAxis(const T* quaternion, T* angle_axis) {
// to not perform division by a small number.
template <typename T>
inline void RotationMatrixToAngleAxis(const T * R, T * angle_axis) {
+ RotationMatrixToAngleAxis(ColumnMajorAdapter3x3(R), angle_axis);
+}
+
+template <typename T, int row_stride, int col_stride>
+void RotationMatrixToAngleAxis(
+ const MatrixAdapter<const T, row_stride, col_stride>& R,
+ T * angle_axis) {
// x = k * 2 * sin(theta), where k is the axis of rotation.
- angle_axis[0] = R[5] - R[7];
- angle_axis[1] = R[6] - R[2];
- angle_axis[2] = R[1] - R[3];
+ angle_axis[0] = R(2, 1) - R(1, 2);
+ angle_axis[1] = R(0, 2) - R(2, 0);
+ angle_axis[2] = R(1, 0) - R(0, 1);
static const T kOne = T(1.0);
static const T kTwo = T(2.0);
// Since the right hand side may give numbers just above 1.0 or
// below -1.0 leading to atan misbehaving, we threshold.
- T costheta = std::min(std::max((R[0] + R[4] + R[8] - kOne) / kTwo,
+ T costheta = std::min(std::max((R(0, 0) + R(1, 1) + R(2, 2) - kOne) / kTwo,
T(-1.0)),
kOne);
@@ -296,7 +376,7 @@ inline void RotationMatrixToAngleAxis(const T * R, T * angle_axis) {
// with the sign of sin(theta). If they are the same, then
// angle_axis[i] should be positive, otherwise negative.
for (int i = 0; i < 3; ++i) {
- angle_axis[i] = theta * sqrt((R[i*4] - costheta) * inv_one_minus_costheta);
+ angle_axis[i] = theta * sqrt((R(i, i) - costheta) * inv_one_minus_costheta);
if (((sintheta < 0.0) && (angle_axis[i] > 0.0)) ||
((sintheta > 0.0) && (angle_axis[i] < 0.0))) {
angle_axis[i] = -angle_axis[i];
@@ -306,6 +386,13 @@ inline void RotationMatrixToAngleAxis(const T * R, T * angle_axis) {
template <typename T>
inline void AngleAxisToRotationMatrix(const T * angle_axis, T * R) {
+ AngleAxisToRotationMatrix(angle_axis, ColumnMajorAdapter3x3(R));
+}
+
+template <typename T, int row_stride, int col_stride>
+void AngleAxisToRotationMatrix(
+ const T * angle_axis,
+ const MatrixAdapter<T, row_stride, col_stride>& R) {
static const T kOne = T(1.0);
const T theta2 = DotProduct(angle_axis, angle_axis);
if (theta2 > 0.0) {
@@ -320,33 +407,41 @@ inline void AngleAxisToRotationMatrix(const T * angle_axis, T * R) {
const T costheta = cos(theta);
const T sintheta = sin(theta);
- R[0] = costheta + wx*wx*(kOne - costheta);
- R[1] = wz*sintheta + wx*wy*(kOne - costheta);
- R[2] = -wy*sintheta + wx*wz*(kOne - costheta);
- R[3] = wx*wy*(kOne - costheta) - wz*sintheta;
- R[4] = costheta + wy*wy*(kOne - costheta);
- R[5] = wx*sintheta + wy*wz*(kOne - costheta);
- R[6] = wy*sintheta + wx*wz*(kOne - costheta);
- R[7] = -wx*sintheta + wy*wz*(kOne - costheta);
- R[8] = costheta + wz*wz*(kOne - costheta);
+ R(0, 0) = costheta + wx*wx*(kOne - costheta);
+ R(1, 0) = wz*sintheta + wx*wy*(kOne - costheta);
+ R(2, 0) = -wy*sintheta + wx*wz*(kOne - costheta);
+ R(0, 1) = wx*wy*(kOne - costheta) - wz*sintheta;
+ R(1, 1) = costheta + wy*wy*(kOne - costheta);
+ R(2, 1) = wx*sintheta + wy*wz*(kOne - costheta);
+ R(0, 2) = wy*sintheta + wx*wz*(kOne - costheta);
+ R(1, 2) = -wx*sintheta + wy*wz*(kOne - costheta);
+ R(2, 2) = costheta + wz*wz*(kOne - costheta);
} else {
// At zero, we switch to using the first order Taylor expansion.
- R[0] = kOne;
- R[1] = -angle_axis[2];
- R[2] = angle_axis[1];
- R[3] = angle_axis[2];
- R[4] = kOne;
- R[5] = -angle_axis[0];
- R[6] = -angle_axis[1];
- R[7] = angle_axis[0];
- R[8] = kOne;
+ R(0, 0) = kOne;
+ R(1, 0) = -angle_axis[2];
+ R(2, 0) = angle_axis[1];
+ R(0, 1) = angle_axis[2];
+ R(1, 1) = kOne;
+ R(2, 1) = -angle_axis[0];
+ R(0, 2) = -angle_axis[1];
+ R(1, 2) = angle_axis[0];
+ R(2, 2) = kOne;
}
}
template <typename T>
inline void EulerAnglesToRotationMatrix(const T* euler,
- const int row_stride,
+ const int row_stride_parameter,
T* R) {
+ CHECK_EQ(row_stride_parameter, 3);
+ EulerAnglesToRotationMatrix(euler, RowMajorAdapter3x3(R));
+}
+
+template <typename T, int row_stride, int col_stride>
+void EulerAnglesToRotationMatrix(
+ const T* euler,
+ const MatrixAdapter<T, row_stride, col_stride>& R) {
const double kPi = 3.14159265358979323846;
const T degrees_to_radians(kPi / 180.0);
@@ -361,26 +456,28 @@ inline void EulerAnglesToRotationMatrix(const T* euler,
const T c3 = cos(pitch);
const T s3 = sin(pitch);
- // Rows of the rotation matrix.
- T* R1 = R;
- T* R2 = R1 + row_stride;
- T* R3 = R2 + row_stride;
-
- R1[0] = c1*c2;
- R1[1] = -s1*c3 + c1*s2*s3;
- R1[2] = s1*s3 + c1*s2*c3;
+ R(0, 0) = c1*c2;
+ R(0, 1) = -s1*c3 + c1*s2*s3;
+ R(0, 2) = s1*s3 + c1*s2*c3;
- R2[0] = s1*c2;
- R2[1] = c1*c3 + s1*s2*s3;
- R2[2] = -c1*s3 + s1*s2*c3;
+ R(1, 0) = s1*c2;
+ R(1, 1) = c1*c3 + s1*s2*s3;
+ R(1, 2) = -c1*s3 + s1*s2*c3;
- R3[0] = -s2;
- R3[1] = c2*s3;
- R3[2] = c2*c3;
+ R(2, 0) = -s2;
+ R(2, 1) = c2*s3;
+ R(2, 2) = c2*c3;
}
template <typename T> inline
void QuaternionToScaledRotation(const T q[4], T R[3 * 3]) {
+ QuaternionToScaledRotation(q, RowMajorAdapter3x3(R));
+}
+
+template <typename T, int row_stride, int col_stride> inline
+void QuaternionToScaledRotation(
+ const T q[4],
+ const MatrixAdapter<T, row_stride, col_stride>& R) {
// Make convenient names for elements of q.
T a = q[0];
T b = q[1];
@@ -399,21 +496,29 @@ void QuaternionToScaledRotation(const T q[4], T R[3 * 3]) {
T cd = c * d;
T dd = d * d;
- R[0] = aa + bb - cc - dd; R[1] = T(2) * (bc - ad); R[2] = T(2) * (ac + bd); // NOLINT
- R[3] = T(2) * (ad + bc); R[4] = aa - bb + cc - dd; R[5] = T(2) * (cd - ab); // NOLINT
- R[6] = T(2) * (bd - ac); R[7] = T(2) * (ab + cd); R[8] = aa - bb - cc + dd; // NOLINT
+ R(0, 0) = aa + bb - cc - dd; R(0, 1) = T(2) * (bc - ad); R(0, 2) = T(2) * (ac + bd); // NOLINT
+ R(1, 0) = T(2) * (ad + bc); R(1, 1) = aa - bb + cc - dd; R(1, 2) = T(2) * (cd - ab); // NOLINT
+ R(2, 0) = T(2) * (bd - ac); R(2, 1) = T(2) * (ab + cd); R(2, 2) = aa - bb - cc + dd; // NOLINT
}
template <typename T> inline
void QuaternionToRotation(const T q[4], T R[3 * 3]) {
+ QuaternionToRotation(q, RowMajorAdapter3x3(R));
+}
+
+template <typename T, int row_stride, int col_stride> inline
+void QuaternionToRotation(const T q[4],
+ const MatrixAdapter<T, row_stride, col_stride>& R) {
QuaternionToScaledRotation(q, R);
T normalizer = q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3];
CHECK_NE(normalizer, T(0));
normalizer = T(1) / normalizer;
- for (int i = 0; i < 9; ++i) {
- R[i] *= normalizer;
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ R(i, j) *= normalizer;
+ }
}
}
@@ -433,7 +538,6 @@ void UnitQuaternionRotatePoint(const T q[4], const T pt[3], T result[3]) {
result[2] = T(2) * ((t7 - t3) * pt[0] + (t2 + t9) * pt[1] + (t5 + t8) * pt[2]) + pt[2]; // NOLINT
}
-
template <typename T> inline
void QuaternionRotatePoint(const T q[4], const T pt[3], T result[3]) {
// 'scale' is 1 / norm(q).
diff --git a/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h
index 2894a9fba5c..6bfc1af31a2 100644
--- a/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h
+++ b/extern/libmv/third_party/ceres/include/ceres/sized_cost_function.h
@@ -45,25 +45,29 @@
namespace ceres {
template<int kNumResiduals,
- int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0, int N5 = 0>
+ int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
+ int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
class SizedCostFunction : public CostFunction {
public:
SizedCostFunction() {
- // Sanity checking.
CHECK(kNumResiduals > 0 || kNumResiduals == DYNAMIC)
<< "Cost functions must have at least one residual block.";
- CHECK_GT(N0, 0)
- << "Cost functions must have at least one parameter block.";
- CHECK((!N1 && !N2 && !N3 && !N4 && !N5) ||
- ((N1 > 0) && !N2 && !N3 && !N4 && !N5) ||
- ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5) ||
- ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5) ||
- ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5) ||
- ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0)))
+ // This block breaks the 80 column rule to keep it somewhat readable.
+ CHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) ||
+ ((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0)))
<< "Zero block cannot precede a non-zero block. Block sizes are "
<< "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
- << N3 << ", " << N4 << ", " << N5;
+ << N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
+ << N8 << ", " << N9;
set_num_residuals(kNumResiduals);
@@ -75,6 +79,10 @@ class SizedCostFunction : public CostFunction {
ADD_PARAMETER_BLOCK(N3);
ADD_PARAMETER_BLOCK(N4);
ADD_PARAMETER_BLOCK(N5);
+ ADD_PARAMETER_BLOCK(N6);
+ ADD_PARAMETER_BLOCK(N7);
+ ADD_PARAMETER_BLOCK(N8);
+ ADD_PARAMETER_BLOCK(N9);
#undef ADD_PARAMETER_BLOCK
}
diff --git a/extern/libmv/third_party/ceres/include/ceres/solver.h b/extern/libmv/third_party/ceres/include/ceres/solver.h
index 31d5e8d7987..122870c86c8 100644
--- a/extern/libmv/third_party/ceres/include/ceres/solver.h
+++ b/extern/libmv/third_party/ceres/include/ceres/solver.h
@@ -38,6 +38,7 @@
#include "ceres/internal/macros.h"
#include "ceres/internal/port.h"
#include "ceres/iteration_callback.h"
+#include "ceres/ordered_groups.h"
#include "ceres/types.h"
namespace ceres {
@@ -57,6 +58,11 @@ class Solver {
struct Options {
// Default constructor that sets up a generic sparse problem.
Options() {
+ minimizer_type = TRUST_REGION;
+ line_search_direction_type = LBFGS;
+ line_search_type = ARMIJO;
+ nonlinear_conjugate_gradient_type = FLETCHER_REEVES;
+ max_lbfgs_rank = 20;
trust_region_strategy_type = LEVENBERG_MARQUARDT;
dogleg_type = TRADITIONAL_DOGLEG;
use_nonmonotonic_steps = false;
@@ -89,27 +95,21 @@ class Solver {
#endif
num_linear_solver_threads = 1;
- num_eliminate_blocks = 0;
- ordering_type = NATURAL;
#if defined(CERES_NO_SUITESPARSE)
use_block_amd = false;
#else
use_block_amd = true;
#endif
-
+ linear_solver_ordering = NULL;
+ use_inner_iterations = false;
+ inner_iteration_ordering = NULL;
linear_solver_min_num_iterations = 1;
linear_solver_max_num_iterations = 500;
eta = 1e-1;
jacobi_scaling = true;
logging_type = PER_MINIMIZER_ITERATION;
minimizer_progress_to_stdout = false;
- return_initial_residuals = false;
- return_initial_gradient = false;
- return_initial_jacobian = false;
- return_final_residuals = false;
- return_final_gradient = false;
- return_final_jacobian = false;
lsqp_dump_directory = "/tmp";
lsqp_dump_format_type = TEXTFILE;
check_gradients = false;
@@ -118,8 +118,64 @@ class Solver {
update_state_every_iteration = false;
}
+ ~Options();
// Minimizer options ----------------------------------------
+ // Ceres supports the two major families of optimization strategies -
+ // Trust Region and Line Search.
+ //
+ // 1. The line search approach first finds a descent direction
+ // along which the objective function will be reduced and then
+ // computes a step size that decides how far should move along
+ // that direction. The descent direction can be computed by
+ // various methods, such as gradient descent, Newton's method and
+ // Quasi-Newton method. The step size can be determined either
+ // exactly or inexactly.
+ //
+ // 2. The trust region approach approximates the objective
+ // function using using a model function (often a quadratic) over
+ // a subset of the search space known as the trust region. If the
+ // model function succeeds in minimizing the true objective
+ // function the trust region is expanded; conversely, otherwise it
+ // is contracted and the model optimization problem is solved
+ // again.
+ //
+ // Trust region methods are in some sense dual to line search methods:
+ // trust region methods first choose a step size (the size of the
+ // trust region) and then a step direction while line search methods
+ // first choose a step direction and then a step size.
+ MinimizerType minimizer_type;
+
+ LineSearchDirectionType line_search_direction_type;
+ LineSearchType line_search_type;
+ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
+
+ // The LBFGS hessian approximation is a low rank approximation to
+ // the inverse of the Hessian matrix. The rank of the
+ // approximation determines (linearly) the space and time
+ // complexity of using the approximation. Higher the rank, the
+ // better is the quality of the approximation. The increase in
+ // quality is however is bounded for a number of reasons.
+ //
+ // 1. The method only uses secant information and not actual
+ // derivatives.
+ //
+ // 2. The Hessian approximation is constrained to be positive
+ // definite.
+ //
+ // So increasing this rank to a large number will cost time and
+ // space complexity without the corresponding increase in solution
+ // quality. There are no hard and fast rules for choosing the
+ // maximum rank. The best choice usually requires some problem
+ // specific experimentation.
+ //
+ // For more theoretical and implementation details of the LBFGS
+ // method, please see:
+ //
+ // Nocedal, J. (1980). "Updating Quasi-Newton Matrices with
+ // Limited Storage". Mathematics of Computation 35 (151): 773–782.
+ int max_lbfgs_rank;
+
TrustRegionStrategyType trust_region_strategy_type;
// Type of dogleg strategy to use.
@@ -229,29 +285,76 @@ class Solver {
// using this setting.
int num_linear_solver_threads;
- // For Schur reduction based methods, the first 0 to num blocks are
- // eliminated using the Schur reduction. For example, when solving
- // traditional structure from motion problems where the parameters are in
- // two classes (cameras and points) then num_eliminate_blocks would be the
- // number of points.
- //
- // This parameter is used in conjunction with the ordering.
- // Applies to: Preprocessor and linear least squares solver.
- int num_eliminate_blocks;
-
- // Internally Ceres reorders the parameter blocks to help the
- // various linear solvers. This parameter allows the user to
- // influence the re-ordering strategy used. For structure from
- // motion problems use SCHUR, for other problems NATURAL (default)
- // is a good choice. In case you wish to specify your own ordering
- // scheme, for example in conjunction with num_eliminate_blocks,
- // use USER.
- OrderingType ordering_type;
-
- // The ordering of the parameter blocks. The solver pays attention
- // to it if the ordering_type is set to USER and the vector is
- // non-empty.
- vector<double*> ordering;
+ // The order in which variables are eliminated in a linear solver
+ // can have a significant of impact on the efficiency and accuracy
+ // of the method. e.g., when doing sparse Cholesky factorization,
+ // there are matrices for which a good ordering will give a
+ // Cholesky factor with O(n) storage, where as a bad ordering will
+ // result in an completely dense factor.
+ //
+ // Ceres allows the user to provide varying amounts of hints to
+ // the solver about the variable elimination ordering to use. This
+ // can range from no hints, where the solver is free to decide the
+ // best possible ordering based on the user's choices like the
+ // linear solver being used, to an exact order in which the
+ // variables should be eliminated, and a variety of possibilities
+ // in between.
+ //
+ // Instances of the ParameterBlockOrdering class are used to
+ // communicate this information to Ceres.
+ //
+ // Formally an ordering is an ordered partitioning of the
+ // parameter blocks, i.e, each parameter block belongs to exactly
+ // one group, and each group has a unique non-negative integer
+ // associated with it, that determines its order in the set of
+ // groups.
+ //
+ // Given such an ordering, Ceres ensures that the parameter blocks in
+ // the lowest numbered group are eliminated first, and then the
+ // parmeter blocks in the next lowest numbered group and so on. Within
+ // each group, Ceres is free to order the parameter blocks as it
+ // chooses.
+ //
+ // If NULL, then all parameter blocks are assumed to be in the
+ // same group and the solver is free to decide the best
+ // ordering.
+ //
+ // e.g. Consider the linear system
+ //
+ // x + y = 3
+ // 2x + 3y = 7
+ //
+ // There are two ways in which it can be solved. First eliminating x
+ // from the two equations, solving for y and then back substituting
+ // for x, or first eliminating y, solving for x and back substituting
+ // for y. The user can construct three orderings here.
+ //
+ // {0: x}, {1: y} - eliminate x first.
+ // {0: y}, {1: x} - eliminate y first.
+ // {0: x, y} - Solver gets to decide the elimination order.
+ //
+ // Thus, to have Ceres determine the ordering automatically using
+ // heuristics, put all the variables in group 0 and to control the
+ // ordering for every variable, create groups 0..N-1, one per
+ // variable, in the desired order.
+ //
+ // Bundle Adjustment
+ // -----------------
+ //
+ // A particular case of interest is bundle adjustment, where the user
+ // has two options. The default is to not specify an ordering at all,
+ // the solver will see that the user wants to use a Schur type solver
+ // and figure out the right elimination ordering.
+ //
+ // But if the user already knows what parameter blocks are points and
+ // what are cameras, they can save preprocessing time by partitioning
+ // the parameter blocks into two groups, one for the points and one
+ // for the cameras, where the group containing the points has an id
+ // smaller than the group containing cameras.
+ //
+ // Once assigned, Solver::Options owns this pointer and will
+ // deallocate the memory when destroyed.
+ ParameterBlockOrdering* linear_solver_ordering;
// By virtue of the modeling layer in Ceres being block oriented,
// all the matrices used by Ceres are also block oriented. When
@@ -267,6 +370,77 @@ class Solver {
// sparse_linear_algebra_library = SUITE_SPARSE.
bool use_block_amd;
+ // Some non-linear least squares problems have additional
+ // structure in the way the parameter blocks interact that it is
+ // beneficial to modify the way the trust region step is computed.
+ //
+ // e.g., consider the following regression problem
+ //
+ // y = a_1 exp(b_1 x) + a_2 exp(b_3 x^2 + c_1)
+ //
+ // Given a set of pairs{(x_i, y_i)}, the user wishes to estimate
+ // a_1, a_2, b_1, b_2, and c_1.
+ //
+ // Notice here that the expression on the left is linear in a_1
+ // and a_2, and given any value for b_1, b_2 and c_1, it is
+ // possible to use linear regression to estimate the optimal
+ // values of a_1 and a_2. Indeed, its possible to analytically
+ // eliminate the variables a_1 and a_2 from the problem all
+ // together. Problems like these are known as separable least
+ // squares problem and the most famous algorithm for solving them
+ // is the Variable Projection algorithm invented by Golub &
+ // Pereyra.
+ //
+ // Similar structure can be found in the matrix factorization with
+ // missing data problem. There the corresponding algorithm is
+ // known as Wiberg's algorithm.
+ //
+ // Ruhe & Wedin (Algorithms for Separable Nonlinear Least Squares
+ // Problems, SIAM Reviews, 22(3), 1980) present an analyis of
+ // various algorithms for solving separable non-linear least
+ // squares problems and refer to "Variable Projection" as
+ // Algorithm I in their paper.
+ //
+ // Implementing Variable Projection is tedious and expensive, and
+ // they present a simpler algorithm, which they refer to as
+ // Algorithm II, where once the Newton/Trust Region step has been
+ // computed for the whole problem (a_1, a_2, b_1, b_2, c_1) and
+ // additional optimization step is performed to estimate a_1 and
+ // a_2 exactly.
+ //
+ // This idea can be generalized to cases where the residual is not
+ // linear in a_1 and a_2, i.e., Solve for the trust region step
+ // for the full problem, and then use it as the starting point to
+ // further optimize just a_1 and a_2. For the linear case, this
+ // amounts to doing a single linear least squares solve. For
+ // non-linear problems, any method for solving the a_1 and a_2
+ // optimization problems will do. The only constraint on a_1 and
+ // a_2 is that they do not co-occur in any residual block.
+ //
+ // This idea can be further generalized, by not just optimizing
+ // (a_1, a_2), but decomposing the graph corresponding to the
+ // Hessian matrix's sparsity structure in a collection of
+ // non-overlapping independent sets and optimizing each of them.
+ //
+ // Setting "use_inner_iterations" to true enables the use of this
+ // non-linear generalization of Ruhe & Wedin's Algorithm II. This
+ // version of Ceres has a higher iteration complexity, but also
+ // displays better convergence behaviour per iteration. Setting
+ // Solver::Options::num_threads to the maximum number possible is
+ // highly recommended.
+ bool use_inner_iterations;
+
+ // If inner_iterations is true, then the user has two choices.
+ //
+ // 1. Let the solver heuristically decide which parameter blocks
+ // to optimize in each inner iteration. To do this leave
+ // Solver::Options::inner_iteration_ordering untouched.
+ //
+ // 2. Specify a collection of of ordered independent sets. Where
+ // the lower numbered groups are optimized before the higher
+ // number groups. Each group must be an independent set.
+ ParameterBlockOrdering* inner_iteration_ordering;
+
// Minimum number of iterations for which the linear solver should
// run, even if the convergence criterion is satisfied.
int linear_solver_min_num_iterations;
@@ -301,14 +475,6 @@ class Solver {
// is sent to STDOUT.
bool minimizer_progress_to_stdout;
- bool return_initial_residuals;
- bool return_initial_gradient;
- bool return_initial_jacobian;
-
- bool return_final_residuals;
- bool return_final_gradient;
- bool return_final_jacobian;
-
// List of iterations at which the optimizer should dump the
// linear least squares problem to disk. Useful for testing and
// benchmarking. If empty (default), no problems are dumped.
@@ -398,6 +564,8 @@ class Solver {
string FullReport() const;
// Minimizer summary -------------------------------------------------
+ MinimizerType minimizer_type;
+
SolverTerminationType termination_type;
// If the solver did not run, or there was a failure, a
@@ -414,54 +582,6 @@ class Solver {
// blocks that they depend on were fixed.
double fixed_cost;
- // Vectors of residuals before and after the optimization. The
- // entries of these vectors are in the order in which
- // ResidualBlocks were added to the Problem object.
- //
- // Whether the residual vectors are populated with values is
- // controlled by Solver::Options::return_initial_residuals and
- // Solver::Options::return_final_residuals respectively.
- vector<double> initial_residuals;
- vector<double> final_residuals;
-
- // Gradient vectors, before and after the optimization. The rows
- // are in the same order in which the ParameterBlocks were added
- // to the Problem object.
- //
- // NOTE: Since AddResidualBlock adds ParameterBlocks to the
- // Problem automatically if they do not already exist, if you wish
- // to have explicit control over the ordering of the vectors, then
- // use Problem::AddParameterBlock to explicitly add the
- // ParameterBlocks in the order desired.
- //
- // Whether the vectors are populated with values is controlled by
- // Solver::Options::return_initial_gradient and
- // Solver::Options::return_final_gradient respectively.
- vector<double> initial_gradient;
- vector<double> final_gradient;
-
- // Jacobian matrices before and after the optimization. The rows
- // of these matrices are in the same order in which the
- // ResidualBlocks were added to the Problem object. The columns
- // are in the same order in which the ParameterBlocks were added
- // to the Problem object.
- //
- // NOTE: Since AddResidualBlock adds ParameterBlocks to the
- // Problem automatically if they do not already exist, if you wish
- // to have explicit control over the column ordering of the
- // matrix, then use Problem::AddParameterBlock to explicitly add
- // the ParameterBlocks in the order desired.
- //
- // The Jacobian matrices are stored as compressed row sparse
- // matrices. Please see ceres/crs_matrix.h for more details of the
- // format.
- //
- // Whether the Jacboan matrices are populated with values is
- // controlled by Solver::Options::return_initial_jacobian and
- // Solver::Options::return_final_jacobian respectively.
- CRSMatrix initial_jacobian;
- CRSMatrix final_jacobian;
-
vector<IterationSummary> iterations;
int num_successful_steps;
@@ -484,6 +604,10 @@ class Solver {
// Some total of all time spent inside Ceres when Solve is called.
double total_time_in_seconds;
+ double linear_solver_time_in_seconds;
+ double residual_evaluation_time_in_seconds;
+ double jacobian_evaluation_time_in_seconds;
+
// Preprocessor summary.
int num_parameter_blocks;
int num_parameters;
@@ -507,12 +631,23 @@ class Solver {
LinearSolverType linear_solver_type_given;
LinearSolverType linear_solver_type_used;
+ vector<int> linear_solver_ordering_given;
+ vector<int> linear_solver_ordering_used;
+
PreconditionerType preconditioner_type;
- OrderingType ordering_type;
TrustRegionStrategyType trust_region_strategy_type;
DoglegType dogleg_type;
+ bool inner_iterations;
+
SparseLinearAlgebraLibraryType sparse_linear_algebra_library;
+
+ LineSearchDirectionType line_search_direction_type;
+ LineSearchType line_search_type;
+ int max_lbfgs_rank;
+
+ vector<int> inner_iteration_ordering_given;
+ vector<int> inner_iteration_ordering_used;
};
// Once a least squares problem has been built, this function takes
diff --git a/extern/libmv/third_party/ceres/include/ceres/types.h b/extern/libmv/third_party/ceres/include/ceres/types.h
index 3980885b53c..5512340f7b3 100644
--- a/extern/libmv/third_party/ceres/include/ceres/types.h
+++ b/extern/libmv/third_party/ceres/include/ceres/types.h
@@ -37,6 +37,8 @@
#ifndef CERES_PUBLIC_TYPES_H_
#define CERES_PUBLIC_TYPES_H_
+#include "ceres/internal/port.h"
+
namespace ceres {
// Basic integer types. These typedefs are in the Ceres namespace to avoid
@@ -99,8 +101,7 @@ enum PreconditionerType {
JACOBI,
// Block diagonal of the Schur complement. This preconditioner may
- // only be used with the ITERATIVE_SCHUR solver. Requires
- // SuiteSparse/CHOLMOD.
+ // only be used with the ITERATIVE_SCHUR solver.
SCHUR_JACOBI,
// Visibility clustering based preconditioners.
@@ -143,18 +144,6 @@ enum LinearSolverTerminationType {
FAILURE
};
-enum OrderingType {
- // The order in which the parameter blocks were defined.
- NATURAL,
-
- // Use the ordering specificed in the vector ordering.
- USER,
-
- // Automatically figure out the best ordering to use the schur
- // complement based solver.
- SCHUR
-};
-
// Logging options
// The options get progressively noisier.
enum LoggingType {
@@ -162,6 +151,55 @@ enum LoggingType {
PER_MINIMIZER_ITERATION
};
+enum MinimizerType {
+ LINE_SEARCH,
+ TRUST_REGION
+};
+
+enum LineSearchDirectionType {
+ // Negative of the gradient.
+ STEEPEST_DESCENT,
+
+ // A generalization of the Conjugate Gradient method to non-linear
+ // functions. The generalization can be performed in a number of
+ // different ways, resulting in a variety of search directions. The
+ // precise choice of the non-linear conjugate gradient algorithm
+ // used is determined by NonlinerConjuateGradientType.
+ NONLINEAR_CONJUGATE_GRADIENT,
+
+ // A limited memory approximation to the inverse Hessian is
+ // maintained and used to compute a quasi-Newton step.
+ //
+ // For more details see
+ //
+ // Nocedal, J. (1980). "Updating Quasi-Newton Matrices with Limited
+ // Storage". Mathematics of Computation 35 (151): 773–782.
+ //
+ // Byrd, R. H.; Nocedal, J.; Schnabel, R. B. (1994).
+ // "Representations of Quasi-Newton Matrices and their use in
+ // Limited Memory Methods". Mathematical Programming 63 (4):
+ // 129–156.
+ LBFGS,
+};
+
+// Nonliner conjugate gradient methods are a generalization of the
+// method of Conjugate Gradients for linear systems. The
+// generalization can be carried out in a number of different ways
+// leading to number of different rules for computing the search
+// direction. Ceres provides a number of different variants. For more
+// details see Numerical Optimization by Nocedal & Wright.
+enum NonlinearConjugateGradientType {
+ FLETCHER_REEVES,
+ POLAK_RIBIRERE,
+ HESTENES_STIEFEL,
+};
+
+enum LineSearchType {
+ // Backtracking line search with polynomial interpolation or
+ // bisection.
+ ARMIJO,
+};
+
// Ceres supports different strategies for computing the trust region
// step.
enum TrustRegionStrategyType {
@@ -296,18 +334,54 @@ enum DimensionType {
DYNAMIC = -1
};
+enum NumericDiffMethod {
+ CENTRAL,
+ FORWARD
+};
+
const char* LinearSolverTypeToString(LinearSolverType type);
+bool StringToLinearSolverType(string value, LinearSolverType* type);
+
const char* PreconditionerTypeToString(PreconditionerType type);
+bool StringToPreconditionerType(string value, PreconditionerType* type);
+
const char* SparseLinearAlgebraLibraryTypeToString(
SparseLinearAlgebraLibraryType type);
+bool StringToSparseLinearAlgebraLibraryType(
+ string value,
+ SparseLinearAlgebraLibraryType* type);
+
+const char* TrustRegionStrategyTypeToString(TrustRegionStrategyType type);
+bool StringToTrustRegionStrategyType(string value,
+ TrustRegionStrategyType* type);
+
+const char* DoglegTypeToString(DoglegType type);
+bool StringToDoglegType(string value, DoglegType* type);
+
+const char* MinimizerTypeToString(MinimizerType type);
+bool StringToMinimizerType(string value, MinimizerType* type);
+
+const char* LineSearchDirectionTypeToString(LineSearchDirectionType type);
+bool StringToLineSearchDirectionType(string value,
+ LineSearchDirectionType* type);
+
+const char* LineSearchTypeToString(LineSearchType type);
+bool StringToLineSearchType(string value, LineSearchType* type);
+
+const char* NonlinearConjugateGradientTypeToString(
+ NonlinearConjugateGradientType type);
+bool StringToNonlinearConjugateGradientType(
+ string value, NonlinearConjugateGradientType* type);
+
const char* LinearSolverTerminationTypeToString(
LinearSolverTerminationType type);
-const char* OrderingTypeToString(OrderingType type);
+
const char* SolverTerminationTypeToString(SolverTerminationType type);
-const char* SparseLinearAlgebraLibraryTypeToString(
- SparseLinearAlgebraLibraryType type);
-const char* TrustRegionStrategyTypeToString( TrustRegionStrategyType type);
+
bool IsSchurType(LinearSolverType type);
+bool IsSparseLinearAlgebraLibraryTypeAvailable(
+ SparseLinearAlgebraLibraryType type);
+
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/array_utils.h b/extern/libmv/third_party/ceres/internal/ceres/array_utils.h
index 99cc8d8ebbf..742f439d886 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/array_utils.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/array_utils.h
@@ -28,7 +28,7 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
//
-// Utility routines for validating arrays.
+// Utility routines for validating arrays.
//
// These are useful for detecting two common class of errors.
//
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc
index 474c37f7ca4..1d5f9d77ab0 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc
@@ -40,10 +40,10 @@
namespace ceres {
namespace internal {
-BlockJacobiPreconditioner::BlockJacobiPreconditioner(const LinearOperator& A)
+BlockJacobiPreconditioner::BlockJacobiPreconditioner(
+ const BlockSparseMatrixBase& A)
: num_rows_(A.num_rows()),
- block_structure_(
- *(down_cast<const BlockSparseMatrix*>(&A)->block_structure())) {
+ block_structure_(*A.block_structure()) {
// Calculate the amount of storage needed.
int storage_needed = 0;
for (int c = 0; c < block_structure_.cols.size(); ++c) {
@@ -64,11 +64,10 @@ BlockJacobiPreconditioner::BlockJacobiPreconditioner(const LinearOperator& A)
}
}
-BlockJacobiPreconditioner::~BlockJacobiPreconditioner() {
-}
+BlockJacobiPreconditioner::~BlockJacobiPreconditioner() {}
-void BlockJacobiPreconditioner::Update(const LinearOperator& matrix, const double* D) {
- const BlockSparseMatrix& A = *(down_cast<const BlockSparseMatrix*>(&matrix));
+bool BlockJacobiPreconditioner::Update(const BlockSparseMatrixBase& A,
+ const double* D) {
const CompressedRowBlockStructure* bs = A.block_structure();
// Compute the diagonal blocks by block inner products.
@@ -107,16 +106,19 @@ void BlockJacobiPreconditioner::Update(const LinearOperator& matrix, const doubl
MatrixRef block(blocks_[c], size, size);
if (D != NULL) {
- block.diagonal() += ConstVectorRef(D + position, size).array().square().matrix();
+ block.diagonal() +=
+ ConstVectorRef(D + position, size).array().square().matrix();
}
block = block.selfadjointView<Eigen::Upper>()
.ldlt()
.solve(Matrix::Identity(size, size));
}
+ return true;
}
-void BlockJacobiPreconditioner::RightMultiply(const double* x, double* y) const {
+void BlockJacobiPreconditioner::RightMultiply(const double* x,
+ double* y) const {
for (int c = 0; c < block_structure_.cols.size(); ++c) {
const int size = block_structure_.cols[c].size;
const int position = block_structure_.cols[c].position;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h
index 91cfeddb688..ed5eebc8dc6 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h
@@ -32,38 +32,33 @@
#define CERES_INTERNAL_BLOCK_JACOBI_PRECONDITIONER_H_
#include <vector>
-#include "ceres/linear_operator.h"
+#include "ceres/preconditioner.h"
namespace ceres {
namespace internal {
-class CompressedRowBlockStructure;
+class BlockSparseMatrixBase;
+struct CompressedRowBlockStructure;
class LinearOperator;
-class SparseMatrix;
-// A block Jacobi preconditioner. This is intended for use with conjugate
-// gradients, or other iterative symmetric solvers. To use the preconditioner,
-// create one by passing a BlockSparseMatrix as the linear operator "A" to the
-// constructor. This fixes the sparsity pattern to the pattern of the matrix
-// A^TA.
+// A block Jacobi preconditioner. This is intended for use with
+// conjugate gradients, or other iterative symmetric solvers. To use
+// the preconditioner, create one by passing a BlockSparseMatrix "A"
+// to the constructor. This fixes the sparsity pattern to the pattern
+// of the matrix A^TA.
//
// Before each use of the preconditioner in a solve with conjugate gradients,
// update the matrix by running Update(A, D). The values of the matrix A are
// inspected to construct the preconditioner. The vector D is applied as the
// D^TD diagonal term.
-class BlockJacobiPreconditioner : public LinearOperator {
+class BlockJacobiPreconditioner : public Preconditioner {
public:
// A must remain valid while the BlockJacobiPreconditioner is.
- BlockJacobiPreconditioner(const LinearOperator& A);
+ explicit BlockJacobiPreconditioner(const BlockSparseMatrixBase& A);
virtual ~BlockJacobiPreconditioner();
- // Update the preconditioner with the values found in A. The sparsity pattern
- // must match that of the A passed to the constructor. D is a vector that
- // must have the same number of rows as A, and is applied as a diagonal in
- // addition to the block diagonals of A.
- void Update(const LinearOperator& A, const double* D);
-
- // LinearOperator interface.
+ // Preconditioner interface
+ virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
virtual void RightMultiply(const double* x, double* y) const;
virtual void LeftMultiply(const double* x, double* y) const;
virtual int num_rows() const { return num_rows_; }
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc
index 0f95e8932b8..aedfc745f22 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc
@@ -28,12 +28,12 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
-#include "glog/logging.h"
#include "ceres/block_random_access_dense_matrix.h"
#include <vector>
#include "ceres/internal/eigen.h"
#include "ceres/internal/scoped_ptr.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc
index 9ed62ce948b..f789436364a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc
@@ -28,7 +28,6 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
-#include "glog/logging.h"
#include "ceres/block_random_access_sparse_matrix.h"
#include <algorithm>
@@ -40,6 +39,7 @@
#include "ceres/mutex.h"
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h
index 2d1eb403995..5f8e4e3e5dd 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h
@@ -43,16 +43,16 @@
#include <vector>
-#include <glog/logging.h>
#include "ceres/collections_port.h"
#include "ceres/graph.h"
-#include "ceres/map_util.h"
#include "ceres/internal/macros.h"
+#include "ceres/map_util.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
-class CanonicalViewsClusteringOptions;
+struct CanonicalViewsClusteringOptions;
// Compute a partitioning of the vertices of the graph using the
// canonical views clustering algorithm.
diff --git a/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc
index ccc8026f9f7..e2e799fe607 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.cc
@@ -30,25 +30,28 @@
#include "ceres/cgnr_solver.h"
-#include "glog/logging.h"
-#include "ceres/linear_solver.h"
+#include "ceres/block_jacobi_preconditioner.h"
#include "ceres/cgnr_linear_operator.h"
#include "ceres/conjugate_gradients_solver.h"
-#include "ceres/block_jacobi_preconditioner.h"
+#include "ceres/linear_solver.h"
+#include "ceres/wall_time.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
CgnrSolver::CgnrSolver(const LinearSolver::Options& options)
: options_(options),
- jacobi_preconditioner_(NULL) {
+ preconditioner_(NULL) {
}
-LinearSolver::Summary CgnrSolver::Solve(
- LinearOperator* A,
+LinearSolver::Summary CgnrSolver::SolveImpl(
+ BlockSparseMatrixBase* A,
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) {
+ EventLogger event_logger("CgnrSolver::Solve");
+
// Form z = Atb.
scoped_array<double> z(new double[A->num_cols()]);
std::fill(z.get(), z.get() + A->num_cols(), 0.0);
@@ -57,11 +60,11 @@ LinearSolver::Summary CgnrSolver::Solve(
// Precondition if necessary.
LinearSolver::PerSolveOptions cg_per_solve_options = per_solve_options;
if (options_.preconditioner_type == JACOBI) {
- if (jacobi_preconditioner_.get() == NULL) {
- jacobi_preconditioner_.reset(new BlockJacobiPreconditioner(*A));
+ if (preconditioner_.get() == NULL) {
+ preconditioner_.reset(new BlockJacobiPreconditioner(*A));
}
- jacobi_preconditioner_->Update(*A, per_solve_options.D);
- cg_per_solve_options.preconditioner = jacobi_preconditioner_.get();
+ preconditioner_->Update(*A, per_solve_options.D);
+ cg_per_solve_options.preconditioner = preconditioner_.get();
} else if (options_.preconditioner_type != IDENTITY) {
LOG(FATAL) << "CGNR only supports IDENTITY and JACOBI preconditioners.";
}
@@ -69,11 +72,14 @@ LinearSolver::Summary CgnrSolver::Solve(
// Solve (AtA + DtD)x = z (= Atb).
std::fill(x, x + A->num_cols(), 0.0);
CgnrLinearOperator lhs(*A, per_solve_options.D);
+ event_logger.AddEvent("Setup");
+
ConjugateGradientsSolver conjugate_gradient_solver(options_);
- return conjugate_gradient_solver.Solve(&lhs,
- z.get(),
- cg_per_solve_options,
- x);
+ LinearSolver::Summary summary =
+ conjugate_gradient_solver.Solve(&lhs, z.get(), cg_per_solve_options, x);
+ event_logger.AddEvent("Solve");
+
+ return summary;
}
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h
index 877b4c4ceea..d560a9de58d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/cgnr_solver.h
@@ -37,6 +37,8 @@
namespace ceres {
namespace internal {
+class Preconditioner;
+
class BlockJacobiPreconditioner;
// A conjugate gradients on the normal equations solver. This directly solves
@@ -46,17 +48,18 @@ class BlockJacobiPreconditioner;
//
// as required for solving for x in the least squares sense. Currently only
// block diagonal preconditioning is supported.
-class CgnrSolver : public LinearSolver {
+class CgnrSolver : public BlockSparseMatrixBaseSolver {
public:
explicit CgnrSolver(const LinearSolver::Options& options);
- virtual Summary Solve(LinearOperator* A,
- const double* b,
- const LinearSolver::PerSolveOptions& per_solve_options,
- double* x);
+ virtual Summary SolveImpl(
+ BlockSparseMatrixBase* A,
+ const double* b,
+ const LinearSolver::PerSolveOptions& per_solve_options,
+ double* x);
private:
const LinearSolver::Options options_;
- scoped_ptr<BlockJacobiPreconditioner> jacobi_preconditioner_;
+ scoped_ptr<Preconditioner> preconditioner_;
CERES_DISALLOW_COPY_AND_ASSIGN(CgnrSolver);
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/collections_port.h b/extern/libmv/third_party/ceres/internal/ceres/collections_port.h
index c2fce9033cd..715c975e00e 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/collections_port.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/collections_port.h
@@ -37,7 +37,7 @@
# include <map>
# include <set>
#else
-# if defined(_MSC_VER) && _MSC_VER <= 1600
+# if defined(_MSC_VER)
# include <unordered_map>
# include <unordered_set>
# else
diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc
index 912c4845441..bbadb772805 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_jacobian_writer.cc
@@ -135,7 +135,8 @@ SparseMatrix* CompressedRowJacobianWriter::CreateJacobian() const {
// Populate the row and column block vectors for use by block
// oriented ordering algorithms. This is useful when
// Solver::Options::use_block_amd = true.
- const vector<ParameterBlock*>& parameter_blocks = program_->parameter_blocks();
+ const vector<ParameterBlock*>& parameter_blocks =
+ program_->parameter_blocks();
vector<int>& col_blocks = *(jacobian->mutable_col_blocks());
col_blocks.resize(parameter_blocks.size());
for (int i = 0; i < parameter_blocks.size(); ++i) {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h
index 6a9d82842e5..c9c904bf63c 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/compressed_row_sparse_matrix.h
@@ -32,17 +32,18 @@
#define CERES_INTERNAL_COMPRESSED_ROW_SPARSE_MATRIX_H_
#include <vector>
-#include <glog/logging.h>
-#include "ceres/sparse_matrix.h"
-#include "ceres/triplet_sparse_matrix.h"
+
#include "ceres/internal/eigen.h"
#include "ceres/internal/macros.h"
#include "ceres/internal/port.h"
+#include "ceres/sparse_matrix.h"
+#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
+#include "glog/logging.h"
namespace ceres {
-class CRSMatrix;
+struct CRSMatrix;
namespace internal {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc
new file mode 100644
index 00000000000..c4da987919a
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc
@@ -0,0 +1,236 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/coordinate_descent_minimizer.h"
+
+#ifdef CERES_USE_OPENMP
+#include <omp.h>
+#endif
+
+#include <iterator>
+#include <numeric>
+#include <vector>
+#include "ceres/evaluator.h"
+#include "ceres/linear_solver.h"
+#include "ceres/minimizer.h"
+#include "ceres/ordered_groups.h"
+#include "ceres/parameter_block.h"
+#include "ceres/problem_impl.h"
+#include "ceres/program.h"
+#include "ceres/residual_block.h"
+#include "ceres/solver.h"
+#include "ceres/solver_impl.h"
+#include "ceres/trust_region_minimizer.h"
+#include "ceres/trust_region_strategy.h"
+
+namespace ceres {
+namespace internal {
+
+CoordinateDescentMinimizer::~CoordinateDescentMinimizer() {
+}
+
+bool CoordinateDescentMinimizer::Init(
+ const Program& program,
+ const ProblemImpl::ParameterMap& parameter_map,
+ const ParameterBlockOrdering& ordering,
+ string* error) {
+ parameter_blocks_.clear();
+ independent_set_offsets_.clear();
+ independent_set_offsets_.push_back(0);
+
+ // Serialize the OrderedGroups into a vector of parameter block
+ // offsets for parallel access.
+ map<ParameterBlock*, int> parameter_block_index;
+ map<int, set<double*> > group_to_elements = ordering.group_to_elements();
+ for (map<int, set<double*> >::const_iterator it = group_to_elements.begin();
+ it != group_to_elements.end();
+ ++it) {
+ for (set<double*>::const_iterator ptr_it = it->second.begin();
+ ptr_it != it->second.end();
+ ++ptr_it) {
+ parameter_blocks_.push_back(parameter_map.find(*ptr_it)->second);
+ parameter_block_index[parameter_blocks_.back()] =
+ parameter_blocks_.size() - 1;
+ }
+ independent_set_offsets_.push_back(
+ independent_set_offsets_.back() + it->second.size());
+ }
+
+ // The ordering does not have to contain all parameter blocks, so
+ // assign zero offsets/empty independent sets to these parameter
+ // blocks.
+ const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
+ for (int i = 0; i < parameter_blocks.size(); ++i) {
+ if (!ordering.IsMember(parameter_blocks[i]->mutable_user_state())) {
+ parameter_blocks_.push_back(parameter_blocks[i]);
+ independent_set_offsets_.push_back(independent_set_offsets_.back());
+ }
+ }
+
+ // Compute the set of residual blocks that depend on each parameter
+ // block.
+ residual_blocks_.resize(parameter_block_index.size());
+ const vector<ResidualBlock*>& residual_blocks = program.residual_blocks();
+ for (int i = 0; i < residual_blocks.size(); ++i) {
+ ResidualBlock* residual_block = residual_blocks[i];
+ const int num_parameter_blocks = residual_block->NumParameterBlocks();
+ for (int j = 0; j < num_parameter_blocks; ++j) {
+ ParameterBlock* parameter_block = residual_block->parameter_blocks()[j];
+ const map<ParameterBlock*, int>::const_iterator it =
+ parameter_block_index.find(parameter_block);
+ if (it != parameter_block_index.end()) {
+ residual_blocks_[it->second].push_back(residual_block);
+ }
+ }
+ }
+
+ evaluator_options_.linear_solver_type = DENSE_QR;
+ evaluator_options_.num_eliminate_blocks = 0;
+ evaluator_options_.num_threads = 1;
+
+ return true;
+}
+
+void CoordinateDescentMinimizer::Minimize(
+ const Minimizer::Options& options,
+ double* parameters,
+ Solver::Summary* summary) {
+ // Set the state and mark all parameter blocks constant.
+ for (int i = 0; i < parameter_blocks_.size(); ++i) {
+ ParameterBlock* parameter_block = parameter_blocks_[i];
+ parameter_block->SetState(parameters + parameter_block->state_offset());
+ parameter_block->SetConstant();
+ }
+
+ scoped_array<LinearSolver*> linear_solvers(
+ new LinearSolver*[options.num_threads]);
+
+ LinearSolver::Options linear_solver_options;
+ linear_solver_options.type = DENSE_QR;
+
+ for (int i = 0; i < options.num_threads; ++i) {
+ linear_solvers[i] = LinearSolver::Create(linear_solver_options);
+ }
+
+ for (int i = 0; i < independent_set_offsets_.size() - 1; ++i) {
+ // No point paying the price for an OpemMP call if the set if of
+ // size zero.
+ if (independent_set_offsets_[i] == independent_set_offsets_[i + 1]) {
+ continue;
+ }
+
+ // The parameter blocks in each independent set can be optimized
+ // in parallel, since they do not co-occur in any residual block.
+#pragma omp parallel for num_threads(options.num_threads)
+ for (int j = independent_set_offsets_[i];
+ j < independent_set_offsets_[i + 1];
+ ++j) {
+#ifdef CERES_USE_OPENMP
+ int thread_id = omp_get_thread_num();
+#else
+ int thread_id = 0;
+#endif
+
+ ParameterBlock* parameter_block = parameter_blocks_[j];
+ const int old_index = parameter_block->index();
+ const int old_delta_offset = parameter_block->delta_offset();
+ parameter_block->SetVarying();
+ parameter_block->set_index(0);
+ parameter_block->set_delta_offset(0);
+
+ Program inner_program;
+ inner_program.mutable_parameter_blocks()->push_back(parameter_block);
+ *inner_program.mutable_residual_blocks() = residual_blocks_[j];
+
+ // TODO(sameeragarwal): Better error handling. Right now we
+ // assume that this is not going to lead to problems of any
+ // sort. Basically we should be checking for numerical failure
+ // of some sort.
+ //
+ // On the other hand, if the optimization is a failure, that in
+ // some ways is fine, since it won't change the parameters and
+ // we are fine.
+ Solver::Summary inner_summary;
+ Solve(&inner_program,
+ linear_solvers[thread_id],
+ parameters + parameter_block->state_offset(),
+ &inner_summary);
+
+ parameter_block->set_index(old_index);
+ parameter_block->set_delta_offset(old_delta_offset);
+ parameter_block->SetState(parameters + parameter_block->state_offset());
+ parameter_block->SetConstant();
+ }
+ }
+
+ for (int i = 0; i < parameter_blocks_.size(); ++i) {
+ parameter_blocks_[i]->SetVarying();
+ }
+
+ for (int i = 0; i < options.num_threads; ++i) {
+ delete linear_solvers[i];
+ }
+}
+
+// Solve the optimization problem for one parameter block.
+void CoordinateDescentMinimizer::Solve(Program* program,
+ LinearSolver* linear_solver,
+ double* parameter,
+ Solver::Summary* summary) {
+ *summary = Solver::Summary();
+ summary->initial_cost = 0.0;
+ summary->fixed_cost = 0.0;
+ summary->final_cost = 0.0;
+ string error;
+
+ scoped_ptr<Evaluator> evaluator(
+ Evaluator::Create(evaluator_options_, program, &error));
+ CHECK_NOTNULL(evaluator.get());
+
+ scoped_ptr<SparseMatrix> jacobian(evaluator->CreateJacobian());
+ CHECK_NOTNULL(jacobian.get());
+
+ TrustRegionStrategy::Options trs_options;
+ trs_options.linear_solver = linear_solver;
+
+ scoped_ptr<TrustRegionStrategy>trust_region_strategy(
+ CHECK_NOTNULL(TrustRegionStrategy::Create(trs_options)));
+
+ Minimizer::Options minimizer_options;
+ minimizer_options.evaluator = evaluator.get();
+ minimizer_options.jacobian = jacobian.get();
+ minimizer_options.trust_region_strategy = trust_region_strategy.get();
+
+ TrustRegionMinimizer minimizer;
+ minimizer.Minimize(minimizer_options, parameter, summary);
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h
new file mode 100644
index 00000000000..3dcf8faee59
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h
@@ -0,0 +1,88 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_COORDINATE_DESCENT_MINIMIZER_H_
+#define CERES_INTERNAL_COORDINATE_DESCENT_MINIMIZER_H_
+
+#include <vector>
+
+#include "ceres/evaluator.h"
+#include "ceres/minimizer.h"
+#include "ceres/problem_impl.h"
+#include "ceres/program.h"
+#include "ceres/solver.h"
+
+namespace ceres {
+namespace internal {
+
+// Given a Program, and a ParameterBlockOrdering which partitions
+// (non-exhaustively) the Hessian matrix into independent sets,
+// perform coordinate descent on the parameter blocks in the
+// ordering. The independent set structure allows for all parameter
+// blocks in the same independent set to be optimized in parallel, and
+// the order of the independent set determines the order in which the
+// parameter block groups are optimized.
+//
+// The minimizer assumes that none of the parameter blocks in the
+// program are constant.
+class CoordinateDescentMinimizer : public Minimizer {
+ public:
+ bool Init(const Program& program,
+ const ProblemImpl::ParameterMap& parameter_map,
+ const ParameterBlockOrdering& ordering,
+ string* error);
+
+ // Minimizer interface.
+ virtual ~CoordinateDescentMinimizer();
+ virtual void Minimize(const Minimizer::Options& options,
+ double* parameters,
+ Solver::Summary* summary);
+
+ private:
+ void Solve(Program* program,
+ LinearSolver* linear_solver,
+ double* parameters,
+ Solver::Summary* summary);
+
+ vector<ParameterBlock*> parameter_blocks_;
+ vector<vector<ResidualBlock*> > residual_blocks_;
+ // The optimization is performed in rounds. In each round all the
+ // parameter blocks that form one independent set are optimized in
+ // parallel. This array, marks the boundaries of the independent
+ // sets in parameter_blocks_.
+ vector<int> independent_set_offsets_;
+
+ Evaluator::Options evaluator_options_;
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_COORDINATE_DESCENT_MINIMIZER_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/corrector.cc b/extern/libmv/third_party/ceres/internal/ceres/corrector.cc
index eff4dff8566..c3858abd2f4 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/corrector.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/corrector.cc
@@ -113,12 +113,19 @@ void Corrector::CorrectJacobian(int nrow, int ncol,
double* residuals, double* jacobian) {
DCHECK(residuals != NULL);
DCHECK(jacobian != NULL);
- ConstVectorRef r_ref(residuals, nrow);
- MatrixRef j_ref(jacobian, nrow, ncol);
- // Equation 11 in BANS.
- j_ref = sqrt_rho1_ * (j_ref - alpha_sq_norm_ *
- r_ref * (r_ref.transpose() * j_ref));
+ if (nrow == 1) {
+ // Specialization for the case where the residual is a scalar.
+ VectorRef j_ref(jacobian, ncol);
+ j_ref *= sqrt_rho1_ * (1.0 - alpha_sq_norm_ * pow(*residuals, 2));
+ } else {
+ ConstVectorRef r_ref(residuals, nrow);
+ MatrixRef j_ref(jacobian, nrow, ncol);
+
+ // Equation 11 in BANS.
+ j_ref = sqrt_rho1_ * (j_ref - alpha_sq_norm_ *
+ r_ref * (r_ref.transpose() * j_ref));
+ }
}
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc
index ca36ce07614..19fa17cc37d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc
@@ -39,7 +39,7 @@
namespace ceres {
namespace internal {
-CXSparse::CXSparse() : scratch_size_(0), scratch_(NULL) {
+CXSparse::CXSparse() : scratch_(NULL), scratch_size_(0) {
}
CXSparse::~CXSparse() {
@@ -116,12 +116,12 @@ cs_di* CXSparse::CreateSparseMatrix(TripletSparseMatrix* tsm) {
return cs_compress(&tsm_wrapper);
}
-void CXSparse::Free(cs_di* factor) {
- cs_free(factor);
+void CXSparse::Free(cs_di* sparse_matrix) {
+ cs_di_spfree(sparse_matrix);
}
-void CXSparse::Free(cs_dis* factor) {
- cs_sfree(factor);
+void CXSparse::Free(cs_dis* symbolic_factorization) {
+ cs_di_sfree(symbolic_factorization);
}
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h
index d3b64fcd1a5..dd5eadc8da8 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h
@@ -72,9 +72,8 @@ class CXSparse {
// The returned matrix should be deallocated with Free when not used anymore.
cs_dis* AnalyzeCholesky(cs_di* A);
- // Deallocates the memory of a matrix obtained from AnalyzeCholesky.
- void Free(cs_di* factor);
- void Free(cs_dis* factor);
+ void Free(cs_di* sparse_matrix);
+ void Free(cs_dis* symbolic_factorization);
private:
// Cached scratch space
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h b/extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h
index 1177b83a556..be743a8591c 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_jacobian_writer.h
@@ -62,7 +62,8 @@ class DenseJacobianWriter {
SparseMatrix* CreateJacobian() const {
return new DenseSparseMatrix(program_->NumResiduals(),
- program_->NumEffectiveParameters());
+ program_->NumEffectiveParameters(),
+ true);
}
void Write(int residual_id,
@@ -87,10 +88,10 @@ class DenseJacobianWriter {
continue;
}
- int parameter_block_size = parameter_block->LocalSize();
- MatrixRef parameter_jacobian(jacobians[j],
- num_residuals,
- parameter_block_size);
+ const int parameter_block_size = parameter_block->LocalSize();
+ ConstMatrixRef parameter_jacobian(jacobians[j],
+ num_residuals,
+ parameter_block_size);
dense_jacobian->mutable_matrix().block(
residual_offset,
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc
index f6bb99abf63..a340e1664f0 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc
@@ -34,10 +34,11 @@
#include "Eigen/Dense"
#include "ceres/dense_sparse_matrix.h"
-#include "ceres/linear_solver.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/scoped_ptr.h"
+#include "ceres/linear_solver.h"
#include "ceres/types.h"
+#include "ceres/wall_time.h"
namespace ceres {
namespace internal {
@@ -51,6 +52,8 @@ LinearSolver::Summary DenseNormalCholeskySolver::SolveImpl(
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) {
+ EventLogger event_logger("DenseNormalCholeskySolver::Solve");
+
const int num_rows = A->num_rows();
const int num_cols = A->num_cols();
@@ -58,6 +61,7 @@ LinearSolver::Summary DenseNormalCholeskySolver::SolveImpl(
Matrix lhs(num_cols, num_cols);
lhs.setZero();
+ event_logger.AddEvent("Setup");
// lhs += A'A
//
// Using rankUpdate instead of GEMM, exposes the fact that its the
@@ -73,12 +77,13 @@ LinearSolver::Summary DenseNormalCholeskySolver::SolveImpl(
lhs += D.array().square().matrix().asDiagonal();
}
- VectorRef(x, num_cols) =
- lhs.selfadjointView<Eigen::Upper>().ldlt().solve(rhs);
-
LinearSolver::Summary summary;
summary.num_iterations = 1;
summary.termination_type = TOLERANCE;
+ VectorRef(x, num_cols) =
+ lhs.selfadjointView<Eigen::Upper>().ldlt().solve(rhs);
+ event_logger.AddEvent("Solve");
+
return summary;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc
index 2b329ee0e9c..1fb9709b42a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.cc
@@ -34,10 +34,11 @@
#include "Eigen/Dense"
#include "ceres/dense_sparse_matrix.h"
-#include "ceres/linear_solver.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/scoped_ptr.h"
+#include "ceres/linear_solver.h"
#include "ceres/types.h"
+#include "ceres/wall_time.h"
namespace ceres {
namespace internal {
@@ -50,10 +51,10 @@ LinearSolver::Summary DenseQRSolver::SolveImpl(
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) {
+ EventLogger event_logger("DenseQRSolver::Solve");
+
const int num_rows = A->num_rows();
const int num_cols = A->num_cols();
- VLOG(2) << "DenseQRSolver: "
- << num_rows << " x " << num_cols << " system.";
if (per_solve_options.D != NULL) {
// Temporarily append a diagonal block to the A matrix, but undo
@@ -62,18 +63,18 @@ LinearSolver::Summary DenseQRSolver::SolveImpl(
}
// rhs = [b;0] to account for the additional rows in the lhs.
- Vector rhs(num_rows + ((per_solve_options.D != NULL) ? num_cols : 0));
- rhs.setZero();
- rhs.head(num_rows) = ConstVectorRef(b, num_rows);
+ const int augmented_num_rows =
+ num_rows + ((per_solve_options.D != NULL) ? num_cols : 0);
+ if (rhs_.rows() != augmented_num_rows) {
+ rhs_.resize(augmented_num_rows);
+ rhs_.setZero();
+ }
+ rhs_.head(num_rows) = ConstVectorRef(b, num_rows);
+ event_logger.AddEvent("Setup");
// Solve the system.
- VectorRef(x, num_cols) = A->matrix().colPivHouseholderQr().solve(rhs);
-
- VLOG(3) << "A:\n" << A->matrix();
- VLOG(3) << "x:\n" << VectorRef(x, num_cols);
- VLOG(3) << "b:\n" << rhs;
- VLOG(3) << "error: " << (A->matrix() * VectorRef(x, num_cols) - rhs).norm();
-
+ VectorRef(x, num_cols) = A->matrix().colPivHouseholderQr().solve(rhs_);
+ event_logger.AddEvent("Solve");
if (per_solve_options.D != NULL) {
// Undo the modifications to the matrix A.
@@ -86,6 +87,8 @@ LinearSolver::Summary DenseQRSolver::SolveImpl(
LinearSolver::Summary summary;
summary.num_iterations = 1;
summary.termination_type = TOLERANCE;
+
+ event_logger.AddEvent("TearDown");
return summary;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h
index dd683a8c4ea..f78fa72c5f3 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_qr_solver.h
@@ -33,6 +33,7 @@
#define CERES_INTERNAL_DENSE_QR_SOLVER_H_
#include "ceres/linear_solver.h"
+#include "ceres/internal/eigen.h"
#include "ceres/internal/macros.h"
namespace ceres {
@@ -90,6 +91,7 @@ class DenseQRSolver: public DenseSparseMatrixSolver {
double* x);
const LinearSolver::Options options_;
+ Vector rhs_;
CERES_DISALLOW_COPY_AND_ASSIGN(DenseQRSolver);
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc
index 86730cc101b..978ac6abe15 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc
@@ -47,6 +47,20 @@ DenseSparseMatrix::DenseSparseMatrix(int num_rows, int num_cols)
m_.setZero();
}
+DenseSparseMatrix::DenseSparseMatrix(int num_rows,
+ int num_cols,
+ bool reserve_diagonal)
+ : has_diagonal_appended_(false),
+ has_diagonal_reserved_(reserve_diagonal) {
+ // Allocate enough space for the diagonal.
+ if (reserve_diagonal) {
+ m_.resize(num_rows + num_cols, num_cols);
+ } else {
+ m_.resize(num_rows, num_cols);
+ }
+ m_.setZero();
+}
+
DenseSparseMatrix::DenseSparseMatrix(const TripletSparseMatrix& m)
: m_(Eigen::MatrixXd::Zero(m.num_rows(), m.num_cols())),
has_diagonal_appended_(false),
@@ -105,7 +119,7 @@ void DenseSparseMatrix::ScaleColumns(const double* scale) {
}
void DenseSparseMatrix::ToDenseMatrix(Matrix* dense_matrix) const {
- *dense_matrix = m_;
+ *dense_matrix = m_.block(0, 0, num_rows(), num_cols());
}
#ifndef CERES_NO_PROTOCOL_BUFFERS
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h
index e7ad14d0ee6..1e4d499b631 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h
@@ -57,6 +57,7 @@ class DenseSparseMatrix : public SparseMatrix {
#endif
DenseSparseMatrix(int num_rows, int num_cols);
+ DenseSparseMatrix(int num_rows, int num_cols, bool reserve_diagonal);
virtual ~DenseSparseMatrix() {}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.cc b/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.cc
index 668fa54b8b8..a330ad2c7a2 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.cc
@@ -35,7 +35,7 @@
#include "ceres/array_utils.h"
#include "ceres/internal/eigen.h"
#include "ceres/linear_solver.h"
-#include "ceres/polynomial_solver.h"
+#include "ceres/polynomial.h"
#include "ceres/sparse_matrix.h"
#include "ceres/trust_region_strategy.h"
#include "ceres/types.h"
@@ -87,7 +87,7 @@ TrustRegionStrategy::Summary DoglegStrategy::ComputeStep(
// Gauss-Newton and gradient vectors are always available, only a
// new interpolant need to be computed. For the subspace case,
// the subspace and the two-dimensional model are also still valid.
- switch(dogleg_type_) {
+ switch (dogleg_type_) {
case TRADITIONAL_DOGLEG:
ComputeTraditionalDoglegStep(step);
break;
@@ -135,7 +135,7 @@ TrustRegionStrategy::Summary DoglegStrategy::ComputeStep(
summary.termination_type = linear_solver_summary.termination_type;
if (linear_solver_summary.termination_type != FAILURE) {
- switch(dogleg_type_) {
+ switch (dogleg_type_) {
// Interpolate the Cauchy point and the Gauss-Newton step.
case TRADITIONAL_DOGLEG:
ComputeTraditionalDoglegStep(step);
@@ -415,15 +415,15 @@ Vector DoglegStrategy::MakePolynomialForBoundaryConstrainedProblem() const {
const double trB = subspace_B_.trace();
const double r2 = radius_ * radius_;
Matrix2d B_adj;
- B_adj << subspace_B_(1,1) , -subspace_B_(0,1),
- -subspace_B_(1,0) , subspace_B_(0,0);
+ B_adj << subspace_B_(1, 1) , -subspace_B_(0, 1),
+ -subspace_B_(1, 0) , subspace_B_(0, 0);
Vector polynomial(5);
polynomial(0) = r2;
polynomial(1) = 2.0 * r2 * trB;
- polynomial(2) = r2 * ( trB * trB + 2.0 * detB ) - subspace_g_.squaredNorm();
- polynomial(3) = -2.0 * ( subspace_g_.transpose() * B_adj * subspace_g_
- - r2 * detB * trB );
+ polynomial(2) = r2 * (trB * trB + 2.0 * detB) - subspace_g_.squaredNorm();
+ polynomial(3) = -2.0 * (subspace_g_.transpose() * B_adj * subspace_g_
+ - r2 * detB * trB);
polynomial(4) = r2 * detB * detB - (B_adj * subspace_g_).squaredNorm();
return polynomial;
@@ -598,7 +598,7 @@ void DoglegStrategy::StepAccepted(double step_quality) {
// Reduce the regularization multiplier, in the hope that whatever
// was causing the rank deficiency has gone away and we can return
// to doing a pure Gauss-Newton solve.
- mu_ = max(min_mu_, 2.0 * mu_ / mu_increase_factor_ );
+ mu_ = max(min_mu_, 2.0 * mu_ / mu_increase_factor_);
reuse_ = false;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.h b/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.h
index bff1689aa4a..7131467d6ce 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/dogleg_strategy.h
@@ -53,8 +53,8 @@ namespace internal {
// This finds the exact optimum over the two-dimensional subspace
// spanned by the two Dogleg vectors.
class DoglegStrategy : public TrustRegionStrategy {
-public:
- DoglegStrategy(const TrustRegionStrategy::Options& options);
+ public:
+ explicit DoglegStrategy(const TrustRegionStrategy::Options& options);
virtual ~DoglegStrategy() {}
// TrustRegionStrategy interface
diff --git a/extern/libmv/third_party/ceres/internal/ceres/evaluator.h b/extern/libmv/third_party/ceres/internal/ceres/evaluator.h
index 6aa30d7b739..14a88188145 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/evaluator.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/evaluator.h
@@ -32,14 +32,17 @@
#ifndef CERES_INTERNAL_EVALUATOR_H_
#define CERES_INTERNAL_EVALUATOR_H_
+#include <map>
#include <string>
#include <vector>
+
+#include "ceres/execution_summary.h"
#include "ceres/internal/port.h"
#include "ceres/types.h"
namespace ceres {
-class CRSMatrix;
+struct CRSMatrix;
namespace internal {
@@ -152,6 +155,18 @@ class Evaluator {
// The number of residuals in the optimization problem.
virtual int NumResiduals() const = 0;
+
+ // The following two methods return copies instead of references so
+ // that the base class implementation does not have to worry about
+ // life time issues. Further, these calls are not expected to be
+ // frequent or performance sensitive.
+ virtual map<string, int> CallStatistics() const {
+ return map<string, int>();
+ }
+
+ virtual map<string, double> TimeStatistics() const {
+ return map<string, double>();
+ }
};
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/execution_summary.h b/extern/libmv/third_party/ceres/internal/ceres/execution_summary.h
new file mode 100644
index 00000000000..29bdc69ecd7
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/execution_summary.h
@@ -0,0 +1,90 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_EXECUTION_SUMMARY_H_
+#define CERES_INTERNAL_EXECUTION_SUMMARY_H_
+
+#include <map>
+#include <string>
+
+#include "ceres/internal/port.h"
+#include "ceres/wall_time.h"
+#include "ceres/mutex.h"
+
+namespace ceres {
+namespace internal {
+
+// Struct used by various objects to report statistics and other
+// information about their execution. e.g., ExecutionSummary::times
+// can be used for reporting times associated with various activities.
+class ExecutionSummary {
+ public:
+ void IncrementTimeBy(const string& name, const double value) {
+ CeresMutexLock l(&times_mutex_);
+ times_[name] += value;
+ }
+
+ void IncrementCall(const string& name) {
+ CeresMutexLock l(&calls_mutex_);
+ calls_[name] += 1;
+ }
+
+ const map<string, double>& times() const { return times_; }
+ const map<string, int>& calls() const { return calls_; }
+
+ private:
+ Mutex times_mutex_;
+ map<string, double> times_;
+
+ Mutex calls_mutex_;
+ map<string, int> calls_;
+};
+
+class ScopedExecutionTimer {
+ public:
+ ScopedExecutionTimer(const string& name, ExecutionSummary* summary)
+ : start_time_(WallTimeInSeconds()),
+ name_(name),
+ summary_(summary) {}
+
+ ~ScopedExecutionTimer() {
+ summary_->IncrementTimeBy(name_, WallTimeInSeconds() - start_time_);
+ }
+
+ private:
+ const double start_time_;
+ const string name_;
+ ExecutionSummary* summary_;
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_EXECUTION_SUMMARY_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/file.cc b/extern/libmv/third_party/ceres/internal/ceres/file.cc
index 6fe7557246d..5226c85e6ee 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/file.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/file.cc
@@ -30,8 +30,9 @@
//
// Really simple file IO.
+#include "ceres/file.h"
+
#include <cstdio>
-#include "file.h"
#include "glog/logging.h"
namespace ceres {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc
index 7fb3ed7b3a8..3edf95da6e0 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc
@@ -154,8 +154,8 @@ class GradientCheckingCostFunction : public CostFunction {
"Jacobian for " "block %d: (%ld by %ld)) "
"==========\n",
k,
- term_jacobians[k].rows(),
- term_jacobians[k].cols());
+ static_cast<long>(term_jacobians[k].rows()),
+ static_cast<long>(term_jacobians[k].cols()));
// The funny spacing creates appropriately aligned column headers.
m += " block row col user dx/dy num diff dx/dy "
"abs error relative error parameter residual\n";
diff --git a/extern/libmv/third_party/ceres/internal/ceres/graph.h b/extern/libmv/third_party/ceres/internal/ceres/graph.h
index 2c0f6d28e54..5f92d4d4df2 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/graph.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/graph.h
@@ -32,12 +32,13 @@
#define CERES_INTERNAL_GRAPH_H_
#include <limits>
-#include <glog/logging.h>
+#include <utility>
#include "ceres/integral_types.h"
#include "ceres/map_util.h"
#include "ceres/collections_port.h"
#include "ceres/internal/macros.h"
#include "ceres/types.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
@@ -65,6 +66,28 @@ class Graph {
AddVertex(vertex, 1.0);
}
+ bool RemoveVertex(const Vertex& vertex) {
+ if (vertices_.find(vertex) == vertices_.end()) {
+ return false;
+ }
+
+ vertices_.erase(vertex);
+ vertex_weights_.erase(vertex);
+ const HashSet<Vertex>& sinks = edges_[vertex];
+ for (typename HashSet<Vertex>::const_iterator it = sinks.begin();
+ it != sinks.end(); ++it) {
+ if (vertex < *it) {
+ edge_weights_.erase(make_pair(vertex, *it));
+ } else {
+ edge_weights_.erase(make_pair(*it, vertex));
+ }
+ edges_[*it].erase(vertex);
+ }
+
+ edges_.erase(vertex);
+ return true;
+ }
+
// Add a weighted edge between the vertex1 and vertex2. Calling
// AddEdge on a pair of vertices which do not exist in the graph yet
// will result in undefined behavior.
diff --git a/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h b/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h
index 3b42d936336..2e6eec0e6d8 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h
@@ -33,10 +33,12 @@
#ifndef CERES_INTERNAL_GRAPH_ALGORITHMS_H_
#define CERES_INTERNAL_GRAPH_ALGORITHMS_H_
+#include <algorithm>
#include <vector>
-#include <glog/logging.h>
+#include <utility>
#include "ceres/collections_port.h"
#include "ceres/graph.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc
index 679c41f2431..cf5562ac771 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc
@@ -33,6 +33,7 @@
#include <algorithm>
#include <cstring>
#include <vector>
+
#include "Eigen/Dense"
#include "ceres/block_sparse_matrix.h"
#include "ceres/block_structure.h"
@@ -41,9 +42,12 @@
#include "ceres/internal/eigen.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/linear_solver.h"
+#include "ceres/preconditioner.h"
+#include "ceres/schur_jacobi_preconditioner.h"
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
#include "ceres/visibility_based_preconditioner.h"
+#include "ceres/wall_time.h"
#include "glog/logging.h"
namespace ceres {
@@ -62,12 +66,14 @@ LinearSolver::Summary IterativeSchurComplementSolver::SolveImpl(
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) {
+ EventLogger event_logger("IterativeSchurComplementSolver::Solve");
+
CHECK_NOTNULL(A->block_structure());
// Initialize a ImplicitSchurComplement object.
if (schur_complement_ == NULL) {
schur_complement_.reset(
- new ImplicitSchurComplement(options_.num_eliminate_blocks,
+ new ImplicitSchurComplement(options_.elimination_groups[0],
options_.preconditioner_type == JACOBI));
}
schur_complement_->Init(*A, per_solve_options.D, b);
@@ -89,44 +95,58 @@ LinearSolver::Summary IterativeSchurComplementSolver::SolveImpl(
cg_per_solve_options.r_tolerance = per_solve_options.r_tolerance;
cg_per_solve_options.q_tolerance = per_solve_options.q_tolerance;
- bool is_preconditioner_good = false;
+ Preconditioner::Options preconditioner_options;
+ preconditioner_options.type = options_.preconditioner_type;
+ preconditioner_options.sparse_linear_algebra_library =
+ options_.sparse_linear_algebra_library;
+ preconditioner_options.use_block_amd = options_.use_block_amd;
+ preconditioner_options.num_threads = options_.num_threads;
+ preconditioner_options.row_block_size = options_.row_block_size;
+ preconditioner_options.e_block_size = options_.e_block_size;
+ preconditioner_options.f_block_size = options_.f_block_size;
+ preconditioner_options.elimination_groups = options_.elimination_groups;
+
switch (options_.preconditioner_type) {
case IDENTITY:
- is_preconditioner_good = true;
break;
case JACOBI:
- // We need to strip the constness of the block_diagonal_FtF_inverse
- // matrix here because the only other way to initialize the struct
- // cg_solve_options would be to add a constructor to it. We know
- // that the only method ever called on the preconditioner is the
- // RightMultiply which is a const method so we don't need to worry
- // about the object getting modified.
- cg_per_solve_options.preconditioner =
- const_cast<BlockSparseMatrix*>(
- schur_complement_->block_diagonal_FtF_inverse());
- is_preconditioner_good = true;
+ preconditioner_.reset(
+ new SparseMatrixPreconditionerWrapper(
+ schur_complement_->block_diagonal_FtF_inverse()));
break;
case SCHUR_JACOBI:
+ if (preconditioner_.get() == NULL) {
+ preconditioner_.reset(
+ new SchurJacobiPreconditioner(
+ *A->block_structure(), preconditioner_options));
+ }
+ break;
case CLUSTER_JACOBI:
case CLUSTER_TRIDIAGONAL:
- if (visibility_based_preconditioner_.get() == NULL) {
- visibility_based_preconditioner_.reset(
- new VisibilityBasedPreconditioner(*A->block_structure(), options_));
+ if (preconditioner_.get() == NULL) {
+ preconditioner_.reset(
+ new VisibilityBasedPreconditioner(
+ *A->block_structure(), preconditioner_options));
}
- is_preconditioner_good =
- visibility_based_preconditioner_->Update(*A, per_solve_options.D);
- cg_per_solve_options.preconditioner =
- visibility_based_preconditioner_.get();
break;
default:
LOG(FATAL) << "Unknown Preconditioner Type";
}
+ bool preconditioner_update_was_successful = true;
+ if (preconditioner_.get() != NULL) {
+ preconditioner_update_was_successful =
+ preconditioner_->Update(*A, per_solve_options.D);
+ cg_per_solve_options.preconditioner = preconditioner_.get();
+ }
+
+ event_logger.AddEvent("Setup");
+
LinearSolver::Summary cg_summary;
cg_summary.num_iterations = 0;
cg_summary.termination_type = FAILURE;
- if (is_preconditioner_good) {
+ if (preconditioner_update_was_successful) {
cg_summary = cg_solver.Solve(schur_complement_.get(),
schur_complement_->rhs().data(),
cg_per_solve_options,
@@ -138,6 +158,8 @@ LinearSolver::Summary IterativeSchurComplementSolver::SolveImpl(
}
VLOG(2) << "CG Iterations : " << cg_summary.num_iterations;
+
+ event_logger.AddEvent("Solve");
return cg_summary;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h
index cfeb65e1eec..f8abe04c142 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.h
@@ -39,13 +39,12 @@
namespace ceres {
namespace internal {
-class BlockSparseMatrix;
class BlockSparseMatrixBase;
class ImplicitSchurComplement;
-class VisibilityBasedPreconditioner;
+class Preconditioner;
// This class implements an iterative solver for the linear least
-// squares problems that have a bi-partitte sparsity structure common
+// squares problems that have a bi-partite sparsity structure common
// to Structure from Motion problems.
//
// The algorithm used by this solver was developed in a series of
@@ -70,9 +69,7 @@ class VisibilityBasedPreconditioner;
// "Iterative Methods for Sparse Linear Systems".
class IterativeSchurComplementSolver : public BlockSparseMatrixBaseSolver {
public:
- explicit IterativeSchurComplementSolver(
- const LinearSolver::Options& options);
-
+ explicit IterativeSchurComplementSolver(const LinearSolver::Options& options);
virtual ~IterativeSchurComplementSolver();
private:
@@ -84,8 +81,9 @@ class IterativeSchurComplementSolver : public BlockSparseMatrixBaseSolver {
LinearSolver::Options options_;
scoped_ptr<internal::ImplicitSchurComplement> schur_complement_;
- scoped_ptr<VisibilityBasedPreconditioner> visibility_based_preconditioner_;
+ scoped_ptr<Preconditioner> preconditioner_;
Vector reduced_linear_system_solution_;
+ CERES_DISALLOW_COPY_AND_ASSIGN(IterativeSchurComplementSolver);
};
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt_strategy.h b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt_strategy.h
index 90c21789797..344e3285422 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt_strategy.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/levenberg_marquardt_strategy.h
@@ -43,8 +43,9 @@ namespace internal {
//
// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf
class LevenbergMarquardtStrategy : public TrustRegionStrategy {
-public:
- LevenbergMarquardtStrategy(const TrustRegionStrategy::Options& options);
+ public:
+ explicit LevenbergMarquardtStrategy(
+ const TrustRegionStrategy::Options& options);
virtual ~LevenbergMarquardtStrategy();
// TrustRegionStrategy interface
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search.cc b/extern/libmv/third_party/ceres/internal/ceres/line_search.cc
new file mode 100644
index 00000000000..e7508caec56
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search.cc
@@ -0,0 +1,211 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/line_search.h"
+
+#include <glog/logging.h>
+#include "ceres/fpclassify.h"
+#include "ceres/evaluator.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/polynomial.h"
+
+
+namespace ceres {
+namespace internal {
+namespace {
+
+FunctionSample ValueSample(const double x, const double value) {
+ FunctionSample sample;
+ sample.x = x;
+ sample.value = value;
+ sample.value_is_valid = true;
+ return sample;
+};
+
+FunctionSample ValueAndGradientSample(const double x,
+ const double value,
+ const double gradient) {
+ FunctionSample sample;
+ sample.x = x;
+ sample.value = value;
+ sample.gradient = gradient;
+ sample.value_is_valid = true;
+ sample.gradient_is_valid = true;
+ return sample;
+};
+
+} // namespace
+
+LineSearchFunction::LineSearchFunction(Evaluator* evaluator)
+ : evaluator_(evaluator),
+ position_(evaluator->NumParameters()),
+ direction_(evaluator->NumEffectiveParameters()),
+ evaluation_point_(evaluator->NumParameters()),
+ scaled_direction_(evaluator->NumEffectiveParameters()),
+ gradient_(evaluator->NumEffectiveParameters()) {
+}
+
+void LineSearchFunction::Init(const Vector& position,
+ const Vector& direction) {
+ position_ = position;
+ direction_ = direction;
+}
+
+bool LineSearchFunction::Evaluate(const double x, double* f, double* g) {
+ scaled_direction_ = x * direction_;
+ if (!evaluator_->Plus(position_.data(),
+ scaled_direction_.data(),
+ evaluation_point_.data())) {
+ return false;
+ }
+
+ if (g == NULL) {
+ return (evaluator_->Evaluate(evaluation_point_.data(),
+ f, NULL, NULL, NULL) &&
+ IsFinite(*f));
+ }
+
+ if (!evaluator_->Evaluate(evaluation_point_.data(),
+ f,
+ NULL,
+ gradient_.data(), NULL)) {
+ return false;
+ }
+
+ *g = direction_.dot(gradient_);
+ return IsFinite(*f) && IsFinite(*g);
+}
+
+void ArmijoLineSearch::Search(const LineSearch::Options& options,
+ const double initial_step_size,
+ const double initial_cost,
+ const double initial_gradient,
+ Summary* summary) {
+ *CHECK_NOTNULL(summary) = LineSearch::Summary();
+ Function* function = options.function;
+
+ double previous_step_size = 0.0;
+ double previous_cost = 0.0;
+ double previous_gradient = 0.0;
+ bool previous_step_size_is_valid = false;
+
+ double step_size = initial_step_size;
+ double cost = 0.0;
+ double gradient = 0.0;
+ bool step_size_is_valid = false;
+
+ ++summary->num_evaluations;
+ step_size_is_valid =
+ function->Evaluate(step_size,
+ &cost,
+ options.interpolation_degree < 2 ? NULL : &gradient);
+ while (!step_size_is_valid || cost > (initial_cost
+ + options.sufficient_decrease
+ * initial_gradient
+ * step_size)) {
+ // If step_size_is_valid is not true we treat it as if the cost at
+ // that point is not large enough to satisfy the sufficient
+ // decrease condition.
+
+ const double current_step_size = step_size;
+ // Backtracking search. Each iteration of this loop finds a new point
+
+ if ((options.interpolation_degree == 0) || !step_size_is_valid) {
+ // Backtrack by halving the step_size;
+ step_size *= 0.5;
+ } else {
+ // Backtrack by interpolating the function and gradient values
+ // and minimizing the corresponding polynomial.
+
+ vector<FunctionSample> samples;
+ samples.push_back(ValueAndGradientSample(0.0,
+ initial_cost,
+ initial_gradient));
+
+ if (options.interpolation_degree == 1) {
+ // Two point interpolation using function values and the
+ // initial gradient.
+ samples.push_back(ValueSample(step_size, cost));
+
+ if (options.use_higher_degree_interpolation_when_possible &&
+ summary->num_evaluations > 1 &&
+ previous_step_size_is_valid) {
+ // Three point interpolation, using function values and the
+ // initial gradient.
+ samples.push_back(ValueSample(previous_step_size, previous_cost));
+ }
+ } else {
+ // Two point interpolation using the function values and the gradients.
+ samples.push_back(ValueAndGradientSample(step_size,
+ cost,
+ gradient));
+
+ if (options.use_higher_degree_interpolation_when_possible &&
+ summary->num_evaluations > 1 &&
+ previous_step_size_is_valid) {
+ // Three point interpolation using the function values and
+ // the gradients.
+ samples.push_back(ValueAndGradientSample(previous_step_size,
+ previous_cost,
+ previous_gradient));
+ }
+ }
+
+ double min_value;
+ MinimizeInterpolatingPolynomial(samples, 0.0, current_step_size,
+ &step_size, &min_value);
+ step_size =
+ min(max(step_size,
+ options.min_relative_step_size_change * current_step_size),
+ options.max_relative_step_size_change * current_step_size);
+ }
+
+ previous_step_size = current_step_size;
+ previous_cost = cost;
+ previous_gradient = gradient;
+
+ if (fabs(initial_gradient) * step_size < options.step_size_threshold) {
+ LOG(WARNING) << "Line search failed: step_size too small: " << step_size;
+ return;
+ }
+
+ ++summary->num_evaluations;
+ step_size_is_valid =
+ function->Evaluate(step_size,
+ &cost,
+ options.interpolation_degree < 2 ? NULL : &gradient);
+ }
+
+ summary->optimal_step_size = step_size;
+ summary->success = true;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search.h b/extern/libmv/third_party/ceres/internal/ceres/line_search.h
new file mode 100644
index 00000000000..fccf63b598a
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search.h
@@ -0,0 +1,212 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Interface for and implementation of various Line search algorithms.
+
+#ifndef CERES_INTERNAL_LINE_SEARCH_H_
+#define CERES_INTERNAL_LINE_SEARCH_H_
+
+#include <glog/logging.h>
+#include <vector>
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+
+namespace ceres {
+namespace internal {
+
+class Evaluator;
+
+// Line search is another name for a one dimensional optimization
+// algorithm. The name "line search" comes from the fact one
+// dimensional optimization problems that arise as subproblems of
+// general multidimensional optimization problems.
+//
+// While finding the exact minimum of a one dimensionl function is
+// hard, instances of LineSearch find a point that satisfies a
+// sufficient decrease condition. Depending on the particular
+// condition used, we get a variety of different line search
+// algorithms, e.g., Armijo, Wolfe etc.
+class LineSearch {
+ public:
+ class Function;
+
+ struct Options {
+ Options()
+ : interpolation_degree(1),
+ use_higher_degree_interpolation_when_possible(false),
+ sufficient_decrease(1e-4),
+ min_relative_step_size_change(1e-3),
+ max_relative_step_size_change(0.6),
+ step_size_threshold(1e-9),
+ function(NULL) {}
+
+ // TODO(sameeragarwal): Replace this with enums which are common
+ // across various line searches.
+ //
+ // Degree of the polynomial used to approximate the objective
+ // function. Valid values are {0, 1, 2}.
+ //
+ // For Armijo line search
+ //
+ // 0: Bisection based backtracking search.
+ // 1: Quadratic interpolation.
+ // 2: Cubic interpolation.
+ int interpolation_degree;
+
+ // Usually its possible to increase the degree of the
+ // interpolation polynomial by storing and using an extra point.
+ bool use_higher_degree_interpolation_when_possible;
+
+ // Armijo line search parameters.
+
+ // Solving the line search problem exactly is computationally
+ // prohibitive. Fortunately, line search based optimization
+ // algorithms can still guarantee convergence if instead of an
+ // exact solution, the line search algorithm returns a solution
+ // which decreases the value of the objective function
+ // sufficiently. More precisely, we are looking for a step_size
+ // s.t.
+ //
+ // f(step_size) <= f(0) + sufficient_decrease * f'(0) * step_size
+ double sufficient_decrease;
+
+ // In each iteration of the Armijo line search,
+ //
+ // new_step_size >= min_relative_step_size_change * step_size
+ double min_relative_step_size_change;
+
+ // In each iteration of the Armijo line search,
+ //
+ // new_step_size <= max_relative_step_size_change * step_size
+ double max_relative_step_size_change;
+
+ // If during the line search, the step_size falls below this
+ // value, it is truncated to zero.
+ double step_size_threshold;
+
+ // The one dimensional function that the line search algorithm
+ // minimizes.
+ Function* function;
+ };
+
+ // An object used by the line search to access the function values
+ // and gradient of the one dimensional function being optimized.
+ //
+ // In practice, this object will provide access to the objective
+ // function value and the directional derivative of the underlying
+ // optimization problem along a specific search direction.
+ //
+ // See LineSearchFunction for an example implementation.
+ class Function {
+ public:
+ virtual ~Function() {}
+ // Evaluate the line search objective
+ //
+ // f(x) = p(position + x * direction)
+ //
+ // Where, p is the objective function of the general optimization
+ // problem.
+ //
+ // g is the gradient f'(x) at x.
+ //
+ // f must not be null. The gradient is computed only if g is not null.
+ virtual bool Evaluate(double x, double* f, double* g) = 0;
+ };
+
+ // Result of the line search.
+ struct Summary {
+ Summary()
+ : success(false),
+ optimal_step_size(0.0),
+ num_evaluations(0) {}
+
+ bool success;
+ double optimal_step_size;
+ int num_evaluations;
+ };
+
+ virtual ~LineSearch() {}
+
+ // Perform the line search.
+ //
+ // initial_step_size must be a positive number.
+ //
+ // initial_cost and initial_gradient are the values and gradient of
+ // the function at zero.
+ // summary must not be null and will contain the result of the line
+ // search.
+ //
+ // Summary::success is true if a non-zero step size is found.
+ virtual void Search(const LineSearch::Options& options,
+ double initial_step_size,
+ double initial_cost,
+ double initial_gradient,
+ Summary* summary) = 0;
+};
+
+class LineSearchFunction : public LineSearch::Function {
+ public:
+ explicit LineSearchFunction(Evaluator* evaluator);
+ virtual ~LineSearchFunction() {}
+ void Init(const Vector& position, const Vector& direction);
+ virtual bool Evaluate(const double x, double* f, double* g);
+
+ private:
+ Evaluator* evaluator_;
+ Vector position_;
+ Vector direction_;
+
+ // evaluation_point = Evaluator::Plus(position_, x * direction_);
+ Vector evaluation_point_;
+
+ // scaled_direction = x * direction_;
+ Vector scaled_direction_;
+ Vector gradient_;
+};
+
+// Backtracking and interpolation based Armijo line search. This
+// implementation is based on the Armijo line search that ships in the
+// minFunc package by Mark Schmidt.
+//
+// For more details: http://www.di.ens.fr/~mschmidt/Software/minFunc.html
+class ArmijoLineSearch : public LineSearch {
+ public:
+ virtual ~ArmijoLineSearch() {}
+ virtual void Search(const LineSearch::Options& options,
+ double initial_step_size,
+ double initial_cost,
+ double initial_gradient,
+ Summary* summary);
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_LINE_SEARCH_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
new file mode 100644
index 00000000000..2f27a78301a
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
@@ -0,0 +1,145 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/line_search_direction.h"
+#include "ceres/line_search_minimizer.h"
+#include "ceres/low_rank_inverse_hessian.h"
+#include "ceres/internal/eigen.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+class SteepestDescent : public LineSearchDirection {
+ public:
+ virtual ~SteepestDescent() {}
+ bool NextDirection(const LineSearchMinimizer::State& previous,
+ const LineSearchMinimizer::State& current,
+ Vector* search_direction) {
+ *search_direction = -current.gradient;
+ return true;
+ }
+};
+
+class NonlinearConjugateGradient : public LineSearchDirection {
+ public:
+ NonlinearConjugateGradient(const NonlinearConjugateGradientType type,
+ const double function_tolerance)
+ : type_(type),
+ function_tolerance_(function_tolerance) {
+ }
+
+ bool NextDirection(const LineSearchMinimizer::State& previous,
+ const LineSearchMinimizer::State& current,
+ Vector* search_direction) {
+ double beta = 0.0;
+ Vector gradient_change;
+ switch (type_) {
+ case FLETCHER_REEVES:
+ beta = current.gradient_squared_norm / previous.gradient_squared_norm;
+ break;
+ case POLAK_RIBIRERE:
+ gradient_change = current.gradient - previous.gradient;
+ beta = (current.gradient.dot(gradient_change) /
+ previous.gradient_squared_norm);
+ break;
+ case HESTENES_STIEFEL:
+ gradient_change = current.gradient - previous.gradient;
+ beta = (current.gradient.dot(gradient_change) /
+ previous.search_direction.dot(gradient_change));
+ break;
+ default:
+ LOG(FATAL) << "Unknown nonlinear conjugate gradient type: " << type_;
+ }
+
+ *search_direction = -current.gradient + beta * previous.search_direction;
+ const double directional_derivative =
+ current. gradient.dot(*search_direction);
+ if (directional_derivative > -function_tolerance_) {
+ LOG(WARNING) << "Restarting non-linear conjugate gradients: "
+ << directional_derivative;
+ *search_direction = -current.gradient;
+ };
+
+ return true;
+ }
+
+ private:
+ const NonlinearConjugateGradientType type_;
+ const double function_tolerance_;
+};
+
+class LBFGS : public LineSearchDirection {
+ public:
+ LBFGS(const int num_parameters, const int max_lbfgs_rank)
+ : low_rank_inverse_hessian_(num_parameters, max_lbfgs_rank) {}
+
+ virtual ~LBFGS() {}
+
+ bool NextDirection(const LineSearchMinimizer::State& previous,
+ const LineSearchMinimizer::State& current,
+ Vector* search_direction) {
+ low_rank_inverse_hessian_.Update(
+ previous.search_direction * previous.step_size,
+ current.gradient - previous.gradient);
+ search_direction->setZero();
+ low_rank_inverse_hessian_.RightMultiply(current.gradient.data(),
+ search_direction->data());
+ *search_direction *= -1.0;
+ return true;
+ }
+
+ private:
+ LowRankInverseHessian low_rank_inverse_hessian_;
+};
+
+LineSearchDirection*
+LineSearchDirection::Create(const LineSearchDirection::Options& options) {
+ if (options.type == STEEPEST_DESCENT) {
+ return new SteepestDescent;
+ }
+
+ if (options.type == NONLINEAR_CONJUGATE_GRADIENT) {
+ return new NonlinearConjugateGradient(
+ options.nonlinear_conjugate_gradient_type,
+ options.function_tolerance);
+ }
+
+ if (options.type == ceres::LBFGS) {
+ return new ceres::internal::LBFGS(options.num_parameters,
+ options.max_lbfgs_rank);
+ }
+
+ LOG(ERROR) << "Unknown line search direction type: " << options.type;
+ return NULL;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/polynomial_solver.h b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.h
index 1cf07ddb549..71063ab8414 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/polynomial_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.h
@@ -26,40 +26,45 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
-// Author: moll.markus@arcor.de (Markus Moll)
+// Author: sameeragarwal@google.com (Sameer Agarwal)
-#ifndef CERES_INTERNAL_POLYNOMIAL_SOLVER_H_
-#define CERES_INTERNAL_POLYNOMIAL_SOLVER_H_
+#ifndef CERES_INTERNAL_LINE_SEARCH_DIRECTION_H_
+#define CERES_INTERNAL_LINE_SEARCH_DIRECTION_H_
#include "ceres/internal/eigen.h"
+#include "ceres/line_search_minimizer.h"
+#include "ceres/types.h"
namespace ceres {
namespace internal {
-// Use the companion matrix eigenvalues to determine the roots of the polynomial
-//
-// sum_{i=0}^N polynomial(i) x^{N-i}.
-//
-// This function returns true on success, false otherwise.
-// Failure indicates that the polynomial is invalid (of size 0) or
-// that the eigenvalues of the companion matrix could not be computed.
-// On failure, a more detailed message will be written to LOG(ERROR).
-// If real is not NULL, the real parts of the roots will be returned in it.
-// Likewise, if imaginary is not NULL, imaginary parts will be returned in it.
-bool FindPolynomialRoots(const Vector& polynomial,
- Vector* real,
- Vector* imaginary);
+class LineSearchDirection {
+ public:
+ struct Options {
+ Options()
+ : num_parameters(0),
+ type(LBFGS),
+ nonlinear_conjugate_gradient_type(FLETCHER_REEVES),
+ function_tolerance(1e-12),
+ max_lbfgs_rank(20) {
+ }
+
+ int num_parameters;
+ LineSearchDirectionType type;
+ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
+ double function_tolerance;
+ int max_lbfgs_rank;
+ };
+
+ static LineSearchDirection* Create(const Options& options);
-// Evaluate the polynomial at x using the Horner scheme.
-inline double EvaluatePolynomial(const Vector& polynomial, double x) {
- double v = 0.0;
- for (int i = 0; i < polynomial.size(); ++i) {
- v = v * x + polynomial(i);
- }
- return v;
-}
+ virtual ~LineSearchDirection() {}
+ virtual bool NextDirection(const LineSearchMinimizer::State& previous,
+ const LineSearchMinimizer::State& current,
+ Vector* search_direction) = 0;
+};
} // namespace internal
} // namespace ceres
-#endif // CERES_INTERNAL_POLYNOMIAL_SOLVER_H_
+#endif // CERES_INTERNAL_LINE_SEARCH_DIRECTION_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc
new file mode 100644
index 00000000000..ca7d639c5ef
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc
@@ -0,0 +1,283 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Generic loop for line search based optimization algorithms.
+//
+// This is primarily inpsired by the minFunc packaged written by Mark
+// Schmidt.
+//
+// http://www.di.ens.fr/~mschmidt/Software/minFunc.html
+//
+// For details on the theory and implementation see "Numerical
+// Optimization" by Nocedal & Wright.
+
+#include "ceres/line_search_minimizer.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <cmath>
+#include <string>
+#include <vector>
+
+#include "Eigen/Dense"
+#include "ceres/array_utils.h"
+#include "ceres/evaluator.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/line_search.h"
+#include "ceres/line_search_direction.h"
+#include "ceres/stringprintf.h"
+#include "ceres/types.h"
+#include "ceres/wall_time.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+namespace {
+// Small constant for various floating point issues.
+// TODO(sameeragarwal): Change to a better name if this has only one
+// use.
+const double kEpsilon = 1e-12;
+
+bool Evaluate(Evaluator* evaluator,
+ const Vector& x,
+ LineSearchMinimizer::State* state) {
+ const bool status = evaluator->Evaluate(x.data(),
+ &(state->cost),
+ NULL,
+ state->gradient.data(),
+ NULL);
+ if (status) {
+ state->gradient_squared_norm = state->gradient.squaredNorm();
+ state->gradient_max_norm = state->gradient.lpNorm<Eigen::Infinity>();
+ }
+
+ return status;
+}
+
+} // namespace
+
+void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
+ double* parameters,
+ Solver::Summary* summary) {
+ double start_time = WallTimeInSeconds();
+ double iteration_start_time = start_time;
+
+ Evaluator* evaluator = CHECK_NOTNULL(options.evaluator);
+ const int num_parameters = evaluator->NumParameters();
+ const int num_effective_parameters = evaluator->NumEffectiveParameters();
+
+ summary->termination_type = NO_CONVERGENCE;
+ summary->num_successful_steps = 0;
+ summary->num_unsuccessful_steps = 0;
+
+ VectorRef x(parameters, num_parameters);
+
+ State current_state(num_parameters, num_effective_parameters);
+ State previous_state(num_parameters, num_effective_parameters);
+
+ Vector delta(num_effective_parameters);
+ Vector x_plus_delta(num_parameters);
+
+ IterationSummary iteration_summary;
+ iteration_summary.iteration = 0;
+ iteration_summary.step_is_valid = false;
+ iteration_summary.step_is_successful = false;
+ iteration_summary.cost_change = 0.0;
+ iteration_summary.gradient_max_norm = 0.0;
+ iteration_summary.step_norm = 0.0;
+ iteration_summary.linear_solver_iterations = 0;
+ iteration_summary.step_solver_time_in_seconds = 0;
+
+ // Do initial cost and Jacobian evaluation.
+ if (!Evaluate(evaluator, x, &current_state)) {
+ LOG(WARNING) << "Terminating: Cost and gradient evaluation failed.";
+ summary->termination_type = NUMERICAL_FAILURE;
+ return;
+ }
+
+ summary->initial_cost = current_state.cost + summary->fixed_cost;
+ iteration_summary.cost = current_state.cost + summary->fixed_cost;
+
+ iteration_summary.gradient_max_norm = current_state.gradient_max_norm;
+
+ // The initial gradient max_norm is bounded from below so that we do
+ // not divide by zero.
+ const double initial_gradient_max_norm =
+ max(iteration_summary.gradient_max_norm, kEpsilon);
+ const double absolute_gradient_tolerance =
+ options.gradient_tolerance * initial_gradient_max_norm;
+
+ if (iteration_summary.gradient_max_norm <= absolute_gradient_tolerance) {
+ summary->termination_type = GRADIENT_TOLERANCE;
+ VLOG(1) << "Terminating: Gradient tolerance reached."
+ << "Relative gradient max norm: "
+ << iteration_summary.gradient_max_norm / initial_gradient_max_norm
+ << " <= " << options.gradient_tolerance;
+ return;
+ }
+
+ iteration_summary.iteration_time_in_seconds =
+ WallTimeInSeconds() - iteration_start_time;
+ iteration_summary.cumulative_time_in_seconds =
+ WallTimeInSeconds() - start_time
+ + summary->preprocessor_time_in_seconds;
+ summary->iterations.push_back(iteration_summary);
+
+ LineSearchDirection::Options line_search_direction_options;
+ line_search_direction_options.num_parameters = num_effective_parameters;
+ line_search_direction_options.type = options.line_search_direction_type;
+ line_search_direction_options.nonlinear_conjugate_gradient_type =
+ options.nonlinear_conjugate_gradient_type;
+ line_search_direction_options.max_lbfgs_rank = options.max_lbfgs_rank;
+ scoped_ptr<LineSearchDirection> line_search_direction(
+ LineSearchDirection::Create(line_search_direction_options));
+
+ LineSearchFunction line_search_function(evaluator);
+ LineSearch::Options line_search_options;
+ line_search_options.function = &line_search_function;
+
+ // TODO(sameeragarwal): Make this parameterizable over different
+ // line searches.
+ ArmijoLineSearch line_search;
+ LineSearch::Summary line_search_summary;
+
+ while (true) {
+ if (!RunCallbacks(options.callbacks, iteration_summary, summary)) {
+ return;
+ }
+
+ iteration_start_time = WallTimeInSeconds();
+ if (iteration_summary.iteration >= options.max_num_iterations) {
+ summary->termination_type = NO_CONVERGENCE;
+ VLOG(1) << "Terminating: Maximum number of iterations reached.";
+ break;
+ }
+
+ const double total_solver_time = iteration_start_time - start_time +
+ summary->preprocessor_time_in_seconds;
+ if (total_solver_time >= options.max_solver_time_in_seconds) {
+ summary->termination_type = NO_CONVERGENCE;
+ VLOG(1) << "Terminating: Maximum solver time reached.";
+ break;
+ }
+
+ iteration_summary = IterationSummary();
+ iteration_summary.iteration = summary->iterations.back().iteration + 1;
+
+ bool line_search_status = true;
+ if (iteration_summary.iteration == 1) {
+ current_state.search_direction = -current_state.gradient;
+ } else {
+ line_search_status = line_search_direction->NextDirection(
+ previous_state,
+ current_state,
+ &current_state.search_direction);
+ }
+
+ if (!line_search_status) {
+ LOG(WARNING) << "Line search direction computation failed. "
+ "Resorting to steepest descent.";
+ current_state.search_direction = -current_state.gradient;
+ }
+
+ line_search_function.Init(x, current_state.search_direction);
+ current_state.directional_derivative =
+ current_state.gradient.dot(current_state.search_direction);
+
+ // TODO(sameeragarwal): Refactor this into its own object and add
+ // explanations for the various choices.
+ const double initial_step_size = (iteration_summary.iteration == 1)
+ ? min(1.0, 1.0 / current_state.gradient_max_norm)
+ : min(1.0, 2.0 * (current_state.cost - previous_state.cost) /
+ current_state.directional_derivative);
+
+ line_search.Search(line_search_options,
+ initial_step_size,
+ current_state.cost,
+ current_state.directional_derivative,
+ &line_search_summary);
+
+ current_state.step_size = line_search_summary.optimal_step_size;
+ delta = current_state.step_size * current_state.search_direction;
+
+ previous_state = current_state;
+
+ // TODO(sameeragarwal): Collect stats.
+ if (!evaluator->Plus(x.data(), delta.data(), x_plus_delta.data()) ||
+ !Evaluate(evaluator, x_plus_delta, &current_state)) {
+ LOG(WARNING) << "Evaluation failed.";
+ } else {
+ x = x_plus_delta;
+ }
+
+ iteration_summary.gradient_max_norm = current_state.gradient_max_norm;
+ if (iteration_summary.gradient_max_norm <= absolute_gradient_tolerance) {
+ summary->termination_type = GRADIENT_TOLERANCE;
+ VLOG(1) << "Terminating: Gradient tolerance reached."
+ << "Relative gradient max norm: "
+ << iteration_summary.gradient_max_norm / initial_gradient_max_norm
+ << " <= " << options.gradient_tolerance;
+ break;
+ }
+
+ iteration_summary.cost_change = previous_state.cost - current_state.cost;
+ const double absolute_function_tolerance =
+ options.function_tolerance * previous_state.cost;
+ if (fabs(iteration_summary.cost_change) < absolute_function_tolerance) {
+ VLOG(1) << "Terminating. Function tolerance reached. "
+ << "|cost_change|/cost: "
+ << fabs(iteration_summary.cost_change) / previous_state.cost
+ << " <= " << options.function_tolerance;
+ summary->termination_type = FUNCTION_TOLERANCE;
+ return;
+ }
+
+ iteration_summary.cost = current_state.cost + summary->fixed_cost;
+ iteration_summary.step_norm = delta.norm();
+ iteration_summary.step_is_valid = true;
+ iteration_summary.step_is_successful = true;
+ iteration_summary.step_norm = delta.norm();
+ iteration_summary.step_size = current_state.step_size;
+ iteration_summary.line_search_function_evaluations =
+ line_search_summary.num_evaluations;
+ iteration_summary.iteration_time_in_seconds =
+ WallTimeInSeconds() - iteration_start_time;
+ iteration_summary.cumulative_time_in_seconds =
+ WallTimeInSeconds() - start_time
+ + summary->preprocessor_time_in_seconds;
+
+ summary->iterations.push_back(iteration_summary);
+ }
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.h
new file mode 100644
index 00000000000..f82f13984a8
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.h
@@ -0,0 +1,77 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
+#define CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
+
+#include "ceres/minimizer.h"
+#include "ceres/solver.h"
+#include "ceres/types.h"
+#include "ceres/internal/eigen.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+// Generic line search minimization algorithm.
+//
+// For example usage, see SolverImpl::Minimize.
+class LineSearchMinimizer : public Minimizer {
+ public:
+ struct State {
+ State(int num_parameters,
+ int num_effective_parameters)
+ : cost(0.0),
+ gradient(num_effective_parameters),
+ gradient_squared_norm(0.0),
+ search_direction(num_effective_parameters),
+ directional_derivative(0.0),
+ step_size(0.0) {
+ }
+
+ double cost;
+ Vector gradient;
+ double gradient_squared_norm;
+ double gradient_max_norm;
+ Vector search_direction;
+ double directional_derivative;
+ double step_size;
+ };
+
+ ~LineSearchMinimizer() {}
+ virtual void Minimize(const Minimizer::Options& options,
+ double* parameters,
+ Solver::Summary* summary);
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc
index a91e254a663..6c886a1be38 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.cc
@@ -573,13 +573,14 @@ LinearLeastSquaresProblem* LinearLeastSquaresProblem3() {
return problem;
}
-static bool DumpLinearLeastSquaresProblemToConsole(const string& directory,
- int iteration,
- const SparseMatrix* A,
- const double* D,
- const double* b,
- const double* x,
- int num_eliminate_blocks) {
+namespace {
+bool DumpLinearLeastSquaresProblemToConsole(const string& directory,
+ int iteration,
+ const SparseMatrix* A,
+ const double* D,
+ const double* b,
+ const double* x,
+ int num_eliminate_blocks) {
CHECK_NOTNULL(A);
Matrix AA;
A->ToDenseMatrix(&AA);
@@ -601,13 +602,13 @@ static bool DumpLinearLeastSquaresProblemToConsole(const string& directory,
};
#ifndef CERES_NO_PROTOCOL_BUFFERS
-static bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
- int iteration,
- const SparseMatrix* A,
- const double* D,
- const double* b,
- const double* x,
- int num_eliminate_blocks) {
+bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
+ int iteration,
+ const SparseMatrix* A,
+ const double* D,
+ const double* b,
+ const double* x,
+ int num_eliminate_blocks) {
CHECK_NOTNULL(A);
LinearLeastSquaresProblemProto lsqp;
A->ToProto(lsqp.mutable_a());
@@ -641,13 +642,13 @@ static bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& director
return true;
}
#else
-static bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
- int iteration,
- const SparseMatrix* A,
- const double* D,
- const double* b,
- const double* x,
- int num_eliminate_blocks) {
+bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
+ int iteration,
+ const SparseMatrix* A,
+ const double* D,
+ const double* b,
+ const double* x,
+ int num_eliminate_blocks) {
LOG(ERROR) << "Dumping least squares problems is only "
<< "supported when Ceres is compiled with "
<< "protocol buffer support.";
@@ -655,9 +656,9 @@ static bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& director
}
#endif
-static void WriteArrayToFileOrDie(const string& filename,
- const double* x,
- const int size) {
+void WriteArrayToFileOrDie(const string& filename,
+ const double* x,
+ const int size) {
CHECK_NOTNULL(x);
VLOG(2) << "Writing array to: " << filename;
FILE* fptr = fopen(filename.c_str(), "w");
@@ -668,13 +669,13 @@ static void WriteArrayToFileOrDie(const string& filename,
fclose(fptr);
}
-static bool DumpLinearLeastSquaresProblemToTextFile(const string& directory,
- int iteration,
- const SparseMatrix* A,
- const double* D,
- const double* b,
- const double* x,
- int num_eliminate_blocks) {
+bool DumpLinearLeastSquaresProblemToTextFile(const string& directory,
+ int iteration,
+ const SparseMatrix* A,
+ const double* D,
+ const double* b,
+ const double* x,
+ int num_eliminate_blocks) {
CHECK_NOTNULL(A);
string format_string = JoinPath(directory,
"lm_iteration_%03d");
@@ -732,9 +733,10 @@ static bool DumpLinearLeastSquaresProblemToTextFile(const string& directory,
WriteStringToFileOrDie(matlab_script, matlab_filename);
return true;
}
+} // namespace
bool DumpLinearLeastSquaresProblem(const string& directory,
- int iteration,
+ int iteration,
DumpFormatType dump_format_type,
const SparseMatrix* A,
const double* D,
@@ -742,18 +744,18 @@ bool DumpLinearLeastSquaresProblem(const string& directory,
const double* x,
int num_eliminate_blocks) {
switch (dump_format_type) {
- case (CONSOLE):
+ case CONSOLE:
return DumpLinearLeastSquaresProblemToConsole(directory,
iteration,
A, D, b, x,
num_eliminate_blocks);
- case (PROTOBUF):
+ case PROTOBUF:
return DumpLinearLeastSquaresProblemToProtocolBuffer(
directory,
iteration,
A, D, b, x,
num_eliminate_blocks);
- case (TEXTFILE):
+ case TEXTFILE:
return DumpLinearLeastSquaresProblemToTextFile(directory,
iteration,
A, D, b, x,
diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h
index 553cc0d3db3..c76ae91c7d8 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/linear_least_squares_problems.h
@@ -74,7 +74,7 @@ LinearLeastSquaresProblem* LinearLeastSquaresProblem3();
// Write the linear least squares problem to disk. The exact format
// depends on dump_format_type.
bool DumpLinearLeastSquaresProblem(const string& directory,
- int iteration,
+ int iteration,
DumpFormatType dump_format_type,
const SparseMatrix* A,
const double* D,
diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
index 31f88740b9f..a98051468e7 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
@@ -35,14 +35,16 @@
#define CERES_INTERNAL_LINEAR_SOLVER_H_
#include <cstddef>
-
-#include <glog/logging.h>
+#include <map>
+#include <vector>
#include "ceres/block_sparse_matrix.h"
#include "ceres/casts.h"
#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/dense_sparse_matrix.h"
+#include "ceres/execution_summary.h"
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
@@ -76,7 +78,6 @@ class LinearSolver {
min_num_iterations(1),
max_num_iterations(1),
num_threads(1),
- num_eliminate_blocks(0),
residual_reset_period(10),
row_block_size(Dynamic),
e_block_size(Dynamic),
@@ -100,15 +101,23 @@ class LinearSolver {
// If possible, how many threads can the solver use.
int num_threads;
- // Eliminate 0 to num_eliminate_blocks - 1 from the Normal
- // equations to form a schur complement. Only used by the Schur
- // complement based solver. The most common use for this parameter
- // is in the case of structure from motion problems where we have
- // camera blocks and point blocks. Then setting the
- // num_eliminate_blocks to the number of points allows the solver
- // to use the Schur complement trick. For more details see the
- // description of this parameter in solver.h.
- int num_eliminate_blocks;
+ // Hints about the order in which the parameter blocks should be
+ // eliminated by the linear solver.
+ //
+ // For example if elimination_groups is a vector of size k, then
+ // the linear solver is informed that it should eliminate the
+ // parameter blocks 0 - elimination_groups[0] - 1 first, and then
+ // elimination_groups[0] - elimination_groups[1] and so on. Within
+ // each elimination group, the linear solver is free to choose how
+ // the parameter blocks are ordered. Different linear solvers have
+ // differing requirements on elimination_groups.
+ //
+ // The most common use is for Schur type solvers, where there
+ // should be at least two elimination groups and the first
+ // elimination group must form an independent set in the normal
+ // equations. The first elimination group corresponds to the
+ // num_eliminate_blocks in the Schur type solvers.
+ vector<int> elimination_groups;
// Iterative solvers, e.g. Preconditioned Conjugate Gradients
// maintain a cheap estimate of the residual which may become
@@ -247,6 +256,18 @@ class LinearSolver {
const PerSolveOptions& per_solve_options,
double* x) = 0;
+ // The following two methods return copies instead of references so
+ // that the base class implementation does not have to worry about
+ // life time issues. Further, these calls are not expected to be
+ // frequent or performance sensitive.
+ virtual map<string, int> CallStatistics() const {
+ return map<string, int>();
+ }
+
+ virtual map<string, double> TimeStatistics() const {
+ return map<string, double>();
+ }
+
// Factory
static LinearSolver* Create(const Options& options);
};
@@ -267,18 +288,29 @@ class TypedLinearSolver : public LinearSolver {
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) {
+ ScopedExecutionTimer total_time("LinearSolver::Solve", &execution_summary_);
CHECK_NOTNULL(A);
CHECK_NOTNULL(b);
CHECK_NOTNULL(x);
return SolveImpl(down_cast<MatrixType*>(A), b, per_solve_options, x);
}
+ virtual map<string, int> CallStatistics() const {
+ return execution_summary_.calls();
+ }
+
+ virtual map<string, double> TimeStatistics() const {
+ return execution_summary_.times();
+ }
+
private:
virtual LinearSolver::Summary SolveImpl(
MatrixType* A,
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) = 0;
+
+ ExecutionSummary execution_summary_;
};
// Linear solvers that depend on acccess to the low level structure of
diff --git a/extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.cc b/extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.cc
new file mode 100644
index 00000000000..3fe113f1afb
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.cc
@@ -0,0 +1,109 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/internal/eigen.h"
+#include "ceres/low_rank_inverse_hessian.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+LowRankInverseHessian::LowRankInverseHessian(int num_parameters,
+ int max_num_corrections)
+ : num_parameters_(num_parameters),
+ max_num_corrections_(max_num_corrections),
+ num_corrections_(0),
+ diagonal_(1.0),
+ delta_x_history_(num_parameters, max_num_corrections),
+ delta_gradient_history_(num_parameters, max_num_corrections),
+ delta_x_dot_delta_gradient_(max_num_corrections) {
+}
+
+bool LowRankInverseHessian::Update(const Vector& delta_x,
+ const Vector& delta_gradient) {
+ const double delta_x_dot_delta_gradient = delta_x.dot(delta_gradient);
+ if (delta_x_dot_delta_gradient <= 1e-10) {
+ VLOG(2) << "Skipping LBFGS Update. " << delta_x_dot_delta_gradient;
+ return false;
+ }
+
+ if (num_corrections_ == max_num_corrections_) {
+ // TODO(sameeragarwal): This can be done more efficiently using
+ // a circular buffer/indexing scheme, but for simplicity we will
+ // do the expensive copy for now.
+ delta_x_history_.block(0, 0, num_parameters_, max_num_corrections_ - 2) =
+ delta_x_history_
+ .block(0, 1, num_parameters_, max_num_corrections_ - 1);
+
+ delta_gradient_history_
+ .block(0, 0, num_parameters_, max_num_corrections_ - 2) =
+ delta_gradient_history_
+ .block(0, 1, num_parameters_, max_num_corrections_ - 1);
+
+ delta_x_dot_delta_gradient_.head(num_corrections_ - 2) =
+ delta_x_dot_delta_gradient_.tail(num_corrections_ - 1);
+ } else {
+ ++num_corrections_;
+ }
+
+ delta_x_history_.col(num_corrections_ - 1) = delta_x;
+ delta_gradient_history_.col(num_corrections_ - 1) = delta_gradient;
+ delta_x_dot_delta_gradient_(num_corrections_ - 1) =
+ delta_x_dot_delta_gradient;
+ diagonal_ = delta_x_dot_delta_gradient / delta_gradient.squaredNorm();
+ return true;
+}
+
+void LowRankInverseHessian::RightMultiply(const double* x_ptr,
+ double* y_ptr) const {
+ ConstVectorRef gradient(x_ptr, num_parameters_);
+ VectorRef search_direction(y_ptr, num_parameters_);
+
+ search_direction = gradient;
+
+ Vector alpha(num_corrections_);
+
+ for (int i = num_corrections_ - 1; i >= 0; --i) {
+ alpha(i) = delta_x_history_.col(i).dot(search_direction) /
+ delta_x_dot_delta_gradient_(i);
+ search_direction -= alpha(i) * delta_gradient_history_.col(i);
+ }
+
+ search_direction *= diagonal_;
+
+ for (int i = 0; i < num_corrections_; ++i) {
+ const double beta = delta_gradient_history_.col(i).dot(search_direction) /
+ delta_x_dot_delta_gradient_(i);
+ search_direction += delta_x_history_.col(i) * (alpha(i) - beta);
+ }
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.h b/extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.h
new file mode 100644
index 00000000000..6f3fc0c9d00
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/low_rank_inverse_hessian.h
@@ -0,0 +1,99 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Limited memory positive definite approximation to the inverse
+// Hessian, using the LBFGS algorithm
+
+#ifndef CERES_INTERNAL_LOW_RANK_INVERSE_HESSIAN_H_
+#define CERES_INTERNAL_LOW_RANK_INVERSE_HESSIAN_H_
+
+#include "ceres/internal/eigen.h"
+#include "ceres/linear_operator.h"
+
+namespace ceres {
+namespace internal {
+
+// LowRankInverseHessian is a positive definite approximation to the
+// Hessian using the limited memory variant of the
+// Broyden-Fletcher-Goldfarb-Shanno (BFGS)secant formula for
+// approximating the Hessian.
+//
+// Other update rules like the Davidon-Fletcher-Powell (DFP) are
+// possible, but the BFGS rule is considered the best performing one.
+//
+// The limited memory variant was developed by Nocedal and further
+// enhanced with scaling rule by Byrd, Nocedal and Schanbel.
+//
+// Nocedal, J. (1980). "Updating Quasi-Newton Matrices with Limited
+// Storage". Mathematics of Computation 35 (151): 773–782.
+//
+// Byrd, R. H.; Nocedal, J.; Schnabel, R. B. (1994).
+// "Representations of Quasi-Newton Matrices and their use in
+// Limited Memory Methods". Mathematical Programming 63 (4):
+class LowRankInverseHessian : public LinearOperator {
+ public:
+ // num_parameters is the row/column size of the Hessian.
+ // max_num_corrections is the rank of the Hessian approximation.
+ // The approximation uses:
+ // 2 * max_num_corrections * num_parameters + max_num_corrections
+ // doubles.
+ LowRankInverseHessian(int num_parameters, int max_num_corrections);
+ virtual ~LowRankInverseHessian() {}
+
+ // Update the low rank approximation. delta_x is the change in the
+ // domain of Hessian, and delta_gradient is the change in the
+ // gradient. The update copies the delta_x and delta_gradient
+ // vectors, and gets rid of the oldest delta_x and delta_gradient
+ // vectors if the number of corrections is already equal to
+ // max_num_corrections.
+ bool Update(const Vector& delta_x, const Vector& delta_gradient);
+
+ // LinearOperator interface
+ virtual void RightMultiply(const double* x, double* y) const;
+ virtual void LeftMultiply(const double* x, double* y) const {
+ RightMultiply(x, y);
+ }
+ virtual int num_rows() const { return num_parameters_; }
+ virtual int num_cols() const { return num_parameters_; }
+
+ private:
+ const int num_parameters_;
+ const int max_num_corrections_;
+ int num_corrections_;
+ double diagonal_;
+ Matrix delta_x_history_;
+ Matrix delta_gradient_history_;
+ Vector delta_x_dot_delta_gradient_;
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_LOW_RANK_INVERSE_HESSIAN_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/map_util.h b/extern/libmv/third_party/ceres/internal/ceres/map_util.h
index ddf1252f674..929c6b36982 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/map_util.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/map_util.h
@@ -35,6 +35,7 @@
#include <utility>
#include "ceres/internal/port.h"
+#include "glog/logging.h"
namespace ceres {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/minimizer.cc
new file mode 100644
index 00000000000..2e2c15ac612
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/minimizer.cc
@@ -0,0 +1,67 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/minimizer.h"
+#include "ceres/types.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+Minimizer::~Minimizer() {}
+
+bool Minimizer::RunCallbacks(const vector<IterationCallback*> callbacks,
+ const IterationSummary& iteration_summary,
+ Solver::Summary* summary) {
+ CallbackReturnType status = SOLVER_CONTINUE;
+ int i = 0;
+ while (status == SOLVER_CONTINUE && i < callbacks.size()) {
+ status = (*callbacks[i])(iteration_summary);
+ ++i;
+ }
+ switch (status) {
+ case SOLVER_CONTINUE:
+ return true;
+ case SOLVER_TERMINATE_SUCCESSFULLY:
+ summary->termination_type = USER_SUCCESS;
+ VLOG(1) << "Terminating: User callback returned USER_SUCCESS.";
+ return false;
+ case SOLVER_ABORT:
+ summary->termination_type = USER_ABORT;
+ VLOG(1) << "Terminating: User callback returned USER_ABORT.";
+ return false;
+ default:
+ LOG(FATAL) << "Unknown type of user callback status";
+ }
+ return false;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h
index cfc98a3ebd0..708974d63c2 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/minimizer.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h
@@ -32,8 +32,9 @@
#define CERES_INTERNAL_MINIMIZER_H_
#include <vector>
-#include "ceres/solver.h"
+#include "ceres/internal/port.h"
#include "ceres/iteration_callback.h"
+#include "ceres/solver.h"
namespace ceres {
namespace internal {
@@ -59,6 +60,7 @@ class Minimizer {
}
void Init(const Solver::Options& options) {
+ num_threads = options.num_threads;
max_num_iterations = options.max_num_iterations;
max_solver_time_in_seconds = options.max_solver_time_in_seconds;
max_step_solver_retries = 5;
@@ -74,18 +76,24 @@ class Minimizer {
lsqp_dump_directory = options.lsqp_dump_directory;
lsqp_iterations_to_dump = options.lsqp_iterations_to_dump;
lsqp_dump_format_type = options.lsqp_dump_format_type;
- num_eliminate_blocks = options.num_eliminate_blocks;
max_num_consecutive_invalid_steps =
options.max_num_consecutive_invalid_steps;
min_trust_region_radius = options.min_trust_region_radius;
+ line_search_direction_type = options.line_search_direction_type;
+ line_search_type = options.line_search_type;
+ nonlinear_conjugate_gradient_type =
+ options.nonlinear_conjugate_gradient_type;
+ max_lbfgs_rank = options.max_lbfgs_rank;
evaluator = NULL;
trust_region_strategy = NULL;
jacobian = NULL;
callbacks = options.callbacks;
+ inner_iteration_minimizer = NULL;
}
int max_num_iterations;
double max_solver_time_in_seconds;
+ int num_threads;
// Number of times the linear solver should be retried in case of
// numerical failure. The retries are done by exponentially scaling up
@@ -104,9 +112,12 @@ class Minimizer {
vector<int> lsqp_iterations_to_dump;
DumpFormatType lsqp_dump_format_type;
string lsqp_dump_directory;
- int num_eliminate_blocks;
int max_num_consecutive_invalid_steps;
int min_trust_region_radius;
+ LineSearchDirectionType line_search_direction_type;
+ LineSearchType line_search_type;
+ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
+ int max_lbfgs_rank;
// List of callbacks that are executed by the Minimizer at the end
// of each iteration.
@@ -128,10 +139,15 @@ class Minimizer {
// and will remain constant for the life time of the
// optimization. The Options struct does not own this pointer.
SparseMatrix* jacobian;
+
+ Minimizer* inner_iteration_minimizer;
};
- virtual ~Minimizer() {}
+ static bool RunCallbacks(const vector<IterationCallback*> callbacks,
+ const IterationSummary& iteration_summary,
+ Solver::Summary* summary);
+ virtual ~Minimizer();
// Note: The minimizer is expected to update the state of the
// parameters array every iteration. This is required for the
// StateUpdatingCallback to work.
diff --git a/extern/libmv/third_party/ceres/internal/ceres/mutex.h b/extern/libmv/third_party/ceres/internal/ceres/mutex.h
index 5090a71b78d..410748ff0ab 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/mutex.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/mutex.h
@@ -107,10 +107,12 @@
# define _WIN32_WINNT 0x0400
# endif
# endif
+// Unfortunately, windows.h defines a bunch of macros with common
+// names. Two in particular need avoiding: ERROR and min/max.
// To avoid macro definition of ERROR.
-# define CERES_NOGDI
+# define NOGDI
// To avoid macro definition of min/max.
-# define CERES_NOMINMAX
+# define NOMINMAX
# include <windows.h>
typedef CRITICAL_SECTION MutexType;
#elif defined(CERES_HAVE_PTHREAD) && defined(CERES_HAVE_RWLOCK)
diff --git a/extern/libmv/third_party/ceres/internal/ceres/parameter_block.h b/extern/libmv/third_party/ceres/internal/ceres/parameter_block.h
index f20805ca873..b1e8d938b8a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/parameter_block.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/parameter_block.h
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
#include <cstdlib>
#include <string>
#include "ceres/array_utils.h"
+#include "ceres/collections_port.h"
#include "ceres/integral_types.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/port.h"
@@ -46,6 +47,7 @@ namespace ceres {
namespace internal {
class ProblemImpl;
+class ResidualBlock;
// The parameter block encodes the location of the user's original value, and
// also the "current state" of the parameter. The evaluator uses whatever is in
@@ -58,13 +60,29 @@ class ProblemImpl;
// responsible for the proper disposal of the local parameterization.
class ParameterBlock {
public:
- ParameterBlock(double* user_state, int size) {
- Init(user_state, size, NULL);
+ // TODO(keir): Decide what data structure is best here. Should this be a set?
+ // Probably not, because sets are memory inefficient. However, if it's a
+ // vector, you can get into pathological linear performance when removing a
+ // residual block from a problem where all the residual blocks depend on one
+ // parameter; for example, shared focal length in a bundle adjustment
+ // problem. It might be worth making a custom structure that is just an array
+ // when it is small, but transitions to a hash set when it has more elements.
+ //
+ // For now, use a hash set.
+ typedef HashSet<ResidualBlock*> ResidualBlockSet;
+
+ // Create a parameter block with the user state, size, and index specified.
+ // The size is the size of the parameter block and the index is the position
+ // of the parameter block inside a Program (if any).
+ ParameterBlock(double* user_state, int size, int index) {
+ Init(user_state, size, index, NULL);
}
+
ParameterBlock(double* user_state,
int size,
+ int index,
LocalParameterization* local_parameterization) {
- Init(user_state, size, local_parameterization);
+ Init(user_state, size, index, local_parameterization);
}
// The size of the parameter block.
@@ -187,12 +205,43 @@ class ParameterBlock {
delta_offset_);
}
+ void EnableResidualBlockDependencies() {
+ CHECK(residual_blocks_.get() == NULL)
+ << "Ceres bug: There is already a residual block collection "
+ << "for parameter block: " << ToString();
+ residual_blocks_.reset(new ResidualBlockSet);
+ }
+
+ void AddResidualBlock(ResidualBlock* residual_block) {
+ CHECK(residual_blocks_.get() != NULL)
+ << "Ceres bug: The residual block collection is null for parameter "
+ << "block: " << ToString();
+ residual_blocks_->insert(residual_block);
+ }
+
+ void RemoveResidualBlock(ResidualBlock* residual_block) {
+ CHECK(residual_blocks_.get() != NULL)
+ << "Ceres bug: The residual block collection is null for parameter "
+ << "block: " << ToString();
+ CHECK(residual_blocks_->find(residual_block) != residual_blocks_->end())
+ << "Ceres bug: Missing residual for parameter block: " << ToString();
+ residual_blocks_->erase(residual_block);
+ }
+
+ // This is only intended for iterating; perhaps this should only expose
+ // .begin() and .end().
+ ResidualBlockSet* mutable_residual_blocks() {
+ return residual_blocks_.get();
+ }
+
private:
void Init(double* user_state,
int size,
+ int index,
LocalParameterization* local_parameterization) {
user_state_ = user_state;
size_ = size;
+ index_ = index;
is_constant_ = false;
state_ = user_state_;
@@ -201,7 +250,6 @@ class ParameterBlock {
SetParameterization(local_parameterization);
}
- index_ = -1;
state_offset_ = -1;
delta_offset_ = -1;
}
@@ -261,6 +309,9 @@ class ParameterBlock {
// The offset of this parameter block inside a larger delta vector.
int32 delta_offset_;
+ // If non-null, contains the residual blocks this parameter block is in.
+ scoped_ptr<ResidualBlockSet> residual_blocks_;
+
// Necessary so ProblemImpl can clean up the parameterizations.
friend class ProblemImpl;
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc
index 1cdff4e6dec..e8f626f8e80 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc
@@ -28,7 +28,7 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
-#include "ceres/schur_ordering.h"
+#include "ceres/parameter_block_ordering.h"
#include "ceres/graph.h"
#include "ceres/graph_algorithms.h"
@@ -46,8 +46,7 @@ int ComputeSchurOrdering(const Program& program,
vector<ParameterBlock*>* ordering) {
CHECK_NOTNULL(ordering)->clear();
- scoped_ptr<Graph< ParameterBlock*> > graph(
- CHECK_NOTNULL(CreateHessianGraph(program)));
+ scoped_ptr<Graph< ParameterBlock*> > graph(CreateHessianGraph(program));
int independent_set_size = IndependentSetOrdering(*graph, ordering);
const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
@@ -62,9 +61,31 @@ int ComputeSchurOrdering(const Program& program,
return independent_set_size;
}
+void ComputeRecursiveIndependentSetOrdering(const Program& program,
+ ParameterBlockOrdering* ordering) {
+ CHECK_NOTNULL(ordering)->Clear();
+ const vector<ParameterBlock*> parameter_blocks = program.parameter_blocks();
+ scoped_ptr<Graph< ParameterBlock*> > graph(CreateHessianGraph(program));
+
+ int num_covered = 0;
+ int round = 0;
+ while (num_covered < parameter_blocks.size()) {
+ vector<ParameterBlock*> independent_set_ordering;
+ const int independent_set_size =
+ IndependentSetOrdering(*graph, &independent_set_ordering);
+ for (int i = 0; i < independent_set_size; ++i) {
+ ParameterBlock* parameter_block = independent_set_ordering[i];
+ ordering->AddElementToGroup(parameter_block->mutable_user_state(), round);
+ graph->RemoveVertex(parameter_block);
+ }
+ num_covered += independent_set_size;
+ ++round;
+ }
+}
+
Graph<ParameterBlock*>*
CreateHessianGraph(const Program& program) {
- Graph<ParameterBlock*>* graph = new Graph<ParameterBlock*>;
+ Graph<ParameterBlock*>* graph = CHECK_NOTNULL(new Graph<ParameterBlock*>);
const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
for (int i = 0; i < parameter_blocks.size(); ++i) {
ParameterBlock* parameter_block = parameter_blocks[i];
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h
index 1f9a4ff354f..a5277a44c70 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_ordering.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h
@@ -27,14 +27,12 @@
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
-//
-// Compute a parameter block ordering for use with the Schur
-// complement based algorithms.
-#ifndef CERES_INTERNAL_SCHUR_ORDERING_H_
-#define CERES_INTERNAL_SCHUR_ORDERING_H_
+#ifndef CERES_INTERNAL_PARAMETER_BLOCK_ORDERING_H_
+#define CERES_INTERNAL_PARAMETER_BLOCK_ORDERING_H_
#include <vector>
+#include "ceres/ordered_groups.h"
#include "ceres/graph.h"
#include "ceres/types.h"
@@ -60,6 +58,12 @@ class ParameterBlock;
int ComputeSchurOrdering(const Program& program,
vector<ParameterBlock* >* ordering);
+// Use an approximate independent set ordering to decompose the
+// parameter blocks of a problem in a sequence of independent
+// sets. The ordering covers all the non-constant parameter blocks in
+// the program.
+void ComputeRecursiveIndependentSetOrdering(const Program& program,
+ ParameterBlockOrdering* ordering);
// Builds a graph on the parameter blocks of a Problem, whose
// structure reflects the sparsity structure of the Hessian. Each
@@ -71,4 +75,4 @@ Graph<ParameterBlock*>* CreateHessianGraph(const Program& program);
} // namespace internal
} // namespace ceres
-#endif // CERES_INTERNAL_SCHUR_ORDERING_H_
+#endif // CERES_INTERNAL_PARAMETER_BLOCK_ORDERING_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/polynomial_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/polynomial.cc
index 20c01566a89..3238b89670e 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/polynomial_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/polynomial.cc
@@ -27,11 +27,14 @@
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: moll.markus@arcor.de (Markus Moll)
+// sameeragarwal@google.com (Sameer Agarwal)
-#include "ceres/polynomial_solver.h"
+#include "ceres/polynomial.h"
#include <cmath>
#include <cstddef>
+#include <vector>
+
#include "Eigen/Dense"
#include "ceres/internal/port.h"
#include "glog/logging.h"
@@ -159,8 +162,7 @@ bool FindPolynomialRoots(const Vector& polynomial_in,
BalanceCompanionMatrix(&companion_matrix);
// Find its (complex) eigenvalues.
- Eigen::EigenSolver<Matrix> solver(companion_matrix,
- Eigen::EigenvaluesOnly);
+ Eigen::EigenSolver<Matrix> solver(companion_matrix, false);
if (solver.info() != Eigen::Success) {
LOG(ERROR) << "Failed to extract eigenvalues from companion matrix.";
return false;
@@ -180,5 +182,138 @@ bool FindPolynomialRoots(const Vector& polynomial_in,
return true;
}
+Vector DifferentiatePolynomial(const Vector& polynomial) {
+ const int degree = polynomial.rows() - 1;
+ CHECK_GE(degree, 0);
+
+ // Degree zero polynomials are constants, and their derivative does
+ // not result in a smaller degree polynomial, just a degree zero
+ // polynomial with value zero.
+ if (degree == 0) {
+ return Eigen::VectorXd::Zero(1);
+ }
+
+ Vector derivative(degree);
+ for (int i = 0; i < degree; ++i) {
+ derivative(i) = (degree - i) * polynomial(i);
+ }
+
+ return derivative;
+}
+
+void MinimizePolynomial(const Vector& polynomial,
+ const double x_min,
+ const double x_max,
+ double* optimal_x,
+ double* optimal_value) {
+ // Find the minimum of the polynomial at the two ends.
+ //
+ // We start by inspecting the middle of the interval. Technically
+ // this is not needed, but we do this to make this code as close to
+ // the minFunc package as possible.
+ *optimal_x = (x_min + x_max) / 2.0;
+ *optimal_value = EvaluatePolynomial(polynomial, *optimal_x);
+
+ const double x_min_value = EvaluatePolynomial(polynomial, x_min);
+ if (x_min_value < *optimal_value) {
+ *optimal_value = x_min_value;
+ *optimal_x = x_min;
+ }
+
+ const double x_max_value = EvaluatePolynomial(polynomial, x_max);
+ if (x_max_value < *optimal_value) {
+ *optimal_value = x_max_value;
+ *optimal_x = x_max;
+ }
+
+ // If the polynomial is linear or constant, we are done.
+ if (polynomial.rows() <= 2) {
+ return;
+ }
+
+ const Vector derivative = DifferentiatePolynomial(polynomial);
+ Vector roots_real;
+ if (!FindPolynomialRoots(derivative, &roots_real, NULL)) {
+ LOG(WARNING) << "Unable to find the critical points of "
+ << "the interpolating polynomial.";
+ return;
+ }
+
+ // This is a bit of an overkill, as some of the roots may actually
+ // have a complex part, but its simpler to just check these values.
+ for (int i = 0; i < roots_real.rows(); ++i) {
+ const double root = roots_real(i);
+ if ((root < x_min) || (root > x_max)) {
+ continue;
+ }
+
+ const double value = EvaluatePolynomial(polynomial, root);
+ if (value < *optimal_value) {
+ *optimal_value = value;
+ *optimal_x = root;
+ }
+ }
+}
+
+Vector FindInterpolatingPolynomial(const vector<FunctionSample>& samples) {
+ const int num_samples = samples.size();
+ int num_constraints = 0;
+ for (int i = 0; i < num_samples; ++i) {
+ if (samples[i].value_is_valid) {
+ ++num_constraints;
+ }
+ if (samples[i].gradient_is_valid) {
+ ++num_constraints;
+ }
+ }
+
+ const int degree = num_constraints - 1;
+ Matrix lhs = Matrix::Zero(num_constraints, num_constraints);
+ Vector rhs = Vector::Zero(num_constraints);
+
+ int row = 0;
+ for (int i = 0; i < num_samples; ++i) {
+ const FunctionSample& sample = samples[i];
+ if (sample.value_is_valid) {
+ for (int j = 0; j <= degree; ++j) {
+ lhs(row, j) = pow(sample.x, degree - j);
+ }
+ rhs(row) = sample.value;
+ ++row;
+ }
+
+ if (sample.gradient_is_valid) {
+ for (int j = 0; j < degree; ++j) {
+ lhs(row, j) = (degree - j) * pow(sample.x, degree - j - 1);
+ }
+ rhs(row) = sample.gradient;
+ ++row;
+ }
+ }
+
+ return lhs.fullPivLu().solve(rhs);
+}
+
+void MinimizeInterpolatingPolynomial(const vector<FunctionSample>& samples,
+ double x_min,
+ double x_max,
+ double* optimal_x,
+ double* optimal_value) {
+ const Vector polynomial = FindInterpolatingPolynomial(samples);
+ MinimizePolynomial(polynomial, x_min, x_max, optimal_x, optimal_value);
+ for (int i = 0; i < samples.size(); ++i) {
+ const FunctionSample& sample = samples[i];
+ if ((sample.x < x_min) || (sample.x > x_max)) {
+ continue;
+ }
+
+ const double value = EvaluatePolynomial(polynomial, sample.x);
+ if (value < *optimal_value) {
+ *optimal_x = sample.x;
+ *optimal_value = value;
+ }
+ }
+}
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/polynomial.h b/extern/libmv/third_party/ceres/internal/ceres/polynomial.h
new file mode 100644
index 00000000000..42ffdcb13c5
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/polynomial.h
@@ -0,0 +1,134 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: moll.markus@arcor.de (Markus Moll)
+// sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_POLYNOMIAL_SOLVER_H_
+#define CERES_INTERNAL_POLYNOMIAL_SOLVER_H_
+
+#include <vector>
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+
+namespace ceres {
+namespace internal {
+
+// All polynomials are assumed to be the form
+//
+// sum_{i=0}^N polynomial(i) x^{N-i}.
+//
+// and are given by a vector of coefficients of size N + 1.
+
+// Evaluate the polynomial at x using the Horner scheme.
+inline double EvaluatePolynomial(const Vector& polynomial, double x) {
+ double v = 0.0;
+ for (int i = 0; i < polynomial.size(); ++i) {
+ v = v * x + polynomial(i);
+ }
+ return v;
+}
+
+// Use the companion matrix eigenvalues to determine the roots of the
+// polynomial.
+//
+// This function returns true on success, false otherwise.
+// Failure indicates that the polynomial is invalid (of size 0) or
+// that the eigenvalues of the companion matrix could not be computed.
+// On failure, a more detailed message will be written to LOG(ERROR).
+// If real is not NULL, the real parts of the roots will be returned in it.
+// Likewise, if imaginary is not NULL, imaginary parts will be returned in it.
+bool FindPolynomialRoots(const Vector& polynomial,
+ Vector* real,
+ Vector* imaginary);
+
+// Return the derivative of the given polynomial. It is assumed that
+// the input polynomial is at least of degree zero.
+Vector DifferentiatePolynomial(const Vector& polynomial);
+
+// Find the minimum value of the polynomial in the interval [x_min,
+// x_max]. The minimum is obtained by computing all the roots of the
+// derivative of the input polynomial. All real roots within the
+// interval [x_min, x_max] are considered as well as the end points
+// x_min and x_max. Since polynomials are differentiable functions,
+// this ensures that the true minimum is found.
+void MinimizePolynomial(const Vector& polynomial,
+ double x_min,
+ double x_max,
+ double* optimal_x,
+ double* optimal_value);
+
+// Structure for storing sample values of a function.
+//
+// Clients can use this struct to communicate the value of the
+// function and or its gradient at a given point x.
+struct FunctionSample {
+ FunctionSample()
+ : x(0.0),
+ value(0.0),
+ value_is_valid(false),
+ gradient(0.0),
+ gradient_is_valid(false) {
+ }
+
+ double x;
+ double value; // value = f(x)
+ bool value_is_valid;
+ double gradient; // gradient = f'(x)
+ bool gradient_is_valid;
+};
+
+// Given a set of function value and/or gradient samples, find a
+// polynomial whose value and gradients are exactly equal to the ones
+// in samples.
+//
+// Generally speaking,
+//
+// degree = # values + # gradients - 1
+//
+// Of course its possible to sample a polynomial any number of times,
+// in which case, generally speaking the spurious higher order
+// coefficients will be zero.
+Vector FindInterpolatingPolynomial(const vector<FunctionSample>& samples);
+
+// Interpolate the function described by samples with a polynomial,
+// and minimize it on the interval [x_min, x_max]. Depending on the
+// input samples, it is possible that the interpolation or the root
+// finding algorithms may fail due to numerical difficulties. But the
+// function is guaranteed to return its best guess of an answer, by
+// considering the samples and the end points as possible solutions.
+void MinimizeInterpolatingPolynomial(const vector<FunctionSample>& samples,
+ double x_min,
+ double x_max,
+ double* optimal_x,
+ double* optimal_value);
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_POLYNOMIAL_SOLVER_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc
new file mode 100644
index 00000000000..05e539f9fb1
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc
@@ -0,0 +1,63 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/preconditioner.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+Preconditioner::~Preconditioner() {
+}
+
+SparseMatrixPreconditionerWrapper::SparseMatrixPreconditionerWrapper(
+ const SparseMatrix* matrix)
+ : matrix_(CHECK_NOTNULL(matrix)) {
+}
+
+SparseMatrixPreconditionerWrapper::~SparseMatrixPreconditionerWrapper() {
+}
+
+bool SparseMatrixPreconditionerWrapper::Update(const BlockSparseMatrixBase& A,
+ const double* D) {
+ return true;
+}
+
+void SparseMatrixPreconditionerWrapper::RightMultiply(const double* x,
+ double* y) const {
+ matrix_->RightMultiply(x, y);
+}
+
+int SparseMatrixPreconditionerWrapper::num_rows() const {
+ return matrix_->num_rows();
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
new file mode 100644
index 00000000000..5bb077e0e33
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
@@ -0,0 +1,148 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_PRECONDITIONER_H_
+#define CERES_INTERNAL_PRECONDITIONER_H_
+
+#include <vector>
+#include "ceres/linear_operator.h"
+#include "ceres/sparse_matrix.h"
+
+namespace ceres {
+namespace internal {
+
+class BlockSparseMatrixBase;
+class SparseMatrix;
+
+class Preconditioner : public LinearOperator {
+ public:
+ struct Options {
+ Options()
+ : type(JACOBI),
+ sparse_linear_algebra_library(SUITE_SPARSE),
+ use_block_amd(true),
+ num_threads(1),
+ row_block_size(Dynamic),
+ e_block_size(Dynamic),
+ f_block_size(Dynamic) {
+ }
+
+ PreconditionerType type;
+
+ SparseLinearAlgebraLibraryType sparse_linear_algebra_library;
+
+ // See solver.h for explanation of this option.
+ bool use_block_amd;
+
+ // If possible, how many threads the preconditioner can use.
+ int num_threads;
+
+ // Hints about the order in which the parameter blocks should be
+ // eliminated by the linear solver.
+ //
+ // For example if elimination_groups is a vector of size k, then
+ // the linear solver is informed that it should eliminate the
+ // parameter blocks 0 ... elimination_groups[0] - 1 first, and
+ // then elimination_groups[0] ... elimination_groups[1] and so
+ // on. Within each elimination group, the linear solver is free to
+ // choose how the parameter blocks are ordered. Different linear
+ // solvers have differing requirements on elimination_groups.
+ //
+ // The most common use is for Schur type solvers, where there
+ // should be at least two elimination groups and the first
+ // elimination group must form an independent set in the normal
+ // equations. The first elimination group corresponds to the
+ // num_eliminate_blocks in the Schur type solvers.
+ vector<int> elimination_groups;
+
+ // If the block sizes in a BlockSparseMatrix are fixed, then in
+ // some cases the Schur complement based solvers can detect and
+ // specialize on them.
+ //
+ // It is expected that these parameters are set programmatically
+ // rather than manually.
+ //
+ // Please see schur_complement_solver.h and schur_eliminator.h for
+ // more details.
+ int row_block_size;
+ int e_block_size;
+ int f_block_size;
+ };
+
+ virtual ~Preconditioner();
+
+ // Update the numerical value of the preconditioner for the linear
+ // system:
+ //
+ // | A | x = |b|
+ // |diag(D)| |0|
+ //
+ // for some vector b. It is important that the matrix A have the
+ // same block structure as the one used to construct this object.
+ //
+ // D can be NULL, in which case its interpreted as a diagonal matrix
+ // of size zero.
+ virtual bool Update(const BlockSparseMatrixBase& A, const double* D) = 0;
+
+ // LinearOperator interface. Since the operator is symmetric,
+ // LeftMultiply and num_cols are just calls to RightMultiply and
+ // num_rows respectively. Update() must be called before
+ // RightMultiply can be called.
+ virtual void RightMultiply(const double* x, double* y) const = 0;
+ virtual void LeftMultiply(const double* x, double* y) const {
+ return RightMultiply(x, y);
+ }
+
+ virtual int num_rows() const = 0;
+ virtual int num_cols() const {
+ return num_rows();
+ }
+};
+
+// Wrap a SparseMatrix object as a preconditioner.
+class SparseMatrixPreconditionerWrapper : public Preconditioner {
+ public:
+ // Wrapper does NOT take ownership of the matrix pointer.
+ explicit SparseMatrixPreconditionerWrapper(const SparseMatrix* matrix);
+ virtual ~SparseMatrixPreconditionerWrapper();
+
+ // Preconditioner interface
+ virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
+ virtual void RightMultiply(const double* x, double* y) const;
+ virtual int num_rows() const;
+
+ private:
+ const SparseMatrix* matrix_;
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_PRECONDITIONER_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem.cc b/extern/libmv/third_party/ceres/internal/ceres/problem.cc
index b8c25d9db84..43e78835b15 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/problem.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/problem.cc
@@ -32,12 +32,11 @@
#include "ceres/problem.h"
#include <vector>
+#include "ceres/crs_matrix.h"
#include "ceres/problem_impl.h"
namespace ceres {
-class ResidualBlock;
-
Problem::Problem() : problem_impl_(new internal::ProblemImpl) {}
Problem::Problem(const Problem::Options& options)
: problem_impl_(new internal::ProblemImpl(options)) {}
@@ -106,6 +105,47 @@ ResidualBlockId Problem::AddResidualBlock(
x0, x1, x2, x3, x4, x5);
}
+ResidualBlockId Problem::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6) {
+ return problem_impl_->AddResidualBlock(cost_function,
+ loss_function,
+ x0, x1, x2, x3, x4, x5, x6);
+}
+
+ResidualBlockId Problem::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6, double* x7) {
+ return problem_impl_->AddResidualBlock(cost_function,
+ loss_function,
+ x0, x1, x2, x3, x4, x5, x6, x7);
+}
+
+ResidualBlockId Problem::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8) {
+ return problem_impl_->AddResidualBlock(cost_function,
+ loss_function,
+ x0, x1, x2, x3, x4, x5, x6, x7, x8);
+}
+
+ResidualBlockId Problem::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8, double* x9) {
+ return problem_impl_->AddResidualBlock(
+ cost_function,
+ loss_function,
+ x0, x1, x2, x3, x4, x5, x6, x7, x8, x9);
+}
+
void Problem::AddParameterBlock(double* values, int size) {
problem_impl_->AddParameterBlock(values, size);
}
@@ -116,6 +156,14 @@ void Problem::AddParameterBlock(double* values,
problem_impl_->AddParameterBlock(values, size, local_parameterization);
}
+void Problem::RemoveResidualBlock(ResidualBlockId residual_block) {
+ problem_impl_->RemoveResidualBlock(residual_block);
+}
+
+void Problem::RemoveParameterBlock(double* values) {
+ problem_impl_->RemoveParameterBlock(values);
+}
+
void Problem::SetParameterBlockConstant(double* values) {
problem_impl_->SetParameterBlockConstant(values);
}
@@ -130,6 +178,18 @@ void Problem::SetParameterization(
problem_impl_->SetParameterization(values, local_parameterization);
}
+bool Problem::Evaluate(const EvaluateOptions& evaluate_options,
+ double* cost,
+ vector<double>* residuals,
+ vector<double>* gradient,
+ CRSMatrix* jacobian) {
+ return problem_impl_->Evaluate(evaluate_options,
+ cost,
+ residuals,
+ gradient,
+ jacobian);
+}
+
int Problem::NumParameterBlocks() const {
return problem_impl_->NumParameterBlocks();
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
index c186f527be8..bc378aaafff 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
@@ -37,7 +37,11 @@
#include <string>
#include <utility>
#include <vector>
+#include "ceres/casts.h"
+#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/cost_function.h"
+#include "ceres/crs_matrix.h"
+#include "ceres/evaluator.h"
#include "ceres/loss_function.h"
#include "ceres/map_util.h"
#include "ceres/parameter_block.h"
@@ -73,54 +77,103 @@ static void CheckForNoAliasing(double* existing_block,
<< "size " << new_block_size << ".";
}
-static ParameterBlock* InternalAddParameterBlock(
- double* values,
- int size,
- ParameterMap* parameter_map,
- vector<ParameterBlock*>* parameter_blocks) {
- CHECK(values) << "Null pointer passed to AddParameterBlock for a parameter "
- << "with size " << size;
+ParameterBlock* ProblemImpl::InternalAddParameterBlock(double* values,
+ int size) {
+ CHECK(values != NULL) << "Null pointer passed to AddParameterBlock "
+ << "for a parameter with size " << size;
// Ignore the request if there is a block for the given pointer already.
- ParameterMap::iterator it = parameter_map->find(values);
- if (it != parameter_map->end()) {
- int existing_size = it->second->Size();
- CHECK(size == existing_size)
- << "Tried adding a parameter block with the same double pointer, "
- << values << ", twice, but with different block sizes. Original "
- << "size was " << existing_size << " but new size is "
- << size;
+ ParameterMap::iterator it = parameter_block_map_.find(values);
+ if (it != parameter_block_map_.end()) {
+ if (!options_.disable_all_safety_checks) {
+ int existing_size = it->second->Size();
+ CHECK(size == existing_size)
+ << "Tried adding a parameter block with the same double pointer, "
+ << values << ", twice, but with different block sizes. Original "
+ << "size was " << existing_size << " but new size is "
+ << size;
+ }
return it->second;
}
- // Before adding the parameter block, also check that it doesn't alias any
- // other parameter blocks.
- if (!parameter_map->empty()) {
- ParameterMap::iterator lb = parameter_map->lower_bound(values);
-
- // If lb is not the first block, check the previous block for aliasing.
- if (lb != parameter_map->begin()) {
- ParameterMap::iterator previous = lb;
- --previous;
- CheckForNoAliasing(previous->first,
- previous->second->Size(),
- values,
- size);
- }
- // If lb is not off the end, check lb for aliasing.
- if (lb != parameter_map->end()) {
- CheckForNoAliasing(lb->first,
- lb->second->Size(),
- values,
- size);
+ if (!options_.disable_all_safety_checks) {
+ // Before adding the parameter block, also check that it doesn't alias any
+ // other parameter blocks.
+ if (!parameter_block_map_.empty()) {
+ ParameterMap::iterator lb = parameter_block_map_.lower_bound(values);
+
+ // If lb is not the first block, check the previous block for aliasing.
+ if (lb != parameter_block_map_.begin()) {
+ ParameterMap::iterator previous = lb;
+ --previous;
+ CheckForNoAliasing(previous->first,
+ previous->second->Size(),
+ values,
+ size);
+ }
+
+ // If lb is not off the end, check lb for aliasing.
+ if (lb != parameter_block_map_.end()) {
+ CheckForNoAliasing(lb->first,
+ lb->second->Size(),
+ values,
+ size);
+ }
}
}
- ParameterBlock* new_parameter_block = new ParameterBlock(values, size);
- (*parameter_map)[values] = new_parameter_block;
- parameter_blocks->push_back(new_parameter_block);
+
+ // Pass the index of the new parameter block as well to keep the index in
+ // sync with the position of the parameter in the program's parameter vector.
+ ParameterBlock* new_parameter_block =
+ new ParameterBlock(values, size, program_->parameter_blocks_.size());
+
+ // For dynamic problems, add the list of dependent residual blocks, which is
+ // empty to start.
+ if (options_.enable_fast_parameter_block_removal) {
+ new_parameter_block->EnableResidualBlockDependencies();
+ }
+ parameter_block_map_[values] = new_parameter_block;
+ program_->parameter_blocks_.push_back(new_parameter_block);
return new_parameter_block;
}
+// Deletes the residual block in question, assuming there are no other
+// references to it inside the problem (e.g. by another parameter). Referenced
+// cost and loss functions are tucked away for future deletion, since it is not
+// possible to know whether other parts of the problem depend on them without
+// doing a full scan.
+void ProblemImpl::DeleteBlock(ResidualBlock* residual_block) {
+ // The const casts here are legit, since ResidualBlock holds these
+ // pointers as const pointers but we have ownership of them and
+ // have the right to destroy them when the destructor is called.
+ if (options_.cost_function_ownership == TAKE_OWNERSHIP &&
+ residual_block->cost_function() != NULL) {
+ cost_functions_to_delete_.push_back(
+ const_cast<CostFunction*>(residual_block->cost_function()));
+ }
+ if (options_.loss_function_ownership == TAKE_OWNERSHIP &&
+ residual_block->loss_function() != NULL) {
+ loss_functions_to_delete_.push_back(
+ const_cast<LossFunction*>(residual_block->loss_function()));
+ }
+ delete residual_block;
+}
+
+// Deletes the parameter block in question, assuming there are no other
+// references to it inside the problem (e.g. by any residual blocks).
+// Referenced parameterizations are tucked away for future deletion, since it
+// is not possible to know whether other parts of the problem depend on them
+// without doing a full scan.
+void ProblemImpl::DeleteBlock(ParameterBlock* parameter_block) {
+ if (options_.local_parameterization_ownership == TAKE_OWNERSHIP &&
+ parameter_block->local_parameterization() != NULL) {
+ local_parameterizations_to_delete_.push_back(
+ parameter_block->mutable_local_parameterization());
+ }
+ parameter_block_map_.erase(parameter_block->mutable_user_state());
+ delete parameter_block;
+}
+
ProblemImpl::ProblemImpl() : program_(new internal::Program) {}
ProblemImpl::ProblemImpl(const Problem::Options& options)
: options_(options),
@@ -128,48 +181,28 @@ ProblemImpl::ProblemImpl(const Problem::Options& options)
ProblemImpl::~ProblemImpl() {
// Collect the unique cost/loss functions and delete the residuals.
- set<CostFunction*> cost_functions;
- set<LossFunction*> loss_functions;
+ const int num_residual_blocks = program_->residual_blocks_.size();
+ cost_functions_to_delete_.reserve(num_residual_blocks);
+ loss_functions_to_delete_.reserve(num_residual_blocks);
for (int i = 0; i < program_->residual_blocks_.size(); ++i) {
- ResidualBlock* residual_block = program_->residual_blocks_[i];
-
- // The const casts here are legit, since ResidualBlock holds these
- // pointers as const pointers but we have ownership of them and
- // have the right to destroy them when the destructor is called.
- if (options_.cost_function_ownership == TAKE_OWNERSHIP) {
- cost_functions.insert(
- const_cast<CostFunction*>(residual_block->cost_function()));
- }
- if (options_.loss_function_ownership == TAKE_OWNERSHIP) {
- loss_functions.insert(
- const_cast<LossFunction*>(residual_block->loss_function()));
- }
-
- delete residual_block;
+ DeleteBlock(program_->residual_blocks_[i]);
}
// Collect the unique parameterizations and delete the parameters.
- set<LocalParameterization*> local_parameterizations;
for (int i = 0; i < program_->parameter_blocks_.size(); ++i) {
- ParameterBlock* parameter_block = program_->parameter_blocks_[i];
-
- if (options_.local_parameterization_ownership == TAKE_OWNERSHIP) {
- local_parameterizations.insert(parameter_block->local_parameterization_);
- }
-
- delete parameter_block;
+ DeleteBlock(program_->parameter_blocks_[i]);
}
// Delete the owned cost/loss functions and parameterizations.
- STLDeleteContainerPointers(local_parameterizations.begin(),
- local_parameterizations.end());
- STLDeleteContainerPointers(cost_functions.begin(),
- cost_functions.end());
- STLDeleteContainerPointers(loss_functions.begin(),
- loss_functions.end());
+ STLDeleteUniqueContainerPointers(local_parameterizations_to_delete_.begin(),
+ local_parameterizations_to_delete_.end());
+ STLDeleteUniqueContainerPointers(cost_functions_to_delete_.begin(),
+ cost_functions_to_delete_.end());
+ STLDeleteUniqueContainerPointers(loss_functions_to_delete_.begin(),
+ loss_functions_to_delete_.end());
}
-const ResidualBlock* ProblemImpl::AddResidualBlock(
+ResidualBlock* ProblemImpl::AddResidualBlock(
CostFunction* cost_function,
LossFunction* loss_function,
const vector<double*>& parameter_blocks) {
@@ -180,25 +213,28 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
// Check the sizes match.
const vector<int16>& parameter_block_sizes =
cost_function->parameter_block_sizes();
- CHECK_EQ(parameter_block_sizes.size(), parameter_blocks.size())
- << "Number of blocks input is different than the number of blocks "
- << "that the cost function expects.";
-
- // Check for duplicate parameter blocks.
- vector<double*> sorted_parameter_blocks(parameter_blocks);
- sort(sorted_parameter_blocks.begin(), sorted_parameter_blocks.end());
- vector<double*>::const_iterator duplicate_items =
- unique(sorted_parameter_blocks.begin(),
- sorted_parameter_blocks.end());
- if (duplicate_items != sorted_parameter_blocks.end()) {
- string blocks;
- for (int i = 0; i < parameter_blocks.size(); ++i) {
- blocks += internal::StringPrintf(" %p ", parameter_blocks[i]);
- }
- LOG(FATAL) << "Duplicate parameter blocks in a residual parameter "
- << "are not allowed. Parameter block pointers: ["
- << blocks << "]";
+ if (!options_.disable_all_safety_checks) {
+ CHECK_EQ(parameter_block_sizes.size(), parameter_blocks.size())
+ << "Number of blocks input is different than the number of blocks "
+ << "that the cost function expects.";
+
+ // Check for duplicate parameter blocks.
+ vector<double*> sorted_parameter_blocks(parameter_blocks);
+ sort(sorted_parameter_blocks.begin(), sorted_parameter_blocks.end());
+ vector<double*>::const_iterator duplicate_items =
+ unique(sorted_parameter_blocks.begin(),
+ sorted_parameter_blocks.end());
+ if (duplicate_items != sorted_parameter_blocks.end()) {
+ string blocks;
+ for (int i = 0; i < parameter_blocks.size(); ++i) {
+ blocks += StringPrintf(" %p ", parameter_blocks[i]);
+ }
+
+ LOG(FATAL) << "Duplicate parameter blocks in a residual parameter "
+ << "are not allowed. Parameter block pointers: ["
+ << blocks << "]";
+ }
}
// Add parameter blocks and convert the double*'s to parameter blocks.
@@ -206,33 +242,42 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
for (int i = 0; i < parameter_blocks.size(); ++i) {
parameter_block_ptrs[i] =
InternalAddParameterBlock(parameter_blocks[i],
- parameter_block_sizes[i],
- &parameter_block_map_,
- &program_->parameter_blocks_);
+ parameter_block_sizes[i]);
}
- // Check that the block sizes match the block sizes expected by the
- // cost_function.
- for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
- CHECK_EQ(cost_function->parameter_block_sizes()[i],
- parameter_block_ptrs[i]->Size())
- << "The cost function expects parameter block " << i
- << " of size " << cost_function->parameter_block_sizes()[i]
- << " but was given a block of size "
- << parameter_block_ptrs[i]->Size();
+ if (!options_.disable_all_safety_checks) {
+ // Check that the block sizes match the block sizes expected by the
+ // cost_function.
+ for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
+ CHECK_EQ(cost_function->parameter_block_sizes()[i],
+ parameter_block_ptrs[i]->Size())
+ << "The cost function expects parameter block " << i
+ << " of size " << cost_function->parameter_block_sizes()[i]
+ << " but was given a block of size "
+ << parameter_block_ptrs[i]->Size();
+ }
}
ResidualBlock* new_residual_block =
new ResidualBlock(cost_function,
loss_function,
- parameter_block_ptrs);
+ parameter_block_ptrs,
+ program_->residual_blocks_.size());
+
+ // Add dependencies on the residual to the parameter blocks.
+ if (options_.enable_fast_parameter_block_removal) {
+ for (int i = 0; i < parameter_blocks.size(); ++i) {
+ parameter_block_ptrs[i]->AddResidualBlock(new_residual_block);
+ }
+ }
+
program_->residual_blocks_.push_back(new_residual_block);
return new_residual_block;
}
// Unfortunately, macros don't help much to reduce this code, and var args don't
// work because of the ambiguous case that there is no loss function.
-const ResidualBlock* ProblemImpl::AddResidualBlock(
+ResidualBlock* ProblemImpl::AddResidualBlock(
CostFunction* cost_function,
LossFunction* loss_function,
double* x0) {
@@ -241,7 +286,7 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
return AddResidualBlock(cost_function, loss_function, residual_parameters);
}
-const ResidualBlock* ProblemImpl::AddResidualBlock(
+ResidualBlock* ProblemImpl::AddResidualBlock(
CostFunction* cost_function,
LossFunction* loss_function,
double* x0, double* x1) {
@@ -251,7 +296,7 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
return AddResidualBlock(cost_function, loss_function, residual_parameters);
}
-const ResidualBlock* ProblemImpl::AddResidualBlock(
+ResidualBlock* ProblemImpl::AddResidualBlock(
CostFunction* cost_function,
LossFunction* loss_function,
double* x0, double* x1, double* x2) {
@@ -262,7 +307,7 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
return AddResidualBlock(cost_function, loss_function, residual_parameters);
}
-const ResidualBlock* ProblemImpl::AddResidualBlock(
+ResidualBlock* ProblemImpl::AddResidualBlock(
CostFunction* cost_function,
LossFunction* loss_function,
double* x0, double* x1, double* x2, double* x3) {
@@ -274,7 +319,7 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
return AddResidualBlock(cost_function, loss_function, residual_parameters);
}
-const ResidualBlock* ProblemImpl::AddResidualBlock(
+ResidualBlock* ProblemImpl::AddResidualBlock(
CostFunction* cost_function,
LossFunction* loss_function,
double* x0, double* x1, double* x2, double* x3, double* x4) {
@@ -287,7 +332,7 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
return AddResidualBlock(cost_function, loss_function, residual_parameters);
}
-const ResidualBlock* ProblemImpl::AddResidualBlock(
+ResidualBlock* ProblemImpl::AddResidualBlock(
CostFunction* cost_function,
LossFunction* loss_function,
double* x0, double* x1, double* x2, double* x3, double* x4, double* x5) {
@@ -301,12 +346,78 @@ const ResidualBlock* ProblemImpl::AddResidualBlock(
return AddResidualBlock(cost_function, loss_function, residual_parameters);
}
+ResidualBlock* ProblemImpl::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6) {
+ vector<double*> residual_parameters;
+ residual_parameters.push_back(x0);
+ residual_parameters.push_back(x1);
+ residual_parameters.push_back(x2);
+ residual_parameters.push_back(x3);
+ residual_parameters.push_back(x4);
+ residual_parameters.push_back(x5);
+ residual_parameters.push_back(x6);
+ return AddResidualBlock(cost_function, loss_function, residual_parameters);
+}
+
+ResidualBlock* ProblemImpl::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6, double* x7) {
+ vector<double*> residual_parameters;
+ residual_parameters.push_back(x0);
+ residual_parameters.push_back(x1);
+ residual_parameters.push_back(x2);
+ residual_parameters.push_back(x3);
+ residual_parameters.push_back(x4);
+ residual_parameters.push_back(x5);
+ residual_parameters.push_back(x6);
+ residual_parameters.push_back(x7);
+ return AddResidualBlock(cost_function, loss_function, residual_parameters);
+}
+
+ResidualBlock* ProblemImpl::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8) {
+ vector<double*> residual_parameters;
+ residual_parameters.push_back(x0);
+ residual_parameters.push_back(x1);
+ residual_parameters.push_back(x2);
+ residual_parameters.push_back(x3);
+ residual_parameters.push_back(x4);
+ residual_parameters.push_back(x5);
+ residual_parameters.push_back(x6);
+ residual_parameters.push_back(x7);
+ residual_parameters.push_back(x8);
+ return AddResidualBlock(cost_function, loss_function, residual_parameters);
+}
+
+ResidualBlock* ProblemImpl::AddResidualBlock(
+ CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8, double* x9) {
+ vector<double*> residual_parameters;
+ residual_parameters.push_back(x0);
+ residual_parameters.push_back(x1);
+ residual_parameters.push_back(x2);
+ residual_parameters.push_back(x3);
+ residual_parameters.push_back(x4);
+ residual_parameters.push_back(x5);
+ residual_parameters.push_back(x6);
+ residual_parameters.push_back(x7);
+ residual_parameters.push_back(x8);
+ residual_parameters.push_back(x9);
+ return AddResidualBlock(cost_function, loss_function, residual_parameters);
+}
void ProblemImpl::AddParameterBlock(double* values, int size) {
- InternalAddParameterBlock(values,
- size,
- &parameter_block_map_,
- &program_->parameter_blocks_);
+ InternalAddParameterBlock(values, size);
}
void ProblemImpl::AddParameterBlock(
@@ -314,15 +425,83 @@ void ProblemImpl::AddParameterBlock(
int size,
LocalParameterization* local_parameterization) {
ParameterBlock* parameter_block =
- InternalAddParameterBlock(values,
- size,
- &parameter_block_map_,
- &program_->parameter_blocks_);
+ InternalAddParameterBlock(values, size);
if (local_parameterization != NULL) {
parameter_block->SetParameterization(local_parameterization);
}
}
+// Delete a block from a vector of blocks, maintaining the indexing invariant.
+// This is done in constant time by moving an element from the end of the
+// vector over the element to remove, then popping the last element. It
+// destroys the ordering in the interest of speed.
+template<typename Block>
+void ProblemImpl::DeleteBlockInVector(vector<Block*>* mutable_blocks,
+ Block* block_to_remove) {
+ CHECK_EQ((*mutable_blocks)[block_to_remove->index()], block_to_remove)
+ << "You found a Ceres bug! Block: " << block_to_remove->ToString();
+
+ // Prepare the to-be-moved block for the new, lower-in-index position by
+ // setting the index to the blocks final location.
+ Block* tmp = mutable_blocks->back();
+ tmp->set_index(block_to_remove->index());
+
+ // Overwrite the to-be-deleted residual block with the one at the end.
+ (*mutable_blocks)[block_to_remove->index()] = tmp;
+
+ DeleteBlock(block_to_remove);
+
+ // The block is gone so shrink the vector of blocks accordingly.
+ mutable_blocks->pop_back();
+}
+
+void ProblemImpl::RemoveResidualBlock(ResidualBlock* residual_block) {
+ CHECK_NOTNULL(residual_block);
+
+ // If needed, remove the parameter dependencies on this residual block.
+ if (options_.enable_fast_parameter_block_removal) {
+ const int num_parameter_blocks_for_residual =
+ residual_block->NumParameterBlocks();
+ for (int i = 0; i < num_parameter_blocks_for_residual; ++i) {
+ residual_block->parameter_blocks()[i]
+ ->RemoveResidualBlock(residual_block);
+ }
+ }
+ DeleteBlockInVector(program_->mutable_residual_blocks(), residual_block);
+}
+
+void ProblemImpl::RemoveParameterBlock(double* values) {
+ ParameterBlock* parameter_block = FindOrDie(parameter_block_map_, values);
+
+ if (options_.enable_fast_parameter_block_removal) {
+ // Copy the dependent residuals from the parameter block because the set of
+ // dependents will change after each call to RemoveResidualBlock().
+ vector<ResidualBlock*> residual_blocks_to_remove(
+ parameter_block->mutable_residual_blocks()->begin(),
+ parameter_block->mutable_residual_blocks()->end());
+ for (int i = 0; i < residual_blocks_to_remove.size(); ++i) {
+ RemoveResidualBlock(residual_blocks_to_remove[i]);
+ }
+ } else {
+ // Scan all the residual blocks to remove ones that depend on the parameter
+ // block. Do the scan backwards since the vector changes while iterating.
+ const int num_residual_blocks = NumResidualBlocks();
+ for (int i = num_residual_blocks - 1; i >= 0; --i) {
+ ResidualBlock* residual_block =
+ (*(program_->mutable_residual_blocks()))[i];
+ const int num_parameter_blocks = residual_block->NumParameterBlocks();
+ for (int j = 0; j < num_parameter_blocks; ++j) {
+ if (residual_block->parameter_blocks()[j] == parameter_block) {
+ RemoveResidualBlock(residual_block);
+ // The parameter blocks are guaranteed unique.
+ break;
+ }
+ }
+ }
+ }
+ DeleteBlockInVector(program_->mutable_parameter_blocks(), parameter_block);
+}
+
void ProblemImpl::SetParameterBlockConstant(double* values) {
FindOrDie(parameter_block_map_, values)->SetConstant();
}
@@ -338,6 +517,164 @@ void ProblemImpl::SetParameterization(
->SetParameterization(local_parameterization);
}
+bool ProblemImpl::Evaluate(const Problem::EvaluateOptions& evaluate_options,
+ double* cost,
+ vector<double>* residuals,
+ vector<double>* gradient,
+ CRSMatrix* jacobian) {
+ if (cost == NULL &&
+ residuals == NULL &&
+ gradient == NULL &&
+ jacobian == NULL) {
+ LOG(INFO) << "Nothing to do.";
+ return true;
+ }
+
+ // If the user supplied residual blocks, then use them, otherwise
+ // take the residual blocks from the underlying program.
+ Program program;
+ *program.mutable_residual_blocks() =
+ ((evaluate_options.residual_blocks.size() > 0)
+ ? evaluate_options.residual_blocks : program_->residual_blocks());
+
+ const vector<double*>& parameter_block_ptrs =
+ evaluate_options.parameter_blocks;
+
+ vector<ParameterBlock*> variable_parameter_blocks;
+ vector<ParameterBlock*>& parameter_blocks =
+ *program.mutable_parameter_blocks();
+
+ if (parameter_block_ptrs.size() == 0) {
+ // The user did not provide any parameter blocks, so default to
+ // using all the parameter blocks in the order that they are in
+ // the underlying program object.
+ parameter_blocks = program_->parameter_blocks();
+ } else {
+ // The user supplied a vector of parameter blocks. Using this list
+ // requires a number of steps.
+
+ // 1. Convert double* into ParameterBlock*
+ parameter_blocks.resize(parameter_block_ptrs.size());
+ for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
+ parameter_blocks[i] =
+ FindOrDie(parameter_block_map_, parameter_block_ptrs[i]);
+ }
+
+ // 2. The user may have only supplied a subset of parameter
+ // blocks, so identify the ones that are not supplied by the user
+ // and are NOT constant. These parameter blocks are stored in
+ // variable_parameter_blocks.
+ //
+ // To ensure that the parameter blocks are not included in the
+ // columns of the jacobian, we need to make sure that they are
+ // constant during evaluation and then make them variable again
+ // after we are done.
+ vector<ParameterBlock*> all_parameter_blocks(program_->parameter_blocks());
+ vector<ParameterBlock*> included_parameter_blocks(
+ program.parameter_blocks());
+
+ vector<ParameterBlock*> excluded_parameter_blocks;
+ sort(all_parameter_blocks.begin(), all_parameter_blocks.end());
+ sort(included_parameter_blocks.begin(), included_parameter_blocks.end());
+ set_difference(all_parameter_blocks.begin(),
+ all_parameter_blocks.end(),
+ included_parameter_blocks.begin(),
+ included_parameter_blocks.end(),
+ back_inserter(excluded_parameter_blocks));
+
+ variable_parameter_blocks.reserve(excluded_parameter_blocks.size());
+ for (int i = 0; i < excluded_parameter_blocks.size(); ++i) {
+ ParameterBlock* parameter_block = excluded_parameter_blocks[i];
+ if (!parameter_block->IsConstant()) {
+ variable_parameter_blocks.push_back(parameter_block);
+ parameter_block->SetConstant();
+ }
+ }
+ }
+
+ // Setup the Parameter indices and offsets before an evaluator can
+ // be constructed and used.
+ program.SetParameterOffsetsAndIndex();
+
+ Evaluator::Options evaluator_options;
+
+ // Even though using SPARSE_NORMAL_CHOLESKY requires SuiteSparse or
+ // CXSparse, here it just being used for telling the evaluator to
+ // use a SparseRowCompressedMatrix for the jacobian. This is because
+ // the Evaluator decides the storage for the Jacobian based on the
+ // type of linear solver being used.
+ evaluator_options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+ evaluator_options.num_threads = evaluate_options.num_threads;
+
+ string error;
+ scoped_ptr<Evaluator> evaluator(
+ Evaluator::Create(evaluator_options, &program, &error));
+ if (evaluator.get() == NULL) {
+ LOG(ERROR) << "Unable to create an Evaluator object. "
+ << "Error: " << error
+ << "This is a Ceres bug; please contact the developers!";
+
+ // Make the parameter blocks that were temporarily marked
+ // constant, variable again.
+ for (int i = 0; i < variable_parameter_blocks.size(); ++i) {
+ variable_parameter_blocks[i]->SetVarying();
+ }
+ return false;
+ }
+
+ if (residuals !=NULL) {
+ residuals->resize(evaluator->NumResiduals());
+ }
+
+ if (gradient != NULL) {
+ gradient->resize(evaluator->NumEffectiveParameters());
+ }
+
+ scoped_ptr<CompressedRowSparseMatrix> tmp_jacobian;
+ if (jacobian != NULL) {
+ tmp_jacobian.reset(
+ down_cast<CompressedRowSparseMatrix*>(evaluator->CreateJacobian()));
+ }
+
+ // Point the state pointers to the user state pointers. This is
+ // needed so that we can extract a parameter vector which is then
+ // passed to Evaluator::Evaluate.
+ program.SetParameterBlockStatePtrsToUserStatePtrs();
+
+ // Copy the value of the parameter blocks into a vector, since the
+ // Evaluate::Evaluate method needs its input as such. The previous
+ // call to SetParameterBlockStatePtrsToUserStatePtrs ensures that
+ // these values are the ones corresponding to the actual state of
+ // the parameter blocks, rather than the temporary state pointer
+ // used for evaluation.
+ Vector parameters(program.NumParameters());
+ program.ParameterBlocksToStateVector(parameters.data());
+
+ double tmp_cost = 0;
+ bool status = evaluator->Evaluate(parameters.data(),
+ &tmp_cost,
+ residuals != NULL ? &(*residuals)[0] : NULL,
+ gradient != NULL ? &(*gradient)[0] : NULL,
+ tmp_jacobian.get());
+
+ // Make the parameter blocks that were temporarirly marked
+ // constant, variable again.
+ for (int i = 0; i < variable_parameter_blocks.size(); ++i) {
+ variable_parameter_blocks[i]->SetVarying();
+ }
+
+ if (status) {
+ if (cost != NULL) {
+ *cost = tmp_cost;
+ }
+ if (jacobian != NULL) {
+ tmp_jacobian->ToCRSMatrix(jacobian);
+ }
+ }
+
+ return status;
+}
+
int ProblemImpl::NumParameterBlocks() const {
return program_->NumParameterBlocks();
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h
index 2ca055448c3..ccc315de6b6 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h
@@ -53,6 +53,7 @@ namespace ceres {
class CostFunction;
class LossFunction;
class LocalParameterization;
+struct CRSMatrix;
namespace internal {
@@ -93,14 +94,46 @@ class ProblemImpl {
LossFunction* loss_function,
double* x0, double* x1, double* x2,
double* x3, double* x4, double* x5);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6, double* x7);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8);
+ ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+ LossFunction* loss_function,
+ double* x0, double* x1, double* x2,
+ double* x3, double* x4, double* x5,
+ double* x6, double* x7, double* x8,
+ double* x9);
void AddParameterBlock(double* values, int size);
void AddParameterBlock(double* values,
int size,
LocalParameterization* local_parameterization);
+
+ void RemoveResidualBlock(ResidualBlock* residual_block);
+ void RemoveParameterBlock(double* values);
+
void SetParameterBlockConstant(double* values);
void SetParameterBlockVariable(double* values);
void SetParameterization(double* values,
LocalParameterization* local_parameterization);
+
+ bool Evaluate(const Problem::EvaluateOptions& options,
+ double* cost,
+ vector<double>* residuals,
+ vector<double>* gradient,
+ CRSMatrix* jacobian);
+
int NumParameterBlocks() const;
int NumParameters() const;
int NumResidualBlocks() const;
@@ -112,12 +145,41 @@ class ProblemImpl {
const ParameterMap& parameter_map() const { return parameter_block_map_; }
private:
+ ParameterBlock* InternalAddParameterBlock(double* values, int size);
+
+ bool InternalEvaluate(Program* program,
+ double* cost,
+ vector<double>* residuals,
+ vector<double>* gradient,
+ CRSMatrix* jacobian);
+
+ // Delete the arguments in question. These differ from the Remove* functions
+ // in that they do not clean up references to the block to delete; they
+ // merely delete them.
+ template<typename Block>
+ void DeleteBlockInVector(vector<Block*>* mutable_blocks,
+ Block* block_to_remove);
+ void DeleteBlock(ResidualBlock* residual_block);
+ void DeleteBlock(ParameterBlock* parameter_block);
+
const Problem::Options options_;
// The mapping from user pointers to parameter blocks.
map<double*, ParameterBlock*> parameter_block_map_;
+ // The actual parameter and residual blocks.
internal::scoped_ptr<internal::Program> program_;
+
+ // When removing residual and parameter blocks, cost/loss functions and
+ // parameterizations have ambiguous ownership. Instead of scanning the entire
+ // problem to see if the cost/loss/parameterization is shared with other
+ // residual or parameter blocks, buffer them until destruction.
+ //
+ // TODO(keir): See if it makes sense to use sets instead.
+ vector<CostFunction*> cost_functions_to_delete_;
+ vector<LossFunction*> loss_functions_to_delete_;
+ vector<LocalParameterization*> local_parameterizations_to_delete_;
+
CERES_DISALLOW_COPY_AND_ASSIGN(ProblemImpl);
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h b/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h
index 6c48e7d7643..a19cdf8a86a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h
@@ -83,11 +83,14 @@
#include <omp.h>
#endif
+#include <map>
+#include <vector>
+#include "ceres/execution_summary.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/scoped_ptr.h"
#include "ceres/parameter_block.h"
#include "ceres/program.h"
#include "ceres/residual_block.h"
-#include "ceres/internal/eigen.h"
-#include "ceres/internal/scoped_ptr.h"
namespace ceres {
namespace internal {
@@ -122,6 +125,12 @@ class ProgramEvaluator : public Evaluator {
double* residuals,
double* gradient,
SparseMatrix* jacobian) {
+ ScopedExecutionTimer total_timer("Evaluator::Total", &execution_summary_);
+ ScopedExecutionTimer call_type_timer(gradient == NULL && jacobian == NULL
+ ? "Evaluator::Residual"
+ : "Evaluator::Jacobian",
+ &execution_summary_);
+
// The parameters are stateful, so set the state before evaluating.
if (!program_->StateVectorToParameterBlocks(state)) {
return false;
@@ -129,7 +138,7 @@ class ProgramEvaluator : public Evaluator {
if (residuals != NULL) {
VectorRef(residuals, program_->NumResiduals()).setZero();
- }
+ }
if (jacobian != NULL) {
jacobian->SetZero();
@@ -138,6 +147,10 @@ class ProgramEvaluator : public Evaluator {
// Each thread gets it's own cost and evaluate scratch space.
for (int i = 0; i < options_.num_threads; ++i) {
evaluate_scratch_[i].cost = 0.0;
+ if (gradient != NULL) {
+ VectorRef(evaluate_scratch_[i].gradient.get(),
+ program_->NumEffectiveParameters()).setZero();
+ }
}
// This bool is used to disable the loop if an error is encountered
@@ -262,6 +275,14 @@ class ProgramEvaluator : public Evaluator {
return program_->NumResiduals();
}
+ virtual map<string, int> CallStatistics() const {
+ return execution_summary_.calls();
+ }
+
+ virtual map<string, double> TimeStatistics() const {
+ return execution_summary_.times();
+ }
+
private:
// Per-thread scratch space needed to evaluate and store each residual block.
struct EvaluateScratch {
@@ -327,6 +348,7 @@ class ProgramEvaluator : public Evaluator {
scoped_array<EvaluatePreparer> evaluate_preparers_;
scoped_array<EvaluateScratch> evaluate_scratch_;
vector<int> residual_layout_;
+ ::ceres::internal::ExecutionSummary execution_summary_;
};
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc b/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc
index bdb88b1dd97..7f789605e5f 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc
@@ -49,12 +49,14 @@ namespace internal {
ResidualBlock::ResidualBlock(const CostFunction* cost_function,
const LossFunction* loss_function,
- const vector<ParameterBlock*>& parameter_blocks)
+ const vector<ParameterBlock*>& parameter_blocks,
+ int index)
: cost_function_(cost_function),
loss_function_(loss_function),
parameter_blocks_(
new ParameterBlock* [
- cost_function->parameter_block_sizes().size()]) {
+ cost_function->parameter_block_sizes().size()]),
+ index_(index) {
std::copy(parameter_blocks.begin(),
parameter_blocks.end(),
parameter_blocks_.get());
diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block.h b/extern/libmv/third_party/ceres/internal/ceres/residual_block.h
index e0a06e78958..3921d1d4678 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/residual_block.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block.h
@@ -34,11 +34,13 @@
#ifndef CERES_INTERNAL_RESIDUAL_BLOCK_H_
#define CERES_INTERNAL_RESIDUAL_BLOCK_H_
+#include <string>
#include <vector>
#include "ceres/cost_function.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
+#include "ceres/stringprintf.h"
#include "ceres/types.h"
namespace ceres {
@@ -64,9 +66,13 @@ class ParameterBlock;
// loss functions, and parameter blocks.
class ResidualBlock {
public:
+ // Construct the residual block with the given cost/loss functions. Loss may
+ // be null. The index is the index of the residual block in the Program's
+ // residual_blocks array.
ResidualBlock(const CostFunction* cost_function,
const LossFunction* loss_function,
- const vector<ParameterBlock*>& parameter_blocks);
+ const vector<ParameterBlock*>& parameter_blocks,
+ int index);
// Evaluates the residual term, storing the scalar cost in *cost, the residual
// components in *residuals, and the jacobians between the parameters and
@@ -112,10 +118,23 @@ class ResidualBlock {
// The minimum amount of scratch space needed to pass to Evaluate().
int NumScratchDoublesForEvaluate() const;
+ // This residual block's index in an array.
+ int index() const { return index_; }
+ void set_index(int index) { index_ = index; }
+
+ string ToString() {
+ return StringPrintf("{residual block; index=%d}", index_);
+ }
+
private:
const CostFunction* cost_function_;
const LossFunction* loss_function_;
scoped_array<ParameterBlock*> parameter_blocks_;
+
+ // The index of the residual, typically in a Program. This is only to permit
+ // switching from a ResidualBlock* to an index in the Program's array, needed
+ // to do efficient removals.
+ int32 index_;
};
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc b/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc
index 9442bb2a1c1..4d88a9f4f8a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block_utils.cc
@@ -63,7 +63,8 @@ void InvalidateEvaluation(const ResidualBlock& block,
// Utility routine to print an array of doubles to a string. If the
// array pointer is NULL, it is treated as an array of zeros.
-static void AppendArrayToString(const int size, const double* x, string* result) {
+namespace {
+void AppendArrayToString(const int size, const double* x, string* result) {
for (int i = 0; i < size; ++i) {
if (x == NULL) {
StringAppendF(result, "Not Computed ");
@@ -76,6 +77,7 @@ static void AppendArrayToString(const int size, const double* x, string* result)
}
}
}
+} // namespace
string EvaluationToString(const ResidualBlock& block,
double const* const* parameters,
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc
index 2cbe78d133a..17537596c75 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc
@@ -38,22 +38,21 @@
#endif // CERES_NO_CXSPARSE
#include "Eigen/Dense"
-#include "glog/logging.h"
#include "ceres/block_random_access_dense_matrix.h"
#include "ceres/block_random_access_matrix.h"
#include "ceres/block_random_access_sparse_matrix.h"
#include "ceres/block_sparse_matrix.h"
#include "ceres/block_structure.h"
#include "ceres/detect_structure.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/internal/scoped_ptr.h"
#include "ceres/linear_solver.h"
#include "ceres/schur_complement_solver.h"
#include "ceres/suitesparse.h"
#include "ceres/triplet_sparse_matrix.h"
-#include "ceres/internal/eigen.h"
-#include "ceres/internal/port.h"
-#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
-
+#include "ceres/wall_time.h"
namespace ceres {
namespace internal {
@@ -63,43 +62,39 @@ LinearSolver::Summary SchurComplementSolver::SolveImpl(
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) {
- const time_t start_time = time(NULL);
+ EventLogger event_logger("SchurComplementSolver::Solve");
+
if (eliminator_.get() == NULL) {
InitStorage(A->block_structure());
DetectStructure(*A->block_structure(),
- options_.num_eliminate_blocks,
+ options_.elimination_groups[0],
&options_.row_block_size,
&options_.e_block_size,
&options_.f_block_size);
eliminator_.reset(CHECK_NOTNULL(SchurEliminatorBase::Create(options_)));
- eliminator_->Init(options_.num_eliminate_blocks, A->block_structure());
+ eliminator_->Init(options_.elimination_groups[0], A->block_structure());
};
- const time_t init_time = time(NULL);
fill(x, x + A->num_cols(), 0.0);
+ event_logger.AddEvent("Setup");
LinearSolver::Summary summary;
summary.num_iterations = 1;
summary.termination_type = FAILURE;
eliminator_->Eliminate(A, b, per_solve_options.D, lhs_.get(), rhs_.get());
- const time_t eliminate_time = time(NULL);
+ event_logger.AddEvent("Eliminate");
double* reduced_solution = x + A->num_cols() - lhs_->num_cols();
const bool status = SolveReducedLinearSystem(reduced_solution);
- const time_t solve_time = time(NULL);
+ event_logger.AddEvent("ReducedSolve");
if (!status) {
return summary;
}
eliminator_->BackSubstitute(A, b, per_solve_options.D, reduced_solution, x);
- const time_t backsubstitute_time = time(NULL);
summary.termination_type = TOLERANCE;
- VLOG(2) << "time (sec) total: " << (backsubstitute_time - start_time)
- << " init: " << (init_time - start_time)
- << " eliminate: " << (eliminate_time - init_time)
- << " solve: " << (solve_time - eliminate_time)
- << " backsubstitute: " << (backsubstitute_time - solve_time);
+ event_logger.AddEvent("BackSubstitute");
return summary;
}
@@ -107,7 +102,7 @@ LinearSolver::Summary SchurComplementSolver::SolveImpl(
// complement.
void DenseSchurComplementSolver::InitStorage(
const CompressedRowBlockStructure* bs) {
- const int num_eliminate_blocks = options().num_eliminate_blocks;
+ const int num_eliminate_blocks = options().elimination_groups[0];
const int num_col_blocks = bs->cols.size();
vector<int> blocks(num_col_blocks - num_eliminate_blocks, 0);
@@ -179,7 +174,7 @@ SparseSchurComplementSolver::~SparseSchurComplementSolver() {
// initialize a BlockRandomAccessSparseMatrix object.
void SparseSchurComplementSolver::InitStorage(
const CompressedRowBlockStructure* bs) {
- const int num_eliminate_blocks = options().num_eliminate_blocks;
+ const int num_eliminate_blocks = options().elimination_groups[0];
const int num_col_blocks = bs->cols.size();
const int num_row_blocks = bs->rows.size();
@@ -268,8 +263,6 @@ bool SparseSchurComplementSolver::SolveReducedLinearSystem(double* solution) {
// CHOLMOD's sparse cholesky factorization routines.
bool SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
double* solution) {
- const time_t start_time = time(NULL);
-
TripletSparseMatrix* tsm =
const_cast<TripletSparseMatrix*>(
down_cast<const BlockRandomAccessSparseMatrix*>(lhs())->matrix());
@@ -286,11 +279,9 @@ bool SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
// The matrix is symmetric, and the upper triangular part of the
// matrix contains the values.
cholmod_lhs->stype = 1;
- const time_t lhs_time = time(NULL);
cholmod_dense* cholmod_rhs =
ss_.CreateDenseVector(const_cast<double*>(rhs()), num_rows, num_rows);
- const time_t rhs_time = time(NULL);
// Symbolic factorization is computed if we don't already have one handy.
if (factor_ == NULL) {
@@ -307,32 +298,22 @@ bool SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
CHECK_NOTNULL(factor_);
- const time_t symbolic_time = time(NULL);
cholmod_dense* cholmod_solution =
ss_.SolveCholesky(cholmod_lhs, factor_, cholmod_rhs);
- const time_t solve_time = time(NULL);
-
ss_.Free(cholmod_lhs);
cholmod_lhs = NULL;
ss_.Free(cholmod_rhs);
cholmod_rhs = NULL;
if (cholmod_solution == NULL) {
- LOG(ERROR) << "CHOLMOD solve failed.";
+ LOG(WARNING) << "CHOLMOD solve failed.";
return false;
}
VectorRef(solution, num_rows)
= VectorRef(static_cast<double*>(cholmod_solution->x), num_rows);
ss_.Free(cholmod_solution);
- const time_t final_time = time(NULL);
- VLOG(2) << "time: " << (final_time - start_time)
- << " lhs : " << (lhs_time - start_time)
- << " rhs: " << (rhs_time - lhs_time)
- << " analyze: " << (symbolic_time - rhs_time)
- << " factor_and_solve: " << (solve_time - symbolic_time)
- << " cleanup: " << (final_time - solve_time);
return true;
}
#else
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h
index ea1b3184c33..7e98f316255 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h
@@ -33,6 +33,7 @@
#include <set>
#include <utility>
+#include <vector>
#include "ceres/block_random_access_matrix.h"
#include "ceres/block_sparse_matrix.h"
@@ -97,13 +98,14 @@ class BlockSparseMatrixBase;
// The two solvers can be instantiated by calling
// LinearSolver::CreateLinearSolver with LinearSolver::Options::type
// set to DENSE_SCHUR and SPARSE_SCHUR
-// respectively. LinearSolver::Options::num_eliminate_blocks should be
+// respectively. LinearSolver::Options::elimination_groups[0] should be
// at least 1.
class SchurComplementSolver : public BlockSparseMatrixBaseSolver {
public:
explicit SchurComplementSolver(const LinearSolver::Options& options)
: options_(options) {
- CHECK_GT(options.num_eliminate_blocks, 0);
+ CHECK_GT(options.elimination_groups.size(), 1);
+ CHECK_GT(options.elimination_groups[0], 0);
}
// LinearSolver methods
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h
index 6120db9b009..339c44bc41c 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h
@@ -50,7 +50,6 @@
#include <algorithm>
#include <map>
-#include <glog/logging.h>
#include "Eigen/Dense"
#include "ceres/block_random_access_matrix.h"
#include "ceres/block_sparse_matrix.h"
@@ -60,6 +59,7 @@
#include "ceres/stl_util.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/scoped_ptr.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc
new file mode 100644
index 00000000000..33a666ed037
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc
@@ -0,0 +1,145 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/schur_jacobi_preconditioner.h"
+
+#include <utility>
+#include <vector>
+#include "Eigen/Dense"
+#include "ceres/block_random_access_sparse_matrix.h"
+#include "ceres/block_sparse_matrix.h"
+#include "ceres/collections_port.h"
+#include "ceres/detect_structure.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/linear_solver.h"
+#include "ceres/schur_eliminator.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+SchurJacobiPreconditioner::SchurJacobiPreconditioner(
+ const CompressedRowBlockStructure& bs,
+ const Preconditioner::Options& options)
+ : options_(options) {
+ CHECK_GT(options_.elimination_groups.size(), 1);
+ CHECK_GT(options_.elimination_groups[0], 0);
+ const int num_blocks = bs.cols.size() - options_.elimination_groups[0];
+ CHECK_GT(num_blocks, 0)
+ << "Jacobian should have atleast 1 f_block for "
+ << "SCHUR_JACOBI preconditioner.";
+
+ block_size_.resize(num_blocks);
+ set<pair<int, int> > block_pairs;
+
+ int num_block_diagonal_entries = 0;
+ for (int i = 0; i < num_blocks; ++i) {
+ block_size_[i] = bs.cols[i + options_.elimination_groups[0]].size;
+ block_pairs.insert(make_pair(i, i));
+ num_block_diagonal_entries += block_size_[i] * block_size_[i];
+ }
+
+ m_.reset(new BlockRandomAccessSparseMatrix(block_size_, block_pairs));
+ InitEliminator(bs);
+}
+
+SchurJacobiPreconditioner::~SchurJacobiPreconditioner() {
+}
+
+// Initialize the SchurEliminator.
+void SchurJacobiPreconditioner::InitEliminator(
+ const CompressedRowBlockStructure& bs) {
+ LinearSolver::Options eliminator_options;
+
+ eliminator_options.elimination_groups = options_.elimination_groups;
+ eliminator_options.num_threads = options_.num_threads;
+
+ DetectStructure(bs, options_.elimination_groups[0],
+ &eliminator_options.row_block_size,
+ &eliminator_options.e_block_size,
+ &eliminator_options.f_block_size);
+
+ eliminator_.reset(SchurEliminatorBase::Create(eliminator_options));
+ eliminator_->Init(options_.elimination_groups[0], &bs);
+}
+
+// Update the values of the preconditioner matrix and factorize it.
+bool SchurJacobiPreconditioner::Update(const BlockSparseMatrixBase& A,
+ const double* D) {
+ const int num_rows = m_->num_rows();
+ CHECK_GT(num_rows, 0);
+
+ // We need a dummy rhs vector and a dummy b vector since the Schur
+ // eliminator combines the computation of the reduced camera matrix
+ // with the computation of the right hand side of that linear
+ // system.
+ //
+ // TODO(sameeragarwal): Perhaps its worth refactoring the
+ // SchurEliminator::Eliminate function to allow NULL for the rhs. As
+ // of now it does not seem to be worth the effort.
+ Vector rhs = Vector::Zero(m_->num_rows());
+ Vector b = Vector::Zero(A.num_rows());
+
+ // Compute a subset of the entries of the Schur complement.
+ eliminator_->Eliminate(&A, b.data(), D, m_.get(), rhs.data());
+ return true;
+}
+
+void SchurJacobiPreconditioner::RightMultiply(const double* x,
+ double* y) const {
+ CHECK_NOTNULL(x);
+ CHECK_NOTNULL(y);
+
+ const double* lhs_values =
+ down_cast<BlockRandomAccessSparseMatrix*>(m_.get())->matrix()->values();
+
+ // This loop can be easily multi-threaded with OpenMP if need be.
+ for (int i = 0; i < block_size_.size(); ++i) {
+ const int block_size = block_size_[i];
+ ConstMatrixRef block(lhs_values, block_size, block_size);
+
+ VectorRef(y, block_size) =
+ block
+ .selfadjointView<Eigen::Upper>()
+ .ldlt()
+ .solve(ConstVectorRef(x, block_size));
+
+ x += block_size;
+ y += block_size;
+ lhs_values += block_size * block_size;
+ }
+}
+
+int SchurJacobiPreconditioner::num_rows() const {
+ return m_->num_rows();
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h
new file mode 100644
index 00000000000..3addd73abd2
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h
@@ -0,0 +1,110 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Detailed descriptions of these preconditions beyond what is
+// documented here can be found in
+//
+// Bundle Adjustment in the Large
+// S. Agarwal, N. Snavely, S. Seitz & R. Szeliski, ECCV 2010
+// http://www.cs.washington.edu/homes/sagarwal/bal.pdf
+
+#ifndef CERES_INTERNAL_SCHUR_JACOBI_PRECONDITIONER_H_
+#define CERES_INTERNAL_SCHUR_JACOBI_PRECONDITIONER_H_
+
+#include <set>
+#include <vector>
+#include <utility>
+#include "ceres/collections_port.h"
+#include "ceres/internal/macros.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/preconditioner.h"
+
+namespace ceres {
+namespace internal {
+
+class BlockRandomAccessSparseMatrix;
+class BlockSparseMatrixBase;
+struct CompressedRowBlockStructure;
+class SchurEliminatorBase;
+
+// This class implements the SCHUR_JACOBI preconditioner for Structure
+// from Motion/Bundle Adjustment problems. Full mathematical details
+// can be found in
+//
+// Bundle Adjustment in the Large
+// S. Agarwal, N. Snavely, S. Seitz & R. Szeliski, ECCV 2010
+// http://www.cs.washington.edu/homes/sagarwal/bal.pdf
+//
+// Example usage:
+//
+// Preconditioner::Options options;
+// options.preconditioner_type = SCHUR_JACOBI;
+// options.elimination_groups.push_back(num_points);
+// options.elimination_groups.push_back(num_cameras);
+// SchurJacobiPreconditioner preconditioner(
+// *A.block_structure(), options);
+// preconditioner.Update(A, NULL);
+// preconditioner.RightMultiply(x, y);
+//
+class SchurJacobiPreconditioner : public Preconditioner {
+ public:
+ // Initialize the symbolic structure of the preconditioner. bs is
+ // the block structure of the linear system to be solved. It is used
+ // to determine the sparsity structure of the preconditioner matrix.
+ //
+ // It has the same structural requirement as other Schur complement
+ // based solvers. Please see schur_eliminator.h for more details.
+ SchurJacobiPreconditioner(const CompressedRowBlockStructure& bs,
+ const Preconditioner::Options& options);
+ virtual ~SchurJacobiPreconditioner();
+
+ // Preconditioner interface.
+ virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
+ virtual void RightMultiply(const double* x, double* y) const;
+ virtual int num_rows() const;
+
+ private:
+ void InitEliminator(const CompressedRowBlockStructure& bs);
+
+ Preconditioner::Options options_;
+
+ // Sizes of the blocks in the schur complement.
+ vector<int> block_size_;
+ scoped_ptr<SchurEliminatorBase> eliminator_;
+
+ // Preconditioner matrix.
+ scoped_ptr<BlockRandomAccessSparseMatrix> m_;
+ CERES_DISALLOW_COPY_AND_ASSIGN(SchurJacobiPreconditioner);
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_SCHUR_JACOBI_PRECONDITIONER_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver.cc b/extern/libmv/third_party/ceres/internal/ceres/solver.cc
index 66ca93283a1..6436d2df2a7 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver.cc
@@ -37,20 +37,41 @@
#include "ceres/program.h"
#include "ceres/solver_impl.h"
#include "ceres/stringprintf.h"
+#include "ceres/wall_time.h"
namespace ceres {
+namespace {
+
+void StringifyOrdering(const vector<int>& ordering, string* report) {
+ if (ordering.size() == 0) {
+ internal::StringAppendF(report, "AUTOMATIC");
+ return;
+ }
+
+ for (int i = 0; i < ordering.size() - 1; ++i) {
+ internal::StringAppendF(report, "%d, ", ordering[i]);
+ }
+ internal::StringAppendF(report, "%d", ordering.back());
+}
+
+} // namespace
+
+Solver::Options::~Options() {
+ delete linear_solver_ordering;
+ delete inner_iteration_ordering;
+}
Solver::~Solver() {}
-// TODO(sameeragarwal): Use subsecond timers.
void Solver::Solve(const Solver::Options& options,
Problem* problem,
Solver::Summary* summary) {
- time_t start_time_seconds = time(NULL);
+ double start_time_seconds = internal::WallTimeInSeconds();
internal::ProblemImpl* problem_impl =
CHECK_NOTNULL(problem)->problem_impl_.get();
internal::SolverImpl::Solve(options, problem_impl, summary);
- summary->total_time_in_seconds = time(NULL) - start_time_seconds;
+ summary->total_time_in_seconds =
+ internal::WallTimeInSeconds() - start_time_seconds;
}
void Solve(const Solver::Options& options,
@@ -63,7 +84,8 @@ void Solve(const Solver::Options& options,
Solver::Summary::Summary()
// Invalid values for most fields, to ensure that we are not
// accidentally reporting default values.
- : termination_type(DID_NOT_RUN),
+ : minimizer_type(TRUST_REGION),
+ termination_type(DID_NOT_RUN),
initial_cost(-1.0),
final_cost(-1.0),
fixed_cost(-1.0),
@@ -73,6 +95,9 @@ Solver::Summary::Summary()
minimizer_time_in_seconds(-1.0),
postprocessor_time_in_seconds(-1.0),
total_time_in_seconds(-1.0),
+ linear_solver_time_in_seconds(-1.0),
+ residual_evaluation_time_in_seconds(-1.0),
+ jacobian_evaluation_time_in_seconds(-1.0),
num_parameter_blocks(-1),
num_parameters(-1),
num_residual_blocks(-1),
@@ -81,8 +106,6 @@ Solver::Summary::Summary()
num_parameters_reduced(-1),
num_residual_blocks_reduced(-1),
num_residuals_reduced(-1),
- num_eliminate_blocks_given(-1),
- num_eliminate_blocks_used(-1),
num_threads_given(-1),
num_threads_used(-1),
num_linear_solver_threads_given(-1),
@@ -90,9 +113,11 @@ Solver::Summary::Summary()
linear_solver_type_given(SPARSE_NORMAL_CHOLESKY),
linear_solver_type_used(SPARSE_NORMAL_CHOLESKY),
preconditioner_type(IDENTITY),
- ordering_type(NATURAL),
trust_region_strategy_type(LEVENBERG_MARQUARDT),
- sparse_linear_algebra_library(SUITE_SPARSE) {
+ inner_iterations(false),
+ sparse_linear_algebra_library(SUITE_SPARSE),
+ line_search_direction_type(LBFGS),
+ line_search_type(ARMIJO) {
}
string Solver::Summary::BriefReport() const {
@@ -121,6 +146,8 @@ string Solver::Summary::BriefReport() const {
return report;
};
+using internal::StringAppendF;
+
string Solver::Summary::FullReport() const {
string report =
"\n"
@@ -128,124 +155,210 @@ string Solver::Summary::FullReport() const {
"-------------------\n";
if (termination_type == DID_NOT_RUN) {
- internal::StringAppendF(&report, " Original\n");
- internal::StringAppendF(&report, "Parameter blocks % 10d\n",
- num_parameter_blocks);
- internal::StringAppendF(&report, "Parameters % 10d\n",
- num_parameters);
- internal::StringAppendF(&report, "Residual blocks % 10d\n",
- num_residual_blocks);
- internal::StringAppendF(&report, "Residuals % 10d\n\n",
- num_residuals);
+ StringAppendF(&report, " Original\n");
+ StringAppendF(&report, "Parameter blocks % 10d\n",
+ num_parameter_blocks);
+ StringAppendF(&report, "Parameters % 10d\n",
+ num_parameters);
+ StringAppendF(&report, "Residual blocks % 10d\n",
+ num_residual_blocks);
+ StringAppendF(&report, "Residuals % 10d\n\n",
+ num_residuals);
} else {
- internal::StringAppendF(&report, "%45s %21s\n", "Original", "Reduced");
- internal::StringAppendF(&report, "Parameter blocks % 25d% 25d\n",
- num_parameter_blocks, num_parameter_blocks_reduced);
- internal::StringAppendF(&report, "Parameters % 25d% 25d\n",
- num_parameters, num_parameters_reduced);
- internal::StringAppendF(&report, "Residual blocks % 25d% 25d\n",
- num_residual_blocks, num_residual_blocks_reduced);
- internal::StringAppendF(&report, "Residual % 25d% 25d\n\n",
- num_residuals, num_residuals_reduced);
+ StringAppendF(&report, "%45s %21s\n", "Original", "Reduced");
+ StringAppendF(&report, "Parameter blocks % 25d% 25d\n",
+ num_parameter_blocks, num_parameter_blocks_reduced);
+ StringAppendF(&report, "Parameters % 25d% 25d\n",
+ num_parameters, num_parameters_reduced);
+ StringAppendF(&report, "Residual blocks % 25d% 25d\n",
+ num_residual_blocks, num_residual_blocks_reduced);
+ StringAppendF(&report, "Residual % 25d% 25d\n",
+ num_residuals, num_residuals_reduced);
}
- internal::StringAppendF(&report, "%45s %21s\n", "Given", "Used");
- internal::StringAppendF(&report, "Linear solver %25s%25s\n",
- LinearSolverTypeToString(linear_solver_type_given),
- LinearSolverTypeToString(linear_solver_type_used));
+ // TODO(sameeragarwal): Refactor this into separate functions.
- if (linear_solver_type_given == CGNR ||
- linear_solver_type_given == ITERATIVE_SCHUR) {
- internal::StringAppendF(&report, "Preconditioner %25s%25s\n",
- PreconditionerTypeToString(preconditioner_type),
- PreconditionerTypeToString(preconditioner_type));
- } else {
- internal::StringAppendF(&report, "Preconditioner %25s%25s\n",
- "N/A", "N/A");
- }
+ if (minimizer_type == TRUST_REGION) {
+ StringAppendF(&report, "\nMinimizer %19s\n",
+ "TRUST_REGION");
+ if (linear_solver_type_used == SPARSE_NORMAL_CHOLESKY ||
+ linear_solver_type_used == SPARSE_SCHUR ||
+ (linear_solver_type_used == ITERATIVE_SCHUR &&
+ (preconditioner_type == CLUSTER_JACOBI ||
+ preconditioner_type == CLUSTER_TRIDIAGONAL))) {
+ StringAppendF(&report, "\nSparse Linear Algebra Library %15s\n",
+ SparseLinearAlgebraLibraryTypeToString(
+ sparse_linear_algebra_library));
+ }
- internal::StringAppendF(&report, "Ordering %25s%25s\n",
- OrderingTypeToString(ordering_type),
- OrderingTypeToString(ordering_type));
+ StringAppendF(&report, "Trust Region Strategy %19s",
+ TrustRegionStrategyTypeToString(
+ trust_region_strategy_type));
+ if (trust_region_strategy_type == DOGLEG) {
+ if (dogleg_type == TRADITIONAL_DOGLEG) {
+ StringAppendF(&report, " (TRADITIONAL)");
+ } else {
+ StringAppendF(&report, " (SUBSPACE)");
+ }
+ }
+ StringAppendF(&report, "\n");
+ StringAppendF(&report, "\n");
+
+ StringAppendF(&report, "%45s %21s\n", "Given", "Used");
+ StringAppendF(&report, "Linear solver %25s%25s\n",
+ LinearSolverTypeToString(linear_solver_type_given),
+ LinearSolverTypeToString(linear_solver_type_used));
- if (IsSchurType(linear_solver_type_given)) {
- if (ordering_type == SCHUR) {
- internal::StringAppendF(&report, "num_eliminate_blocks%25s% 25d\n",
- "N/A",
- num_eliminate_blocks_used);
+ if (linear_solver_type_given == CGNR ||
+ linear_solver_type_given == ITERATIVE_SCHUR) {
+ StringAppendF(&report, "Preconditioner %25s%25s\n",
+ PreconditionerTypeToString(preconditioner_type),
+ PreconditionerTypeToString(preconditioner_type));
} else {
- internal::StringAppendF(&report, "num_eliminate_blocks% 25d% 25d\n",
- num_eliminate_blocks_given,
- num_eliminate_blocks_used);
+ StringAppendF(&report, "Preconditioner %25s%25s\n",
+ "N/A", "N/A");
}
- }
- internal::StringAppendF(&report, "Threads: % 25d% 25d\n",
- num_threads_given, num_threads_used);
- internal::StringAppendF(&report, "Linear solver threads % 23d% 25d\n",
- num_linear_solver_threads_given,
- num_linear_solver_threads_used);
-
- if (linear_solver_type_used == SPARSE_NORMAL_CHOLESKY ||
- linear_solver_type_used == SPARSE_SCHUR ||
- (linear_solver_type_used == ITERATIVE_SCHUR &&
- (preconditioner_type == SCHUR_JACOBI ||
- preconditioner_type == CLUSTER_JACOBI ||
- preconditioner_type == CLUSTER_TRIDIAGONAL))) {
- internal::StringAppendF(&report, "\nSparse Linear Algebra Library %15s\n",
- SparseLinearAlgebraLibraryTypeToString(
- sparse_linear_algebra_library));
- }
+ StringAppendF(&report, "Threads: % 25d% 25d\n",
+ num_threads_given, num_threads_used);
+ StringAppendF(&report, "Linear solver threads % 23d% 25d\n",
+ num_linear_solver_threads_given,
+ num_linear_solver_threads_used);
+
+ if (IsSchurType(linear_solver_type_used)) {
+ string given;
+ StringifyOrdering(linear_solver_ordering_given, &given);
+ string used;
+ StringifyOrdering(linear_solver_ordering_used, &used);
+ StringAppendF(&report,
+ "Linear solver ordering %22s %24s\n",
+ given.c_str(),
+ used.c_str());
+ }
+
+ if (inner_iterations) {
+ string given;
+ StringifyOrdering(inner_iteration_ordering_given, &given);
+ string used;
+ StringifyOrdering(inner_iteration_ordering_used, &used);
+ StringAppendF(&report,
+ "Inner iteration ordering %20s %24s\n",
+ given.c_str(),
+ used.c_str());
+ }
+
+ if (termination_type == DID_NOT_RUN) {
+ CHECK(!error.empty())
+ << "Solver terminated with DID_NOT_RUN but the solver did not "
+ << "return a reason. This is a Ceres error. Please report this "
+ << "to the Ceres team";
+ StringAppendF(&report, "Termination: %20s\n",
+ "DID_NOT_RUN");
+ StringAppendF(&report, "Reason: %s\n", error.c_str());
+ return report;
+ }
+
+ StringAppendF(&report, "\nCost:\n");
+ StringAppendF(&report, "Initial % 30e\n", initial_cost);
+ if (termination_type != NUMERICAL_FAILURE &&
+ termination_type != USER_ABORT) {
+ StringAppendF(&report, "Final % 30e\n", final_cost);
+ StringAppendF(&report, "Change % 30e\n",
+ initial_cost - final_cost);
+ }
+
+ StringAppendF(&report, "\nNumber of iterations:\n");
+ StringAppendF(&report, "Successful % 20d\n",
+ num_successful_steps);
+ StringAppendF(&report, "Unsuccessful % 20d\n",
+ num_unsuccessful_steps);
+ StringAppendF(&report, "Total % 20d\n",
+ num_successful_steps + num_unsuccessful_steps);
+
+ StringAppendF(&report, "\nTime (in seconds):\n");
+ StringAppendF(&report, "Preprocessor %25.3f\n",
+ preprocessor_time_in_seconds);
+ StringAppendF(&report, "\n Residual Evaluations %22.3f\n",
+ residual_evaluation_time_in_seconds);
+ StringAppendF(&report, " Jacobian Evaluations %22.3f\n",
+ jacobian_evaluation_time_in_seconds);
+ StringAppendF(&report, " Linear Solver %23.3f\n",
+ linear_solver_time_in_seconds);
+ StringAppendF(&report, "Minimizer %25.3f\n\n",
+ minimizer_time_in_seconds);
+
+ StringAppendF(&report, "Postprocessor %24.3f\n",
+ postprocessor_time_in_seconds);
- internal::StringAppendF(&report, "Trust Region Strategy %19s",
- TrustRegionStrategyTypeToString(
- trust_region_strategy_type));
- if (trust_region_strategy_type == DOGLEG) {
- if (dogleg_type == TRADITIONAL_DOGLEG) {
- internal::StringAppendF(&report, " (TRADITIONAL)");
+ StringAppendF(&report, "Total %25.3f\n\n",
+ total_time_in_seconds);
+
+ StringAppendF(&report, "Termination: %25s\n",
+ SolverTerminationTypeToString(termination_type));
+ } else {
+ // LINE_SEARCH
+ StringAppendF(&report, "\nMinimizer %19s\n", "LINE_SEARCH");
+ if (line_search_direction_type == LBFGS) {
+ StringAppendF(&report, "Line search direction %19s(%d)\n",
+ LineSearchDirectionTypeToString(line_search_direction_type),
+ max_lbfgs_rank);
} else {
- internal::StringAppendF(&report, " (SUBSPACE)");
+ StringAppendF(&report, "Line search direction %19s\n",
+ LineSearchDirectionTypeToString(
+ line_search_direction_type));
}
- }
- internal::StringAppendF(&report, "\n");
+ StringAppendF(&report, "Line search type %19s\n",
+ LineSearchTypeToString(line_search_type));
+ StringAppendF(&report, "\n");
- if (termination_type == DID_NOT_RUN) {
- CHECK(!error.empty())
- << "Solver terminated with DID_NOT_RUN but the solver did not "
- << "return a reason. This is a Ceres error. Please report this "
- << "to the Ceres team";
- internal::StringAppendF(&report, "Termination: %20s\n",
- "DID_NOT_RUN");
- internal::StringAppendF(&report, "Reason: %s\n", error.c_str());
- return report;
- }
+ StringAppendF(&report, "%45s %21s\n", "Given", "Used");
+ StringAppendF(&report, "Threads: % 25d% 25d\n",
+ num_threads_given, num_threads_used);
- internal::StringAppendF(&report, "\nCost:\n");
- internal::StringAppendF(&report, "Initial % 30e\n", initial_cost);
- if (termination_type != NUMERICAL_FAILURE && termination_type != USER_ABORT) {
- internal::StringAppendF(&report, "Final % 30e\n", final_cost);
- internal::StringAppendF(&report, "Change % 30e\n",
- initial_cost - final_cost);
+ if (termination_type == DID_NOT_RUN) {
+ CHECK(!error.empty())
+ << "Solver terminated with DID_NOT_RUN but the solver did not "
+ << "return a reason. This is a Ceres error. Please report this "
+ << "to the Ceres team";
+ StringAppendF(&report, "Termination: %20s\n",
+ "DID_NOT_RUN");
+ StringAppendF(&report, "Reason: %s\n", error.c_str());
+ return report;
+ }
+
+ StringAppendF(&report, "\nCost:\n");
+ StringAppendF(&report, "Initial % 30e\n", initial_cost);
+ if (termination_type != NUMERICAL_FAILURE &&
+ termination_type != USER_ABORT) {
+ StringAppendF(&report, "Final % 30e\n", final_cost);
+ StringAppendF(&report, "Change % 30e\n",
+ initial_cost - final_cost);
+ }
+
+ StringAppendF(&report, "\nNumber of iterations: % 20ld\n",
+ iterations.size() - 1);
+
+ StringAppendF(&report, "\nTime (in seconds):\n");
+ StringAppendF(&report, "Preprocessor %25.3f\n",
+ preprocessor_time_in_seconds);
+ StringAppendF(&report, "\n Residual Evaluations %22.3f\n",
+ residual_evaluation_time_in_seconds);
+ StringAppendF(&report, " Jacobian Evaluations %22.3f\n",
+ jacobian_evaluation_time_in_seconds);
+ StringAppendF(&report, "Minimizer %25.3f\n\n",
+ minimizer_time_in_seconds);
+
+ StringAppendF(&report, "Postprocessor %24.3f\n",
+ postprocessor_time_in_seconds);
+
+ StringAppendF(&report, "Total %25.3f\n\n",
+ total_time_in_seconds);
+
+ StringAppendF(&report, "Termination: %25s\n",
+ SolverTerminationTypeToString(termination_type));
}
- internal::StringAppendF(&report, "\nNumber of iterations:\n");
- internal::StringAppendF(&report, "Successful % 20d\n",
- num_successful_steps);
- internal::StringAppendF(&report, "Unsuccessful % 20d\n",
- num_unsuccessful_steps);
- internal::StringAppendF(&report, "Total % 20d\n",
- num_successful_steps + num_unsuccessful_steps);
- internal::StringAppendF(&report, "\nTime (in seconds):\n");
- internal::StringAppendF(&report, "Preprocessor % 25e\n",
- preprocessor_time_in_seconds);
- internal::StringAppendF(&report, "Minimizer % 25e\n",
- minimizer_time_in_seconds);
- internal::StringAppendF(&report, "Total % 25e\n",
- total_time_in_seconds);
-
- internal::StringAppendF(&report, "Termination: %25s\n",
- SolverTerminationTypeToString(termination_type));
return report;
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
index 8ef5b98e35f..5bcfdc6312f 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
@@ -33,21 +33,25 @@
#include <cstdio>
#include <iostream> // NOLINT
#include <numeric>
+#include "ceres/coordinate_descent_minimizer.h"
#include "ceres/evaluator.h"
#include "ceres/gradient_checking_cost_function.h"
#include "ceres/iteration_callback.h"
#include "ceres/levenberg_marquardt_strategy.h"
#include "ceres/linear_solver.h"
+#include "ceres/line_search_minimizer.h"
#include "ceres/map_util.h"
#include "ceres/minimizer.h"
+#include "ceres/ordered_groups.h"
#include "ceres/parameter_block.h"
+#include "ceres/parameter_block_ordering.h"
#include "ceres/problem.h"
#include "ceres/problem_impl.h"
#include "ceres/program.h"
#include "ceres/residual_block.h"
-#include "ceres/schur_ordering.h"
#include "ceres/stringprintf.h"
#include "ceres/trust_region_minimizer.h"
+#include "ceres/wall_time.h"
namespace ceres {
namespace internal {
@@ -73,14 +77,24 @@ class StateUpdatingCallback : public IterationCallback {
double* parameters_;
};
+void SetSummaryFinalCost(Solver::Summary* summary) {
+ summary->final_cost = summary->initial_cost;
+ // We need the loop here, instead of just looking at the last
+ // iteration because the minimizer maybe making non-monotonic steps.
+ for (int i = 0; i < summary->iterations.size(); ++i) {
+ const IterationSummary& iteration_summary = summary->iterations[i];
+ summary->final_cost = min(iteration_summary.cost, summary->final_cost);
+ }
+}
+
// Callback for logging the state of the minimizer to STDERR or STDOUT
// depending on the user's preferences and logging level.
-class LoggingCallback : public IterationCallback {
+class TrustRegionLoggingCallback : public IterationCallback {
public:
- explicit LoggingCallback(bool log_to_stdout)
+ explicit TrustRegionLoggingCallback(bool log_to_stdout)
: log_to_stdout_(log_to_stdout) {}
- ~LoggingCallback() {}
+ ~TrustRegionLoggingCallback() {}
CallbackReturnType operator()(const IterationSummary& summary) {
const char* kReportRowFormat =
@@ -109,6 +123,42 @@ class LoggingCallback : public IterationCallback {
const bool log_to_stdout_;
};
+// Callback for logging the state of the minimizer to STDERR or STDOUT
+// depending on the user's preferences and logging level.
+class LineSearchLoggingCallback : public IterationCallback {
+ public:
+ explicit LineSearchLoggingCallback(bool log_to_stdout)
+ : log_to_stdout_(log_to_stdout) {}
+
+ ~LineSearchLoggingCallback() {}
+
+ CallbackReturnType operator()(const IterationSummary& summary) {
+ const char* kReportRowFormat =
+ "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
+ "s:% 3.2e e:% 3d it:% 3.2e tt:% 3.2e";
+ string output = StringPrintf(kReportRowFormat,
+ summary.iteration,
+ summary.cost,
+ summary.cost_change,
+ summary.gradient_max_norm,
+ summary.step_norm,
+ summary.step_size,
+ summary.line_search_function_evaluations,
+ summary.iteration_time_in_seconds,
+ summary.cumulative_time_in_seconds);
+ if (log_to_stdout_) {
+ cout << output << endl;
+ } else {
+ VLOG(1) << output;
+ }
+ return SOLVER_CONTINUE;
+ }
+
+ private:
+ const bool log_to_stdout_;
+};
+
+
// Basic callback to record the execution of the solver to a file for
// offline analysis.
class FileLoggingCallback : public IterationCallback {
@@ -137,14 +187,34 @@ class FileLoggingCallback : public IterationCallback {
FILE* fptr_;
};
+// Iterate over each of the groups in order of their priority and fill
+// summary with their sizes.
+void SummarizeOrdering(ParameterBlockOrdering* ordering,
+ vector<int>* summary) {
+ CHECK_NOTNULL(summary)->clear();
+ if (ordering == NULL) {
+ return;
+ }
+
+ const map<int, set<double*> >& group_to_elements =
+ ordering->group_to_elements();
+ for (map<int, set<double*> >::const_iterator it = group_to_elements.begin();
+ it != group_to_elements.end();
+ ++it) {
+ summary->push_back(it->second.size());
+ }
+}
+
} // namespace
-void SolverImpl::Minimize(const Solver::Options& options,
- Program* program,
- Evaluator* evaluator,
- LinearSolver* linear_solver,
- double* parameters,
- Solver::Summary* summary) {
+void SolverImpl::TrustRegionMinimize(
+ const Solver::Options& options,
+ Program* program,
+ CoordinateDescentMinimizer* inner_iteration_minimizer,
+ Evaluator* evaluator,
+ LinearSolver* linear_solver,
+ double* parameters,
+ Solver::Summary* summary) {
Minimizer::Options minimizer_options(options);
// TODO(sameeragarwal): Add support for logging the configuration
@@ -156,7 +226,8 @@ void SolverImpl::Minimize(const Solver::Options& options,
file_logging_callback.get());
}
- LoggingCallback logging_callback(options.minimizer_progress_to_stdout);
+ TrustRegionLoggingCallback logging_callback(
+ options.minimizer_progress_to_stdout);
if (options.logging_type != SILENT) {
minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
&logging_callback);
@@ -172,7 +243,9 @@ void SolverImpl::Minimize(const Solver::Options& options,
minimizer_options.evaluator = evaluator;
scoped_ptr<SparseMatrix> jacobian(evaluator->CreateJacobian());
+
minimizer_options.jacobian = jacobian.get();
+ minimizer_options.inner_iteration_minimizer = inner_iteration_minimizer;
TrustRegionStrategy::Options trust_region_strategy_options;
trust_region_strategy_options.linear_solver = linear_solver;
@@ -189,78 +262,140 @@ void SolverImpl::Minimize(const Solver::Options& options,
minimizer_options.trust_region_strategy = strategy.get();
TrustRegionMinimizer minimizer;
- time_t minimizer_start_time = time(NULL);
+ double minimizer_start_time = WallTimeInSeconds();
minimizer.Minimize(minimizer_options, parameters, summary);
- summary->minimizer_time_in_seconds = time(NULL) - minimizer_start_time;
+ summary->minimizer_time_in_seconds =
+ WallTimeInSeconds() - minimizer_start_time;
}
-void SolverImpl::Solve(const Solver::Options& original_options,
- ProblemImpl* original_problem_impl,
+
+void SolverImpl::LineSearchMinimize(
+ const Solver::Options& options,
+ Program* program,
+ Evaluator* evaluator,
+ double* parameters,
+ Solver::Summary* summary) {
+ Minimizer::Options minimizer_options(options);
+
+ // TODO(sameeragarwal): Add support for logging the configuration
+ // and more detailed stats.
+ scoped_ptr<IterationCallback> file_logging_callback;
+ if (!options.solver_log.empty()) {
+ file_logging_callback.reset(new FileLoggingCallback(options.solver_log));
+ minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
+ file_logging_callback.get());
+ }
+
+ LineSearchLoggingCallback logging_callback(
+ options.minimizer_progress_to_stdout);
+ if (options.logging_type != SILENT) {
+ minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
+ &logging_callback);
+ }
+
+ StateUpdatingCallback updating_callback(program, parameters);
+ if (options.update_state_every_iteration) {
+ // This must get pushed to the front of the callbacks so that it is run
+ // before any of the user callbacks.
+ minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
+ &updating_callback);
+ }
+
+ minimizer_options.evaluator = evaluator;
+
+ LineSearchMinimizer minimizer;
+ double minimizer_start_time = WallTimeInSeconds();
+ minimizer.Minimize(minimizer_options, parameters, summary);
+ summary->minimizer_time_in_seconds =
+ WallTimeInSeconds() - minimizer_start_time;
+}
+
+void SolverImpl::Solve(const Solver::Options& options,
+ ProblemImpl* problem_impl,
Solver::Summary* summary) {
- time_t solver_start_time = time(NULL);
- Solver::Options options(original_options);
+ if (options.minimizer_type == TRUST_REGION) {
+ TrustRegionSolve(options, problem_impl, summary);
+ } else {
+ LineSearchSolve(options, problem_impl, summary);
+ }
+}
+
+void SolverImpl::TrustRegionSolve(const Solver::Options& original_options,
+ ProblemImpl* original_problem_impl,
+ Solver::Summary* summary) {
+ EventLogger event_logger("TrustRegionSolve");
+ double solver_start_time = WallTimeInSeconds();
+
Program* original_program = original_problem_impl->mutable_program();
ProblemImpl* problem_impl = original_problem_impl;
+
// Reset the summary object to its default values.
*CHECK_NOTNULL(summary) = Solver::Summary();
+ summary->minimizer_type = TRUST_REGION;
+ summary->num_parameter_blocks = problem_impl->NumParameterBlocks();
+ summary->num_parameters = problem_impl->NumParameters();
+ summary->num_residual_blocks = problem_impl->NumResidualBlocks();
+ summary->num_residuals = problem_impl->NumResiduals();
+
+ // Empty programs are usually a user error.
+ if (summary->num_parameter_blocks == 0) {
+ summary->error = "Problem contains no parameter blocks.";
+ LOG(ERROR) << summary->error;
+ return;
+ }
+
+ if (summary->num_residual_blocks == 0) {
+ summary->error = "Problem contains no residual blocks.";
+ LOG(ERROR) << summary->error;
+ return;
+ }
+
+ SummarizeOrdering(original_options.linear_solver_ordering,
+ &(summary->linear_solver_ordering_given));
+
+ SummarizeOrdering(original_options.inner_iteration_ordering,
+ &(summary->inner_iteration_ordering_given));
+
+ Solver::Options options(original_options);
+ options.linear_solver_ordering = NULL;
+ options.inner_iteration_ordering = NULL;
#ifndef CERES_USE_OPENMP
if (options.num_threads > 1) {
LOG(WARNING)
<< "OpenMP support is not compiled into this binary; "
- << "only options.num_threads=1 is supported. Switching"
+ << "only options.num_threads=1 is supported. Switching "
<< "to single threaded mode.";
options.num_threads = 1;
}
if (options.num_linear_solver_threads > 1) {
LOG(WARNING)
<< "OpenMP support is not compiled into this binary; "
- << "only options.num_linear_solver_threads=1 is supported. Switching"
+ << "only options.num_linear_solver_threads=1 is supported. Switching "
<< "to single threaded mode.";
options.num_linear_solver_threads = 1;
}
#endif
- summary->linear_solver_type_given = options.linear_solver_type;
- summary->num_eliminate_blocks_given = original_options.num_eliminate_blocks;
summary->num_threads_given = original_options.num_threads;
- summary->num_linear_solver_threads_given =
- original_options.num_linear_solver_threads;
- summary->ordering_type = original_options.ordering_type;
+ summary->num_threads_used = options.num_threads;
- summary->num_parameter_blocks = problem_impl->NumParameterBlocks();
- summary->num_parameters = problem_impl->NumParameters();
- summary->num_residual_blocks = problem_impl->NumResidualBlocks();
- summary->num_residuals = problem_impl->NumResiduals();
+ if (options.lsqp_iterations_to_dump.size() > 0) {
+ LOG(WARNING) << "Dumping linear least squares problems to disk is"
+ " currently broken. Ignoring Solver::Options::lsqp_iterations_to_dump";
+ }
- summary->num_threads_used = options.num_threads;
- summary->sparse_linear_algebra_library =
- options.sparse_linear_algebra_library;
- summary->trust_region_strategy_type = options.trust_region_strategy_type;
- summary->dogleg_type = options.dogleg_type;
+ event_logger.AddEvent("Init");
- // Evaluate the initial cost, residual vector and the jacobian
- // matrix if requested by the user. The initial cost needs to be
- // computed on the original unpreprocessed problem, as it is used to
- // determine the value of the "fixed" part of the objective function
- // after the problem has undergone reduction.
- Evaluator::Evaluate(
- original_program,
- options.num_threads,
- &(summary->initial_cost),
- options.return_initial_residuals ? &summary->initial_residuals : NULL,
- options.return_initial_gradient ? &summary->initial_gradient : NULL,
- options.return_initial_jacobian ? &summary->initial_jacobian : NULL);
- original_program->SetParameterBlockStatePtrsToUserStatePtrs();
+ original_program->SetParameterBlockStatePtrsToUserStatePtrs();
+ event_logger.AddEvent("SetParameterBlockPtrs");
// If the user requests gradient checking, construct a new
// ProblemImpl by wrapping the CostFunctions of problem_impl inside
// GradientCheckingCostFunction and replacing problem_impl with
// gradient_checking_problem_impl.
scoped_ptr<ProblemImpl> gradient_checking_problem_impl;
- // Save the original problem impl so we don't use the gradient
- // checking one when computing the residuals.
if (options.check_gradients) {
VLOG(1) << "Checking Gradients";
gradient_checking_problem_impl.reset(
@@ -269,45 +404,344 @@ void SolverImpl::Solve(const Solver::Options& original_options,
options.numeric_derivative_relative_step_size,
options.gradient_check_relative_precision));
- // From here on, problem_impl will point to the GradientChecking version.
+ // From here on, problem_impl will point to the gradient checking
+ // version.
problem_impl = gradient_checking_problem_impl.get();
}
+ if (original_options.linear_solver_ordering != NULL) {
+ if (!IsOrderingValid(original_options, problem_impl, &summary->error)) {
+ LOG(ERROR) << summary->error;
+ return;
+ }
+ event_logger.AddEvent("CheckOrdering");
+ options.linear_solver_ordering =
+ new ParameterBlockOrdering(*original_options.linear_solver_ordering);
+ event_logger.AddEvent("CopyOrdering");
+ } else {
+ options.linear_solver_ordering = new ParameterBlockOrdering;
+ const ProblemImpl::ParameterMap& parameter_map =
+ problem_impl->parameter_map();
+ for (ProblemImpl::ParameterMap::const_iterator it = parameter_map.begin();
+ it != parameter_map.end();
+ ++it) {
+ options.linear_solver_ordering->AddElementToGroup(it->first, 0);
+ }
+ event_logger.AddEvent("ConstructOrdering");
+ }
+
// Create the three objects needed to minimize: the transformed program, the
// evaluator, and the linear solver.
-
scoped_ptr<Program> reduced_program(CreateReducedProgram(&options,
problem_impl,
&summary->fixed_cost,
&summary->error));
+
+ event_logger.AddEvent("CreateReducedProgram");
if (reduced_program == NULL) {
return;
}
+ SummarizeOrdering(options.linear_solver_ordering,
+ &(summary->linear_solver_ordering_used));
+
summary->num_parameter_blocks_reduced = reduced_program->NumParameterBlocks();
summary->num_parameters_reduced = reduced_program->NumParameters();
summary->num_residual_blocks_reduced = reduced_program->NumResidualBlocks();
summary->num_residuals_reduced = reduced_program->NumResiduals();
+ if (summary->num_parameter_blocks_reduced == 0) {
+ summary->preprocessor_time_in_seconds =
+ WallTimeInSeconds() - solver_start_time;
+
+ double post_process_start_time = WallTimeInSeconds();
+ LOG(INFO) << "Terminating: FUNCTION_TOLERANCE reached. "
+ << "No non-constant parameter blocks found.";
+
+ summary->initial_cost = summary->fixed_cost;
+ summary->final_cost = summary->fixed_cost;
+
+ // FUNCTION_TOLERANCE is the right convergence here, as we know
+ // that the objective function is constant and cannot be changed
+ // any further.
+ summary->termination_type = FUNCTION_TOLERANCE;
+
+ // Ensure the program state is set to the user parameters on the way out.
+ original_program->SetParameterBlockStatePtrsToUserStatePtrs();
+
+ summary->postprocessor_time_in_seconds =
+ WallTimeInSeconds() - post_process_start_time;
+ return;
+ }
+
scoped_ptr<LinearSolver>
linear_solver(CreateLinearSolver(&options, &summary->error));
+ event_logger.AddEvent("CreateLinearSolver");
+ if (linear_solver == NULL) {
+ return;
+ }
+
+ summary->linear_solver_type_given = original_options.linear_solver_type;
summary->linear_solver_type_used = options.linear_solver_type;
+
summary->preconditioner_type = options.preconditioner_type;
- summary->num_eliminate_blocks_used = options.num_eliminate_blocks;
+
+ summary->num_linear_solver_threads_given =
+ original_options.num_linear_solver_threads;
summary->num_linear_solver_threads_used = options.num_linear_solver_threads;
- if (linear_solver == NULL) {
+ summary->sparse_linear_algebra_library =
+ options.sparse_linear_algebra_library;
+
+ summary->trust_region_strategy_type = options.trust_region_strategy_type;
+ summary->dogleg_type = options.dogleg_type;
+
+ // Only Schur types require the lexicographic reordering.
+ if (IsSchurType(options.linear_solver_type)) {
+ const int num_eliminate_blocks =
+ options.linear_solver_ordering
+ ->group_to_elements().begin()
+ ->second.size();
+ if (!LexicographicallyOrderResidualBlocks(num_eliminate_blocks,
+ reduced_program.get(),
+ &summary->error)) {
+ return;
+ }
+ }
+
+ scoped_ptr<Evaluator> evaluator(CreateEvaluator(options,
+ problem_impl->parameter_map(),
+ reduced_program.get(),
+ &summary->error));
+
+ event_logger.AddEvent("CreateEvaluator");
+
+ if (evaluator == NULL) {
+ return;
+ }
+
+ scoped_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer;
+ if (options.use_inner_iterations) {
+ if (reduced_program->parameter_blocks().size() < 2) {
+ LOG(WARNING) << "Reduced problem only contains one parameter block."
+ << "Disabling inner iterations.";
+ } else {
+ inner_iteration_minimizer.reset(
+ CreateInnerIterationMinimizer(original_options,
+ *reduced_program,
+ problem_impl->parameter_map(),
+ summary));
+ if (inner_iteration_minimizer == NULL) {
+ LOG(ERROR) << summary->error;
+ return;
+ }
+ }
+ }
+
+ event_logger.AddEvent("CreateIIM");
+
+ // The optimizer works on contiguous parameter vectors; allocate some.
+ Vector parameters(reduced_program->NumParameters());
+
+ // Collect the discontiguous parameters into a contiguous state vector.
+ reduced_program->ParameterBlocksToStateVector(parameters.data());
+
+ Vector original_parameters = parameters;
+
+ double minimizer_start_time = WallTimeInSeconds();
+ summary->preprocessor_time_in_seconds =
+ minimizer_start_time - solver_start_time;
+
+ // Run the optimization.
+ TrustRegionMinimize(options,
+ reduced_program.get(),
+ inner_iteration_minimizer.get(),
+ evaluator.get(),
+ linear_solver.get(),
+ parameters.data(),
+ summary);
+ event_logger.AddEvent("Minimize");
+
+ SetSummaryFinalCost(summary);
+
+ // If the user aborted mid-optimization or the optimization
+ // terminated because of a numerical failure, then return without
+ // updating user state.
+ if (summary->termination_type == USER_ABORT ||
+ summary->termination_type == NUMERICAL_FAILURE) {
return;
}
- if (!MaybeReorderResidualBlocks(options,
- reduced_program.get(),
- &summary->error)) {
+ double post_process_start_time = WallTimeInSeconds();
+
+ // Push the contiguous optimized parameters back to the user's
+ // parameters.
+ reduced_program->StateVectorToParameterBlocks(parameters.data());
+ reduced_program->CopyParameterBlockStateToUserState();
+
+ // Ensure the program state is set to the user parameters on the way
+ // out.
+ original_program->SetParameterBlockStatePtrsToUserStatePtrs();
+
+ const map<string, double>& linear_solver_time_statistics =
+ linear_solver->TimeStatistics();
+ summary->linear_solver_time_in_seconds =
+ FindWithDefault(linear_solver_time_statistics,
+ "LinearSolver::Solve",
+ 0.0);
+
+ const map<string, double>& evaluator_time_statistics =
+ evaluator->TimeStatistics();
+
+ summary->residual_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0);
+ summary->jacobian_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0);
+
+ // Stick a fork in it, we're done.
+ summary->postprocessor_time_in_seconds =
+ WallTimeInSeconds() - post_process_start_time;
+ event_logger.AddEvent("PostProcess");
+}
+
+void SolverImpl::LineSearchSolve(const Solver::Options& original_options,
+ ProblemImpl* original_problem_impl,
+ Solver::Summary* summary) {
+ double solver_start_time = WallTimeInSeconds();
+
+ Program* original_program = original_problem_impl->mutable_program();
+ ProblemImpl* problem_impl = original_problem_impl;
+
+ // Reset the summary object to its default values.
+ *CHECK_NOTNULL(summary) = Solver::Summary();
+
+ summary->minimizer_type = LINE_SEARCH;
+ summary->line_search_direction_type =
+ original_options.line_search_direction_type;
+ summary->max_lbfgs_rank = original_options.max_lbfgs_rank;
+ summary->line_search_type = original_options.line_search_type;
+ summary->num_parameter_blocks = problem_impl->NumParameterBlocks();
+ summary->num_parameters = problem_impl->NumParameters();
+ summary->num_residual_blocks = problem_impl->NumResidualBlocks();
+ summary->num_residuals = problem_impl->NumResiduals();
+
+ // Empty programs are usually a user error.
+ if (summary->num_parameter_blocks == 0) {
+ summary->error = "Problem contains no parameter blocks.";
+ LOG(ERROR) << summary->error;
return;
}
- scoped_ptr<Evaluator> evaluator(
- CreateEvaluator(options, reduced_program.get(), &summary->error));
+ if (summary->num_residual_blocks == 0) {
+ summary->error = "Problem contains no residual blocks.";
+ LOG(ERROR) << summary->error;
+ return;
+ }
+
+ Solver::Options options(original_options);
+
+ // This ensures that we get a Block Jacobian Evaluator along with
+ // none of the Schur nonsense. This file will have to be extensively
+ // refactored to deal with the various bits of cleanups related to
+ // line search.
+ options.linear_solver_type = CGNR;
+
+ options.linear_solver_ordering = NULL;
+ options.inner_iteration_ordering = NULL;
+
+#ifndef CERES_USE_OPENMP
+ if (options.num_threads > 1) {
+ LOG(WARNING)
+ << "OpenMP support is not compiled into this binary; "
+ << "only options.num_threads=1 is supported. Switching "
+ << "to single threaded mode.";
+ options.num_threads = 1;
+ }
+#endif
+
+ summary->num_threads_given = original_options.num_threads;
+ summary->num_threads_used = options.num_threads;
+
+ if (original_options.linear_solver_ordering != NULL) {
+ if (!IsOrderingValid(original_options, problem_impl, &summary->error)) {
+ LOG(ERROR) << summary->error;
+ return;
+ }
+ options.linear_solver_ordering =
+ new ParameterBlockOrdering(*original_options.linear_solver_ordering);
+ } else {
+ options.linear_solver_ordering = new ParameterBlockOrdering;
+ const ProblemImpl::ParameterMap& parameter_map =
+ problem_impl->parameter_map();
+ for (ProblemImpl::ParameterMap::const_iterator it = parameter_map.begin();
+ it != parameter_map.end();
+ ++it) {
+ options.linear_solver_ordering->AddElementToGroup(it->first, 0);
+ }
+ }
+
+ original_program->SetParameterBlockStatePtrsToUserStatePtrs();
+
+ // If the user requests gradient checking, construct a new
+ // ProblemImpl by wrapping the CostFunctions of problem_impl inside
+ // GradientCheckingCostFunction and replacing problem_impl with
+ // gradient_checking_problem_impl.
+ scoped_ptr<ProblemImpl> gradient_checking_problem_impl;
+ if (options.check_gradients) {
+ VLOG(1) << "Checking Gradients";
+ gradient_checking_problem_impl.reset(
+ CreateGradientCheckingProblemImpl(
+ problem_impl,
+ options.numeric_derivative_relative_step_size,
+ options.gradient_check_relative_precision));
+
+ // From here on, problem_impl will point to the gradient checking
+ // version.
+ problem_impl = gradient_checking_problem_impl.get();
+ }
+
+ // Create the three objects needed to minimize: the transformed program, the
+ // evaluator, and the linear solver.
+ scoped_ptr<Program> reduced_program(CreateReducedProgram(&options,
+ problem_impl,
+ &summary->fixed_cost,
+ &summary->error));
+ if (reduced_program == NULL) {
+ return;
+ }
+
+ summary->num_parameter_blocks_reduced = reduced_program->NumParameterBlocks();
+ summary->num_parameters_reduced = reduced_program->NumParameters();
+ summary->num_residual_blocks_reduced = reduced_program->NumResidualBlocks();
+ summary->num_residuals_reduced = reduced_program->NumResiduals();
+
+ if (summary->num_parameter_blocks_reduced == 0) {
+ summary->preprocessor_time_in_seconds =
+ WallTimeInSeconds() - solver_start_time;
+
+ LOG(INFO) << "Terminating: FUNCTION_TOLERANCE reached. "
+ << "No non-constant parameter blocks found.";
+
+ // FUNCTION_TOLERANCE is the right convergence here, as we know
+ // that the objective function is constant and cannot be changed
+ // any further.
+ summary->termination_type = FUNCTION_TOLERANCE;
+
+ const double post_process_start_time = WallTimeInSeconds();
+
+ SetSummaryFinalCost(summary);
+
+ // Ensure the program state is set to the user parameters on the way out.
+ original_program->SetParameterBlockStatePtrsToUserStatePtrs();
+ summary->postprocessor_time_in_seconds =
+ WallTimeInSeconds() - post_process_start_time;
+ return;
+ }
+
+ scoped_ptr<Evaluator> evaluator(CreateEvaluator(options,
+ problem_impl->parameter_map(),
+ reduced_program.get(),
+ &summary->error));
if (evaluator == NULL) {
return;
}
@@ -318,17 +752,18 @@ void SolverImpl::Solve(const Solver::Options& original_options,
// Collect the discontiguous parameters into a contiguous state vector.
reduced_program->ParameterBlocksToStateVector(parameters.data());
- time_t minimizer_start_time = time(NULL);
+ Vector original_parameters = parameters;
+
+ const double minimizer_start_time = WallTimeInSeconds();
summary->preprocessor_time_in_seconds =
minimizer_start_time - solver_start_time;
// Run the optimization.
- Minimize(options,
- reduced_program.get(),
- evaluator.get(),
- linear_solver.get(),
- parameters.data(),
- summary);
+ LineSearchMinimize(options,
+ reduced_program.get(),
+ evaluator.get(),
+ parameters.data(),
+ summary);
// If the user aborted mid-optimization or the optimization
// terminated because of a numerical failure, then return without
@@ -338,35 +773,100 @@ void SolverImpl::Solve(const Solver::Options& original_options,
return;
}
- time_t post_process_start_time = time(NULL);
+ const double post_process_start_time = WallTimeInSeconds();
// Push the contiguous optimized parameters back to the user's parameters.
reduced_program->StateVectorToParameterBlocks(parameters.data());
reduced_program->CopyParameterBlockStateToUserState();
- // Evaluate the final cost, residual vector and the jacobian
- // matrix if requested by the user.
- Evaluator::Evaluate(
- original_program,
- options.num_threads,
- &summary->final_cost,
- options.return_final_residuals ? &summary->final_residuals : NULL,
- options.return_final_gradient ? &summary->final_gradient : NULL,
- options.return_final_jacobian ? &summary->final_jacobian : NULL);
+ SetSummaryFinalCost(summary);
// Ensure the program state is set to the user parameters on the way out.
original_program->SetParameterBlockStatePtrsToUserStatePtrs();
+
+ const map<string, double>& evaluator_time_statistics =
+ evaluator->TimeStatistics();
+
+ summary->residual_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0);
+ summary->jacobian_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0);
+
// Stick a fork in it, we're done.
- summary->postprocessor_time_in_seconds = time(NULL) - post_process_start_time;
+ summary->postprocessor_time_in_seconds =
+ WallTimeInSeconds() - post_process_start_time;
+}
+
+
+bool SolverImpl::IsOrderingValid(const Solver::Options& options,
+ const ProblemImpl* problem_impl,
+ string* error) {
+ if (options.linear_solver_ordering->NumElements() !=
+ problem_impl->NumParameterBlocks()) {
+ *error = "Number of parameter blocks in user supplied ordering "
+ "does not match the number of parameter blocks in the problem";
+ return false;
+ }
+
+ const Program& program = problem_impl->program();
+ const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
+ for (vector<ParameterBlock*>::const_iterator it = parameter_blocks.begin();
+ it != parameter_blocks.end();
+ ++it) {
+ if (!options.linear_solver_ordering
+ ->IsMember(const_cast<double*>((*it)->user_state()))) {
+ *error = "Problem contains a parameter block that is not in "
+ "the user specified ordering.";
+ return false;
+ }
+ }
+
+ if (IsSchurType(options.linear_solver_type) &&
+ options.linear_solver_ordering->NumGroups() > 1) {
+ const vector<ResidualBlock*>& residual_blocks = program.residual_blocks();
+ const set<double*>& e_blocks =
+ options.linear_solver_ordering->group_to_elements().begin()->second;
+ if (!IsParameterBlockSetIndependent(e_blocks, residual_blocks)) {
+ *error = "The user requested the use of a Schur type solver. "
+ "But the first elimination group in the ordering is not an "
+ "independent set.";
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SolverImpl::IsParameterBlockSetIndependent(
+ const set<double*>& parameter_block_ptrs,
+ const vector<ResidualBlock*>& residual_blocks) {
+ // Loop over each residual block and ensure that no two parameter
+ // blocks in the same residual block are part of
+ // parameter_block_ptrs as that would violate the assumption that it
+ // is an independent set in the Hessian matrix.
+ for (vector<ResidualBlock*>::const_iterator it = residual_blocks.begin();
+ it != residual_blocks.end();
+ ++it) {
+ ParameterBlock* const* parameter_blocks = (*it)->parameter_blocks();
+ const int num_parameter_blocks = (*it)->NumParameterBlocks();
+ int count = 0;
+ for (int i = 0; i < num_parameter_blocks; ++i) {
+ count += parameter_block_ptrs.count(
+ parameter_blocks[i]->mutable_user_state());
+ }
+ if (count > 1) {
+ return false;
+ }
+ }
+ return true;
}
+
// Strips varying parameters and residuals, maintaining order, and updating
// num_eliminate_blocks.
bool SolverImpl::RemoveFixedBlocksFromProgram(Program* program,
- int* num_eliminate_blocks,
+ ParameterBlockOrdering* ordering,
double* fixed_cost,
string* error) {
- int original_num_eliminate_blocks = *num_eliminate_blocks;
vector<ParameterBlock*>* parameter_blocks =
program->mutable_parameter_blocks();
@@ -423,7 +923,7 @@ bool SolverImpl::RemoveFixedBlocksFromProgram(Program* program,
}
// Filter out unused or fixed parameter blocks, and update
- // num_eliminate_blocks as necessary.
+ // the ordering.
{
vector<ParameterBlock*>* parameter_blocks =
program->mutable_parameter_blocks();
@@ -432,8 +932,8 @@ bool SolverImpl::RemoveFixedBlocksFromProgram(Program* program,
ParameterBlock* parameter_block = (*parameter_blocks)[i];
if (parameter_block->index() == 1) {
(*parameter_blocks)[j++] = parameter_block;
- } else if (i < original_num_eliminate_blocks) {
- (*num_eliminate_blocks)--;
+ } else {
+ ordering->Remove(parameter_block->mutable_user_state());
}
}
parameter_blocks->resize(j);
@@ -451,70 +951,127 @@ Program* SolverImpl::CreateReducedProgram(Solver::Options* options,
ProblemImpl* problem_impl,
double* fixed_cost,
string* error) {
+ EventLogger event_logger("CreateReducedProgram");
+
+ CHECK_NOTNULL(options->linear_solver_ordering);
Program* original_program = problem_impl->mutable_program();
scoped_ptr<Program> transformed_program(new Program(*original_program));
+ event_logger.AddEvent("TransformedProgram");
- if (options->ordering_type == USER &&
- !ApplyUserOrdering(*problem_impl,
- options->ordering,
- transformed_program.get(),
- error)) {
- return NULL;
- }
-
- if (options->ordering_type == SCHUR && options->num_eliminate_blocks != 0) {
- *error = "Can't specify SCHUR ordering and num_eliminate_blocks "
- "at the same time; SCHUR ordering determines "
- "num_eliminate_blocks automatically.";
- return NULL;
- }
-
- if (options->ordering_type == SCHUR && options->ordering.size() != 0) {
- *error = "Can't specify SCHUR ordering type and the ordering "
- "vector at the same time; SCHUR ordering determines "
- "a suitable parameter ordering automatically.";
- return NULL;
- }
+ ParameterBlockOrdering* linear_solver_ordering =
+ options->linear_solver_ordering;
- int num_eliminate_blocks = options->num_eliminate_blocks;
+ const int min_group_id =
+ linear_solver_ordering->group_to_elements().begin()->first;
+ const int original_num_groups = linear_solver_ordering->NumGroups();
if (!RemoveFixedBlocksFromProgram(transformed_program.get(),
- &num_eliminate_blocks,
+ linear_solver_ordering,
fixed_cost,
error)) {
return NULL;
}
+ event_logger.AddEvent("RemoveFixedBlocks");
+
if (transformed_program->NumParameterBlocks() == 0) {
+ if (transformed_program->NumResidualBlocks() > 0) {
+ *error = "Zero parameter blocks but non-zero residual blocks"
+ " in the reduced program. Congratulations, you found a "
+ "Ceres bug! Please report this error to the developers.";
+ return NULL;
+ }
+
LOG(WARNING) << "No varying parameter blocks to optimize; "
<< "bailing early.";
return transformed_program.release();
}
- if (options->ordering_type == SCHUR) {
+ // If the user supplied an linear_solver_ordering with just one
+ // group, it is equivalent to the user supplying NULL as
+ // ordering. Ceres is completely free to choose the parameter block
+ // ordering as it sees fit. For Schur type solvers, this means that
+ // the user wishes for Ceres to identify the e_blocks, which we do
+ // by computing a maximal independent set.
+ if (original_num_groups == 1 && IsSchurType(options->linear_solver_type)) {
vector<ParameterBlock*> schur_ordering;
- num_eliminate_blocks = ComputeSchurOrdering(*transformed_program,
- &schur_ordering);
+ const int num_eliminate_blocks = ComputeSchurOrdering(*transformed_program,
+ &schur_ordering);
CHECK_EQ(schur_ordering.size(), transformed_program->NumParameterBlocks())
<< "Congratulations, you found a Ceres bug! Please report this error "
<< "to the developers.";
- // Replace the transformed program's ordering with the schur ordering.
- swap(*transformed_program->mutable_parameter_blocks(), schur_ordering);
+ for (int i = 0; i < schur_ordering.size(); ++i) {
+ linear_solver_ordering->AddElementToGroup(
+ schur_ordering[i]->mutable_user_state(),
+ (i < num_eliminate_blocks) ? 0 : 1);
+ }
}
- options->num_eliminate_blocks = num_eliminate_blocks;
- CHECK_GE(options->num_eliminate_blocks, 0)
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
+ event_logger.AddEvent("SchurOrdering");
+
+ if (!ApplyUserOrdering(problem_impl->parameter_map(),
+ linear_solver_ordering,
+ transformed_program.get(),
+ error)) {
+ return NULL;
+ }
+ event_logger.AddEvent("ApplyOrdering");
+
+ // If the user requested the use of a Schur type solver, and
+ // supplied a non-NULL linear_solver_ordering object with more than
+ // one elimination group, then it can happen that after all the
+ // parameter blocks which are fixed or unused have been removed from
+ // the program and the ordering, there are no more parameter blocks
+ // in the first elimination group.
+ //
+ // In such a case, the use of a Schur type solver is not possible,
+ // as they assume there is at least one e_block. Thus, we
+ // automatically switch to one of the other solvers, depending on
+ // the user's indicated preferences.
+ if (IsSchurType(options->linear_solver_type) &&
+ original_num_groups > 1 &&
+ linear_solver_ordering->GroupSize(min_group_id) == 0) {
+ string msg = "No e_blocks remaining. Switching from ";
+ if (options->linear_solver_type == SPARSE_SCHUR) {
+ options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+ msg += "SPARSE_SCHUR to SPARSE_NORMAL_CHOLESKY.";
+ } else if (options->linear_solver_type == DENSE_SCHUR) {
+ // TODO(sameeragarwal): This is probably not a great choice.
+ // Ideally, we should have a DENSE_NORMAL_CHOLESKY, that can
+ // take a BlockSparseMatrix as input.
+ options->linear_solver_type = DENSE_QR;
+ msg += "DENSE_SCHUR to DENSE_QR.";
+ } else if (options->linear_solver_type == ITERATIVE_SCHUR) {
+ msg += StringPrintf("ITERATIVE_SCHUR with %s preconditioner "
+ "to CGNR with JACOBI preconditioner.",
+ PreconditionerTypeToString(
+ options->preconditioner_type));
+ options->linear_solver_type = CGNR;
+ if (options->preconditioner_type != IDENTITY) {
+ // CGNR currently only supports the JACOBI preconditioner.
+ options->preconditioner_type = JACOBI;
+ }
+ }
- // Since the transformed program is the "active" program, and it is mutated,
- // update the parameter offsets and indices.
+ LOG(WARNING) << msg;
+ }
+
+ event_logger.AddEvent("AlternateSolver");
+
+ // Since the transformed program is the "active" program, and it is
+ // mutated, update the parameter offsets and indices.
transformed_program->SetParameterOffsetsAndIndex();
+
+ event_logger.AddEvent("SetOffsets");
return transformed_program.release();
}
LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
string* error) {
+ CHECK_NOTNULL(options);
+ CHECK_NOTNULL(options->linear_solver_ordering);
+ CHECK_NOTNULL(error);
+
if (options->trust_region_strategy_type == DOGLEG) {
if (options->linear_solver_type == ITERATIVE_SCHUR ||
options->linear_solver_type == CGNR) {
@@ -532,6 +1089,18 @@ LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
"SuiteSparse was not enabled when Ceres was built.";
return NULL;
}
+
+ if (options->preconditioner_type == CLUSTER_JACOBI) {
+ *error = "CLUSTER_JACOBI preconditioner not suppored. Please build Ceres "
+ "with SuiteSparse support.";
+ return NULL;
+ }
+
+ if (options->preconditioner_type == CLUSTER_TRIDIAGONAL) {
+ *error = "CLUSTER_TRIDIAGONAL preconditioner not suppored. Please build "
+ "Ceres with SuiteSparse support.";
+ return NULL;
+ }
#endif
#ifdef CERES_NO_CXSPARSE
@@ -543,6 +1112,13 @@ LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
}
#endif
+#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
+ if (options->linear_solver_type == SPARSE_SCHUR) {
+ *error = "Can't use SPARSE_SCHUR because neither SuiteSparse nor"
+ "CXSparse was enabled when Ceres was compiled.";
+ return NULL;
+ }
+#endif
if (options->linear_solver_max_num_iterations <= 0) {
*error = "Solver::Options::linear_solver_max_num_iterations is 0.";
@@ -568,52 +1144,8 @@ LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
linear_solver_options.preconditioner_type = options->preconditioner_type;
linear_solver_options.sparse_linear_algebra_library =
options->sparse_linear_algebra_library;
- linear_solver_options.use_block_amd = options->use_block_amd;
-
-#ifdef CERES_NO_SUITESPARSE
- if (linear_solver_options.preconditioner_type == SCHUR_JACOBI) {
- *error = "SCHUR_JACOBI preconditioner not suppored. Please build Ceres "
- "with SuiteSparse support.";
- return NULL;
- }
-
- if (linear_solver_options.preconditioner_type == CLUSTER_JACOBI) {
- *error = "CLUSTER_JACOBI preconditioner not suppored. Please build Ceres "
- "with SuiteSparse support.";
- return NULL;
- }
-
- if (linear_solver_options.preconditioner_type == CLUSTER_TRIDIAGONAL) {
- *error = "CLUSTER_TRIDIAGONAL preconditioner not suppored. Please build "
- "Ceres with SuiteSparse support.";
- return NULL;
- }
-#endif
linear_solver_options.num_threads = options->num_linear_solver_threads;
- linear_solver_options.num_eliminate_blocks =
- options->num_eliminate_blocks;
-
- if ((linear_solver_options.num_eliminate_blocks == 0) &&
- IsSchurType(linear_solver_options.type)) {
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
- LOG(INFO) << "No elimination block remaining switching to DENSE_QR.";
- linear_solver_options.type = DENSE_QR;
-#else
- LOG(INFO) << "No elimination block remaining "
- << "switching to SPARSE_NORMAL_CHOLESKY.";
- linear_solver_options.type = SPARSE_NORMAL_CHOLESKY;
-#endif
- }
-
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
- if (linear_solver_options.type == SPARSE_SCHUR) {
- *error = "Can't use SPARSE_SCHUR because neither SuiteSparse nor"
- "CXSparse was enabled when Ceres was compiled.";
- return NULL;
- }
-#endif
-
// The matrix used for storing the dense Schur complement has a
// single lock guarding the whole matrix. Running the
// SchurComplementSolver with multiple threads leads to maximum
@@ -628,56 +1160,67 @@ LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
<< "switching to single-threaded.";
linear_solver_options.num_threads = 1;
}
-
- options->linear_solver_type = linear_solver_options.type;
options->num_linear_solver_threads = linear_solver_options.num_threads;
+ linear_solver_options.use_block_amd = options->use_block_amd;
+ const map<int, set<double*> >& groups =
+ options->linear_solver_ordering->group_to_elements();
+ for (map<int, set<double*> >::const_iterator it = groups.begin();
+ it != groups.end();
+ ++it) {
+ linear_solver_options.elimination_groups.push_back(it->second.size());
+ }
+ // Schur type solvers, expect at least two elimination groups. If
+ // there is only one elimination group, then CreateReducedProgram
+ // guarantees that this group only contains e_blocks. Thus we add a
+ // dummy elimination group with zero blocks in it.
+ if (IsSchurType(linear_solver_options.type) &&
+ linear_solver_options.elimination_groups.size() == 1) {
+ linear_solver_options.elimination_groups.push_back(0);
+ }
+
return LinearSolver::Create(linear_solver_options);
}
-bool SolverImpl::ApplyUserOrdering(const ProblemImpl& problem_impl,
- vector<double*>& ordering,
- Program* program,
- string* error) {
- if (ordering.size() != program->NumParameterBlocks()) {
+bool SolverImpl::ApplyUserOrdering(
+ const ProblemImpl::ParameterMap& parameter_map,
+ const ParameterBlockOrdering* ordering,
+ Program* program,
+ string* error) {
+ if (ordering->NumElements() != program->NumParameterBlocks()) {
*error = StringPrintf("User specified ordering does not have the same "
"number of parameters as the problem. The problem"
- "has %d blocks while the ordering has %ld blocks.",
+ "has %d blocks while the ordering has %d blocks.",
program->NumParameterBlocks(),
- ordering.size());
+ ordering->NumElements());
return false;
}
- // Ensure that there are no duplicates in the user's ordering.
- {
- vector<double*> ordering_copy(ordering);
- sort(ordering_copy.begin(), ordering_copy.end());
- if (unique(ordering_copy.begin(), ordering_copy.end())
- != ordering_copy.end()) {
- *error = "User specified ordering contains duplicates.";
- return false;
- }
- }
-
vector<ParameterBlock*>* parameter_blocks =
program->mutable_parameter_blocks();
-
- fill(parameter_blocks->begin(),
- parameter_blocks->end(),
- static_cast<ParameterBlock*>(NULL));
-
- const ProblemImpl::ParameterMap& parameter_map = problem_impl.parameter_map();
- for (int i = 0; i < ordering.size(); ++i) {
- ProblemImpl::ParameterMap::const_iterator it =
- parameter_map.find(ordering[i]);
- if (it == parameter_map.end()) {
- *error = StringPrintf("User specified ordering contains a pointer "
- "to a double that is not a parameter block in the "
- "problem. The invalid double is at position %d "
- " in options.ordering.", i);
- return false;
+ parameter_blocks->clear();
+
+ const map<int, set<double*> >& groups =
+ ordering->group_to_elements();
+
+ for (map<int, set<double*> >::const_iterator group_it = groups.begin();
+ group_it != groups.end();
+ ++group_it) {
+ const set<double*>& group = group_it->second;
+ for (set<double*>::const_iterator parameter_block_ptr_it = group.begin();
+ parameter_block_ptr_it != group.end();
+ ++parameter_block_ptr_it) {
+ ProblemImpl::ParameterMap::const_iterator parameter_block_it =
+ parameter_map.find(*parameter_block_ptr_it);
+ if (parameter_block_it == parameter_map.end()) {
+ *error = StringPrintf("User specified ordering contains a pointer "
+ "to a double that is not a parameter block in "
+ "the problem. The invalid double is in group: %d",
+ group_it->first);
+ return false;
+ }
+ parameter_blocks->push_back(parameter_block_it->second);
}
- (*parameter_blocks)[i] = it->second;
}
return true;
}
@@ -704,36 +1247,31 @@ static int MinParameterBlock(const ResidualBlock* residual_block,
// Reorder the residuals for program, if necessary, so that the residuals
// involving each E block occur together. This is a necessary condition for the
// Schur eliminator, which works on these "row blocks" in the jacobian.
-bool SolverImpl::MaybeReorderResidualBlocks(const Solver::Options& options,
- Program* program,
- string* error) {
- // Only Schur types require the lexicographic reordering.
- if (!IsSchurType(options.linear_solver_type)) {
- return true;
- }
-
- CHECK_NE(0, options.num_eliminate_blocks)
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
+bool SolverImpl::LexicographicallyOrderResidualBlocks(
+ const int num_eliminate_blocks,
+ Program* program,
+ string* error) {
+ CHECK_GE(num_eliminate_blocks, 1)
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
// Create a histogram of the number of residuals for each E block. There is an
// extra bucket at the end to catch all non-eliminated F blocks.
- vector<int> residual_blocks_per_e_block(options.num_eliminate_blocks + 1);
+ vector<int> residual_blocks_per_e_block(num_eliminate_blocks + 1);
vector<ResidualBlock*>* residual_blocks = program->mutable_residual_blocks();
vector<int> min_position_per_residual(residual_blocks->size());
for (int i = 0; i < residual_blocks->size(); ++i) {
ResidualBlock* residual_block = (*residual_blocks)[i];
- int position = MinParameterBlock(residual_block,
- options.num_eliminate_blocks);
+ int position = MinParameterBlock(residual_block, num_eliminate_blocks);
min_position_per_residual[i] = position;
- DCHECK_LE(position, options.num_eliminate_blocks);
+ DCHECK_LE(position, num_eliminate_blocks);
residual_blocks_per_e_block[position]++;
}
// Run a cumulative sum on the histogram, to obtain offsets to the start of
// each histogram bucket (where each bucket is for the residuals for that
// E-block).
- vector<int> offsets(options.num_eliminate_blocks + 1);
+ vector<int> offsets(num_eliminate_blocks + 1);
std::partial_sum(residual_blocks_per_e_block.begin(),
residual_blocks_per_e_block.end(),
offsets.begin());
@@ -772,7 +1310,7 @@ bool SolverImpl::MaybeReorderResidualBlocks(const Solver::Options& options,
// Sanity check #1: The difference in bucket offsets should match the
// histogram sizes.
- for (int i = 0; i < options.num_eliminate_blocks; ++i) {
+ for (int i = 0; i < num_eliminate_blocks; ++i) {
CHECK_EQ(residual_blocks_per_e_block[i], offsets[i + 1] - offsets[i])
<< "Congratulations, you found a Ceres bug! Please report this error "
<< "to the developers.";
@@ -789,15 +1327,76 @@ bool SolverImpl::MaybeReorderResidualBlocks(const Solver::Options& options,
return true;
}
-Evaluator* SolverImpl::CreateEvaluator(const Solver::Options& options,
- Program* program,
- string* error) {
+Evaluator* SolverImpl::CreateEvaluator(
+ const Solver::Options& options,
+ const ProblemImpl::ParameterMap& parameter_map,
+ Program* program,
+ string* error) {
Evaluator::Options evaluator_options;
evaluator_options.linear_solver_type = options.linear_solver_type;
- evaluator_options.num_eliminate_blocks = options.num_eliminate_blocks;
+ evaluator_options.num_eliminate_blocks =
+ (options.linear_solver_ordering->NumGroups() > 0 &&
+ IsSchurType(options.linear_solver_type))
+ ? (options.linear_solver_ordering
+ ->group_to_elements().begin()
+ ->second.size())
+ : 0;
evaluator_options.num_threads = options.num_threads;
return Evaluator::Create(evaluator_options, program, error);
}
+CoordinateDescentMinimizer* SolverImpl::CreateInnerIterationMinimizer(
+ const Solver::Options& options,
+ const Program& program,
+ const ProblemImpl::ParameterMap& parameter_map,
+ Solver::Summary* summary) {
+ scoped_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer(
+ new CoordinateDescentMinimizer);
+ scoped_ptr<ParameterBlockOrdering> inner_iteration_ordering;
+ ParameterBlockOrdering* ordering_ptr = NULL;
+
+ if (options.inner_iteration_ordering == NULL) {
+ // Find a recursive decomposition of the Hessian matrix as a set
+ // of independent sets of decreasing size and invert it. This
+ // seems to work better in practice, i.e., Cameras before
+ // points.
+ inner_iteration_ordering.reset(new ParameterBlockOrdering);
+ ComputeRecursiveIndependentSetOrdering(program,
+ inner_iteration_ordering.get());
+ inner_iteration_ordering->Reverse();
+ ordering_ptr = inner_iteration_ordering.get();
+ } else {
+ const map<int, set<double*> >& group_to_elements =
+ options.inner_iteration_ordering->group_to_elements();
+
+ // Iterate over each group and verify that it is an independent
+ // set.
+ map<int, set<double*> >::const_iterator it = group_to_elements.begin();
+ for ( ; it != group_to_elements.end(); ++it) {
+ if (!IsParameterBlockSetIndependent(it->second,
+ program.residual_blocks())) {
+ summary->error =
+ StringPrintf("The user-provided "
+ "parameter_blocks_for_inner_iterations does not "
+ "form an independent set. Group Id: %d", it->first);
+ return NULL;
+ }
+ }
+ ordering_ptr = options.inner_iteration_ordering;
+ }
+
+ if (!inner_iteration_minimizer->Init(program,
+ parameter_map,
+ *ordering_ptr,
+ &summary->error)) {
+ return NULL;
+ }
+
+ summary->inner_iterations = true;
+ SummarizeOrdering(ordering_ptr, &(summary->inner_iteration_ordering_used));
+
+ return inner_iteration_minimizer.release();
+}
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h
index 11b44de6f42..c5f5efad3d7 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h
@@ -31,17 +31,20 @@
#ifndef CERES_INTERNAL_SOLVER_IMPL_H_
#define CERES_INTERNAL_SOLVER_IMPL_H_
+#include <set>
#include <string>
#include <vector>
#include "ceres/internal/port.h"
+#include "ceres/ordered_groups.h"
+#include "ceres/problem_impl.h"
#include "ceres/solver.h"
namespace ceres {
namespace internal {
+class CoordinateDescentMinimizer;
class Evaluator;
class LinearSolver;
-class ProblemImpl;
class Program;
class SolverImpl {
@@ -52,10 +55,19 @@ class SolverImpl {
ProblemImpl* problem_impl,
Solver::Summary* summary);
+ static void TrustRegionSolve(const Solver::Options& options,
+ ProblemImpl* problem_impl,
+ Solver::Summary* summary);
+
+ static void LineSearchSolve(const Solver::Options& options,
+ ProblemImpl* problem_impl,
+ Solver::Summary* summary);
+
// Create the transformed Program, which has all the fixed blocks
// and residuals eliminated, and in the case of automatic schur
// ordering, has the E blocks first in the resulting program, with
// options.num_eliminate_blocks set appropriately.
+ //
// If fixed_cost is not NULL, the residual blocks that are removed
// are evaluated and the sum of their cost is returned in fixed_cost.
static Program* CreateReducedProgram(Solver::Options* options,
@@ -71,46 +83,73 @@ class SolverImpl {
static LinearSolver* CreateLinearSolver(Solver::Options* options,
string* error);
- // Reorder the parameter blocks in program using the vector
- // ordering. A return value of true indicates success and false
- // indicates an error was encountered whose cause is logged to
- // LOG(ERROR).
- static bool ApplyUserOrdering(const ProblemImpl& problem_impl,
- vector<double*>& ordering,
+ // Reorder the parameter blocks in program using the ordering. A
+ // return value of true indicates success and false indicates an
+ // error was encountered whose cause is logged to LOG(ERROR).
+ static bool ApplyUserOrdering(const ProblemImpl::ParameterMap& parameter_map,
+ const ParameterBlockOrdering* ordering,
Program* program,
string* error);
+
// Reorder the residuals for program, if necessary, so that the
- // residuals involving each E block occur together. This is a
- // necessary condition for the Schur eliminator, which works on
- // these "row blocks" in the jacobian.
- static bool MaybeReorderResidualBlocks(const Solver::Options& options,
- Program* program,
- string* error);
+ // residuals involving e block (i.e., the first num_eliminate_block
+ // parameter blocks) occur together. This is a necessary condition
+ // for the Schur eliminator.
+ static bool LexicographicallyOrderResidualBlocks(
+ const int num_eliminate_blocks,
+ Program* program,
+ string* error);
// Create the appropriate evaluator for the transformed program.
- static Evaluator* CreateEvaluator(const Solver::Options& options,
- Program* program,
- string* error);
-
- // Run the minimization for the given evaluator and configuration.
- static void Minimize(const Solver::Options &options,
- Program* program,
- Evaluator* evaluator,
- LinearSolver* linear_solver,
- double* parameters,
- Solver::Summary* summary);
+ static Evaluator* CreateEvaluator(
+ const Solver::Options& options,
+ const ProblemImpl::ParameterMap& parameter_map,
+ Program* program,
+ string* error);
+
+ // Run the TrustRegionMinimizer for the given evaluator and configuration.
+ static void TrustRegionMinimize(
+ const Solver::Options &options,
+ Program* program,
+ CoordinateDescentMinimizer* inner_iteration_minimizer,
+ Evaluator* evaluator,
+ LinearSolver* linear_solver,
+ double* parameters,
+ Solver::Summary* summary);
+
+ // Run the LineSearchMinimizer for the given evaluator and configuration.
+ static void LineSearchMinimize(
+ const Solver::Options &options,
+ Program* program,
+ Evaluator* evaluator,
+ double* parameters,
+ Solver::Summary* summary);
// Remove the fixed or unused parameter blocks and residuals
// depending only on fixed parameters from the problem. Also updates
// num_eliminate_blocks, since removed parameters changes the point
- // at which the eliminated blocks is valid.
- // If fixed_cost is not NULL, the residual blocks that are removed
- // are evaluated and the sum of their cost is returned in fixed_cost.
+ // at which the eliminated blocks is valid. If fixed_cost is not
+ // NULL, the residual blocks that are removed are evaluated and the
+ // sum of their cost is returned in fixed_cost.
static bool RemoveFixedBlocksFromProgram(Program* program,
- int* num_eliminate_blocks,
+ ParameterBlockOrdering* ordering,
double* fixed_cost,
string* error);
+
+ static bool IsOrderingValid(const Solver::Options& options,
+ const ProblemImpl* problem_impl,
+ string* error);
+
+ static bool IsParameterBlockSetIndependent(
+ const set<double*>& parameter_block_ptrs,
+ const vector<ResidualBlock*>& residual_blocks);
+
+ static CoordinateDescentMinimizer* CreateInnerIterationMinimizer(
+ const Solver::Options& options,
+ const Program& program,
+ const ProblemImpl::ParameterMap& parameter_map,
+ Solver::Summary* summary);
};
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc
index 9e00b4402dc..dd05f0c6f41 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc
@@ -39,12 +39,13 @@
#endif
#include "ceres/compressed_row_sparse_matrix.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/scoped_ptr.h"
#include "ceres/linear_solver.h"
#include "ceres/suitesparse.h"
#include "ceres/triplet_sparse_matrix.h"
-#include "ceres/internal/eigen.h"
-#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
+#include "ceres/wall_time.h"
namespace ceres {
namespace internal {
@@ -103,6 +104,8 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse(
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double * x) {
+ EventLogger event_logger("SparseNormalCholeskySolver::CXSparse::Solve");
+
LinearSolver::Summary summary;
summary.num_iterations = 1;
const int num_cols = A->num_cols();
@@ -129,25 +132,34 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse(
// off of Jt to compute the Cholesky factorization of the normal
// equations.
cs_di* A2 = cs_transpose(&At, 1);
- cs_di* AtA = cs_multiply(&At,A2);
+ cs_di* AtA = cs_multiply(&At, A2);
cxsparse_.Free(A2);
if (per_solve_options.D != NULL) {
A->DeleteRows(num_cols);
}
+ event_logger.AddEvent("Setup");
+
// Compute symbolic factorization if not available.
if (cxsparse_factor_ == NULL) {
cxsparse_factor_ = CHECK_NOTNULL(cxsparse_.AnalyzeCholesky(AtA));
}
+ event_logger.AddEvent("Analysis");
+
+
// Solve the linear system.
if (cxsparse_.SolveCholesky(AtA, cxsparse_factor_, Atb.data())) {
VectorRef(x, Atb.rows()) = Atb;
summary.termination_type = TOLERANCE;
}
+ event_logger.AddEvent("Solve");
+
cxsparse_.Free(AtA);
+
+ event_logger.AddEvent("Teardown");
return summary;
}
#else
@@ -169,9 +181,9 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double * x) {
- const time_t start_time = time(NULL);
- const int num_cols = A->num_cols();
+ EventLogger event_logger("SparseNormalCholeskySolver::SuiteSparse::Solve");
+ const int num_cols = A->num_cols();
LinearSolver::Summary summary;
Vector Atb = Vector::Zero(num_cols);
A->LeftMultiply(b, Atb.data());
@@ -189,7 +201,7 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
CHECK_NOTNULL(lhs.get());
cholmod_dense* rhs = ss_.CreateDenseVector(Atb.data(), num_cols, num_cols);
- const time_t init_time = time(NULL);
+ event_logger.AddEvent("Setup");
if (factor_ == NULL) {
if (options_.use_block_amd) {
@@ -206,11 +218,10 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
}
CHECK_NOTNULL(factor_);
-
- const time_t symbolic_time = time(NULL);
+ event_logger.AddEvent("Analysis");
cholmod_dense* sol = ss_.SolveCholesky(lhs.get(), factor_, rhs);
- const time_t solve_time = time(NULL);
+ event_logger.AddEvent("Solve");
ss_.Free(rhs);
rhs = NULL;
@@ -228,12 +239,7 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
summary.termination_type = TOLERANCE;
}
- const time_t cleanup_time = time(NULL);
- VLOG(2) << "time (sec) total: " << (cleanup_time - start_time)
- << " init: " << (init_time - start_time)
- << " symbolic: " << (symbolic_time - init_time)
- << " solve: " << (solve_time - symbolic_time)
- << " cleanup: " << (cleanup_time - solve_time);
+ event_logger.AddEvent("Teardown");
return summary;
}
#else
diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h
index 40d9e0a0327..8d48096d4c6 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h
@@ -35,8 +35,8 @@
#define CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
#include "ceres/cxsparse.h"
-#include "ceres/linear_solver.h"
#include "ceres/internal/macros.h"
+#include "ceres/linear_solver.h"
#include "ceres/suitesparse.h"
namespace ceres {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/split.cc b/extern/libmv/third_party/ceres/internal/ceres/split.cc
index c65c8a5bb5d..3edbc281340 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/split.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/split.cc
@@ -28,10 +28,11 @@
//
// Author: keir@google.com (Keir Mierle)
+#include "ceres/split.h"
+
#include <string>
#include <vector>
#include <iterator>
-#include "ceres/split.h"
#include "ceres/internal/port.h"
namespace ceres {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/split.h b/extern/libmv/third_party/ceres/internal/ceres/split.h
index ec579e974da..4df48c3a7cd 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/split.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/split.h
@@ -2,7 +2,7 @@
// Author: keir@google.com (Keir Mierle)
#ifndef CERES_INTERNAL_SPLIT_H_
-#define VISION_OPTIMIZATION_LEAST_SQUARES_INTERNAL_SPLIT_H_
+#define CERES_INTERNAL_SPLIT_H_
#include <string>
#include <vector>
diff --git a/extern/libmv/third_party/ceres/internal/ceres/stl_util.h b/extern/libmv/third_party/ceres/internal/ceres/stl_util.h
index a1a19e8b3ce..08f15ec8398 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/stl_util.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/stl_util.h
@@ -31,6 +31,8 @@
#ifndef CERES_INTERNAL_STL_UTIL_H_
#define CERES_INTERNAL_STL_UTIL_H_
+#include <algorithm>
+
namespace ceres {
// STLDeleteContainerPointers()
@@ -53,6 +55,20 @@ void STLDeleteContainerPointers(ForwardIterator begin,
}
}
+// Variant of STLDeleteContainerPointers which allows the container to
+// contain duplicates.
+template <class ForwardIterator>
+void STLDeleteUniqueContainerPointers(ForwardIterator begin,
+ ForwardIterator end) {
+ sort(begin, end);
+ ForwardIterator new_end = unique(begin, end);
+ while (begin != new_end) {
+ ForwardIterator temp = begin;
+ ++begin;
+ delete *temp;
+ }
+}
+
// STLDeleteElements() deletes all the elements in an STL container and clears
// the container. This function is suitable for use with a vector, set,
// hash_set, or any other STL container which defines sensible begin(), end(),
diff --git a/extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc
index 396a48b7d97..ce204674dce 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.cc
@@ -28,13 +28,14 @@
//
// Author: Sanjay Ghemawat
+#include "ceres/stringprintf.h"
+
#include <cerrno>
#include <cstdarg> // For va_list and related operations
#include <cstdio> // MSVC requires this for _vsnprintf
#include <string>
#include <vector>
-#include "ceres/stringprintf.h"
#include "ceres/internal/port.h"
namespace ceres {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/stringprintf.h b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.h
index f2f907ab32d..cd1be142aed 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/stringprintf.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/stringprintf.h
@@ -65,17 +65,17 @@ namespace internal {
// Return a C++ string.
extern string StringPrintf(const char* format, ...)
// Tell the compiler to do printf format string checking.
- CERES_PRINTF_ATTRIBUTE(1,2);
+ CERES_PRINTF_ATTRIBUTE(1, 2);
// Store result into a supplied string and return it.
extern const string& SStringPrintf(string* dst, const char* format, ...)
// Tell the compiler to do printf format string checking.
- CERES_PRINTF_ATTRIBUTE(2,3);
+ CERES_PRINTF_ATTRIBUTE(2, 3);
// Append result to a supplied string.
extern void StringAppendF(string* dst, const char* format, ...)
// Tell the compiler to do printf format string checking.
- CERES_PRINTF_ATTRIBUTE(2,3);
+ CERES_PRINTF_ATTRIBUTE(2, 3);
// Lower-level routine that takes a va_list and appends to a specified string.
// All other routines are just convenience wrappers around it.
diff --git a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc
index cf3c48f84e6..d200aeb82f3 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc
@@ -135,10 +135,11 @@ cholmod_factor* SuiteSparse::BlockAnalyzeCholesky(
return AnalyzeCholeskyWithUserOrdering(A, ordering);
}
-cholmod_factor* SuiteSparse::AnalyzeCholeskyWithUserOrdering(cholmod_sparse* A,
- const vector<int>& ordering) {
+cholmod_factor* SuiteSparse::AnalyzeCholeskyWithUserOrdering(
+ cholmod_sparse* A,
+ const vector<int>& ordering) {
CHECK_EQ(ordering.size(), A->nrow);
- cc_.nmethods = 1 ;
+ cc_.nmethods = 1;
cc_.method[0].ordering = CHOLMOD_GIVEN;
cholmod_factor* factor =
cholmod_analyze_p(A, const_cast<int*>(&ordering[0]), NULL, 0, &cc_);
diff --git a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h
index eb691c0c0ed..3fe79080d5d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h
@@ -39,9 +39,9 @@
#include <string>
#include <vector>
-#include <glog/logging.h>
-#include "cholmod.h"
#include "ceres/internal/port.h"
+#include "cholmod.h"
+#include "glog/logging.h"
namespace ceres {
namespace internal {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc
index ed8677ea18a..a09f38ee24e 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/triplet_sparse_matrix.cc
@@ -71,7 +71,8 @@ TripletSparseMatrix::TripletSparseMatrix(int num_rows,
}
TripletSparseMatrix::TripletSparseMatrix(const TripletSparseMatrix& orig)
- : num_rows_(orig.num_rows_),
+ : SparseMatrix(),
+ num_rows_(orig.num_rows_),
num_cols_(orig.num_cols_),
max_num_nonzeros_(orig.max_num_nonzeros_),
num_nonzeros_(orig.num_nonzeros_),
diff --git a/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc
index 76c4f8a7580..981c60a12e7 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc
@@ -45,8 +45,10 @@
#include "ceres/internal/scoped_ptr.h"
#include "ceres/linear_least_squares_problems.h"
#include "ceres/sparse_matrix.h"
+#include "ceres/stringprintf.h"
#include "ceres/trust_region_strategy.h"
#include "ceres/types.h"
+#include "ceres/wall_time.h"
#include "glog/logging.h"
namespace ceres {
@@ -56,28 +58,13 @@ namespace {
const double kEpsilon = 1e-12;
} // namespace
-// Execute the list of IterationCallbacks sequentially. If any one of
-// the callbacks does not return SOLVER_CONTINUE, then stop and return
-// its status.
-CallbackReturnType TrustRegionMinimizer::RunCallbacks(
- const IterationSummary& iteration_summary) {
- for (int i = 0; i < options_.callbacks.size(); ++i) {
- const CallbackReturnType status =
- (*options_.callbacks[i])(iteration_summary);
- if (status != SOLVER_CONTINUE) {
- return status;
- }
- }
- return SOLVER_CONTINUE;
-}
-
// Compute a scaling vector that is used to improve the conditioning
// of the Jacobian.
void TrustRegionMinimizer::EstimateScale(const SparseMatrix& jacobian,
double* scale) const {
jacobian.SquaredColumnNorm(scale);
for (int i = 0; i < jacobian.num_cols(); ++i) {
- scale[i] = 1.0 / (kEpsilon + sqrt(scale[i]));
+ scale[i] = 1.0 / (1.0 + sqrt(scale[i]));
}
}
@@ -96,29 +83,19 @@ bool TrustRegionMinimizer::MaybeDumpLinearLeastSquaresProblem(
// moved inside TrustRegionStrategy, its not clear how we dump the
// regularization vector/matrix anymore.
//
- // Doing this right requires either an API change to the
- // TrustRegionStrategy and/or how LinearLeastSquares problems are
- // stored on disk.
+ // Also num_eliminate_blocks is not visible to the trust region
+ // minimizer either.
//
- // For now, we will just not dump the regularizer.
- return (!binary_search(options_.lsqp_iterations_to_dump.begin(),
- options_.lsqp_iterations_to_dump.end(),
- iteration) ||
- DumpLinearLeastSquaresProblem(options_.lsqp_dump_directory,
- iteration,
- options_.lsqp_dump_format_type,
- jacobian,
- NULL,
- residuals,
- step,
- options_.num_eliminate_blocks));
+ // Both of these indicate that this is the wrong place for this
+ // code, and going forward this should needs fixing/refactoring.
+ return true;
}
void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
double* parameters,
Solver::Summary* summary) {
- time_t start_time = time(NULL);
- time_t iteration_start_time = start_time;
+ double start_time = WallTimeInSeconds();
+ double iteration_start_time = start_time;
Init(options);
summary->termination_type = NO_CONVERGENCE;
@@ -149,7 +126,6 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
iteration_summary.iteration = 0;
iteration_summary.step_is_valid = false;
iteration_summary.step_is_successful = false;
- iteration_summary.cost = summary->initial_cost;
iteration_summary.cost_change = 0.0;
iteration_summary.gradient_max_norm = 0.0;
iteration_summary.step_norm = 0.0;
@@ -169,6 +145,9 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
return;
}
+ summary->initial_cost = cost + summary->fixed_cost;
+ iteration_summary.cost = cost + summary->fixed_cost;
+
int num_consecutive_nonmonotonic_steps = 0;
double minimum_cost = cost;
double reference_cost = cost;
@@ -189,45 +168,34 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
// The initial gradient max_norm is bounded from below so that we do
// not divide by zero.
- const double gradient_max_norm_0 =
+ const double initial_gradient_max_norm =
max(iteration_summary.gradient_max_norm, kEpsilon);
const double absolute_gradient_tolerance =
- options_.gradient_tolerance * gradient_max_norm_0;
+ options_.gradient_tolerance * initial_gradient_max_norm;
if (iteration_summary.gradient_max_norm <= absolute_gradient_tolerance) {
summary->termination_type = GRADIENT_TOLERANCE;
VLOG(1) << "Terminating: Gradient tolerance reached."
<< "Relative gradient max norm: "
- << iteration_summary.gradient_max_norm / gradient_max_norm_0
+ << iteration_summary.gradient_max_norm / initial_gradient_max_norm
<< " <= " << options_.gradient_tolerance;
return;
}
iteration_summary.iteration_time_in_seconds =
- time(NULL) - iteration_start_time;
- iteration_summary.cumulative_time_in_seconds = time(NULL) - start_time +
- summary->preprocessor_time_in_seconds;
+ WallTimeInSeconds() - iteration_start_time;
+ iteration_summary.cumulative_time_in_seconds =
+ WallTimeInSeconds() - start_time
+ + summary->preprocessor_time_in_seconds;
summary->iterations.push_back(iteration_summary);
- // Call the various callbacks.
- switch (RunCallbacks(iteration_summary)) {
- case SOLVER_TERMINATE_SUCCESSFULLY:
- summary->termination_type = USER_SUCCESS;
- VLOG(1) << "Terminating: User callback returned USER_SUCCESS.";
- return;
- case SOLVER_ABORT:
- summary->termination_type = USER_ABORT;
- VLOG(1) << "Terminating: User callback returned USER_ABORT.";
- return;
- case SOLVER_CONTINUE:
- break;
- default:
- LOG(FATAL) << "Unknown type of user callback status";
- }
-
int num_consecutive_invalid_steps = 0;
while (true) {
- iteration_start_time = time(NULL);
+ if (!RunCallbacks(options.callbacks, iteration_summary, summary)) {
+ return;
+ }
+
+ iteration_start_time = WallTimeInSeconds();
if (iteration_summary.iteration >= options_.max_num_iterations) {
summary->termination_type = NO_CONVERGENCE;
VLOG(1) << "Terminating: Maximum number of iterations reached.";
@@ -248,7 +216,7 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
iteration_summary.step_is_valid = false;
iteration_summary.step_is_successful = false;
- const time_t strategy_start_time = time(NULL);
+ const double strategy_start_time = WallTimeInSeconds();
TrustRegionStrategy::PerSolveOptions per_solve_options;
per_solve_options.eta = options_.eta;
TrustRegionStrategy::Summary strategy_summary =
@@ -258,7 +226,7 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
trust_region_step.data());
iteration_summary.step_solver_time_in_seconds =
- time(NULL) - strategy_start_time;
+ WallTimeInSeconds() - strategy_start_time;
iteration_summary.linear_solver_iterations =
strategy_summary.num_iterations;
@@ -270,23 +238,24 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
<< options.lsqp_dump_directory << "but failed.";
}
- double new_model_cost = 0.0;
+ double model_cost_change = 0.0;
if (strategy_summary.termination_type != FAILURE) {
- // new_model_cost = 1/2 |f + J * step|^2
- model_residuals = residuals;
+ // new_model_cost
+ // = 1/2 [f + J * step]^2
+ // = 1/2 [ f'f + 2f'J * step + step' * J' * J * step ]
+ // model_cost_change
+ // = cost - new_model_cost
+ // = f'f/2 - 1/2 [ f'f + 2f'J * step + step' * J' * J * step]
+ // = -f'J * step - step' * J' * J * step / 2
+ model_residuals.setZero();
jacobian->RightMultiply(trust_region_step.data(), model_residuals.data());
- new_model_cost = model_residuals.squaredNorm() / 2.0;
-
- // In exact arithmetic, this would never be the case. But poorly
- // conditioned matrices can give rise to situations where the
- // new_model_cost can actually be larger than half the squared
- // norm of the residual vector. We allow for small tolerance
- // around cost and beyond that declare the step to be invalid.
- if ((1.0 - new_model_cost / cost) < -kEpsilon) {
+ model_cost_change = -(residuals.dot(model_residuals) +
+ model_residuals.squaredNorm() / 2.0);
+
+ if (model_cost_change < 0.0) {
VLOG(1) << "Invalid step: current_cost: " << cost
- << " new_model_cost " << new_model_cost
- << " absolute difference " << (cost - new_model_cost)
- << " relative difference " << (1.0 - new_model_cost/cost);
+ << " absolute difference " << model_cost_change
+ << " relative difference " << (model_cost_change / cost);
} else {
iteration_summary.step_is_valid = true;
}
@@ -299,10 +268,12 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
if (++num_consecutive_invalid_steps >=
options_.max_num_consecutive_invalid_steps) {
summary->termination_type = NUMERICAL_FAILURE;
- LOG(WARNING) << "Terminating. Number of successive invalid steps more "
- << "than "
- << "Solver::Options::max_num_consecutive_invalid_steps: "
- << options_.max_num_consecutive_invalid_steps;
+ summary->error = StringPrintf(
+ "Terminating. Number of successive invalid steps more "
+ "than Solver::Options::max_num_consecutive_invalid_steps: %d",
+ options_.max_num_consecutive_invalid_steps);
+
+ LOG(WARNING) << summary->error;
return;
}
@@ -311,7 +282,7 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
// as an unsuccessful iteration. Since the various callbacks are
// still executed, we are going to fill the iteration summary
// with data that assumes a step of length zero and no progress.
- iteration_summary.cost = cost;
+ iteration_summary.cost = cost + summary->fixed_cost;
iteration_summary.cost_change = 0.0;
iteration_summary.gradient_max_norm =
summary->iterations.back().gradient_max_norm;
@@ -322,51 +293,19 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
// The step is numerically valid, so now we can judge its quality.
num_consecutive_invalid_steps = 0;
- // We allow some slop around 0, and clamp the model_cost_change
- // at kEpsilon * min(1.0, cost) from below.
- //
- // In exact arithmetic this should never be needed, as we are
- // guaranteed to new_model_cost <= cost. However, due to various
- // numerical issues, it is possible that new_model_cost is
- // nearly equal to cost, and the difference is a small negative
- // number. To make sure that the relative_decrease computation
- // remains sane, as clamp the difference (cost - new_model_cost)
- // from below at a small positive number.
- //
- // This number is the minimum of kEpsilon * (cost, 1.0), which
- // ensures that it will never get too large in absolute value,
- // while scaling down proportionally with the magnitude of the
- // cost. This is important for problems where the minimum of the
- // objective function is near zero.
- const double model_cost_change =
- max(kEpsilon * min(1.0, cost), cost - new_model_cost);
-
// Undo the Jacobian column scaling.
delta = (trust_region_step.array() * scale.array()).matrix();
- iteration_summary.step_norm = delta.norm();
-
- // Convergence based on parameter_tolerance.
- const double step_size_tolerance = options_.parameter_tolerance *
- (x_norm + options_.parameter_tolerance);
- if (iteration_summary.step_norm <= step_size_tolerance) {
- VLOG(1) << "Terminating. Parameter tolerance reached. "
- << "relative step_norm: "
- << iteration_summary.step_norm /
- (x_norm + options_.parameter_tolerance)
- << " <= " << options_.parameter_tolerance;
- summary->termination_type = PARAMETER_TOLERANCE;
- return;
- }
-
if (!evaluator->Plus(x.data(), delta.data(), x_plus_delta.data())) {
summary->termination_type = NUMERICAL_FAILURE;
- LOG(WARNING) << "Terminating. Failed to compute "
- << "Plus(x, delta, x_plus_delta).";
+ summary->error =
+ "Terminating. Failed to compute Plus(x, delta, x_plus_delta).";
+
+ LOG(WARNING) << summary->error;
return;
}
// Try this step.
- double new_cost;
+ double new_cost = numeric_limits<double>::max();
if (!evaluator->Evaluate(x_plus_delta.data(),
&new_cost,
NULL, NULL, NULL)) {
@@ -375,6 +314,45 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
LOG(WARNING) << "Step failed to evaluate. "
<< "Treating it as step with infinite cost";
new_cost = numeric_limits<double>::max();
+ } else {
+ // Check if performing an inner iteration will make it better.
+ if (options.inner_iteration_minimizer != NULL) {
+ const double x_plus_delta_cost = new_cost;
+ Vector inner_iteration_x = x_plus_delta;
+ Solver::Summary inner_iteration_summary;
+ options.inner_iteration_minimizer->Minimize(options,
+ inner_iteration_x.data(),
+ &inner_iteration_summary);
+ if (!evaluator->Evaluate(inner_iteration_x.data(),
+ &new_cost,
+ NULL, NULL, NULL)) {
+ VLOG(2) << "Inner iteration failed.";
+ new_cost = x_plus_delta_cost;
+ } else {
+ x_plus_delta = inner_iteration_x;
+ // Boost the model_cost_change, since the inner iteration
+ // improvements are not accounted for by the trust region.
+ model_cost_change += x_plus_delta_cost - new_cost;
+ VLOG(2) << "Inner iteration succeeded; current cost: " << cost
+ << " x_plus_delta_cost: " << x_plus_delta_cost
+ << " new_cost: " << new_cost;
+ }
+ }
+ }
+
+ iteration_summary.step_norm = (x - x_plus_delta).norm();
+
+ // Convergence based on parameter_tolerance.
+ const double step_size_tolerance = options_.parameter_tolerance *
+ (x_norm + options_.parameter_tolerance);
+ if (iteration_summary.step_norm <= step_size_tolerance) {
+ VLOG(1) << "Terminating. Parameter tolerance reached. "
+ << "relative step_norm: "
+ << iteration_summary.step_norm /
+ (x_norm + options_.parameter_tolerance)
+ << " <= " << options_.parameter_tolerance;
+ summary->termination_type = PARAMETER_TOLERANCE;
+ return;
}
VLOG(2) << "old cost: " << cost << " new cost: " << new_cost;
@@ -421,6 +399,7 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
accumulated_candidate_model_cost_change += model_cost_change;
accumulated_reference_model_cost_change += model_cost_change;
if (relative_decrease <= options_.min_relative_decrease) {
+ iteration_summary.step_is_nonmonotonic = true;
VLOG(2) << "Non-monotonic step! "
<< " relative_decrease: " << relative_decrease
<< " historical_relative_decrease: "
@@ -443,7 +422,9 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
NULL,
jacobian)) {
summary->termination_type = NUMERICAL_FAILURE;
- LOG(WARNING) << "Terminating: Residual and Jacobian evaluation failed.";
+ summary->error =
+ "Terminating: Residual and Jacobian evaluation failed.";
+ LOG(WARNING) << summary->error;
return;
}
@@ -455,7 +436,8 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
summary->termination_type = GRADIENT_TOLERANCE;
VLOG(1) << "Terminating: Gradient tolerance reached."
<< "Relative gradient max norm: "
- << iteration_summary.gradient_max_norm / gradient_max_norm_0
+ << (iteration_summary.gradient_max_norm /
+ initial_gradient_max_norm)
<< " <= " << options_.gradient_tolerance;
return;
}
@@ -523,25 +505,11 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
}
iteration_summary.iteration_time_in_seconds =
- time(NULL) - iteration_start_time;
- iteration_summary.cumulative_time_in_seconds = time(NULL) - start_time +
- summary->preprocessor_time_in_seconds;
+ WallTimeInSeconds() - iteration_start_time;
+ iteration_summary.cumulative_time_in_seconds =
+ WallTimeInSeconds() - start_time
+ + summary->preprocessor_time_in_seconds;
summary->iterations.push_back(iteration_summary);
-
- switch (RunCallbacks(iteration_summary)) {
- case SOLVER_TERMINATE_SUCCESSFULLY:
- summary->termination_type = USER_SUCCESS;
- VLOG(1) << "Terminating: User callback returned USER_SUCCESS.";
- return;
- case SOLVER_ABORT:
- summary->termination_type = USER_ABORT;
- VLOG(1) << "Terminating: User callback returned USER_ABORT.";
- return;
- case SOLVER_CONTINUE:
- break;
- default:
- LOG(FATAL) << "Unknown type of user callback status";
- }
}
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.h
index a4f5ba3674d..9a022843233 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.h
@@ -39,8 +39,7 @@ namespace ceres {
namespace internal {
// Generic trust region minimization algorithm. The heavy lifting is
-// done by a TrustRegionStrategy object passed in as one of the
-// arguments to the Minimize method.
+// done by a TrustRegionStrategy object passed in as part of options.
//
// For example usage, see SolverImpl::Minimize.
class TrustRegionMinimizer : public Minimizer {
@@ -53,11 +52,10 @@ class TrustRegionMinimizer : public Minimizer {
private:
void Init(const Minimizer::Options& options);
void EstimateScale(const SparseMatrix& jacobian, double* scale) const;
- CallbackReturnType RunCallbacks(const IterationSummary& iteration_summary);
- bool MaybeDumpLinearLeastSquaresProblem( const int iteration,
- const SparseMatrix* jacobian,
- const double* residuals,
- const double* step) const;
+ bool MaybeDumpLinearLeastSquaresProblem(const int iteration,
+ const SparseMatrix* jacobian,
+ const double* residuals,
+ const double* step) const;
Minimizer::Options options_;
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.cc b/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.cc
index 89bc19d084b..c68269d0449 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.cc
@@ -1,3 +1,35 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012, 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+// keir@google.com (Keir Mierle)
+
#include "ceres/trust_region_strategy.h"
#include "ceres/dogleg_strategy.h"
#include "ceres/levenberg_marquardt_strategy.h"
diff --git a/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.h b/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.h
index 391da97d5eb..f150594bbd2 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/trust_region_strategy.h
@@ -52,7 +52,7 @@ class SparseMatrix;
// radius to scale the damping term, which controls the step size, but
// does not set a hard limit on its size.
class TrustRegionStrategy {
-public:
+ public:
struct Options {
Options()
: trust_region_strategy_type(LEVENBERG_MARQUARDT),
diff --git a/extern/libmv/third_party/ceres/internal/ceres/types.cc b/extern/libmv/third_party/ceres/internal/ceres/types.cc
index 05e573ff6d5..2e19322cc76 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/types.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/types.cc
@@ -28,15 +28,23 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+#include <algorithm>
+#include <cctype>
#include <string>
#include "ceres/types.h"
+#include "glog/logging.h"
namespace ceres {
#define CASESTR(x) case x: return #x
+#define STRENUM(x) if (value == #x) { *type = x; return true;}
-const char* LinearSolverTypeToString(LinearSolverType solver_type) {
- switch (solver_type) {
+static void UpperCase(string* input) {
+ std::transform(input->begin(), input->end(), input->begin(), ::toupper);
+}
+
+const char* LinearSolverTypeToString(LinearSolverType type) {
+ switch (type) {
CASESTR(DENSE_NORMAL_CHOLESKY);
CASESTR(DENSE_QR);
CASESTR(SPARSE_NORMAL_CHOLESKY);
@@ -49,9 +57,20 @@ const char* LinearSolverTypeToString(LinearSolverType solver_type) {
}
}
-const char* PreconditionerTypeToString(
- PreconditionerType preconditioner_type) {
- switch (preconditioner_type) {
+bool StringToLinearSolverType(string value, LinearSolverType* type) {
+ UpperCase(&value);
+ STRENUM(DENSE_NORMAL_CHOLESKY);
+ STRENUM(DENSE_QR);
+ STRENUM(SPARSE_NORMAL_CHOLESKY);
+ STRENUM(DENSE_SCHUR);
+ STRENUM(SPARSE_SCHUR);
+ STRENUM(ITERATIVE_SCHUR);
+ STRENUM(CGNR);
+ return false;
+}
+
+const char* PreconditionerTypeToString(PreconditionerType type) {
+ switch (type) {
CASESTR(IDENTITY);
CASESTR(JACOBI);
CASESTR(SCHUR_JACOBI);
@@ -62,9 +81,19 @@ const char* PreconditionerTypeToString(
}
}
+bool StringToPreconditionerType(string value, PreconditionerType* type) {
+ UpperCase(&value);
+ STRENUM(IDENTITY);
+ STRENUM(JACOBI);
+ STRENUM(SCHUR_JACOBI);
+ STRENUM(CLUSTER_JACOBI);
+ STRENUM(CLUSTER_TRIDIAGONAL);
+ return false;
+}
+
const char* SparseLinearAlgebraLibraryTypeToString(
- SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type) {
- switch (sparse_linear_algebra_library_type) {
+ SparseLinearAlgebraLibraryType type) {
+ switch (type) {
CASESTR(SUITE_SPARSE);
CASESTR(CX_SPARSE);
default:
@@ -72,19 +101,121 @@ const char* SparseLinearAlgebraLibraryTypeToString(
}
}
-const char* OrderingTypeToString(OrderingType ordering_type) {
- switch (ordering_type) {
- CASESTR(NATURAL);
- CASESTR(USER);
- CASESTR(SCHUR);
+
+bool StringToSparseLinearAlgebraLibraryType(
+ string value,
+ SparseLinearAlgebraLibraryType* type) {
+ UpperCase(&value);
+ STRENUM(SUITE_SPARSE);
+ STRENUM(CX_SPARSE);
+ return false;
+}
+
+const char* TrustRegionStrategyTypeToString(TrustRegionStrategyType type) {
+ switch (type) {
+ CASESTR(LEVENBERG_MARQUARDT);
+ CASESTR(DOGLEG);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+bool StringToTrustRegionStrategyType(string value,
+ TrustRegionStrategyType* type) {
+ UpperCase(&value);
+ STRENUM(LEVENBERG_MARQUARDT);
+ STRENUM(DOGLEG);
+ return false;
+}
+
+const char* DoglegTypeToString(DoglegType type) {
+ switch (type) {
+ CASESTR(TRADITIONAL_DOGLEG);
+ CASESTR(SUBSPACE_DOGLEG);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+bool StringToDoglegType(string value, DoglegType* type) {
+ UpperCase(&value);
+ STRENUM(TRADITIONAL_DOGLEG);
+ STRENUM(SUBSPACE_DOGLEG);
+ return false;
+}
+
+const char* MinimizerTypeToString(MinimizerType type) {
+ switch (type) {
+ CASESTR(TRUST_REGION);
+ CASESTR(LINE_SEARCH);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+bool StringToMinimizerType(string value, MinimizerType* type) {
+ UpperCase(&value);
+ STRENUM(TRUST_REGION);
+ STRENUM(LINE_SEARCH);
+ return false;
+}
+
+const char* LineSearchDirectionTypeToString(LineSearchDirectionType type) {
+ switch (type) {
+ CASESTR(STEEPEST_DESCENT);
+ CASESTR(NONLINEAR_CONJUGATE_GRADIENT);
+ CASESTR(LBFGS);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+bool StringToLineSearchDirectionType(string value,
+ LineSearchDirectionType* type) {
+ UpperCase(&value);
+ STRENUM(STEEPEST_DESCENT);
+ STRENUM(NONLINEAR_CONJUGATE_GRADIENT);
+ STRENUM(LBFGS);
+ return false;
+}
+
+const char* LineSearchTypeToString(LineSearchType type) {
+ switch (type) {
+ CASESTR(ARMIJO);
default:
return "UNKNOWN";
}
}
-const char* SolverTerminationTypeToString(
- SolverTerminationType termination_type) {
- switch (termination_type) {
+bool StringToLineSearchType(string value, LineSearchType* type) {
+ UpperCase(&value);
+ STRENUM(ARMIJO);
+ return false;
+}
+
+const char* NonlinearConjugateGradientTypeToString(
+ NonlinearConjugateGradientType type) {
+ switch (type) {
+ CASESTR(FLETCHER_REEVES);
+ CASESTR(POLAK_RIBIRERE);
+ CASESTR(HESTENES_STIEFEL);
+ default:
+ return "UNKNOWN";
+ }
+}
+
+bool StringToNonlinearConjugateGradientType(
+ string value,
+ NonlinearConjugateGradientType* type) {
+ UpperCase(&value);
+ STRENUM(FLETCHER_REEVES);
+ STRENUM(POLAK_RIBIRERE);
+ STRENUM(HESTENES_STIEFEL);
+ return false;
+}
+
+const char* SolverTerminationTypeToString(SolverTerminationType type) {
+ switch (type) {
CASESTR(NO_CONVERGENCE);
CASESTR(FUNCTION_TOLERANCE);
CASESTR(GRADIENT_TOLERANCE);
@@ -98,29 +229,20 @@ const char* SolverTerminationTypeToString(
}
}
-#if 0 /* UNUSED */
-static const char* SparseLinearAlgebraTypeToString(
- SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type) {
- switch (sparse_linear_algebra_library_type) {
- CASESTR(CX_SPARSE);
- CASESTR(SUITE_SPARSE);
- default:
- return "UNKNOWN";
- }
-}
-#endif
-
-const char* TrustRegionStrategyTypeToString(
- TrustRegionStrategyType trust_region_strategy_type) {
- switch (trust_region_strategy_type) {
- CASESTR(LEVENBERG_MARQUARDT);
- CASESTR(DOGLEG);
+const char* LinearSolverTerminationTypeToString(
+ LinearSolverTerminationType type) {
+ switch (type) {
+ CASESTR(TOLERANCE);
+ CASESTR(MAX_ITERATIONS);
+ CASESTR(STAGNATION);
+ CASESTR(FAILURE);
default:
return "UNKNOWN";
}
}
#undef CASESTR
+#undef STRENUM
bool IsSchurType(LinearSolverType type) {
return ((type == SPARSE_SCHUR) ||
@@ -128,4 +250,26 @@ bool IsSchurType(LinearSolverType type) {
(type == ITERATIVE_SCHUR));
}
+bool IsSparseLinearAlgebraLibraryTypeAvailable(
+ SparseLinearAlgebraLibraryType type) {
+ if (type == SUITE_SPARSE) {
+#ifdef CERES_NO_SUITESPARSE
+ return false;
+#else
+ return true;
+#endif
+ }
+
+ if (type == CX_SPARSE) {
+#ifdef CERES_NO_CXSPARSE
+ return false;
+#else
+ return true;
+#endif
+ }
+
+ LOG(WARNING) << "Unknown sparse linear algebra library " << type;
+ return false;
+}
+
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility.cc b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
index 564cc54493e..8e80fd121bb 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
@@ -28,6 +28,8 @@
//
// Author: kushalav@google.com (Avanish Kushal)
+#include "ceres/visibility.h"
+
#include <cmath>
#include <ctime>
#include <algorithm>
@@ -36,7 +38,6 @@
#include <utility>
#include "ceres/block_structure.h"
#include "ceres/collections_port.h"
-#include "ceres/visibility.h"
#include "ceres/graph.h"
#include "glog/logging.h"
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility.h b/extern/libmv/third_party/ceres/internal/ceres/visibility.h
index 692dd87201e..f29e3c6a0a8 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility.h
@@ -42,7 +42,7 @@
namespace ceres {
namespace internal {
-class CompressedRowBlockStructure;
+struct CompressedRowBlockStructure;
// Given a compressed row block structure, computes the set of
// e_blocks "visible" to each f_block. If an e_block co-occurs with an
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc
index 4caad03d7a1..a75d6f0c17e 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc
@@ -65,17 +65,17 @@ static const double kSimilarityPenaltyWeight = 0.0;
#ifndef CERES_NO_SUITESPARSE
VisibilityBasedPreconditioner::VisibilityBasedPreconditioner(
const CompressedRowBlockStructure& bs,
- const LinearSolver::Options& options)
+ const Preconditioner::Options& options)
: options_(options),
num_blocks_(0),
num_clusters_(0),
factor_(NULL) {
- CHECK_GT(options_.num_eliminate_blocks, 0);
- CHECK(options_.preconditioner_type == SCHUR_JACOBI ||
- options_.preconditioner_type == CLUSTER_JACOBI ||
- options_.preconditioner_type == CLUSTER_TRIDIAGONAL)
- << "Unknown preconditioner type: " << options_.preconditioner_type;
- num_blocks_ = bs.cols.size() - options_.num_eliminate_blocks;
+ CHECK_GT(options_.elimination_groups.size(), 1);
+ CHECK_GT(options_.elimination_groups[0], 0);
+ CHECK(options_.type == CLUSTER_JACOBI ||
+ options_.type == CLUSTER_TRIDIAGONAL)
+ << "Unknown preconditioner type: " << options_.type;
+ num_blocks_ = bs.cols.size() - options_.elimination_groups[0];
CHECK_GT(num_blocks_, 0)
<< "Jacobian should have atleast 1 f_block for "
<< "visibility based preconditioning.";
@@ -83,14 +83,11 @@ VisibilityBasedPreconditioner::VisibilityBasedPreconditioner(
// Vector of camera block sizes
block_size_.resize(num_blocks_);
for (int i = 0; i < num_blocks_; ++i) {
- block_size_[i] = bs.cols[i + options_.num_eliminate_blocks].size;
+ block_size_[i] = bs.cols[i + options_.elimination_groups[0]].size;
}
const time_t start_time = time(NULL);
- switch (options_.preconditioner_type) {
- case SCHUR_JACOBI:
- ComputeSchurJacobiSparsity(bs);
- break;
+ switch (options_.type) {
case CLUSTER_JACOBI:
ComputeClusterJacobiSparsity(bs);
break;
@@ -130,24 +127,6 @@ VisibilityBasedPreconditioner::~VisibilityBasedPreconditioner() {
}
}
-// Determine the sparsity structure of the SCHUR_JACOBI
-// preconditioner. SCHUR_JACOBI is an extreme case of a visibility
-// based preconditioner where each camera block corresponds to a
-// cluster and there is no interaction between clusters.
-void VisibilityBasedPreconditioner::ComputeSchurJacobiSparsity(
- const CompressedRowBlockStructure& bs) {
- num_clusters_ = num_blocks_;
- cluster_membership_.resize(num_blocks_);
- cluster_pairs_.clear();
-
- // Each camea block is a member of its own cluster and the only
- // cluster pairs are the self edges (i,i).
- for (int i = 0; i < num_clusters_; ++i) {
- cluster_membership_[i] = i;
- cluster_pairs_.insert(make_pair(i, i));
- }
-}
-
// Determine the sparsity structure of the CLUSTER_JACOBI
// preconditioner. It clusters cameras using their scene
// visibility. The clusters form the diagonal blocks of the
@@ -155,7 +134,7 @@ void VisibilityBasedPreconditioner::ComputeSchurJacobiSparsity(
void VisibilityBasedPreconditioner::ComputeClusterJacobiSparsity(
const CompressedRowBlockStructure& bs) {
vector<set<int> > visibility;
- ComputeVisibility(bs, options_.num_eliminate_blocks, &visibility);
+ ComputeVisibility(bs, options_.elimination_groups[0], &visibility);
CHECK_EQ(num_blocks_, visibility.size());
ClusterCameras(visibility);
cluster_pairs_.clear();
@@ -173,7 +152,7 @@ void VisibilityBasedPreconditioner::ComputeClusterJacobiSparsity(
void VisibilityBasedPreconditioner::ComputeClusterTridiagonalSparsity(
const CompressedRowBlockStructure& bs) {
vector<set<int> > visibility;
- ComputeVisibility(bs, options_.num_eliminate_blocks, &visibility);
+ ComputeVisibility(bs, options_.elimination_groups[0], &visibility);
CHECK_EQ(num_blocks_, visibility.size());
ClusterCameras(visibility);
@@ -253,7 +232,7 @@ void VisibilityBasedPreconditioner::ComputeBlockPairsInPreconditioner(
int r = 0;
const int num_row_blocks = bs.rows.size();
- const int num_eliminate_blocks = options_.num_eliminate_blocks;
+ const int num_eliminate_blocks = options_.elimination_groups[0];
// Iterate over each row of the matrix. The block structure of the
// matrix is assumed to be sorted in order of the e_blocks/point
@@ -331,16 +310,16 @@ void VisibilityBasedPreconditioner::ComputeBlockPairsInPreconditioner(
void VisibilityBasedPreconditioner::InitEliminator(
const CompressedRowBlockStructure& bs) {
LinearSolver::Options eliminator_options;
- eliminator_options.num_eliminate_blocks = options_.num_eliminate_blocks;
+ eliminator_options.elimination_groups = options_.elimination_groups;
eliminator_options.num_threads = options_.num_threads;
- DetectStructure(bs, options_.num_eliminate_blocks,
+ DetectStructure(bs, options_.elimination_groups[0],
&eliminator_options.row_block_size,
&eliminator_options.e_block_size,
&eliminator_options.f_block_size);
eliminator_.reset(SchurEliminatorBase::Create(eliminator_options));
- eliminator_->Init(options_.num_eliminate_blocks, &bs);
+ eliminator_->Init(options_.elimination_groups[0], &bs);
}
// Update the values of the preconditioner matrix and factorize it.
@@ -364,13 +343,13 @@ bool VisibilityBasedPreconditioner::Update(const BlockSparseMatrixBase& A,
// Compute a subset of the entries of the Schur complement.
eliminator_->Eliminate(&A, b.data(), D, m_.get(), rhs.data());
- // Try factorizing the matrix. For SCHUR_JACOBI and CLUSTER_JACOBI,
- // this should always succeed modulo some numerical/conditioning
- // problems. For CLUSTER_TRIDIAGONAL, in general the preconditioner
- // matrix as constructed is not positive definite. However, we will
- // go ahead and try factorizing it. If it works, great, otherwise we
- // scale all the cells in the preconditioner corresponding to the
- // edges in the degree-2 forest and that guarantees positive
+ // Try factorizing the matrix. For CLUSTER_JACOBI, this should
+ // always succeed modulo some numerical/conditioning problems. For
+ // CLUSTER_TRIDIAGONAL, in general the preconditioner matrix as
+ // constructed is not positive definite. However, we will go ahead
+ // and try factorizing it. If it works, great, otherwise we scale
+ // all the cells in the preconditioner corresponding to the edges in
+ // the degree-2 forest and that guarantees positive
// definiteness. The proof of this fact can be found in Lemma 1 in
// "Visibility Based Preconditioning for Bundle Adjustment".
//
@@ -380,10 +359,10 @@ bool VisibilityBasedPreconditioner::Update(const BlockSparseMatrixBase& A,
// The scaling only affects the tri-diagonal case, since
// ScaleOffDiagonalBlocks only pays attenion to the cells that
- // belong to the edges of the degree-2 forest. In the SCHUR_JACOBI
- // and the CLUSTER_JACOBI cases, the preconditioner is guaranteed to
- // be positive semidefinite.
- if (!status && options_.preconditioner_type == CLUSTER_TRIDIAGONAL) {
+ // belong to the edges of the degree-2 forest. In the CLUSTER_JACOBI
+ // case, the preconditioner is guaranteed to be positive
+ // semidefinite.
+ if (!status && options_.type == CLUSTER_TRIDIAGONAL) {
VLOG(1) << "Unscaled factorization failed. Retrying with off-diagonal "
<< "scaling";
ScaleOffDiagonalCells();
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
index 888c65eba3a..8a09c78d36a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
@@ -29,25 +29,19 @@
// Author: sameeragarwal@google.com (Sameer Agarwal)
//
// Preconditioners for linear systems that arise in Structure from
-// Motion problems. VisibilityBasedPreconditioner implements three
-// preconditioners:
+// Motion problems. VisibilityBasedPreconditioner implements:
//
-// SCHUR_JACOBI
// CLUSTER_JACOBI
// CLUSTER_TRIDIAGONAL
//
// Detailed descriptions of these preconditions beyond what is
// documented here can be found in
//
-// Bundle Adjustment in the Large
-// S. Agarwal, N. Snavely, S. Seitz & R. Szeliski, ECCV 2010
-// http://www.cs.washington.edu/homes/sagarwal/bal.pdf
-//
// Visibility Based Preconditioning for Bundle Adjustment
// A. Kushal & S. Agarwal, submitted to CVPR 2012
// http://www.cs.washington.edu/homes/sagarwal/vbp.pdf
//
-// The three preconditioners share enough code that its most efficient
+// The two preconditioners share enough code that its most efficient
// to implement them as part of the same code base.
#ifndef CERES_INTERNAL_VISIBILITY_BASED_PRECONDITIONER_H_
@@ -58,36 +52,26 @@
#include <utility>
#include "ceres/collections_port.h"
#include "ceres/graph.h"
-#include "ceres/linear_solver.h"
-#include "ceres/linear_operator.h"
-#include "ceres/suitesparse.h"
#include "ceres/internal/macros.h"
#include "ceres/internal/scoped_ptr.h"
+#include "ceres/preconditioner.h"
+#include "ceres/suitesparse.h"
namespace ceres {
namespace internal {
class BlockRandomAccessSparseMatrix;
class BlockSparseMatrixBase;
-class CompressedRowBlockStructure;
+struct CompressedRowBlockStructure;
class SchurEliminatorBase;
-// This class implements three preconditioners for Structure from
-// Motion/Bundle Adjustment problems. The name
+// This class implements visibility based preconditioners for
+// Structure from Motion/Bundle Adjustment problems. The name
// VisibilityBasedPreconditioner comes from the fact that the sparsity
// structure of the preconditioner matrix is determined by analyzing
// the visibility structure of the scene, i.e. which cameras see which
// points.
//
-// Strictly speaking, SCHUR_JACOBI is not a visibility based
-// preconditioner but it is an extreme case of CLUSTER_JACOBI, where
-// every cluster contains exactly one camera block. Treating it as a
-// special case of CLUSTER_JACOBI makes it easy to implement as part
-// of the same code base with no significant loss of performance.
-//
-// In the following, we will only discuss CLUSTER_JACOBI and
-// CLUSTER_TRIDIAGONAL.
-//
// The key idea of visibility based preconditioning is to identify
// cameras that we expect have strong interactions, and then using the
// entries in the Schur complement matrix corresponding to these
@@ -130,15 +114,15 @@ class SchurEliminatorBase;
//
// LinearSolver::Options options;
// options.preconditioner_type = CLUSTER_JACOBI;
-// options.num_eliminate_blocks = num_points;
+// options.elimination_groups.push_back(num_points);
+// options.elimination_groups.push_back(num_cameras);
// VisibilityBasedPreconditioner preconditioner(
// *A.block_structure(), options);
// preconditioner.Update(A, NULL);
// preconditioner.RightMultiply(x, y);
//
-
#ifndef CERES_NO_SUITESPARSE
-class VisibilityBasedPreconditioner : public LinearOperator {
+class VisibilityBasedPreconditioner : public Preconditioner {
public:
// Initialize the symbolic structure of the preconditioner. bs is
// the block structure of the linear system to be solved. It is used
@@ -146,48 +130,17 @@ class VisibilityBasedPreconditioner : public LinearOperator {
//
// It has the same structural requirement as other Schur complement
// based solvers. Please see schur_eliminator.h for more details.
- //
- // LinearSolver::Options::num_eliminate_blocks should be set to the
- // number of e_blocks in the block structure.
- //
- // TODO(sameeragarwal): The use of LinearSolver::Options should
- // ultimately be replaced with Preconditioner::Options and some sort
- // of preconditioner factory along the lines of
- // LinearSolver::CreateLinearSolver. I will wait to do this till I
- // create a general purpose block Jacobi preconditioner for general
- // sparse problems along with a CGLS solver.
VisibilityBasedPreconditioner(const CompressedRowBlockStructure& bs,
- const LinearSolver::Options& options);
+ const Preconditioner::Options& options);
virtual ~VisibilityBasedPreconditioner();
- // Update the numerical value of the preconditioner for the linear
- // system:
- //
- // | A | x = |b|
- // |diag(D)| |0|
- //
- // for some vector b. It is important that the matrix A have the
- // same block structure as the one used to construct this object.
- //
- // D can be NULL, in which case its interpreted as a diagonal matrix
- // of size zero.
- bool Update(const BlockSparseMatrixBase& A, const double* D);
-
-
- // LinearOperator interface. Since the operator is symmetric,
- // LeftMultiply and num_cols are just calls to RightMultiply and
- // num_rows respectively. Update() must be called before
- // RightMultiply can be called.
+ // Preconditioner interface
+ virtual bool Update(const BlockSparseMatrixBase& A, const double* D);
virtual void RightMultiply(const double* x, double* y) const;
- virtual void LeftMultiply(const double* x, double* y) const {
- RightMultiply(x, y);
- }
virtual int num_rows() const;
- virtual int num_cols() const { return num_rows(); }
friend class VisibilityBasedPreconditionerTest;
private:
- void ComputeSchurJacobiSparsity(const CompressedRowBlockStructure& bs);
void ComputeClusterJacobiSparsity(const CompressedRowBlockStructure& bs);
void ComputeClusterTridiagonalSparsity(const CompressedRowBlockStructure& bs);
void InitStorage(const CompressedRowBlockStructure& bs);
@@ -207,7 +160,7 @@ class VisibilityBasedPreconditioner : public LinearOperator {
bool IsBlockPairInPreconditioner(int block1, int block2) const;
bool IsBlockPairOffDiagonal(int block1, int block2) const;
- LinearSolver::Options options_;
+ Preconditioner::Options options_;
// Number of parameter blocks in the schur complement.
int num_blocks_;
@@ -249,10 +202,10 @@ class VisibilityBasedPreconditioner : public LinearOperator {
#else // SuiteSparse
// If SuiteSparse is not compiled in, the preconditioner is not
// available.
-class VisibilityBasedPreconditioner : public LinearOperator {
+class VisibilityBasedPreconditioner : public Preconditioner {
public:
VisibilityBasedPreconditioner(const CompressedRowBlockStructure& bs,
- const LinearSolver::Options& options) {
+ const Preconditioner::Options& options) {
LOG(FATAL) << "Visibility based preconditioning is not available. Please "
"build Ceres with SuiteSparse.";
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/wall_time.cc b/extern/libmv/third_party/ceres/internal/ceres/wall_time.cc
new file mode 100644
index 00000000000..e63d20c0ab1
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/wall_time.cc
@@ -0,0 +1,96 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: strandmark@google.com (Petter Strandmark)
+
+#include "ceres/wall_time.h"
+
+#ifdef CERES_USE_OPENMP
+#include <omp.h>
+#else
+#include <ctime>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+namespace ceres {
+namespace internal {
+
+double WallTimeInSeconds() {
+#ifdef CERES_USE_OPENMP
+ return omp_get_wtime();
+#else
+#ifdef _WIN32
+ return static_cast<double>(std::time(NULL));
+#else
+ timeval time_val;
+ gettimeofday(&time_val, NULL);
+ return (time_val.tv_sec + time_val.tv_usec * 1e-6);
+#endif
+#endif
+}
+
+EventLogger::EventLogger(const string& logger_name)
+ : start_time_(WallTimeInSeconds()),
+ last_event_time_(start_time_),
+ events_("") {
+ StringAppendF(&events_,
+ "\n%s\n Delta Cumulative\n",
+ logger_name.c_str());
+}
+
+EventLogger::~EventLogger() {
+ if (VLOG_IS_ON(3)) {
+ AddEvent("Total");
+ VLOG(2) << "\n" << events_ << "\n";
+ }
+}
+
+void EventLogger::AddEvent(const string& event_name) {
+ if (!VLOG_IS_ON(3)) {
+ return;
+ }
+
+ const double current_time = WallTimeInSeconds();
+ const double relative_time_delta = current_time - last_event_time_;
+ const double absolute_time_delta = current_time - start_time_;
+ last_event_time_ = current_time;
+
+ StringAppendF(&events_,
+ " %25s : %10.5f %10.5f\n",
+ event_name.c_str(),
+ relative_time_delta,
+ absolute_time_delta);
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/wall_time.h b/extern/libmv/third_party/ceres/internal/ceres/wall_time.h
new file mode 100644
index 00000000000..45f65ca1aa5
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/wall_time.h
@@ -0,0 +1,88 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: strandmark@google.com (Petter Strandmark)
+
+#ifndef CERES_INTERNAL_WALL_TIME_H_
+#define CERES_INTERNAL_WALL_TIME_H_
+
+#include <map>
+
+#include "ceres/internal/port.h"
+#include "ceres/stringprintf.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+// Returns time, in seconds, from some arbitrary starting point. If
+// OpenMP is available then the high precision openmp_get_wtime()
+// function is used. Otherwise on unixes, gettimeofday is used. The
+// granularity is in seconds on windows systems.
+double WallTimeInSeconds();
+
+// Log a series of events, recording for each event the time elapsed
+// since the last event and since the creation of the object.
+//
+// The information is output to VLOG(3) upon destruction. A
+// name::Total event is added as the final event right before
+// destruction.
+//
+// Example usage:
+//
+// void Foo() {
+// EventLogger event_logger("Foo");
+// Bar1();
+// event_logger.AddEvent("Bar1")
+// Bar2();
+// event_logger.AddEvent("Bar2")
+// Bar3();
+// }
+//
+// Will produce output that looks like
+//
+// Foo
+// Bar1: time1 time1
+// Bar2: time2 time1 + time2;
+// Total: time3 time1 + time2 + time3;
+class EventLogger {
+ public:
+ explicit EventLogger(const string& logger_name);
+ ~EventLogger();
+ void AddEvent(const string& event_name);
+
+ private:
+ const double start_time_;
+ double last_event_time_;
+ string events_;
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_WALL_TIME_H_
diff --git a/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch b/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch
deleted file mode 100644
index c01a17c7992..00000000000
--- a/extern/libmv/third_party/ceres/patches/collections_port.h.mingw.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/internal/ceres/collections_port.h b/internal/ceres/collections_port.h
-index a356cc0..c2fce90 100644
---- a/internal/ceres/collections_port.h
-+++ b/internal/ceres/collections_port.h
-@@ -77,7 +77,7 @@ struct HashMap : std::tr1::unordered_map<K, V> {};
- template<typename K>
- struct HashSet : std::tr1::unordered_set<K> {};
-
--#ifdef _WIN32
-+#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__)
- #define GG_LONGLONG(x) x##I64
- #define GG_ULONGLONG(x) x##UI64
- #else
diff --git a/extern/libmv/third_party/ceres/patches/msvc_glog_fix.patch b/extern/libmv/third_party/ceres/patches/msvc_glog_fix.patch
deleted file mode 100644
index f3200fb8e0a..00000000000
--- a/extern/libmv/third_party/ceres/patches/msvc_glog_fix.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-diff --git a/internal/ceres/block_random_access_dense_matrix.cc b/internal/ceres/block_random_access_dense_matrix.cc
-index aedfc74..0f95e89 100644
---- a/internal/ceres/block_random_access_dense_matrix.cc
-+++ b/internal/ceres/block_random_access_dense_matrix.cc
-@@ -28,12 +28,12 @@
- //
- // Author: sameeragarwal@google.com (Sameer Agarwal)
-
-+#include "glog/logging.h"
- #include "ceres/block_random_access_dense_matrix.h"
-
- #include <vector>
- #include "ceres/internal/eigen.h"
- #include "ceres/internal/scoped_ptr.h"
--#include "glog/logging.h"
-
- namespace ceres {
- namespace internal {
-diff --git a/internal/ceres/block_random_access_sparse_matrix.cc b/internal/ceres/block_random_access_sparse_matrix.cc
-index f789436..9ed62ce 100644
---- a/internal/ceres/block_random_access_sparse_matrix.cc
-+++ b/internal/ceres/block_random_access_sparse_matrix.cc
-@@ -28,6 +28,7 @@
- //
- // Author: sameeragarwal@google.com (Sameer Agarwal)
-
-+#include "glog/logging.h"
- #include "ceres/block_random_access_sparse_matrix.h"
-
- #include <algorithm>
-@@ -39,7 +40,6 @@
- #include "ceres/mutex.h"
- #include "ceres/triplet_sparse_matrix.h"
- #include "ceres/types.h"
--#include "glog/logging.h"
-
- namespace ceres {
- namespace internal {
-diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
-index b9224d8..2cbe78d 100644
---- a/internal/ceres/schur_complement_solver.cc
-+++ b/internal/ceres/schur_complement_solver.cc
-@@ -38,6 +38,7 @@
- #endif // CERES_NO_CXSPARSE
-
- #include "Eigen/Dense"
-+#include "glog/logging.h"
- #include "ceres/block_random_access_dense_matrix.h"
- #include "ceres/block_random_access_matrix.h"
- #include "ceres/block_random_access_sparse_matrix.h"
diff --git a/extern/libmv/third_party/ceres/patches/no_previous_declaration_fix.patch b/extern/libmv/third_party/ceres/patches/no_previous_declaration_fix.patch
deleted file mode 100644
index 03f1c500d9a..00000000000
--- a/extern/libmv/third_party/ceres/patches/no_previous_declaration_fix.patch
+++ /dev/null
@@ -1,199 +0,0 @@
-diff --git a/internal/ceres/file.cc b/internal/ceres/file.cc
-index 387f359..6fe7557 100644
---- a/internal/ceres/file.cc
-+++ b/internal/ceres/file.cc
-@@ -31,6 +31,7 @@
- // Really simple file IO.
-
- #include <cstdio>
-+#include "file.h"
- #include "glog/logging.h"
-
- namespace ceres {
-diff --git a/internal/ceres/linear_least_squares_problems.cc b/internal/ceres/linear_least_squares_problems.cc
-index 3e3bcd0..a91e254 100644
---- a/internal/ceres/linear_least_squares_problems.cc
-+++ b/internal/ceres/linear_least_squares_problems.cc
-@@ -573,13 +573,13 @@ LinearLeastSquaresProblem* LinearLeastSquaresProblem3() {
- return problem;
- }
-
--bool DumpLinearLeastSquaresProblemToConsole(const string& directory,
-- int iteration,
-- const SparseMatrix* A,
-- const double* D,
-- const double* b,
-- const double* x,
-- int num_eliminate_blocks) {
-+static bool DumpLinearLeastSquaresProblemToConsole(const string& directory,
-+ int iteration,
-+ const SparseMatrix* A,
-+ const double* D,
-+ const double* b,
-+ const double* x,
-+ int num_eliminate_blocks) {
- CHECK_NOTNULL(A);
- Matrix AA;
- A->ToDenseMatrix(&AA);
-@@ -601,13 +601,13 @@ bool DumpLinearLeastSquaresProblemToConsole(const string& directory,
- };
-
- #ifndef CERES_NO_PROTOCOL_BUFFERS
--bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
-- int iteration,
-- const SparseMatrix* A,
-- const double* D,
-- const double* b,
-- const double* x,
-- int num_eliminate_blocks) {
-+static bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
-+ int iteration,
-+ const SparseMatrix* A,
-+ const double* D,
-+ const double* b,
-+ const double* x,
-+ int num_eliminate_blocks) {
- CHECK_NOTNULL(A);
- LinearLeastSquaresProblemProto lsqp;
- A->ToProto(lsqp.mutable_a());
-@@ -641,13 +641,13 @@ bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
- return true;
- }
- #else
--bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
-- int iteration,
-- const SparseMatrix* A,
-- const double* D,
-- const double* b,
-- const double* x,
-- int num_eliminate_blocks) {
-+static bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
-+ int iteration,
-+ const SparseMatrix* A,
-+ const double* D,
-+ const double* b,
-+ const double* x,
-+ int num_eliminate_blocks) {
- LOG(ERROR) << "Dumping least squares problems is only "
- << "supported when Ceres is compiled with "
- << "protocol buffer support.";
-@@ -655,9 +655,9 @@ bool DumpLinearLeastSquaresProblemToProtocolBuffer(const string& directory,
- }
- #endif
-
--void WriteArrayToFileOrDie(const string& filename,
-- const double* x,
-- const int size) {
-+static void WriteArrayToFileOrDie(const string& filename,
-+ const double* x,
-+ const int size) {
- CHECK_NOTNULL(x);
- VLOG(2) << "Writing array to: " << filename;
- FILE* fptr = fopen(filename.c_str(), "w");
-@@ -668,13 +668,13 @@ void WriteArrayToFileOrDie(const string& filename,
- fclose(fptr);
- }
-
--bool DumpLinearLeastSquaresProblemToTextFile(const string& directory,
-- int iteration,
-- const SparseMatrix* A,
-- const double* D,
-- const double* b,
-- const double* x,
-- int num_eliminate_blocks) {
-+static bool DumpLinearLeastSquaresProblemToTextFile(const string& directory,
-+ int iteration,
-+ const SparseMatrix* A,
-+ const double* D,
-+ const double* b,
-+ const double* x,
-+ int num_eliminate_blocks) {
- CHECK_NOTNULL(A);
- string format_string = JoinPath(directory,
- "lm_iteration_%03d");
-diff --git a/internal/ceres/residual_block_utils.cc b/internal/ceres/residual_block_utils.cc
-index ff18e21..9442bb2 100644
---- a/internal/ceres/residual_block_utils.cc
-+++ b/internal/ceres/residual_block_utils.cc
-@@ -63,7 +63,7 @@ void InvalidateEvaluation(const ResidualBlock& block,
-
- // Utility routine to print an array of doubles to a string. If the
- // array pointer is NULL, it is treated as an array of zeros.
--void AppendArrayToString(const int size, const double* x, string* result) {
-+static void AppendArrayToString(const int size, const double* x, string* result) {
- for (int i = 0; i < size; ++i) {
- if (x == NULL) {
- StringAppendF(result, "Not Computed ");
-diff --git a/internal/ceres/solver_impl.cc b/internal/ceres/solver_impl.cc
-index 2802a75..8ef5b98 100644
---- a/internal/ceres/solver_impl.cc
-+++ b/internal/ceres/solver_impl.cc
-@@ -685,8 +685,8 @@ bool SolverImpl::ApplyUserOrdering(const ProblemImpl& problem_impl,
- // Find the minimum index of any parameter block to the given residual.
- // Parameter blocks that have indices greater than num_eliminate_blocks are
- // considered to have an index equal to num_eliminate_blocks.
--int MinParameterBlock(const ResidualBlock* residual_block,
-- int num_eliminate_blocks) {
-+static int MinParameterBlock(const ResidualBlock* residual_block,
-+ int num_eliminate_blocks) {
- int min_parameter_block_position = num_eliminate_blocks;
- for (int i = 0; i < residual_block->NumParameterBlocks(); ++i) {
- ParameterBlock* parameter_block = residual_block->parameter_blocks()[i];
-diff --git a/internal/ceres/split.cc b/internal/ceres/split.cc
-index 4fa1bd4..c65c8a5 100644
---- a/internal/ceres/split.cc
-+++ b/internal/ceres/split.cc
-@@ -31,6 +31,7 @@
- #include <string>
- #include <vector>
- #include <iterator>
-+#include "ceres/split.h"
- #include "ceres/internal/port.h"
-
- namespace ceres {
-diff --git a/internal/ceres/stringprintf.cc b/internal/ceres/stringprintf.cc
-index c0f3522..396a48b 100644
---- a/internal/ceres/stringprintf.cc
-+++ b/internal/ceres/stringprintf.cc
-@@ -34,6 +34,7 @@
- #include <string>
- #include <vector>
-
-+#include "ceres/stringprintf.h"
- #include "ceres/internal/port.h"
-
- namespace ceres {
-diff --git a/internal/ceres/types.cc b/internal/ceres/types.cc
-index 2e950c5..05e573f 100644
---- a/internal/ceres/types.cc
-+++ b/internal/ceres/types.cc
-@@ -98,7 +98,8 @@ const char* SolverTerminationTypeToString(
- }
- }
-
--const char* SparseLinearAlgebraTypeToString(
-+#if 0 /* UNUSED */
-+static const char* SparseLinearAlgebraTypeToString(
- SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type) {
- switch (sparse_linear_algebra_library_type) {
- CASESTR(CX_SPARSE);
-@@ -107,6 +108,7 @@ const char* SparseLinearAlgebraTypeToString(
- return "UNKNOWN";
- }
- }
-+#endif
-
- const char* TrustRegionStrategyTypeToString(
- TrustRegionStrategyType trust_region_strategy_type) {
-diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc
-index 9d80654..564cc54 100644
---- a/internal/ceres/visibility.cc
-+++ b/internal/ceres/visibility.cc
-@@ -36,6 +36,7 @@
- #include <utility>
- #include "ceres/block_structure.h"
- #include "ceres/collections_port.h"
-+#include "ceres/visibility.h"
- #include "ceres/graph.h"
- #include "glog/logging.h"
-
diff --git a/extern/libmv/third_party/ceres/patches/series b/extern/libmv/third_party/ceres/patches/series
index a6874318923..e69de29bb2d 100644
--- a/extern/libmv/third_party/ceres/patches/series
+++ b/extern/libmv/third_party/ceres/patches/series
@@ -1,3 +0,0 @@
-collections_port.h.mingw.patch
-msvc_glog_fix.patch
-no_previous_declaration_fix.patch \ No newline at end of file
diff --git a/extern/libmv/third_party/gflags/README.libmv b/extern/libmv/third_party/gflags/README.libmv
index 673099ce618..b310c57ac34 100644
--- a/extern/libmv/third_party/gflags/README.libmv
+++ b/extern/libmv/third_party/gflags/README.libmv
@@ -11,4 +11,6 @@ Local modifications:
- 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.
+- Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
+
TODO(keir): Import and use gflags for Windows from upstream.
diff --git a/extern/libmv/third_party/glog/README.libmv b/extern/libmv/third_party/glog/README.libmv
index 025a70b76a5..345bc9f5969 100644
--- a/extern/libmv/third_party/glog/README.libmv
+++ b/extern/libmv/third_party/glog/README.libmv
@@ -22,3 +22,4 @@ Upgrading Notes
* Do not define va_copy for MinGW platforms (it's already defined there).
* Patch localtime_r to be working fine with MinGW, disable strerror_r for MinGW because
of lack of needed functions.
+* Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
diff --git a/extern/lzo/minilzo/COPYING b/extern/lzo/minilzo/COPYING
index 5ee49f42e91..d159169d105 100644
--- a/extern/lzo/minilzo/COPYING
+++ b/extern/lzo/minilzo/COPYING
@@ -1,8 +1,8 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
+the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
-
+
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
-
+
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
-
+
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
-
+
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
-
+
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
+ Copyright (C) <year> <name of author>
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
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
+ 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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
- Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
+library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
diff --git a/extern/lzo/minilzo/README.LZO b/extern/lzo/minilzo/README.LZO
index 3700f28e310..058eace70a0 100644
--- a/extern/lzo/minilzo/README.LZO
+++ b/extern/lzo/minilzo/README.LZO
@@ -6,8 +6,8 @@
Author : Markus Franz Xaver Johannes Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
- Version : 2.03
- Date : 30 Apr 2008
+ Version : 2.06
+ Date : 12 Aug 2011
I've created miniLZO for projects where it is inconvenient to
include (or require) the full LZO source code just because you
@@ -24,10 +24,10 @@
To use miniLZO just copy these files into your source directory, add
minilzo.c to your Makefile and #include minilzo.h from your program.
- Note: you also must distribute this file (`README.LZO') with your project.
+ Note: you also must distribute this file ('README.LZO') with your project.
- minilzo.o compiles to about 6 kB (using gcc or Visual C on a i386), and
- the sources are about 30 kB when packed with zip - so there's no more
+ minilzo.o compiles to about 6 KiB (using gcc or Visual C on an i386), and
+ the sources are about 30 KiB when packed with zip - so there's no more
excuse that your application doesn't support data compression :-)
For more information, documentation, example programs and other support
@@ -49,15 +49,15 @@
out-of-the-box on most machines.
If you are running on a very unusual architecture and lzo_init() fails then
- you should first recompile with `-DLZO_DEBUG' to see what causes the failure.
- The most probable case is something like `sizeof(char *) != sizeof(long)'.
+ you should first recompile with '-DLZO_DEBUG' to see what causes the failure.
+ The most probable case is something like 'sizeof(void *) != sizeof(size_t)'.
After identifying the problem you can compile by adding some defines
- like `-DSIZEOF_CHAR_P=8' to your Makefile.
+ like '-DSIZEOF_VOID_P=8' to your Makefile.
The best solution is (of course) using Autoconf - if your project uses
- Autoconf anyway just add `-DMINILZO_HAVE_CONFIG_H' to your compiler
+ Autoconf anyway just add '-DMINILZO_HAVE_CONFIG_H' to your compiler
flags when compiling minilzo.c. See the LZO distribution for an example
- how to set up configure.in.
+ how to set up configure.ac.
Appendix B: list of public functions available in miniLZO
@@ -87,7 +87,7 @@
lzo_memset()
- Appendix C: suggested macros for `configure.in' when using Autoconf
+ Appendix C: suggested macros for 'configure.ac' when using Autoconf
-------------------------------------------------------------------
Checks for typedefs and structures
AC_CHECK_TYPE(ptrdiff_t,long)
@@ -110,8 +110,9 @@
Appendix D: Copyright
---------------------
- LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008 Markus Franz Xaver Johannes Oberhumer
+ LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ Markus Franz Xaver Oberhumer <markus@oberhumer.com>.
LZO and miniLZO are distributed under the terms of the GNU General
Public License (GPL). See the file COPYING.
diff --git a/extern/lzo/minilzo/lzoconf.h b/extern/lzo/minilzo/lzoconf.h
index cc437f1ebfe..23c6ca93fcc 100644
--- a/extern/lzo/minilzo/lzoconf.h
+++ b/extern/lzo/minilzo/lzoconf.h
@@ -1,7 +1,10 @@
-/* lzoconf.h -- configuration for the LZO real-time data compression library
+/* lzoconf.h -- configuration of the LZO data compression library
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
@@ -39,11 +42,11 @@
#ifndef __LZOCONF_H_INCLUDED
-#define __LZOCONF_H_INCLUDED
+#define __LZOCONF_H_INCLUDED 1
-#define LZO_VERSION 0x2030
-#define LZO_VERSION_STRING "2.03"
-#define LZO_VERSION_DATE "Apr 30 2008"
+#define LZO_VERSION 0x2060
+#define LZO_VERSION_STRING "2.06"
+#define LZO_VERSION_DATE "Aug 12 2011"
/* internal Autoconf configuration file - only used when building LZO */
#if defined(LZO_HAVE_CONFIG_H)
@@ -157,6 +160,27 @@ extern "C" {
# endif
#endif
+/* Integral types with exactly 64 bits. */
+#if !defined(LZO_UINT64_MAX)
+# if (LZO_UINT_MAX >= LZO_0xffffffffL)
+# if ((((LZO_UINT_MAX) >> 31) >> 31) == 3)
+# define lzo_uint64 lzo_uint
+# define lzo_int64 lzo_int
+# define LZO_UINT64_MAX LZO_UINT_MAX
+# define LZO_INT64_MAX LZO_INT_MAX
+# define LZO_INT64_MIN LZO_INT_MIN
+# endif
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+# if ((((ULONG_MAX) >> 31) >> 31) == 3)
+ typedef unsigned long lzo_uint64;
+ typedef long lzo_int64;
+# define LZO_UINT64_MAX ULONG_MAX
+# define LZO_INT64_MAX LONG_MAX
+# define LZO_INT64_MIN LONG_MIN
+# endif
+# endif
+#endif
+
/* The larger type of lzo_uint and lzo_uint32. */
#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
# define lzo_xint lzo_uint
@@ -167,12 +191,12 @@ extern "C" {
/* Memory model that allows to access memory at offsets of lzo_uint. */
#if !defined(__LZO_MMODEL)
# if (LZO_UINT_MAX <= UINT_MAX)
-# define __LZO_MMODEL
+# define __LZO_MMODEL /*empty*/
# elif defined(LZO_HAVE_MM_HUGE_PTR)
# define __LZO_MMODEL_HUGE 1
# define __LZO_MMODEL __huge
# else
-# define __LZO_MMODEL
+# define __LZO_MMODEL /*empty*/
# endif
#endif
@@ -184,12 +208,16 @@ extern "C" {
#define lzo_ushortp unsigned short __LZO_MMODEL *
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
#define lzo_int32p lzo_int32 __LZO_MMODEL *
+#if defined(LZO_UINT64_MAX)
+#define lzo_uint64p lzo_uint64 __LZO_MMODEL *
+#define lzo_int64p lzo_int64 __LZO_MMODEL *
+#endif
#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_intp lzo_int __LZO_MMODEL *
#define lzo_xintp lzo_xint __LZO_MMODEL *
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
-/* deprecated - use `lzo_bytep' instead of `lzo_byte *' */
+/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
#define lzo_byte unsigned char __LZO_MMODEL
typedef int lzo_bool;
@@ -215,10 +243,10 @@ typedef int lzo_bool;
/* DLL export information */
#if !defined(__LZO_EXPORT1)
-# define __LZO_EXPORT1
+# define __LZO_EXPORT1 /*empty*/
#endif
#if !defined(__LZO_EXPORT2)
-# define __LZO_EXPORT2
+# define __LZO_EXPORT2 /*empty*/
#endif
/* __cdecl calling convention for public C and assembly functions */
@@ -306,7 +334,7 @@ struct lzo_callback_t
*/
#define LZO_E_OK 0
#define LZO_E_ERROR (-1)
-#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */
+#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
#define LZO_E_INPUT_OVERRUN (-4)
#define LZO_E_OUTPUT_OVERRUN (-5)
@@ -314,6 +342,7 @@ struct lzo_callback_t
#define LZO_E_EOF_NOT_FOUND (-7)
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
+#define LZO_E_INVALID_ARGUMENT (-10)
#ifndef lzo_sizeof_dict_t
@@ -341,32 +370,32 @@ LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
/* string functions */
LZO_EXTERN(int)
-lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len);
+ lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len);
LZO_EXTERN(lzo_voidp)
-lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+ lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
LZO_EXTERN(lzo_voidp)
-lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+ lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
LZO_EXTERN(lzo_voidp)
-lzo_memset(lzo_voidp _s, int _c, lzo_uint _len);
+ lzo_memset(lzo_voidp buf, int c, lzo_uint len);
/* checksum functions */
LZO_EXTERN(lzo_uint32)
-lzo_adler32(lzo_uint32 _adler, const lzo_bytep _buf, lzo_uint _len);
+ lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(lzo_uint32)
-lzo_crc32(lzo_uint32 _c, const lzo_bytep _buf, lzo_uint _len);
+ lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(const lzo_uint32p)
-lzo_get_crc32_table(void);
+ lzo_get_crc32_table(void);
/* misc. */
LZO_EXTERN(int) _lzo_config_check(void);
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
-typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t;
+typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t;
-/* align a char pointer on a boundary that is a multiple of `size' */
-LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size);
-#define LZO_PTR_ALIGN_UP(_ptr,_size) \
- ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size)))
+/* align a char pointer on a boundary that is a multiple of 'size' */
+LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
+#define LZO_PTR_ALIGN_UP(p,size) \
+ ((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size)))
/***********************************************************************
@@ -395,8 +424,8 @@ LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size);
# define __LZO_WIN 1
#endif
-#define __LZO_CMODEL
-#define __LZO_DMODEL
+#define __LZO_CMODEL /*empty*/
+#define __LZO_DMODEL /*empty*/
#define __LZO_ENTRY __LZO_CDECL
#define LZO_EXTERN_CDECL LZO_EXTERN
#define LZO_ALIGN LZO_PTR_ALIGN_UP
diff --git a/extern/lzo/minilzo/lzodefs.h b/extern/lzo/minilzo/lzodefs.h
index 180563723e5..0e40e332a8d 100644
--- a/extern/lzo/minilzo/lzodefs.h
+++ b/extern/lzo/minilzo/lzodefs.h
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
@@ -121,7 +124,7 @@
#endif
#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL)
# define ptrdiff_t long
-# define _PTRDIFF_T_DEFINED
+# define _PTRDIFF_T_DEFINED 1
#endif
#if (UINT_MAX == LZO_0xffffL)
# undef __LZO_RENAME_A
@@ -265,9 +268,9 @@
# define LZO_EXTERN_C extern
#endif
#if !defined(__LZO_OS_OVERRIDE)
-#if defined(LZO_OS_FREESTANDING)
+#if (LZO_OS_FREESTANDING)
# define LZO_INFO_OS "freestanding"
-#elif defined(LZO_OS_EMBEDDED)
+#elif (LZO_OS_EMBEDDED)
# define LZO_INFO_OS "embedded"
#elif 1 && defined(__IAR_SYSTEMS_ICC__)
# define LZO_OS_EMBEDDED 1
@@ -476,12 +479,27 @@
# define LZO_CC_PELLESC 1
# define LZO_INFO_CC "Pelles C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__)
-#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
-# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# if defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# else
+# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# endif
+# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
+# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__)
+# else
+# define LZO_CC_CLANG_CLANG 0x010000L
+# endif
+# define LZO_CC_CLANG LZO_CC_CLANG_GNUC
+# define LZO_INFO_CC "clang"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# if defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
# else
-# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
# endif
+# define LZO_CC_LLVM LZO_CC_LLVM_GNUC
# define LZO_INFO_CC "llvm-gcc"
# define LZO_INFO_CCVER __VERSION__
#elif defined(__GNUC__) && defined(__VERSION__)
@@ -502,6 +520,10 @@
# define LZO_CC_AZTECC 1
# define LZO_INFO_CC "Aztec C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__)
+#elif defined(__CODEGEARC__)
+# define LZO_CC_CODEGEARC 1
+# define LZO_INFO_CC "CodeGear C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__)
#elif defined(__BORLANDC__)
# define LZO_CC_BORLANDC 1
# define LZO_INFO_CC "Borland C"
@@ -632,7 +654,7 @@
#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER)
# error "LZO_CC_MSC: _MSC_FULL_VER is not defined"
#endif
-#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY)
+#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY)
# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY)
# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E)
# define LZO_ARCH_CRAY_MPP 1
@@ -642,7 +664,7 @@
# endif
#endif
#if !defined(__LZO_ARCH_OVERRIDE)
-#if defined(LZO_ARCH_GENERIC)
+#if (LZO_ARCH_GENERIC)
# define LZO_INFO_ARCH "generic"
#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086 1
@@ -677,6 +699,9 @@
#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__)
# define LZO_ARCH_AVR 1
# define LZO_INFO_ARCH "avr"
+#elif defined(__avr32__) || defined(__AVR32__)
+# define LZO_ARCH_AVR32 1
+# define LZO_INFO_ARCH "avr32"
#elif defined(__bfin__)
# define LZO_ARCH_BLACKFIN 1
# define LZO_INFO_ARCH "blackfin"
@@ -799,10 +824,10 @@
# define LZO_ARCH_I086PM 1
# define LZO_ARCH_IA16PM 1
#endif
-#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM)
+#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM)
# error "this should not happen"
#endif
-#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086)
+#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086)
# error "this should not happen"
#endif
#if (LZO_ARCH_I086)
@@ -875,7 +900,7 @@
#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295))
# undef LZO_HAVE_MM_HUGE_ARRAY
#endif
-#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR)
+#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR)
# if (LZO_OS_DOS16)
# error "this should not happen"
# elif (LZO_CC_ZORTECHC)
@@ -1091,7 +1116,7 @@ extern "C" {
#if (LZO_ARCH_I086 && LZO_CC_DMC)
#elif (LZO_CC_CILLY) && defined(__GNUC__)
# define LZO_SIZEOF_LONG_LONG 8
-#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define LZO_SIZEOF_LONG_LONG 8
#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400))
# define LZO_SIZEOF_LONG_LONG 8
@@ -1125,12 +1150,12 @@ extern "C" {
#endif
#endif
#endif
-#if defined(__cplusplus) && defined(LZO_CC_GNUC)
+#if defined(__cplusplus) && (LZO_CC_GNUC)
# if (LZO_CC_GNUC < 0x020800ul)
# undef LZO_SIZEOF_LONG_LONG
# endif
#endif
-#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
+#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
# undef LZO_SIZEOF_LONG_LONG
#endif
#if !defined(LZO_SIZEOF_VOID_P)
@@ -1229,15 +1254,17 @@ extern "C" {
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T
#endif
#endif
-#if defined(LZO_ABI_NEUTRAL_ENDIAN)
+#if (LZO_ABI_NEUTRAL_ENDIAN)
# undef LZO_ABI_BIG_ENDIAN
# undef LZO_ABI_LITTLE_ENDIAN
-#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN)
+#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN)
#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP)
# define LZO_ABI_BIG_ENDIAN 1
+#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64)
+# define LZO_ABI_LITTLE_ENDIAN 1
#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430)
# define LZO_ABI_LITTLE_ENDIAN 1
-#elif (LZO_ARCH_M68K || LZO_ARCH_S390)
+#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390)
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__)
# if (__LITTLE_ENDIAN__ == 1)
@@ -1259,14 +1286,14 @@ extern "C" {
# define LZO_ABI_LITTLE_ENDIAN 1
#endif
#endif
-#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN)
+#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN)
# error "this should not happen"
#endif
-#if defined(LZO_ABI_BIG_ENDIAN)
+#if (LZO_ABI_BIG_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "be"
-#elif defined(LZO_ABI_LITTLE_ENDIAN)
+#elif (LZO_ABI_LITTLE_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "le"
-#elif defined(LZO_ABI_NEUTRAL_ENDIAN)
+#elif (LZO_ABI_NEUTRAL_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "neutral"
#endif
#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
@@ -1292,15 +1319,15 @@ extern "C" {
# define LZO_INFO_ABI_PM "ip32l64"
#endif
#if !defined(__LZO_LIBC_OVERRIDE)
-#if defined(LZO_LIBC_NAKED)
+#if (LZO_LIBC_NAKED)
# define LZO_INFO_LIBC "naked"
-#elif defined(LZO_LIBC_FREESTANDING)
+#elif (LZO_LIBC_FREESTANDING)
# define LZO_INFO_LIBC "freestanding"
-#elif defined(LZO_LIBC_MOSTLY_FREESTANDING)
+#elif (LZO_LIBC_MOSTLY_FREESTANDING)
# define LZO_INFO_LIBC "mfreestanding"
-#elif defined(LZO_LIBC_ISOC90)
+#elif (LZO_LIBC_ISOC90)
# define LZO_INFO_LIBC "isoc90"
-#elif defined(LZO_LIBC_ISOC99)
+#elif (LZO_LIBC_ISOC99)
# define LZO_INFO_LIBC "isoc99"
#elif defined(__dietlibc__)
# define LZO_LIBC_DIETLIBC 1
@@ -1332,22 +1359,24 @@ extern "C" {
#if !defined(__lzo_gnuc_extension__)
#if (LZO_CC_GNUC >= 0x020800ul)
# define __lzo_gnuc_extension__ __extension__
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_gnuc_extension__ __extension__
#else
-# define __lzo_gnuc_extension__
+# define __lzo_gnuc_extension__ /*empty*/
#endif
#endif
#if !defined(__lzo_ua_volatile)
# define __lzo_ua_volatile volatile
#endif
#if !defined(__lzo_alignof)
-#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
# define __lzo_alignof(e) __alignof__(e)
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
# define __lzo_alignof(e) __alignof__(e)
#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
# define __lzo_alignof(e) __alignof(e)
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_alignof(e) __alignof__(e)
#endif
#endif
#if defined(__lzo_alignof)
@@ -1358,7 +1387,7 @@ extern "C" {
# define __lzo_constructor __attribute__((__constructor__,__used__))
#elif (LZO_CC_GNUC >= 0x020700ul)
# define __lzo_constructor __attribute__((__constructor__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_constructor __attribute__((__constructor__))
#endif
#endif
@@ -1370,14 +1399,14 @@ extern "C" {
# define __lzo_destructor __attribute__((__destructor__,__used__))
#elif (LZO_CC_GNUC >= 0x020700ul)
# define __lzo_destructor __attribute__((__destructor__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_destructor __attribute__((__destructor__))
#endif
#endif
#if defined(__lzo_destructor)
# define __lzo_HAVE_destructor 1
#endif
-#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor)
+#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor)
# error "this should not happen"
#endif
#if !defined(__lzo_inline)
@@ -1386,7 +1415,7 @@ extern "C" {
# define __lzo_inline inline
#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
# define __lzo_inline __inline
-#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
# define __lzo_inline __inline__
#elif (LZO_CC_DMC)
# define __lzo_inline __inline
@@ -1396,6 +1425,8 @@ extern "C" {
# define __lzo_inline __inline
#elif (LZO_CC_MSC && (_MSC_VER >= 900))
# define __lzo_inline __inline
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_inline __inline__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define __lzo_inline inline
#endif
@@ -1403,7 +1434,7 @@ extern "C" {
#if defined(__lzo_inline)
# define __lzo_HAVE_inline 1
#else
-# define __lzo_inline
+# define __lzo_inline /*empty*/
#endif
#if !defined(__lzo_forceinline)
#if (LZO_CC_GNUC >= 0x030200ul)
@@ -1412,16 +1443,18 @@ extern "C" {
# define __lzo_forceinline __forceinline
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
# define __lzo_forceinline __forceinline
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
#endif
#endif
#if defined(__lzo_forceinline)
# define __lzo_HAVE_forceinline 1
#else
-# define __lzo_forceinline
+# define __lzo_forceinline /*empty*/
#endif
#if !defined(__lzo_noinline)
#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
@@ -1432,7 +1465,7 @@ extern "C" {
# define __lzo_noinline __declspec(noinline)
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_noinline __attribute__((__noinline__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
# define __lzo_noinline __declspec(noinline)
@@ -1441,14 +1474,16 @@ extern "C" {
# else
# define __lzo_noinline __declspec(noinline)
# endif
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_noinline __attribute__((__noinline__))
#endif
#endif
#if defined(__lzo_noinline)
# define __lzo_HAVE_noinline 1
#else
-# define __lzo_noinline
+# define __lzo_noinline /*empty*/
#endif
-#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline)
+#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline)
# error "this should not happen"
#endif
#if !defined(__lzo_noreturn)
@@ -1458,7 +1493,7 @@ extern "C" {
# define __lzo_noreturn __declspec(noreturn)
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_noreturn __attribute__((__noreturn__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
# define __lzo_noreturn __declspec(noreturn)
@@ -1467,16 +1502,16 @@ extern "C" {
#if defined(__lzo_noreturn)
# define __lzo_HAVE_noreturn 1
#else
-# define __lzo_noreturn
+# define __lzo_noreturn /*empty*/
#endif
#if !defined(__lzo_nothrow)
#if (LZO_CC_GNUC >= 0x030300ul)
# define __lzo_nothrow __attribute__((__nothrow__))
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus)
# define __lzo_nothrow __declspec(nothrow)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC)
# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_nothrow __attribute__((__nothrow__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
# define __lzo_nothrow __declspec(nothrow)
@@ -1485,14 +1520,14 @@ extern "C" {
#if defined(__lzo_nothrow)
# define __lzo_HAVE_nothrow 1
#else
-# define __lzo_nothrow
+# define __lzo_nothrow /*empty*/
#endif
#if !defined(__lzo_restrict)
#if (LZO_CC_GNUC >= 0x030400ul)
# define __lzo_restrict __restrict__
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
# define __lzo_restrict __restrict__
-#elif (LZO_CC_LLVM)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM)
# define __lzo_restrict __restrict__
#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
# define __lzo_restrict __restrict
@@ -1501,7 +1536,7 @@ extern "C" {
#if defined(__lzo_restrict)
# define __lzo_HAVE_restrict 1
#else
-# define __lzo_restrict
+# define __lzo_restrict /*empty*/
#endif
#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
#if (LZO_CC_GNUC >= 0x030200ul)
@@ -1510,7 +1545,7 @@ extern "C" {
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
# define __lzo_likely(e) (__builtin_expect(!!(e),1))
# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_likely(e) (__builtin_expect(!!(e),1))
# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
#endif
@@ -1530,7 +1565,7 @@ extern "C" {
# define LZO_UNUSED(var) ((void) &var)
# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
# define LZO_UNUSED(var) if (&var) ; else
-# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define LZO_UNUSED(var) ((void) var)
# elif (LZO_CC_MSC && (_MSC_VER < 900))
# define LZO_UNUSED(var) if (&var) ; else
@@ -1549,7 +1584,7 @@ extern "C" {
# define LZO_UNUSED_FUNC(func) ((void) func)
# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
# define LZO_UNUSED_FUNC(func) if (func) ; else
-# elif (LZO_CC_LLVM)
+# elif (LZO_CC_CLANG || LZO_CC_LLVM)
# define LZO_UNUSED_FUNC(func) ((void) &func)
# elif (LZO_CC_MSC && (_MSC_VER < 900))
# define LZO_UNUSED_FUNC(func) if (func) ; else
@@ -1564,7 +1599,7 @@ extern "C" {
#if !defined(LZO_UNUSED_LABEL)
# if (LZO_CC_WATCOMC) && defined(__cplusplus)
# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
-# elif (LZO_CC_INTELC || LZO_CC_WATCOMC)
+# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC)
# define LZO_UNUSED_LABEL(l) if (0) goto l
# else
# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
@@ -1579,6 +1614,15 @@ extern "C" {
# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
# endif
#endif
+#if !defined(LZO_UNCONST_CAST)
+# if 0 && defined(__cplusplus)
+# define LZO_UNCONST_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e))))))
+# else
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e)))))
+# endif
+#endif
#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
@@ -1607,7 +1651,7 @@ extern "C" {
# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
# define __lzo_cdecl __cdecl
-# define __lzo_cdecl_atexit
+# define __lzo_cdecl_atexit /*empty*/
# define __lzo_cdecl_main __cdecl
# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
# define __lzo_cdecl_qsort __pascal
@@ -1648,24 +1692,24 @@ extern "C" {
# define __lzo_cdecl cdecl
#endif
#if !defined(__lzo_cdecl)
-# define __lzo_cdecl
+# define __lzo_cdecl /*empty*/
#endif
#if !defined(__lzo_cdecl_atexit)
-# define __lzo_cdecl_atexit
+# define __lzo_cdecl_atexit /*empty*/
#endif
#if !defined(__lzo_cdecl_main)
-# define __lzo_cdecl_main
+# define __lzo_cdecl_main /*empty*/
#endif
#if !defined(__lzo_cdecl_qsort)
-# define __lzo_cdecl_qsort
+# define __lzo_cdecl_qsort /*empty*/
#endif
#if !defined(__lzo_cdecl_sighandler)
-# define __lzo_cdecl_sighandler
+# define __lzo_cdecl_sighandler /*empty*/
#endif
#if !defined(__lzo_cdecl_va)
# define __lzo_cdecl_va __lzo_cdecl
#endif
-#if !defined(LZO_CFG_NO_WINDOWS_H)
+#if !(LZO_CFG_NO_WINDOWS_H)
#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
@@ -1711,7 +1755,7 @@ extern "C" {
#elif (LZO_ARCH_POWERPC)
# define LZO_OPT_PREFER_PREINC 1
# define LZO_OPT_PREFER_PREDEC 1
-# if defined(LZO_ABI_BIG_ENDIAN)
+# if (LZO_ABI_BIG_ENDIAN)
# define LZO_OPT_UNALIGNED16 1
# define LZO_OPT_UNALIGNED32 1
# endif
@@ -1725,28 +1769,29 @@ extern "C" {
# define LZO_OPT_PREFER_POSTINC 1
# define LZO_OPT_PREFER_PREDEC 1
#endif
-#if !defined(LZO_CFG_NO_INLINE_ASM)
-#if defined(LZO_CC_LLVM)
+#ifndef LZO_CFG_NO_INLINE_ASM
+#if (LZO_CC_LLVM)
# define LZO_CFG_NO_INLINE_ASM 1
#endif
#endif
-#if !defined(LZO_CFG_NO_UNALIGNED)
-#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC)
+#ifndef LZO_CFG_NO_UNALIGNED
+#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC)
# define LZO_CFG_NO_UNALIGNED 1
#endif
#endif
-#if defined(LZO_CFG_NO_UNALIGNED)
+#if (LZO_CFG_NO_UNALIGNED)
# undef LZO_OPT_UNALIGNED16
# undef LZO_OPT_UNALIGNED32
# undef LZO_OPT_UNALIGNED64
#endif
-#if defined(LZO_CFG_NO_INLINE_ASM)
+#if (LZO_CFG_NO_INLINE_ASM)
#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
# define LZO_ASM_SYNTAX_MSC 1
#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
-#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul))
+#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
# define LZO_ASM_SYNTAX_GNUC 1
-#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
# define LZO_ASM_SYNTAX_GNUC 1
#endif
#if (LZO_ASM_SYNTAX_GNUC)
diff --git a/extern/lzo/minilzo/minilzo.c b/extern/lzo/minilzo/minilzo.c
index 6a62b31b94a..34ce0f090bd 100644
--- a/extern/lzo/minilzo/minilzo.c
+++ b/extern/lzo/minilzo/minilzo.c
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
@@ -43,8 +46,7 @@
* http://www.oberhumer.com/opensource/lzo/
*/
-#define __LZO_IN_MINILZO
-#define LZO_BUILD
+#define __LZO_IN_MINILZO 1
#if defined(LZO_CFG_FREESTANDING)
# undef MINILZO_HAVE_CONFIG_H
@@ -142,7 +144,7 @@
#endif
#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL)
# define ptrdiff_t long
-# define _PTRDIFF_T_DEFINED
+# define _PTRDIFF_T_DEFINED 1
#endif
#if (UINT_MAX == LZO_0xffffL)
# undef __LZO_RENAME_A
@@ -286,9 +288,9 @@
# define LZO_EXTERN_C extern
#endif
#if !defined(__LZO_OS_OVERRIDE)
-#if defined(LZO_OS_FREESTANDING)
+#if (LZO_OS_FREESTANDING)
# define LZO_INFO_OS "freestanding"
-#elif defined(LZO_OS_EMBEDDED)
+#elif (LZO_OS_EMBEDDED)
# define LZO_INFO_OS "embedded"
#elif 1 && defined(__IAR_SYSTEMS_ICC__)
# define LZO_OS_EMBEDDED 1
@@ -497,12 +499,27 @@
# define LZO_CC_PELLESC 1
# define LZO_INFO_CC "Pelles C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__)
-#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
-# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# if defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# else
+# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# endif
+# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
+# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__)
# else
-# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# define LZO_CC_CLANG_CLANG 0x010000L
# endif
+# define LZO_CC_CLANG LZO_CC_CLANG_GNUC
+# define LZO_INFO_CC "clang"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# if defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# else
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# endif
+# define LZO_CC_LLVM LZO_CC_LLVM_GNUC
# define LZO_INFO_CC "llvm-gcc"
# define LZO_INFO_CCVER __VERSION__
#elif defined(__GNUC__) && defined(__VERSION__)
@@ -523,6 +540,10 @@
# define LZO_CC_AZTECC 1
# define LZO_INFO_CC "Aztec C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__)
+#elif defined(__CODEGEARC__)
+# define LZO_CC_CODEGEARC 1
+# define LZO_INFO_CC "CodeGear C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__)
#elif defined(__BORLANDC__)
# define LZO_CC_BORLANDC 1
# define LZO_INFO_CC "Borland C"
@@ -653,7 +674,7 @@
#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER)
# error "LZO_CC_MSC: _MSC_FULL_VER is not defined"
#endif
-#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY)
+#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY)
# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY)
# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E)
# define LZO_ARCH_CRAY_MPP 1
@@ -663,7 +684,7 @@
# endif
#endif
#if !defined(__LZO_ARCH_OVERRIDE)
-#if defined(LZO_ARCH_GENERIC)
+#if (LZO_ARCH_GENERIC)
# define LZO_INFO_ARCH "generic"
#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086 1
@@ -698,6 +719,9 @@
#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__)
# define LZO_ARCH_AVR 1
# define LZO_INFO_ARCH "avr"
+#elif defined(__avr32__) || defined(__AVR32__)
+# define LZO_ARCH_AVR32 1
+# define LZO_INFO_ARCH "avr32"
#elif defined(__bfin__)
# define LZO_ARCH_BLACKFIN 1
# define LZO_INFO_ARCH "blackfin"
@@ -820,10 +844,10 @@
# define LZO_ARCH_I086PM 1
# define LZO_ARCH_IA16PM 1
#endif
-#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM)
+#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM)
# error "this should not happen"
#endif
-#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086)
+#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086)
# error "this should not happen"
#endif
#if (LZO_ARCH_I086)
@@ -896,7 +920,7 @@
#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295))
# undef LZO_HAVE_MM_HUGE_ARRAY
#endif
-#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR)
+#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR)
# if (LZO_OS_DOS16)
# error "this should not happen"
# elif (LZO_CC_ZORTECHC)
@@ -1112,7 +1136,7 @@ extern "C" {
#if (LZO_ARCH_I086 && LZO_CC_DMC)
#elif (LZO_CC_CILLY) && defined(__GNUC__)
# define LZO_SIZEOF_LONG_LONG 8
-#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define LZO_SIZEOF_LONG_LONG 8
#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400))
# define LZO_SIZEOF_LONG_LONG 8
@@ -1146,12 +1170,12 @@ extern "C" {
#endif
#endif
#endif
-#if defined(__cplusplus) && defined(LZO_CC_GNUC)
+#if defined(__cplusplus) && (LZO_CC_GNUC)
# if (LZO_CC_GNUC < 0x020800ul)
# undef LZO_SIZEOF_LONG_LONG
# endif
#endif
-#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
+#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
# undef LZO_SIZEOF_LONG_LONG
#endif
#if !defined(LZO_SIZEOF_VOID_P)
@@ -1250,15 +1274,17 @@ extern "C" {
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T
#endif
#endif
-#if defined(LZO_ABI_NEUTRAL_ENDIAN)
+#if (LZO_ABI_NEUTRAL_ENDIAN)
# undef LZO_ABI_BIG_ENDIAN
# undef LZO_ABI_LITTLE_ENDIAN
-#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN)
+#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN)
#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP)
# define LZO_ABI_BIG_ENDIAN 1
+#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64)
+# define LZO_ABI_LITTLE_ENDIAN 1
#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430)
# define LZO_ABI_LITTLE_ENDIAN 1
-#elif (LZO_ARCH_M68K || LZO_ARCH_S390)
+#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390)
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__)
# if (__LITTLE_ENDIAN__ == 1)
@@ -1280,14 +1306,14 @@ extern "C" {
# define LZO_ABI_LITTLE_ENDIAN 1
#endif
#endif
-#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN)
+#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN)
# error "this should not happen"
#endif
-#if defined(LZO_ABI_BIG_ENDIAN)
+#if (LZO_ABI_BIG_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "be"
-#elif defined(LZO_ABI_LITTLE_ENDIAN)
+#elif (LZO_ABI_LITTLE_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "le"
-#elif defined(LZO_ABI_NEUTRAL_ENDIAN)
+#elif (LZO_ABI_NEUTRAL_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "neutral"
#endif
#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
@@ -1313,15 +1339,15 @@ extern "C" {
# define LZO_INFO_ABI_PM "ip32l64"
#endif
#if !defined(__LZO_LIBC_OVERRIDE)
-#if defined(LZO_LIBC_NAKED)
+#if (LZO_LIBC_NAKED)
# define LZO_INFO_LIBC "naked"
-#elif defined(LZO_LIBC_FREESTANDING)
+#elif (LZO_LIBC_FREESTANDING)
# define LZO_INFO_LIBC "freestanding"
-#elif defined(LZO_LIBC_MOSTLY_FREESTANDING)
+#elif (LZO_LIBC_MOSTLY_FREESTANDING)
# define LZO_INFO_LIBC "mfreestanding"
-#elif defined(LZO_LIBC_ISOC90)
+#elif (LZO_LIBC_ISOC90)
# define LZO_INFO_LIBC "isoc90"
-#elif defined(LZO_LIBC_ISOC99)
+#elif (LZO_LIBC_ISOC99)
# define LZO_INFO_LIBC "isoc99"
#elif defined(__dietlibc__)
# define LZO_LIBC_DIETLIBC 1
@@ -1353,22 +1379,24 @@ extern "C" {
#if !defined(__lzo_gnuc_extension__)
#if (LZO_CC_GNUC >= 0x020800ul)
# define __lzo_gnuc_extension__ __extension__
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_gnuc_extension__ __extension__
#else
-# define __lzo_gnuc_extension__
+# define __lzo_gnuc_extension__ /*empty*/
#endif
#endif
#if !defined(__lzo_ua_volatile)
# define __lzo_ua_volatile volatile
#endif
#if !defined(__lzo_alignof)
-#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
# define __lzo_alignof(e) __alignof__(e)
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
# define __lzo_alignof(e) __alignof__(e)
#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
# define __lzo_alignof(e) __alignof(e)
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_alignof(e) __alignof__(e)
#endif
#endif
#if defined(__lzo_alignof)
@@ -1379,7 +1407,7 @@ extern "C" {
# define __lzo_constructor __attribute__((__constructor__,__used__))
#elif (LZO_CC_GNUC >= 0x020700ul)
# define __lzo_constructor __attribute__((__constructor__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_constructor __attribute__((__constructor__))
#endif
#endif
@@ -1391,14 +1419,14 @@ extern "C" {
# define __lzo_destructor __attribute__((__destructor__,__used__))
#elif (LZO_CC_GNUC >= 0x020700ul)
# define __lzo_destructor __attribute__((__destructor__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_destructor __attribute__((__destructor__))
#endif
#endif
#if defined(__lzo_destructor)
# define __lzo_HAVE_destructor 1
#endif
-#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor)
+#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor)
# error "this should not happen"
#endif
#if !defined(__lzo_inline)
@@ -1407,7 +1435,7 @@ extern "C" {
# define __lzo_inline inline
#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
# define __lzo_inline __inline
-#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
# define __lzo_inline __inline__
#elif (LZO_CC_DMC)
# define __lzo_inline __inline
@@ -1417,6 +1445,8 @@ extern "C" {
# define __lzo_inline __inline
#elif (LZO_CC_MSC && (_MSC_VER >= 900))
# define __lzo_inline __inline
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_inline __inline__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define __lzo_inline inline
#endif
@@ -1424,7 +1454,7 @@ extern "C" {
#if defined(__lzo_inline)
# define __lzo_HAVE_inline 1
#else
-# define __lzo_inline
+# define __lzo_inline /*empty*/
#endif
#if !defined(__lzo_forceinline)
#if (LZO_CC_GNUC >= 0x030200ul)
@@ -1433,16 +1463,18 @@ extern "C" {
# define __lzo_forceinline __forceinline
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
# define __lzo_forceinline __forceinline
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
#endif
#endif
#if defined(__lzo_forceinline)
# define __lzo_HAVE_forceinline 1
#else
-# define __lzo_forceinline
+# define __lzo_forceinline /*empty*/
#endif
#if !defined(__lzo_noinline)
#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
@@ -1453,7 +1485,7 @@ extern "C" {
# define __lzo_noinline __declspec(noinline)
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_noinline __attribute__((__noinline__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
# define __lzo_noinline __declspec(noinline)
@@ -1462,14 +1494,16 @@ extern "C" {
# else
# define __lzo_noinline __declspec(noinline)
# endif
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_noinline __attribute__((__noinline__))
#endif
#endif
#if defined(__lzo_noinline)
# define __lzo_HAVE_noinline 1
#else
-# define __lzo_noinline
+# define __lzo_noinline /*empty*/
#endif
-#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline)
+#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline)
# error "this should not happen"
#endif
#if !defined(__lzo_noreturn)
@@ -1479,7 +1513,7 @@ extern "C" {
# define __lzo_noreturn __declspec(noreturn)
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_noreturn __attribute__((__noreturn__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
# define __lzo_noreturn __declspec(noreturn)
@@ -1488,16 +1522,16 @@ extern "C" {
#if defined(__lzo_noreturn)
# define __lzo_HAVE_noreturn 1
#else
-# define __lzo_noreturn
+# define __lzo_noreturn /*empty*/
#endif
#if !defined(__lzo_nothrow)
#if (LZO_CC_GNUC >= 0x030300ul)
# define __lzo_nothrow __attribute__((__nothrow__))
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus)
# define __lzo_nothrow __declspec(nothrow)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC)
# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_nothrow __attribute__((__nothrow__))
#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
# define __lzo_nothrow __declspec(nothrow)
@@ -1506,14 +1540,14 @@ extern "C" {
#if defined(__lzo_nothrow)
# define __lzo_HAVE_nothrow 1
#else
-# define __lzo_nothrow
+# define __lzo_nothrow /*empty*/
#endif
#if !defined(__lzo_restrict)
#if (LZO_CC_GNUC >= 0x030400ul)
# define __lzo_restrict __restrict__
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
# define __lzo_restrict __restrict__
-#elif (LZO_CC_LLVM)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM)
# define __lzo_restrict __restrict__
#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
# define __lzo_restrict __restrict
@@ -1522,7 +1556,7 @@ extern "C" {
#if defined(__lzo_restrict)
# define __lzo_HAVE_restrict 1
#else
-# define __lzo_restrict
+# define __lzo_restrict /*empty*/
#endif
#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
#if (LZO_CC_GNUC >= 0x030200ul)
@@ -1531,7 +1565,7 @@ extern "C" {
#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
# define __lzo_likely(e) (__builtin_expect(!!(e),1))
# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define __lzo_likely(e) (__builtin_expect(!!(e),1))
# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
#endif
@@ -1551,7 +1585,7 @@ extern "C" {
# define LZO_UNUSED(var) ((void) &var)
# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
# define LZO_UNUSED(var) if (&var) ; else
-# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define LZO_UNUSED(var) ((void) var)
# elif (LZO_CC_MSC && (_MSC_VER < 900))
# define LZO_UNUSED(var) if (&var) ; else
@@ -1570,7 +1604,7 @@ extern "C" {
# define LZO_UNUSED_FUNC(func) ((void) func)
# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
# define LZO_UNUSED_FUNC(func) if (func) ; else
-# elif (LZO_CC_LLVM)
+# elif (LZO_CC_CLANG || LZO_CC_LLVM)
# define LZO_UNUSED_FUNC(func) ((void) &func)
# elif (LZO_CC_MSC && (_MSC_VER < 900))
# define LZO_UNUSED_FUNC(func) if (func) ; else
@@ -1585,7 +1619,7 @@ extern "C" {
#if !defined(LZO_UNUSED_LABEL)
# if (LZO_CC_WATCOMC) && defined(__cplusplus)
# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
-# elif (LZO_CC_INTELC || LZO_CC_WATCOMC)
+# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC)
# define LZO_UNUSED_LABEL(l) if (0) goto l
# else
# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
@@ -1600,6 +1634,15 @@ extern "C" {
# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
# endif
#endif
+#if !defined(LZO_UNCONST_CAST)
+# if 0 && defined(__cplusplus)
+# define LZO_UNCONST_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e))))))
+# else
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e)))))
+# endif
+#endif
#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
@@ -1628,7 +1671,7 @@ extern "C" {
# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
# define __lzo_cdecl __cdecl
-# define __lzo_cdecl_atexit
+# define __lzo_cdecl_atexit /*empty*/
# define __lzo_cdecl_main __cdecl
# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
# define __lzo_cdecl_qsort __pascal
@@ -1669,24 +1712,24 @@ extern "C" {
# define __lzo_cdecl cdecl
#endif
#if !defined(__lzo_cdecl)
-# define __lzo_cdecl
+# define __lzo_cdecl /*empty*/
#endif
#if !defined(__lzo_cdecl_atexit)
-# define __lzo_cdecl_atexit
+# define __lzo_cdecl_atexit /*empty*/
#endif
#if !defined(__lzo_cdecl_main)
-# define __lzo_cdecl_main
+# define __lzo_cdecl_main /*empty*/
#endif
#if !defined(__lzo_cdecl_qsort)
-# define __lzo_cdecl_qsort
+# define __lzo_cdecl_qsort /*empty*/
#endif
#if !defined(__lzo_cdecl_sighandler)
-# define __lzo_cdecl_sighandler
+# define __lzo_cdecl_sighandler /*empty*/
#endif
#if !defined(__lzo_cdecl_va)
# define __lzo_cdecl_va __lzo_cdecl
#endif
-#if !defined(LZO_CFG_NO_WINDOWS_H)
+#if !(LZO_CFG_NO_WINDOWS_H)
#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
@@ -1732,7 +1775,7 @@ extern "C" {
#elif (LZO_ARCH_POWERPC)
# define LZO_OPT_PREFER_PREINC 1
# define LZO_OPT_PREFER_PREDEC 1
-# if defined(LZO_ABI_BIG_ENDIAN)
+# if (LZO_ABI_BIG_ENDIAN)
# define LZO_OPT_UNALIGNED16 1
# define LZO_OPT_UNALIGNED32 1
# endif
@@ -1746,28 +1789,29 @@ extern "C" {
# define LZO_OPT_PREFER_POSTINC 1
# define LZO_OPT_PREFER_PREDEC 1
#endif
-#if !defined(LZO_CFG_NO_INLINE_ASM)
-#if defined(LZO_CC_LLVM)
+#ifndef LZO_CFG_NO_INLINE_ASM
+#if (LZO_CC_LLVM)
# define LZO_CFG_NO_INLINE_ASM 1
#endif
#endif
-#if !defined(LZO_CFG_NO_UNALIGNED)
-#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC)
+#ifndef LZO_CFG_NO_UNALIGNED
+#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC)
# define LZO_CFG_NO_UNALIGNED 1
#endif
#endif
-#if defined(LZO_CFG_NO_UNALIGNED)
+#if (LZO_CFG_NO_UNALIGNED)
# undef LZO_OPT_UNALIGNED16
# undef LZO_OPT_UNALIGNED32
# undef LZO_OPT_UNALIGNED64
#endif
-#if defined(LZO_CFG_NO_INLINE_ASM)
+#if (LZO_CFG_NO_INLINE_ASM)
#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
# define LZO_ASM_SYNTAX_MSC 1
#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
-#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul))
+#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
# define LZO_ASM_SYNTAX_GNUC 1
-#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
# define LZO_ASM_SYNTAX_GNUC 1
#endif
#if (LZO_ASM_SYNTAX_GNUC)
@@ -1830,34 +1874,34 @@ extern "C" {
#undef LZO_HAVE_CONFIG_H
#include "minilzo.h"
-#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2030)
+#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2060)
# error "version mismatch in miniLZO source files"
#endif
#ifdef MINILZO_HAVE_CONFIG_H
-# define LZO_HAVE_CONFIG_H
+# define LZO_HAVE_CONFIG_H 1
#endif
#ifndef __LZO_CONF_H
-#define __LZO_CONF_H
+#define __LZO_CONF_H 1
#if !defined(__LZO_IN_MINILZO)
-#if defined(LZO_CFG_FREESTANDING)
+#if (LZO_CFG_FREESTANDING)
# define LZO_LIBC_FREESTANDING 1
# define LZO_OS_FREESTANDING 1
# define ACC_LIBC_FREESTANDING 1
# define ACC_OS_FREESTANDING 1
#endif
-#if defined(LZO_CFG_NO_UNALIGNED)
+#if (LZO_CFG_NO_UNALIGNED)
# define ACC_CFG_NO_UNALIGNED 1
#endif
-#if defined(LZO_ARCH_GENERIC)
+#if (LZO_ARCH_GENERIC)
# define ACC_ARCH_GENERIC 1
#endif
-#if defined(LZO_ABI_NEUTRAL_ENDIAN)
+#if (LZO_ABI_NEUTRAL_ENDIAN)
# define ACC_ABI_NEUTRAL_ENDIAN 1
#endif
-#if defined(LZO_HAVE_CONFIG_H)
+#if (LZO_HAVE_CONFIG_H)
# define ACC_CONFIG_NO_HEADER 1
#endif
#if defined(LZO_CFG_EXTRA_CONFIG_HEADER)
@@ -1886,11 +1930,14 @@ extern "C" {
#endif
#if (LZO_CC_SUNPROC)
+#if !defined(__cplusplus)
# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED)
# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP)
+# pragma error_messages(off,E_STATEMENT_NOT_REACHED)
+#endif
#endif
-#if defined(__LZO_MMODEL_HUGE) && (!LZO_HAVE_MM_HUGE_PTR)
+#if (__LZO_MMODEL_HUGE) && !(LZO_HAVE_MM_HUGE_PTR)
# error "this should not happen - check defines for __huge"
#endif
@@ -1955,40 +2002,44 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#include <string.h>
#endif
-#if defined(LZO_CFG_FREESTANDING)
+#if (LZO_CFG_FREESTANDING)
# undef HAVE_MEMCMP
# undef HAVE_MEMCPY
# undef HAVE_MEMMOVE
# undef HAVE_MEMSET
#endif
-#if !defined(HAVE_MEMCMP)
+#if !(HAVE_MEMCMP)
# undef memcmp
# define memcmp(a,b,c) lzo_memcmp(a,b,c)
-#elif !defined(__LZO_MMODEL_HUGE)
+#elif !(__LZO_MMODEL_HUGE)
+# undef lzo_memcmp
# define lzo_memcmp(a,b,c) memcmp(a,b,c)
#endif
-#if !defined(HAVE_MEMCPY)
+#if !(HAVE_MEMCPY)
# undef memcpy
# define memcpy(a,b,c) lzo_memcpy(a,b,c)
-#elif !defined(__LZO_MMODEL_HUGE)
+#elif !(__LZO_MMODEL_HUGE)
+# undef lzo_memcpy
# define lzo_memcpy(a,b,c) memcpy(a,b,c)
#endif
-#if !defined(HAVE_MEMMOVE)
+#if !(HAVE_MEMMOVE)
# undef memmove
# define memmove(a,b,c) lzo_memmove(a,b,c)
-#elif !defined(__LZO_MMODEL_HUGE)
+#elif !(__LZO_MMODEL_HUGE)
+# undef lzo_memmove
# define lzo_memmove(a,b,c) memmove(a,b,c)
#endif
-#if !defined(HAVE_MEMSET)
+#if !(HAVE_MEMSET)
# undef memset
# define memset(a,b,c) lzo_memset(a,b,c)
-#elif !defined(__LZO_MMODEL_HUGE)
+#elif !(__LZO_MMODEL_HUGE)
+# undef lzo_memset
# define lzo_memset(a,b,c) memset(a,b,c)
#endif
#undef NDEBUG
-#if defined(LZO_CFG_FREESTANDING)
+#if (LZO_CFG_FREESTANDING)
# undef LZO_DEBUG
# define NDEBUG 1
# undef assert
@@ -2008,13 +2059,24 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#endif
#if !defined(__lzo_inline)
-# define __lzo_inline
+# define __lzo_inline /*empty*/
#endif
#if !defined(__lzo_forceinline)
-# define __lzo_forceinline
+# define __lzo_forceinline /*empty*/
#endif
#if !defined(__lzo_noinline)
-# define __lzo_noinline
+# define __lzo_noinline /*empty*/
+#endif
+
+#if (LZO_CFG_PGO)
+# undef __acc_likely
+# undef __acc_unlikely
+# undef __lzo_likely
+# undef __lzo_unlikely
+# define __acc_likely(e) (e)
+# define __acc_unlikely(e) (e)
+# define __lzo_likely(e) (e)
+# define __lzo_unlikely(e) (e)
#endif
#if 1
@@ -2050,24 +2112,69 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#endif
#endif
-#if 1 && !defined(LZO_CFG_NO_UNALIGNED)
-#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386 || LZO_ARCH_POWERPC)
# if (LZO_SIZEOF_SHORT == 2)
-# define LZO_UNALIGNED_OK_2
+# define LZO_UNALIGNED_OK_2 1
# endif
# if (LZO_SIZEOF_INT == 4)
-# define LZO_UNALIGNED_OK_4
+# define LZO_UNALIGNED_OK_4 1
# endif
#endif
+#if 1 && (LZO_ARCH_AMD64)
+# if defined(LZO_UINT64_MAX)
+# define LZO_UNALIGNED_OK_8 1
+# endif
#endif
-
+#if (LZO_CFG_NO_UNALIGNED)
+# undef LZO_UNALIGNED_OK_2
+# undef LZO_UNALIGNED_OK_4
+# undef LZO_UNALIGNED_OK_8
+#endif
+
+#undef UA_GET16
+#undef UA_SET16
+#undef UA_COPY16
+#undef UA_GET32
+#undef UA_SET32
+#undef UA_COPY32
+#undef UA_GET64
+#undef UA_SET64
+#undef UA_COPY64
#if defined(LZO_UNALIGNED_OK_2)
- LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(unsigned short) == 2)
+# if 1 && defined(ACC_UA_COPY16)
+# define UA_GET16 ACC_UA_GET16
+# define UA_SET16 ACC_UA_SET16
+# define UA_COPY16 ACC_UA_COPY16
+# else
+# define UA_GET16(p) (* (__lzo_ua_volatile const lzo_ushortp) (__lzo_ua_volatile const lzo_voidp) (p))
+# define UA_SET16(p,v) ((* (__lzo_ua_volatile lzo_ushortp) (__lzo_ua_volatile lzo_voidp) (p)) = (unsigned short) (v))
+# define UA_COPY16(d,s) UA_SET16(d, UA_GET16(s))
+# endif
#endif
-#if defined(LZO_UNALIGNED_OK_4)
- LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4)
-#elif defined(LZO_ALIGNED_OK_4)
- LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4)
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4)
+# if 1 && defined(ACC_UA_COPY32)
+# define UA_GET32 ACC_UA_GET32
+# define UA_SET32 ACC_UA_SET32
+# define UA_COPY32 ACC_UA_COPY32
+# else
+# define UA_GET32(p) (* (__lzo_ua_volatile const lzo_uint32p) (__lzo_ua_volatile const lzo_voidp) (p))
+# define UA_SET32(p,v) ((* (__lzo_ua_volatile lzo_uint32p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint32) (v))
+# define UA_COPY32(d,s) UA_SET32(d, UA_GET32(s))
+# endif
+#endif
+#if defined(LZO_UNALIGNED_OK_8)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64) == 8)
+# if 1 && defined(ACC_UA_COPY64)
+# define UA_GET64 ACC_UA_GET64
+# define UA_SET64 ACC_UA_SET64
+# define UA_COPY64 ACC_UA_COPY64
+# else
+# define UA_GET64(p) (* (__lzo_ua_volatile const lzo_uint64p) (__lzo_ua_volatile const lzo_voidp) (p))
+# define UA_SET64(p,v) ((* (__lzo_ua_volatile lzo_uint64p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint64) (v))
+# define UA_COPY64(d,s) UA_SET64(d, UA_GET64(s))
+# endif
#endif
#define MEMCPY8_DS(dest,src,len) \
@@ -2079,19 +2186,17 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#define MEMCPY_DS(dest,src,len) \
do *dest++ = *src++; while (--len > 0)
-__LZO_EXTERN_C int __lzo_init_done;
-__LZO_EXTERN_C const char __lzo_copyright[];
LZO_EXTERN(const lzo_bytep) lzo_copyright(void);
#ifndef __LZO_PTR_H
-#define __LZO_PTR_H
+#define __LZO_PTR_H 1
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(lzo_uintptr_t)
-# if defined(__LZO_MMODEL_HUGE)
+# if (__LZO_MMODEL_HUGE)
# define lzo_uintptr_t unsigned long
# else
# define lzo_uintptr_t acc_uintptr_t
@@ -2140,6 +2245,10 @@ typedef union
lzo_uint a_lzo_uint;
lzo_int32 a_lzo_int32;
lzo_uint32 a_lzo_uint32;
+#if defined(LZO_UINT64_MAX)
+ lzo_int64 a_lzo_int64;
+ lzo_uint64 a_lzo_uint64;
+#endif
ptrdiff_t a_ptrdiff_t;
lzo_uintptr_t a_lzo_uintptr_t;
lzo_voidp a_lzo_voidp;
@@ -2161,14 +2270,19 @@ lzo_full_align_t;
#endif
-#define LZO_DETERMINISTIC
+#ifndef LZO_DETERMINISTIC
+#define LZO_DETERMINISTIC 1
+#endif
-#define LZO_DICT_USE_PTR
+#ifndef LZO_DICT_USE_PTR
+#define LZO_DICT_USE_PTR 1
#if 0 && (LZO_ARCH_I086)
# undef LZO_DICT_USE_PTR
+# define LZO_DICT_USE_PTR 0
+#endif
#endif
-#if defined(LZO_DICT_USE_PTR)
+#if (LZO_DICT_USE_PTR)
# define lzo_dict_t const lzo_bytep
# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
#else
@@ -2216,22 +2330,22 @@ __lzo_align_gap(const lzo_voidp ptr, lzo_uint size)
}
#endif
+#if !defined(MINILZO_CFG_SKIP_LZO_UTIL)
/* If you use the LZO library in a product, I would appreciate that you
* keep this copyright string in the executable of your product.
*/
-const char __lzo_copyright[] =
+static const char __lzo_copyright[] =
#if !defined(__LZO_IN_MINLZO)
LZO_VERSION_STRING;
#else
"\r\n\n"
"LZO data compression library.\n"
- "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Markus Franz Xaver Johannes Oberhumer\n"
+ "$Copyright: LZO Copyright (C) 1996-2011 Markus Franz Xaver Johannes Oberhumer\n"
"<markus@oberhumer.com>\n"
"http://www.oberhumer.com $\n\n"
"$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n"
- "$Built: " __DATE__ " " __TIME__ " $\n"
"$Info: " LZO_INFO_STRING " $\n";
#endif
@@ -2321,6 +2435,7 @@ lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len)
#undef LZO_DO8
#undef LZO_DO16
+#endif
#if !defined(MINILZO_CFG_SKIP_LZO_STRING)
#undef lzo_memcmp
#undef lzo_memcpy
@@ -2343,7 +2458,7 @@ lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len)
#endif
LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len)
{
-#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCMP)
+#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP)
const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1;
const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2;
if __lzo_likely(len > 0) do
@@ -2360,7 +2475,7 @@ LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo
}
LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len)
{
-#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCPY)
+#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY)
lzo_hbyte_p p1 = (lzo_hbyte_p) dest;
const lzo_hbyte_p p2 = (const lzo_hbyte_p) src;
if (!(len > 0) || p1 == p2)
@@ -2375,7 +2490,7 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src
}
LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len)
{
-#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMMOVE)
+#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE)
lzo_hbyte_p p1 = (lzo_hbyte_p) dest;
const lzo_hbyte_p p2 = (const lzo_hbyte_p) src;
if (!(len > 0) || p1 == p2)
@@ -2401,7 +2516,7 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p sr
}
LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len)
{
-#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMSET)
+#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET)
lzo_hbyte_p p = (lzo_hbyte_p) s;
if __lzo_likely(len > 0) do
*p++ = (unsigned char) c;
@@ -2413,6 +2528,7 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len)
}
#undef LZOLIB_PUBLIC
#endif
+#if !defined(MINILZO_CFG_SKIP_LZO_INIT)
#if !defined(__LZO_IN_MINILZO)
@@ -2426,6 +2542,11 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len)
ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32)
ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0)
ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4)
+#if defined(LZO_UINT64_MAX)
+ ACCCHK_ASSERT(sizeof(lzo_uint64) == 8)
+ ACCCHK_ASSERT_IS_SIGNED_T(lzo_int64)
+ ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint64)
+#endif
#if !defined(__LZO_UINTPTR_T_IS_POINTER)
ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t)
@@ -2440,40 +2561,158 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len)
#endif
#undef ACCCHK_ASSERT
+#define WANT_lzo_bitops_clz32 1
+#define WANT_lzo_bitops_clz64 1
+#define WANT_lzo_bitops_ctz32 1
+#define WANT_lzo_bitops_ctz64 1
+
+#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400)))
+#include <intrin.h>
+#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0
+#pragma intrinsic(_BitScanReverse)
+static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v)
+{
+ unsigned long r;
+ (void) _BitScanReverse(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_clz32 lzo_bitops_clz32
+#endif
+#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0
+#pragma intrinsic(_BitScanReverse64)
+static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v)
+{
+ unsigned long r;
+ (void) _BitScanReverse64(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_clz64 lzo_bitops_clz64
+#endif
+#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
+#pragma intrinsic(_BitScanForward)
+static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v)
+{
+ unsigned long r;
+ (void) _BitScanForward(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_ctz32 lzo_bitops_ctz32
+#endif
+#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
+#pragma intrinsic(_BitScanForward64)
+static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v)
+{
+ unsigned long r;
+ (void) _BitScanForward64(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_ctz64 lzo_bitops_ctz64
+#endif
+
+#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul))))
+#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32)
+#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v))
+#endif
+#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX)
+#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v))
+#endif
+#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
+#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v))
+#endif
+#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
+#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v))
+#endif
+#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32)
+#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v))
+#endif
+#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX)
+#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v))
+#endif
+#endif
+
+#if 0
+#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off)))
+#else
+static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off)
+{
+ return (lzo_voidp) ((lzo_bytep) ptr + off);
+}
+#endif
+
LZO_PUBLIC(int)
_lzo_config_check(void)
{
lzo_bool r = 1;
- union { unsigned char c[2*sizeof(lzo_xint)]; lzo_xint l[2]; } u;
- lzo_uintptr_t p;
-
+ union {
+ lzo_xint a[2]; unsigned char b[2*LZO_MAX(8,sizeof(lzo_xint))];
+#if defined(LZO_UNALIGNED_OK_8)
+ lzo_uint64 c[2];
+#endif
+ unsigned short x[2]; lzo_uint32 y[2]; lzo_uint z[2];
+ } u;
+ lzo_voidp p;
+
+ u.a[0] = u.a[1] = 0;
+ p = u2p(&u, 0);
+ r &= ((* (lzo_bytep) p) == 0);
#if !defined(LZO_CFG_NO_CONFIG_CHECK)
#if defined(LZO_ABI_BIG_ENDIAN)
- u.l[0] = u.l[1] = 0; u.c[sizeof(lzo_xint) - 1] = 128;
- r &= (u.l[0] == 128);
+ u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128;
+ p = u2p(&u, 0);
+ r &= ((* (lzo_uintp) p) == 128);
#endif
#if defined(LZO_ABI_LITTLE_ENDIAN)
- u.l[0] = u.l[1] = 0; u.c[0] = 128;
- r &= (u.l[0] == 128);
+ u.a[0] = u.a[1] = 0; u.b[0] = 128;
+ p = u2p(&u, 0);
+ r &= ((* (lzo_uintp) p) == 128);
#endif
#if defined(LZO_UNALIGNED_OK_2)
- p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0];
- u.l[0] = u.l[1] = 0;
- r &= ((* (const lzo_ushortp) (p+1)) == 0);
+ u.a[0] = u.a[1] = 0;
+ u.b[0] = 1; u.b[sizeof(unsigned short) + 1] = 2;
+ p = u2p(&u, 1);
+ r &= ((* (lzo_ushortp) p) == 0);
#endif
#if defined(LZO_UNALIGNED_OK_4)
- p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0];
- u.l[0] = u.l[1] = 0;
- r &= ((* (const lzo_uint32p) (p+1)) == 0);
+ u.a[0] = u.a[1] = 0;
+ u.b[0] = 3; u.b[sizeof(lzo_uint32) + 1] = 4;
+ p = u2p(&u, 1);
+ r &= ((* (lzo_uint32p) p) == 0);
+#endif
+#if defined(LZO_UNALIGNED_OK_8)
+ u.c[0] = u.c[1] = 0;
+ u.b[0] = 5; u.b[sizeof(lzo_uint64) + 1] = 6;
+ p = u2p(&u, 1);
+ r &= ((* (lzo_uint64p) p) == 0);
+#endif
+#if defined(lzo_bitops_clz32)
+ { unsigned i; lzo_uint32 v = 1;
+ for (i = 0; i < 32; i++, v <<= 1)
+ r &= lzo_bitops_clz32(v) == 31 - i;
+ }
+#endif
+#if defined(lzo_bitops_clz64)
+ { unsigned i; lzo_uint64 v = 1;
+ for (i = 0; i < 64; i++, v <<= 1)
+ r &= lzo_bitops_clz64(v) == 63 - i;
+ }
+#endif
+#if defined(lzo_bitops_ctz32)
+ { unsigned i; lzo_uint32 v = 1;
+ for (i = 0; i < 32; i++, v <<= 1)
+ r &= lzo_bitops_ctz32(v) == i;
+ }
+#endif
+#if defined(lzo_bitops_ctz64)
+ { unsigned i; lzo_uint64 v = 1;
+ for (i = 0; i < 64; i++, v <<= 1)
+ r &= lzo_bitops_ctz64(v) == i;
+ }
#endif
#endif
- LZO_UNUSED(u); LZO_UNUSED(p);
return r == 1 ? LZO_E_OK : LZO_E_ERROR;
}
-int __lzo_init_done = 0;
-
LZO_PUBLIC(int)
__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5,
int s6, int s7, int s8, int s9)
@@ -2489,8 +2728,6 @@ __lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5,
#endif
#undef ACCCHK_ASSERT
- __lzo_init_done = 1;
-
if (v == 0)
return LZO_E_ERROR;
@@ -2532,27 +2769,47 @@ int __far __pascal LibMain ( int a, short b, short c, long d )
#endif
-#define do_compress _lzo1x_1_do_compress
+#endif
+
+#define LZO1X 1
+#define LZO_EOF_CODE 1
+#define M2_MAX_OFFSET 0x0800
#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS)
-#define LZO_NEED_DICT_H
+#if 1 && defined(UA_GET32)
+#undef LZO_DICT_USE_PTR
+#define LZO_DICT_USE_PTR 0
+#undef lzo_dict_t
+#define lzo_dict_t unsigned short
+#endif
+
+#define LZO_NEED_DICT_H 1
+#ifndef D_BITS
#define D_BITS 14
+#endif
#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5)
#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
+#if 1
+#define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS)))
+#else
+#define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS)))
+#endif
#ifndef __LZO_CONFIG1X_H
-#define __LZO_CONFIG1X_H
+#define __LZO_CONFIG1X_H 1
#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z)
-# define LZO1X
+# define LZO1X 1
#endif
#if !defined(__LZO_IN_MINILZO)
#include "lzo/lzo1x.h"
#endif
-#define LZO_EOF_CODE
+#ifndef LZO_EOF_CODE
+#define LZO_EOF_CODE 1
+#endif
#undef LZO_DETERMINISTIC
#define M1_MAX_OFFSET 0x0400
@@ -2592,7 +2849,7 @@ int __far __pascal LibMain ( int a, short b, short c, long d )
#define DL_MIN_LEN M2_MIN_LEN
#ifndef __LZO_DICT_H
-#define __LZO_DICT_H
+#define __LZO_DICT_H 1
#ifdef __cplusplus
extern "C" {
@@ -2633,10 +2890,10 @@ extern "C" {
#if (D_BITS != DL_BITS + DD_BITS)
# error "D_BITS does not match"
#endif
-#if (D_BITS < 8 || D_BITS > 18)
+#if (D_BITS < 6 || D_BITS > 18)
# error "invalid D_BITS"
#endif
-#if (DL_BITS < 8 || DL_BITS > 20)
+#if (DL_BITS < 6 || DL_BITS > 20)
# error "invalid DL_BITS"
#endif
#if (DD_BITS < 0 || DD_BITS > 6)
@@ -2695,14 +2952,14 @@ extern "C" {
# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT))
#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL)
-# define __LZO_HASH_INCREMENTAL
+# define __LZO_HASH_INCREMENTAL 1
# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT)
# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2])
# define _DINDEX(dv,p) (dv)
# define DVAL_LOOKAHEAD DL_MIN_LEN
#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A)
-# define __LZO_HASH_INCREMENTAL
+# define __LZO_HASH_INCREMENTAL 1
# define DVAL_FIRST(dv,p) dv = _DV_A((p),5)
# define DVAL_NEXT(dv,p) \
dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2])
@@ -2710,7 +2967,7 @@ extern "C" {
# define DVAL_LOOKAHEAD DL_MIN_LEN
#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B)
-# define __LZO_HASH_INCREMENTAL
+# define __LZO_HASH_INCREMENTAL 1
# define DVAL_FIRST(dv,p) dv = _DV_B((p),5)
# define DVAL_NEXT(dv,p) \
dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5)))
@@ -2739,7 +2996,12 @@ extern "C" {
#if !defined(DVAL_ASSERT)
#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG)
-static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
+#if (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_LLVM)
+static void __attribute__((__unused__))
+#else
+static void
+#endif
+DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
{
lzo_xint df;
DVAL_FIRST(df,(p));
@@ -2750,11 +3012,11 @@ static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
#endif
#endif
-#if defined(LZO_DICT_USE_PTR)
+#if (LZO_DICT_USE_PTR)
# define DENTRY(p,in) (p)
# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex]
#else
-# define DENTRY(p,in) ((lzo_uint) ((p)-(in)))
+# define DENTRY(p,in) ((lzo_dict_t) pd(p, in))
# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex]
#endif
@@ -2775,7 +3037,7 @@ static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
#endif
-#if defined(LZO_DICT_USE_PTR)
+#if (LZO_DICT_USE_PTR)
#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
(m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset)
@@ -2784,7 +3046,7 @@ static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
(BOUNDS_CHECKING_OFF_IN_EXPR(( \
m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \
PTR_LT(m_pos,in) || \
- (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) <= 0 || \
+ (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \
m_off > max_offset )))
#else
@@ -2801,7 +3063,7 @@ static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
#endif
-#if defined(LZO_DETERMINISTIC)
+#if (LZO_DETERMINISTIC)
# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET
#else
# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET
@@ -2817,17 +3079,99 @@ static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
#endif
+#define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR)
+
+#ifndef DO_COMPRESS
#define DO_COMPRESS lzo1x_1_compress
+#endif
+
+#if 1 && defined(DO_COMPRESS) && !defined(do_compress)
+# define do_compress LZO_CPP_ECONCAT2(DO_COMPRESS,_core)
+#endif
+
+#if defined(UA_GET64) && (LZO_ABI_BIG_ENDIAN)
+# define WANT_lzo_bitops_clz64 1
+#elif defined(UA_GET64) && (LZO_ABI_LITTLE_ENDIAN)
+# define WANT_lzo_bitops_ctz64 1
+#elif defined(UA_GET32) && (LZO_ABI_BIG_ENDIAN)
+# define WANT_lzo_bitops_clz32 1
+#elif defined(UA_GET32) && (LZO_ABI_LITTLE_ENDIAN)
+# define WANT_lzo_bitops_ctz32 1
+#endif
+
+#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400)))
+#include <intrin.h>
+#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0
+#pragma intrinsic(_BitScanReverse)
+static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v)
+{
+ unsigned long r;
+ (void) _BitScanReverse(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_clz32 lzo_bitops_clz32
+#endif
+#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0
+#pragma intrinsic(_BitScanReverse64)
+static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v)
+{
+ unsigned long r;
+ (void) _BitScanReverse64(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_clz64 lzo_bitops_clz64
+#endif
+#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
+#pragma intrinsic(_BitScanForward)
+static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v)
+{
+ unsigned long r;
+ (void) _BitScanForward(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_ctz32 lzo_bitops_ctz32
+#endif
+#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
+#pragma intrinsic(_BitScanForward64)
+static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v)
+{
+ unsigned long r;
+ (void) _BitScanForward64(&r, v);
+ return (unsigned) r;
+}
+#define lzo_bitops_ctz64 lzo_bitops_ctz64
+#endif
+
+#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul))))
+#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32)
+#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v))
+#endif
+#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX)
+#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v))
+#endif
+#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
+#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v))
+#endif
+#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
+#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v))
+#endif
+#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32)
+#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v))
+#endif
+#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX)
+#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v))
+#endif
+#endif
static __lzo_noinline lzo_uint
do_compress ( const lzo_bytep in , lzo_uint in_len,
lzo_bytep out, lzo_uintp out_len,
- lzo_voidp wrkmem )
+ lzo_uint ti, lzo_voidp wrkmem)
{
register const lzo_bytep ip;
lzo_bytep op;
const lzo_bytep const in_end = in + in_len;
- const lzo_bytep const ip_end = in + in_len - M2_MAX_LEN - 5;
+ const lzo_bytep const ip_end = in + in_len - 20;
const lzo_bytep ii;
lzo_dict_p const dict = (lzo_dict_p) wrkmem;
@@ -2835,14 +3179,17 @@ do_compress ( const lzo_bytep in , lzo_uint in_len,
ip = in;
ii = ip;
- ip += 4;
+ ip += ti < 4 ? 4 - ti : 0;
for (;;)
{
- register const lzo_bytep m_pos;
- lzo_uint m_off;
+ const lzo_bytep m_pos;
+#if !(LZO_DETERMINISTIC)
+ LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0);
lzo_uint m_len;
lzo_uint dindex;
-
+next:
+ if __lzo_unlikely(ip >= ip_end)
+ break;
DINDEX1(dindex,ip);
GINDEX(m_pos,m_off,dict,dindex,in);
if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
@@ -2860,200 +3207,245 @@ do_compress ( const lzo_bytep in , lzo_uint in_len,
goto literal;
try_match:
-#if 1 && defined(LZO_UNALIGNED_OK_2)
- if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
+#if defined(UA_GET32)
+ if (UA_GET32(m_pos) != UA_GET32(ip))
#else
- if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
+ if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3])
#endif
{
+literal:
+ UPDATE_I(dict,0,dindex,ip,in);
+ ip += 1 + ((ip - ii) >> 5);
+ continue;
}
- else
- {
- if __lzo_likely(m_pos[2] == ip[2])
- {
-#if 0
- if (m_off <= M2_MAX_OFFSET)
- goto match;
- if (lit <= 3)
- goto match;
- if (lit == 3)
- {
- assert(op - 2 > out); op[-2] |= LZO_BYTE(3);
- *op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
- goto code_match;
- }
- if (m_pos[3] == ip[3])
-#endif
- goto match;
- }
- else
- {
-#if 0
-#if 0
- if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3)
+ UPDATE_I(dict,0,dindex,ip,in);
#else
- if (m_off <= M1_MAX_OFFSET && lit == 3)
-#endif
- {
- register lzo_uint t;
-
- t = lit;
- assert(op - 2 > out); op[-2] |= LZO_BYTE(t);
- do *op++ = *ii++; while (--t > 0);
- assert(ii == ip);
- m_off -= 1;
- *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2));
- *op++ = LZO_BYTE(m_off >> 2);
- ip += 2;
- goto match_done;
- }
-#endif
- }
- }
-
+ lzo_uint m_off;
+ lzo_uint m_len;
+ {
+ lzo_uint32 dv;
+ lzo_uint dindex;
literal:
- UPDATE_I(dict,0,dindex,ip,in);
- ++ip;
+ ip += 1 + ((ip - ii) >> 5);
+next:
if __lzo_unlikely(ip >= ip_end)
break;
- continue;
-
-match:
+ dv = UA_GET32(ip);
+ dindex = DINDEX(dv,ip);
+ GINDEX(m_off,m_pos,in+dict,dindex,in);
UPDATE_I(dict,0,dindex,ip,in);
- if (pd(ip,ii) > 0)
- {
- register lzo_uint t = pd(ip,ii);
+ if __lzo_unlikely(dv != UA_GET32(m_pos))
+ goto literal;
+ }
+#endif
+ ii -= ti; ti = 0;
+ {
+ register lzo_uint t = pd(ip,ii);
+ if (t != 0)
+ {
if (t <= 3)
{
- assert(op - 2 > out);
op[-2] |= LZO_BYTE(t);
+#if defined(UA_COPY32)
+ UA_COPY32(op, ii);
+ op += t;
+#else
+ { do *op++ = *ii++; while (--t > 0); }
+#endif
}
- else if (t <= 18)
+#if defined(UA_COPY32) || defined(UA_COPY64)
+ else if (t <= 16)
+ {
*op++ = LZO_BYTE(t - 3);
+#if defined(UA_COPY64)
+ UA_COPY64(op, ii);
+ UA_COPY64(op+8, ii+8);
+#else
+ UA_COPY32(op, ii);
+ UA_COPY32(op+4, ii+4);
+ UA_COPY32(op+8, ii+8);
+ UA_COPY32(op+12, ii+12);
+#endif
+ op += t;
+ }
+#endif
else
{
- register lzo_uint tt = t - 18;
-
- *op++ = 0;
- while (tt > 255)
+ if (t <= 18)
+ *op++ = LZO_BYTE(t - 3);
+ else
{
- tt -= 255;
+ register lzo_uint tt = t - 18;
*op++ = 0;
+ while __lzo_unlikely(tt > 255)
+ {
+ tt -= 255;
+#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
+ * (volatile unsigned char *) op++ = 0;
+#else
+ *op++ = 0;
+#endif
+ }
+ assert(tt > 0);
+ *op++ = LZO_BYTE(tt);
}
- assert(tt > 0);
- *op++ = LZO_BYTE(tt);
+#if defined(UA_COPY32) || defined(UA_COPY64)
+ do {
+#if defined(UA_COPY64)
+ UA_COPY64(op, ii);
+ UA_COPY64(op+8, ii+8);
+#else
+ UA_COPY32(op, ii);
+ UA_COPY32(op+4, ii+4);
+ UA_COPY32(op+8, ii+8);
+ UA_COPY32(op+12, ii+12);
+#endif
+ op += 16; ii += 16; t -= 16;
+ } while (t >= 16); if (t > 0)
+#endif
+ { do *op++ = *ii++; while (--t > 0); }
}
- do *op++ = *ii++; while (--t > 0);
}
-
- assert(ii == ip);
- ip += 3;
- if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ ||
- m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++
-#ifdef LZO1Y
- || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++
- || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++
+ }
+ m_len = 4;
+ {
+#if defined(UA_GET64)
+ lzo_uint64 v;
+ v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len);
+ if __lzo_unlikely(v == 0) {
+ do {
+ m_len += 8;
+ v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len);
+ if __lzo_unlikely(ip + m_len >= ip_end)
+ goto m_len_done;
+ } while (v == 0);
+ }
+#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_clz64)
+ m_len += lzo_bitops_clz64(v) / CHAR_BIT;
+#elif (LZO_ABI_BIG_ENDIAN)
+ if ((v >> (64 - CHAR_BIT)) == 0) do {
+ v <<= CHAR_BIT;
+ m_len += 1;
+ } while ((v >> (64 - CHAR_BIT)) == 0);
+#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz64)
+ m_len += lzo_bitops_ctz64(v) / CHAR_BIT;
+#elif (LZO_ABI_LITTLE_ENDIAN)
+ if ((v & UCHAR_MAX) == 0) do {
+ v >>= CHAR_BIT;
+ m_len += 1;
+ } while ((v & UCHAR_MAX) == 0);
+#else
+ if (ip[m_len] == m_pos[m_len]) do {
+ m_len += 1;
+ } while (ip[m_len] == m_pos[m_len]);
+#endif
+#elif defined(UA_GET32)
+ lzo_uint32 v;
+ v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len);
+ if __lzo_unlikely(v == 0) {
+ do {
+ m_len += 4;
+ v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len);
+ if __lzo_unlikely(ip + m_len >= ip_end)
+ goto m_len_done;
+ } while (v == 0);
+ }
+#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_clz32)
+ m_len += lzo_bitops_clz32(v) / CHAR_BIT;
+#elif (LZO_ABI_BIG_ENDIAN)
+ if ((v >> (32 - CHAR_BIT)) == 0) do {
+ v <<= CHAR_BIT;
+ m_len += 1;
+ } while ((v >> (32 - CHAR_BIT)) == 0);
+#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz32)
+ m_len += lzo_bitops_ctz32(v) / CHAR_BIT;
+#elif (LZO_ABI_LITTLE_ENDIAN)
+ if ((v & UCHAR_MAX) == 0) do {
+ v >>= CHAR_BIT;
+ m_len += 1;
+ } while ((v & UCHAR_MAX) == 0);
+#else
+ if (ip[m_len] == m_pos[m_len]) do {
+ m_len += 1;
+ } while (ip[m_len] == m_pos[m_len]);
+#endif
+#else
+ if __lzo_unlikely(ip[m_len] == m_pos[m_len]) {
+ do {
+ m_len += 1;
+ if __lzo_unlikely(ip + m_len >= ip_end)
+ goto m_len_done;
+ } while (ip[m_len] == m_pos[m_len]);
+ }
#endif
- )
+ }
+m_len_done:
+ m_off = pd(ip,m_pos);
+ ip += m_len;
+ ii = ip;
+ if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
{
- --ip;
- m_len = pd(ip, ii);
- assert(m_len >= 3); assert(m_len <= M2_MAX_LEN);
-
- if (m_off <= M2_MAX_OFFSET)
- {
- m_off -= 1;
+ m_off -= 1;
#if defined(LZO1X)
- *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
- *op++ = LZO_BYTE(m_off >> 3);
+ *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
+ *op++ = LZO_BYTE(m_off >> 3);
#elif defined(LZO1Y)
- *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2));
- *op++ = LZO_BYTE(m_off >> 2);
+ *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2));
+ *op++ = LZO_BYTE(m_off >> 2);
#endif
- }
- else if (m_off <= M3_MAX_OFFSET)
- {
- m_off -= 1;
+ }
+ else if (m_off <= M3_MAX_OFFSET)
+ {
+ m_off -= 1;
+ if (m_len <= M3_MAX_LEN)
*op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
- goto m3_m4_offset;
- }
else
-#if defined(LZO1X)
{
- m_off -= 0x4000;
- assert(m_off > 0); assert(m_off <= 0x7fff);
- *op++ = LZO_BYTE(M4_MARKER |
- ((m_off & 0x4000) >> 11) | (m_len - 2));
- goto m3_m4_offset;
- }
-#elif defined(LZO1Y)
- goto m4_match;
+ m_len -= M3_MAX_LEN;
+ *op++ = M3_MARKER | 0;
+ while __lzo_unlikely(m_len > 255)
+ {
+ m_len -= 255;
+#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
+ * (volatile unsigned char *) op++ = 0;
+#else
+ *op++ = 0;
#endif
+ }
+ *op++ = LZO_BYTE(m_len);
+ }
+ *op++ = LZO_BYTE(m_off << 2);
+ *op++ = LZO_BYTE(m_off >> 6);
}
else
{
- {
- const lzo_bytep end = in_end;
- const lzo_bytep m = m_pos + M2_MAX_LEN + 1;
- while (ip < end && *m == *ip)
- m++, ip++;
- m_len = pd(ip, ii);
- }
- assert(m_len > M2_MAX_LEN);
-
- if (m_off <= M3_MAX_OFFSET)
- {
- m_off -= 1;
- if (m_len <= 33)
- *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
- else
- {
- m_len -= 33;
- *op++ = M3_MARKER | 0;
- goto m3_m4_len;
- }
- }
+ m_off -= 0x4000;
+ if (m_len <= M4_MAX_LEN)
+ *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8) | (m_len - 2));
else
{
-#if defined(LZO1Y)
-m4_match:
-#endif
- m_off -= 0x4000;
- assert(m_off > 0); assert(m_off <= 0x7fff);
- if (m_len <= M4_MAX_LEN)
- *op++ = LZO_BYTE(M4_MARKER |
- ((m_off & 0x4000) >> 11) | (m_len - 2));
- else
+ m_len -= M4_MAX_LEN;
+ *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8));
+ while __lzo_unlikely(m_len > 255)
{
- m_len -= M4_MAX_LEN;
- *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
-m3_m4_len:
- while (m_len > 255)
- {
- m_len -= 255;
- *op++ = 0;
- }
- assert(m_len > 0);
- *op++ = LZO_BYTE(m_len);
+ m_len -= 255;
+#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
+ * (volatile unsigned char *) op++ = 0;
+#else
+ *op++ = 0;
+#endif
}
+ *op++ = LZO_BYTE(m_len);
}
-
-m3_m4_offset:
- *op++ = LZO_BYTE((m_off & 63) << 2);
+ *op++ = LZO_BYTE(m_off << 2);
*op++ = LZO_BYTE(m_off >> 6);
}
-
-#if 0
-match_done:
-#endif
- ii = ip;
- if __lzo_unlikely(ip >= ip_end)
- break;
+ goto next;
}
*out_len = pd(op, out);
- return pd(in_end,ii);
+ return pd(in_end,ii-ti);
}
LZO_PUBLIC(int)
@@ -3061,16 +3453,30 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
lzo_bytep out, lzo_uintp out_len,
lzo_voidp wrkmem )
{
+ const lzo_bytep ip = in;
lzo_bytep op = out;
- lzo_uint t;
+ lzo_uint l = in_len;
+ lzo_uint t = 0;
- if __lzo_unlikely(in_len <= M2_MAX_LEN + 5)
- t = in_len;
- else
+ while (l > 20)
{
- t = do_compress(in,in_len,op,out_len,wrkmem);
+ lzo_uint ll = l;
+ lzo_uintptr_t ll_end;
+#if 0 || (LZO_DETERMINISTIC)
+ ll = LZO_MIN(ll, 49152);
+#endif
+ ll_end = (lzo_uintptr_t)ip + ll;
+ if ((ll_end + ((t + ll) >> 5)) <= ll_end || (const lzo_bytep)(ll_end + ((t + ll) >> 5)) <= ip + ll)
+ break;
+#if (LZO_DETERMINISTIC)
+ lzo_memset(wrkmem, 0, ((lzo_uint)1 << D_BITS) * sizeof(lzo_dict_t));
+#endif
+ t = do_compress(ip,ll,op,out_len,t,wrkmem);
+ ip += ll;
op += *out_len;
+ l -= ll;
}
+ t += l;
if (t > 0)
{
@@ -3090,7 +3496,12 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
while (tt > 255)
{
tt -= 255;
+#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
+
+ * (volatile unsigned char *) op++ = 0;
+#else
*op++ = 0;
+#endif
}
assert(tt > 0);
*op++ = LZO_BYTE(tt);
@@ -3126,7 +3537,7 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
# define LZO_TEST_OVERRUN_OUTPUT 2
# endif
# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND)
-# define LZO_TEST_OVERRUN_LOOKBEHIND
+# define LZO_TEST_OVERRUN_LOOKBEHIND 1
# endif
#endif
@@ -3177,42 +3588,32 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
#endif
#if defined(TEST_IP)
-# define HAVE_TEST_IP
+# define HAVE_TEST_IP 1
#else
# define TEST_IP 1
#endif
#if defined(TEST_OP)
-# define HAVE_TEST_OP
+# define HAVE_TEST_OP 1
#else
# define TEST_OP 1
#endif
#if defined(NEED_IP)
-# define HAVE_NEED_IP
+# define HAVE_NEED_IP 1
#else
# define NEED_IP(x) ((void) 0)
#endif
#if defined(NEED_OP)
-# define HAVE_NEED_OP
+# define HAVE_NEED_OP 1
#else
# define NEED_OP(x) ((void) 0)
#endif
#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
-# define HAVE_ANY_IP
+# define HAVE_ANY_IP 1
#endif
#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
-# define HAVE_ANY_OP
-#endif
-
-#undef __COPY4
-#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
-
-#undef COPY4
-#if defined(LZO_UNALIGNED_OK_4)
-# define COPY4(dst,src) __COPY4(dst,src)
-#elif defined(LZO_ALIGNED_OK_4)
-# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src))
+# define HAVE_ANY_OP 1
#endif
#if defined(DO_DECOMPRESS)
@@ -3291,19 +3692,36 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
t += 15 + *ip++;
}
assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
-#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+ t += 3;
+ if (t >= 8) do
+ {
+ UA_COPY64(op,ip);
+ op += 8; ip += 8; t -= 8;
+ } while (t >= 8);
+ if (t >= 4)
+ {
+ UA_COPY32(op,ip);
+ op += 4; ip += 4; t -= 4;
+ }
+ if (t > 0)
+ {
+ *op++ = *ip++;
+ if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
+ }
+#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
#if !defined(LZO_UNALIGNED_OK_4)
if (PTR_ALIGNED2_4(op,ip))
{
#endif
- COPY4(op,ip);
+ UA_COPY32(op,ip);
op += 4; ip += 4;
if (--t > 0)
{
if (t >= 4)
{
do {
- COPY4(op,ip);
+ UA_COPY32(op,ip);
op += 4; ip += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *ip++; while (--t > 0);
@@ -3316,7 +3734,7 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
else
#endif
#endif
-#if !defined(LZO_UNALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8)
{
*op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
do *op++ = *ip++; while (--t > 0);
@@ -3437,7 +3855,7 @@ match:
}
#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
m_pos = op - 1;
- m_pos -= (* (const lzo_ushortp) ip) >> 2;
+ m_pos -= UA_GET16(ip) >> 2;
#else
m_pos = op - 1;
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
@@ -3482,7 +3900,7 @@ match:
#if defined(LZO1Z)
m_pos -= (ip[0] << 6) + (ip[1] >> 2);
#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
- m_pos -= (* (const lzo_ushortp) ip) >> 2;
+ m_pos -= UA_GET16(ip) >> 2;
#else
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
#endif
@@ -3530,7 +3948,28 @@ match:
#else
TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
-#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+ if (op - m_pos >= 8)
+ {
+ t += (3 - 1);
+ if (t >= 8) do
+ {
+ UA_COPY64(op,m_pos);
+ op += 8; m_pos += 8; t -= 8;
+ } while (t >= 8);
+ if (t >= 4)
+ {
+ UA_COPY32(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ }
+ if (t > 0)
+ {
+ *op++ = m_pos[0];
+ if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
+ }
+ }
+ else
+#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
#if !defined(LZO_UNALIGNED_OK_4)
if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
{
@@ -3539,10 +3978,10 @@ match:
if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
{
#endif
- COPY4(op,m_pos);
+ UA_COPY32(op,m_pos);
op += 4; m_pos += 4; t -= 4 - (3 - 1);
do {
- COPY4(op,m_pos);
+ UA_COPY32(op,m_pos);
op += 4; m_pos += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *m_pos++; while (--t > 0);
@@ -3610,7 +4049,7 @@ lookbehind_overrun:
#endif
-#define LZO_TEST_OVERRUN
+#define LZO_TEST_OVERRUN 1
#undef DO_DECOMPRESS
#define DO_DECOMPRESS lzo1x_decompress_safe
@@ -3624,7 +4063,7 @@ lookbehind_overrun:
# define LZO_TEST_OVERRUN_OUTPUT 2
# endif
# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND)
-# define LZO_TEST_OVERRUN_LOOKBEHIND
+# define LZO_TEST_OVERRUN_LOOKBEHIND 1
# endif
#endif
@@ -3675,42 +4114,32 @@ lookbehind_overrun:
#endif
#if defined(TEST_IP)
-# define HAVE_TEST_IP
+# define HAVE_TEST_IP 1
#else
# define TEST_IP 1
#endif
#if defined(TEST_OP)
-# define HAVE_TEST_OP
+# define HAVE_TEST_OP 1
#else
# define TEST_OP 1
#endif
#if defined(NEED_IP)
-# define HAVE_NEED_IP
+# define HAVE_NEED_IP 1
#else
# define NEED_IP(x) ((void) 0)
#endif
#if defined(NEED_OP)
-# define HAVE_NEED_OP
+# define HAVE_NEED_OP 1
#else
# define NEED_OP(x) ((void) 0)
#endif
#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
-# define HAVE_ANY_IP
+# define HAVE_ANY_IP 1
#endif
#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
-# define HAVE_ANY_OP
-#endif
-
-#undef __COPY4
-#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
-
-#undef COPY4
-#if defined(LZO_UNALIGNED_OK_4)
-# define COPY4(dst,src) __COPY4(dst,src)
-#elif defined(LZO_ALIGNED_OK_4)
-# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src))
+# define HAVE_ANY_OP 1
#endif
#if defined(DO_DECOMPRESS)
@@ -3789,19 +4218,36 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
t += 15 + *ip++;
}
assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
-#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+ t += 3;
+ if (t >= 8) do
+ {
+ UA_COPY64(op,ip);
+ op += 8; ip += 8; t -= 8;
+ } while (t >= 8);
+ if (t >= 4)
+ {
+ UA_COPY32(op,ip);
+ op += 4; ip += 4; t -= 4;
+ }
+ if (t > 0)
+ {
+ *op++ = *ip++;
+ if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
+ }
+#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
#if !defined(LZO_UNALIGNED_OK_4)
if (PTR_ALIGNED2_4(op,ip))
{
#endif
- COPY4(op,ip);
+ UA_COPY32(op,ip);
op += 4; ip += 4;
if (--t > 0)
{
if (t >= 4)
{
do {
- COPY4(op,ip);
+ UA_COPY32(op,ip);
op += 4; ip += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *ip++; while (--t > 0);
@@ -3814,7 +4260,7 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
else
#endif
#endif
-#if !defined(LZO_UNALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8)
{
*op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
do *op++ = *ip++; while (--t > 0);
@@ -3935,7 +4381,7 @@ match:
}
#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
m_pos = op - 1;
- m_pos -= (* (const lzo_ushortp) ip) >> 2;
+ m_pos -= UA_GET16(ip) >> 2;
#else
m_pos = op - 1;
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
@@ -3980,7 +4426,7 @@ match:
#if defined(LZO1Z)
m_pos -= (ip[0] << 6) + (ip[1] >> 2);
#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
- m_pos -= (* (const lzo_ushortp) ip) >> 2;
+ m_pos -= UA_GET16(ip) >> 2;
#else
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
#endif
@@ -4028,7 +4474,28 @@ match:
#else
TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
-#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+ if (op - m_pos >= 8)
+ {
+ t += (3 - 1);
+ if (t >= 8) do
+ {
+ UA_COPY64(op,m_pos);
+ op += 8; m_pos += 8; t -= 8;
+ } while (t >= 8);
+ if (t >= 4)
+ {
+ UA_COPY32(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ }
+ if (t > 0)
+ {
+ *op++ = m_pos[0];
+ if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
+ }
+ }
+ else
+#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
#if !defined(LZO_UNALIGNED_OK_4)
if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
{
@@ -4037,10 +4504,10 @@ match:
if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
{
#endif
- COPY4(op,m_pos);
+ UA_COPY32(op,m_pos);
op += 4; m_pos += 4; t -= 4 - (3 - 1);
do {
- COPY4(op,m_pos);
+ UA_COPY32(op,m_pos);
op += 4; m_pos += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *m_pos++; while (--t > 0);
diff --git a/extern/lzo/minilzo/minilzo.h b/extern/lzo/minilzo/minilzo.h
index 93916bc89b2..f2c104856e3 100644
--- a/extern/lzo/minilzo/minilzo.h
+++ b/extern/lzo/minilzo/minilzo.h
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
@@ -45,9 +48,9 @@
#ifndef __MINILZO_H
-#define __MINILZO_H
+#define __MINILZO_H 1
-#define MINILZO_VERSION 0x2030
+#define MINILZO_VERSION 0x2060
#ifdef __LZOCONF_H
# error "you cannot use both LZO and miniLZO"
@@ -103,7 +106,6 @@ lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
#define LZO_HEAP_ALLOC(var,size) \
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
-
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/extern/rangetree/CMakeLists.txt b/extern/rangetree/CMakeLists.txt
new file mode 100644
index 00000000000..ba682233381
--- /dev/null
+++ b/extern/rangetree/CMakeLists.txt
@@ -0,0 +1,31 @@
+# ***** 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 *****
+
+set(INC
+ .
+)
+
+set(SRC
+ range_tree.hh
+ range_tree_c_api.h
+
+ range_tree_c_api.cc
+)
+
+blender_add_lib(extern_rangetree "${SRC}" "${INC}" "")
+
diff --git a/extern/rangetree/README.org b/extern/rangetree/README.org
new file mode 100644
index 00000000000..46a4cedaf8f
--- /dev/null
+++ b/extern/rangetree/README.org
@@ -0,0 +1,13 @@
+* Overview
+ Basic class for storing non-overlapping scalar ranges. Underlying
+ representation is a C++ STL set for fast lookups.
+
+* License
+ GPL version 2 or later (see COPYING)
+
+* Author Note
+ This implementation is intended for storing free unique IDs in a new
+ undo system for BMesh in Blender, but could be useful elsewhere.
+
+* Website
+ https://github.com/nicholasbishop/RangeTree
diff --git a/extern/rangetree/SConscript b/extern/rangetree/SConscript
new file mode 100644
index 00000000000..787decd599e
--- /dev/null
+++ b/extern/rangetree/SConscript
@@ -0,0 +1,9 @@
+2#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('*.cc')
+
+incs = '.'
+defs = ''
+
+env.BlenderLib ('extern_rangetree', sources, Split(incs), Split(defs), libtype=['extern'], priority=[100] )
diff --git a/extern/rangetree/range_tree.hh b/extern/rangetree/range_tree.hh
new file mode 100644
index 00000000000..2a47c5a1d93
--- /dev/null
+++ b/extern/rangetree/range_tree.hh
@@ -0,0 +1,228 @@
+/* This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include <cassert>
+#include <climits>
+#include <iostream>
+#include <set>
+
+#ifndef RANGE_TREE_DEBUG_PRINT_FUNCTION
+# define RANGE_TREE_DEBUG_PRINT_FUNCTION 0
+#endif
+
+template <typename T>
+struct RangeTree {
+ struct Range {
+ Range(T min_, T max_)
+ : min(min_), max(max_), single(min_ == max_) {
+ assert(min_ <= max_);
+ }
+
+ Range(T t)
+ : min(t), max(t), single(true)
+ {}
+
+ bool operator<(const Range& v) const {
+ return max < v.min;
+ }
+
+ const T min;
+ const T max;
+ const bool single;
+ };
+
+ typedef std::set<Range> Tree;
+ typedef typename Tree::iterator TreeIter;
+ typedef typename Tree::reverse_iterator TreeIterReverse;
+ typedef typename Tree::const_iterator TreeIterConst;
+
+ /* Initialize with a single range from 'min' to 'max', inclusive. */
+ RangeTree(T min, T max) {
+ tree.insert(Range(min, max));
+ }
+
+ /* Initialize with a single range from 0 to 'max', inclusive. */
+ RangeTree(T max) {
+ tree.insert(Range(0, max));
+ }
+
+ RangeTree(const RangeTree<T>& src) {
+ tree = src.tree;
+ }
+
+ /* Remove 't' from the associated range in the tree. Precondition:
+ a range including 't' must exist in the tree. */
+ void take(T t) {
+ #if RANGE_TREE_DEBUG_PRINT_FUNCTION
+ std::cout << __func__ << "(" << t << ")\n";
+ #endif
+
+ /* Find the range that includes 't' and its neighbors */
+ TreeIter iter = tree.find(Range(t));
+ assert(iter != tree.end());
+ Range cur = *iter;
+ TreeIter prev = iter;
+ TreeIter next = iter;
+ --prev;
+ ++next;
+
+ /* Remove the original range (note that this does not
+ invalidate the prev/next iterators) */
+ tree.erase(iter);
+
+ /* Construct two new ranges that together cover the original
+ range, except for 't' */
+ if (t > cur.min)
+ tree.insert(Range(cur.min, t - 1));
+ if (t + 1 <= cur.max)
+ tree.insert(Range(t + 1, cur.max));
+ }
+
+ /* Take the first element out of the first range in the
+ tree. Precondition: tree must not be empty. */
+ T take_any() {
+ #if RANGE_TREE_DEBUG_PRINT_FUNCTION
+ std::cout << __func__ << "()\n";
+ #endif
+
+ /* Find the first element */
+ TreeIter iter = tree.begin();
+ assert(iter != tree.end());
+ T first = iter->min;
+
+ /* Take the first element */
+ take(first);
+ return first;
+ }
+
+ /* Return 't' to the tree, either expanding/merging existing
+ ranges or adding a range to cover it. Precondition: 't' cannot
+ be in an existing range. */
+ void release(T t) {
+ #if RANGE_TREE_DEBUG_PRINT_FUNCTION
+ std::cout << __func__ << "(" << t << ")\n";
+ #endif
+
+ /* TODO: these cases should be simplified/unified */
+
+ TreeIter right = tree.upper_bound(t);
+ if (right != tree.end()) {
+ TreeIter left = right;
+ if (left != tree.begin())
+ --left;
+
+ if (left == right) {
+ /* 't' lies before any existing ranges */
+ if (t + 1 == left->min) {
+ /* 't' lies directly before the first range,
+ resize and replace that range */
+ const Range r(t, left->max);
+ tree.erase(left);
+ tree.insert(r);
+ }
+ else {
+ /* There's a gap between 't' and the first range,
+ add a new range */
+ tree.insert(Range(t));
+ }
+ }
+ else if ((left->max + 1 == t) &&
+ (t + 1 == right->min)) {
+ /* 't' fills a hole. Remove left and right, and insert a
+ new range that covers both. */
+ const Range r(left->min, right->max);
+ tree.erase(left);
+ tree.erase(right);
+ tree.insert(r);
+ }
+ else if (left->max + 1 == t) {
+ /* 't' lies directly after 'left' range, resize and
+ replace that range */
+ const Range r(left->min, t);
+ tree.erase(left);
+ tree.insert(r);
+ }
+ else if (t + 1 == right->min) {
+ /* 't' lies directly before 'right' range, resize and
+ replace that range */
+ const Range r(t, right->max);
+ tree.erase(right);
+ tree.insert(r);
+ }
+ else {
+ /* There's a gap between 't' and both adjacent ranges,
+ add a new range */
+ tree.insert(Range(t));
+ }
+ }
+ else {
+ /* 't' lies after any existing ranges */
+ right = tree.end();
+ right--;
+ if (right->max + 1 == t) {
+ /* 't' lies directly after last range, resize and
+ replace that range */
+ const Range r(right->min, t);
+ tree.erase(right);
+ tree.insert(r);
+ }
+ else {
+ /* There's a gap between the last range and 't', add a
+ new range */
+ tree.insert(Range(t));
+ }
+ }
+ }
+
+ bool has(T t) const {
+ TreeIterConst iter = tree.find(Range(t));
+ return (iter != tree.end()) && (t <= iter->max);
+ }
+
+ bool has_range(T min, T max) const {
+ TreeIterConst iter = tree.find(Range(min, max));
+ return (iter != tree.end()) && (min == iter->min && max == iter->max);
+ }
+
+ bool empty() const {
+ return tree.empty();
+ }
+
+ int size() const {
+ return tree.size();
+ }
+
+ void print() const {
+ std::cout << "RangeTree:\n";
+ for (TreeIterConst iter = tree.begin(); iter != tree.end(); ++iter) {
+ const Range& r = *iter;
+ if (r.single)
+ std::cout << " [" << r.min << "]\n";
+ else
+ std::cout << " [" << r.min << ", " << r.max << "]\n";
+ }
+ if (empty())
+ std::cout << " <empty>";
+ std::cout << "\n";
+ }
+
+ unsigned int allocation_lower_bound() const {
+ return tree.size() * sizeof(Range);
+ }
+
+private:
+ Tree tree;
+};
diff --git a/extern/rangetree/range_tree_c_api.cc b/extern/rangetree/range_tree_c_api.cc
new file mode 100644
index 00000000000..56f2d90d329
--- /dev/null
+++ b/extern/rangetree/range_tree_c_api.cc
@@ -0,0 +1,86 @@
+/* This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "range_tree.hh"
+
+/* Give RangeTreeUInt a real type rather than the opaque struct type
+ defined for external use. */
+#define RANGE_TREE_C_API_INTERNAL
+typedef RangeTree<unsigned> RangeTreeUInt;
+
+#include "range_tree_c_api.h"
+
+RangeTreeUInt *range_tree_uint_alloc(unsigned min, unsigned max)
+{
+ return new RangeTreeUInt(min, max);
+}
+
+RangeTreeUInt *range_tree_uint_copy(RangeTreeUInt *src)
+{
+ return new RangeTreeUInt(*src);
+}
+
+void range_tree_uint_free(RangeTreeUInt *rt)
+{
+ delete rt;
+}
+
+void range_tree_uint_take(RangeTreeUInt *rt, unsigned v)
+{
+ rt->take(v);
+}
+
+unsigned range_tree_uint_take_any(RangeTreeUInt *rt)
+{
+ return rt->take_any();
+}
+
+void range_tree_uint_release(RangeTreeUInt *rt, unsigned v)
+{
+ rt->release(v);
+}
+
+int range_tree_uint_has(const RangeTreeUInt *rt, unsigned v)
+{
+ return rt->has(v);
+}
+
+int range_tree_uint_has_range(const RangeTreeUInt *rt,
+ unsigned vmin,
+ unsigned vmax)
+{
+ return rt->has_range(vmin, vmax);
+}
+
+int range_tree_uint_empty(const RangeTreeUInt *rt)
+{
+ return rt->empty();
+}
+
+unsigned range_tree_uint_size(const RangeTreeUInt *rt)
+{
+ return rt->size();
+}
+
+void range_tree_uint_print(const RangeTreeUInt *rt)
+{
+ rt->print();
+}
+
+unsigned int range_tree_uint_allocation_lower_bound(const RangeTreeUInt *rt)
+{
+ return rt->allocation_lower_bound();
+}
diff --git a/extern/rangetree/range_tree_c_api.h b/extern/rangetree/range_tree_c_api.h
new file mode 100644
index 00000000000..af6a7b161a8
--- /dev/null
+++ b/extern/rangetree/range_tree_c_api.h
@@ -0,0 +1,60 @@
+/* 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.
+*/
+
+#ifndef RANGE_TREE_C_API_H
+#define RANGE_TREE_C_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple C-accessible wrapper for RangeTree<unsigned> */
+
+#ifndef RANGE_TREE_C_API_INTERNAL
+typedef struct RangeTreeUInt RangeTreeUInt;
+#endif
+
+RangeTreeUInt *range_tree_uint_alloc(unsigned min, unsigned max);
+
+RangeTreeUInt *range_tree_uint_copy(RangeTreeUInt *src);
+
+void range_tree_uint_free(RangeTreeUInt *rt);
+
+void range_tree_uint_take(RangeTreeUInt *rt, unsigned v);
+
+unsigned range_tree_uint_take_any(RangeTreeUInt *rt);
+
+void range_tree_uint_release(RangeTreeUInt *rt, unsigned v);
+
+int range_tree_uint_has(const RangeTreeUInt *rt, unsigned v);
+
+int range_tree_uint_has_range(const RangeTreeUInt *rt,
+ unsigned vmin,
+ unsigned vmax);
+
+int range_tree_uint_empty(const RangeTreeUInt *rt);
+
+unsigned range_tree_uint_size(const RangeTreeUInt *rt);
+
+void range_tree_uint_print(const RangeTreeUInt *rt);
+
+unsigned int range_tree_uint_allocation_lower_bound(const RangeTreeUInt *rt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DUALCON_H__ */
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index be797c45ba1..bb8cd7aaf70 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -69,6 +69,14 @@ if(WITH_INTERNATIONAL)
add_subdirectory(locale)
endif()
+if(WITH_BULLET)
+ add_subdirectory(rigidbody)
+endif()
+
+if(WITH_COMPOSITOR)
+ add_subdirectory(opencl)
+endif()
+
# only windows needs utf16 converter
if(WIN32)
add_subdirectory(utfconv)
diff --git a/intern/SConscript b/intern/SConscript
index 5360ce4ea88..828c1adc20d 100644
--- a/intern/SConscript
+++ b/intern/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
SConscript(['audaspace/SConscript',
@@ -33,6 +59,12 @@ if env['WITH_BF_BOOLEAN']:
if env['WITH_BF_INTERNATIONAL']:
SConscript(['locale/SConscript'])
+if env['WITH_BF_BULLET']:
+ SConscript (['rigidbody/SConscript'])
+
+if env['WITH_BF_COMPOSITOR']:
+ SConscript (['opencl/SConscript'])
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'):
SConscript(['utfconv/SConscript'])
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index 1617e520ac7..ec66cffea3b 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -33,7 +33,9 @@ set(INC_SYS
set(SRC
FX/AUD_AccumulatorFactory.cpp
+ FX/AUD_BandpassCalculator.cpp
FX/AUD_BaseIIRFilterReader.cpp
+ FX/AUD_ButterworthCalculator.cpp
FX/AUD_ButterworthFactory.cpp
FX/AUD_CallbackIIRFilterReader.cpp
FX/AUD_DelayFactory.cpp
@@ -47,6 +49,7 @@ set(SRC
FX/AUD_EnvelopeFactory.cpp
FX/AUD_FaderFactory.cpp
FX/AUD_FaderReader.cpp
+ FX/AUD_HighpassCalculator.cpp
FX/AUD_HighpassFactory.cpp
FX/AUD_IIRFilterFactory.cpp
FX/AUD_IIRFilterReader.cpp
@@ -54,6 +57,7 @@ set(SRC
FX/AUD_LimiterReader.cpp
FX/AUD_LoopFactory.cpp
FX/AUD_LoopReader.cpp
+ FX/AUD_LowpassCalculator.cpp
FX/AUD_LowpassFactory.cpp
FX/AUD_PingPongFactory.cpp
FX/AUD_PitchFactory.cpp
@@ -144,7 +148,9 @@ set(SRC
intern/AUD_StreamBufferFactory.h
FX/AUD_AccumulatorFactory.h
+ FX/AUD_BandpassCalculator.h
FX/AUD_BaseIIRFilterReader.h
+ FX/AUD_ButterworthCalculator.h
FX/AUD_ButterworthFactory.h
FX/AUD_CallbackIIRFilterReader.h
FX/AUD_DelayFactory.h
@@ -159,6 +165,7 @@ set(SRC
FX/AUD_EnvelopeFactory.h
FX/AUD_FaderFactory.h
FX/AUD_FaderReader.h
+ FX/AUD_HighpassCalculator.h
FX/AUD_HighpassFactory.h
FX/AUD_IIRFilterFactory.h
FX/AUD_IIRFilterReader.h
@@ -166,6 +173,7 @@ set(SRC
FX/AUD_LimiterReader.h
FX/AUD_LoopFactory.h
FX/AUD_LoopReader.h
+ FX/AUD_LowpassCalculator.h
FX/AUD_LowpassFactory.h
FX/AUD_PingPongFactory.h
FX/AUD_PitchFactory.h
diff --git a/intern/audaspace/FX/AUD_BandpassCalculator.cpp b/intern/audaspace/FX/AUD_BandpassCalculator.cpp
new file mode 100644
index 00000000000..f5bbd63f81c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_BandpassCalculator.cpp
@@ -0,0 +1,5 @@
+#include "AUD_BandpassCalculator.h"
+
+AUD_BandpassCalculator::AUD_BandpassCalculator()
+{
+}
diff --git a/intern/audaspace/FX/AUD_BandpassCalculator.h b/intern/audaspace/FX/AUD_BandpassCalculator.h
new file mode 100644
index 00000000000..b5b3cad17ca
--- /dev/null
+++ b/intern/audaspace/FX/AUD_BandpassCalculator.h
@@ -0,0 +1,10 @@
+#ifndef AUD_BANDPASSCALCULATOR_H
+#define AUD_BANDPASSCALCULATOR_H
+
+class AUD_BandpassCalculator
+{
+public:
+ AUD_BandpassCalculator();
+};
+
+#endif // AUD_BANDPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_ButterworthCalculator.cpp b/intern/audaspace/FX/AUD_ButterworthCalculator.cpp
new file mode 100644
index 00000000000..7a3c6f71e15
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ButterworthCalculator.cpp
@@ -0,0 +1,38 @@
+#include "AUD_ButterworthCalculator.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define BWPB41 0.76536686473
+#define BWPB42 1.84775906502
+
+AUD_ButterworthCalculator::AUD_ButterworthCalculator(float frequency) :
+ m_frequency(frequency)
+{
+}
+
+void AUD_ButterworthCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float omega = 2 * tan(m_frequency * M_PI / rate);
+ float o2 = omega * omega;
+ float o4 = o2 * o2;
+ float x1 = o2 + 2.0f * (float)BWPB41 * omega + 4.0f;
+ float x2 = o2 + 2.0f * (float)BWPB42 * omega + 4.0f;
+ float y1 = o2 - 2.0f * (float)BWPB41 * omega + 4.0f;
+ float y2 = o2 - 2.0f * (float)BWPB42 * omega + 4.0f;
+ float o228 = 2.0f * o2 - 8.0f;
+ float norm = x1 * x2;
+ a.push_back(1);
+ a.push_back((x1 + x2) * o228 / norm);
+ a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
+ a.push_back((y1 + y2) * o228 / norm);
+ a.push_back(y1 * y2 / norm);
+ b.push_back(o4 / norm);
+ b.push_back(4 * o4 / norm);
+ b.push_back(6 * o4 / norm);
+ b.push_back(b[1]);
+ b.push_back(b[0]);
+}
diff --git a/intern/audaspace/FX/AUD_ButterworthCalculator.h b/intern/audaspace/FX/AUD_ButterworthCalculator.h
new file mode 100644
index 00000000000..a7ae196afda
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ButterworthCalculator.h
@@ -0,0 +1,20 @@
+#ifndef AUD_BUTTERWORTHCALCULATOR_H
+#define AUD_BUTTERWORTHCALCULATOR_H
+
+#include "AUD_IDynamicIIRFilterCalculator.h"
+
+class AUD_ButterworthCalculator : public AUD_IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ const float m_frequency;
+
+public:
+ AUD_ButterworthCalculator(float frequency);
+
+ virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+#endif // AUD_BUTTERWORTHCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
index 97d85c8122f..12c4306c2f7 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
@@ -29,44 +29,11 @@
#include "AUD_ButterworthFactory.h"
#include "AUD_IIRFilterReader.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define BWPB41 0.76536686473
-#define BWPB42 1.84775906502
+#include "AUD_ButterworthCalculator.h"
AUD_ButterworthFactory::AUD_ButterworthFactory(boost::shared_ptr<AUD_IFactory> factory,
float frequency) :
- AUD_DynamicIIRFilterFactory(factory),
- m_frequency(frequency)
+ AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_ButterworthCalculator(frequency)))
{
}
-void AUD_ButterworthFactory::recalculateCoefficients(AUD_SampleRate rate,
- std::vector<float> &b,
- std::vector<float> &a)
-{
- float omega = 2 * tan(m_frequency * M_PI / rate);
- float o2 = omega * omega;
- float o4 = o2 * o2;
- float x1 = o2 + 2.0f * (float)BWPB41 * omega + 4.0f;
- float x2 = o2 + 2.0f * (float)BWPB42 * omega + 4.0f;
- float y1 = o2 - 2.0f * (float)BWPB41 * omega + 4.0f;
- float y2 = o2 - 2.0f * (float)BWPB42 * omega + 4.0f;
- float o228 = 2.0f * o2 - 8.0f;
- float norm = x1 * x2;
- a.push_back(1);
- a.push_back((x1 + x2) * o228 / norm);
- a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
- a.push_back((y1 + y2) * o228 / norm);
- a.push_back(y1 * y2 / norm);
- b.push_back(o4 / norm);
- b.push_back(4 * o4 / norm);
- b.push_back(6 * o4 / norm);
- b.push_back(b[1]);
- b.push_back(b[0]);
-}
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
index e796f76aa29..3a86b14a7a6 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.h
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.h
@@ -38,11 +38,6 @@
class AUD_ButterworthFactory : public AUD_DynamicIIRFilterFactory
{
private:
- /**
- * The attack value in seconds.
- */
- const float m_frequency;
-
// hide copy constructor and operator=
AUD_ButterworthFactory(const AUD_ButterworthFactory&);
AUD_ButterworthFactory& operator=(const AUD_ButterworthFactory&);
@@ -54,10 +49,6 @@ public:
* \param frequency The cutoff frequency.
*/
AUD_ButterworthFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate,
- std::vector<float>& b,
- std::vector<float>& a);
};
#endif //__AUD_BUTTERWORTHFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
index e8ea4323b2e..319a78cfedd 100644
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
@@ -30,8 +30,10 @@
#include "AUD_DynamicIIRFilterReader.h"
-AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
+AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory,
+ boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator) :
+ AUD_EffectFactory(factory),
+ m_calculator(calculator)
{
}
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
index f36a37f44b4..aece7a8c2ef 100644
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
@@ -49,7 +49,8 @@ public:
* Creates a new Dynmic IIR filter factory.
* \param factory The input factory.
*/
- AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory);
+ AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory,
+ boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator);
virtual boost::shared_ptr<AUD_IReader> createReader();
};
diff --git a/intern/audaspace/FX/AUD_HighpassCalculator.cpp b/intern/audaspace/FX/AUD_HighpassCalculator.cpp
new file mode 100644
index 00000000000..573bba1c62b
--- /dev/null
+++ b/intern/audaspace/FX/AUD_HighpassCalculator.cpp
@@ -0,0 +1,27 @@
+#include "AUD_HighpassCalculator.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+AUD_HighpassCalculator::AUD_HighpassCalculator(float frequency, float Q) :
+ m_frequency(frequency),
+ m_Q(Q)
+{
+}
+
+void AUD_HighpassCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float w0 = 2.0 * M_PI * (AUD_SampleRate)m_frequency / rate;
+ float alpha = (float)(sin(w0) / (2.0 * (double)m_Q));
+ float norm = 1 + alpha;
+ float c = cos(w0);
+ a.push_back(1);
+ a.push_back(-2 * c / norm);
+ a.push_back((1 - alpha) / norm);
+ b.push_back((1 + c) / (2 * norm));
+ b.push_back((-1 - c) / norm);
+ b.push_back(b[0]);
+}
diff --git a/intern/audaspace/FX/AUD_HighpassCalculator.h b/intern/audaspace/FX/AUD_HighpassCalculator.h
new file mode 100644
index 00000000000..bad1c08f7c7
--- /dev/null
+++ b/intern/audaspace/FX/AUD_HighpassCalculator.h
@@ -0,0 +1,25 @@
+#ifndef AUD_HIGHPASSCALCULATOR_H
+#define AUD_HIGHPASSCALCULATOR_H
+
+#include "AUD_IDynamicIIRFilterCalculator.h"
+
+class AUD_HighpassCalculator : public AUD_IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The cutoff frequency.
+ */
+ const float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ const float m_Q;
+
+public:
+ AUD_HighpassCalculator(float frequency, float Q);
+
+ virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+#endif // AUD_HIGHPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
index ba5297d21ed..2456085a8a1 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp
@@ -29,33 +29,11 @@
#include "AUD_HighpassFactory.h"
#include "AUD_IIRFilterReader.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
+#include "AUD_HighpassCalculator.h"
AUD_HighpassFactory::AUD_HighpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
float Q) :
- AUD_DynamicIIRFilterFactory(factory),
- m_frequency(frequency),
- m_Q(Q)
+ AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_HighpassCalculator(frequency, Q)))
{
}
-void AUD_HighpassFactory::recalculateCoefficients(AUD_SampleRate rate,
- std::vector<float> &b,
- std::vector<float> &a)
-{
- float w0 = 2.0 * M_PI * (AUD_SampleRate)m_frequency / rate;
- float alpha = (float)(sin(w0) / (2.0 * (double)m_Q));
- float norm = 1 + alpha;
- float c = cos(w0);
- a.push_back(1);
- a.push_back(-2 * c / norm);
- a.push_back((1 - alpha) / norm);
- b.push_back((1 + c) / (2 * norm));
- b.push_back((-1 - c) / norm);
- b.push_back(b[0]);
-}
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
index ed7e9db44a4..56ced91c53c 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.h
+++ b/intern/audaspace/FX/AUD_HighpassFactory.h
@@ -38,16 +38,6 @@
class AUD_HighpassFactory : public AUD_DynamicIIRFilterFactory
{
private:
- /**
- * The cutoff frequency.
- */
- const float m_frequency;
-
- /**
- * The Q factor.
- */
- const float m_Q;
-
// hide copy constructor and operator=
AUD_HighpassFactory(const AUD_HighpassFactory&);
AUD_HighpassFactory& operator=(const AUD_HighpassFactory&);
@@ -60,8 +50,6 @@ public:
* \param Q The Q factor.
*/
AUD_HighpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
};
#endif //__AUD_HIGHPASSFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h b/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
index 77d83360255..29b87e57ad0 100644
--- a/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
+++ b/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
@@ -29,6 +29,8 @@
#ifndef AUD_IDYNAMICIIRFILTERCALCULATOR_H
#define AUD_IDYNAMICIIRFILTERCALCULATOR_H
+#include "AUD_Space.h"
+
#include <vector>
/**
diff --git a/intern/audaspace/FX/AUD_LowpassCalculator.cpp b/intern/audaspace/FX/AUD_LowpassCalculator.cpp
new file mode 100644
index 00000000000..57452f09038
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LowpassCalculator.cpp
@@ -0,0 +1,27 @@
+#include "AUD_LowpassCalculator.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+AUD_LowpassCalculator::AUD_LowpassCalculator(float frequency, float Q) :
+ m_frequency(frequency),
+ m_Q(Q)
+{
+}
+
+void AUD_LowpassCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float w0 = 2 * M_PI * m_frequency / rate;
+ float alpha = sin(w0) / (2 * m_Q);
+ float norm = 1 + alpha;
+ float c = cos(w0);
+ a.push_back(1);
+ a.push_back(-2 * c / norm);
+ a.push_back((1 - alpha) / norm);
+ b.push_back((1 - c) / (2 * norm));
+ b.push_back((1 - c) / norm);
+ b.push_back(b[0]);
+}
diff --git a/intern/audaspace/FX/AUD_LowpassCalculator.h b/intern/audaspace/FX/AUD_LowpassCalculator.h
new file mode 100644
index 00000000000..18bb11feda7
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LowpassCalculator.h
@@ -0,0 +1,25 @@
+#ifndef AUD_LOWPASSCALCULATOR_H
+#define AUD_LOWPASSCALCULATOR_H
+
+#include "AUD_IDynamicIIRFilterCalculator.h"
+
+class AUD_LowpassCalculator : public AUD_IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The cutoff frequency.
+ */
+ const float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ const float m_Q;
+
+public:
+ AUD_LowpassCalculator(float frequency, float Q);
+
+ virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+#endif // AUD_LOWPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
index e2faa241ac9..bd225998392 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp
@@ -29,33 +29,10 @@
#include "AUD_LowpassFactory.h"
#include "AUD_IIRFilterReader.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
+#include "AUD_LowpassCalculator.h"
AUD_LowpassFactory::AUD_LowpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
float Q) :
- AUD_DynamicIIRFilterFactory(factory),
- m_frequency(frequency),
- m_Q(Q)
-{
-}
-
-void AUD_LowpassFactory::recalculateCoefficients(AUD_SampleRate rate,
- std::vector<float> &b,
- std::vector<float> &a)
+ AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_LowpassCalculator(frequency, Q)))
{
- float w0 = 2 * M_PI * m_frequency / rate;
- float alpha = sin(w0) / (2 * m_Q);
- float norm = 1 + alpha;
- float c = cos(w0);
- a.push_back(1);
- a.push_back(-2 * c / norm);
- a.push_back((1 - alpha) / norm);
- b.push_back((1 - c) / (2 * norm));
- b.push_back((1 - c) / norm);
- b.push_back(b[0]);
}
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
index fdbc6e5d91d..dfd8ab35521 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.h
+++ b/intern/audaspace/FX/AUD_LowpassFactory.h
@@ -38,16 +38,6 @@
class AUD_LowpassFactory : public AUD_DynamicIIRFilterFactory
{
private:
- /**
- * The cutoff frequency.
- */
- const float m_frequency;
-
- /**
- * The Q factor.
- */
- const float m_Q;
-
// hide copy constructor and operator=
AUD_LowpassFactory(const AUD_LowpassFactory&);
AUD_LowpassFactory& operator=(const AUD_LowpassFactory&);
@@ -60,8 +50,6 @@ public:
* \param Q The Q factor.
*/
AUD_LowpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
};
#endif //__AUD_LOWPASSFACTORY_H__
diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript
index e2b6efacc96..ba549530e64 100644
--- a/intern/audaspace/SConscript
+++ b/intern/audaspace/SConscript
@@ -1,4 +1,25 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** BEGIN LGPL LICENSE BLOCK *****
+#
+# Copyright 2009 Jrg Hermann Mller
+#
+# This file is part of AudaSpace.
+#
+# AudaSpace is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# AudaSpace is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+#
+# ***** END LGPL LICENSE BLOCK *****
Import ('env')
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 0a3d0f8e85a..831e1998182 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -107,7 +107,7 @@ void AUD_FFMPEGReader::init()
m_position = 0;
m_pkgbuf_left = 0;
- if(av_find_stream_info(m_formatCtx)<0)
+ if(avformat_find_stream_info(m_formatCtx, NULL) < 0)
AUD_THROW(AUD_ERROR_FFMPEG, streaminfo_error);
// find audio stream and codec
@@ -133,7 +133,7 @@ void AUD_FFMPEGReader::init()
if(!aCodec)
AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error);
- if(avcodec_open(m_codecCtx, aCodec)<0)
+ if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0)
AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error);
// XXX this prints file information to stdout:
@@ -236,14 +236,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer) :
AUD_FFMPEGReader::~AUD_FFMPEGReader()
{
avcodec_close(m_codecCtx);
-
- if(m_aviocontext)
- {
- avformat_close_input(&m_formatCtx);
- av_free(m_aviocontext);
- }
- else
- av_close_input_file(m_formatCtx);
+ avformat_close_input(&m_formatCtx);
}
int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
index 2b34348da81..55040e4db8e 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
@@ -55,10 +55,15 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
{
static const char* formats[] = { NULL, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
- if(avformat_alloc_output_context2(&m_formatCtx, NULL, formats[format], filename.c_str()))
- AUD_THROW(AUD_ERROR_FFMPEG, context_error);
+ m_formatCtx = avformat_alloc_context();
+ if (!m_formatCtx) AUD_THROW(AUD_ERROR_FFMPEG, context_error);
- m_outputFmt = m_formatCtx->oformat;
+ strcpy(m_formatCtx->filename, filename.c_str());
+ m_outputFmt = m_formatCtx->oformat = av_guess_format(formats[format], filename.c_str(), NULL);
+ if (!m_outputFmt) {
+ avformat_free_context(m_formatCtx);
+ AUD_THROW(AUD_ERROR_FFMPEG, context_error);
+ }
switch(codec)
{
@@ -116,7 +121,7 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
if(m_outputFmt->audio_codec == CODEC_ID_NONE)
AUD_THROW(AUD_ERROR_SPECS, codec_error);
- m_stream = av_new_stream(m_formatCtx, 0);
+ m_stream = avformat_new_stream(m_formatCtx, NULL);
if(!m_stream)
AUD_THROW(AUD_ERROR_FFMPEG, stream_error);
@@ -164,7 +169,7 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
if(!codec)
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
- if(avcodec_open(m_codecCtx, codec))
+ if(avcodec_open2(m_codecCtx, codec, NULL))
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
m_output_buffer.resize(FF_MIN_BUFFER_SIZE);
diff --git a/intern/bsp/SConscript b/intern/bsp/SConscript
index d3f7cf1c6ec..92c8ee48b33 100644
--- a/intern/bsp/SConscript
+++ b/intern/bsp/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/bsp/intern/CSG_BooleanOps.cpp b/intern/bsp/intern/CSG_BooleanOps.cpp
index 4f71e7992a1..f74dfc3c253 100644
--- a/intern/bsp/intern/CSG_BooleanOps.cpp
+++ b/intern/bsp/intern/CSG_BooleanOps.cpp
@@ -88,16 +88,16 @@ CSG_PerformBooleanOperation(
BoolOpType boolType;
- switch( op_type ) {
- case e_csg_union:
- boolType = BOP_UNION;
- break;
- case e_csg_difference:
- boolType = BOP_DIFFERENCE;
- break;
- default:
- boolType = BOP_INTERSECTION;
- break;
+ switch (op_type) {
+ case e_csg_union:
+ boolType = BOP_UNION;
+ break;
+ case e_csg_difference:
+ boolType = BOP_DIFFERENCE;
+ break;
+ default:
+ boolType = BOP_INTERSECTION;
+ break;
}
BoolOpState boolOpResult;
diff --git a/intern/container/SConscript b/intern/container/SConscript
index 8edf86d7d4a..1f943157d6a 100644
--- a/intern/container/SConscript
+++ b/intern/container/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 12829f15aed..226218ae512 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -13,10 +13,12 @@ if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
endif()
if(WIN32 AND MSVC)
- set(CYCLES_OPTIMIZED_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc")
+ set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc")
+ set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /EHsc")
elseif(CMAKE_COMPILER_IS_GNUCC)
- set(CYCLES_OPTIMIZED_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mfpmath=sse")
+ set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse")
+ set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mfpmath=sse")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
endif()
@@ -44,13 +46,10 @@ endif()
if(WITH_CYCLES_OSL)
add_definitions(-DWITH_OSL)
+ add_definitions(-DOSL_STATIC_LIBRARY)
include_directories(${OSL_INCLUDES})
endif()
-if(WITH_CYCLES_CUDA_BINARIES)
- add_definitions(-DWITH_CUDA_BINARIES)
-endif()
-
add_definitions(-DWITH_OPENCL)
add_definitions(-DWITH_CUDA)
add_definitions(-DWITH_MULTI)
@@ -68,7 +67,7 @@ if(WITH_CYCLES_BLENDER)
add_subdirectory(blender)
endif()
-if(WITH_CYCLES_TEST)
+if(WITH_CYCLES_TEST OR WITH_CYCLES_NETWORK)
add_subdirectory(app)
endif()
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index a0e2650ddc6..7b4d2db6861 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
from os import path
Import('env')
@@ -10,12 +36,15 @@ sources = cycles.Glob('bvh/*.cpp') + cycles.Glob('device/*.cpp') + cycles.Glob('
sources.remove(path.join('util', 'util_view.cpp'))
sources.remove(path.join('render', 'film_response.cpp'))
-sources.remove(path.join('kernel', 'kernel_optimized.cpp'))
+sources.remove(path.join('kernel', 'kernel_sse2.cpp'))
+sources.remove(path.join('kernel', 'kernel_sse3.cpp'))
incs = []
defs = []
cxxflags = Split(env['CXXFLAGS'])
+defs.append('GLEW_STATIC')
+
defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {')
defs.append('CCL_NAMESPACE_END=}')
@@ -25,11 +54,9 @@ defs.append('WITH_CUDA')
if env['WITH_BF_CYCLES_OSL']:
defs.append('WITH_OSL')
+ defs.append('OSL_STATIC_LIBRARY')
incs.append(cycles['BF_OSL_INC'])
-if env['WITH_BF_CYCLES_CUDA_BINARIES']:
- defs.append('WITH_CUDA_BINARIES')
-
incs.extend('. bvh render device kernel kernel/osl kernel/svm util subd'.split())
incs.extend('#intern/guardedalloc #source/blender/makesrna #source/blender/makesdna'.split())
incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.split())
@@ -49,21 +76,29 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
# optimized kernel
if env['WITH_BF_RAYOPTIMIZATION']:
- optim_cxxflags = Split(env['CXXFLAGS'])
+ sse2_cxxflags = Split(env['CXXFLAGS'])
+ sse3_cxxflags = Split(env['CXXFLAGS'])
if env['OURPLATFORM'] == 'win32-vc':
- optim_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
+ sse2_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
+ sse3_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
elif env['OURPLATFORM'] == 'win64-vc':
- optim_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
+ sse2_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
+ sse3_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
else:
- optim_cxxflags.append('-ffast-math -msse -msse2 -msse3 -mfpmath=sse'.split())
+ sse2_cxxflags.append('-ffast-math -msse -msse2 -mfpmath=sse'.split())
+ sse3_cxxflags.append('-ffast-math -msse -msse2 -msse3 -mfpmath=sse'.split())
defs.append('WITH_OPTIMIZED_KERNEL')
optim_defs = defs[:]
- optim_sources = [path.join('kernel', 'kernel_optimized.cpp')]
- cycles_optim = cycles.Clone()
- cycles_optim.BlenderLib('bf_intern_cycles_optimized', optim_sources, incs, optim_defs, libtype=['intern'], priority=[10], cxx_compileflags=optim_cxxflags)
+ cycles_sse3 = cycles.Clone()
+ sse3_sources = [path.join('kernel', 'kernel_sse3.cpp')]
+ cycles_sse3.BlenderLib('bf_intern_cycles_sse3', sse3_sources, incs, optim_defs, libtype=['intern'], priority=[10], cxx_compileflags=sse3_cxxflags)
+
+ cycles_sse2 = cycles.Clone()
+ sse2_sources = [path.join('kernel', 'kernel_sse2.cpp')]
+ cycles_sse2.BlenderLib('bf_intern_cycles_sse2', sse2_sources, incs, optim_defs, libtype=['intern'], priority=[10], cxx_compileflags=sse2_cxxflags)
cycles.BlenderLib('bf_intern_cycles', sources, incs, defs, libtype=['intern'], priority=[0], cxx_compileflags=cxxflags)
diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp
index e6a13e04b48..f94a29b9451 100644
--- a/intern/cycles/app/cycles_server.cpp
+++ b/intern/cycles/app/cycles_server.cpp
@@ -23,7 +23,9 @@
#include "util_args.h"
#include "util_foreach.h"
#include "util_path.h"
+#include "util_stats.h"
#include "util_string.h"
+#include "util_task.h"
using namespace ccl;
@@ -32,29 +34,29 @@ int main(int argc, const char **argv)
path_init();
/* device types */
- string devices = "";
+ string devicelist = "";
string devicename = "cpu";
bool list = false;
vector<DeviceType>& types = Device::available_types();
foreach(DeviceType type, types) {
- if(devices != "")
- devices += ", ";
+ if(devicelist != "")
+ devicelist += ", ";
- devices += Device::string_from_type(type);
+ devicelist += Device::string_from_type(type);
}
/* parse options */
ArgParse ap;
ap.options ("Usage: cycles_server [options]",
- "--device %s", &devicename, ("Devices to use: " + devices).c_str(),
+ "--device %s", &devicename, ("Devices to use: " + devicelist).c_str(),
"--list-devices", &list, "List information about all available devices",
NULL);
if(ap.parse(argc, argv) < 0) {
- fprintf(stderr, "%s\n", ap.error_message().c_str());
+ fprintf(stderr, "%s\n", ap.geterror().c_str());
ap.usage();
exit(EXIT_FAILURE);
}
@@ -84,13 +86,18 @@ int main(int argc, const char **argv)
}
}
+ TaskScheduler::init();
+
while(1) {
- Device *device = Device::create(device_info);
- printf("Cycles Server with device: %s\n", device->description().c_str());
+ Stats stats;
+ Device *device = Device::create(device_info, stats);
+ printf("Cycles Server with device: %s\n", device->info.description.c_str());
device->server_run();
delete device;
}
+ TaskScheduler::exit();
+
return 0;
}
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index 5de9d71b8cc..40fbb7af556 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -233,16 +233,16 @@ static void xml_read_film(const XMLReadState& state, pugi::xml_node node)
float aspect = (float)cam->width/(float)cam->height;
if(cam->width >= cam->height) {
- cam->left = -aspect;
- cam->right = aspect;
- cam->bottom = -1.0f;
- cam->top = 1.0f;
+ cam->viewplane.left = -aspect;
+ cam->viewplane.right = aspect;
+ cam->viewplane.bottom = -1.0f;
+ cam->viewplane.top = 1.0f;
}
else {
- cam->left = -1.0f;
- cam->right = 1.0f;
- cam->bottom = -1.0f/aspect;
- cam->top = 1.0f/aspect;
+ cam->viewplane.left = -1.0f;
+ cam->viewplane.right = 1.0f;
+ cam->viewplane.bottom = -1.0f/aspect;
+ cam->viewplane.top = 1.0f/aspect;
}
cam->need_update = true;
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 292c37d6b61..710e8ba6a90 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SRC
blender_mesh.cpp
blender_object.cpp
blender_particles.cpp
+ blender_curves.cpp
blender_python.cpp
blender_session.cpp
blender_shader.cpp
@@ -38,7 +39,6 @@ set(SRC
set(ADDON_FILES
addon/__init__.py
addon/engine.py
- addon/enums.py
addon/osl.py
addon/presets.py
addon/properties.py
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 0fad2ac5618..526c5658b93 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Cycles Render Engine",
"author": "",
- "blender": (2, 6, 3),
+ "blender": (2, 66, 0),
"location": "Info header, render engine menu",
"description": "Cycles Render Engine integration",
"warning": "",
@@ -31,16 +31,17 @@ bl_info = {
"category": "Render"}
import bpy
-from . import ui, properties, engine, presets
+
+from . import engine
class CyclesRender(bpy.types.RenderEngine):
bl_idname = 'CYCLES'
bl_label = "Cycles Render"
bl_use_shading_nodes = True
+ bl_use_preview = True
def __init__(self):
- engine.init()
self.session = None
def __del__(self):
@@ -48,28 +49,28 @@ class CyclesRender(bpy.types.RenderEngine):
# final render
def update(self, data, scene):
- if not self.session:
- engine.create(self, data, scene)
+ if self.is_preview:
+ if not self.session:
+ use_osl = bpy.context.scene.cycles.shading_system
+
+ engine.create(self, data, scene,
+ None, None, None, use_osl)
else:
- engine.reset(self, data, scene)
+ if not self.session:
+ engine.create(self, data, scene)
+ else:
+ engine.reset(self, data, scene)
engine.update(self, data, scene)
def render(self, scene):
engine.render(self)
- # preview render
- # def preview_update(self, context, id):
- # pass
- #
- # def preview_render(self):
- # pass
-
# viewport render
def view_update(self, context):
if not self.session:
engine.create(self, context.blend_data, context.scene,
- context.region, context.space_data, context.region_data)
+ context.region, context.space_data, context.region_data)
engine.update(self, context.blend_data, context.scene)
def view_draw(self, context):
@@ -84,6 +85,12 @@ class CyclesRender(bpy.types.RenderEngine):
def register():
+ from . import ui
+ from . import properties
+ from . import presets
+
+ engine.init()
+
properties.register()
ui.register()
presets.register()
@@ -91,8 +98,11 @@ def register():
def unregister():
+ from . import ui
+ from . import properties
+ from . import presets
+
ui.unregister()
properties.unregister()
presets.unregister()
bpy.utils.unregister_module(__name__)
-
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index ca5cbee9325..8958ca3e42e 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -18,10 +18,9 @@
# <pep8 compliant>
-import bpy
-
def init():
+ import bpy
import _cycles
import os.path
@@ -31,7 +30,8 @@ def init():
_cycles.init(path, user_path)
-def create(engine, data, scene, region=0, v3d=0, rv3d=0):
+def create(engine, data, scene, region=0, v3d=0, rv3d=0, preview_osl=False):
+ import bpy
import _cycles
data = data.as_pointer()
@@ -44,7 +44,7 @@ def create(engine, data, scene, region=0, v3d=0, rv3d=0):
if rv3d:
rv3d = rv3d.as_pointer()
- engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d)
+ engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d, preview_osl)
def free(engine):
@@ -90,4 +90,3 @@ def available_devices():
def with_osl():
import _cycles
return _cycles.with_osl
-
diff --git a/intern/cycles/blender/addon/enums.py b/intern/cycles/blender/addon/enums.py
deleted file mode 100644
index 82b48973ca1..00000000000
--- a/intern/cycles/blender/addon/enums.py
+++ /dev/null
@@ -1,63 +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.
-#
-
-# <pep8 compliant>
-
-from . import engine
-
-devices = (
- ('CPU', "CPU", "Use CPU for rendering"),
- ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"))
-
-feature_set = (
- ('SUPPORTED', "Supported", "Only use finished and supported features"),
- ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"),
- )
-
-shading_systems = (
- ('GPU_COMPATIBLE', "GPU Compatible", "Restricted shading system compatible with GPU rendering"),
- ('OSL', "Open Shading Language", "Open Shading Language shading system that only runs on the CPU"),
- )
-
-displacement_methods = (
- ('BUMP', "Bump", "Bump mapping to simulate the appearance of displacement"),
- ('TRUE', "True", "Use true displacement only, requires fine subdivision"),
- ('BOTH', "Both", "Combination of displacement and bump mapping"),
- )
-
-bvh_types = (
- ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
- ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
- )
-
-filter_types = (
- ('BOX', "Box", "Box filter"),
- ('GAUSSIAN', "Gaussian", "Gaussian filter"),
- )
-
-aperture_types = (
- ('RADIUS', "Radius", "Directly change the size of the aperture"),
- ('FSTOP', "F/stop", "Change the size of the aperture by f/stops"),
- )
-
-panorama_types = (
- ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
- ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
- ('FISHEYE_EQUISOLID', "Fisheye Equisolid",
- "Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
- )
diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py
index 79ce3df20c3..0a67edac1e3 100644
--- a/intern/cycles/blender/addon/osl.py
+++ b/intern/cycles/blender/addon/osl.py
@@ -18,10 +18,13 @@
# <pep8 compliant>
-import bpy, _cycles, os, tempfile
+import bpy
+import _cycles
+
-# compile .osl file with given filepath to temporary .oso file
def osl_compile(input_path, report):
+ """compile .osl file with given filepath to temporary .oso file"""
+ import tempfile
output_file = tempfile.NamedTemporaryFile(mode='w', suffix=".oso", delete=False)
output_path = output_file.name
output_file.close()
@@ -33,9 +36,12 @@ def osl_compile(input_path, report):
return ok, output_path
-# compile and update shader script node
+
def update_script_node(node, report):
- import os, shutil
+ """compile and update shader script node"""
+ import os
+ import shutil
+ import tempfile
if node.mode == 'EXTERNAL':
# compile external script file
@@ -103,7 +109,7 @@ def update_script_node(node, report):
report({'ERROR'}, "Can't read OSO bytecode to store in node at %r" % oso_path)
ok = False
-
+
else:
report({'WARNING'}, "No text or file specified in node, nothing to compile")
return
@@ -125,4 +131,3 @@ def update_script_node(node, report):
pass
return ok
-
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 0b8ca6e0fbe..65f245fba69 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -25,9 +25,87 @@ from bpy.props import (BoolProperty,
IntProperty,
PointerProperty)
-import math
-
-from . import enums
+# enums
+
+enum_devices = (
+ ('CPU', "CPU", "Use CPU for rendering"),
+ ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"))
+
+enum_feature_set = (
+ ('SUPPORTED', "Supported", "Only use finished and supported features"),
+ ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"),
+ )
+
+enum_displacement_methods = (
+ ('BUMP', "Bump", "Bump mapping to simulate the appearance of displacement"),
+ ('TRUE', "True", "Use true displacement only, requires fine subdivision"),
+ ('BOTH', "Both", "Combination of displacement and bump mapping"),
+ )
+
+enum_bvh_types = (
+ ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
+ ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
+ )
+
+enum_filter_types = (
+ ('BOX', "Box", "Box filter"),
+ ('GAUSSIAN', "Gaussian", "Gaussian filter"),
+ )
+
+enum_aperture_types = (
+ ('RADIUS', "Radius", "Directly change the size of the aperture"),
+ ('FSTOP', "F/stop", "Change the size of the aperture by f/stops"),
+ )
+
+enum_panorama_types = (
+ ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
+ ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
+ ('FISHEYE_EQUISOLID', "Fisheye Equisolid",
+ "Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
+ )
+
+enum_curve_presets = (
+ ('CUSTOM', "Custom", "Set general parameters"),
+ ('FAST_PLANES', "Fast Planes", "Use camera facing triangles (fast but memory intensive)"),
+ ('TANGENT_SHADING', "Tangent Normal", "Use planar line segments and tangent normals"),
+ ('TRUE_NORMAL', "True Normal", "Use true normals with line segments(good for thin strands)"),
+ ('ACCURATE_PRESET', "Accurate", "Use best line segment settings (suitable for glass materials)"),
+ ('SMOOTH_CURVES', "Smooth Curves", "Use smooth cardinal curves (slowest)"),
+ )
+
+enum_curve_primitives = (
+ ('TRIANGLES', "Triangles", "Create triangle geometry around strands"),
+ ('LINE_SEGMENTS', "Line Segments", "Use line segment primitives"),
+ ('CURVE_SEGMENTS', "Curve Segments", "Use segmented cardinal curve primitives"),
+ ('CURVE_RIBBONS', "Curve Ribbons", "Use smooth cardinal curve ribbon primitives"),
+ )
+
+enum_triangle_curves = (
+ ('CAMERA_TRIANGLES', "Planes", "Create individual triangles forming planes that face camera"),
+ ('RIBBON_TRIANGLES', "Ribbons", "Create individual triangles forming ribbon"),
+ ('TESSELLATED_TRIANGLES', "Tessellated", "Create mesh surrounding each strand"),
+ )
+
+enum_line_curves = (
+ ('ACCURATE', "Accurate", "Always take into consideration strand width for intersections"),
+ ('QT_CORRECTED', "Corrected", "Ignore width for initial intersection and correct later"),
+ ('ENDCORRECTED', "Correct found", "Ignore width for all intersections and only correct closest"),
+ ('QT_UNCORRECTED', "Uncorrected", "Calculate intersections without considering width"),
+ )
+
+enum_curves_interpolation = (
+ ('LINEAR', "Linear interpolation", "Use Linear interpolation between segments"),
+ ('CARDINAL', "Cardinal interpolation", "Use cardinal interpolation between segments"),
+ ('BSPLINE', "B-spline interpolation", "Use b-spline interpolation between segments"),
+ )
+
+enum_tile_order = (
+ ('CENTER', "Center", "Render from center to the edges"),
+ ('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"),
+ ('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"),
+ ('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"),
+ ('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"),
+ )
class CyclesRenderSettings(bpy.types.PropertyGroup):
@@ -41,20 +119,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
cls.device = EnumProperty(
name="Device",
description="Device to use for rendering",
- items=enums.devices,
+ items=enum_devices,
default='CPU',
)
cls.feature_set = EnumProperty(
name="Feature Set",
description="Feature set to use for rendering",
- items=enums.feature_set,
+ items=enum_feature_set,
default='SUPPORTED',
)
- cls.shading_system = EnumProperty(
- name="Shading System",
- description="Shading system to use for rendering",
- items=enums.shading_systems,
- default='GPU_COMPATIBLE',
+ cls.shading_system = BoolProperty(
+ name="Open Shading Language",
+ description="Use Open Shading Language (CPU rendering only)",
)
cls.progressive = BoolProperty(
@@ -205,14 +281,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
)
cls.film_transparent = BoolProperty(
name="Transparent",
- description="World background is transparent",
+ description="World background is transparent with premultiplied alpha",
default=False,
)
cls.filter_type = EnumProperty(
name="Filter Type",
description="Pixel filter type",
- items=enums.filter_types,
+ items=enum_filter_types,
default='GAUSSIAN',
)
cls.filter_width = FloatProperty(
@@ -275,7 +351,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
cls.debug_bvh_type = EnumProperty(
name="Viewport BVH Type",
description="Choose between faster updates, or faster render",
- items=enums.bvh_types,
+ items=enum_bvh_types,
default='DYNAMIC_BVH',
)
cls.debug_use_spatial_splits = BoolProperty(
@@ -288,6 +364,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Cache last built BVH to disk for faster re-render if no geometry changed",
default=False,
)
+ cls.tile_order = EnumProperty(
+ name="Tile Order",
+ description="Tile order for rendering",
+ items=enum_tile_order,
+ default='CENTER',
+ )
cls.use_progressive_refine = BoolProperty(
name="Progressive Refine",
description="Instead of rendering each tile until it is finished, "
@@ -305,6 +387,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
class CyclesCameraSettings(bpy.types.PropertyGroup):
@classmethod
def register(cls):
+ import math
+
bpy.types.Camera.cycles = PointerProperty(
name="Cycles Camera Settings",
description="Cycles camera settings",
@@ -314,7 +398,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
cls.aperture_type = EnumProperty(
name="Aperture Type",
description="Use F/stop number or aperture radius",
- items=enums.aperture_types,
+ items=enum_aperture_types,
default='RADIUS',
)
cls.aperture_fstop = FloatProperty(
@@ -349,7 +433,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
cls.panorama_type = EnumProperty(
name="Panorama Type",
description="Distortion to use for the calculation",
- items=enums.panorama_types,
+ items=enum_panorama_types,
default='FISHEYE_EQUISOLID',
)
cls.fisheye_fov = FloatProperty(
@@ -380,8 +464,8 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
type=cls,
)
cls.sample_as_light = BoolProperty(
- name="Sample as Lamp",
- description="Use direct light sampling for this material, "
+ name="Multiple Importance Sample",
+ description="Use multiple importance sampling for this material, "
"disabling may reduce overall noise for large "
"objects that emit little light compared to other light sources",
default=True,
@@ -417,6 +501,12 @@ class CyclesLampSettings(bpy.types.PropertyGroup):
min=1, max=10000,
default=1,
)
+ cls.use_multiple_importance_sampling = BoolProperty(
+ name="Multiple Importance Sample",
+ description="Use multiple importance sampling for the lamp, "
+ "reduces noise for area lamps and sharp glossy materials",
+ default=False,
+ )
@classmethod
def unregister(cls):
@@ -432,8 +522,8 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
type=cls,
)
cls.sample_as_light = BoolProperty(
- name="Sample as Lamp",
- description="Use direct light sampling for the environment, "
+ name="Multiple Importance Sample",
+ description="Use multiple importance sampling for the environment, "
"enabling for non-solid colors is recommended",
default=False,
)
@@ -518,7 +608,7 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
cls.displacement_method = EnumProperty(
name="Displacement Method",
description="Method to use for the displacement",
- items=enums.displacement_methods,
+ items=enum_displacement_methods,
default='BUMP',
)
cls.use_subdivision = BoolProperty(
@@ -540,6 +630,162 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
del bpy.types.MetaBall.cycles
+class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
+ @classmethod
+ def register(cls):
+ bpy.types.Scene.cycles_curves = PointerProperty(
+ name="Cycles Hair Rendering Settings",
+ description="Cycles hair rendering settings",
+ type=cls,
+ )
+ cls.preset = EnumProperty(
+ name="Mode",
+ description="Hair rendering mode",
+ items=enum_curve_presets,
+ default='TRUE_NORMAL',
+ )
+ cls.primitive = EnumProperty(
+ name="Primitive",
+ description="Type of primitive used for hair rendering",
+ items=enum_curve_primitives,
+ default='LINE_SEGMENTS',
+ )
+ cls.triangle_method = EnumProperty(
+ name="Mesh Geometry",
+ description="Method for creating triangle geometry",
+ items=enum_triangle_curves,
+ default='CAMERA_TRIANGLES',
+ )
+ cls.line_method = EnumProperty(
+ name="Intersection Method",
+ description="Method for line segment intersection",
+ items=enum_line_curves,
+ default='ACCURATE',
+ )
+ cls.interpolation = EnumProperty(
+ name="Interpolation",
+ description="Interpolation method",
+ items=enum_curves_interpolation,
+ default='BSPLINE',
+ )
+ cls.use_backfacing = BoolProperty(
+ name="Check back-faces",
+ description="Test back-faces of strands",
+ default=False,
+ )
+ cls.use_encasing = BoolProperty(
+ name="Exclude encasing",
+ description="Ignore strands encasing a ray's initial location",
+ default=True,
+ )
+ cls.use_tangent_normal_geometry = BoolProperty(
+ name="Tangent normal geometry",
+ description="Use the tangent normal for actual normal",
+ default=False,
+ )
+ cls.use_tangent_normal = BoolProperty(
+ name="Tangent normal default",
+ description="Use the tangent normal for all normals",
+ default=False,
+ )
+ cls.use_tangent_normal_correction = BoolProperty(
+ name="Strand slope correction",
+ description="Correct the tangent normal for the strand's slope",
+ default=False,
+ )
+ cls.use_parents = BoolProperty(
+ name="Use parent strands",
+ description="Use parents with children",
+ default=False,
+ )
+ cls.use_smooth = BoolProperty(
+ name="Smooth Strands",
+ description="Use vertex normals",
+ default=True,
+ )
+ cls.use_joined = BoolProperty(
+ name="Join",
+ description="Fill gaps between segments (requires more memory)",
+ default=False,
+ )
+ cls.use_curves = BoolProperty(
+ name="Use Cycles Hair Rendering",
+ description="Activate Cycles hair rendering for particle system",
+ default=True,
+ )
+ cls.segments = IntProperty(
+ name="Segments",
+ description="Number of segments between path keys (note that this combines with the 'draw step' value)",
+ min=1, max=64,
+ default=1,
+ )
+ cls.resolution = IntProperty(
+ name="Resolution",
+ description="Resolution of generated mesh",
+ min=3, max=64,
+ default=3,
+ )
+ cls.normalmix = FloatProperty(
+ name="Normal mix",
+ description="Scale factor for tangent normal removal (zero gives ray normal)",
+ min=0, max=2.0,
+ default=1,
+ )
+ cls.encasing_ratio = FloatProperty(
+ name="Encasing ratio",
+ description="Scale factor for encasing strand width",
+ min=0, max=100.0,
+ default=1.01,
+ )
+ cls.subdivisions = IntProperty(
+ name="Subdivisions",
+ description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
+ min=0, max=24,
+ default=3,
+ )
+
+ @classmethod
+ def unregister(cls):
+ del bpy.types.Scene.cycles_curves
+
+
+class CyclesCurveSettings(bpy.types.PropertyGroup):
+ @classmethod
+ def register(cls):
+ bpy.types.ParticleSettings.cycles = PointerProperty(
+ name="Cycles Hair Settings",
+ description="Cycles hair settings",
+ type=cls,
+ )
+ cls.root_width = FloatProperty(
+ name="Root Size Multiplier",
+ description="Multiplier of particle size for the strand's width at root",
+ min=0.0, max=1000.0,
+ default=1.0,
+ )
+ cls.tip_width = FloatProperty(
+ name="Tip Size Multiplier",
+ description="Multiplier of particle size for the strand's width at tip",
+ min=0.0, max=1000.0,
+ default=0.0,
+ )
+ cls.shape = FloatProperty(
+ name="Strand Shape",
+ description="Strand shape parameter",
+ min=-1.0, max=1.0,
+ default=0.0,
+ )
+ cls.use_closetip = BoolProperty(
+ name="Close tip",
+ description="Set tip radius to zero",
+ default=True,
+ )
+
+ @classmethod
+ def unregister(cls):
+ del bpy.types.ParticleSettings.cycles
+
+
def register():
bpy.utils.register_class(CyclesRenderSettings)
bpy.utils.register_class(CyclesCameraSettings)
@@ -548,6 +794,8 @@ def register():
bpy.utils.register_class(CyclesWorldSettings)
bpy.utils.register_class(CyclesVisibilitySettings)
bpy.utils.register_class(CyclesMeshSettings)
+ bpy.utils.register_class(CyclesCurveRenderSettings)
+ bpy.utils.register_class(CyclesCurveSettings)
def unregister():
@@ -558,3 +806,5 @@ def unregister():
bpy.utils.unregister_class(CyclesWorldSettings)
bpy.utils.unregister_class(CyclesMeshSettings)
bpy.utils.unregister_class(CyclesVisibilitySettings)
+ bpy.utils.unregister_class(CyclesCurveRenderSettings)
+ bpy.utils.unregister_class(CyclesCurveSettings)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index ba931469e8a..9d2555d3003 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -22,8 +22,6 @@ import bpy
from bpy.types import Panel, Menu
-from . import enums, engine
-
class CYCLES_MT_integrator_presets(Menu):
bl_label = "Integrator Presets"
@@ -170,6 +168,19 @@ class CyclesRender_PT_film(CyclesButtonsPanel, Panel):
if cscene.filter_type != 'BOX':
sub.prop(cscene, "filter_width", text="Width")
+ layout.separator()
+
+ rd = scene.render
+ col = layout.column()
+
+ split = col.split(percentage=0.40)
+ split.prop(rd, "use_antialiasing", "OpenGL AA")
+ row = split.row()
+ row.active = rd.use_antialiasing
+ row.prop(rd, "antialiasing_samples", expand=True)
+
+ col.prop(rd, "alpha_mode", text="OpenGL Alpha")
+
class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
bl_label = "Performance"
@@ -193,7 +204,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
sub.prop(rd, "threads")
sub = col.column(align=True)
- sub.label(text="Tile Size:")
+ sub.label(text="Tiles:")
+ sub.prop(cscene, "tile_order", text="")
sub.prop(rd, "tile_x", text="X")
sub.prop(rd, "tile_y", text="Y")
@@ -233,7 +245,7 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
rd = scene.render
row = layout.row()
- row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
+ row.template_list("RENDER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
col = row.column(align=True)
col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
@@ -379,7 +391,7 @@ class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
if ob:
row = layout.row()
- row.template_list(ob, "material_slots", ob, "active_material_index", rows=2)
+ row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=2)
col = row.column(align=True)
col.operator("object.material_slot_add", icon='ZOOMIN', text="")
@@ -523,6 +535,19 @@ def panel_node_draw(layout, id_data, output_type, input_name):
return True
+class CyclesLamp_PT_preview(CyclesButtonsPanel, Panel):
+ bl_label = "Preview"
+ bl_context = "data"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.lamp and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ self.layout.template_preview(context.lamp)
+
+
class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
bl_label = "Lamp"
bl_context = "data"
@@ -562,6 +587,8 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
col = split.column()
col.prop(clamp, "cast_shadow")
+ layout.prop(clamp, "use_multiple_importance_sampling")
+
if lamp.type == 'HEMI':
layout.label(text="Not supported, interpreted as sun lamp.")
@@ -607,6 +634,19 @@ class CyclesLamp_PT_spot(CyclesButtonsPanel, Panel):
col.prop(lamp, "show_cone")
+class CyclesWorld_PT_preview(CyclesButtonsPanel, Panel):
+ bl_label = "Preview"
+ bl_context = "world"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.world and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ self.layout.template_preview(context.world)
+
+
class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
bl_label = "Surface"
bl_context = "world"
@@ -693,6 +733,19 @@ class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
sub.prop(cworld, "samples")
+class CyclesMaterial_PT_preview(CyclesButtonsPanel, Panel):
+ bl_label = "Preview"
+ bl_context = "material"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.material and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ self.layout.template_preview(context.material)
+
+
class CyclesMaterial_PT_surface(CyclesButtonsPanel, Panel):
bl_label = "Surface"
bl_context = "material"
@@ -769,9 +822,10 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
col.prop(mat, "diffuse_color", text="Viewport Color")
col = split.column()
- col.prop(cmat, "sample_as_light")
col.prop(mat, "pass_index")
+ layout.prop(cmat, "sample_as_light")
+
class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
bl_label = ""
@@ -809,24 +863,8 @@ class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
split = layout.split(percentage=0.2)
split.label(text="Type:")
split.prop(tex, "type", text="")
-
-
-class CyclesTexture_PT_nodes(CyclesButtonsPanel, Panel):
- bl_label = "Nodes"
- bl_context = "texture"
-
- @classmethod
- def poll(cls, context):
- tex = context.texture
- return (tex and tex.use_nodes) and CyclesButtonsPanel.poll(context)
-
- def draw(self, context):
- layout = self.layout
-
- tex = context.texture
- panel_node_draw(layout, tex, 'OUTPUT_TEXTURE', 'Color')
-
-
+
+
class CyclesTexture_PT_node(CyclesButtonsPanel, Panel):
bl_label = "Node"
bl_context = "texture"
@@ -850,14 +888,12 @@ class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- tex = context.texture
node = context.texture_node
- return (node or (tex and tex.use_nodes)) and CyclesButtonsPanel.poll(context)
+ return node and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
-
- # tex = context.texture
+
node = context.texture_node
mapping = node.texture_mapping
@@ -883,15 +919,13 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- # tex = context.texture
# node = context.texture_node
return False
- #return (node or (tex and tex.use_nodes)) and CyclesButtonsPanel.poll(context)
+ #return node and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
-
- # tex = context.texture
+
node = context.texture_node
mapping = node.color_mapping
@@ -917,6 +951,132 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel):
layout.template_color_ramp(mapping, "color_ramp", expand=True)
+class CyclesParticle_PT_textures(CyclesButtonsPanel, Panel):
+ bl_label = "Textures"
+ bl_context = "particle"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ psys = context.particle_system
+ return psys and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = psys.settings
+
+ row = layout.row()
+ row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2)
+
+ col = row.column(align=True)
+ col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
+ col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
+ col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="")
+
+ if not part.active_texture:
+ layout.template_ID(part, "active_texture", new="texture.new")
+ else:
+ slot = part.texture_slots[part.active_texture_index]
+ layout.template_ID(slot, "texture", new="texture.new")
+
+
+class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
+ bl_label = "Cycles Hair Rendering"
+ bl_context = "particle"
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ cscene = scene.cycles
+ psys = context.particle_system
+ device_type = context.user_preferences.system.compute_device_type
+ experimental = ((cscene.feature_set == 'EXPERIMENTAL') and (cscene.device == 'CPU' or device_type == 'NONE'))
+ return CyclesButtonsPanel.poll(context) and experimental and psys
+
+ def draw_header(self, context):
+ ccscene = context.scene.cycles_curves
+ self.layout.prop(ccscene, "use_curves", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ ccscene = scene.cycles_curves
+
+ layout.active = ccscene.use_curves
+
+ layout.prop(ccscene, "preset", text="Mode")
+
+ if ccscene.preset == 'CUSTOM':
+ layout.prop(ccscene, "primitive", text="Primitive")
+
+ if ccscene.primitive == 'TRIANGLES':
+ layout.prop(ccscene, "triangle_method", text="Method")
+ if ccscene.triangle_method == 'TESSELLATED_TRIANGLES':
+ layout.prop(ccscene, "resolution", text="Resolution")
+ layout.prop(ccscene, "use_smooth", text="Smooth")
+ elif ccscene.primitive == 'LINE_SEGMENTS':
+ layout.prop(ccscene, "use_backfacing", text="Check back-faces")
+
+ row = layout.row()
+ row.prop(ccscene, "use_encasing", text="Exclude encasing")
+ sub = row.row()
+ sub.active = ccscene.use_encasing
+ sub.prop(ccscene, "encasing_ratio", text="Ratio for encasing")
+
+ layout.prop(ccscene, "line_method", text="Method")
+ layout.prop(ccscene, "use_tangent_normal", text="Use tangent normal as default")
+ layout.prop(ccscene, "use_tangent_normal_geometry", text="Use tangent normal geometry")
+ layout.prop(ccscene, "use_tangent_normal_correction", text="Correct tangent normal for slope")
+ layout.prop(ccscene, "interpolation", text="Interpolation")
+
+ row = layout.row()
+ row.prop(ccscene, "segments", text="Segments")
+ row.prop(ccscene, "normalmix", text="Ray Mix")
+ elif ccscene.primitive in {'CURVE_SEGMENTS', 'CURVE_RIBBONS'}:
+ layout.prop(ccscene, "subdivisions", text="Curve subdivisions")
+ layout.prop(ccscene, "use_backfacing", text="Check back-faces")
+
+ layout.prop(ccscene, "interpolation", text="Interpolation")
+ row = layout.row()
+ row.prop(ccscene, "segments", text="Segments")
+
+ row = layout.row()
+ row.prop(ccscene, "use_parents", text="Include parents")
+
+
+class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
+ bl_label = "Cycles Hair Settings"
+ bl_context = "particle"
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ cscene = scene.cycles
+ ccscene = scene.cycles_curves
+ use_curves = ccscene.use_curves and context.particle_system
+ device_type = context.user_preferences.system.compute_device_type
+ experimental = cscene.feature_set == 'EXPERIMENTAL' and (cscene.device == 'CPU' or device_type == 'NONE')
+ return CyclesButtonsPanel.poll(context) and experimental and use_curves
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_settings
+ cpsys = psys.cycles
+
+ row = layout.row()
+ row.prop(cpsys, "shape", text="Shape")
+ row.prop(cpsys, "use_closetip", text="Close tip")
+
+ layout.label(text="Width multiplier:")
+ row = layout.row()
+ row.prop(cpsys, "root_width", text="Root")
+ row.prop(cpsys, "tip_width", text="Tip")
+
+
class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
bl_label = "Simplify"
bl_context = "scene"
@@ -933,13 +1093,9 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
layout.active = rd.use_simplify
- split = layout.split()
-
- col = split.column()
- col.prop(rd, "simplify_subdivision", text="Subdivision")
-
- col = split.column()
- col.prop(rd, "simplify_child_particles", text="Child Particles")
+ row = layout.row()
+ row.prop(rd, "simplify_subdivision", text="Subdivision")
+ row.prop(rd, "simplify_child_particles", text="Child Particles")
def draw_device(self, context):
@@ -947,6 +1103,7 @@ def draw_device(self, context):
layout = self.layout
if scene.render.engine == 'CYCLES':
+ from . import engine
cscene = scene.cycles
layout.prop(cscene, "feature_set")
@@ -976,73 +1133,89 @@ def draw_pause(self, context):
def get_panels():
+ types = bpy.types
return (
- bpy.types.RENDER_PT_render,
- bpy.types.RENDER_PT_output,
- bpy.types.RENDER_PT_encoding,
- bpy.types.RENDER_PT_dimensions,
- bpy.types.RENDER_PT_stamp,
- bpy.types.SCENE_PT_scene,
- bpy.types.SCENE_PT_audio,
- bpy.types.SCENE_PT_unit,
- bpy.types.SCENE_PT_keying_sets,
- bpy.types.SCENE_PT_keying_set_paths,
- bpy.types.SCENE_PT_physics,
- bpy.types.WORLD_PT_context_world,
- bpy.types.DATA_PT_context_mesh,
- bpy.types.DATA_PT_context_camera,
- bpy.types.DATA_PT_context_lamp,
- bpy.types.DATA_PT_context_speaker,
- bpy.types.DATA_PT_texture_space,
- bpy.types.DATA_PT_curve_texture_space,
- bpy.types.DATA_PT_mball_texture_space,
- bpy.types.DATA_PT_vertex_groups,
- bpy.types.DATA_PT_shape_keys,
- bpy.types.DATA_PT_uv_texture,
- bpy.types.DATA_PT_vertex_colors,
- bpy.types.DATA_PT_camera,
- bpy.types.DATA_PT_camera_display,
- bpy.types.DATA_PT_lens,
- bpy.types.DATA_PT_speaker,
- bpy.types.DATA_PT_distance,
- bpy.types.DATA_PT_cone,
- bpy.types.DATA_PT_customdata,
- bpy.types.DATA_PT_custom_props_mesh,
- bpy.types.DATA_PT_custom_props_camera,
- bpy.types.DATA_PT_custom_props_lamp,
- bpy.types.DATA_PT_custom_props_speaker,
- bpy.types.TEXTURE_PT_clouds,
- bpy.types.TEXTURE_PT_wood,
- bpy.types.TEXTURE_PT_marble,
- bpy.types.TEXTURE_PT_magic,
- bpy.types.TEXTURE_PT_blend,
- bpy.types.TEXTURE_PT_stucci,
- bpy.types.TEXTURE_PT_image,
- bpy.types.TEXTURE_PT_image_sampling,
- bpy.types.TEXTURE_PT_image_mapping,
- bpy.types.TEXTURE_PT_musgrave,
- bpy.types.TEXTURE_PT_voronoi,
- bpy.types.TEXTURE_PT_distortednoise,
- bpy.types.TEXTURE_PT_voxeldata,
- bpy.types.TEXTURE_PT_pointdensity,
- bpy.types.TEXTURE_PT_pointdensity_turbulence,
- bpy.types.TEXTURE_PT_mapping,
- bpy.types.TEXTURE_PT_influence,
- bpy.types.PARTICLE_PT_context_particles,
- bpy.types.PARTICLE_PT_emission,
- bpy.types.PARTICLE_PT_hair_dynamics,
- bpy.types.PARTICLE_PT_cache,
- bpy.types.PARTICLE_PT_velocity,
- bpy.types.PARTICLE_PT_rotation,
- bpy.types.PARTICLE_PT_physics,
- bpy.types.PARTICLE_PT_boidbrain,
- bpy.types.PARTICLE_PT_render,
- bpy.types.PARTICLE_PT_draw,
- bpy.types.PARTICLE_PT_children,
- bpy.types.PARTICLE_PT_field_weights,
- bpy.types.PARTICLE_PT_force_fields,
- bpy.types.PARTICLE_PT_vertexgroups,
- bpy.types.PARTICLE_PT_custom_props,
+ types.RENDER_PT_render,
+ types.RENDER_PT_output,
+ types.RENDER_PT_encoding,
+ types.RENDER_PT_dimensions,
+ types.RENDER_PT_stamp,
+ types.SCENE_PT_scene,
+ types.SCENE_PT_color_management,
+ types.SCENE_PT_custom_props,
+ types.SCENE_PT_audio,
+ types.SCENE_PT_unit,
+ types.SCENE_PT_keying_sets,
+ types.SCENE_PT_keying_set_paths,
+ types.SCENE_PT_physics,
+ types.WORLD_PT_context_world,
+ types.WORLD_PT_custom_props,
+ types.DATA_PT_context_mesh,
+ types.DATA_PT_context_camera,
+ types.DATA_PT_context_lamp,
+ types.DATA_PT_context_speaker,
+ types.DATA_PT_texture_space,
+ types.DATA_PT_curve_texture_space,
+ types.DATA_PT_mball_texture_space,
+ types.DATA_PT_vertex_groups,
+ types.DATA_PT_shape_keys,
+ types.DATA_PT_uv_texture,
+ types.DATA_PT_vertex_colors,
+ types.DATA_PT_camera,
+ types.DATA_PT_camera_display,
+ types.DATA_PT_lens,
+ types.DATA_PT_speaker,
+ types.DATA_PT_distance,
+ types.DATA_PT_cone,
+ types.DATA_PT_customdata,
+ types.DATA_PT_custom_props_mesh,
+ types.DATA_PT_custom_props_camera,
+ types.DATA_PT_custom_props_lamp,
+ types.DATA_PT_custom_props_speaker,
+ types.DATA_PT_custom_props_arm,
+ types.DATA_PT_custom_props_curve,
+ types.DATA_PT_custom_props_lattice,
+ types.DATA_PT_custom_props_metaball,
+ types.TEXTURE_PT_custom_props,
+ types.TEXTURE_PT_clouds,
+ types.TEXTURE_PT_wood,
+ types.TEXTURE_PT_marble,
+ types.TEXTURE_PT_magic,
+ types.TEXTURE_PT_blend,
+ types.TEXTURE_PT_stucci,
+ types.TEXTURE_PT_image,
+ types.TEXTURE_PT_image_sampling,
+ types.TEXTURE_PT_image_mapping,
+ types.TEXTURE_PT_musgrave,
+ types.TEXTURE_PT_voronoi,
+ types.TEXTURE_PT_distortednoise,
+ types.TEXTURE_PT_voxeldata,
+ types.TEXTURE_PT_pointdensity,
+ types.TEXTURE_PT_pointdensity_turbulence,
+ types.TEXTURE_PT_mapping,
+ types.TEXTURE_PT_influence,
+ types.TEXTURE_PT_colors,
+ types.PARTICLE_PT_context_particles,
+ types.PARTICLE_PT_custom_props,
+ types.PARTICLE_PT_emission,
+ types.PARTICLE_PT_hair_dynamics,
+ types.PARTICLE_PT_cache,
+ types.PARTICLE_PT_velocity,
+ types.PARTICLE_PT_rotation,
+ types.PARTICLE_PT_physics,
+ types.SCENE_PT_rigid_body_world,
+ types.SCENE_PT_rigid_body_cache,
+ types.SCENE_PT_rigid_body_field_weights,
+ types.PARTICLE_PT_boidbrain,
+ types.PARTICLE_PT_render,
+ types.PARTICLE_PT_draw,
+ types.PARTICLE_PT_children,
+ types.PARTICLE_PT_field_weights,
+ types.PARTICLE_PT_force_fields,
+ types.PARTICLE_PT_vertexgroups,
+ types.MATERIAL_PT_custom_props,
+ types.BONE_PT_custom_props,
+ types.OBJECT_PT_custom_props,
)
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
new file mode 100644
index 00000000000..5b8d495084d
--- /dev/null
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -0,0 +1,1175 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "attribute.h"
+#include "mesh.h"
+#include "object.h"
+#include "scene.h"
+#include "curves.h"
+
+#include "blender_sync.h"
+#include "blender_util.h"
+
+#include "util_foreach.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Utilities */
+
+/* Hair curve functions */
+
+void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, float3 *v4, const float w[4]);
+void interp_weights(float t, float data[4], int type);
+float shaperadius(float shape, float root, float tip, float time);
+void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData, int interpolation);
+bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int uv_num);
+bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int vcol_num);
+bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background);
+void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments);
+void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam);
+void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments);
+void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int resolution, int segments);
+void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *uvdata);
+void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *fdata);
+
+ParticleCurveData::ParticleCurveData()
+{
+}
+
+ParticleCurveData::~ParticleCurveData()
+{
+ psys_firstcurve.clear();
+ psys_curvenum.clear();
+ psys_shader.clear();
+ psys_rootradius.clear();
+ psys_tipradius.clear();
+ psys_shape.clear();
+
+ curve_firstkey.clear();
+ curve_keynum.clear();
+ curve_length.clear();
+ curve_uv.clear();
+ curve_vcol.clear();
+
+ curvekey_co.clear();
+ curvekey_time.clear();
+}
+
+void interp_weights(float t, float data[4], int type)
+{
+ float t2, t3, fc;
+
+ if(type == CURVE_LINEAR) {
+ data[0] = 0.0f;
+ data[1] = -t + 1.0f;
+ data[2] = t;
+ data[3] = 0.0f;
+ }
+ else if(type == CURVE_CARDINAL) {
+ t2 = t * t;
+ t3 = t2 * t;
+ fc = 0.71f;
+
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
+ }
+ else if(type == CURVE_BSPLINE) {
+ t2 = t * t;
+ t3 = t2 * t;
+
+ data[0] = -0.16666666f * t3 + 0.5f * t2 - 0.5f * t + 0.16666666f;
+ data[1] = 0.5f * t3 - t2 + 0.66666666f;
+ data[2] = -0.5f * t3 + 0.5f * t2 + 0.5f * t + 0.16666666f;
+ data[3] = 0.16666666f * t3;
+ }
+}
+
+void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, float3 *v4, const float w[4])
+{
+ p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3];
+ p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3];
+ p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3];
+}
+
+float shaperadius(float shape, float root, float tip, float time)
+{
+ float radius = 1.0f - time;
+ if(shape != 0.0f) {
+ if(shape < 0.0f)
+ radius = (float)pow(1.0f - time, 1.f + shape);
+ else
+ radius = (float)pow(1.0f - time, 1.f / (1.f - shape));
+ }
+ return (radius * (root - tip)) + tip;
+}
+
+/* curve functions */
+
+void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData, int interpolation)
+{
+ float3 ckey_loc1 = CData->curvekey_co[key];
+ float3 ckey_loc2 = ckey_loc1;
+ float3 ckey_loc3 = CData->curvekey_co[key+1];
+ float3 ckey_loc4 = ckey_loc3;
+
+ if(key > CData->curve_firstkey[curve])
+ ckey_loc1 = CData->curvekey_co[key - 1];
+
+ if(key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
+ ckey_loc4 = CData->curvekey_co[key + 2];
+
+
+ float time1 = CData->curvekey_time[key]/CData->curve_length[curve];
+ float time2 = CData->curvekey_time[key + 1]/CData->curve_length[curve];
+
+ float dfra = (time2 - time1) / (float)segno;
+
+ if(time)
+ *time = (dfra * seg) + time1;
+
+ float t[4];
+
+ interp_weights((float)seg / (float)segno, t, interpolation);
+
+ if(keyloc)
+ curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
+}
+
+bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background)
+{
+
+ int curvenum = 0;
+ int keyno = 0;
+
+ if(!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
+
+ int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
+ int shader = mesh->used_shaders[mi];
+ int draw_step = background ? b_psys.settings().render_step() : b_psys.settings().draw_step();
+ int ren_step = (int)pow((float)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_psys.settings().draw_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if(use_parents || b_psys.settings().child_type() == 0)
+ totcurves += totparts;
+
+ if(totcurves == 0)
+ continue;
+
+ PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
+
+ CData->psys_firstcurve.push_back(curvenum);
+ CData->psys_curvenum.push_back(totcurves);
+ CData->psys_shader.push_back(shader);
+
+ float radius = b_psys.settings().particle_size() * 0.5f;
+
+ CData->psys_rootradius.push_back(radius * get_float(cpsys, "root_width"));
+ CData->psys_tipradius.push_back(radius * get_float(cpsys, "tip_width"));
+ CData->psys_shape.push_back(get_float(cpsys, "shape"));
+ CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip"));
+
+ int pa_no = 0;
+ if(!use_parents && !(b_psys.settings().child_type() == 0))
+ pa_no = totparts;
+
+ for(; pa_no < totparts+totchild; pa_no++) {
+
+ CData->curve_firstkey.push_back(keyno);
+ CData->curve_keynum.push_back(ren_step+1);
+
+ float curve_length = 0.0f;
+ float3 pcKey;
+ for(int step_no = 0; step_no <= ren_step; step_no++) {
+ float nco[3];
+ b_psys.co_hair(*b_ob, psmd, pa_no, step_no, nco);
+ float3 cKey = make_float3(nco[0],nco[1],nco[2]);
+ cKey = transform_point(&itfm, cKey);
+ if(step_no > 0)
+ curve_length += len(cKey - pcKey);
+ CData->curvekey_co.push_back(cKey);
+ CData->curvekey_time.push_back(curve_length);
+ pcKey = cKey;
+ keyno++;
+ }
+ CData->curve_length.push_back(curve_length);
+
+ curvenum++;
+
+ }
+ }
+
+ }
+ }
+
+ return true;
+
+}
+
+bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int uv_num)
+{
+#if 0
+ int keyno = 0;
+#endif
+
+ if(!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+#if 0
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+#endif
+
+ CData->curve_uv.clear();
+
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
+#if 0
+ int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
+ int shader = mesh->used_shaders[mi];
+#endif
+
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_psys.settings().draw_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (use_parents || b_psys.settings().child_type() == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if(!use_parents && !(b_psys.settings().child_type() == 0))
+ pa_no = totparts;
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for(; pa_no < totparts+totchild; pa_no++) {
+
+ /*add uvs*/
+ BL::Mesh::tessface_uv_textures_iterator l;
+ b_mesh->tessface_uv_textures.begin(l);
+
+ float3 uv = make_float3(0.0f, 0.0f, 0.0f);
+ if(b_mesh->tessface_uv_textures.length())
+ b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
+ CData->curve_uv.push_back(uv);
+
+ if(pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+
+ }
+ }
+
+ }
+ }
+
+ return true;
+
+}
+
+bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int vcol_num)
+{
+#if 0
+ int keyno = 0;
+#endif
+ if(!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+#if 0
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+#endif
+
+ CData->curve_vcol.clear();
+
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
+#if 0
+ int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
+ int shader = mesh->used_shaders[mi];
+#endif
+ int totparts = b_psys.particles.length();
+ int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_psys.settings().draw_percentage() / 100.0f);
+ int totcurves = totchild;
+
+ if (use_parents || b_psys.settings().child_type() == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if(!use_parents && !(b_psys.settings().child_type() == 0))
+ pa_no = totparts;
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for(; pa_no < totparts+totchild; pa_no++) {
+
+ /*add uvs*/
+ BL::Mesh::tessface_vertex_colors_iterator l;
+ b_mesh->tessface_vertex_colors.begin(l);
+
+ float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
+ if(b_mesh->tessface_vertex_colors.length())
+ b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
+ CData->curve_vcol.push_back(vcol);
+
+ if(pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+
+ }
+ }
+
+ }
+ }
+
+ return true;
+
+}
+
+static void set_resolution(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, BL::Scene *scene, bool render)
+{
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+ b_psys.set_resolution(*scene, *b_ob, (render)? 2: 1);
+ }
+ }
+}
+
+void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam)
+{
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ float3 xbasis;
+
+ float3 v1;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])];
+ else
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1];
+
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ xbasis = normalize(cross(RotCam - ickey_loc,v1));
+ float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
+ float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
+ mesh->verts.push_back(ickey_loc_shfl);
+ mesh->verts.push_back(ickey_loc_shfr);
+ if(subv!=0) {
+ mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], use_smooth);
+ }
+ vertexindex += 2;
+ }
+ }
+ }
+ }
+
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
+}
+
+void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments)
+{
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]);
+ if(len_squared(firstxbasis)!= 0.0f)
+ firstxbasis = normalize(firstxbasis);
+ else
+ firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]));
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ float3 xbasis = firstxbasis;
+ float3 v1;
+ float3 v2;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ firstxbasis = normalize(xbasis);
+ break;
+ }
+ }
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ float3 v1;
+ float3 v2;
+ float3 xbasis;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ xbasis = normalize(xbasis);
+ firstxbasis = xbasis;
+ }
+ else
+ xbasis = firstxbasis;
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
+ float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
+ mesh->verts.push_back(ickey_loc_shfl);
+ mesh->verts.push_back(ickey_loc_shfr);
+ if(subv!=0) {
+ mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], use_smooth);
+ }
+ vertexindex += 2;
+ }
+ }
+ }
+ }
+
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ /* texture coords still needed */
+
+}
+
+void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int resolution, int segments)
+{
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]);
+ if(len_squared(firstxbasis)!= 0.0f)
+ firstxbasis = normalize(firstxbasis);
+ else
+ firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]));
+
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ float3 xbasis = firstxbasis;
+ float3 v1;
+ float3 v2;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ firstxbasis = normalize(xbasis);
+ break;
+ }
+ }
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ float3 xbasis;
+ float3 ybasis;
+ float3 v1;
+ float3 v2;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ xbasis = normalize(xbasis);
+ firstxbasis = xbasis;
+ }
+ else
+ xbasis = firstxbasis;
+
+ ybasis = normalize(cross(xbasis,v2));
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ float angle = 2 * M_PI_F / (float)resolution;
+ for(int section = 0 ; section < resolution; section++) {
+ float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis + sinf(angle * section) * ybasis);
+ mesh->verts.push_back(ickey_loc_shf);
+ }
+
+ if(subv!=0) {
+ for(int section = 0 ; section < resolution - 1; section++) {
+ mesh->add_triangle(vertexindex - resolution + section, vertexindex + section, vertexindex - resolution + section + 1, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex + section + 1, vertexindex - resolution + section + 1, vertexindex + section, CData->psys_shader[sys], use_smooth);
+ }
+ mesh->add_triangle(vertexindex-1, vertexindex + resolution - 1, vertexindex - resolution, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex, vertexindex - resolution , vertexindex + resolution - 1, CData->psys_shader[sys], use_smooth);
+ }
+ vertexindex += resolution;
+ }
+ }
+ }
+ }
+
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
+}
+
+static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
+{
+ int num_keys = 0;
+ int num_curves = 0;
+
+ if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
+ return;
+
+ Attribute *attr_intercept = NULL;
+
+ if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
+ attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+
+ if(CData->psys_curvenum[sys] == 0)
+ continue;
+
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ if(CData->curve_keynum[curve] <= 1)
+ continue;
+
+ size_t num_curve_keys = 0;
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ if(curvekey == CData->curve_firstkey[curve])
+ subv = 0;
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
+ radius =0.0f;
+
+ mesh->add_curve_key(ickey_loc, radius);
+ if(attr_intercept)
+ attr_intercept->add(time);
+
+ num_curve_keys++;
+ }
+ }
+
+ mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]);
+ num_keys += num_curve_keys;
+ num_curves++;
+ }
+ }
+
+ /* check allocation*/
+ if((mesh->curve_keys.size() != num_keys) || (mesh->curves.size() != num_curves)) {
+ /* allocation failed -> clear data */
+ mesh->curve_keys.clear();
+ mesh->curves.clear();
+ mesh->curve_attributes.clear();
+ }
+}
+
+void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *uvdata)
+{
+ if(uvdata == NULL)
+ return;
+
+ float time = 0.0f;
+ float prevtime = 0.0f;
+
+ int vertexindex = vert_offset;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+
+ if (curvekey == CData->curve_firstkey[curve])
+ subv = 0;
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ if(subv!=0) {
+ for(int section = 0 ; section < resol; section++) {
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = prevtime;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = time;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = prevtime;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = time;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = prevtime;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = time;
+ vertexindex++;
+ }
+ }
+
+ prevtime = time;
+ }
+ }
+ }
+ }
+
+}
+
+void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *fdata)
+{
+ if(fdata == NULL)
+ return;
+
+ float time = 0.0f;
+// float prevtime = 0.0f; // UNUSED
+
+ int vertexindex = vert_offset;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+
+ if (curvekey == CData->curve_firstkey[curve])
+ subv = 0;
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ if(subv!=0) {
+ for(int section = 0 ; section < resol; section++) {
+ fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]);
+ vertexindex++;
+ fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]);
+ vertexindex++;
+ fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]);
+ vertexindex++;
+ fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]);
+ vertexindex++;
+ fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]);
+ vertexindex++;
+ fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]);
+ vertexindex++;
+ }
+ }
+
+ // prevtime = time; // UNUSED
+ }
+ }
+ }
+ }
+
+}
+
+/* Hair Curve Sync */
+
+void BlenderSync::sync_curve_settings()
+{
+ PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves");
+
+ int preset = get_enum(csscene, "preset");
+
+ CurveSystemManager *curve_system_manager = scene->curve_system_manager;
+ CurveSystemManager prev_curve_system_manager = *curve_system_manager;
+
+ curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
+
+ if(preset == CURVE_CUSTOM) {
+ /*custom properties*/
+ curve_system_manager->primitive = get_enum(csscene, "primitive");
+ curve_system_manager->line_method = get_enum(csscene, "line_method");
+ curve_system_manager->interpolation = get_enum(csscene, "interpolation");
+ curve_system_manager->triangle_method = get_enum(csscene, "triangle_method");
+ curve_system_manager->resolution = get_int(csscene, "resolution");
+ curve_system_manager->segments = get_int(csscene, "segments");
+ curve_system_manager->use_smooth = get_boolean(csscene, "use_smooth");
+ curve_system_manager->subdivisions = get_int(csscene, "subdivisions");
+
+ curve_system_manager->normalmix = get_float(csscene, "normalmix");
+ curve_system_manager->encasing_ratio = get_float(csscene, "encasing_ratio");
+
+ curve_system_manager->use_parents = get_boolean(csscene, "use_parents");
+ curve_system_manager->use_encasing = get_boolean(csscene, "use_encasing");
+ curve_system_manager->use_backfacing = get_boolean(csscene, "use_backfacing");
+ curve_system_manager->use_joined = get_boolean(csscene, "use_joined");
+ curve_system_manager->use_tangent_normal = get_boolean(csscene, "use_tangent_normal");
+ curve_system_manager->use_tangent_normal_geometry = get_boolean(csscene, "use_tangent_normal_geometry");
+ curve_system_manager->use_tangent_normal_correction = get_boolean(csscene, "use_tangent_normal_correction");
+ }
+ else {
+ curve_system_manager->primitive = CURVE_LINE_SEGMENTS;
+ curve_system_manager->interpolation = CURVE_CARDINAL;
+ curve_system_manager->normalmix = 1.0f;
+ curve_system_manager->encasing_ratio = 1.01f;
+ curve_system_manager->use_parents = false;
+ curve_system_manager->segments = 1;
+ curve_system_manager->use_joined = false;
+
+ switch(preset) {
+ case CURVE_FAST_PLANES:
+ /*camera facing planes*/
+ curve_system_manager->primitive = CURVE_TRIANGLES;
+ curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES;
+ curve_system_manager->use_smooth = true;
+ curve_system_manager->resolution = 1;
+ break;
+ case CURVE_TANGENT_SHADING:
+ /*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 = true;
+ curve_system_manager->use_tangent_normal_geometry = true;
+ curve_system_manager->use_tangent_normal_correction = false;
+ break;
+ case CURVE_TRUE_NORMAL:
+ /*True Normal*/
+ curve_system_manager->line_method = CURVE_CORRECTED;
+ curve_system_manager->use_encasing = true;
+ curve_system_manager->use_backfacing = false;
+ curve_system_manager->use_tangent_normal = false;
+ curve_system_manager->use_tangent_normal_geometry = false;
+ curve_system_manager->use_tangent_normal_correction = false;
+ break;
+ case CURVE_ACCURATE_PRESET:
+ /*Accurate*/
+ curve_system_manager->line_method = CURVE_ACCURATE;
+ curve_system_manager->use_encasing = false;
+ curve_system_manager->use_backfacing = true;
+ curve_system_manager->use_tangent_normal = false;
+ curve_system_manager->use_tangent_normal_geometry = false;
+ curve_system_manager->use_tangent_normal_correction = false;
+ break;
+ case CURVE_SMOOTH_CURVES:
+ /*Cardinal curves preset*/
+ curve_system_manager->primitive = CURVE_SEGMENTS;
+ curve_system_manager->use_backfacing = true;
+ curve_system_manager->subdivisions = 4;
+ break;
+ }
+
+ }
+
+ if(curve_system_manager->modified_mesh(prev_curve_system_manager))
+ {
+ BL::BlendData::objects_iterator b_ob;
+
+ for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
+ if(object_is_mesh(*b_ob)) {
+ BL::Object::particle_systems_iterator b_psys;
+ for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
+ if((b_psys->settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys->settings().type()==BL::ParticleSettings::type_HAIR)) {
+ BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
+ mesh_map.set_recalc(key);
+ object_map.set_recalc(*b_ob);
+ }
+ }
+ }
+ }
+ }
+
+ if(curve_system_manager->modified(prev_curve_system_manager))
+ curve_system_manager->tag_update(scene);
+
+}
+
+void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool object_updated)
+{
+ /* Clear stored curve data */
+ mesh->curve_keys.clear();
+ mesh->curves.clear();
+ mesh->curve_attributes.clear();
+
+ /* obtain general settings */
+ bool use_curves = scene->curve_system_manager->use_curves;
+
+ if(!(use_curves && b_ob.mode() == b_ob.mode_OBJECT)) {
+ mesh->compute_bounds();
+ return;
+ }
+
+ int primitive = scene->curve_system_manager->primitive;
+ int interpolation = scene->curve_system_manager->interpolation;
+ int triangle_method = scene->curve_system_manager->triangle_method;
+ int resolution = scene->curve_system_manager->resolution;
+ int segments = scene->curve_system_manager->segments;
+ bool use_smooth = scene->curve_system_manager->use_smooth;
+ bool use_parents = scene->curve_system_manager->use_parents;
+ bool export_tgs = scene->curve_system_manager->use_joined;
+ size_t vert_num = mesh->verts.size();
+ size_t tri_num = mesh->triangles.size();
+ int used_res = 1;
+
+ /* extract particle hair data - should be combined with connecting to mesh later*/
+
+ ParticleCurveData CData;
+
+ if(!preview)
+ set_resolution(mesh, &b_mesh, &b_ob, &b_scene, true);
+
+ ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents, !preview);
+
+ /* obtain camera parameters */
+ BL::Object b_CamOb = b_scene.camera();
+ float3 RotCam = make_float3(0.0f, 0.0f, 0.0f);
+ if(b_CamOb) {
+ Transform ctfm = get_transform(b_CamOb.matrix_world());
+ Transform tfm = get_transform(b_ob.matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+ RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, ctfm.z.w));
+ }
+
+ /* add hair geometry to mesh */
+ if(primitive == CURVE_TRIANGLES){
+ if(triangle_method == CURVE_CAMERA_TRIANGLES)
+ ExportCurveTrianglePlanes(mesh, &CData, interpolation, use_smooth, segments, RotCam);
+ else if(triangle_method == CURVE_RIBBON_TRIANGLES)
+ ExportCurveTriangleRibbons(mesh, &CData, interpolation, use_smooth, segments);
+ else {
+ ExportCurveTriangleGeometry(mesh, &CData, interpolation, use_smooth, resolution, segments);
+ used_res = resolution;
+ }
+ }
+ else {
+ ExportCurveSegments(scene, mesh, &CData, interpolation, segments);
+ int ckey_num = mesh->curve_keys.size();
+
+ /*export tangents or curve data? - not functional yet*/
+ if(export_tgs && ckey_num > 1) {
+ Attribute *attr_tangent = mesh->curve_attributes.add(ATTR_STD_CURVE_TANGENT);
+ float3 *data_tangent = attr_tangent->data_float3();
+
+ for(int ck = 0; ck < ckey_num; ck++) {
+ float3 tg = normalize(normalize(mesh->curve_keys[min(ck + 1, ckey_num - 1)].co - mesh->curve_keys[ck].co) -
+ normalize(mesh->curve_keys[max(ck - 1, 0)].co - mesh->curve_keys[ck].co));
+
+ data_tangent[ck] = tg;
+ }
+ }
+ }
+
+
+ /* generated coordinates from first key. we should ideally get this from
+ * blender to handle deforming objects */
+ {
+ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ if(primitive == CURVE_TRIANGLES) {
+ Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+
+ for(size_t i = vert_num; i < mesh->verts.size(); i++)
+ generated[i] = mesh->verts[i]*size - loc;
+ }
+ else {
+ Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+ size_t i = 0;
+
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ float3 co = mesh->curve_keys[curve.first_key].co;
+ generated[i++] = co*size - loc;
+ }
+ }
+ }
+ }
+
+ /* create vertex color attributes */
+ {
+ BL::Mesh::tessface_vertex_colors_iterator l;
+ int vcol_num = 0;
+
+ for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l, vcol_num++) {
+ if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, use_parents, !preview, vcol_num);
+
+ if(primitive == CURVE_TRIANGLES) {
+
+ Attribute *attr_vcol = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER);
+
+ float3 *fdata = attr_vcol->data_float3();
+
+ ExportCurveTriangleVcol(mesh, &CData, interpolation, segments, tri_num * 3, used_res, fdata);
+ }
+ else {
+ Attribute *attr_vcol = mesh->curve_attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
+
+ float3 *fdata = attr_vcol->data_float3();
+
+ if(fdata) {
+ for(size_t curve = 0; curve < CData.curve_vcol.size() ;curve++)
+ fdata[curve] = color_srgb_to_scene_linear(CData.curve_vcol[curve]);
+ }
+ }
+ }
+ }
+
+ /* create UV attributes */
+ {
+ BL::Mesh::tessface_uv_textures_iterator l;
+ int uv_num = 0;
+
+ for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l, uv_num++) {
+ 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_uv;
+
+ ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents, !preview, uv_num);
+
+ if(primitive == CURVE_TRIANGLES) {
+ if(active_render)
+ attr_uv = mesh->attributes.add(std, name);
+ else
+ attr_uv = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
+
+ float3 *uv = attr_uv->data_float3();
+
+ ExportCurveTriangleUV(mesh, &CData, interpolation, segments, tri_num * 3, used_res, uv);
+ }
+ else {
+ if(active_render)
+ attr_uv = mesh->curve_attributes.add(std, name);
+ else
+ attr_uv = mesh->curve_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
+
+ float3 *uv = attr_uv->data_float3();
+
+ if(uv) {
+ for(size_t curve = 0; curve < CData.curve_uv.size(); curve++)
+ uv[curve] = CData.curve_uv[curve];
+ }
+ }
+ }
+ }
+ }
+
+ if(!preview)
+ set_resolution(mesh, &b_mesh, &b_ob, &b_scene, false);
+
+ mesh->compute_bounds();
+}
+
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index c9748756d43..c61a7fafb57 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -147,7 +147,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
if(active_render)
attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
else
- attr = mesh->attributes.add(name, TypeDesc::TypeVector, Attribute::CORNER);
+ attr = mesh->attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
float3 *tangent = attr->data_float3();
@@ -161,7 +161,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
if(active_render)
attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
else
- attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, Attribute::CORNER);
+ attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
tangent_sign = attr_sign->data_float();
}
@@ -223,10 +223,19 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
int shader = used_shaders[mi];
bool smooth = f->use_smooth();
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
-
- if(n == 4)
- mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
+ if(n == 4) {
+ if(len_squared(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) == 0.0f ||
+ len_squared(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])) == 0.0f) {
+ mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
+ mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
+ }
+ else {
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
+ mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
+ }
+ }
+ else
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
nverts.push_back(n);
}
@@ -240,7 +249,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
continue;
Attribute *attr = mesh->attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, Attribute::CORNER);
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER);
BL::MeshColorLayer::data_iterator c;
float3 *fdata = attr->data_float3();
@@ -279,7 +288,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
if(active_render)
attr = mesh->attributes.add(std, name);
else
- attr = mesh->attributes.add(name, TypeDesc::TypePoint, Attribute::CORNER);
+ attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
BL::MeshTextureFaceLayer::data_iterator t;
float3 *fdata = attr->data_float3();
@@ -304,7 +313,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
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) || mesh->need_attribute(scene, std)) {
+ 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));
@@ -319,14 +328,9 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
* is available in the api. */
if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
- float3 loc = get_float3(b_mesh.texspace_location());
- float3 size = get_float3(b_mesh.texspace_size());
-
- if(size.x != 0.0f) size.x = 0.5f/size.x;
- if(size.y != 0.0f) size.y = 0.5f/size.y;
- if(size.z != 0.0f) size.z = 0.5f/size.z;
- loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
float3 *generated = attr->data_float3();
size_t i = 0;
@@ -376,7 +380,7 @@ static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, con
/* Sync */
-Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
+Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris)
{
/* test if we can instance or if the object is modified */
BL::ID b_ob_data = b_ob.data();
@@ -431,20 +435,28 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
mesh_synced.insert(mesh);
/* create derived mesh */
- BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
+ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview);
PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");
vector<Mesh::Triangle> oldtriangle = mesh->triangles;
+
+ /* compares curve_keys rather than strands in order to handle quick hair adjustsments in dynamic BVH - other methods could probably do this better*/
+ vector<Mesh::CurveKey> oldcurve_keys = mesh->curve_keys;
mesh->clear();
mesh->used_shaders = used_shaders;
mesh->name = ustring(b_ob_data.name().c_str());
if(b_mesh) {
- if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
- create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
- else
- create_mesh(scene, mesh, b_mesh, used_shaders);
+ if(!(hide_tris && experimental && is_cpu)) {
+ if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
+ create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
+ else
+ create_mesh(scene, mesh, b_mesh, used_shaders);
+ }
+
+ if(experimental && is_cpu)
+ sync_curves(mesh, b_mesh, b_ob, object_updated);
/* free derived mesh */
b_data.meshes.remove(b_mesh);
@@ -471,6 +483,13 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0)
rebuild = true;
}
+
+ if(oldcurve_keys.size() != mesh->curve_keys.size())
+ rebuild = true;
+ else if(oldcurve_keys.size()) {
+ if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(Mesh::CurveKey)*oldcurve_keys.size()) != 0)
+ rebuild = true;
+ }
mesh->tag_update(scene, rebuild);
@@ -488,7 +507,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
return;
/* get derived mesh */
- BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
+ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview);
if(b_mesh) {
BL::Mesh::vertices_iterator v;
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 38f27bcf2af..a9d37dbed99 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -127,8 +127,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
case BL::Lamp::type_AREA: {
BL::AreaLamp b_area_lamp(b_lamp);
light->size = 1.0f;
- light->axisu = make_float3(tfm.x.x, tfm.y.x, tfm.z.x);
- light->axisv = make_float3(tfm.x.y, tfm.y.y, tfm.z.y);
+ light->axisu = transform_get_column(&tfm, 0);
+ light->axisv = transform_get_column(&tfm, 1);
light->sizeu = b_area_lamp.size();
if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE)
light->sizev = b_area_lamp.size_y();
@@ -140,8 +140,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
}
/* location and (inverted!) direction */
- light->co = make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
- light->dir = -make_float3(tfm.x.z, tfm.y.z, tfm.z.z);
+ light->co = transform_get_column(&tfm, 3);
+ light->dir = -transform_get_column(&tfm, 2);
/* shader */
vector<uint> used_shaders;
@@ -156,6 +156,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
/* shadow */
PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles");
light->cast_shadow = get_boolean(clamp, "cast_shadow");
+ light->use_mis = get_boolean(clamp, "use_multiple_importance_sampling");
light->samples = get_int(clamp, "samples");
/* tag */
@@ -196,7 +197,7 @@ void BlenderSync::sync_background_light()
/* Object */
-Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion)
+Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, bool hide_tris)
{
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
@@ -247,7 +248,7 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
bool use_holdout = (layer_flag & render_layer.holdout_layer) != 0;
/* mesh sync */
- object->mesh = sync_mesh(b_ob, object_updated);
+ object->mesh = sync_mesh(b_ob, object_updated, hide_tris);
/* sspecial case not tracked by object update flags */
if(use_holdout != object->use_holdout) {
@@ -390,7 +391,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
/* sync object and mesh or light data */
- Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion);
+ Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion, false);
/* sync possible particle data, note particle_id
* starts counting at 1, first is dummy particle */
@@ -412,9 +413,23 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
- if(b_psys->settings().use_render_emitter())
+ bool hair_present = false;
+ bool show_emitter = false;
+ bool hide_tris = false;
+
+ for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
+
+ if((b_psys->settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
+ hair_present = true;
+
+ if(b_psys->settings().use_render_emitter()) {
hide = false;
+ show_emitter = true;
+ }
+ }
+
+ if(hair_present && !show_emitter)
+ hide_tris = true;
/* hide original object for duplis */
BL::Object parent = b_ob->parent();
@@ -424,7 +439,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
if(!hide) {
/* object itself */
Transform tfm = get_transform(b_ob->matrix_world());
- sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion);
+ sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion, hide_tris);
}
}
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index d164920ceff..a10f3b63033 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -52,8 +52,9 @@ static PyObject *init_func(PyObject *self, PyObject *args)
static PyObject *create_func(PyObject *self, PyObject *args)
{
PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
+ int preview_osl;
- if(!PyArg_ParseTuple(args, "OOOOOOO", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
+ if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d, &preview_osl))
return NULL;
/* RNA */
@@ -91,14 +92,22 @@ static PyObject *create_func(PyObject *self, PyObject *args)
Py_BEGIN_ALLOW_THREADS
if(rv3d) {
- /* interactive session */
+ /* interactive viewport session */
int width = region.width();
int height = region.height();
session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
}
else {
- /* offline session */
+ /* override some settings for preview */
+ if(engine.is_preview()) {
+ PointerRNA cscene = RNA_pointer_get(&sceneptr, "cycles");
+
+ RNA_boolean_set(&cscene, "shading_system", preview_osl);
+ RNA_boolean_set(&cscene, "use_progressive_refine", true);
+ }
+
+ /* offline session or preview render */
session = new BlenderSession(engine, userpref, data, scene);
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index b8ed942f5b6..dda7eb053c4 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -96,7 +96,7 @@ void BlenderSession::create_session()
session->set_pause(BlenderSync::get_session_pause(b_scene, background));
/* create sync */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
sync->sync_data(b_v3d, b_engine.camera_override());
if(b_rv3d)
@@ -107,6 +107,13 @@ void BlenderSession::create_session()
/* set buffer parameters */
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
+
+ /* setup callbacks for builtin image support */
+ scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6);
+ scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3);
+ scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3);
}
void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
@@ -121,7 +128,8 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
height = b_engine.resolution_y();
if(scene->params.modified(scene_params) ||
- session->params.modified(session_params))
+ session->params.modified(session_params) ||
+ !scene_params.persistent_data)
{
/* if scene or session parameters changed, it's easier to simply re-create
* them rather than trying to distinguish which settings need to be updated
@@ -137,18 +145,22 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
session->progress.reset();
scene->reset();
+ session->tile_manager.set_tile_order(session_params.tile_order);
+
/* peak memory usage should show current render peak, not peak for all renders
* made by this render session
*/
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);
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
sync->sync_data(b_v3d, b_engine.camera_override());
sync->sync_camera(b_engine.camera_override(), width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
}
void BlenderSession::free_session()
@@ -252,7 +264,15 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda
if (do_update_only) {
/* update only needed */
- update_render_result(b_rr, b_rlay, rtile);
+
+ if (rtile.sample != 0) {
+ /* sample would be zero at initial tile update, which is only needed
+ * to tag tile form blender side as IN PROGRESS for proper highlight
+ * no buffers should be sent to blender yet
+ */
+ update_render_result(b_rr, b_rlay, rtile);
+ }
+
end_render_result(b_engine, b_rr, true);
}
else {
@@ -269,7 +289,14 @@ void BlenderSession::write_render_tile(RenderTile& rtile)
void BlenderSession::update_render_tile(RenderTile& rtile)
{
- do_write_update_render_tile(rtile, true);
+ /* use final write for preview renders, otherwise render result wouldn't be
+ * be updated in blender side
+ * would need to be investigated a bit further, but for now shall be fine
+ */
+ if (!b_engine.is_preview())
+ do_write_update_render_tile(rtile, true);
+ else
+ do_write_update_render_tile(rtile, false);
}
void BlenderSession::render()
@@ -384,8 +411,10 @@ void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::Re
int components = b_pass.channels();
/* copy pixels */
- if(buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0]))
- b_pass.rect(&pixels[0]);
+ if(!buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0]))
+ memset(&pixels[0], 0, pixels.size()*sizeof(float));
+
+ b_pass.rect(&pixels[0]);
}
}
@@ -467,11 +496,10 @@ bool BlenderSession::draw(int w, int h)
}
else {
/* update camera from 3d view */
- bool need_update = scene->camera->need_update;
sync->sync_view(b_v3d, b_rv3d, w, h);
- if(scene->camera->need_update && !need_update)
+ if(scene->camera->need_update)
reset = true;
session->scene->mutex.unlock();
@@ -492,6 +520,9 @@ bool BlenderSession::draw(int w, int h)
session->reset(buffer_params, session_params.samples);
}
}
+ else {
+ tag_update();
+ }
/* update status and progress for 3d view draw */
update_status_progress();
@@ -593,5 +624,120 @@ void BlenderSession::test_cancel()
session->progress.set_cancel("Cancelled");
}
+/* builtin image file name is actually an image datablock name with
+ * absolute sequence frame number concatenated via '@' character
+ *
+ * this function splits frame from builtin name
+ */
+int BlenderSession::builtin_image_frame(const string &builtin_name)
+{
+ int last = builtin_name.find_last_of('@');
+ return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
+}
+
+void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &channels)
+{
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID*)builtin_data, &ptr);
+ BL::Image b_image(ptr);
+
+ if(b_image) {
+ is_float = b_image.is_float();
+ width = b_image.size()[0];
+ height = b_image.size()[1];
+ channels = b_image.channels();
+ }
+ else {
+ is_float = false;
+ width = 0;
+ height = 0;
+ channels = 0;
+ }
+}
+
+bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels)
+{
+ int frame = builtin_image_frame(builtin_name);
+
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID*)builtin_data, &ptr);
+ BL::Image b_image(ptr);
+
+ if(b_image) {
+ int width = b_image.size()[0];
+ int height = b_image.size()[1];
+ int channels = b_image.channels();
+
+ unsigned char *image_pixels;
+ image_pixels = image_get_pixels_for_frame(b_image, frame);
+
+ if(image_pixels) {
+ memcpy(pixels, image_pixels, width * height * channels * sizeof(unsigned char));
+ MEM_freeN(image_pixels);
+ }
+ else {
+ if(channels == 1) {
+ memset(pixels, 0, width * height * sizeof(unsigned char));
+ }
+ else {
+ unsigned char *cp = pixels;
+ for(int i = 0; i < width * height; i++, cp += channels) {
+ cp[0] = 255;
+ cp[1] = 0;
+ cp[2] = 255;
+ if(channels == 4)
+ cp[3] = 255;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels)
+{
+ int frame = builtin_image_frame(builtin_name);
+
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID*)builtin_data, &ptr);
+ BL::Image b_image(ptr);
+
+ if(b_image) {
+ int width = b_image.size()[0];
+ int height = b_image.size()[1];
+ int channels = b_image.channels();
+
+ float *image_pixels;
+ image_pixels = image_get_float_pixels_for_frame(b_image, frame);
+
+ if(image_pixels) {
+ memcpy(pixels, image_pixels, width * height * channels * sizeof(float));
+ MEM_freeN(image_pixels);
+ }
+ else {
+ if(channels == 1) {
+ memset(pixels, 0, width * height * sizeof(float));
+ }
+ else {
+ float *fp = pixels;
+ for(int i = 0; i < width * height; i++, fp += channels) {
+ fp[0] = 1.0f;
+ fp[1] = 0.0f;
+ fp[2] = 1.0f;
+ if(channels == 4)
+ fp[3] = 1.0f;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 7f3973ae873..0210df9c044 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -93,6 +93,11 @@ public:
protected:
void do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only);
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
+
+ int builtin_image_frame(const string &builtin_name);
+ void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &channels);
+ bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels);
+ bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index c9380d8d58b..0f7dc15db19 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -173,7 +173,6 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
switch(b_node.type()) {
/* not supported */
- case BL::ShaderNode::type_CURVE_VEC: break;
case BL::ShaderNode::type_GEOMETRY: break;
case BL::ShaderNode::type_MATERIAL: break;
case BL::ShaderNode::type_MATERIAL_EXT: break;
@@ -193,9 +192,18 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
node = proxy;
break;
}
+ case BL::ShaderNode::type_CURVE_VEC: {
+ BL::ShaderNodeVectorCurve b_curve_node(b_node);
+ VectorCurvesNode *curves = new VectorCurvesNode();
+ curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, false);
+ node = curves;
+ break;
+ }
case BL::ShaderNode::type_CURVE_RGB: {
- RGBCurvesNode *ramp = new RGBCurvesNode();
- node = ramp;
+ BL::ShaderNodeRGBCurve b_curve_node(b_node);
+ RGBCurvesNode *curves = new RGBCurvesNode();
+ curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, true);
+ node = curves;
break;
}
case BL::ShaderNode::type_VALTORGB: {
@@ -439,6 +447,10 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
node = new ParticleInfoNode();
break;
}
+ case BL::ShaderNode::type_HAIR_INFO: {
+ node = new HairInfoNode();
+ break;
+ }
case BL::ShaderNode::type_BUMP: {
node = new BumpNode();
break;
@@ -499,9 +511,31 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeTexImage b_image_node(b_node);
BL::Image b_image(b_image_node.image());
ImageTextureNode *image = new ImageTextureNode();
- /* todo: handle generated/builtin images */
- if(b_image && b_image.source() != BL::Image::source_MOVIE) {
- image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current());
+ if(b_image) {
+ /* builtin images will use callback-based reading because
+ * they could only be loaded correct from blender side
+ */
+ bool is_builtin = b_image.packed_file() ||
+ b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE;
+
+ if(is_builtin) {
+ /* for builtin images we're using image datablock name to find an image to
+ * read pixels from later
+ *
+ * also store frame number as well, so there's no differences in handling
+ * builtin names for packed images and movies
+ */
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_image_node.image_user(), scene_frame);
+ image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ image->builtin_data = b_image.ptr.data;
+ }
+ else {
+ image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current());
+ image->builtin_data = NULL;
+ }
+
image->animated = b_image_node.image_user().use_auto_refresh();
}
image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
@@ -515,9 +549,22 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeTexEnvironment b_env_node(b_node);
BL::Image b_image(b_env_node.image());
EnvironmentTextureNode *env = new EnvironmentTextureNode();
- if(b_image && b_image.source() != BL::Image::source_MOVIE) {
- env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current());
- env->animated = b_env_node.image_user().use_auto_refresh();
+ if(b_image) {
+ bool is_builtin = b_image.packed_file() ||
+ b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE;
+
+ if(is_builtin) {
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_env_node.image_user(), scene_frame);
+ env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ env->builtin_data = b_image.ptr.data;
+ }
+ else {
+ env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current());
+ env->animated = b_env_node.image_user().use_auto_refresh();
+ env->builtin_data = NULL;
+ }
}
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index d0e8b508df6..f6ff78ab2ac 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -28,6 +28,7 @@
#include "object.h"
#include "scene.h"
#include "shader.h"
+#include "curves.h"
#include "device.h"
@@ -41,7 +42,7 @@ CCL_NAMESPACE_BEGIN
/* Constructor */
-BlenderSync::BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_, Scene *scene_, bool preview_, Progress &progress_)
+BlenderSync::BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_, Scene *scene_, bool preview_, Progress &progress_, bool is_cpu_)
: b_engine(b_engine_),
b_data(b_data_), b_scene(b_scene_),
shader_map(&scene_->shaders),
@@ -56,6 +57,7 @@ BlenderSync::BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::
{
scene = scene_;
preview = preview_;
+ is_cpu = is_cpu_;
}
BlenderSync::~BlenderSync()
@@ -141,6 +143,7 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const
sync_integrator();
sync_film();
sync_shaders();
+ sync_curve_settings();
sync_objects(b_v3d);
sync_motion(b_v3d, b_override);
}
@@ -289,7 +292,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background)
BL::RenderSettings r = b_scene.render();
SceneParams params;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- int shadingsystem = RNA_enum_get(&cscene, "shading_system");
+ int shadingsystem = RNA_boolean_get(&cscene, "shading_system");
if(shadingsystem == 0)
params.shadingsystem = SceneParams::SVM;
@@ -304,7 +307,10 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background)
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false;
- params.persistent_images = (background)? r.use_persistent_data(): false;
+ if(background && params.shadingsystem != SceneParams::OSL)
+ params.persistent_data = r.use_persistent_data();
+ else
+ params.persistent_data = false;
return params;
}
@@ -331,7 +337,13 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
/* device default CPU */
params.device = devices[0];
- if(RNA_enum_get(&cscene, "device") != 0) {
+ if(RNA_enum_get(&cscene, "device") == 2) {
+ /* find network device */
+ foreach(DeviceInfo& info, devices)
+ if(info.type == DEVICE_NETWORK)
+ params.device = info;
+ }
+ else if(RNA_enum_get(&cscene, "device") == 1) {
/* find GPU device with given id */
PointerRNA systemptr = b_userpref.system().ptr;
PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device");
@@ -350,22 +362,22 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.background = background;
/* samples */
- if(get_boolean(cscene, "progressive")) {
+ if(get_boolean(cscene, "progressive") == 0 && params.device.type == DEVICE_CPU){
if(background) {
- params.samples = get_int(cscene, "samples");
+ params.samples = get_int(cscene, "aa_samples");
}
else {
- params.samples = get_int(cscene, "preview_samples");
+ params.samples = get_int(cscene, "preview_aa_samples");
if(params.samples == 0)
params.samples = INT_MAX;
}
}
else {
if(background) {
- params.samples = get_int(cscene, "aa_samples");
+ params.samples = get_int(cscene, "samples");
}
else {
- params.samples = get_int(cscene, "preview_aa_samples");
+ params.samples = get_int(cscene, "preview_samples");
if(params.samples == 0)
params.samples = INT_MAX;
}
@@ -387,6 +399,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.tile_size = make_int2(tile_x, tile_y);
}
+
+ params.tile_order = RNA_enum_get(&cscene, "tile_order");
params.start_resolution = get_int(cscene, "preview_start_resolution");
@@ -414,7 +428,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.progressive = true;
/* shading system - scene level needs full refresh */
- int shadingsystem = RNA_enum_get(&cscene, "shading_system");
+ int shadingsystem = RNA_boolean_get(&cscene, "shading_system");
if(shadingsystem == 0)
params.shadingsystem = SessionParams::SVM;
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index d3d21fbdf72..5050743f1cf 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -50,7 +50,7 @@ class ShaderNode;
class BlenderSync {
public:
- BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data, BL::Scene b_scene, Scene *scene_, bool preview_, Progress &progress_);
+ BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data, BL::Scene b_scene, Scene *scene_, bool preview_, Progress &progress_, bool is_cpu_);
~BlenderSync();
/* sync */
@@ -78,10 +78,12 @@ private:
void sync_world(bool update_all);
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
void sync_shaders();
+ void sync_curve_settings();
void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
- Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
- Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion);
+ Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris);
+ void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool object_updated);
+ Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, bool hide_tris);
void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm);
void sync_background_light();
void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
@@ -113,6 +115,7 @@ private:
Scene *scene;
bool preview;
bool experimental;
+ bool is_cpu;
struct RenderLayerInfo {
RenderLayerInfo()
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 0a9f2dd06aa..976ed875211 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -33,13 +33,15 @@ extern "C" {
void BLI_timestr(double _time, char *str);
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
+unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
+float *BKE_image_get_float_pixels_for_frame(void *image, int frame);
}
CCL_NAMESPACE_BEGIN
-static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render)
+static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render)
{
- return self.to_mesh(scene, apply_modifiers, (render)? 2: 1);
+ return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, true);
}
static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)
@@ -52,6 +54,36 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size
}
}
+static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *data, int size, bool rgb_curve)
+{
+ cumap.update();
+
+ BL::CurveMap mapR = cumap.curves[0];
+ BL::CurveMap mapG = cumap.curves[1];
+ BL::CurveMap mapB = cumap.curves[2];
+
+ if(rgb_curve) {
+ BL::CurveMap mapI = cumap.curves[3];
+
+ for(int i = 0; i < size; i++) {
+ float t = i/(float)(size-1);
+
+ data[i][0] = mapR.evaluate(mapI.evaluate(t));
+ data[i][1] = mapG.evaluate(mapI.evaluate(t));
+ data[i][2] = mapB.evaluate(mapI.evaluate(t));
+ }
+ }
+ else {
+ for(int i = 0; i < size; i++) {
+ float t = i/(float)(size-1);
+
+ data[i][0] = mapR.evaluate(t);
+ data[i][1] = mapG.evaluate(t);
+ data[i][2] = mapB.evaluate(t);
+ }
+ }
+}
+
static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview)
{
return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
@@ -70,6 +102,22 @@ static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, in
return string(filepath);
}
+static inline int image_user_frame_number(BL::ImageUser iuser, int cfra)
+{
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
+ return iuser.frame_current();
+}
+
+static inline unsigned char *image_get_pixels_for_frame(BL::Image image, int frame)
+{
+ return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
+}
+
+static inline float *image_get_float_pixels_for_frame(BL::Image image, int frame)
+{
+ return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
+}
+
/* Utilities */
static inline Transform get_transform(BL::Array<float, 16> array)
@@ -212,6 +260,20 @@ static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, co
return path;
}
+/* Texture Space */
+
+static inline void mesh_texture_space(BL::Mesh b_mesh, float3& loc, float3& size)
+{
+ loc = get_float3(b_mesh.texspace_location());
+ size = get_float3(b_mesh.texspace_size());
+
+ if(size.x != 0.0f) size.x = 0.5f/size.x;
+ if(size.y != 0.0f) size.y = 0.5f/size.y;
+ if(size.z != 0.0f) size.z = 0.5f/size.z;
+
+ loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+}
+
/* ID Map
*
* Utility class to keep in sync with blender data.
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index b58a34f9942..f11b3c4c0bc 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -18,6 +18,7 @@
#include "mesh.h"
#include "object.h"
#include "scene.h"
+#include "curves.h"
#include "bvh.h"
#include "bvh_build.h"
@@ -29,6 +30,7 @@
#include "util_foreach.h"
#include "util_map.h"
#include "util_progress.h"
+#include "util_system.h"
#include "util_types.h"
CCL_NAMESPACE_BEGIN
@@ -70,11 +72,14 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects)
bool BVH::cache_read(CacheData& key)
{
+ key.add(system_cpu_bits());
key.add(&params, sizeof(params));
foreach(Object *ob, objects) {
key.add(ob->mesh->verts);
key.add(ob->mesh->triangles);
+ key.add(ob->mesh->curve_keys);
+ key.add(ob->mesh->curves);
key.add(&ob->bounds, sizeof(ob->bounds));
key.add(&ob->visibility, sizeof(ob->visibility));
key.add(&ob->mesh->transform_applied, sizeof(bool));
@@ -91,6 +96,7 @@ bool BVH::cache_read(CacheData& key)
value.read(pack.nodes);
value.read(pack.object_node);
value.read(pack.tri_woop);
+ value.read(pack.prim_segment);
value.read(pack.prim_visibility);
value.read(pack.prim_index);
value.read(pack.prim_object);
@@ -112,6 +118,7 @@ void BVH::cache_write(CacheData& key)
value.add(pack.nodes);
value.add(pack.object_node);
value.add(pack.tri_woop);
+ value.add(pack.prim_segment);
value.add(pack.prim_visibility);
value.add(pack.prim_index);
value.add(pack.prim_object);
@@ -157,10 +164,11 @@ void BVH::build(Progress& progress)
}
/* build nodes */
+ vector<int> prim_segment;
vector<int> prim_index;
vector<int> prim_object;
- BVHBuild bvh_build(objects, prim_index, prim_object, params, progress);
+ BVHBuild bvh_build(objects, prim_segment, prim_index, prim_object, params, progress);
BVHNode *root = bvh_build.run();
if(progress.get_cancel()) {
@@ -169,6 +177,7 @@ void BVH::build(Progress& progress)
}
/* todo: get rid of this copy */
+ pack.prim_segment = prim_segment;
pack.prim_index = prim_index;
pack.prim_object = prim_object;
@@ -182,8 +191,8 @@ void BVH::build(Progress& progress)
}
/* pack triangles */
- progress.set_substatus("Packing BVH triangles");
- pack_triangles();
+ progress.set_substatus("Packing BVH triangles and strands");
+ pack_primitives();
if(progress.get_cancel()) {
root->deleteSubtree();
@@ -215,8 +224,8 @@ void BVH::build(Progress& progress)
void BVH::refit(Progress& progress)
{
- progress.set_substatus("Packing BVH triangles");
- pack_triangles();
+ progress.set_substatus("Packing BVH primitives");
+ pack_primitives();
if(progress.get_cancel()) return;
@@ -263,7 +272,52 @@ void BVH::pack_triangle(int idx, float4 woop[3])
}
}
-void BVH::pack_triangles()
+/* 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 = pack.prim_segment[idx];
+ int k0 = mesh->curves[tidx].first_key + segment;
+ int k1 = mesh->curves[tidx].first_key + segment + 1;
+ float3 v0 = mesh->curve_keys[k0].co;
+ float3 v1 = mesh->curve_keys[k1].co;
+
+ 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);
+ */
+ Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
+ float3 tg0 = make_float3(1.0f, 0.0f, 0.0f);
+ float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
+
+ if(attr_tangent) {
+ const float3 *data_tangent = attr_tangent->data_float3();
+
+ tg0 = data_tangent[k0];
+ tg1 = data_tangent[k1];
+ }
+
+ 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;
size_t tidx_size = pack.prim_index.size();
@@ -277,13 +331,21 @@ void BVH::pack_triangles()
if(pack.prim_index[i] != -1) {
float4 woop[3];
- pack_triangle(i, woop);
+ if(pack.prim_segment[i] != ~0)
+ pack_curve_segment(i, woop);
+ else
+ pack_triangle(i, woop);
+
memcpy(&pack.tri_woop[i * nsize], woop, sizeof(float4)*3);
int tob = pack.prim_object[i];
Object *ob = objects[tob];
pack.prim_visibility[i] = ob->visibility;
}
+ else {
+ memset(&pack.tri_woop[i * nsize], 0, sizeof(float4)*3);
+ pack.prim_visibility[i] = 0;
+ }
}
}
@@ -300,11 +362,15 @@ void BVH::pack_instances(size_t nodes_size)
/* adjust primitive index to point to the triangle in the global array, for
* meshes with transform applied and already in the top level BVH */
for(size_t i = 0; i < pack.prim_index.size(); i++)
- if(pack.prim_index[i] != -1)
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ if(pack.prim_index[i] != -1) {
+ if(pack.prim_segment[i] != ~0)
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
+ else
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ }
/* track offsets of instanced BVH data in global array */
- size_t tri_offset = pack.prim_index.size();
+ size_t prim_offset = pack.prim_index.size();
size_t nodes_offset = nodes_size;
/* clear array that gives the node indexes for instanced objects */
@@ -339,6 +405,7 @@ void BVH::pack_instances(size_t nodes_size)
mesh_map.clear();
pack.prim_index.resize(prim_index_size);
+ pack.prim_segment.resize(prim_index_size);
pack.prim_object.resize(prim_index_size);
pack.prim_visibility.resize(prim_index_size);
pack.tri_woop.resize(tri_woop_size);
@@ -346,6 +413,7 @@ void BVH::pack_instances(size_t nodes_size)
pack.object_node.resize(objects.size());
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
+ int *pack_prim_segment = (pack.prim_segment.size())? &pack.prim_segment[0]: NULL;
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
float4 *pack_tri_woop = (pack.tri_woop.size())? &pack.tri_woop[0]: NULL;
@@ -376,6 +444,7 @@ void BVH::pack_instances(size_t nodes_size)
int noffset = nodes_offset/nsize;
int mesh_tri_offset = mesh->tri_offset;
+ int mesh_curve_offset = mesh->curve_offset;
/* fill in node indexes for instances */
if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
@@ -389,10 +458,16 @@ void BVH::pack_instances(size_t nodes_size)
if(bvh->pack.prim_index.size()) {
size_t bvh_prim_index_size = bvh->pack.prim_index.size();
int *bvh_prim_index = &bvh->pack.prim_index[0];
+ int *bvh_prim_segment = &bvh->pack.prim_segment[0];
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
for(size_t i = 0; i < bvh_prim_index_size; i++) {
- pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
+ if(bvh->pack.prim_segment[i] != ~0)
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
+ else
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
+
+ pack_prim_segment[pack_prim_index_offset] = bvh_prim_segment[i];
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
pack_prim_index_offset++;
@@ -401,13 +476,13 @@ void BVH::pack_instances(size_t nodes_size)
/* merge triangle intersection data */
if(bvh->pack.tri_woop.size()) {
- memcpy(pack_tri_woop+pack_tri_woop_offset, &bvh->pack.tri_woop[0],
+ memcpy(pack_tri_woop + pack_tri_woop_offset, &bvh->pack.tri_woop[0],
bvh->pack.tri_woop.size()*sizeof(float4));
pack_tri_woop_offset += bvh->pack.tri_woop.size();
}
/* merge nodes */
- if( bvh->pack.nodes.size()) {
+ if(bvh->pack.nodes.size()) {
size_t nsize_bbox = (use_qbvh)? nsize-2: nsize-1;
int4 *bvh_nodes = &bvh->pack.nodes[0];
size_t bvh_nodes_size = bvh->pack.nodes.size();
@@ -420,8 +495,8 @@ void BVH::pack_instances(size_t nodes_size)
int4 data = bvh_nodes[i + nsize_bbox];
if(bvh_is_leaf && bvh_is_leaf[j]) {
- data.x += tri_offset;
- data.y += tri_offset;
+ data.x += prim_offset;
+ data.y += prim_offset;
}
else {
data.x += (data.x < 0)? -noffset: noffset;
@@ -443,7 +518,7 @@ void BVH::pack_instances(size_t nodes_size)
}
nodes_offset += bvh->pack.nodes.size();
- tri_offset += bvh->pack.prim_index.size();
+ prim_offset += bvh->pack.prim_index.size();
}
}
@@ -544,25 +619,49 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
if(leaf) {
/* refit leaf node */
- for(int tri = c0; tri < c1; tri++) {
- int tidx = pack.prim_index[tri];
- int tob = pack.prim_object[tri];
+ for(int prim = c0; prim < c1; prim++) {
+ int pidx = pack.prim_index[prim];
+ int tob = pack.prim_object[prim];
Object *ob = objects[tob];
- if(tidx == -1) {
+ if(pidx == -1) {
/* object instance */
bbox.grow(ob->bounds);
}
else {
- /* triangles */
+ /* primitives */
const Mesh *mesh = ob->mesh;
- int tri_offset = (params.top_level)? mesh->tri_offset: 0;
- const int *vidx = mesh->triangles[tidx - tri_offset].v;
- const float3 *vpos = &mesh->verts[0];
- bbox.grow(vpos[vidx[0]]);
- bbox.grow(vpos[vidx[1]]);
- bbox.grow(vpos[vidx[2]]);
+ if(pack.prim_segment[prim] != ~0) {
+ /* curves */
+ int str_offset = (params.top_level)? mesh->curve_offset: 0;
+ int k0 = mesh->curves[pidx - str_offset].first_key + pack.prim_segment[prim]; // XXX!
+ int k1 = k0 + 1;
+
+ float3 p[4];
+ p[0] = mesh->curve_keys[max(k0 - 1,mesh->curves[pidx - str_offset].first_key)].co;
+ p[1] = mesh->curve_keys[k0].co;
+ p[2] = mesh->curve_keys[k1].co;
+ p[3] = mesh->curve_keys[min(k1 + 1,mesh->curves[pidx - str_offset].first_key + mesh->curves[pidx - str_offset].num_keys - 1)].co;
+ float3 lower;
+ float3 upper;
+ curvebounds(&lower.x, &upper.x, p, 0);
+ curvebounds(&lower.y, &upper.y, p, 1);
+ curvebounds(&lower.z, &upper.z, p, 2);
+ float mr = max(mesh->curve_keys[k0].radius,mesh->curve_keys[k1].radius);
+ bbox.grow(lower, mr);
+ bbox.grow(upper, mr);
+ }
+ else {
+ /* triangles */
+ int tri_offset = (params.top_level)? mesh->tri_offset: 0;
+ const int *vidx = mesh->triangles[pidx - tri_offset].v;
+ const float3 *vpos = &mesh->verts[0];
+
+ bbox.grow(vpos[vidx[0]]);
+ bbox.grow(vpos[vidx[1]]);
+ bbox.grow(vpos[vidx[2]]);
+ }
}
visibility |= ob->visibility;
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 549f1e3ac1d..00c146143b8 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -51,7 +51,9 @@ struct PackedBVH {
/* object index to BVH node index mapping for instances */
array<int> object_node;
/* precomputed triangle intersection data, one triangle is 4x float4 */
- array<float4> tri_woop;
+ array<float4> tri_woop;
+ /* primitive type - triangle or strand (should be moved to flag?) */
+ array<int> prim_segment;
/* visibility visibilitys for primitives */
array<uint> prim_visibility;
/* mapping from BVH primitive index to true primitive index, as primitives
@@ -101,9 +103,10 @@ protected:
bool cache_read(CacheData& key);
void cache_write(CacheData& key);
- /* triangles */
- void pack_triangles();
+ /* 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);
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 705b805a3a9..022c4c8d294 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -24,6 +24,7 @@
#include "mesh.h"
#include "object.h"
#include "scene.h"
+#include "curves.h"
#include "util_debug.h"
#include "util_foreach.h"
@@ -48,9 +49,10 @@ public:
/* Constructor / Destructor */
BVHBuild::BVHBuild(const vector<Object*>& objects_,
- vector<int>& prim_index_, vector<int>& prim_object_,
+ vector<int>& prim_segment_, vector<int>& prim_index_, vector<int>& prim_object_,
const BVHParams& params_, Progress& progress_)
: objects(objects_),
+ prim_segment(prim_segment_),
prim_index(prim_index_),
prim_object(prim_object_),
params(params_),
@@ -73,25 +75,64 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
BoundBox bounds = BoundBox::empty;
for(int k = 0; k < 3; k++) {
- float3 pt = mesh->verts[t.v[k]];
- bounds.grow(pt);
+ float3 co = mesh->verts[t.v[k]];
+ bounds.grow(co);
}
if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i));
+ references.push_back(BVHReference(bounds, j, i, ~0));
root.grow(bounds);
center.grow(bounds.center2());
}
}
+
+ for(uint j = 0; j < mesh->curves.size(); j++) {
+ Mesh::Curve curve = mesh->curves[j];
+
+ for(int k = 0; k < curve.num_keys - 1; k++) {
+ BoundBox bounds = BoundBox::empty;
+
+ float3 co[4];
+ co[0] = mesh->curve_keys[max(curve.first_key + k - 1,curve.first_key)].co;
+ co[1] = mesh->curve_keys[curve.first_key + k].co;
+ co[2] = mesh->curve_keys[curve.first_key + k + 1].co;
+ co[3] = mesh->curve_keys[min(curve.first_key + k + 2, curve.first_key + curve.num_keys - 1)].co;
+
+ float3 lower;
+ float3 upper;
+ curvebounds(&lower.x, &upper.x, co, 0);
+ curvebounds(&lower.y, &upper.y, co, 1);
+ curvebounds(&lower.z, &upper.z, co, 2);
+ float mr = max(mesh->curve_keys[curve.first_key + k].radius, mesh->curve_keys[curve.first_key + k + 1].radius);
+ bounds.grow(lower, mr);
+ bounds.grow(upper, mr);
+
+ if(bounds.valid()) {
+ references.push_back(BVHReference(bounds, j, i, k));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ }
}
void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i)
{
- references.push_back(BVHReference(ob->bounds, -1, i));
+ references.push_back(BVHReference(ob->bounds, -1, i, false));
root.grow(ob->bounds);
center.grow(ob->bounds.center2());
}
+static size_t count_curve_segments(Mesh *mesh)
+{
+ size_t num = 0, num_curves = mesh->curves.size();
+
+ for(size_t i = 0; i < num_curves; i++)
+ num += mesh->curves[i].num_keys - 1;
+
+ return num;
+}
+
void BVHBuild::add_references(BVHRange& root)
{
/* reserve space for references */
@@ -99,13 +140,17 @@ void BVHBuild::add_references(BVHRange& root)
foreach(Object *ob, objects) {
if(params.top_level) {
- if(ob->mesh->transform_applied)
+ if(ob->mesh->transform_applied) {
num_alloc_references += ob->mesh->triangles.size();
+ num_alloc_references += count_curve_segments(ob->mesh);
+ }
else
num_alloc_references++;
}
- else
+ else {
num_alloc_references += ob->mesh->triangles.size();
+ num_alloc_references += count_curve_segments(ob->mesh);
+ }
}
references.reserve(num_alloc_references);
@@ -162,6 +207,7 @@ BVHNode* BVHBuild::run()
progress_total = references.size();
progress_original_total = progress_total;
+ prim_segment.resize(references.size());
prim_index.resize(references.size());
prim_object.resize(references.size());
@@ -319,10 +365,12 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
if(start == prim_index.size()) {
assert(params.use_spatial_split);
+ prim_segment.push_back(ref->prim_segment());
prim_index.push_back(ref->prim_index());
prim_object.push_back(ref->prim_object());
}
else {
+ prim_segment[start] = ref->prim_segment();
prim_index[start] = ref->prim_index();
prim_object[start] = ref->prim_object();
}
@@ -345,6 +393,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
{
+ vector<int>& p_segment = prim_segment;
vector<int>& p_index = prim_index;
vector<int>& p_object = prim_object;
BoundBox bounds = BoundBox::empty;
@@ -358,10 +407,12 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
if(range.start() + num == prim_index.size()) {
assert(params.use_spatial_split);
+ p_segment.push_back(ref.prim_segment());
p_index.push_back(ref.prim_index());
p_object.push_back(ref.prim_object());
}
else {
+ p_segment[range.start() + num] = ref.prim_segment();
p_index[range.start() + num] = ref.prim_index();
p_object[range.start() + num] = ref.prim_object();
}
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index 44ef918b326..3df4da1739a 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -44,6 +44,7 @@ public:
/* Constructor/Destructor */
BVHBuild(
const vector<Object*>& objects,
+ vector<int>& prim_segment,
vector<int>& prim_index,
vector<int>& prim_object,
const BVHParams& params,
@@ -87,6 +88,7 @@ protected:
int num_original_references;
/* output primitive indexes and objects */
+ vector<int>& prim_segment;
vector<int>& prim_index;
vector<int>& prim_object;
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index a78496d841d..f7bc79f71e6 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -98,19 +98,22 @@ class BVHReference
public:
__forceinline BVHReference() {}
- __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_)
+ __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_segment)
: rbounds(bounds_)
{
rbounds.min.w = __int_as_float(prim_index_);
rbounds.max.w = __int_as_float(prim_object_);
+ segment = prim_segment;
}
__forceinline const BoundBox& bounds() const { return rbounds; }
__forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
__forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
+ __forceinline int prim_segment() const { return segment; }
protected:
BoundBox rbounds;
+ uint segment;
};
/* BVH Range
diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp
index bef384be592..91994be5b96 100644
--- a/intern/cycles/bvh/bvh_sort.cpp
+++ b/intern/cycles/bvh/bvh_sort.cpp
@@ -43,6 +43,8 @@ public:
else if(ra.prim_object() > rb.prim_object()) return false;
else if(ra.prim_index() < rb.prim_index()) return true;
else if(ra.prim_index() > rb.prim_index()) return false;
+ else if(ra.prim_segment() < rb.prim_segment()) return true;
+ else if(ra.prim_segment() > rb.prim_segment()) return false;
return false;
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 263c5834428..03ff69d7b6d 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -252,14 +252,41 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
/* loop over vertices/edges. */
Object *ob = builder->objects[ref.prim_object()];
const Mesh *mesh = ob->mesh;
- const int *inds = mesh->triangles[ref.prim_index()].v;
- const float3 *verts = &mesh->verts[0];
- const float3* v1 = &verts[inds[2]];
-
- for(int i = 0; i < 3; i++) {
- const float3* v0 = v1;
- int vindex = inds[i];
- v1 = &verts[vindex];
+
+ if (ref.prim_segment() == ~0) {
+ const int *inds = mesh->triangles[ref.prim_index()].v;
+ const float3 *verts = &mesh->verts[0];
+ const float3* v1 = &verts[inds[2]];
+
+ for(int i = 0; i < 3; i++) {
+ const float3* v0 = v1;
+ int vindex = inds[i];
+ v1 = &verts[vindex];
+ float v0p = (*v0)[dim];
+ float v1p = (*v1)[dim];
+
+ /* insert vertex to the boxes it belongs to. */
+ if(v0p <= pos)
+ left_bounds.grow(*v0);
+
+ if(v0p >= pos)
+ right_bounds.grow(*v0);
+
+ /* edge intersects the plane => insert intersection to both boxes. */
+ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
+ float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ left_bounds.grow(t);
+ right_bounds.grow(t);
+ }
+ }
+ }
+ else {
+ /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
+ const int k0 = mesh->curves[ref.prim_index()].first_key + ref.prim_segment();
+ const int k1 = k0 + 1;
+ const float3* v0 = &mesh->curve_keys[k0].co;
+ const float3* v1 = &mesh->curve_keys[k1].co;
+
float v0p = (*v0)[dim];
float v1p = (*v1)[dim];
@@ -270,6 +297,12 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
if(v0p >= pos)
right_bounds.grow(*v0);
+ if(v1p <= pos)
+ left_bounds.grow(*v1);
+
+ if(v1p >= pos)
+ right_bounds.grow(*v1);
+
/* edge intersects the plane => insert intersection to both boxes. */
if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
@@ -284,9 +317,9 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
left_bounds.intersect(ref.bounds());
right_bounds.intersect(ref.bounds());
- /* set referecnes */
- left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object());
- right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object());
+ /* set references */
+ left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
+ right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 0071bbe5cdc..fe2368b7ea8 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -18,11 +18,16 @@ set(SRC
device_cpu.cpp
device_cuda.cpp
device_multi.cpp
- device_network.cpp
device_opencl.cpp
device_task.cpp
)
+if(WITH_NETWORK)
+ list(APPEND SRC
+ device_network.cpp
+ )
+endif()
+
set(SRC_HEADERS
device.h
device_memory.h
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 9840687b76a..7b31b9ba157 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -84,6 +84,7 @@ public:
/* info */
DeviceInfo info;
virtual const string& error_message() { return error_msg; }
+ bool have_error() { return !error_message().empty(); }
/* statistics */
Stats &stats;
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index a1d7706a34e..47f3273fdfa 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -58,7 +58,8 @@ public:
#endif
/* do now to avoid thread issues */
- system_cpu_support_optimized();
+ system_cpu_support_sse2();
+ system_cpu_support_sse3();
}
~CPUDevice()
@@ -66,11 +67,6 @@ public:
task_pool.stop();
}
- bool support_advanced_shading()
- {
- return true;
- }
-
void mem_alloc(device_memory& mem, MemoryType type)
{
mem.device_pointer = mem.data_pointer;
@@ -170,7 +166,26 @@ public:
int end_sample = tile.start_sample + tile.num_samples;
#ifdef WITH_OPTIMIZED_KERNEL
- if(system_cpu_support_optimized()) {
+ if(system_cpu_support_sse3()) {
+ for(int sample = start_sample; sample < end_sample; sample++) {
+ if (task.get_cancel() || task_pool.cancelled()) {
+ 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_sse2()) {
for(int sample = start_sample; sample < end_sample; sample++) {
if (task.get_cancel() || task_pool.cancelled()) {
if(task.need_finish_queue == false)
@@ -179,7 +194,7 @@ public:
for(int y = tile.y; y < tile.y + tile.h; y++) {
for(int x = tile.x; x < tile.x + tile.w; x++) {
- kernel_cpu_optimized_path_trace(&kg, render_buffer, rng_state,
+ kernel_cpu_sse2_path_trace(&kg, render_buffer, rng_state,
sample, x, y, tile.offset, tile.stride);
}
}
@@ -227,10 +242,16 @@ public:
void thread_tonemap(DeviceTask& task)
{
#ifdef WITH_OPTIMIZED_KERNEL
- if(system_cpu_support_optimized()) {
+ 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_optimized_tonemap(&kernel_globals, (uchar4*)task.rgba, (float*)task.buffer,
+ kernel_cpu_sse3_tonemap(&kernel_globals, (uchar4*)task.rgba, (float*)task.buffer,
+ task.sample, task.resolution, x, y, task.offset, task.stride);
+ }
+ else 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_tonemap(&kernel_globals, (uchar4*)task.rgba, (float*)task.buffer,
task.sample, task.resolution, x, y, task.offset, task.stride);
}
else
@@ -252,9 +273,17 @@ public:
#endif
#ifdef WITH_OPTIMIZED_KERNEL
- if(system_cpu_support_optimized()) {
+ if(system_cpu_support_sse3()) {
+ 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);
+
+ if(task_pool.cancelled())
+ break;
+ }
+ }
+ else if(system_cpu_support_sse2()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
- kernel_cpu_optimized_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
+ kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
if(task_pool.cancelled())
break;
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 14f8cfa8767..173ac3d57df 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -109,11 +109,11 @@ public:
}
}
-#ifdef NDEBUG
+/*#ifdef NDEBUG
#define cuda_abort()
#else
#define cuda_abort() abort()
-#endif
+#endif*/
#define cuda_assert(stmt) \
{ \
@@ -124,23 +124,25 @@ public:
if(error_msg == "") \
error_msg = message; \
fprintf(stderr, "%s\n", message.c_str()); \
- cuda_abort(); \
+ /*cuda_abort();*/ \
} \
}
- bool cuda_error(CUresult result)
+ bool cuda_error_(CUresult result, const string& stmt)
{
if(result == CUDA_SUCCESS)
return false;
- string message = string_printf("CUDA error: %s", cuda_error_string(result));
+ string message = string_printf("CUDA error at %s: %s", stmt.c_str(), cuda_error_string(result));
if(error_msg == "")
error_msg = message;
fprintf(stderr, "%s\n", message.c_str());
return true;
}
- void cuda_error(const string& message)
+#define cuda_error(stmt) cuda_error_(stmt, #stmt)
+
+ void cuda_error_message(const string& message)
{
if(error_msg == "")
error_msg = message;
@@ -187,7 +189,7 @@ public:
}
}
- if(cuda_error(result))
+ if(cuda_error_(result, "cuCtxCreate"))
return;
cuda_pop_context();
@@ -207,8 +209,8 @@ public:
int major, minor;
cuDeviceComputeCapability(&major, &minor, cuDevId);
- if(major <= 1 && minor <= 2) {
- cuda_error(string_printf("CUDA device supported only with compute capability 1.3 or up, found %d.%d.", major, minor));
+ if(major <= 1 && minor <= 3) {
+ cuda_error_message(string_printf("CUDA device supported only with compute capability 2.0 or up, found %d.%d.", major, minor));
return false;
}
}
@@ -238,18 +240,21 @@ public:
if(path_exists(cubin))
return cubin;
-#if defined(WITH_CUDA_BINARIES) && defined(_WIN32)
- if(major <= 1 && minor <= 2)
- cuda_error(string_printf("CUDA device supported only compute capability 1.3 or up, found %d.%d.", major, minor));
- else
- cuda_error(string_printf("CUDA binary kernel for this graphics card compute capability (%d.%d) not found.", major, minor));
- return "";
-#else
+#ifdef _WIN32
+ if(cuHavePrecompiledKernels()) {
+ if(major <= 1 && minor <= 3)
+ cuda_error_message(string_printf("CUDA device requires compute capability 2.0 or up, found %d.%d. Your GPU is not supported.", major, minor));
+ else
+ cuda_error_message(string_printf("CUDA binary kernel for this graphics card compute capability (%d.%d) not found.", major, minor));
+ return "";
+ }
+#endif
+
/* if not, find CUDA compiler */
string nvcc = cuCompilerPath();
if(nvcc == "") {
- cuda_error("CUDA nvcc compiler not found. Install CUDA toolkit in default location.");
+ cuda_error_message("CUDA nvcc compiler not found. Install CUDA toolkit in default location.");
return "";
}
@@ -269,20 +274,19 @@ public:
nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str());
if(system(command.c_str()) == -1) {
- cuda_error("Failed to execute compilation command, see console for details.");
+ cuda_error_message("Failed to execute compilation command, see console for details.");
return "";
}
/* verify if compilation succeeded */
if(!path_exists(cubin)) {
- cuda_error("CUDA kernel compilation failed, see console for details.");
+ cuda_error_message("CUDA kernel compilation failed, see console for details.");
return "";
}
printf("Kernel compilation finished in %.2lfs.\n", time_dt() - starttime);
return cubin;
-#endif
}
bool load_kernels(bool experimental)
@@ -304,8 +308,8 @@ public:
cuda_push_context();
CUresult result = cuModuleLoad(&cuModule, cubin.c_str());
- if(cuda_error(result))
- cuda_error(string_printf("Failed loading CUDA kernel %s.", cubin.c_str()));
+ if(cuda_error_(result, "cuModuleLoad"))
+ cuda_error_message(string_printf("Failed loading CUDA kernel %s.", cubin.c_str()));
cuda_pop_context();
@@ -326,7 +330,8 @@ public:
void mem_copy_to(device_memory& mem)
{
cuda_push_context();
- cuda_assert(cuMemcpyHtoD(cuda_device_ptr(mem.device_pointer), (void*)mem.data_pointer, mem.memory_size()))
+ if(mem.device_pointer)
+ cuda_assert(cuMemcpyHtoD(cuda_device_ptr(mem.device_pointer), (void*)mem.data_pointer, mem.memory_size()))
cuda_pop_context();
}
@@ -336,8 +341,13 @@ public:
size_t size = elem*w*h;
cuda_push_context();
- cuda_assert(cuMemcpyDtoH((uchar*)mem.data_pointer + offset,
- (CUdeviceptr)((uchar*)mem.device_pointer + offset), size))
+ if(mem.device_pointer) {
+ cuda_assert(cuMemcpyDtoH((uchar*)mem.data_pointer + offset,
+ (CUdeviceptr)((uchar*)mem.device_pointer + offset), size))
+ }
+ else {
+ memset((char*)mem.data_pointer + offset, 0, size);
+ }
cuda_pop_context();
}
@@ -346,7 +356,8 @@ public:
memset((void*)mem.data_pointer, 0, mem.memory_size());
cuda_push_context();
- cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()))
+ if(mem.device_pointer)
+ cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()))
cuda_pop_context();
}
@@ -390,13 +401,18 @@ public:
default: assert(0); return;
}
- CUtexref texref;
+ CUtexref texref = NULL;
cuda_push_context();
cuda_assert(cuModuleGetTexRef(&texref, cuModule, name))
+ if(!texref) {
+ cuda_pop_context();
+ return;
+ }
+
if(interpolation) {
- CUarray handle;
+ CUarray handle = NULL;
CUDA_ARRAY_DESCRIPTOR desc;
desc.Width = mem.data_width;
@@ -406,6 +422,11 @@ public:
cuda_assert(cuArrayCreate(&handle, &desc))
+ if(!handle) {
+ cuda_pop_context();
+ return;
+ }
+
if(mem.data_height > 1) {
CUDA_MEMCPY2D param;
memset(&param, 0, sizeof(param));
@@ -481,6 +502,9 @@ public:
void path_trace(RenderTile& rtile, int sample)
{
+ if(have_error())
+ return;
+
cuda_push_context();
CUfunction cuPathTrace;
@@ -546,6 +570,9 @@ public:
void tonemap(DeviceTask& task, device_ptr buffer, device_ptr rgba)
{
+ if(have_error())
+ return;
+
cuda_push_context();
CUfunction cuFilmConvert;
@@ -615,6 +642,9 @@ public:
void shader(DeviceTask& task)
{
+ if(have_error())
+ return;
+
cuda_push_context();
CUfunction cuDisplace;
@@ -709,7 +739,7 @@ public:
CUresult result = cuGraphicsGLRegisterBuffer(&pmem.cuPBOresource, pmem.cuPBO, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
- if(!cuda_error(result)) {
+ if(result == CUDA_SUCCESS) {
cuda_pop_context();
mem.device_pointer = pmem.cuTexId;
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index a5e0d39df73..201f04bc5d8 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -31,6 +31,8 @@ class NetworkDevice : public Device
public:
boost::asio::io_service io_service;
tcp::socket socket;
+ device_ptr mem_counter;
+ DeviceTask the_task; /* todo: handle multiple tasks */
NetworkDevice(Stats &stats, const char *address)
: Device(stats), socket(io_service)
@@ -49,75 +51,72 @@ public:
socket.close();
socket.connect(*endpoint_iterator++, error);
}
+
if(error)
throw boost::system::system_error(error);
+
+ mem_counter = 0;
}
~NetworkDevice()
{
+ RPCSend snd(socket, "stop");
+ snd.write();
}
void mem_alloc(device_memory& mem, MemoryType type)
{
-#if 0
+ mem.device_pointer = ++mem_counter;
+
RPCSend snd(socket, "mem_alloc");
- snd.archive & size & type;
+ snd.add(mem);
+ snd.add(type);
snd.write();
-
- RPCReceive rcv(socket);
-
- device_ptr mem;
- *rcv.archive & mem;
-
- return mem;
-#endif
}
void mem_copy_to(device_memory& mem)
{
-#if 0
RPCSend snd(socket, "mem_copy_to");
- snd.archive & mem & size;
+ snd.add(mem);
snd.write();
- snd.write_buffer(host, size);
-#endif
+ snd.write_buffer((void*)mem.data_pointer, mem.memory_size());
}
void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
-#if 0
RPCSend snd(socket, "mem_copy_from");
- snd.archive & mem & offset & size;
+ snd.add(mem);
+ snd.add(y);
+ snd.add(w);
+ snd.add(h);
+ snd.add(elem);
snd.write();
RPCReceive rcv(socket);
- rcv.read_buffer(host, size);
-#endif
+ rcv.read_buffer((void*)mem.data_pointer, mem.memory_size());
}
void mem_zero(device_memory& mem)
{
-#if 0
RPCSend snd(socket, "mem_zero");
- snd.archive & mem & size;
+ snd.add(mem);
snd.write();
-#endif
}
void mem_free(device_memory& mem)
{
-#if 0
- if(mem) {
+ if(mem.device_pointer) {
RPCSend snd(socket, "mem_free");
- snd.archive & mem;
+ snd.add(mem);
snd.write();
+
+ mem.device_pointer = 0;
}
-#endif
}
void const_copy_to(const char *name, void *host, size_t size)
@@ -126,79 +125,102 @@ public:
string name_string(name);
- snd.archive & name_string & size;
+ snd.add(name_string);
+ snd.add(size);
snd.write();
snd.write_buffer(host, size);
}
void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
{
-#if 0
+ mem.device_pointer = ++mem_counter;
+
RPCSend snd(socket, "tex_alloc");
string name_string(name);
- snd.archive & name_string & width & height & datatype & components & interpolation;
+ snd.add(name_string);
+ snd.add(mem);
+ snd.add(interpolation);
+ snd.add(periodic);
snd.write();
-
- size_t size = width*height*components*datatype_size(datatype);
- snd.write_buffer(host, size);
-
- RPCReceive rcv(socket);
-
- device_ptr mem;
- *rcv.archive & mem;
-
- return mem;
-#endif
+ snd.write_buffer((void*)mem.data_pointer, mem.memory_size());
}
void tex_free(device_memory& mem)
{
-#if 0
- if(mem) {
+ if(mem.device_pointer) {
RPCSend snd(socket, "tex_free");
- snd.archive & mem;
+ snd.add(mem);
snd.write();
+
+ mem.device_pointer = 0;
}
-#endif
}
- void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int sample)
+ void task_add(DeviceTask& task)
{
-#if 0
- RPCSend snd(socket, "path_trace");
+ the_task = task;
- snd.archive & x & y & w & h & buffer & rng_state & sample;
+ RPCSend snd(socket, "task_add");
+ snd.add(task);
snd.write();
-#endif
}
- void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int sample, int resolution)
+ void task_wait()
{
-#if 0
- RPCSend snd(socket, "tonemap");
-
- snd.archive & x & y & w & h & rgba & buffer & sample & resolution;
+ RPCSend snd(socket, "task_wait");
snd.write();
-#endif
- }
- void task_add(DeviceTask& task)
- {
- if(task.type == DeviceTask::TONEMAP)
- tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.sample, task.resolution);
- else if(task.type == DeviceTask::PATH_TRACE)
- path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.sample);
- }
+ list<RenderTile> the_tiles;
- void task_wait()
- {
+ /* todo: run this threaded for connecting to multiple clients */
+ for(;;) {
+ RPCReceive rcv(socket);
+ RenderTile tile;
+
+ if(rcv.name == "acquire_tile") {
+ /* todo: watch out for recursive calls! */
+ if(the_task.acquire_tile(this, tile)) { /* write return as bool */
+ the_tiles.push_back(tile);
+
+ RPCSend snd(socket, "acquire_tile");
+ snd.add(tile);
+ snd.write();
+ }
+ else {
+ RPCSend snd(socket, "acquire_tile_none");
+ snd.write();
+ }
+ }
+ else if(rcv.name == "release_tile") {
+ rcv.read(tile);
+
+ for(list<RenderTile>::iterator it = the_tiles.begin(); it != the_tiles.end(); it++) {
+ if(tile.x == it->x && tile.y == it->y && tile.start_sample == it->start_sample) {
+ tile.buffers = it->buffers;
+ the_tiles.erase(it);
+ break;
+ }
+ }
+
+ assert(tile.buffers != NULL);
+
+ the_task.release_tile(tile);
+
+ RPCSend snd(socket, "release_tile");
+ snd.write();
+ }
+ else if(rcv.name == "task_wait_done")
+ break;
+ }
}
void task_cancel()
{
+ RPCSend snd(socket, "task_cancel");
+ snd.write();
}
};
@@ -215,166 +237,309 @@ void device_network_info(vector<DeviceInfo>& devices)
info.description = "Network Device";
info.id = "NETWORK";
info.num = 0;
+ info.advanced_shading = true; /* todo: get this info from device */
+ info.pack_images = false;
devices.push_back(info);
}
-void Device::server_run()
-{
- try
+class DeviceServer {
+public:
+ DeviceServer(Device *device_, tcp::socket& socket_)
+ : device(device_), socket(socket_)
{
- /* starts thread that responds to discovery requests */
- ServerDiscovery discovery;
+ }
- for(;;)
- {
+ void listen()
+ {
+ /* receive remote function calls */
+ for(;;) {
+ RPCReceive rcv(socket);
- /* accept connection */
- boost::asio::io_service io_service;
- tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
+ if(rcv.name == "stop")
+ break;
- tcp::socket socket(io_service);
- acceptor.accept(socket);
+ process(rcv);
+ }
+ }
- /* receive remote function calls */
- for(;;) {
- RPCReceive rcv(socket);
+protected:
+ void process(RPCReceive& rcv)
+ {
+ // fprintf(stderr, "receive process %s\n", rcv.name.c_str());
- if(rcv.name == "description") {
- string desc = description();
+ if(rcv.name == "mem_alloc") {
+ MemoryType type;
+ network_device_memory mem;
+ device_ptr remote_pointer;
- RPCSend snd(socket);
- snd.archive & desc;
- snd.write();
- }
- else if(rcv.name == "mem_alloc") {
-#if 0
- MemoryType type;
- size_t size;
- device_ptr mem;
+ rcv.read(mem);
+ rcv.read(type);
- *rcv.archive & size & type;
- mem = mem_alloc(size, type);
+ /* todo: CPU needs mem.data_pointer */
- RPCSend snd(socket);
- snd.archive & mem;
- snd.write();
-#endif
- }
- else if(rcv.name == "mem_copy_to") {
-#if 0
- device_ptr mem;
- size_t size;
+ remote_pointer = mem.device_pointer;
- *rcv.archive & mem & size;
+ mem_data[remote_pointer] = vector<uint8_t>();
+ mem_data[remote_pointer].resize(mem.memory_size());
+ if(mem.memory_size())
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ else
+ mem.data_pointer = 0;
- vector<char> host_vector(size);
- rcv.read_buffer(&host_vector[0], size);
+ device->mem_alloc(mem, type);
- mem_copy_to(mem, &host_vector[0], size);
-#endif
- }
- else if(rcv.name == "mem_copy_from") {
-#if 0
- device_ptr mem;
- size_t offset, size;
+ ptr_map[remote_pointer] = mem.device_pointer;
+ ptr_imap[mem.device_pointer] = remote_pointer;
+ }
+ else if(rcv.name == "mem_copy_to") {
+ network_device_memory mem;
- *rcv.archive & mem & offset & size;
+ rcv.read(mem);
- vector<char> host_vector(size);
+ device_ptr remote_pointer = mem.device_pointer;
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
- mem_copy_from(&host_vector[0], mem, offset, size);
+ rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
- RPCSend snd(socket);
- snd.write();
- snd.write_buffer(&host_vector[0], size);
-#endif
- }
- else if(rcv.name == "mem_zero") {
-#if 0
- device_ptr mem;
- size_t size;
+ mem.device_pointer = ptr_map[remote_pointer];
- *rcv.archive & mem & size;
- mem_zero(mem, size);
-#endif
- }
- else if(rcv.name == "mem_free") {
-#if 0
- device_ptr mem;
+ device->mem_copy_to(mem);
+ }
+ else if(rcv.name == "mem_copy_from") {
+ network_device_memory mem;
+ int y, w, h, elem;
- *rcv.archive & mem;
- mem_free(mem);
-#endif
- }
- else if(rcv.name == "const_copy_to") {
- string name_string;
- size_t size;
+ rcv.read(mem);
+ rcv.read(y);
+ rcv.read(w);
+ rcv.read(h);
+ rcv.read(elem);
- *rcv.archive & name_string & size;
+ device_ptr remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[remote_pointer];
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
- vector<char> host_vector(size);
- rcv.read_buffer(&host_vector[0], size);
+ device->mem_copy_from(mem, y, w, h, elem);
- const_copy_to(name_string.c_str(), &host_vector[0], size);
- }
- else if(rcv.name == "tex_alloc") {
-#if 0
- string name_string;
- DataType datatype;
- device_ptr mem;
- size_t width, height;
- int components;
- bool interpolation;
+ RPCSend snd(socket);
+ snd.write();
+ snd.write_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
+ }
+ else if(rcv.name == "mem_zero") {
+ network_device_memory mem;
+
+ rcv.read(mem);
+ device_ptr remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[mem.device_pointer];
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+
+ device->mem_zero(mem);
+ }
+ else if(rcv.name == "mem_free") {
+ network_device_memory mem;
+ device_ptr remote_pointer;
- *rcv.archive & name_string & width & height & datatype & components & interpolation;
+ rcv.read(mem);
- size_t size = width*height*components*datatype_size(datatype);
+ remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[mem.device_pointer];
+ ptr_map.erase(remote_pointer);
+ ptr_imap.erase(mem.device_pointer);
+ mem_data.erase(remote_pointer);
- vector<char> host_vector(size);
- rcv.read_buffer(&host_vector[0], size);
+ device->mem_free(mem);
+ }
+ else if(rcv.name == "const_copy_to") {
+ string name_string;
+ size_t size;
- mem = tex_alloc(name_string.c_str(), &host_vector[0], width, height, datatype, components, interpolation);
+ rcv.read(name_string);
+ rcv.read(size);
- RPCSend snd(socket);
- snd.archive & mem;
- snd.write();
-#endif
- }
- else if(rcv.name == "tex_free") {
-#if 0
- device_ptr mem;
+ vector<char> host_vector(size);
+ rcv.read_buffer(&host_vector[0], size);
- *rcv.archive & mem;
- tex_free(mem);
-#endif
- }
- else if(rcv.name == "path_trace") {
-#if 0
- device_ptr buffer, rng_state;
- int x, y, w, h;
- int sample;
-
- *rcv.archive & x & y & w & h & buffer & rng_state & sample;
- path_trace(x, y, w, h, buffer, rng_state, sample);
-#endif
- }
- else if(rcv.name == "tonemap") {
-#if 0
- device_ptr rgba, buffer;
- int x, y, w, h;
- int sample, resolution;
-
- *rcv.archive & x & y & w & h & rgba & buffer & sample & resolution;
- tonemap(x, y, w, h, rgba, buffer, sample, resolution);
-#endif
- }
+ device->const_copy_to(name_string.c_str(), &host_vector[0], size);
+ }
+ else if(rcv.name == "tex_alloc") {
+ network_device_memory mem;
+ string name;
+ bool interpolation;
+ bool periodic;
+ device_ptr remote_pointer;
+
+ rcv.read(name);
+ rcv.read(mem);
+ rcv.read(interpolation);
+ rcv.read(periodic);
+
+ remote_pointer = mem.device_pointer;
+
+ mem_data[remote_pointer] = vector<uint8_t>();
+ mem_data[remote_pointer].resize(mem.memory_size());
+ if(mem.memory_size())
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ else
+ mem.data_pointer = 0;
+
+ rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
+
+ device->tex_alloc(name.c_str(), mem, interpolation, periodic);
+
+ ptr_map[remote_pointer] = mem.device_pointer;
+ ptr_imap[mem.device_pointer] = remote_pointer;
+ }
+ else if(rcv.name == "tex_free") {
+ network_device_memory mem;
+ device_ptr remote_pointer;
+
+ rcv.read(mem);
+
+ remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[mem.device_pointer];
+ ptr_map.erase(remote_pointer);
+ ptr_map.erase(mem.device_pointer);
+ mem_data.erase(remote_pointer);
+
+ device->tex_free(mem);
+ }
+ else if(rcv.name == "task_add") {
+ DeviceTask task;
+
+ rcv.read(task);
+
+ if(task.buffer) task.buffer = ptr_map[task.buffer];
+ if(task.rgba) task.rgba = ptr_map[task.rgba];
+ if(task.shader_input) task.shader_input = ptr_map[task.shader_input];
+ if(task.shader_output) task.shader_output = ptr_map[task.shader_output];
+
+ task.acquire_tile = function_bind(&DeviceServer::task_acquire_tile, this, _1, _2);
+ task.release_tile = function_bind(&DeviceServer::task_release_tile, this, _1);
+ task.update_progress_sample = function_bind(&DeviceServer::task_update_progress_sample, this);
+ task.update_tile_sample = function_bind(&DeviceServer::task_update_tile_sample, this, _1);
+ task.get_cancel = function_bind(&DeviceServer::task_get_cancel, this);
+
+ device->task_add(task);
+ }
+ else if(rcv.name == "task_wait") {
+ device->task_wait();
+
+ RPCSend snd(socket, "task_wait_done");
+ snd.write();
+ }
+ else if(rcv.name == "task_cancel") {
+ device->task_cancel();
+ }
+ }
+
+ bool task_acquire_tile(Device *device, RenderTile& tile)
+ {
+ thread_scoped_lock acquire_lock(acquire_mutex);
+
+ bool result = false;
+
+ RPCSend snd(socket, "acquire_tile");
+ snd.write();
+
+ while(1) {
+ RPCReceive rcv(socket);
+
+ if(rcv.name == "acquire_tile") {
+ rcv.read(tile);
+
+ if(tile.buffer) tile.buffer = ptr_map[tile.buffer];
+ if(tile.rng_state) tile.rng_state = ptr_map[tile.rng_state];
+ if(tile.rgba) tile.rgba = ptr_map[tile.rgba];
+
+ result = true;
+ break;
}
+ else if(rcv.name == "acquire_tile_none")
+ break;
+ else
+ process(rcv);
}
+
+ return result;
+ }
+
+ void task_update_progress_sample()
+ {
+ ; /* skip */
}
- catch(exception& e)
+
+ void task_update_tile_sample(RenderTile&)
{
- cerr << "Network server exception: " << e.what() << endl;
+ ; /* skip */
+ }
+
+ void task_release_tile(RenderTile& tile)
+ {
+ thread_scoped_lock acquire_lock(acquire_mutex);
+
+ if(tile.buffer) tile.buffer = ptr_imap[tile.buffer];
+ if(tile.rng_state) tile.rng_state = ptr_imap[tile.rng_state];
+ if(tile.rgba) tile.rgba = ptr_imap[tile.rgba];
+
+ RPCSend snd(socket, "release_tile");
+ snd.add(tile);
+ snd.write();
+
+ while(1) {
+ RPCReceive rcv(socket);
+
+ if(rcv.name == "release_tile")
+ break;
+ else
+ process(rcv);
+ }
+ }
+
+ bool task_get_cancel()
+ {
+ return false;
+ }
+
+ /* properties */
+ Device *device;
+ tcp::socket& socket;
+
+ /* mapping of remote to local pointer */
+ map<device_ptr, device_ptr> ptr_map;
+ map<device_ptr, device_ptr> ptr_imap;
+ map<device_ptr, vector<uint8_t> > mem_data;
+
+ thread_mutex acquire_mutex;
+
+ /* todo: free memory and device (osl) on network error */
+};
+
+void Device::server_run()
+{
+ try {
+ /* starts thread that responds to discovery requests */
+ ServerDiscovery discovery;
+
+ for(;;) {
+ /* accept connection */
+ boost::asio::io_service io_service;
+ tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
+
+ tcp::socket socket(io_service);
+ acceptor.accept(socket);
+
+ string remote_address = socket.remote_endpoint().address().to_string();
+ printf("Connected to remote client at: %s\n", remote_address.c_str());
+
+ DeviceServer server(this, socket);
+ server.listen();
+
+ printf("Disconnected.\n");
+ }
+ }
+ catch(exception& e) {
+ fprintf(stderr, "Network server exception: %s\n", e.what());
}
}
diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h
index e3afe46d2b0..b74329888d3 100644
--- a/intern/cycles/device/device_network.h
+++ b/intern/cycles/device/device_network.h
@@ -31,15 +31,17 @@
#include <iostream>
+#include "buffers.h"
+
#include "util_foreach.h"
#include "util_list.h"
+#include "util_map.h"
#include "util_string.h"
CCL_NAMESPACE_BEGIN
using std::cout;
using std::cerr;
-using std::endl;
using std::hex;
using std::setw;
using std::exception;
@@ -51,13 +53,63 @@ static const int DISCOVER_PORT = 5121;
static const string DISCOVER_REQUEST_MSG = "REQUEST_RENDER_SERVER_IP";
static const string DISCOVER_REPLY_MSG = "REPLY_RENDER_SERVER_IP";
-typedef struct RPCSend {
+/* Serialization of device memory */
+
+class network_device_memory : public device_memory
+{
+public:
+ network_device_memory() {}
+ ~network_device_memory() { device_pointer = 0; };
+
+ vector<char> local_data;
+};
+
+/* Remote procedure call Send */
+
+class RPCSend {
+public:
RPCSend(tcp::socket& socket_, const string& name_ = "")
- : name(name_), socket(socket_), archive(archive_stream)
+ : name(name_), socket(socket_), archive(archive_stream), sent(false)
{
archive & name_;
}
+ ~RPCSend()
+ {
+ if(!sent)
+ fprintf(stderr, "Error: RPC %s not sent\n", name.c_str());
+ }
+
+ void add(const device_memory& mem)
+ {
+ archive & mem.data_type & mem.data_elements & mem.data_size;
+ archive & mem.data_width & mem.data_height & mem.device_pointer;
+ }
+
+ template<typename T> void add(const T& data)
+ {
+ archive & data;
+ }
+
+ void add(const DeviceTask& task)
+ {
+ int type = (int)task.type;
+
+ archive & type & task.x & task.y & task.w & task.h;
+ archive & task.rgba & task.buffer & task.sample & task.num_samples;
+ archive & task.resolution & task.offset & task.stride;
+ archive & task.shader_input & task.shader_output & task.shader_eval_type;
+ archive & task.shader_x & task.shader_w;
+ }
+
+ void add(const RenderTile& tile)
+ {
+ archive & tile.x & tile.y & tile.w & tile.h;
+ archive & tile.start_sample & tile.num_samples & tile.sample;
+ archive & tile.resolution & tile.offset & tile.stride;
+ archive & tile.buffer & tile.rng_state & tile.rgba;
+ }
+
void write()
{
boost::system::error_code error;
@@ -84,6 +136,8 @@ typedef struct RPCSend {
if(error.value())
cout << "Network send error: " << error.message() << "\n";
+
+ sent = true;
}
void write_buffer(void *buffer, size_t size)
@@ -98,13 +152,18 @@ typedef struct RPCSend {
cout << "Network send error: " << error.message() << "\n";
}
+protected:
string name;
tcp::socket& socket;
ostringstream archive_stream;
boost::archive::text_oarchive archive;
-} RPCSend;
+ bool sent;
+};
+
+/* Remote procedure call Receive */
-typedef struct RPCReceive {
+class RPCReceive {
+public:
RPCReceive(tcp::socket& socket_)
: socket(socket_), archive_stream(NULL), archive(NULL)
{
@@ -151,6 +210,19 @@ typedef struct RPCReceive {
delete archive_stream;
}
+ void read(network_device_memory& mem)
+ {
+ *archive & mem.data_type & mem.data_elements & mem.data_size;
+ *archive & mem.data_width & mem.data_height & mem.device_pointer;
+
+ mem.data_pointer = 0;
+ }
+
+ template<typename T> void read(T& data)
+ {
+ *archive & data;
+ }
+
void read_buffer(void *buffer, size_t size)
{
size_t len = boost::asio::read(socket, boost::asio::buffer(buffer, size));
@@ -159,12 +231,39 @@ typedef struct RPCReceive {
cout << "Network receive error: buffer size doesn't match expected size\n";
}
+ void read(DeviceTask& task)
+ {
+ int type;
+
+ *archive & type & task.x & task.y & task.w & task.h;
+ *archive & task.rgba & task.buffer & task.sample & task.num_samples;
+ *archive & task.resolution & task.offset & task.stride;
+ *archive & task.shader_input & task.shader_output & task.shader_eval_type;
+ *archive & task.shader_x & task.shader_w;
+
+ task.type = (DeviceTask::Type)type;
+ }
+
+ void read(RenderTile& tile)
+ {
+ *archive & tile.x & tile.y & tile.w & tile.h;
+ *archive & tile.start_sample & tile.num_samples & tile.sample;
+ *archive & tile.resolution & tile.offset & tile.stride;
+ *archive & tile.buffer & tile.rng_state & tile.rgba;
+
+ tile.buffers = NULL;
+ }
+
string name;
+
+protected:
tcp::socket& socket;
string archive_str;
istringstream *archive_stream;
boost::archive::text_iarchive *archive;
-} RPCReceive;
+};
+
+/* Server auto discovery */
class ServerDiscovery {
public:
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 69287f1a8bd..3ab5d9ee69b 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -303,7 +303,7 @@ public:
string build_options = " -cl-fast-relaxed-math ";
if(platform_name == "NVIDIA CUDA")
- build_options += "-D__KERNEL_SHADING__ -D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=24 -cl-nv-verbose ";
+ build_options += "-D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=24 -cl-nv-verbose ";
else if(platform_name == "Apple")
build_options += "-D__CL_NO_FLOAT3__ -D__KERNEL_OPENCL_APPLE__ ";
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 5a570328948..e83756b7c8a 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -12,7 +12,8 @@ set(INC_SYS
set(SRC
kernel.cpp
- kernel_optimized.cpp
+ kernel_sse2.cpp
+ kernel_sse3.cpp
kernel.cl
kernel.cu
)
@@ -20,12 +21,12 @@ set(SRC
set(SRC_HEADERS
kernel.h
kernel_accumulate.h
- kernel_attribute.h
kernel_bvh.h
kernel_camera.h
kernel_compat_cpu.h
kernel_compat_cuda.h
kernel_compat_opencl.h
+ kernel_curve.h
kernel_differential.h
kernel_displace.h
kernel_emission.h
@@ -37,6 +38,7 @@ set(SRC_HEADERS
kernel_object.h
kernel_passes.h
kernel_path.h
+ kernel_primitive.h
kernel_projection.h
kernel_random.h
kernel_shader.h
@@ -49,12 +51,15 @@ set(SRC_CLOSURE_HEADERS
closure/bsdf.h
closure/bsdf_ashikhmin_velvet.h
closure/bsdf_diffuse.h
+ closure/bsdf_diffuse_ramp.h
closure/bsdf_microfacet.h
closure/bsdf_oren_nayar.h
closure/bsdf_phong_ramp.h
closure/bsdf_reflection.h
closure/bsdf_refraction.h
+ closure/bsdf_toon.h
closure/bsdf_transparent.h
+ closure/bsdf_util.h
closure/bsdf_ward.h
closure/bsdf_westin.h
closure/emissive.h
@@ -63,7 +68,6 @@ set(SRC_CLOSURE_HEADERS
set(SRC_SVM_HEADERS
svm/svm.h
svm/svm_attribute.h
- svm/svm_bsdf.h
svm/svm_camera.h
svm/svm_closure.h
svm/svm_convert.h
@@ -146,7 +150,8 @@ include_directories(SYSTEM ${INC_SYS})
add_library(cycles_kernel ${SRC} ${SRC_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_SVM_HEADERS})
if(WITH_CYCLES_OPTIMIZED_KERNEL)
- set_source_files_properties(kernel_optimized.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_OPTIMIZED_KERNEL_FLAGS}")
+ 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}")
endif()
if(WITH_CYCLES_CUDA)
diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript
index 730f758194e..3a46d10dee1 100644
--- a/intern/cycles/kernel/SConscript
+++ b/intern/cycles/kernel/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
import Blender as B
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index cfb6321a918..f26aefe7fd3 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -1,137 +1,296 @@
/*
- * Adapted from Open Shading Language with this license:
+ * Copyright 2011, Blender Foundation.
*
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
+ * 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.
*
- * Modifications Copyright 2011, Blender Foundation.
+ * 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.
*
- * 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 Sony Pictures Imageworks 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.
+ * 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.
*/
-#ifndef __OSL_BSDF_H__
-#define __OSL_BSDF_H__
+#include "../closure/bsdf_ashikhmin_velvet.h"
+#include "../closure/bsdf_diffuse.h"
+#include "../closure/bsdf_oren_nayar.h"
+#include "../closure/bsdf_phong_ramp.h"
+#include "../closure/bsdf_diffuse_ramp.h"
+#include "../closure/bsdf_microfacet.h"
+#include "../closure/bsdf_reflection.h"
+#include "../closure/bsdf_refraction.h"
+#include "../closure/bsdf_transparent.h"
+#ifdef __ANISOTROPIC__
+#include "../closure/bsdf_ward.h"
+#endif
+#include "../closure/bsdf_westin.h"
CCL_NAMESPACE_BEGIN
-__device float fresnel_dielectric(float eta, const float3 N,
- const float3 I, float3 *R, float3 *T,
-#ifdef __RAY_DIFFERENTIALS__
- const float3 dIdx, const float3 dIdy,
- float3 *dRdx, float3 *dRdy,
- float3 *dTdx, float3 *dTdy,
-#endif
- bool *is_inside)
+__device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
{
- float cos = dot(N, I), neta;
- float3 Nn;
- // compute reflection
- *R = (2 * cos)* N - I;
-#ifdef __RAY_DIFFERENTIALS__
- *dRdx = (2 * dot(N, dIdx)) * N - dIdx;
- *dRdy = (2 * dot(N, dIdy)) * N - dIdy;
+ int label;
+
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf);
#endif
- // check which side of the surface we are on
- if(cos > 0) {
- // we are on the outside of the surface, going in
- neta = 1 / eta;
- Nn = N;
- *is_inside = false;
- }
- else {
- // we are inside the surface,
- cos = -cos;
- neta = eta;
- Nn = -N;
- *is_inside = true;
- }
- *R = (2 * cos)* Nn - I;
- float arg = 1 -(neta * neta *(1 -(cos * cos)));
- if(arg < 0) {
- *T = make_float3(0.0f, 0.0f, 0.0f);
-#ifdef __RAY_DIFFERENTIALS__
- *dTdx = make_float3(0.0f, 0.0f, 0.0f);
- *dTdy = make_float3(0.0f, 0.0f, 0.0f);
+
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+ label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;*/
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
#endif
- return 1; // total internal reflection
- }
- else {
- float dnp = sqrtf(arg);
- float nK = (neta * cos)- dnp;
- *T = -(neta * I)+(nK * Nn);
-#ifdef __RAY_DIFFERENTIALS__
- *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
- *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
#endif
- // compute Fresnel terms
- float cosTheta1 = cos; // N.R
- float cosTheta2 = -dot(Nn, *T);
- float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
- float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
- return 0.5f * (pPara * pPara + pPerp * pPerp);
+ default:
+ label = LABEL_NONE;
+ break;
}
+
+ return label;
}
-__device float fresnel_dielectric_cos(float cosi, float eta)
+__device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
{
- // compute fresnel reflectance without explicitly computing
- // the refracted direction
- float c = fabsf(cosi);
- float g = eta * eta - 1 + c * c;
- if(g > 0) {
- g = sqrtf(g);
- float A = (g - c)/(g + c);
- float B = (c *(g + c)- 1)/(c *(g - c)+ 1);
- return 0.5f * A * A *(1 + B * B);
+ float3 eval;
+
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::bsdf_eval(sd, sc, omega_in, *pdf);
+#endif
+
+ if(dot(sd->Ng, omega_in) >= 0.0f) {
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+ eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;*/
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ default:
+ eval = make_float3(0.0f, 0.0f, 0.0f);
+ break;
+ }
+ }
+ else {
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ default:
+ eval = make_float3(0.0f, 0.0f, 0.0f);
+ break;
+ }
}
- return 1.0f; // TIR(no refracted component)
-}
-__device float fresnel_conductor(float cosi, float eta, float k)
-{
- float tmp_f = eta * eta + k * k;
- float tmp = tmp_f * cosi * cosi;
- float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/
- (tmp + (2.0f * eta * cosi) + 1);
- float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/
- (tmp_f + (2.0f * eta * cosi) + cosi * cosi);
- return(Rparl2 + Rperp2) * 0.5f;
+ return eval;
}
-__device float smooth_step(float edge0, float edge1, float x)
+__device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
{
- float result;
- if(x < edge0) result = 0.0f;
- else if(x >= edge1) result = 1.0f;
- else {
- float t = (x - edge0)/(edge1 - edge0);
- result = (3.0f-2.0f*t)*(t*t);
+#ifdef __OSL__
+ if(kg->osl && sc->prim) {
+ OSLShader::bsdf_blur(sc, roughness);
+ return;
+ }
+#endif
+
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_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;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ bsdf_microfacet_ggx_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ bsdf_microfacet_beckmann_blur(sc, roughness);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ bsdf_ward_blur(sc, roughness);
+ break;
+#endif
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ bsdf_ashikhmin_velvet_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ bsdf_westin_backscatter_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ bsdf_westin_sheen_blur(sc, roughness);
+ break;
+#endif
+ default:
+ break;
}
- return result;
}
CCL_NAMESPACE_END
-#endif /* __OSL_BSDF_H__ */
-
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 016fd73204e..60f809159ac 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -134,8 +134,6 @@ __device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, fl
// TODO: find a better approximation for the retroreflective bounce
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index 88b40e3d479..46318ecd138 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -74,8 +74,6 @@ __device int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, f
// TODO: find a better approximation for the diffuse bounce
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else
@@ -126,10 +124,8 @@ __device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3
*eval = make_float3(*pdf, *pdf, *pdf);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
- *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= -125.0f;
- *domega_in_dy *= -125.0f;
+ *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+ *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
#endif
}
else {
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
new file mode 100644
index 00000000000..8a09979806a
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -0,0 +1,96 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2012, Blender Foundation.
+ *
+ * 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 Sony Pictures Imageworks 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.
+ */
+
+#ifndef __BSDF_DIFFUSE_RAMP_H__
+#define __BSDF_DIFFUSE_RAMP_H__
+
+CCL_NAMESPACE_BEGIN
+
+__device float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const float3 colors[8], float pos)
+{
+ int MAXCOLORS = 8;
+
+ float npos = pos * (float)(MAXCOLORS - 1);
+ int ipos = (int)npos;
+ if (ipos >= (MAXCOLORS - 1))
+ return colors[MAXCOLORS - 1];
+ float offset = npos - (float)ipos;
+ return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
+}
+
+__device int bsdf_diffuse_ramp_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
+}
+
+__device void bsdf_diffuse_ramp_blur(ShaderClosure *sc, float roughness)
+{
+}
+
+__device float3 bsdf_diffuse_ramp_eval_reflect(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf)
+{
+ float3 N = sc->N;
+
+ float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
+ *pdf = cos_pi * M_1_PI_F;
+ return bsdf_diffuse_ramp_get_color(sc, colors, cos_pi) * M_1_PI_F;
+}
+
+__device float3 bsdf_diffuse_ramp_eval_transmit(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device int bsdf_diffuse_ramp_sample(const ShaderClosure *sc, const float3 colors[8], 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;
+
+ // distribution over the hemisphere
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+
+ if(dot(Ng, *omega_in) > 0.0f) {
+ *eval = bsdf_diffuse_ramp_get_color(sc, colors, *pdf * M_PI_F) * M_1_PI_F;
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
+#endif
+ }
+ else
+ *pdf = 0.0f;
+
+ return LABEL_REFLECT|LABEL_DIFFUSE;
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __BSDF_DIFFUSE_RAMP_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index a564b99e759..019ec105111 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -199,12 +199,6 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
#endif
}
}
@@ -251,14 +245,6 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa
// eq. 38 and eq. 17
*pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
*eval = make_float3(out, out, out);
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this refraction, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
-#endif
}
}
}
@@ -430,12 +416,6 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng,
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
#endif
}
}
@@ -486,14 +466,6 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng,
// eq. 38 and eq. 17
*pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
*eval = make_float3(out, out, out);
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this refraction, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
-#endif
}
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index 066937da6eb..770f06dddc5 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -81,8 +81,6 @@ __device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3 I
// TODO: find a better approximation for the bounce
*domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx;
*domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else {
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index 575a798aed4..2f57fc1693f 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -119,15 +119,6 @@ __device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors
*pdf = (m_exponent + 1) * common;
float out = cosNI * (m_exponent + 2) * common;
*eval = bsdf_phong_ramp_get_color(sc, colors, cosp) * out;
-
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // exponent but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10;
- *domega_in_dy *= 10;
-#endif
}
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
new file mode 100644
index 00000000000..40001bf7531
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -0,0 +1,206 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * 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 Sony Pictures Imageworks 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.
+ */
+
+#ifndef __BSDF_TOON_H__
+#define __BSDF_TOON_H__
+
+CCL_NAMESPACE_BEGIN
+
+/* DIFFUSE TOON */
+
+__device int bsdf_diffuse_toon_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_DIFFUSE_TOON_ID;
+ sc->data0 = clamp(sc->data0, 0.0f, 1.0f);
+ sc->data1 = clamp(sc->data1, 0.0f, 1.0f);
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+__device void bsdf_diffuse_toon_blur(ShaderClosure *sc, float roughness)
+{
+}
+
+__device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
+{
+ float is;
+
+ if(angle < max_angle)
+ is = 1.0f;
+ else if(angle < (max_angle + smooth) && smooth != 0.0f)
+ is = (1.0f - (angle - max_angle)/smooth);
+ else
+ is = 0.0f;
+
+ return make_float3(is, is, is);
+}
+
+__device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
+{
+ return fminf(max_angle + smooth, M_PI_2_F);
+}
+
+__device float3 bsdf_diffuse_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float angle = safe_acosf(fmaxf(dot(sc->N, omega_in), 0.0f));
+
+ float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+
+ if(eval.x > 0.0f) {
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return *pdf * eval;
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device float3 bsdf_diffuse_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device int bsdf_diffuse_toon_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)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float angle = sample_angle*randu;
+
+ if(sample_angle > 0.0f) {
+ sample_uniform_cone(sc->N, sample_angle, randu, randv, omega_in, pdf);
+
+ if(dot(Ng, *omega_in) > 0.0f) {
+ *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+
+#ifdef __RAY_DIFFERENTIALS__
+ // TODO: find a better approximation for the bounce
+ *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx;
+ *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy;
+#endif
+ }
+ else
+ *pdf = 0.0f;
+ }
+
+ return LABEL_REFLECT | LABEL_DIFFUSE;
+
+}
+
+/* SPECULAR TOON */
+
+__device int bsdf_specular_toon_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_SPECULAR_TOON_ID;
+ sc->data0 = clamp(sc->data0, 0.0f, 1.0f);
+ sc->data1 = clamp(sc->data1, 0.0f, 1.0f);
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+__device void bsdf_specular_toon_blur(ShaderClosure *sc, float roughness)
+{
+}
+
+__device float3 bsdf_specular_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float cosNI = dot(sc->N, omega_in);
+ float cosNO = dot(sc->N, I);
+
+ if(cosNI > 0 && cosNO > 0) {
+ /* reflect the view vector */
+ float3 R = (2 * cosNO) * sc->N - I;
+ float cosRI = dot(R, omega_in);
+
+ float angle = safe_acosf(fmaxf(cosRI, 0.0f));
+
+ float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return *pdf * eval;
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device float3 bsdf_specular_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device int bsdf_specular_toon_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)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float cosNO = dot(sc->N, I);
+
+ if(cosNO > 0) {
+ /* reflect the view vector */
+ float3 R = (2 * cosNO) * sc->N - I;
+
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float angle = sample_angle*randu;
+
+ sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf);
+
+ if(dot(Ng, *omega_in) > 0.0f) {
+ float cosNI = dot(sc->N, *omega_in);
+
+ /* make sure the direction we chose is still in the right hemisphere */
+ if(cosNI > 0) {
+ *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(sc->N, dIdx)) * sc->N - dIdx;
+ *domega_in_dy = (2 * dot(sc->N, dIdy)) * sc->N - dIdy;
+#endif
+ }
+ else
+ *pdf = 0.0f;
+ }
+ else
+ *pdf = 0.0f;
+ }
+
+ return LABEL_GLOSSY | LABEL_REFLECT;
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __BSDF_TOON_H__ */
+
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
new file mode 100644
index 00000000000..cfb6321a918
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -0,0 +1,137 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * 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 Sony Pictures Imageworks 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.
+ */
+
+#ifndef __OSL_BSDF_H__
+#define __OSL_BSDF_H__
+
+CCL_NAMESPACE_BEGIN
+
+__device float fresnel_dielectric(float eta, const float3 N,
+ const float3 I, float3 *R, float3 *T,
+#ifdef __RAY_DIFFERENTIALS__
+ const float3 dIdx, const float3 dIdy,
+ float3 *dRdx, float3 *dRdy,
+ float3 *dTdx, float3 *dTdy,
+#endif
+ bool *is_inside)
+{
+ float cos = dot(N, I), neta;
+ float3 Nn;
+ // compute reflection
+ *R = (2 * cos)* N - I;
+#ifdef __RAY_DIFFERENTIALS__
+ *dRdx = (2 * dot(N, dIdx)) * N - dIdx;
+ *dRdy = (2 * dot(N, dIdy)) * N - dIdy;
+#endif
+ // check which side of the surface we are on
+ if(cos > 0) {
+ // we are on the outside of the surface, going in
+ neta = 1 / eta;
+ Nn = N;
+ *is_inside = false;
+ }
+ else {
+ // we are inside the surface,
+ cos = -cos;
+ neta = eta;
+ Nn = -N;
+ *is_inside = true;
+ }
+ *R = (2 * cos)* Nn - I;
+ float arg = 1 -(neta * neta *(1 -(cos * cos)));
+ if(arg < 0) {
+ *T = make_float3(0.0f, 0.0f, 0.0f);
+#ifdef __RAY_DIFFERENTIALS__
+ *dTdx = make_float3(0.0f, 0.0f, 0.0f);
+ *dTdy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+ return 1; // total internal reflection
+ }
+ else {
+ float dnp = sqrtf(arg);
+ float nK = (neta * cos)- dnp;
+ *T = -(neta * I)+(nK * Nn);
+#ifdef __RAY_DIFFERENTIALS__
+ *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
+ *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
+#endif
+ // compute Fresnel terms
+ float cosTheta1 = cos; // N.R
+ float cosTheta2 = -dot(Nn, *T);
+ float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
+ float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
+ return 0.5f * (pPara * pPara + pPerp * pPerp);
+ }
+}
+
+__device float fresnel_dielectric_cos(float cosi, float eta)
+{
+ // compute fresnel reflectance without explicitly computing
+ // the refracted direction
+ float c = fabsf(cosi);
+ float g = eta * eta - 1 + c * c;
+ if(g > 0) {
+ g = sqrtf(g);
+ float A = (g - c)/(g + c);
+ float B = (c *(g + c)- 1)/(c *(g - c)+ 1);
+ return 0.5f * A * A *(1 + B * B);
+ }
+ return 1.0f; // TIR(no refracted component)
+}
+
+__device float fresnel_conductor(float cosi, float eta, float k)
+{
+ float tmp_f = eta * eta + k * k;
+ float tmp = tmp_f * cosi * cosi;
+ float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/
+ (tmp + (2.0f * eta * cosi) + 1);
+ float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/
+ (tmp_f + (2.0f * eta * cosi) + cosi * cosi);
+ return(Rparl2 + Rperp2) * 0.5f;
+}
+
+__device float smooth_step(float edge0, float edge1, float x)
+{
+ float result;
+ if(x < edge0) result = 0.0f;
+ else if(x >= edge1) result = 1.0f;
+ else {
+ float t = (x - edge0)/(edge1 - edge0);
+ result = (3.0f-2.0f*t)*(t*t);
+ }
+ return result;
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __OSL_BSDF_H__ */
+
diff --git a/intern/cycles/kernel/closure/bsdf_ward.h b/intern/cycles/kernel/closure/bsdf_ward.h
index dbddcf20dba..c95b0e3f7a0 100644
--- a/intern/cycles/kernel/closure/bsdf_ward.h
+++ b/intern/cycles/kernel/closure/bsdf_ward.h
@@ -182,12 +182,6 @@ __device int bsdf_ward_sample(const ShaderClosure *sc, float3 Ng, float3 I, floa
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
#endif
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h
index 968173208b4..29bfa85bcc1 100644
--- a/intern/cycles/kernel/closure/bsdf_westin.h
+++ b/intern/cycles/kernel/closure/bsdf_westin.h
@@ -108,14 +108,6 @@ __device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng,
*pdf = 0.5f * M_1_PI_F * powf(cosTheta, m_invroughness);
*pdf = (m_invroughness + 1) * (*pdf);
*eval = make_float3(*pdf, *pdf, *pdf);
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // exponent but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
-#endif
}
}
}
@@ -176,8 +168,6 @@ __device int bsdf_westin_sheen_sample(const ShaderClosure *sc, float3 Ng, float3
// TODO: find a better approximation for the diffuse bounce
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else {
diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h
index cbf9d9a4efb..33b1b695a9a 100644
--- a/intern/cycles/kernel/closure/emissive.h
+++ b/intern/cycles/kernel/closure/emissive.h
@@ -49,17 +49,12 @@ __device void emissive_sample(const float3 Ng, float randu, float randv,
/* todo: not implemented and used yet */
}
-__device float3 emissive_eval(const float3 Ng, const float3 I)
+__device float3 emissive_simple_eval(const float3 Ng, const float3 I)
{
float res = emissive_pdf(Ng, I);
return make_float3(res, res, res);
}
-__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
-{
- return emissive_eval(sd->Ng, sd->I);
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 734f9111ab6..0b553f38a25 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -53,8 +53,13 @@ __device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const flo
/* VOLUME CLOSURE */
-__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+__device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::volume_eval_phase(sc, omega_in, omega_out);
+#endif
+
float3 eval;
switch(sc->type) {
diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h
index 26c0bcd6d1a..20ea5a61906 100644
--- a/intern/cycles/kernel/kernel.h
+++ b/intern/cycles/kernel/kernel.h
@@ -44,11 +44,18 @@ void kernel_cpu_shader(KernelGlobals *kg, uint4 *input, float4 *output,
int type, int i);
#ifdef WITH_OPTIMIZED_KERNEL
-void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state,
+void kernel_cpu_sse2_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state,
int sample, int x, int y, int offset, int stride);
-void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer,
+void kernel_cpu_sse2_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer,
int sample, int resolution, int x, int y, int offset, int stride);
-void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output,
+void kernel_cpu_sse2_shader(KernelGlobals *kg, uint4 *input, float4 *output,
+ int type, int i);
+
+void kernel_cpu_sse3_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state,
+ int sample, int x, int y, int offset, int stride);
+void kernel_cpu_sse3_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer,
+ int sample, int resolution, int x, int y, int offset, int stride);
+void kernel_cpu_sse3_shader(KernelGlobals *kg, uint4 *input, float4 *output,
int type, int i);
#endif
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index d99beb8905a..1cf230634fc 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -133,6 +133,10 @@ __device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
+ L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
+
L->emission = make_float3(0.0f, 0.0f, 0.0f);
L->background = make_float3(0.0f, 0.0f, 0.0f);
L->ao = make_float3(0.0f, 0.0f, 0.0f);
@@ -156,11 +160,11 @@ __device_inline void path_radiance_bsdf_bounce(PathRadiance *L, float3 *throughp
/* first on directly visible surface */
float3 value = *throughput*inverse_pdf;
- L->indirect_diffuse = bsdf_eval->diffuse*value;
- L->indirect_glossy = bsdf_eval->glossy*value;
- L->indirect_transmission = bsdf_eval->transmission*value;
+ L->path_diffuse = bsdf_eval->diffuse*value;
+ L->path_glossy = bsdf_eval->glossy*value;
+ L->path_transmission = bsdf_eval->transmission*value;
- *throughput = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission;
+ *throughput = L->path_diffuse + L->path_glossy + L->path_transmission;
L->direct_throughput = *throughput;
}
@@ -216,7 +220,7 @@ __device_inline void path_radiance_accum_ao(PathRadiance *L, float3 throughput,
#endif
}
-__device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, float3 shadow, int bounce, bool is_lamp)
+__device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, float3 shadow, float shadow_fac, int bounce, bool is_lamp)
{
#ifdef __PASSES__
if(L->use_light_pass) {
@@ -229,9 +233,9 @@ __device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughpu
if(is_lamp) {
float3 sum = throughput*(bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission);
- L->shadow.x += shadow.x;
- L->shadow.y += shadow.y;
- L->shadow.z += shadow.z;
+ L->shadow.x += shadow.x*shadow_fac;
+ L->shadow.y += shadow.y*shadow_fac;
+ L->shadow.z += shadow.z*shadow_fac;
L->shadow.w += average(sum);
}
}
@@ -266,22 +270,45 @@ __device_inline void path_radiance_accum_background(PathRadiance *L, float3 thro
#endif
}
-__device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L)
+__device_inline void path_radiance_sum_indirect(PathRadiance *L)
{
#ifdef __PASSES__
+ /* this division is a bit ugly, but means we only have to keep track of
+ * only a single throughput further along the path, here we recover just
+ * the indirect parth that is not influenced by any particular BSDF type */
if(L->use_light_pass) {
- /* this division is a bit ugly, but means we only have to keep track of
- * only a single throughput further along the path, here we recover just
- * the indirect parth that is not influenced by any particular BSDF type */
L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput);
- L->direct_diffuse += L->indirect_diffuse*L->direct_emission;
- L->direct_glossy += L->indirect_glossy*L->direct_emission;
- L->direct_transmission += L->indirect_transmission*L->direct_emission;
+ L->direct_diffuse += L->path_diffuse*L->direct_emission;
+ L->direct_glossy += L->path_glossy*L->direct_emission;
+ L->direct_transmission += L->path_transmission*L->direct_emission;
L->indirect = safe_divide_color(L->indirect, L->direct_throughput);
- L->indirect_diffuse *= L->indirect;
- L->indirect_glossy *= L->indirect;
- L->indirect_transmission *= L->indirect;
+ L->indirect_diffuse += L->path_diffuse*L->indirect;
+ L->indirect_glossy += L->path_glossy*L->indirect;
+ L->indirect_transmission += L->path_transmission*L->indirect;
+ }
+#endif
+}
+
+__device_inline void path_radiance_reset_indirect(PathRadiance *L)
+{
+#ifdef __PASSES__
+ if(L->use_light_pass) {
+ L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
+ L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
+ L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
+
+ L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect = make_float3(0.0f, 0.0f, 0.0f);
+ }
+#endif
+}
+
+__device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L)
+{
+#ifdef __PASSES__
+ if(L->use_light_pass) {
+ path_radiance_sum_indirect(L);
float3 L_sum = L->emission
+ L->direct_diffuse + L->direct_glossy + L->direct_transmission
diff --git a/intern/cycles/kernel/kernel_attribute.h b/intern/cycles/kernel/kernel_attribute.h
deleted file mode 100644
index b7ad731c883..00000000000
--- a/intern/cycles/kernel/kernel_attribute.h
+++ /dev/null
@@ -1,50 +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.
- */
-
-#ifndef __KERNEL_ATTRIBUTE_CL__
-#define __KERNEL_ATTRIBUTE_CL__
-
-CCL_NAMESPACE_BEGIN
-
-/* note: declared in kernel.h, have to add it here because kernel.h is not available */
-bool kernel_osl_use(KernelGlobals *kg);
-
-__device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
-{
-#ifdef __OSL__
- if (kg->osl) {
- return OSLShader::find_attribute(kg, sd, id);
- }
- else
-#endif
- {
- /* for SVM, find attribute by unique id */
- uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id)
- attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
-
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- }
-}
-
-CCL_NAMESPACE_END
-
-#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index d70485fd6cf..2b9ebf35d0c 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -126,21 +126,21 @@ __device_inline void bvh_node_intersect(KernelGlobals *kg,
/* intersect ray against child nodes */
float3 ood = P * idir;
- float c0lox = n0xy.x * idir.x - ood.x;
- float c0hix = n0xy.y * idir.x - ood.x;
- float c0loy = n0xy.z * idir.y - ood.y;
- float c0hiy = n0xy.w * idir.y - ood.y;
- float c0loz = nz.x * idir.z - ood.z;
- float c0hiz = nz.y * idir.z - ood.z;
+ NO_EXTENDED_PRECISION float c0lox = n0xy.x * idir.x - ood.x;
+ NO_EXTENDED_PRECISION float c0hix = n0xy.y * idir.x - ood.x;
+ NO_EXTENDED_PRECISION float c0loy = n0xy.z * idir.y - ood.y;
+ NO_EXTENDED_PRECISION float c0hiy = n0xy.w * idir.y - ood.y;
+ NO_EXTENDED_PRECISION float c0loz = nz.x * idir.z - ood.z;
+ NO_EXTENDED_PRECISION float c0hiz = nz.y * idir.z - ood.z;
NO_EXTENDED_PRECISION float c0min = max4(min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz), 0.0f);
NO_EXTENDED_PRECISION float c0max = min4(max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz), t);
- float c1loz = nz.z * idir.z - ood.z;
- float c1hiz = nz.w * idir.z - ood.z;
- float c1lox = n1xy.x * idir.x - ood.x;
- float c1hix = n1xy.y * idir.x - ood.x;
- float c1loy = n1xy.z * idir.y - ood.y;
- float c1hiy = n1xy.w * idir.y - ood.y;
+ NO_EXTENDED_PRECISION float c1loz = nz.z * idir.z - ood.z;
+ NO_EXTENDED_PRECISION float c1hiz = nz.w * idir.z - ood.z;
+ NO_EXTENDED_PRECISION float c1lox = n1xy.x * idir.x - ood.x;
+ NO_EXTENDED_PRECISION float c1hix = n1xy.y * idir.x - ood.x;
+ NO_EXTENDED_PRECISION float c1loy = n1xy.z * idir.y - ood.y;
+ NO_EXTENDED_PRECISION float c1hiy = n1xy.w * idir.y - ood.y;
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);
@@ -205,7 +205,457 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise
}
}
-__device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
+#ifdef __HAIR__
+__device_inline void curvebounds(float *lower, float *upper, float *extremta, float *extrema, float *extremtb, float *extremb, float p0, float p1, float p2, float p3)
+{
+ float halfdiscroot = (p2 * p2 - 3 * p3 * p1);
+ float ta = -1.0f;
+ float tb = -1.0f;
+ *extremta = -1.0f;
+ *extremtb = -1.0f;
+ *upper = p0;
+ *lower = p0 + p1 + p2 + p3;
+ *extrema = *upper;
+ *extremb = *lower;
+ if(*lower >= *upper) {
+ *upper = *lower;
+ *lower = p0;
+ }
+
+ if(halfdiscroot >= 0) {
+ halfdiscroot = sqrt(halfdiscroot);
+ ta = (-p2 - halfdiscroot) / (3 * p3);
+ tb = (-p2 + halfdiscroot) / (3 * p3);
+ }
+
+ float t2;
+ float t3;
+ if(ta > 0.0f && ta < 1.0f) {
+ t2 = ta * ta;
+ t3 = t2 * ta;
+ *extremta = ta;
+ *extrema = p3 * t3 + p2 * t2 + p1 * ta + p0;
+ if(*extrema > *upper) {
+ *upper = *extrema;
+ }
+ if(*extrema < *lower) {
+ *lower = *extrema;
+ }
+ }
+ if(tb > 0.0f && tb < 1.0f) {
+ t2 = tb * tb;
+ t3 = t2 * tb;
+ *extremtb = tb;
+ *extremb = p3 * t3 + p2 * t2 + p1 * tb + p0;
+ if(*extremb >= *upper) {
+ *upper = *extremb;
+ }
+ if(*extremb <= *lower) {
+ *lower = *extremb;
+ }
+ }
+}
+
+__device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
+ float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
+{
+ int depth = kernel_data.curve_kernel_data.subdivisions;
+
+ /* curve Intersection check */
+ float3 dir = 1.0f/idir;
+
+ int flags = kernel_data.curve_kernel_data.curveflags;
+
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+
+ float3 curve_coef[4];
+ float r_st,r_en;
+
+ /*obtain curve parameters*/
+ {
+ /*ray transform created - this shold be created at beginning of intersection loop*/
+ Transform htfm;
+ float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
+ htfm = make_transform(
+ dir.z / d, 0, -dir.x /d, 0,
+ -dir.x * dir.y /d, d, -dir.y * dir.z /d, 0,
+ dir.x, dir.y, dir.z, 0,
+ 0, 0, 0, 1) * make_transform(
+ 1, 0, 0, -P.x,
+ 0, 1, 0, -P.y,
+ 0, 0, 1, -P.z,
+ 0, 0, 0, 1);
+
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ int ka = max(k0 - 1,__float_as_int(v00.x));
+ int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P0 = kernel_tex_fetch(__curve_keys, ka);
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+ float4 P3 = kernel_tex_fetch(__curve_keys, kb);
+
+ float3 p0 = transform_point(&htfm, float4_to_float3(P0));
+ float3 p1 = transform_point(&htfm, float4_to_float3(P1));
+ float3 p2 = transform_point(&htfm, float4_to_float3(P2));
+ float3 p3 = transform_point(&htfm, float4_to_float3(P3));
+
+ float fc = 0.71f;
+ curve_coef[0] = p1;
+ curve_coef[1] = -fc*p0 + fc*p2;
+ curve_coef[2] = 2.0f * fc * p0 + (fc - 3.0f) * p1 + (3.0f - 2.0f * fc) * p2 - fc * p3;
+ curve_coef[3] = -fc * p0 + (2.0f - fc) * p1 + (fc - 2.0f) * p2 + fc * p3;
+ r_st = P1.w;
+ r_en = P2.w;
+ }
+
+
+ float r_curr = max(r_st, r_en);
+
+ /*find bounds - this is slow for cubic curves*/
+ float upper,lower;
+ float xextrem[4];
+ curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
+ if(lower > r_curr || upper < -r_curr)
+ return;
+
+ float yextrem[4];
+ curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
+ if(lower > r_curr || upper < -r_curr)
+ return;
+
+ float zextrem[4];
+ curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
+ if(lower - r_curr > isect->t || upper + r_curr < 0.0f)
+ return;
+
+ /*setup recurrent loop*/
+ int level = 1 << depth;
+ int tree = 0;
+ float resol = 1.0f / (float)level;
+
+ /*begin loop*/
+ while(!(tree >> (depth))) {
+ float i_st = tree * resol;
+ float i_en = i_st + (level * resol);
+ float3 p_st = ((curve_coef[3] * i_st + curve_coef[2]) * i_st + curve_coef[1]) * i_st + curve_coef[0];
+ float3 p_en = ((curve_coef[3] * i_en + curve_coef[2]) * i_en + curve_coef[1]) * i_en + curve_coef[0];
+
+ float bminx = min(p_st.x, p_en.x);
+ float bmaxx = max(p_st.x, p_en.x);
+ float bminy = min(p_st.y, p_en.y);
+ float bmaxy = max(p_st.y, p_en.y);
+ float bminz = min(p_st.z, p_en.z);
+ float bmaxz = max(p_st.z, p_en.z);
+
+ if(xextrem[0] >= i_st && xextrem[0] <= i_en) {
+ bminx = min(bminx,xextrem[1]);
+ bmaxx = max(bmaxx,xextrem[1]);
+ }
+ if(xextrem[2] >= i_st && xextrem[2] <= i_en) {
+ bminx = min(bminx,xextrem[3]);
+ bmaxx = max(bmaxx,xextrem[3]);
+ }
+ if(yextrem[0] >= i_st && yextrem[0] <= i_en) {
+ bminy = min(bminy,yextrem[1]);
+ bmaxy = max(bmaxy,yextrem[1]);
+ }
+ if(yextrem[2] >= i_st && yextrem[2] <= i_en) {
+ bminy = min(bminy,yextrem[3]);
+ bmaxy = max(bmaxy,yextrem[3]);
+ }
+ if(zextrem[0] >= i_st && zextrem[0] <= i_en) {
+ bminz = min(bminz,zextrem[1]);
+ bmaxz = max(bmaxz,zextrem[1]);
+ }
+ if(zextrem[2] >= i_st && zextrem[2] <= i_en) {
+ bminz = min(bminz,zextrem[3]);
+ bmaxz = max(bmaxz,zextrem[3]);
+ }
+
+ float r1 = r_st + (r_en - r_st) * i_st;
+ float r2 = r_st + (r_en - r_st) * i_en;
+ r_curr = max(r1, r2);
+
+ if (bminz - r_curr > isect->t || bmaxz + r_curr < 0.0f|| bminx > r_curr || bmaxx < -r_curr || bminy > r_curr || bmaxy < -r_curr) {
+ /* the bounding box does not overlap the square centered at O.*/
+ tree += level;
+ level = tree & -tree;
+ }
+ else if (level == 1) {
+
+ /* the maximum recursion depth is reached.
+ * check if dP0.(Q-P0)>=0 and dPn.(Pn-Q)>=0.
+ * dP* is reversed if necessary.*/
+ float t = isect->t;
+ float u = 0.0f;
+ if(flags & CURVE_KN_RIBBONS) {
+ float3 tg = (p_en - p_st);
+ float w = tg.x * tg.x + tg.y * tg.y;
+ if (w == 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
+ w = clamp((float)w, 0.0f, 1.0f);
+
+ /* compute u on the curve segment.*/
+ u = i_st * (1 - w) + i_en * w;
+ r_curr = r_st + (r_en - r_st) * u;
+ /* compare x-y distances.*/
+ float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if (dot(tg, dp_st)< 0)
+ dp_st *= -1;
+ if (dot(dp_st, -p_st) + p_curr.z * dp_st.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if (dot(tg, dp_en) < 0)
+ dp_en *= -1;
+ if (dot(dp_en, p_en) - p_curr.z * dp_en.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ if (p_curr.x * p_curr.x + p_curr.y * p_curr.y >= r_curr * r_curr || p_curr.z <= 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ /* compare z distances.*/
+ if (isect->t < p_curr.z) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ t = p_curr.z;
+ }
+ else {
+ float l = len(p_en - p_st);
+ float3 tg = (p_en - p_st) / l;
+ float gd = (r2 - r1) / l;
+ float difz = -dot(p_st,tg);
+ float cyla = 1.0f - (tg.z * tg.z * (1 + gd*gd));
+ float halfb = (-p_st.z - tg.z*(difz + gd*(difz*gd + r1)));
+ float tcentre = -halfb/cyla;
+ float zcentre = difz + (tg.z * tcentre);
+ float3 tdif = - p_st;
+ tdif.z += tcentre;
+ float tdifz = dot(tdif,tg);
+ float tb = 2*(tdif.z - tg.z*(tdifz + gd*(tdifz*gd + r1)));
+ float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - r1*r1 - 2*r1*tdifz*gd;
+ float td = tb*tb - 4*cyla*tc;
+ if (td < 0.0f){
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ float rootd = sqrtf(td);
+ float correction = ((-tb - rootd)/(2*cyla));
+ t = tcentre + correction;
+ float w = (zcentre + (tg.z * correction))/l;
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if (dot(tg, dp_st)< 0)
+ dp_st *= -1;
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if (dot(tg, dp_en) < 0)
+ dp_en *= -1;
+
+
+ if(flags & CURVE_KN_BACKFACING && (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f)) {
+ correction = ((-tb + rootd)/(2*cyla));
+ t = tcentre + correction;
+ w = (zcentre + (tg.z * correction))/l;
+ }
+
+ if (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ w = clamp((float)w, 0.0f, 1.0f);
+ /* compute u on the curve segment.*/
+ u = i_st * (1 - w) + i_en * w;
+
+ }
+ /* we found a new intersection.*/
+#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, curveAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->prim = curveAddr;
+ isect->segment = segment;
+ isect->object = object;
+ isect->u = u;
+ isect->v = 0.0f;
+ isect->t = t;
+ }
+
+ tree++;
+ level = tree & -tree;
+ }
+ else {
+ /* split the curve into two curves and process */
+ level = level >> 1;
+ }
+ }
+}
+
+__device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
+ float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
+{
+ /* curve Intersection check */
+
+ int flags = kernel_data.curve_kernel_data.curveflags;
+
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+
+ float r1 = P1.w;
+ float r2 = P2.w;
+ float mr = max(r1,r2);
+ float3 p1 = float4_to_float3(P1);
+ float3 p2 = float4_to_float3(P2);
+ float3 dif = P - p1;
+ float3 dir = 1.0f/idir;
+ float l = len(p2 - p1);
+
+ float sp_r = mr + 0.5f * l;
+ float3 sphere_dif = P - ((p1 + p2) * 0.5f);
+ float sphere_b = dot(dir,sphere_dif);
+ sphere_dif = sphere_dif - sphere_b * dir;
+ sphere_b = dot(dir,sphere_dif);
+ float sdisc = sphere_b * sphere_b - len_squared(sphere_dif) + sp_r * sp_r;
+ if(sdisc < 0.0f)
+ return;
+
+ /* obtain parameters and test midpoint distance for suitable modes*/
+ float3 tg = (p2 - p1) / l;
+ float gd = (r2 - r1) / l;
+ float dirz = dot(dir,tg);
+ float difz = dot(dif,tg);
+
+ float a = 1.0f - (dirz*dirz*(1 + gd*gd));
+ float halfb = (dot(dir,dif) - dirz*(difz + gd*(difz*gd + r1)));
+
+ float tcentre = -halfb/a;
+ float zcentre = difz + (dirz * tcentre);
+
+ if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
+ return;
+ if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
+ return;
+
+ /* test minimum separation*/
+ float3 cprod = cross(tg, dir);
+ float3 cprod2 = cross(tg, dif);
+ float cprodsq = len_squared(cprod);
+ float cprod2sq = len_squared(cprod2);
+ float distscaled = dot(cprod,dif);
+
+ if(cprodsq == 0)
+ distscaled = cprod2sq;
+ else
+ distscaled = (distscaled*distscaled)/cprodsq;
+
+ if(distscaled > mr*mr)
+ return;
+
+ /* calculate true intersection*/
+ float3 tdif = P - p1 + tcentre * dir;
+ float tdifz = dot(tdif,tg);
+ float tb = 2*(dot(dir,tdif) - dirz*(tdifz + gd*(tdifz*gd + r1)));
+ float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - r1*r1 - 2*r1*tdifz*gd;
+ float td = tb*tb - 4*a*tc;
+
+ if (td < 0.0f)
+ return;
+
+ float rootd = 0.0f;
+ float correction = 0.0f;
+ if(flags & CURVE_KN_ACCURATE) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ }
+
+ float t = tcentre + correction;
+
+ if(t < isect->t) {
+
+ if(flags & CURVE_KN_INTERSECTCORRECTION) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ t = tcentre + correction;
+ }
+
+ float z = zcentre + (dirz * correction);
+ bool backface = false;
+
+ if(flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
+ backface = true;
+ correction = ((-tb + rootd)/(2*a));
+ t = tcentre + correction;
+ z = zcentre + (dirz * correction);
+ }
+
+ if(t > 0.0f && t < isect->t && z >= 0 && z <= l) {
+
+ if (flags & CURVE_KN_ENCLOSEFILTER) {
+
+ float enc_ratio = kernel_data.curve_kernel_data.encasing_ratio;
+ if((dot(P - p1, tg) > -r1 * enc_ratio) && (dot(P - p2, tg) < r2 * enc_ratio)) {
+ float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
+ float c2 = dot(dif,dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
+ if(a2*c2 < 0.0f)
+ return;
+ }
+ }
+
+#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, curveAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->prim = curveAddr;
+ isect->segment = segment;
+ isect->object = object;
+ isect->u = z/l;
+ isect->v = td/(4*a*a);
+ isect->t = t;
+
+ if(backface)
+ isect->u = -isect->u;
+ }
+ }
+ }
+}
+#endif
+
+__device bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
{
/* traversal stack in CUDA thread-local memory */
int traversalStack[BVH_STACK_SIZE];
@@ -281,10 +731,20 @@ __device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint
nodeAddr = traversalStack[stackPtr];
--stackPtr;
- /* triangle intersection */
+ /* primitive intersection */
while(primAddr < primAddr2) {
- /* intersect ray against triangle */
- bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+ /* intersect ray against primitive */
+#ifdef __HAIR__
+ uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+ if(segment != ~0) {
+ if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_INTERPOLATE)
+ bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ else
+ bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ }
+ else
+#endif
+ bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
/* shadow ray early termination */
if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0)
@@ -325,7 +785,7 @@ __device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint
}
#ifdef __OBJECT_MOTION__
-__device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
+__device bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
{
/* traversal stack in CUDA thread-local memory */
int traversalStack[BVH_STACK_SIZE];
@@ -401,10 +861,20 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con
nodeAddr = traversalStack[stackPtr];
--stackPtr;
- /* triangle intersection */
+ /* primitive intersection */
while(primAddr < primAddr2) {
- /* intersect ray against triangle */
- bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+ /* intersect ray against primitive */
+#ifdef __HAIR__
+ uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+ if(segment != ~0) {
+ if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_INTERPOLATE)
+ bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ else
+ bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ }
+ else
+#endif
+ bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
/* shadow ray early termination */
if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0)
@@ -457,12 +927,15 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
{
#ifdef __INTERSECTION_REFINE__
const float epsilon_f = 1e-5f;
+ /* ideally this should match epsilon_f, but instancing/mblur
+ * precision makes it problematic */
+ const float epsilon_test = 1.0f;
const int epsilon_i = 32;
float3 res;
/* x component */
- if(fabsf(P.x) < epsilon_f) {
+ if(fabsf(P.x) < epsilon_test) {
res.x = P.x + Ng.x*epsilon_f;
}
else {
@@ -472,7 +945,7 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
}
/* y component */
- if(fabsf(P.y) < epsilon_f) {
+ if(fabsf(P.y) < epsilon_test) {
res.y = P.y + Ng.y*epsilon_f;
}
else {
@@ -482,7 +955,7 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
}
/* z component */
- if(fabsf(P.z) < epsilon_f) {
+ if(fabsf(P.z) < epsilon_test) {
res.z = P.z + Ng.z*epsilon_f;
}
else {
@@ -542,5 +1015,159 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co
#endif
}
+#ifdef __HAIR__
+
+__device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
+{
+ float fc = 0.71f;
+ float data[4];
+ float t2 = t * t;
+ data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
+ data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
+ data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
+ data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+}
+
+__device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3)
+{
+ float data[4];
+ float fc = 0.71f;
+ float t2 = t * t;
+ float t3 = t2 * t;
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+}
+
+__device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float t)
+{
+ int flag = kernel_data.curve_kernel_data.curveflags;
+ float3 P = ray->P;
+ float3 D = ray->D;
+
+ if(isect->object != ~0) {
+#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);
+ }
+
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + isect->segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+ float l = 1.0f;
+ float3 tg = normalize_len(float4_to_float3(P2 - P1),&l);
+ float r1 = P1.w;
+ float r2 = P2.w;
+ float gd = ((r2 - r1)/l);
+
+ P = P + D*t;
+
+ if(flag & CURVE_KN_INTERPOLATE) {
+ int ka = max(k0 - 1,__float_as_int(v00.x));
+ int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P0 = kernel_tex_fetch(__curve_keys, ka);
+ float4 P3 = kernel_tex_fetch(__curve_keys, kb);
+
+ float3 p[4];
+ p[0] = float4_to_float3(P0);
+ p[1] = float4_to_float3(P1);
+ p[2] = float4_to_float3(P2);
+ p[3] = float4_to_float3(P3);
+
+ tg = normalize(curvetangent(isect->u,p[0],p[1],p[2],p[3]));
+ float3 p_curr = curvepoint(isect->u,p[0],p[1],p[2],p[3]);
+
+#ifdef __UV__
+ sd->u = isect->u;
+ sd->v = 0.0f;
+#endif
+
+ if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_RIBBONS)
+ sd->Ng = normalize(-(D - tg * (dot(tg,D))));
+ else {
+ sd->Ng = normalize(P - p_curr);
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ sd->N = sd->Ng;
+ }
+ else {
+ float3 dif = P - float4_to_float3(P1);
+
+#ifdef __UV__
+ sd->u = dot(dif,tg)/l;
+ sd->v = 0.0f;
+#endif
+
+ if (flag & CURVE_KN_TRUETANGENTGNORMAL) {
+ sd->Ng = -(D - tg * (dot(tg,D) * kernel_data.curve_kernel_data.normalmix));
+ sd->Ng = normalize(sd->Ng);
+ if (flag & CURVE_KN_NORMALCORRECTION) {
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+ else {
+ sd->Ng = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);
+ if (gd != 0.0f) {
+ sd->Ng = sd->Ng - gd * tg ;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+
+ sd->N = sd->Ng;
+
+ if (flag & CURVE_KN_TANGENTGNORMAL && !(flag & CURVE_KN_TRUETANGENTGNORMAL)) {
+ sd->N = -(D - tg * (dot(tg,D) * kernel_data.curve_kernel_data.normalmix));
+ sd->N = normalize(sd->N);
+ if (flag & CURVE_KN_NORMALCORRECTION) {
+ sd->N = sd->N - gd * tg;
+ sd->N = normalize(sd->N);
+ }
+ }
+ if (!(flag & CURVE_KN_TANGENTGNORMAL) && flag & CURVE_KN_TRUETANGENTGNORMAL) {
+ sd->N = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);
+ if (gd != 0.0f) {
+ sd->N = sd->N - gd * tg ;
+ sd->N = normalize(sd->N);
+ }
+ }
+ }
+
+#ifdef __DPDU__
+ /* dPdu/dPdv */
+ sd->dPdu = tg;
+ sd->dPdv = cross(tg,sd->Ng);
+#endif
+
+ if(isect->object != ~0) {
+#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;
+}
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 97d37a8b3f4..f9d5bd3dd3f 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -199,7 +199,6 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D;
-
#endif
}
@@ -214,7 +213,7 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo
#ifdef __CAMERA_MOTION__
/* motion blur */
- if(kernel_data.cam.shuttertime == 0.0f)
+ if(kernel_data.cam.shuttertime == -1.0f)
ray->time = TIME_INVALID;
else
ray->time = 0.5f + 0.5f*(time - 0.5f)*kernel_data.cam.shuttertime;
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 45f653a686c..01bb78e8e1c 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -112,8 +112,8 @@ template<typename T> struct texture_image {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
int ix, iy, nix, niy;
- float tx = frac(x*width, &ix);
- float ty = frac(y*height, &iy);
+ float tx = frac(x*width - 0.5f, &ix);
+ float ty = frac(y*height - 0.5f, &iy);
if(periodic) {
ix = wrap_periodic(ix, width);
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 40bae069dea..9fd065c3cda 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -37,6 +37,7 @@
#define __global
#define __shared __shared__
#define __constant
+#define __may_alias
/* No assert supported for CUDA */
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index a9d18588cc8..abb2f094f5c 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -40,6 +40,7 @@
#define __device
#define __device_inline __device
#define __device_noinline __device __noinline
+#define __may_alias
/* no assert in opencl */
#define kernel_assert(cond)
diff --git a/intern/cycles/kernel/kernel_curve.h b/intern/cycles/kernel/kernel_curve.h
new file mode 100644
index 00000000000..e065717888c
--- /dev/null
+++ b/intern/cycles/kernel/kernel_curve.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+#ifdef __HAIR__
+
+/* curve attributes */
+
+__device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE) {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return kernel_tex_fetch(__attributes_float, offset + sd->prim);
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
+
+ float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
+ float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = 0.0f;
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return 0.0f;
+ }
+}
+
+__device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE) {
+ /* idea: we can't derive any useful differentials here, but for tiled
+ * mipmap image caching it would be useful to avoid reading the highest
+ * detail level always. maybe a derivative based on the hair density
+ * could be computed somehow? */
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+/* hair info node functions */
+
+__device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
+{
+ float r = 0.0f;
+
+ if(sd->segment != ~0) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+ r = (P2.w - P1.w) * sd->u + P1.w;
+ }
+
+ return r*2.0f;
+}
+
+__device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 tgN = make_float3(0.0f,0.0f,0.0f);
+
+ if(sd->segment != ~0) {
+ float normalmix = kernel_data.curve_kernel_data.normalmix;
+
+ tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
+ tgN = normalize(tgN);
+
+ /* need to find suitable scaled gd for corrected normal */
+#if 0
+ if (kernel_data.curve_kernel_data.use_tangent_normal_correction)
+ tgN = normalize(tgN - gd * sd->dPdu);
+#endif
+ }
+
+ return tgN;
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h
index a55f7a7fd75..fc2be342e02 100644
--- a/intern/cycles/kernel/kernel_displace.h
+++ b/intern/cycles/kernel/kernel_displace.h
@@ -35,7 +35,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
/* evaluate */
float3 P = sd.P;
- shader_eval_displacement(kg, &sd);
+ shader_eval_displacement(kg, &sd, SHADER_CONTEXT_MAIN);
out = sd.P - P;
}
else { // SHADER_EVAL_BACKGROUND
@@ -63,7 +63,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
/* evaluate */
int flag = 0; /* we can't know which type of BSDF this is for */
- out = shader_eval_background(kg, &sd, flag);
+ out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
}
shader_release(kg, &sd);
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 6d650a0158d..9787af535bb 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
/* Direction Emission */
-__device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
+__device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
LightSample *ls, float u, float v, float3 I, float t, float time)
{
/* setup shading at emitter */
@@ -42,17 +42,23 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
ray.time = time;
#endif
shader_setup_from_background(kg, &sd, &ray);
- eval = shader_eval_background(kg, &sd, 0);
+ eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
}
else
#endif
{
- shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time);
+#ifdef __HAIR__
+ if(ls->type == LIGHT_STRAND)
+ shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, ls->prim);
+ else
+#endif
+ shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time);
+
ls->Ng = sd.Ng;
/* no path flag, we're evaluating this for all closures. that's weak but
* we'd have to do multiple evaluations otherwise */
- shader_eval_surface(kg, &sd, rando, 0);
+ shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION);
/* evaluate emissive closure */
if(sd.flag & SD_EMISSION)
@@ -60,37 +66,33 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
else
eval = make_float3(0.0f, 0.0f, 0.0f);
}
+
+ eval *= ls->eval_fac;
shader_release(kg, &sd);
return eval;
}
-__device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
+__device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
bool *is_lamp)
{
LightSample ls;
- float pdf = -1.0f;
-
#ifdef __NON_PROGRESSIVE__
if(lindex != -1) {
/* sample position on a specified light */
- light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf);
+ light_select(kg, lindex, randu, randv, sd->P, &ls);
}
else
#endif
{
/* sample a light and position on int */
- light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls, &pdf);
+ light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls);
}
- /* compute pdf */
- if(pdf < 0.0f)
- pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t);
-
- if(pdf == 0.0f)
+ if(ls.pdf == 0.0f)
return false;
/* evaluate closure */
@@ -106,13 +108,13 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf);
- if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) {
+ if(ls.shader & SHADER_USE_MIS) {
/* multiple importance sampling */
- float mis_weight = power_heuristic(pdf, bsdf_pdf);
+ float mis_weight = power_heuristic(ls.pdf, bsdf_pdf);
light_eval *= mis_weight;
}
- bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf));
+ bsdf_eval_mul(eval, light_eval/ls.pdf);
if(bsdf_eval_is_zero(eval))
return false;
@@ -138,19 +140,24 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
ray->t = 0.0f;
}
- *is_lamp = (ls.prim == ~0);
+ /* return if it's a lamp for shadow pass */
+ *is_lamp = (ls.prim == ~0 && ls.type != LIGHT_BACKGROUND);
return true;
}
-/* Indirect Emission */
+/* Indirect Primitive Emission */
-__device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
+__device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
{
/* evaluate emissive closure */
float3 L = shader_emissive_eval(kg, sd);
+#ifdef __HAIR__
+ if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->segment == ~0)) {
+#else
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
+#endif
/* multiple importance sampling, get triangle light pdf,
* and compute weight with respect to BSDF pdf */
float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
@@ -162,15 +169,44 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
return L;
}
+/* Indirect Lamp Emission */
+
+__device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission)
+{
+ LightSample ls;
+ int lamp = lamp_light_eval_sample(kg, randt);
+
+ if(lamp == ~0)
+ return false;
+
+ if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
+ return false;
+
+ /* todo: missing texture coordinates */
+ float u = 0.0f;
+ float v = 0.0f;
+ float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ls.t, ray->time);
+
+ if(!(path_flag & PATH_RAY_MIS_SKIP)) {
+ /* multiple importance sampling, get regular light pdf,
+ * and compute weight with respect to BSDF pdf */
+ float mis_weight = power_heuristic(bsdf_pdf, ls.pdf);
+ L *= mis_weight;
+ }
+
+ *emission = L;
+ return true;
+}
+
/* Indirect Background */
-__device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf)
+__device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf)
{
#ifdef __BACKGROUND__
/* evaluate background closure */
ShaderData sd;
shader_setup_from_background(kg, &sd, ray);
- float3 L = shader_eval_background(kg, &sd, path_flag);
+ float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
shader_release(kg, &sd);
#ifdef __BACKGROUND_MIS__
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 97ae2d3db87..f6fbd3599ad 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -18,49 +18,26 @@
CCL_NAMESPACE_BEGIN
+/* Light Sample result */
+
typedef struct LightSample {
- float3 P;
- float3 D;
- float3 Ng;
- float t;
- float eval_fac;
- int object;
- int prim;
- int shader;
- LightType type;
+ float3 P; /* position on light, or direction for distant light */
+ float3 Ng; /* normal on light */
+ float3 D; /* direction from shading point to light */
+ float t; /* distance to light (FLT_MAX for distant light) */
+ float pdf; /* light sampling probability density function */
+ float eval_fac; /* intensity multiplier */
+ int object; /* object id for triangle/curve lights */
+ int prim; /* primitive id for triangle/curve ligths */
+ int shader; /* shader id */
+ int lamp; /* lamp id */
+ LightType type; /* type of light */
} LightSample;
-/* Regular Light */
-
-__device float3 disk_light_sample(float3 v, float randu, float randv)
-{
- float3 ru, rv;
-
- make_orthonormals(v, &ru, &rv);
- to_unit_disk(&randu, &randv);
-
- return ru*randu + rv*randv;
-}
-
-__device float3 distant_light_sample(float3 D, float size, float randu, float randv)
-{
- return normalize(D + disk_light_sample(D, randu, randv)*size);
-}
-
-__device float3 sphere_light_sample(float3 P, float3 center, float size, float randu, float randv)
-{
- return disk_light_sample(normalize(P - center), randu, randv)*size;
-}
-
-__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
-{
- randu = randu - 0.5f;
- randv = randv - 0.5f;
-
- return axisu*randu + axisv*randv;
-}
+/* Background Light */
#ifdef __BACKGROUND_MIS__
+
__device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
{
/* for the following, the CDF values are actually a pair of floats, with the
@@ -169,33 +146,105 @@ __device float background_light_pdf(KernelGlobals *kg, float3 direction)
}
#endif
-__device void regular_light_sample(KernelGlobals *kg, int point,
- float randu, float randv, float3 P, LightSample *ls, float *pdf)
+/* Regular Light */
+
+__device float3 disk_light_sample(float3 v, float randu, float randv)
+{
+ float3 ru, rv;
+
+ make_orthonormals(v, &ru, &rv);
+ to_unit_disk(&randu, &randv);
+
+ return ru*randu + rv*randv;
+}
+
+__device float3 distant_light_sample(float3 D, float radius, float randu, float randv)
+{
+ return normalize(D + disk_light_sample(D, randu, randv)*radius);
+}
+
+__device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
+{
+ return disk_light_sample(normalize(P - center), randu, randv)*radius;
+}
+
+__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
+{
+ randu = randu - 0.5f;
+ randv = randv - 0.5f;
+
+ return axisu*randu + axisv*randv;
+}
+
+__device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls)
+{
+ float3 dir = make_float3(data2.y, data2.z, data2.w);
+ float3 I = ls->Ng;
+
+ float spot_angle = data1.w;
+ float spot_smooth = data2.x;
+
+ float attenuation = dot(dir, I);
+
+ if(attenuation <= spot_angle) {
+ attenuation = 0.0f;
+ }
+ else {
+ float t = attenuation - spot_angle;
+
+ if(t < spot_smooth && spot_smooth != 0.0f)
+ attenuation *= smoothstepf(t/spot_smooth);
+ }
+
+ return attenuation;
+}
+
+__device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
+{
+ float cos_pi = dot(Ng, I);
+
+ if(cos_pi <= 0.0f)
+ return 0.0f;
+
+ return t*t/cos_pi;
+}
+
+__device void lamp_light_sample(KernelGlobals *kg, int lamp,
+ float randu, float randv, float3 P, LightSample *ls)
{
- float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0);
- float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1);
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
LightType type = (LightType)__float_as_int(data0.x);
ls->type = type;
+ ls->shader = __float_as_int(data1.x);
+ ls->object = ~0;
+ ls->prim = ~0;
+ ls->lamp = lamp;
if(type == LIGHT_DISTANT) {
/* distant light */
- float3 D = make_float3(data0.y, data0.z, data0.w);
- float size = data1.y;
+ float3 lightD = make_float3(data0.y, data0.z, data0.w);
+ float3 D = lightD;
+ float radius = data1.y;
+ float invarea = data1.w;
- if(size > 0.0f)
- D = distant_light_sample(D, size, randu, randv);
+ if(radius > 0.0f)
+ D = distant_light_sample(D, radius, randu, randv);
ls->P = D;
ls->Ng = D;
ls->D = -D;
ls->t = FLT_MAX;
- ls->eval_fac = 1.0f;
+
+ float costheta = dot(lightD, D);
+ ls->pdf = invarea/(costheta*costheta*costheta);
+ ls->eval_fac = ls->pdf*kernel_data.integrator.inv_pdf_lights;
}
#ifdef __BACKGROUND_MIS__
else if(type == LIGHT_BACKGROUND) {
/* infinite area light (e.g. light dome or env light) */
- float3 D = background_light_sample(kg, randu, randv, pdf);
+ float3 D = background_light_sample(kg, randu, randv, &ls->pdf);
ls->P = D;
ls->Ng = D;
@@ -207,125 +256,266 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
else {
ls->P = make_float3(data0.y, data0.z, data0.w);
- if(type == LIGHT_POINT) {
- float size = data1.y;
-
- /* sphere light */
- if(size > 0.0f)
- ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
-
- ls->Ng = normalize(P - ls->P);
- ls->eval_fac = 0.25f*M_1_PI_F;
- }
- else if(type == LIGHT_SPOT) {
- float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
- float size = data1.y;
-
- /* spot light */
- if(size > 0.0f)
- ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
+ if(type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float radius = data1.y;
- float3 dir = make_float3(data1.z, data1.w, data2.x);
- float3 I = normalize(P - ls->P);
+ if(radius > 0.0f)
+ /* sphere light */
+ ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
- float spot_angle = data2.y;
- float spot_smooth = data2.z;
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->Ng = -ls->D;
- float eval_fac = dot(dir, I);
+ float invarea = data1.z;
+ ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
+ ls->pdf = invarea;
- if(eval_fac <= spot_angle) {
- eval_fac = 0.0f;
+ if(type == LIGHT_SPOT) {
+ /* spot light attentuation */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
}
- else {
- float t = eval_fac - spot_angle;
-
- if(t < spot_smooth && spot_smooth != 0.0f)
- eval_fac *= smoothstepf(t/spot_smooth);
- }
-
- ls->Ng = I;
- ls->eval_fac = eval_fac*0.25f*M_1_PI_F;
}
else {
/* area light */
- float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
- float4 data3 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 3);
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
- float3 axisu = make_float3(data1.y, data1.z, data2.w);
+ float3 axisu = make_float3(data1.y, data1.z, data1.w);
float3 axisv = make_float3(data2.y, data2.z, data2.w);
float3 D = make_float3(data3.y, data3.z, data3.w);
ls->P += area_light_sample(axisu, axisv, randu, randv);
ls->Ng = D;
- ls->eval_fac = 0.25f;
+ ls->D = normalize_len(ls->P - P, &ls->t);
+
+ float invarea = data2.x;
+
+ ls->eval_fac = 0.25f*invarea;
+ ls->pdf = invarea;
}
- ls->t = 0.0f;
+ ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
+}
+__device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
+{
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
+
+ LightType type = (LightType)__float_as_int(data0.x);
+ ls->type = type;
ls->shader = __float_as_int(data1.x);
ls->object = ~0;
ls->prim = ~0;
-}
+ ls->lamp = lamp;
-__device float regular_light_pdf(KernelGlobals *kg,
- const float3 Ng, const float3 I, float t)
-{
- float pdf = kernel_data.integrator.pdf_lights;
+ if(!(ls->shader & SHADER_USE_MIS))
+ return false;
- if(t == FLT_MAX)
- return pdf;
+ if(type == LIGHT_DISTANT) {
+ /* distant light */
+ float radius = data1.y;
+
+ if(radius == 0.0f)
+ return false;
+ if(t != FLT_MAX)
+ return false;
+
+ /* a distant light is infinitely far away, but equivalent to a disk
+ * shaped light exactly 1 unit away from the current shading point.
+ *
+ * radius t^2/cos(theta)
+ * <----------> t = sqrt(1^2 + tan(theta)^2)
+ * tan(th) area = radius*radius*pi
+ * <----->
+ * \ | (1 + tan(theta)^2)/cos(theta)
+ * \ | (1 + tan(acos(cos(theta)))^2)/cos(theta)
+ * t \th| 1 simplifies to
+ * \-| 1/(cos(theta)^3)
+ * \| magic!
+ * P
+ */
+
+ float3 lightD = make_float3(data0.y, data0.z, data0.w);
+ float costheta = dot(-lightD, D);
+ float cosangle = data1.z;
+
+ if(costheta < cosangle)
+ return false;
+
+ ls->P = -D;
+ ls->Ng = -D;
+ ls->D = D;
+ ls->t = FLT_MAX;
- float cos_pi = dot(Ng, I);
+ float invarea = data1.w;
+ ls->pdf = invarea/(costheta*costheta*costheta);
+ ls->eval_fac = ls->pdf;
+ }
+ else if(type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float3 lightP = make_float3(data0.y, data0.z, data0.w);
+ float radius = data1.y;
- if(cos_pi <= 0.0f)
- return 0.0f;
+ /* sphere light */
+ if(radius == 0.0f)
+ return false;
- return t*t*pdf/cos_pi;
+ if(!ray_aligned_disk_intersect(P, D, t,
+ lightP, radius, &ls->P, &ls->t))
+ return false;
+
+ ls->Ng = -D;
+ ls->D = D;
+
+ float invarea = data1.z;
+ ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
+ ls->pdf = invarea;
+
+ if(type == LIGHT_SPOT) {
+ /* spot light attentuation */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
+
+ if(ls->eval_fac == 0.0f)
+ return false;
+ }
+ }
+ else if(type == LIGHT_AREA) {
+ /* area light */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
+
+ float invarea = data2.x;
+ if(invarea == 0.0f)
+ return false;
+
+ float3 axisu = make_float3(data1.y, data1.z, data1.w);
+ float3 axisv = make_float3(data2.y, data2.z, data2.w);
+ float3 Ng = make_float3(data3.y, data3.z, data3.w);
+
+ /* one sided */
+ if(dot(D, Ng) >= 0.0f)
+ return false;
+
+ ls->P = make_float3(data0.y, data0.z, data0.w);
+
+ if(!ray_quad_intersect(P, D, t,
+ ls->P, axisu, axisv, &ls->P, &ls->t))
+ return false;
+
+ ls->D = D;
+ ls->Ng = Ng;
+ ls->pdf = invarea;
+ ls->eval_fac = 0.25f*ls->pdf;
+ }
+ else
+ return false;
+
+ /* compute pdf */
+ if(ls->t != FLT_MAX)
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
+
+ return true;
}
/* Triangle Light */
-__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
- float randu, float randv, float time, LightSample *ls)
+__device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls, int object, float time)
{
- /* triangle, so get position, normal, shader */
- ls->P = triangle_sample_MT(kg, prim, randu, randv);
- ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
- ls->object = object;
- ls->prim = prim;
- ls->t = 0.0f;
- ls->type = LIGHT_AREA;
- ls->eval_fac = 1.0f;
-
#ifdef __INSTANCING__
/* instance transform */
- if(ls->object >= 0) {
+ if(object >= 0) {
#ifdef __OBJECT_MOTION__
Transform itfm;
Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm);
#else
- Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM);
- Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
ls->P = transform_point(&tfm, ls->P);
- ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng));
+ ls->Ng = normalize(transform_direction(&tfm, ls->Ng));
}
#endif
}
+__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
+ float randu, float randv, float time, LightSample *ls)
+{
+ /* triangle, so get position, normal, shader */
+ ls->P = triangle_sample_MT(kg, prim, randu, randv);
+ ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
+ ls->object = object;
+ ls->prim = prim;
+ ls->lamp = ~0;
+ ls->shader |= SHADER_USE_MIS;
+ ls->t = 0.0f;
+ ls->type = LIGHT_TRIANGLE;
+ ls->eval_fac = 1.0f;
+
+ object_transform_light_sample(kg, ls, object, time);
+}
+
__device float triangle_light_pdf(KernelGlobals *kg,
const float3 Ng, const float3 I, float t)
{
+ float pdf = kernel_data.integrator.pdf_triangles;
float cos_pi = fabsf(dot(Ng, I));
if(cos_pi == 0.0f)
return 0.0f;
- return (t*t*kernel_data.integrator.pdf_triangles)/cos_pi;
+ return t*t*pdf/cos_pi;
}
+/* Curve Light */
+
+#ifdef __HAIR__
+
+__device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
+ int segment, float randu, float randv, float time, LightSample *ls)
+{
+ /* this strand code needs completion */
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+
+ float l = len(P2 - P1);
+
+ float r1 = P1.w;
+ float r2 = P2.w;
+ float3 tg = float4_to_float3(P2 - P1) / l;
+ float3 xc = make_float3(tg.x * tg.z, tg.y * tg.z, -(tg.x * tg.x + tg.y * tg.y));
+ if (dot(xc, xc) == 0.0f)
+ xc = make_float3(tg.x * tg.y, -(tg.x * tg.x + tg.z * tg.z), tg.z * tg.y);
+ xc = normalize(xc);
+ float3 yc = cross(tg, xc);
+ float gd = ((r2 - r1)/l);
+
+ /* normal currently ignores gradient */
+ ls->Ng = sinf(2 * M_PI_F * randv) * xc + cosf(2 * M_PI_F * randv) * yc;
+ ls->P = randu * l * tg + (gd * l + r1) * ls->Ng;
+ ls->object = object;
+ ls->prim = prim;
+ ls->lamp = ~0;
+ ls->t = 0.0f;
+ ls->type = LIGHT_STRAND;
+ ls->eval_fac = 1.0f;
+ ls->shader = __float_as_int(v00.z) | SHADER_USE_MIS;
+
+ object_transform_light_sample(kg, ls, object, time);
+}
+
+#endif
+
/* Light Distribution */
__device int light_distribution_sample(KernelGlobals *kg, float randt)
@@ -357,7 +547,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
/* Generic Light */
-__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls, float *pdf)
+__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
{
/* sample index */
int index = light_distribution_sample(kg, randt);
@@ -368,28 +558,25 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
if(prim >= 0) {
int object = __float_as_int(l.w);
- triangle_light_sample(kg, prim, object, randu, randv, time, ls);
+#ifdef __HAIR__
+ int segment = __float_as_int(l.z);
+#endif
+
+#ifdef __HAIR__
+ if (segment != ~0)
+ curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
+ else
+#endif
+ triangle_light_sample(kg, prim, object, randu, randv, time, ls);
+
+ /* compute incoming direction, distance and pdf */
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
else {
- int point = -prim-1;
- regular_light_sample(kg, point, randu, randv, P, ls, pdf);
+ int lamp = -prim-1;
+ lamp_light_sample(kg, lamp, randu, randv, P, ls);
}
-
- /* compute incoming direction and distance */
- if(ls->t != FLT_MAX)
- ls->D = normalize_len(ls->P - P, &ls->t);
-}
-
-__device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
-{
- float pdf;
-
- if(ls->prim != ~0)
- pdf = triangle_light_pdf(kg, ls->Ng, I, t);
- else
- pdf = regular_light_pdf(kg, ls->Ng, I, t);
-
- return pdf;
}
__device int light_select_num_samples(KernelGlobals *kg, int index)
@@ -398,18 +585,26 @@ __device int light_select_num_samples(KernelGlobals *kg, int index)
return __float_as_int(data3.x);
}
-__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf)
+__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls)
{
- regular_light_sample(kg, index, randu, randv, P, ls, pdf);
-
- /* compute incoming direction and distance */
- if(ls->t != FLT_MAX)
- ls->D = normalize_len(ls->P - P, &ls->t);
+ lamp_light_sample(kg, index, randu, randv, P, ls);
}
-__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
+__device int lamp_light_eval_sample(KernelGlobals *kg, float randt)
{
- return regular_light_pdf(kg, ls->Ng, I, t);
+ /* sample index */
+ int index = light_distribution_sample(kg, randt);
+
+ /* fetch light data */
+ float4 l = kernel_tex_fetch(__light_distribution, index);
+ int prim = __float_as_int(l.y);
+
+ if(prim < 0) {
+ int lamp = -prim-1;
+ return lamp;
+ }
+ else
+ return ~0;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index 48d1aa64c9f..fb66501c336 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -105,6 +105,22 @@ __device_inline void sample_uniform_hemisphere(const float3 N,
*pdf = 0.5f * M_1_PI_F;
}
+__device_inline void sample_uniform_cone(const float3 N, float angle,
+ float randu, float randv,
+ float3 *omega_in, float *pdf)
+{
+ float z = cosf(angle*randu);
+ float r = sqrtf(max(0.0f, 1.0f - z*z));
+ float phi = 2.0f * M_PI_F * randv;
+ float x = r * cosf(phi);
+ float y = r * sinf(phi);
+
+ float3 T, B;
+ make_orthonormals (N, &T, &B);
+ *omega_in = x * T + y * B + z * N;
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(angle));
+}
+
__device float3 sample_uniform_sphere(float u1, float u2)
{
float z = 1.0f - 2.0f*u1;
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index 2b38544e527..40aa4753daa 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -20,11 +20,16 @@ CCL_NAMESPACE_BEGIN
enum ObjectTransform {
OBJECT_TRANSFORM = 0,
- OBJECT_INVERSE_TRANSFORM = 3,
- OBJECT_PROPERTIES = 6,
- OBJECT_TRANSFORM_MOTION_PRE = 8,
- OBJECT_TRANSFORM_MOTION_POST = 12,
- OBJECT_DUPLI = 16
+ OBJECT_TRANSFORM_MOTION_PRE = 0,
+ OBJECT_INVERSE_TRANSFORM = 4,
+ OBJECT_TRANSFORM_MOTION_POST = 4,
+ OBJECT_PROPERTIES = 8,
+ OBJECT_DUPLI = 9
+};
+
+enum ObjectVectorTransform {
+ OBJECT_VECTOR_MOTION_PRE = 0,
+ OBJECT_VECTOR_MOTION_POST = 3
};
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
@@ -40,6 +45,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object,
return tfm;
}
+__device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type)
+{
+ int offset = object*OBJECT_VECTOR_SIZE + (int)type;
+
+ Transform tfm;
+ tfm.x = kernel_tex_fetch(__objects_vector, offset + 0);
+ tfm.y = kernel_tex_fetch(__objects_vector, offset + 1);
+ tfm.z = kernel_tex_fetch(__objects_vector, offset + 2);
+ tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
+
+ return tfm;
+}
+
#ifdef __OBJECT_MOTION__
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
{
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 7f8b611ba14..57dbdc2ffc1 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -70,11 +70,11 @@ __device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal);
}
if(flag & PASS_UV) {
- float3 uv = triangle_uv(kg, sd);
+ float3 uv = primitive_uv(kg, sd);
kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv);
}
if(flag & PASS_MOTION) {
- float4 speed = triangle_motion_vector(kg, sd);
+ float4 speed = primitive_motion_vector(kg, sd);
kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, sample, speed);
kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, sample, 1.0f);
}
@@ -125,14 +125,7 @@ __device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission);
if(flag & PASS_SHADOW) {
float4 shadow = L->shadow;
-
- /* bit of an ugly hack to compensate for emitting triangles influencing
- * amount of samples we get for this pass */
- if(kernel_data.integrator.progressive && kernel_data.integrator.pdf_triangles != 0.0f)
- shadow.w = 0.5f;
- else
- shadow.w = 1.0f;
-
+ shadow.w = kernel_data.film.pass_shadow_scale;
kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, sample, shadow);
}
#endif
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 3588b09c790..865ba7ca676 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -24,14 +24,11 @@
#include "kernel_montecarlo.h"
#include "kernel_projection.h"
#include "kernel_object.h"
-#include "kernel_attribute.h"
-#include "kernel_projection.h"
#include "kernel_triangle.h"
-#ifdef __QBVH__
-#include "kernel_qbvh.h"
-#else
+#include "kernel_curve.h"
+#include "kernel_primitive.h"
+#include "kernel_projection.h"
#include "kernel_bvh.h"
-#endif
#include "kernel_accumulate.h"
#include "kernel_camera.h"
#include "kernel_shader.h"
@@ -207,7 +204,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, ray);
- shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
+ shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
throughput *= shader_bsdf_transparency(kg, &sd);
@@ -237,6 +234,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
float min_ray_pdf = FLT_MAX;
float ray_pdf = 0.0f;
+#ifdef __LAMP_MIS__
+ float ray_t = 0.0f;
+#endif
PathState state;
int rng_offset = PRNG_BASE_NUM;
@@ -247,8 +247,29 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect);
- if(!scene_intersect(kg, &ray, visibility, &isect)) {
+#ifdef __LAMP_MIS__
+ if(kernel_data.integrator.use_lamp_mis && !(state.flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray.P - ray_t*ray.D;
+ ray_t += isect.t;
+ light_ray.D = ray.D;
+ light_ray.t = ray_t;
+ light_ray.time = ray.time;
+
+ /* intersect with lamp */
+ float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
+ float3 emission;
+
+ if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission))
+ path_radiance_accum_emission(&L, throughput, emission, state.bounce);
+ }
+#endif
+
+ if(!hit) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
L_transparent += average(throughput);
@@ -272,7 +293,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
- shader_eval_surface(kg, &sd, rbsdf, state.flag);
+ shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
@@ -312,7 +333,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ /* todo: is isect.t wrong here for transparent surfaces? */
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
@@ -385,7 +407,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
- path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp);
+ path_radiance_accum_light(&L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp);
}
}
}
@@ -421,6 +443,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
/* set labels */
if(!(label & LABEL_TRANSPARENT)) {
ray_pdf = bsdf_pdf;
+#ifdef __LAMP_MIS__
+ ray_t = 0.0f;
+#endif
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
}
@@ -456,15 +481,41 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __NON_PROGRESSIVE__
__device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer,
- float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
+ float3 throughput, float throughput_normalize,
+ float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
{
+#ifdef __LAMP_MIS__
+ float ray_t = 0.0f;
+#endif
+
/* path iteration */
for(;; rng_offset += PRNG_BOUNCE_NUM) {
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect);
- if(!scene_intersect(kg, &ray, visibility, &isect)) {
+#ifdef __LAMP_MIS__
+ if(kernel_data.integrator.use_lamp_mis && !(state.flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray.P - ray_t*ray.D;
+ ray_t += isect.t;
+ light_ray.D = ray.D;
+ light_ray.t = ray_t;
+ light_ray.time = ray.time;
+
+ /* intersect with lamp */
+ float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
+ float3 emission;
+
+ if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission))
+ path_radiance_accum_emission(L, throughput, emission, state.bounce);
+ }
+#endif
+
+ if(!hit) {
#ifdef __BACKGROUND__
/* sample background shader */
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf);
@@ -478,7 +529,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
- shader_eval_surface(kg, &sd, rbsdf, state.flag);
+ shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
shader_merge_closures(kg, &sd);
/* blurring of bsdf after bounces, for rays that have a small likelihood
@@ -495,7 +546,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(L, throughput, emission, state.bounce);
}
#endif
@@ -503,7 +554,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_terminate_probability(kg, &state, throughput);
+ float probability = path_state_terminate_probability(kg, &state, throughput*throughput_normalize);
float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
if(terminate >= probability) {
@@ -569,7 +620,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
- path_radiance_accum_light(L, throughput, &L_light, shadow, state.bounce, is_lamp);
+ path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp);
}
}
}
@@ -605,6 +656,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
/* set labels */
if(!(label & LABEL_TRANSPARENT)) {
ray_pdf = bsdf_pdf;
+#ifdef __LAMP_MIS__
+ ray_t = 0.0f;
+#endif
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
}
@@ -666,7 +720,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
- shader_eval_surface(kg, &sd, rbsdf, state.flag);
+ shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
shader_merge_closures(kg, &sd);
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
@@ -696,7 +750,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
@@ -783,7 +837,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
- path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
+ path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state.bounce, is_lamp);
}
}
}
@@ -812,7 +866,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
- path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
+ path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state.bounce, is_lamp);
}
}
}
@@ -884,8 +938,14 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
bsdf_ray.time = sd.time;
#endif
- kernel_path_indirect(kg, rng, sample*num_samples, bsdf_ray, buffer,
- tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
+ kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer,
+ tp*num_samples_inv, num_samples,
+ min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
+
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(&L);
+ path_radiance_reset_indirect(&L);
}
}
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h
new file mode 100644
index 00000000000..323394cd9dc
--- /dev/null
+++ b/intern/cycles/kernel/kernel_primitive.h
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+#ifndef __KERNEL_ATTRIBUTE_CL__
+#define __KERNEL_ATTRIBUTE_CL__
+
+CCL_NAMESPACE_BEGIN
+
+/* attribute lookup */
+
+__device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, AttributeElement *elem)
+{
+ if(sd->object == ~0)
+ return (int)ATTR_STD_NOT_FOUND;
+
+#ifdef __OSL__
+ if (kg->osl) {
+ return OSLShader::find_attribute(kg, sd, id, elem);
+ }
+ else
+#endif
+ {
+ /* for SVM, find attribute by unique id */
+ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+#ifdef __HAIR__
+ attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+#endif
+ 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;
+ }
+}
+
+__device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+#ifdef __HAIR__
+ if(sd->segment == ~0)
+#endif
+ return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+#ifdef __HAIR__
+ else
+ return curve_attribute_float(kg, sd, elem, offset, dx, dy);
+#endif
+}
+
+__device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+#ifdef __HAIR__
+ if(sd->segment == ~0)
+#endif
+ return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+#ifdef __HAIR__
+ else
+ return curve_attribute_float3(kg, sd, elem, offset, dx, dy);
+#endif
+}
+
+__device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
+{
+ AttributeElement elem_uv;
+ int offset_uv = find_attribute(kg, sd, ATTR_STD_UV, &elem_uv);
+
+ if(offset_uv == ATTR_STD_NOT_FOUND)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 uv = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, NULL, NULL);
+ uv.z = 1.0f;
+ return uv;
+}
+
+__device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
+{
+#ifdef __HAIR__
+ if(sd->segment != ~0)
+ return normalize(sd->dPdu);
+#endif
+
+ /* try to create spherical tangent from generated coordinates */
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED, &attr_elem);
+
+ if(attr_offset != ATTR_STD_NOT_FOUND) {
+ float3 data = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
+ data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
+ object_normal_transform(kg, sd, &data);
+ return cross(sd->N, normalize(cross(data, sd->N)));
+ }
+ else {
+ /* otherwise use surface derivatives */
+ return normalize(sd->dPdu);
+ }
+}
+
+/* motion */
+
+__device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 motion_pre = sd->P, motion_post = sd->P;
+
+ /* deformation motion */
+ AttributeElement elem_pre, elem_post;
+ int offset_pre = find_attribute(kg, sd, ATTR_STD_MOTION_PRE, &elem_pre);
+ int offset_post = find_attribute(kg, sd, ATTR_STD_MOTION_POST, &elem_post);
+
+ if(offset_pre != ATTR_STD_NOT_FOUND)
+ motion_pre = primitive_attribute_float3(kg, sd, elem_pre, offset_pre, NULL, NULL);
+ if(offset_post != ATTR_STD_NOT_FOUND)
+ motion_post = primitive_attribute_float3(kg, sd, elem_post, offset_post, NULL, NULL);
+
+ /* object motion. note that depending on the mesh having motion vectors, this
+ * transformation was set match the world/object space of motion_pre/post */
+ Transform tfm;
+
+ tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_PRE);
+ motion_pre = transform_point(&tfm, motion_pre);
+
+ tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST);
+ motion_post = transform_point(&tfm, motion_post);
+
+ float3 P;
+
+ /* camera motion, for perspective/orthographic motion.pre/post will be a
+ * world-to-raster matrix, for panorama it's world-to-camera */
+ if (kernel_data.cam.type != CAMERA_PANORAMA) {
+ tfm = kernel_data.cam.worldtoraster;
+ P = transform_perspective(&tfm, sd->P);
+
+ tfm = kernel_data.cam.motion.pre;
+ motion_pre = transform_perspective(&tfm, motion_pre);
+
+ tfm = kernel_data.cam.motion.post;
+ motion_post = transform_perspective(&tfm, motion_post);
+ }
+ else {
+ tfm = kernel_data.cam.worldtocamera;
+ P = normalize(transform_point(&tfm, sd->P));
+ P = float2_to_float3(direction_to_panorama(kg, P));
+ P.x *= kernel_data.cam.width;
+ P.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion.pre;
+ motion_pre = normalize(transform_point(&tfm, motion_pre));
+ motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre));
+ motion_pre.x *= kernel_data.cam.width;
+ motion_pre.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion.post;
+ motion_post = normalize(transform_point(&tfm, motion_post));
+ motion_post = float2_to_float3(direction_to_panorama(kg, motion_post));
+ motion_post.x *= kernel_data.cam.width;
+ motion_post.y *= kernel_data.cam.height;
+ }
+
+ motion_pre = motion_pre - P;
+ motion_post = P - motion_post;
+
+ return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 98a7ec59d7b..df86b352697 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -26,11 +26,11 @@
*
*/
+#include "closure/bsdf_util.h"
#include "closure/bsdf.h"
#include "closure/emissive.h"
#include "closure/volume.h"
-#include "svm/svm_bsdf.h"
#include "svm/svm.h"
CCL_NAMESPACE_BEGIN
@@ -53,32 +53,14 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD
}
#endif
-__device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
+__device_noinline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::init(kg, sd);
-#endif
-
- /* fetch triangle data */
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 Ns = kernel_tex_fetch(__tri_normal, prim);
- float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
- int shader = __float_as_int(Ns.w);
-
- /* triangle */
#ifdef __INSTANCING__
sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
#endif
- sd->prim = prim;
-#ifdef __UV__
- sd->u = isect->u;
- sd->v = isect->v;
-#endif
- sd->flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
- sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
+ sd->flag = kernel_tex_fetch(__object_flag, sd->object);
/* matrices and time */
#ifdef __OBJECT_MOTION__
@@ -86,23 +68,63 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
sd->time = ray->time;
#endif
- /* vectors */
- sd->P = bvh_triangle_refine(kg, sd, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
- sd->I = -ray->D;
- sd->shader = shader;
+ sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
sd->ray_length = isect->t;
- /* smooth normal */
- if(sd->shader & SHADER_SMOOTH_NORMAL)
- sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+#ifdef __HAIR__
+ if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
+ /* Strand Shader setting*/
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+
+ sd->shader = __float_as_int(curvedata.z);
+ sd->segment = isect->segment;
+
+ float tcorr = isect->t;
+ if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
+ tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
+ sd->ray_length = tcorr;
+ }
+
+ sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
+ }
+ else {
+#endif
+ /* fetch triangle data */
+ float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
+ float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
+ sd->shader = __float_as_int(Ns.w);
+
+#ifdef __HAIR__
+ sd->segment = ~0;
+#endif
+
+#ifdef __UV__
+ sd->u = isect->u;
+ sd->v = isect->v;
+#endif
+
+ /* vectors */
+ sd->P = bvh_triangle_refine(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
+
+ /* smooth normal */
+ if(sd->shader & SHADER_SMOOTH_NORMAL)
+ sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
#ifdef __DPDU__
- /* dPdu/dPdv */
- triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
+ /* dPdu/dPdv */
+ triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
#endif
+#ifdef __HAIR__
+ }
+#endif
+
+ sd->I = -ray->D;
+
+ sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
+
#ifdef __INSTANCING__
if(isect->object != ~0) {
/* instance transform */
@@ -138,26 +160,25 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
/* ShaderData setup from position sampled on mesh */
-__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
+__device_noinline void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I,
- int shader, int object, int prim, float u, float v, float t, float time)
+ int shader, int object, int prim, float u, float v, float t, float time, int segment = ~0)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::init(kg, sd);
-#endif
-
/* vectors */
sd->P = P;
sd->N = Ng;
sd->Ng = Ng;
sd->I = I;
sd->shader = shader;
+#ifdef __HAIR__
+ sd->segment = segment;
+#endif
/* primitive */
#ifdef __INSTANCING__
sd->object = object;
#endif
+ /* currently no access to bvh prim index for strand sd->prim - this will cause errors with needs fixing*/
sd->prim = prim;
#ifdef __UV__
sd->u = u;
@@ -193,8 +214,13 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#endif
/* smooth normal */
+#ifdef __HAIR__
+ if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
+ sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+#else
if(sd->shader & SHADER_SMOOTH_NORMAL) {
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+#endif
#ifdef __INSTANCING__
if(instanced)
@@ -204,10 +230,17 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#ifdef __DPDU__
/* dPdu/dPdv */
+#ifdef __HAIR__
+ if(sd->prim == ~0 || sd->segment != ~0) {
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ }
+#else
if(sd->prim == ~0) {
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
}
+#endif
else {
triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
@@ -250,7 +283,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
/* ShaderData setup for displacement */
-__device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
+__device_noinline void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
int object, int prim, float u, float v)
{
/* Note: no OSLShader::init call here, this is done in shader_setup_from_sample! */
@@ -273,11 +306,6 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
__device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::init(kg, sd);
-#endif
-
/* vectors */
sd->P = ray->D;
sd->N = -sd->P;
@@ -294,6 +322,9 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
sd->object = ~0;
#endif
sd->prim = ~0;
+#ifdef __HAIR__
+ sd->segment = ~0;
+#endif
#ifdef __UV__
sd->u = 0.0f;
sd->v = 0.0f;
@@ -320,36 +351,8 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
#ifdef __MULTI_CLOSURE__
-#ifdef __OSL__
-__device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf,
- int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
-{
- for(int i = 0; i< sd->num_closure; i++) {
- if(i == skip_bsdf)
- continue;
-
- const ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF(sc->type)) {
- float bsdf_pdf = 0.0f;
-
- float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
-
- if(bsdf_pdf != 0.0f) {
- bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
- sum_pdf += bsdf_pdf*sc->sample_weight;
- }
-
- sum_sample_weight += sc->sample_weight;
- }
- }
-
- *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
-}
-#endif
-
-__device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const float3 omega_in, float *pdf,
- int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
+__device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
+ int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
{
for(int i = 0; i< sd->num_closure; i++) {
if(i == skip_bsdf)
@@ -359,11 +362,10 @@ __device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const flo
if(CLOSURE_IS_BSDF(sc->type)) {
float bsdf_pdf = 0.0f;
-
- float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
+ float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
if(bsdf_pdf != 0.0f) {
- bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
+ bsdf_eval_accum(result_eval, sc->type, eval*sc->weight);
sum_pdf += bsdf_pdf*sc->sample_weight;
}
@@ -382,17 +384,12 @@ __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
#ifdef __MULTI_CLOSURE__
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
-#ifdef __OSL__
- if (kg->osl)
- return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
- else
-#endif
- return _shader_bsdf_multi_eval_svm(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+ return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
#else
const ShaderClosure *sc = &sd->closure;
*pdf = 0.0f;
- *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
+ *eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
#endif
}
@@ -439,24 +436,14 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
float3 eval;
*pdf = 0.0f;
-#ifdef __OSL__
- if (kg->osl)
- label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
- else
-#endif
- label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
if(*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
if(sd->num_closure > 1) {
float sweight = sc->sample_weight;
-#ifdef __OSL__
- if (kg->osl)
- _shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
- else
-#endif
- _shader_bsdf_multi_eval_svm(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
+ _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
}
}
@@ -464,7 +451,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
#else
/* sample the single closure that we picked */
*pdf = 0.0f;
- int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
+ int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
*bsdf_eval *= sd->closure.weight;
return label;
#endif
@@ -478,12 +465,7 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
float3 eval;
*pdf = 0.0f;
-#ifdef __OSL__
- if (kg->osl)
- label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
- else
-#endif
- label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
if(*pdf != 0.0f)
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
@@ -497,17 +479,11 @@ __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughnes
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF(sc->type)) {
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::bsdf_blur(sc, roughness);
- else
-#endif
- svm_bsdf_blur(sc, roughness);
- }
+ if(CLOSURE_IS_BSDF(sc->type))
+ bsdf_blur(kg, sc, roughness);
}
#else
- svm_bsdf_blur(&sd->closure, roughness);
+ bsdf_blur(kg, &sd->closure, roughness);
#endif
}
@@ -635,6 +611,16 @@ __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_facto
/* Emission */
+__device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
+{
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::emissive_eval(sd, sc);
+#endif
+
+ return emissive_simple_eval(sd->Ng, sd->I);
+}
+
__device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
{
float3 eval;
@@ -644,18 +630,11 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_EMISSION(sc->type)) {
-#ifdef __OSL__
- if (kg->osl)
- eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
- else
-#endif
- eval += svm_emissive_eval(sd, sc)*sc->weight;
-
- }
+ if(CLOSURE_IS_EMISSION(sc->type))
+ eval += emissive_eval(kg, sd, sc)*sc->weight;
}
#else
- eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
+ eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
#endif
return eval;
@@ -687,11 +666,11 @@ __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
/* Surface Evaluation */
__device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
- float randb, int path_flag)
+ float randb, int path_flag, ShaderContext ctx)
{
#ifdef __OSL__
if (kg->osl)
- OSLShader::eval_surface(kg, sd, randb, path_flag);
+ OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
else
#endif
{
@@ -706,11 +685,11 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
/* Background Evaluation */
-__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
+__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
{
#ifdef __OSL__
if (kg->osl)
- return OSLShader::eval_background(kg, sd, path_flag);
+ return OSLShader::eval_background(kg, sd, path_flag, ctx);
else
#endif
@@ -753,31 +732,25 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
for(int i = 0; i< sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_VOLUME(sc->type)) {
-#ifdef __OSL__
- if (kg->osl)
- eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out);
- else
-#endif
- eval += volume_eval_phase(sc, omega_in, omega_out);
- }
+ if(CLOSURE_IS_VOLUME(sc->type))
+ eval += volume_eval_phase(kg, sc, omega_in, omega_out);
}
return eval;
#else
- return volume_eval_phase(&sd->closure, omega_in, omega_out);
+ return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
#endif
}
/* Volume Evaluation */
__device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
- float randb, int path_flag)
+ float randb, int path_flag, ShaderContext ctx)
{
#ifdef __SVM__
#ifdef __OSL__
if (kg->osl)
- OSLShader::eval_volume(kg, sd, randb, path_flag);
+ OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
else
#endif
svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
@@ -786,13 +759,13 @@ __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
/* Displacement Evaluation */
-__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
+__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
{
/* this will modify sd->P */
#ifdef __SVM__
#ifdef __OSL__
if (kg->osl)
- OSLShader::eval_displacement(kg, sd);
+ OSLShader::eval_displacement(kg, sd, ctx);
else
#endif
svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
@@ -805,8 +778,20 @@ __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
__device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
{
int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 Ns = kernel_tex_fetch(__tri_normal, prim);
- int shader = __float_as_int(Ns.w);
+ int shader = 0;
+
+#ifdef __HAIR__
+ if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
+#endif
+ float4 Ns = kernel_tex_fetch(__tri_normal, prim);
+ shader = __float_as_int(Ns.w);
+#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);
return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
@@ -818,7 +803,6 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
#ifdef __NON_PROGRESSIVE__
__device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
{
-#ifndef __OSL__
/* merge identical closures, better when we sample a single closure at a time */
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sci = &sd->closure[i];
@@ -826,7 +810,11 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
for(int j = i + 1; j < sd->num_closure; j++) {
ShaderClosure *scj = &sd->closure[j];
+#ifdef __OSL__
+ if(!sci->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
+#else
if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
+#endif
sci->weight += scj->weight;
sci->sample_weight += scj->sample_weight;
@@ -838,7 +826,6 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
}
}
}
-#endif
}
#endif
@@ -846,10 +833,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
__device void shader_release(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::release(kg, sd);
-#endif
+ /* nothing to do currently */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_sse2.cpp b/intern/cycles/kernel/kernel_sse2.cpp
new file mode 100644
index 00000000000..e9d482ae5cf
--- /dev/null
+++ b/intern/cycles/kernel/kernel_sse2.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/* Optimized CPU kernel entry points. This file is compiled with SSE2
+ * optimization flags and nearly all functions inlined, while kernel.cpp
+ * is compiled without for other CPU's. */
+
+#ifdef WITH_OPTIMIZED_KERNEL
+
+#include "kernel.h"
+#include "kernel_compat_cpu.h"
+#include "kernel_math.h"
+#include "kernel_types.h"
+#include "kernel_globals.h"
+#include "kernel_film.h"
+#include "kernel_path.h"
+#include "kernel_displace.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Path Tracing */
+
+void kernel_cpu_sse2_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
+{
+ kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride);
+}
+
+/* Tonemapping */
+
+void kernel_cpu_sse2_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, int sample, int resolution, int x, int y, int offset, int stride)
+{
+ kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
+}
+
+/* Shader Evaluate */
+
+void kernel_cpu_sse2_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i)
+{
+ kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
+}
+
+CCL_NAMESPACE_END
+
+#endif
+
diff --git a/intern/cycles/kernel/kernel_optimized.cpp b/intern/cycles/kernel/kernel_sse3.cpp
index 0b662095133..9a8b389cf68 100644
--- a/intern/cycles/kernel/kernel_optimized.cpp
+++ b/intern/cycles/kernel/kernel_sse3.cpp
@@ -35,21 +35,21 @@ CCL_NAMESPACE_BEGIN
/* Path Tracing */
-void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
+void kernel_cpu_sse3_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
{
kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride);
}
/* Tonemapping */
-void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, int sample, int resolution, int x, int y, int offset, int stride)
+void kernel_cpu_sse3_tonemap(KernelGlobals *kg, uchar4 *rgba, float *buffer, int sample, int resolution, int x, int y, int offset, int stride)
{
kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
}
/* Shader Evaluate */
-void kernel_cpu_optimized_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i)
+void kernel_cpu_sse3_shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int i)
{
kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, i);
}
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 4855a948c6e..e27de95e7ab 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -27,6 +27,7 @@
/* bvh */
KERNEL_TEX(float4, texture_float4, __bvh_nodes)
KERNEL_TEX(float4, texture_float4, __tri_woop)
+KERNEL_TEX(uint, texture_uint, __prim_segment)
KERNEL_TEX(uint, texture_uint, __prim_visibility)
KERNEL_TEX(uint, texture_uint, __prim_index)
KERNEL_TEX(uint, texture_uint, __prim_object)
@@ -34,6 +35,7 @@ KERNEL_TEX(uint, texture_uint, __object_node)
/* objects */
KERNEL_TEX(float4, texture_float4, __objects)
+KERNEL_TEX(float4, texture_float4, __objects_vector)
/* triangles */
KERNEL_TEX(float4, texture_float4, __tri_normal)
@@ -41,6 +43,10 @@ KERNEL_TEX(float4, texture_float4, __tri_vnormal)
KERNEL_TEX(float4, texture_float4, __tri_vindex)
KERNEL_TEX(float4, texture_float4, __tri_verts)
+/* curves */
+KERNEL_TEX(float4, texture_float4, __curves)
+KERNEL_TEX(float4, texture_float4, __curve_keys)
+
/* attributes */
KERNEL_TEX(uint4, texture_uint4, __attributes_map)
KERNEL_TEX(float, texture_float, __attributes_float)
diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h
index 0db447289c8..d346137760f 100644
--- a/intern/cycles/kernel/kernel_triangle.h
+++ b/intern/cycles/kernel/kernel_triangle.h
@@ -190,82 +190,5 @@ __device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *s
}
}
-/* motion */
-
-__device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
-{
- float3 motion_pre = sd->P, motion_post = sd->P;
-
- /* deformation motion */
- int offset_pre = find_attribute(kg, sd, ATTR_STD_MOTION_PRE);
- int offset_post = find_attribute(kg, sd, ATTR_STD_MOTION_POST);
-
- if(offset_pre != ATTR_STD_NOT_FOUND)
- motion_pre = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_pre, NULL, NULL);
- if(offset_post != ATTR_STD_NOT_FOUND)
- motion_post = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_post, NULL, NULL);
-
- /* object motion. note that depending on the mesh having motion vectors, this
- * transformation was set match the world/object space of motion_pre/post */
- Transform tfm;
-
- tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_PRE);
- motion_pre = transform_point(&tfm, motion_pre);
-
- tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_POST);
- motion_post = transform_point(&tfm, motion_post);
-
- float3 P;
-
- /* camera motion, for perspective/orthographic motion.pre/post will be a
- * world-to-raster matrix, for panorama it's world-to-camera */
- if (kernel_data.cam.type != CAMERA_PANORAMA) {
- tfm = kernel_data.cam.worldtoraster;
- P = transform_perspective(&tfm, sd->P);
-
- tfm = kernel_data.cam.motion.pre;
- motion_pre = transform_perspective(&tfm, motion_pre);
-
- tfm = kernel_data.cam.motion.post;
- motion_post = transform_perspective(&tfm, motion_post);
- }
- else {
- tfm = kernel_data.cam.worldtocamera;
- P = normalize(transform_point(&tfm, sd->P));
- P = float2_to_float3(direction_to_panorama(kg, P));
- P.x *= kernel_data.cam.width;
- P.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion.pre;
- motion_pre = normalize(transform_point(&tfm, motion_pre));
- motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre));
- motion_pre.x *= kernel_data.cam.width;
- motion_pre.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion.post;
- motion_post = normalize(transform_point(&tfm, motion_post));
- motion_post = float2_to_float3(direction_to_panorama(kg, motion_post));
- motion_post.x *= kernel_data.cam.width;
- motion_post.y *= kernel_data.cam.height;
- }
-
- motion_pre = motion_pre - P;
- motion_post = P - motion_post;
-
- return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
-}
-
-__device float3 triangle_uv(KernelGlobals *kg, ShaderData *sd)
-{
- int offset_uv = find_attribute(kg, sd, ATTR_STD_UV);
-
- if(offset_uv == ATTR_STD_NOT_FOUND)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float3 uv = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, offset_uv, NULL, NULL);
- uv.z = 1.0f;
- return uv;
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index e3a766e56b1..ddbda9240fb 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -29,7 +29,8 @@
CCL_NAMESPACE_BEGIN
/* constants */
-#define OBJECT_SIZE 18
+#define OBJECT_SIZE 11
+#define OBJECT_VECTOR_SIZE 6
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
@@ -42,10 +43,11 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_CPU__
#define __KERNEL_SHADING__
#define __KERNEL_ADV_SHADING__
+#define __NON_PROGRESSIVE__
+#define __HAIR__
#ifdef WITH_OSL
#define __OSL__
#endif
-#define __NON_PROGRESSIVE__
#endif
#ifdef __KERNEL_CUDA__
@@ -110,12 +112,12 @@ CCL_NAMESPACE_BEGIN
#define __TRANSPARENT_SHADOWS__
#define __PASSES__
#define __BACKGROUND_MIS__
+#define __LAMP_MIS__
#define __AO__
-#define __CAMERA_MOTION__
#define __ANISOTROPIC__
+#define __CAMERA_MOTION__
#define __OBJECT_MOTION__
#endif
-
//#define __SOBOL_FULL_SCREEN__
/* Shader Evaluation */
@@ -253,6 +255,10 @@ typedef struct PathRadiance {
float3 indirect_glossy;
float3 indirect_transmission;
+ float3 path_diffuse;
+ float3 path_glossy;
+ float3 path_transmission;
+
float4 shadow;
} PathRadiance;
@@ -279,8 +285,9 @@ typedef enum ShaderFlag {
SHADER_SMOOTH_NORMAL = (1 << 31),
SHADER_CAST_SHADOW = (1 << 30),
SHADER_AREA_LIGHT = (1 << 29),
+ SHADER_USE_MIS = (1 << 28),
- SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT)
+ SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS)
} ShaderFlag;
/* Light Type */
@@ -291,7 +298,9 @@ typedef enum LightType {
LIGHT_BACKGROUND,
LIGHT_AREA,
LIGHT_AO,
- LIGHT_SPOT
+ LIGHT_SPOT,
+ LIGHT_TRIANGLE,
+ LIGHT_STRAND
} LightType;
/* Camera Type */
@@ -342,21 +351,47 @@ typedef struct Intersection {
float t, u, v;
int prim;
int object;
+ int segment;
} Intersection;
/* Attributes */
+#define ATTR_PRIM_TYPES 2
+#define ATTR_PRIM_CURVE 1
+
typedef enum AttributeElement {
+ ATTR_ELEMENT_NONE,
+ ATTR_ELEMENT_VALUE,
ATTR_ELEMENT_FACE,
ATTR_ELEMENT_VERTEX,
ATTR_ELEMENT_CORNER,
- ATTR_ELEMENT_VALUE,
- ATTR_ELEMENT_NONE
+ ATTR_ELEMENT_CURVE,
+ ATTR_ELEMENT_CURVE_KEY
} AttributeElement;
+typedef enum AttributeStandard {
+ ATTR_STD_NONE = 0,
+ ATTR_STD_VERTEX_NORMAL,
+ ATTR_STD_FACE_NORMAL,
+ ATTR_STD_UV,
+ ATTR_STD_UV_TANGENT,
+ ATTR_STD_UV_TANGENT_SIGN,
+ ATTR_STD_GENERATED,
+ ATTR_STD_POSITION_UNDEFORMED,
+ ATTR_STD_POSITION_UNDISPLACED,
+ ATTR_STD_MOTION_PRE,
+ ATTR_STD_MOTION_POST,
+ ATTR_STD_PARTICLE,
+ ATTR_STD_CURVE_TANGENT,
+ ATTR_STD_CURVE_INTERCEPT,
+ ATTR_STD_NUM,
+
+ ATTR_STD_NOT_FOUND = ~0
+} AttributeStandard;
+
/* Closure data */
-#define MAX_CLOSURE 8
+#define MAX_CLOSURE 16
typedef struct ShaderClosure {
ClosureType type;
@@ -379,6 +414,18 @@ typedef struct ShaderClosure {
#endif
} ShaderClosure;
+/* Shader Context
+ *
+ * For OSL we recycle a fixed number of contexts for speed */
+
+typedef enum ShaderContext {
+ SHADER_CONTEXT_MAIN = 0,
+ SHADER_CONTEXT_INDIRECT = 1,
+ SHADER_CONTEXT_EMISSION = 2,
+ SHADER_CONTEXT_SHADOW = 3,
+ SHADER_CONTEXT_NUM = 4
+} ShaderContext;
+
/* Shader Data
*
* Main shader state at a point on the surface or in a volume. All coordinates
@@ -423,6 +470,11 @@ typedef struct ShaderData {
/* primitive id if there is one, ~0 otherwise */
int prim;
+
+#ifdef __HAIR__
+ /* for curves, segment number in curve, ~0 for triangles */
+ int segment;
+#endif
/* parametric coordinates
* - barycentric weights for triangles */
float u, v;
@@ -466,11 +518,6 @@ typedef struct ShaderData {
/* Closure data, with a single sampled closure for low memory usage */
ShaderClosure closure;
#endif
-
-#ifdef __OSL__
- /* OSL context */
- void *osl_ctx;
-#endif
} ShaderData;
/* Constrant Kernel Data
@@ -563,9 +610,9 @@ typedef struct KernelFilm {
int pass_ao;
int pass_shadow;
+ float pass_shadow_scale;
int pass_pad1;
int pass_pad2;
- int pass_pad3;
} KernelFilm;
typedef struct KernelBackground {
@@ -596,6 +643,7 @@ typedef struct KernelIntegrator {
int num_all_lights;
float pdf_triangles;
float pdf_lights;
+ float inv_pdf_lights;
int pdf_background_res;
/* bounces */
@@ -631,7 +679,7 @@ typedef struct KernelIntegrator {
int transmission_samples;
int ao_samples;
int mesh_light_samples;
- int pad1, pad2;
+ int use_lamp_mis;
} KernelIntegrator;
typedef struct KernelBVH {
@@ -642,6 +690,30 @@ typedef struct KernelBVH {
int pad2;
} KernelBVH;
+typedef enum CurveFlag {
+ /* runtime flags */
+ CURVE_KN_BACKFACING = 1, /* backside of cylinder? */
+ CURVE_KN_ENCLOSEFILTER = 2, /* don't consider strands surrounding start point? */
+ CURVE_KN_CURVEDATA = 4, /* curve data available? */
+ CURVE_KN_INTERPOLATE = 8, /* render as a curve? - not supported yet */
+ CURVE_KN_ACCURATE = 16, /* use accurate intersections test? */
+ CURVE_KN_INTERSECTCORRECTION = 32, /* correct for width after determing closest midpoint? */
+ CURVE_KN_POSTINTERSECTCORRECTION = 64, /* correct for width after intersect? */
+ CURVE_KN_NORMALCORRECTION = 128, /* correct tangent normal for slope? */
+ CURVE_KN_TRUETANGENTGNORMAL = 256, /* use tangent normal for geometry? */
+ CURVE_KN_TANGENTGNORMAL = 512, /* use tangent normal for shader? */
+ CURVE_KN_RIBBONS = 1024, /* use flat curve ribbons */
+} CurveFlag;
+
+typedef struct KernelCurves {
+ /* strand intersect and normal parameters - many can be changed to flags*/
+ float normalmix;
+ float encasing_ratio;
+ int curveflags;
+ int subdivisions;
+
+} KernelCurves;
+
typedef struct KernelData {
KernelCamera cam;
KernelFilm film;
@@ -649,6 +721,7 @@ typedef struct KernelData {
KernelSunSky sunsky;
KernelIntegrator integrator;
KernelBVH bvh;
+ KernelCurves curve_kernel_data;
} KernelData;
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt
index 1b1bb558bc9..5a27f7823e4 100644
--- a/intern/cycles/kernel/osl/CMakeLists.txt
+++ b/intern/cycles/kernel/osl/CMakeLists.txt
@@ -14,7 +14,9 @@ set(INC_SYS
set(SRC
background.cpp
+ bsdf_diffuse_ramp.cpp
bsdf_phong_ramp.cpp
+ bsdf_toon.cpp
emissive.cpp
osl_closures.cpp
osl_services.cpp
diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript
index d4b42d2becb..09899567128 100644
--- a/intern/cycles/kernel/osl/SConscript
+++ b/intern/cycles/kernel/osl/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
@@ -21,6 +46,7 @@ defs.append('WITH_OSL')
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
cxxflags.append('-DBOOST_NO_RTTI -DBOOST_NO_TYPEID'.split())
incs.append(env['BF_PTHREADS_INC'])
+ defs.append('OSL_STATIC_LIBRARY')
else:
cxxflags.append('-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID'.split())
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
new file mode 100644
index 00000000000..a320bea118a
--- /dev/null
+++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
@@ -0,0 +1,115 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * 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 Sony Pictures Imageworks 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.
+ */
+
+#include <OpenImageIO/fmath.h>
+
+#include <OSL/genclosure.h>
+
+#include "osl_closures.h"
+
+#include "kernel_types.h"
+#include "kernel_montecarlo.h"
+#include "closure/bsdf_diffuse_ramp.h"
+
+CCL_NAMESPACE_BEGIN
+
+using namespace OSL;
+
+class DiffuseRampClosure : public CBSDFClosure {
+public:
+ DiffuseRampClosure() : CBSDFClosure(LABEL_DIFFUSE) {}
+ Color3 colors[8];
+ float3 fcolors[8];
+
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "diffuse_ramp"; }
+
+ void setup()
+ {
+ sc.prim = this;
+ m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc);
+
+ for(int i = 0; i < 8; i++)
+ fcolors[i] = TO_FLOAT3(colors[i]);
+ }
+
+ bool mergeable(const ClosurePrimitive *other) const
+ {
+ return false;
+ }
+
+ void blur(float roughness)
+ {
+ bsdf_diffuse_ramp_blur(&sc, roughness);
+ }
+
+ void print_on(std::ostream &out) const
+ {
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
+ }
+
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_ramp_eval_reflect(&sc, fcolors, omega_out, omega_in, &pdf);
+ }
+
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_ramp_eval_transmit(&sc, fcolors, omega_out, omega_in, &pdf);
+ }
+
+ int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const
+ {
+ return bsdf_diffuse_ramp_sample(&sc, fcolors, Ng, omega_out, domega_out_dx, domega_out_dy,
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ }
+};
+
+ClosureParam *closure_bsdf_diffuse_ramp_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N),
+ CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(DiffuseRampClosure)
+ };
+ return params;
+}
+
+CLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure)
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index fb144be7e50..ef656ee7d5f 100644
--- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -54,7 +54,7 @@ public:
void setup()
{
- sc.N = TO_FLOAT3(N);
+ sc.prim = this;
m_shaderdata_flag = bsdf_phong_ramp_setup(&sc);
for(int i = 0; i < 8; i++)
@@ -100,7 +100,7 @@ public:
ClosureParam *closure_bsdf_phong_ramp_params()
{
static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(PhongRampClosure, N),
+ CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N),
CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0),
CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
CLOSURE_STRING_KEYPARAM("label"),
diff --git a/intern/cycles/kernel/osl/bsdf_toon.cpp b/intern/cycles/kernel/osl/bsdf_toon.cpp
new file mode 100644
index 00000000000..d409b2cedaf
--- /dev/null
+++ b/intern/cycles/kernel/osl/bsdf_toon.cpp
@@ -0,0 +1,179 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * 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 Sony Pictures Imageworks 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.
+ */
+
+#include <OpenImageIO/fmath.h>
+
+#include <OSL/genclosure.h>
+
+#include "osl_closures.h"
+
+#include "kernel_types.h"
+#include "kernel_montecarlo.h"
+#include "closure/bsdf_toon.h"
+
+CCL_NAMESPACE_BEGIN
+
+using namespace OSL;
+
+/* DIFFUSE TOON */
+
+class DiffuseToonClosure : public CBSDFClosure {
+public:
+ DiffuseToonClosure() : CBSDFClosure(LABEL_DIFFUSE) {}
+
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "diffuse_toon"; }
+
+ void setup()
+ {
+ sc.prim = this;
+ m_shaderdata_flag = bsdf_diffuse_toon_setup(&sc);
+ }
+
+ bool mergeable(const ClosurePrimitive *other) const
+ {
+ return false;
+ }
+
+ void blur(float roughness)
+ {
+ bsdf_diffuse_toon_blur(&sc, roughness);
+ }
+
+ void print_on(std::ostream &out) const
+ {
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
+ }
+
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_toon_eval_reflect(&sc, omega_out, omega_in, &pdf);
+ }
+
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_toon_eval_transmit(&sc, omega_out, omega_in, &pdf);
+ }
+
+ int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const
+ {
+ return bsdf_diffuse_toon_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy,
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ }
+};
+
+ClosureParam *closure_bsdf_diffuse_toon_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, sc.N),
+ CLOSURE_FLOAT_PARAM(DiffuseToonClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(DiffuseToonClosure, sc.data1),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(DiffuseToonClosure)
+ };
+ return params;
+}
+
+CLOSURE_PREPARE(closure_bsdf_diffuse_toon_prepare, DiffuseToonClosure)
+
+/* SPECULAR TOON */
+
+class SpecularToonClosure : public CBSDFClosure {
+public:
+ SpecularToonClosure() : CBSDFClosure(LABEL_GLOSSY) {}
+
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "specular_toon"; }
+
+ void setup()
+ {
+ sc.prim = this;
+ m_shaderdata_flag = bsdf_specular_toon_setup(&sc);
+ }
+
+ bool mergeable(const ClosurePrimitive *other) const
+ {
+ return false;
+ }
+
+ void blur(float roughness)
+ {
+ bsdf_specular_toon_blur(&sc, roughness);
+ }
+
+ void print_on(std::ostream &out) const
+ {
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
+ }
+
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_specular_toon_eval_reflect(&sc, omega_out, omega_in, &pdf);
+ }
+
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_specular_toon_eval_transmit(&sc, omega_out, omega_in, &pdf);
+ }
+
+ int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const
+ {
+ return bsdf_specular_toon_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy,
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ }
+};
+
+ClosureParam *closure_bsdf_specular_toon_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(SpecularToonClosure, sc.N),
+ CLOSURE_FLOAT_PARAM(SpecularToonClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(SpecularToonClosure, sc.data1),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(SpecularToonClosure)
+ };
+ return params;
+}
+
+CLOSURE_PREPARE(closure_bsdf_specular_toon_prepare, SpecularToonClosure)
+
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index 37e3e37c00a..7d9fa81dbdd 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -65,7 +65,7 @@ public:
Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const
{
- float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
+ float3 result = emissive_simple_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
return TO_COLOR3(result);
}
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index f95859d237d..9e65cda1e8f 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -43,12 +43,11 @@
#include "kernel_types.h"
#include "kernel_montecarlo.h"
-#include "closure/bsdf.h"
+#include "closure/bsdf_util.h"
#include "closure/bsdf_ashikhmin_velvet.h"
#include "closure/bsdf_diffuse.h"
#include "closure/bsdf_microfacet.h"
#include "closure/bsdf_oren_nayar.h"
-#include "closure/bsdf_phong_ramp.h"
#include "closure/bsdf_reflection.h"
#include "closure/bsdf_refraction.h"
#include "closure/bsdf_transparent.h"
@@ -62,34 +61,34 @@ using namespace OSL;
/* BSDF class definitions */
BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(DiffuseClosure, N),
+ CLOSURE_FLOAT3_PARAM(DiffuseClosure, sc.N),
BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(TranslucentClosure, N),
+ CLOSURE_FLOAT3_PARAM(TranslucentClosure, sc.N),
BSDF_CLOSURE_CLASS_END(Translucent, translucent)
BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(OrenNayarClosure, N),
+ CLOSURE_FLOAT3_PARAM(OrenNayarClosure, sc.N),
CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR)
- CLOSURE_VECTOR_PARAM(ReflectionClosure, N),
+ CLOSURE_FLOAT3_PARAM(ReflectionClosure, sc.N),
BSDF_CLOSURE_CLASS_END(Reflection, reflection)
BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR)
- CLOSURE_VECTOR_PARAM(RefractionClosure, N),
+ CLOSURE_FLOAT3_PARAM(RefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(Refraction, refraction)
BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N),
+ CLOSURE_FLOAT3_PARAM(WestinBackscatterClosure, sc.N),
CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter)
BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(WestinSheenClosure, N),
+ CLOSURE_FLOAT3_PARAM(WestinSheenClosure, sc.N),
CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen)
@@ -97,35 +96,35 @@ BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR)
BSDF_CLOSURE_CLASS_END(Transparent, transparent)
BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N),
+ CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, sc.N),
CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(WardClosure, N),
- CLOSURE_VECTOR_PARAM(WardClosure, T),
+ CLOSURE_FLOAT3_PARAM(WardClosure, sc.N),
+ CLOSURE_FLOAT3_PARAM(WardClosure, sc.T),
CLOSURE_FLOAT_PARAM(WardClosure, sc.data0),
CLOSURE_FLOAT_PARAM(WardClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(Ward, ward)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
@@ -194,8 +193,14 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
closure_holdout_params(), closure_holdout_prepare);
register_closure(ss, "ambient_occlusion", id++,
closure_ambient_occlusion_params(), closure_ambient_occlusion_prepare);
+ register_closure(ss, "diffuse_ramp", id++,
+ closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare);
register_closure(ss, "phong_ramp", id++,
closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
+ register_closure(ss, "diffuse_toon", id++,
+ closure_bsdf_diffuse_toon_params(), closure_bsdf_diffuse_toon_prepare);
+ register_closure(ss, "specular_toon", id++,
+ closure_bsdf_specular_toon_params(), closure_bsdf_specular_toon_prepare);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 2d91b37be7e..daccc03ede2 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -47,13 +47,19 @@ OSL::ClosureParam *closure_emission_params();
OSL::ClosureParam *closure_background_params();
OSL::ClosureParam *closure_holdout_params();
OSL::ClosureParam *closure_ambient_occlusion_params();
+OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
+OSL::ClosureParam *closure_bsdf_diffuse_toon_params();
+OSL::ClosureParam *closure_bsdf_specular_toon_params();
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_diffuse_toon_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_specular_toon_prepare(OSL::RendererServices *, int id, void *data);
enum {
AmbientOcclusion = 100
@@ -68,8 +74,11 @@ void name(RendererServices *, int id, void *data) \
#define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname)
-#define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
-#define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
+#define CLOSURE_FLOAT3_PARAM(st, fld) \
+ { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
+
+#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
+#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
/* BSDF */
@@ -77,7 +86,6 @@ void name(RendererServices *, int id, void *data) \
class CBSDFClosure : public OSL::ClosurePrimitive {
public:
ShaderClosure sc;
- OSL::Vec3 N, T;
CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
m_scattering_label(scattering), m_shaderdata_flag(0) { }
@@ -85,7 +93,6 @@ public:
int scattering() const { return m_scattering_label; }
int shaderdata_flag() const { return m_shaderdata_flag; }
- ClosureType shaderclosure_type() const { return sc.type; }
virtual void blur(float roughness) = 0;
virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
@@ -112,8 +119,7 @@ public: \
\
void setup() \
{ \
- sc.N = TO_FLOAT3(N); \
- sc.T = TO_FLOAT3(T); \
+ sc.prim = NULL; \
m_shaderdata_flag = bsdf_##lower##_setup(&sc); \
} \
\
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 1a2a210de88..fb569117698 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -75,10 +75,21 @@ struct OSLGlobals {
vector<ustring> object_names;
};
+/* trace() call result */
+struct OSLTraceData {
+ Ray ray;
+ Intersection isect;
+ ShaderData sd;
+ bool setup;
+ bool init;
+};
+
/* thread key for thread specific data lookup */
struct OSLThreadData {
OSL::ShaderGlobals globals;
OSL::PerThreadInfo *thread_info;
+ OSLTraceData tracedata;
+ OSL::ShadingContext *context[SHADER_CONTEXT_NUM];
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index b584a54b1b7..92a023bd765 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -37,9 +37,10 @@
#include "kernel_differential.h"
#include "kernel_object.h"
#include "kernel_bvh.h"
-#include "kernel_attribute.h"
-#include "kernel_projection.h"
#include "kernel_triangle.h"
+#include "kernel_curve.h"
+#include "kernel_primitive.h"
+#include "kernel_projection.h"
#include "kernel_accumulate.h"
#include "kernel_shader.h"
@@ -47,7 +48,7 @@ CCL_NAMESPACE_BEGIN
/* RenderServices implementation */
-#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m))
+#define COPY_MATRIX44(m1, m2) memcpy(m1, m2, sizeof(*m2))
/* static ustrings */
ustring OSLRenderServices::u_distance("distance");
@@ -74,6 +75,11 @@ ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices");
ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
ustring OSLRenderServices::u_geom_name("geom:name");
+#ifdef __HAIR__
+ustring OSLRenderServices::u_is_curve("geom:is_curve");
+ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness");
+ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
+#endif
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
ustring OSLRenderServices::u_trace("trace");
ustring OSLRenderServices::u_hit("hit");
@@ -121,7 +127,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
tfm = transform_transpose(tfm);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -151,7 +157,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
itfm = transform_transpose(itfm);
- result = TO_MATRIX44(itfm);
+ COPY_MATRIX44(&result, &itfm);
return true;
}
@@ -166,22 +172,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
if (from == u_ndc) {
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -194,22 +200,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
if (to == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -232,7 +238,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
tfm = transform_transpose(tfm);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -257,7 +263,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
tfm = transform_transpose(tfm);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -272,22 +278,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
if (from == u_ndc) {
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -300,22 +306,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to)
if (to == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -495,14 +501,14 @@ static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OS
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
{
float3 fval[3];
- fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ fval[0] = primitive_attribute_float3(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float3(fval, type, derivatives, val);
}
else if (attr.type == TypeDesc::TypeFloat) {
float fval[3];
- fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ fval[0] = primitive_attribute_float(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float(fval, type, derivatives, val);
}
else {
@@ -593,10 +599,17 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
float3 f = particle_angular_velocity(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
+
+ /* Geometry Attributes */
else if (name == u_geom_numpolyvertices) {
return set_attribute_int(3, type, derivatives, val);
}
- else if (name == u_geom_trianglevertices || name == u_geom_polyvertices) {
+ else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
+#ifdef __HAIR__
+ && sd->segment == ~0) {
+#else
+ ) {
+#endif
float3 P[3];
triangle_vertices(kg, sd->prim, P);
@@ -612,6 +625,22 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
ustring object_name = kg->osl->object_names[sd->object];
return set_attribute_string(object_name, type, derivatives, val);
}
+
+#ifdef __HAIR__
+ /* Hair Attributes */
+ else if (name == u_is_curve) {
+ float f = (sd->segment != ~0);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_curve_thickness) {
+ float f = curve_thickness(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_curve_tangent_normal) {
+ float3 f = curve_tangent_normal(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+#endif
else
return false;
}
@@ -634,24 +663,34 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
{
KernelGlobals *kg = kernel_globals;
ShaderData *sd = (ShaderData *)renderstate;
- int object = sd->object;
- int tri = sd->prim;
+ int object, prim, segment;
/* lookup of attribute on another object */
- if (object_name != u_empty) {
+ if (object_name != u_empty || sd == NULL) {
OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
if (it == kg->osl->object_name_map.end())
return false;
object = it->second;
- tri = ~0;
+ prim = ~0;
+ segment = ~0;
}
- else if (object == ~0) {
- return get_background_attribute(kg, sd, name, type, derivatives, val);
+ else {
+ object = sd->object;
+ prim = sd->prim;
+#ifdef __HAIR__
+ segment = sd->segment;
+#else
+ segment = ~0;
+#endif
+
+ if (object == ~0)
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
+ object = object*ATTR_PRIM_TYPES + (segment != ~0);
OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
@@ -660,7 +699,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (attr.elem != ATTR_ELEMENT_VALUE) {
/* triangle and vertex attributes */
- if (tri != ~0)
+ if (prim != ~0)
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
}
else {
@@ -815,13 +854,10 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
ray.dD.dy = TO_FLOAT3(dRdy);
/* allocate trace data */
- TraceData *tracedata = new TraceData();
+ OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
tracedata->ray = ray;
tracedata->setup = false;
-
- if(sg->tracedata)
- delete (TraceData*)sg->tracedata;
- sg->tracedata = tracedata;
+ tracedata->init = true;
/* raytrace */
return scene_intersect(kernel_globals, &ray, ~0, &tracedata->isect);
@@ -831,9 +867,9 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
TypeDesc type, void *val, bool derivatives)
{
- TraceData *tracedata = (TraceData*)sg->tracedata;
+ OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
- if(source == u_trace && tracedata) {
+ if(source == u_trace && tracedata->init) {
if(name == u_hit) {
return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
}
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index e687700b383..50c50b9952c 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -106,13 +106,6 @@ public:
static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
TypeDesc type, bool derivatives, void *val);
- struct TraceData {
- Ray ray;
- Intersection isect;
- ShaderData sd;
- bool setup;
- };
-
static ustring u_distance;
static ustring u_index;
static ustring u_camera;
@@ -137,6 +130,9 @@ public:
static ustring u_geom_trianglevertices;
static ustring u_geom_polyvertices;
static ustring u_geom_name;
+ static ustring u_is_curve;
+ static ustring u_curve_thickness;
+ static ustring u_curve_tangent_normal;
static ustring u_path_ray_length;
static ustring u_trace;
static ustring u_hit;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 32712b25e92..a32c526a2be 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -26,9 +26,10 @@
#include "osl_services.h"
#include "osl_shader.h"
-#include "util_attribute.h"
#include "util_foreach.h"
+#include "attribute.h"
+
#include <OSL/oslexec.h>
CCL_NAMESPACE_BEGIN
@@ -51,8 +52,13 @@ void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OS
OSLThreadData *tdata = new OSLThreadData();
memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
+ tdata->globals.tracedata = &tdata->tracedata;
+ tdata->globals.flipHandedness = false;
tdata->thread_info = ss->create_thread_info();
+ for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
+ tdata->context[i] = ss->get_context(tdata->thread_info);
+
kg->osl_ss = (OSLShadingSystem*)ss;
kg->osl_tdata = tdata;
}
@@ -65,6 +71,9 @@ void OSLShader::thread_free(KernelGlobals *kg)
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
OSLThreadData *tdata = kg->osl_tdata;
+ for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
+ ss->release_context(tdata->context[i]);
+
ss->destroy_thread_info(tdata->thread_info);
delete tdata;
@@ -77,8 +86,10 @@ void OSLShader::thread_free(KernelGlobals *kg)
/* Globals */
static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
- int path_flag, OSL::ShaderGlobals *globals)
+ int path_flag, OSLThreadData *tdata)
{
+ OSL::ShaderGlobals *globals = &tdata->globals;
+
/* copy from shader data to shader globals */
globals->P = TO_VEC3(sd->P);
globals->dPdx = TO_VEC3(sd->dP.dx);
@@ -100,15 +111,11 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
globals->time = sd->time;
/* booleans */
- globals->raytype = path_flag; /* todo: add our own ray types */
+ globals->raytype = path_flag;
globals->backfacing = (sd->flag & SD_BACKFACING);
- /* don't know yet if we need this */
- globals->flipHandedness = false;
-
/* shader data to be used in services callbacks */
globals->renderstate = sd;
- globals->tracedata = NULL;
/* hacky, we leave it to services to fetch actual object matrix */
globals->shader2common = sd;
@@ -116,6 +123,9 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
/* must be set to NULL before execute */
globals->Ci = NULL;
+
+ /* clear trace data */
+ tdata->tracedata.init = false;
}
/* Surface */
@@ -132,14 +142,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
if (prim) {
ShaderClosure sc;
- sc.prim = prim;
sc.weight = weight;
switch (prim->category()) {
case OSL::ClosurePrimitive::BSDF: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
CBSDFClosure *bsdf = (CBSDFClosure *)prim;
int scattering = bsdf->scattering();
@@ -151,8 +157,13 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
- sc.type = bsdf->shaderclosure_type();
- sc.N = bsdf->sc.N; /* needed for AO */
+
+ sc.type = bsdf->sc.type;
+ sc.N = bsdf->sc.N;
+ sc.T = bsdf->sc.T;
+ sc.data0 = bsdf->sc.data0;
+ sc.data1 = bsdf->sc.data1;
+ sc.prim = bsdf->sc.prim;
/* add */
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
@@ -162,14 +173,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break;
}
case OSL::ClosurePrimitive::Emissive: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
/* sample weight */
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
sc.type = CLOSURE_EMISSION_ID;
+ sc.prim = NULL;
/* flag */
if(sd->num_closure < MAX_CLOSURE) {
@@ -179,14 +188,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break;
}
case AmbientOcclusion: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
/* sample weight */
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ sc.prim = NULL;
if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc;
@@ -195,11 +202,9 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break;
}
case OSL::ClosurePrimitive::Holdout:
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
sc.sample_weight = 0.0f;
sc.type = CLOSURE_HOLDOUT_ID;
+ sc.prim = NULL;
if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc;
@@ -226,26 +231,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
}
}
-void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
+void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
/* execute shader for this point */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
int shader = sd->shader & SHADER_MASK;
if (kg->osl->surface_state[shader])
- ss->execute(*ctx, *(kg->osl->surface_state[shader]), *globals);
-
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals);
/* flatten closure tree */
sd->num_closure = 0;
@@ -287,24 +286,19 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
return make_float3(0.0f, 0.0f, 0.0f);
}
-float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
+float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
/* execute shader for this point */
- if (kg->osl->background_state)
- ss->execute(*ctx, *(kg->osl->background_state), *globals);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ if (kg->osl->background_state)
+ ss->execute(*octx, *(kg->osl->background_state), *globals);
/* return background color immediately */
if (globals->Ci)
@@ -327,19 +321,16 @@ static void flatten_volume_closure_tree(ShaderData *sd,
if (prim) {
ShaderClosure sc;
- sc.prim = prim;
sc.weight = weight;
switch (prim->category()) {
case OSL::ClosurePrimitive::Volume: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
/* sample weight */
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
sc.type = CLOSURE_VOLUME_ID;
+ sc.prim = NULL;
/* add */
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE)
@@ -368,26 +359,20 @@ static void flatten_volume_closure_tree(ShaderData *sd,
}
}
-void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
+void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
/* execute shader */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
int shader = sd->shader & SHADER_MASK;
if (kg->osl->volume_state[shader])
- ss->execute(*ctx, *(kg->osl->volume_state[shader]), *globals);
-
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);
if (globals->Ci)
flatten_volume_closure_tree(sd, globals->Ci);
@@ -395,46 +380,25 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
/* Displacement */
-void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
+void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, 0, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, 0, tdata);
/* execute shader */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
int shader = sd->shader & SHADER_MASK;
if (kg->osl->displacement_state[shader])
- ss->execute(*ctx, *(kg->osl->displacement_state[shader]), *globals);
-
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ ss->execute(*octx, *(kg->osl->displacement_state[shader]), *globals);
/* get back position */
sd->P = TO_FLOAT3(globals->P);
}
-void OSLShader::init(KernelGlobals *kg, ShaderData *sd)
-{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
-
- sd->osl_ctx = ss->get_context(tdata->thread_info);
-}
-
-void OSLShader::release(KernelGlobals *kg, ShaderData *sd)
-{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-
- ss->release_context((OSL::ShadingContext *)sd->osl_ctx);
-}
-
/* BSDF Closure */
int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
@@ -490,15 +454,21 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
/* Attributes */
-int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
+int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
{
/* for OSL, a hash map is used to lookup the attribute by name. */
- OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[sd->object];
- ustring stdname(std::string("std::") + std::string(attribute_standard_name((AttributeStandard)id)));
+ int object = sd->object*ATTR_PRIM_TYPES;
+#ifdef __HAIR__
+ if(sd->segment != ~0) object += ATTR_PRIM_CURVE;
+#endif
+
+ OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
+ ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
if (it != attr_map.end()) {
const OSLGlobals::Attribute &osl_attr = it->second;
+ *elem = osl_attr.elem;
/* return result */
return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
}
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h
index e614f240dc1..2062c651162 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/osl_shader.h
@@ -55,10 +55,10 @@ public:
static void thread_free(KernelGlobals *kg);
/* eval */
- static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
- static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag);
- static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
- static void eval_displacement(KernelGlobals *kg, ShaderData *sd);
+ static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
+ static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx);
+ static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
+ static void eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx);
/* sample & eval */
static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc,
@@ -73,12 +73,8 @@ public:
static float3 volume_eval_phase(const ShaderClosure *sc,
const float3 omega_in, const float3 omega_out);
- /* release */
- static void init(KernelGlobals *kg, ShaderData *sd);
- static void release(KernelGlobals *kg, ShaderData *sd);
-
/* attributes */
- static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id);
+ static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index f7fec62fd6d..acae46f1615 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -27,6 +27,7 @@ set(SRC_OSL
node_glass_bsdf.osl
node_glossy_bsdf.osl
node_gradient_texture.osl
+ node_hair_info.osl
node_holdout.osl
node_hsv.osl
node_image_texture.osl
@@ -49,6 +50,7 @@ set(SRC_OSL
node_output_volume.osl
node_particle_info.osl
node_refraction_bsdf.osl
+ node_rgb_curves.osl
node_rgb_ramp.osl
node_separate_rgb.osl
node_set_normal.osl
@@ -58,6 +60,7 @@ set(SRC_OSL
node_translucent_bsdf.osl
node_transparent_bsdf.osl
node_value.osl
+ node_vector_curves.osl
node_vector_math.osl
node_velvet_bsdf.osl
node_voronoi_texture.osl
diff --git a/intern/cycles/kernel/shaders/SConscript b/intern/cycles/kernel/shaders/SConscript
index 36b86d7b4f6..daf2b67ad2b 100644
--- a/intern/cycles/kernel/shaders/SConscript
+++ b/intern/cycles/kernel/shaders/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
import Blender as B
diff --git a/intern/cycles/kernel/shaders/node_add_closure.osl b/intern/cycles/kernel/shaders/node_add_closure.osl
index ecf6bf5912e..5c9ffecd1f1 100644
--- a/intern/cycles/kernel/shaders/node_add_closure.osl
+++ b/intern/cycles/kernel/shaders/node_add_closure.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_add_closure(
- closure color Closure1 = background(),
- closure color Closure2 = background(),
- output closure color Closure = background())
+ closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
{
Closure = Closure1 + Closure2;
}
diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
index b9423344e73..58c44224e8d 100644
--- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
+++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
@@ -20,8 +20,8 @@
shader node_ambient_occlusion(
normal NormalIn = N,
- color Color = color(0.8, 0.8, 0.8),
- output closure color AO = ambient_occlusion())
+ color Color = 0.8,
+ output closure color AO = 0)
{
AO = Color * ambient_occlusion();
}
diff --git a/intern/cycles/kernel/shaders/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl
index 8e7c846d1a3..47404927779 100644
--- a/intern/cycles/kernel/shaders/node_attribute.osl
+++ b/intern/cycles/kernel/shaders/node_attribute.osl
@@ -22,7 +22,7 @@ shader node_attribute(
string bump_offset = "center",
string name = "",
output point Vector = point(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Fac = 0.0)
{
getattribute(name, Color);
diff --git a/intern/cycles/kernel/shaders/node_background.osl b/intern/cycles/kernel/shaders/node_background.osl
index b51a1685294..b0c62c0381c 100644
--- a/intern/cycles/kernel/shaders/node_background.osl
+++ b/intern/cycles/kernel/shaders/node_background.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_background(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Strength = 1.0,
- output closure color Background = background())
+ output closure color Background = 0)
{
Background = Color * Strength * background();
}
diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index b1f2a35789f..509b4f2883b 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -65,16 +65,16 @@ shader node_brick_texture(
float Squash = 1.0,
int SquashFrequency = 1,
point Vector = P,
- color Color1 = color(0.2, 0.2, 0.2),
- color Color2 = color(0.8, 0.8, 0.8),
- color Mortar = color(0.0, 0.0, 0.0),
+ color Color1 = 0.2,
+ color Color2 = 0.8,
+ color Mortar = 0.0,
float Scale = 5.0,
float MortarSize = 0.02,
float Bias = 0.0,
float BrickWidth = 0.5,
float RowHeight = 0.25,
output float Fac = 0.0,
- output color Color = color(0.2, 0.2, 0.2))
+ output color Color = 0.2)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl
index b263d815566..2de3c94ecc1 100644
--- a/intern/cycles/kernel/shaders/node_brightness.osl
+++ b/intern/cycles/kernel/shaders/node_brightness.osl
@@ -19,10 +19,10 @@
#include "stdosl.h"
shader node_brightness(
- color ColorIn = color(0.8, 0.8, 0.8),
+ color ColorIn = 0.8,
float Bright = 0.0,
float Contrast = 0.0,
- output color ColorOut = color(0.8, 0.8, 0.8))
+ output color ColorOut = 0.8)
{
float a = 1.0 + Contrast;
float b = Bright - Contrast*0.5;
diff --git a/intern/cycles/kernel/shaders/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl
index eed56f4453a..84cfa8937a6 100644
--- a/intern/cycles/kernel/shaders/node_checker_texture.osl
+++ b/intern/cycles/kernel/shaders/node_checker_texture.osl
@@ -44,10 +44,10 @@ shader node_checker_texture(
matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
float Scale = 5.0,
point Vector = P,
- color Color1 = color(0.8, 0.8, 0.8),
- color Color2 = color(0.2, 0.2, 0.2),
+ color Color1 = 0.8,
+ color Color2 = 0.2,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_combine_rgb.osl b/intern/cycles/kernel/shaders/node_combine_rgb.osl
index 546369f660e..1bdb4de9a5e 100644
--- a/intern/cycles/kernel/shaders/node_combine_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_combine_rgb.osl
@@ -22,7 +22,7 @@ shader node_combine_rgb(
float R = 0.0,
float G = 0.0,
float B = 0.0,
- output color Image = color(0.8, 0.8, 0.8))
+ output color Image = 0.8)
{
Image = color(R, G, B);
}
diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl
index ea488c9ce4c..6a6512e9f5b 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_color.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl
@@ -19,7 +19,7 @@
#include "stdosl.h"
shader node_convert_from_color(
- color Color = color(0.0, 0.0, 0.0),
+ color Color = 0.0,
output string String = "",
output float Val = 0.0,
output int ValInt = 0,
diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl
index a20b491c91d..b6d5084a6dd 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_float.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl
@@ -22,7 +22,7 @@ shader node_convert_from_float(
float Val = 0.0,
output string String = "",
output int ValInt = 0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output vector Vector = vector(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl
index 911b4928db8..3d389cfa587 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_int.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl
@@ -22,7 +22,7 @@ shader node_convert_from_int(
int ValInt = 0,
output string String = "",
output float Val = 0.0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output vector Vector = vector(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
index 1add7400a22..a4cb004f597 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
@@ -24,7 +24,7 @@ shader node_convert_from_normal(
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output point Point = point(0.0, 0.0, 0.0))
{
Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0);
diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl
index 8a315828c55..8ea7d380247 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_point.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl
@@ -24,7 +24,7 @@ shader node_convert_from_point(
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output normal Normal = normal(0.0, 0.0, 0.0))
{
Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0);
diff --git a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
index d6dc17316e8..eae4772f173 100644
--- a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
@@ -19,10 +19,10 @@
#include "stdosl.h"
shader node_diffuse_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Roughness = 0.0,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
if (Roughness == 0.0)
BSDF = Color * diffuse(Normal);
diff --git a/intern/cycles/kernel/shaders/node_emission.osl b/intern/cycles/kernel/shaders/node_emission.osl
index 7ad0f9f7760..854d94c0f9d 100644
--- a/intern/cycles/kernel/shaders/node_emission.osl
+++ b/intern/cycles/kernel/shaders/node_emission.osl
@@ -20,9 +20,9 @@
shader node_emission(
int TotalPower = 0,
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Strength = 1.0,
- output closure color Emission = emission())
+ output closure color Emission = 0)
{
if (TotalPower)
Emission = ((Strength / surfacearea()) * Color) * emission();
diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index 7da336a53f0..33b30a27ee1 100644
--- a/intern/cycles/kernel/shaders/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -48,7 +48,7 @@ shader node_environment_texture(
string filename = "",
string projection = "Equirectangular",
string color_space = "sRGB",
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Alpha = 1.0)
{
vector p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_gamma.osl b/intern/cycles/kernel/shaders/node_gamma.osl
index d55e908b0b7..5c913c29d5f 100644
--- a/intern/cycles/kernel/shaders/node_gamma.osl
+++ b/intern/cycles/kernel/shaders/node_gamma.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_gamma(
- color ColorIn = color(0.8, 0.8, 0.8),
+ color ColorIn = 0.8,
float Gamma = 1.0,
- output color ColorOut = color(0.0, 0.0, 0.0))
+ output color ColorOut = 0.0)
{
ColorOut = pow(ColorIn, Gamma);
}
diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index d1c11b70081..3d5d67360ce 100644
--- a/intern/cycles/kernel/shaders/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -56,8 +56,7 @@ shader node_geometry(
0.0, 0.0, 0.0, 0.0,
0.5, -0.5, 0.0, 1.0);
- vector T = transform(project, generated);
- T = transform("object", "world", T);
+ vector T = transform("object", "world", transform(project, generated));
Tangent = cross(Normal, normalize(cross(T, Normal)));
}
else {
diff --git a/intern/cycles/kernel/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
index 30b9d301f32..da1a42876fe 100644
--- a/intern/cycles/kernel/shaders/node_glass_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
@@ -20,12 +20,12 @@
#include "node_fresnel.h"
shader node_glass_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
string distribution = "Sharp",
float Roughness = 0.2,
float IOR = 1.45,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
float f = max(IOR, 1.0 + 1e-5);
float eta = backfacing() ? 1.0 / f: f;
diff --git a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
index 03340c74af5..79bbe724acd 100644
--- a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
@@ -20,11 +20,11 @@
#include "node_fresnel.h"
shader node_glossy_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
string distribution = "Beckmann",
float Roughness = 0.2,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
if (distribution == "Sharp")
BSDF = Color * reflection(Normal);
diff --git a/intern/cycles/kernel/shaders/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl
index 8d862dbad67..9ae281ff623 100644
--- a/intern/cycles/kernel/shaders/node_gradient_texture.osl
+++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl
@@ -68,7 +68,7 @@ shader node_gradient_texture(
string Type = "Linear",
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl
new file mode 100644
index 00000000000..cbb3b98383f
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_hair_info.osl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_hair_info(
+ output float IsStrand = 0.0,
+ output float Intercept = 0.0,
+ output float Thickness = 0.0,
+ output normal TangentNormal = N)
+{
+ getattribute("geom:is_curve", IsStrand);
+ getattribute("geom:curve_intercept", Intercept);
+ getattribute("geom:curve_thickness", Thickness);
+ getattribute("geom:curve_tangent_normal", TangentNormal);
+}
+
diff --git a/intern/cycles/kernel/shaders/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl
index 0f4bedfb0f8..d5fdb1c616f 100644
--- a/intern/cycles/kernel/shaders/node_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_hsv.osl
@@ -24,8 +24,8 @@ shader node_hsv(
float Saturation = 1.0,
float Value = 1.0,
float Fac = 0.5,
- color ColorIn = color(0.0, 0.0, 0.0),
- output color ColorOut = color(0.0, 0.0, 0.0))
+ color ColorIn = 0.0,
+ output color ColorOut = 0.0)
{
color Color = rgb_to_hsv(ColorIn);
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 99074672a6a..c94a3f7e76a 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -37,7 +37,7 @@ shader node_image_texture(
string color_space = "sRGB",
string projection = "Flat",
float projection_blend = 0.0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Alpha = 1.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_invert.osl b/intern/cycles/kernel/shaders/node_invert.osl
index 27021942558..8711e2f120f 100644
--- a/intern/cycles/kernel/shaders/node_invert.osl
+++ b/intern/cycles/kernel/shaders/node_invert.osl
@@ -20,8 +20,8 @@
shader node_invert(
float Fac = 1.0,
- color ColorIn = color(0.8, 0.8, 0.8),
- output color ColorOut = color(0.8, 0.8, 0.8))
+ color ColorIn = 0.8,
+ output color ColorOut = 0.8)
{
color ColorInv = color(1.0) - ColorIn;
ColorOut = mix(ColorIn, ColorInv, Fac);
diff --git a/intern/cycles/kernel/shaders/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl
index b81a30499b2..943d9c6af68 100644
--- a/intern/cycles/kernel/shaders/node_magic_texture.osl
+++ b/intern/cycles/kernel/shaders/node_magic_texture.osl
@@ -99,7 +99,7 @@ shader node_magic_texture(
float Distortion = 5.0,
float Scale = 5.0,
point Vector = P,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl
index 92df043b39d..787f65217aa 100644
--- a/intern/cycles/kernel/shaders/node_mapping.osl
+++ b/intern/cycles/kernel/shaders/node_mapping.osl
@@ -28,9 +28,8 @@ shader node_mapping(
{
point p = transform(Matrix, VectorIn);
- if(use_minmax)
+ if (use_minmax)
p = min(max(mapping_min, p), mapping_max);
VectorOut = p;
}
-
diff --git a/intern/cycles/kernel/shaders/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl
index b2af36230f8..bcd00bb84e8 100644
--- a/intern/cycles/kernel/shaders/node_mix.osl
+++ b/intern/cycles/kernel/shaders/node_mix.osl
@@ -282,9 +282,9 @@ shader node_mix(
string type = "Mix",
int Clamp = 0,
float Fac = 0.5,
- color Color1 = color(0.0, 0.0, 0.0),
- color Color2 = color(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0))
+ color Color1 = 0.0,
+ color Color2 = 0.0,
+ output color Color = 0.0)
{
float t = clamp(Fac, 0.0, 1.0);
diff --git a/intern/cycles/kernel/shaders/node_mix_closure.osl b/intern/cycles/kernel/shaders/node_mix_closure.osl
index e28dd1fc436..a0bef49b879 100644
--- a/intern/cycles/kernel/shaders/node_mix_closure.osl
+++ b/intern/cycles/kernel/shaders/node_mix_closure.osl
@@ -20,9 +20,9 @@
shader node_mix_closure(
float Fac = 0.5,
- closure color Closure1 = background(),
- closure color Closure2 = background(),
- output closure color Closure = background())
+ closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
{
float t = clamp(Fac, 0.0, 1.0);
Closure = (1.0 - t) * Closure1 + t * Closure2;
diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index afdbca27a3f..8675c23d0d8 100644
--- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -37,14 +37,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float
int i;
for (i = 0; i < (int)octaves; i++) {
- value += noise("perlin", p) * pwr;
+ value += safe_noise(p, 0) * pwr;
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value += rmd * noise("perlin", p) * pwr;
+ value += rmd * safe_noise(p, 0) * pwr;
return value;
}
@@ -65,14 +65,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar
int i;
for (i = 0; i < (int)octaves; i++) {
- value *= (pwr * noise("perlin", p) + 1.0);
+ value *= (pwr * safe_noise(p, 0) + 1.0);
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */
+ value *= (rmd * pwr * safe_noise(p, 0) + 1.0); /* correct? */
return value;
}
@@ -93,11 +93,11 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
int i;
/* first unscaled octave of function; later octaves are scaled */
- value = offset + noise("perlin", p);
+ value = offset + safe_noise(p, 0);
p *= lacunarity;
for (i = 1; i < (int)octaves; i++) {
- increment = (noise("perlin", p) + offset) * pwr * value;
+ increment = (safe_noise(p, 0) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
p *= lacunarity;
@@ -105,7 +105,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
rmd = octaves - floor(octaves);
if (rmd != 0.0) {
- increment = (noise("perlin", p) + offset) * pwr * value;
+ increment = (safe_noise(p, 0) + offset) * pwr * value;
value += rmd * increment;
}
@@ -128,7 +128,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- result = noise("perlin", p) + offset;
+ result = safe_noise(p, 0) + offset;
weight = gain * result;
p *= lacunarity;
@@ -136,7 +136,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
if (weight > 1.0)
weight = 1.0;
- signal = (noise("perlin", p) + offset) * pwr;
+ signal = (safe_noise(p, 0) + offset) * pwr;
pwr *= pwHL;
result += weight * signal;
weight *= gain * signal;
@@ -145,7 +145,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- result += rmd * ((noise("perlin", p) + offset) * pwr);
+ result += rmd * ((safe_noise(p, 0) + offset) * pwr);
return result;
}
@@ -166,7 +166,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- signal = offset - fabs(noise("perlin", p));
+ signal = offset - fabs(safe_noise(p, 0));
signal *= signal;
result = signal;
weight = 1.0;
@@ -174,7 +174,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
for (i = 1; i < (int)octaves; i++) {
p *= lacunarity;
weight = clamp(signal * gain, 0.0, 1.0);
- signal = offset - fabs(noise("perlin", p));
+ signal = offset - fabs(safe_noise(p, 0));
signal *= signal;
signal *= weight;
result += signal * pwr;
@@ -198,7 +198,7 @@ shader node_musgrave_texture(
float Scale = 5.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
float dimension = max(Dimension, 1e-5);
float octaves = clamp(Detail, 0.0, 16.0);
diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl
index 0a379491781..ec86a10b013 100644
--- a/intern/cycles/kernel/shaders/node_noise_texture.osl
+++ b/intern/cycles/kernel/shaders/node_noise_texture.osl
@@ -50,7 +50,7 @@ shader node_noise_texture(
float Detail = 2.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.2, 0.2, 0.2))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl
index dc25eb8539f..21382fab06f 100644
--- a/intern/cycles/kernel/shaders/node_normal_map.osl
+++ b/intern/cycles/kernel/shaders/node_normal_map.osl
@@ -31,15 +31,23 @@ shader node_normal_map(
if (space == "Tangent") {
vector tangent;
+ vector ninterp;
float tangent_sign;
- getattribute(attr_name, tangent);
- getattribute(attr_sign_name, tangent_sign);
+ // get _unnormalized_ interpolated normal and tangent
+ if(!getattribute(attr_name, tangent) ||
+ !getattribute(attr_sign_name, tangent_sign) ||
+ !getattribute("geom:N", ninterp)) {
+ Normal = normal(0, 0, 0);
+ }
+ else {
+ // apply normal map
+ vector B = tangent_sign * cross(ninterp, tangent);
+ Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp);
- tangent = transform("object", "world", tangent);
-
- vector B = tangent_sign * cross(NormalIn, tangent);
- Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * NormalIn);
+ // transform to world space
+ Normal = normalize(transform("object", "world", Normal));
+ }
}
else if (space == "Object")
Normal = normalize(transform("object", "world", vector(mcolor)));
diff --git a/intern/cycles/kernel/shaders/node_output_surface.osl b/intern/cycles/kernel/shaders/node_output_surface.osl
index 6efaf91121b..da6eedb9f98 100644
--- a/intern/cycles/kernel/shaders/node_output_surface.osl
+++ b/intern/cycles/kernel/shaders/node_output_surface.osl
@@ -18,7 +18,7 @@
#include "stdosl.h"
-surface node_output_surface(closure color Surface = background())
+surface node_output_surface(closure color Surface = 0)
{
Ci = Surface;
}
diff --git a/intern/cycles/kernel/shaders/node_output_volume.osl b/intern/cycles/kernel/shaders/node_output_volume.osl
index 18094242dc7..ec32ed3fcd2 100644
--- a/intern/cycles/kernel/shaders/node_output_volume.osl
+++ b/intern/cycles/kernel/shaders/node_output_volume.osl
@@ -18,7 +18,7 @@
#include "stdosl.h"
-volume node_output_volume(closure color Volume = background())
+volume node_output_volume(closure color Volume = 0)
{
Ci = Volume;
}
diff --git a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
index 0cf9d460c6e..d95a26cdff9 100644
--- a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
@@ -19,12 +19,12 @@
#include "stdosl.h"
shader node_refraction_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
string distribution = "Sharp",
float Roughness = 0.2,
float IOR = 1.45,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
float f = max(IOR, 1.0 + 1e-5);
float eta = backfacing() ? 1.0 / f: f;
diff --git a/intern/cycles/kernel/shaders/node_rgb_curves.osl b/intern/cycles/kernel/shaders/node_rgb_curves.osl
new file mode 100644
index 00000000000..362bae8a750
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_rgb_curves.osl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+#include "oslutil.h"
+
+float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component)
+{
+ float f = clamp(at, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0) i = 0;
+ if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1;
+ float t = f - (float)i;
+
+ float result = ramp[i][component];
+
+ if (t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1][component];
+
+ return result;
+}
+
+shader node_rgb_curves(
+ color ramp[RAMP_TABLE_SIZE] = {0.0},
+
+ color ColorIn = 0.0,
+ float Fac = 0.0,
+ output color ColorOut = 0.0)
+{
+ ColorOut[0] = ramp_lookup(ramp, ColorIn[0], 0);
+ ColorOut[1] = ramp_lookup(ramp, ColorIn[1], 1);
+ ColorOut[2] = ramp_lookup(ramp, ColorIn[2], 2);
+
+ ColorOut = mix(ColorIn, ColorOut, Fac);
+}
+
diff --git a/intern/cycles/kernel/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
index 0df11bb38de..bac4b9552e0 100644
--- a/intern/cycles/kernel/shaders/node_rgb_ramp.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
@@ -24,7 +24,7 @@ shader node_rgb_ramp(
float ramp_alpha[RAMP_TABLE_SIZE] = {0.0},
float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Alpha = 1.0)
{
float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
diff --git a/intern/cycles/kernel/shaders/node_separate_rgb.osl b/intern/cycles/kernel/shaders/node_separate_rgb.osl
index b48bd7e59d6..0066a1daa91 100644
--- a/intern/cycles/kernel/shaders/node_separate_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_separate_rgb.osl
@@ -19,7 +19,7 @@
#include "stdosl.h"
shader node_separate_rgb(
- color Image = color(0.8, 0.8, 0.8),
+ color Image = 0.8,
output float R = 0.0,
output float G = 0.0,
output float B = 0.0)
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index 24a63c78458..13f958d65bd 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -154,7 +154,7 @@ shader node_sky_texture(
vector Vector = P,
vector sun_direction = vector(0, 0, 1),
float turbidity = 2.2,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
vector p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index 1b3ba8207ab..463c68a6c27 100644
--- a/intern/cycles/kernel/shaders/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -151,12 +151,31 @@ float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; }
/* Noise Bases */
+float safe_noise(point p, int type)
+{
+ float f = 0.0;
+
+ /* Perlin noise in range -1..1 */
+ if (type == 0)
+ f = noise("perlin", p);
+
+ /* Perlin noise in range 0..1 */
+ else
+ f = noise(p);
+
+ /* can happen for big coordinates, things even out to 0.5 then anyway */
+ if(!isfinite(f))
+ return 0.5;
+
+ return f;
+}
+
float noise_basis(point p, string basis)
{
float result = 0.0;
if (basis == "Perlin")
- result = noise(p); /* returns perlin noise in range 0..1 */
+ result = safe_noise(p, 1);
if (basis == "Voronoi F1")
result = voronoi_F1S(p);
if (basis == "Voronoi F2")
diff --git a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
index e7efe73700c..c0a093b35d2 100644
--- a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_translucent_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
BSDF = Color * translucent(Normal);
}
diff --git a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
index 875bce3f16c..976b7d5f756 100644
--- a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_transparent_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
BSDF = Color * transparent();
}
diff --git a/intern/cycles/kernel/shaders/node_value.osl b/intern/cycles/kernel/shaders/node_value.osl
index bee6f39f2bc..d3672b8c0cf 100644
--- a/intern/cycles/kernel/shaders/node_value.osl
+++ b/intern/cycles/kernel/shaders/node_value.osl
@@ -21,10 +21,10 @@
shader node_value(
float value_value = 0.0,
vector vector_value = vector(0.0, 0.0, 0.0),
- color color_value = color(0.0, 0.0, 0.0),
+ color color_value = 0.0,
output float Value = 0.0,
output vector Vector = vector(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
Value = value_value;
Vector = vector_value;
diff --git a/intern/cycles/kernel/shaders/node_vector_curves.osl b/intern/cycles/kernel/shaders/node_vector_curves.osl
new file mode 100644
index 00000000000..94082287f4d
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_vector_curves.osl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+#include "oslutil.h"
+
+float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component)
+{
+ float f = clamp((at + 1.0)*0.5, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0) i = 0;
+ if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1;
+ float t = f - (float)i;
+
+ float result = ramp[i][component];
+
+ if (t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1][component];
+
+ return result*2.0 - 1.0;
+}
+
+shader node_vector_curves(
+ color ramp[RAMP_TABLE_SIZE] = {0.0},
+
+ vector VectorIn = vector(0.0, 0.0, 0.0),
+ float Fac = 0.0,
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
+{
+ VectorOut[0] = ramp_lookup(ramp, VectorIn[0], 0);
+ VectorOut[1] = ramp_lookup(ramp, VectorIn[1], 1);
+ VectorOut[2] = ramp_lookup(ramp, VectorIn[2], 2);
+
+ VectorOut = mix(VectorIn, VectorOut, Fac);
+}
+
diff --git a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
index 3aa662bdd08..5506ab20703 100644
--- a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
@@ -20,10 +20,10 @@
#include "node_fresnel.h"
shader node_velvet_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Sigma = 0.0,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
float sigma = clamp(Sigma, 0.0, 1.0);
diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
index 43f8ecc666a..db8787892d2 100644
--- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl
+++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
@@ -28,7 +28,7 @@ shader node_voronoi_texture(
float Scale = 5.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
index 82ce15ab9b6..bae55bcceaf 100644
--- a/intern/cycles/kernel/shaders/node_ward_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
@@ -19,13 +19,13 @@
#include "stdosl.h"
shader node_ward_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.0,
float Roughness = 0.0,
float Anisotropy = 0.0,
float Rotation = 0.0,
normal Normal = N,
normal Tangent = normalize(dPdu),
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
/* rotate tangent around normal */
vector T = Tangent;
diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl
index 6648cd06278..11c4689196d 100644
--- a/intern/cycles/kernel/shaders/node_wave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_wave_texture.osl
@@ -55,7 +55,7 @@ shader node_wave_texture(
float DetailScale = 1.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color (0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 24c3a50e6f6..f340eaff95f 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -161,7 +161,15 @@ vector cross (vector a, vector b) BUILTIN;
float dot (vector a, vector b) BUILTIN;
float length (vector v) BUILTIN;
float distance (point a, point b) BUILTIN;
-float distance (point a, point b, point q) BUILTIN;
+float distance (point a, point b, point q)
+{
+ vector d = b - a;
+ float dd = dot(d, d);
+ if(dd == 0.0)
+ return distance(q, a);
+ float t = dot(q - a, d)/dd;
+ return distance(q, a + clamp(t, 0.0, 1.0)*d);
+}
normal normalize (normal v) BUILTIN;
vector normalize (vector v) BUILTIN;
vector faceforward (vector N, vector I, vector Nref) BUILTIN;
@@ -305,7 +313,7 @@ color transformc (string to, color x)
r = color (dot (vector(0.299, 0.587, 0.114), (vector)x),
dot (vector(0.596, -0.275, -0.321), (vector)x),
dot (vector(0.212, -0.523, 0.311), (vector)x));
- else if (to == "xyz")
+ else if (to == "XYZ")
r = color (dot (vector(0.412453, 0.357580, 0.180423), (vector)x),
dot (vector(0.212671, 0.715160, 0.072169), (vector)x),
dot (vector(0.019334, 0.119193, 0.950227), (vector)x));
@@ -367,7 +375,7 @@ color transformc (string from, string to, color x)
r = color (dot (vector(1, 0.9557, 0.6199), (vector)x),
dot (vector(1, -0.2716, -0.6469), (vector)x),
dot (vector(1, -1.1082, 1.7051), (vector)x));
- else if (from == "xyz")
+ else if (from == "XYZ")
r = color (dot (vector( 3.240479, -1.537150, -0.498535), (vector)x),
dot (vector(-0.969256, 1.875991, 0.041556), (vector)x),
dot (vector( 0.055648, -0.204043, 1.057311), (vector)x));
@@ -410,6 +418,8 @@ int startswith (string s, string prefix) BUILTIN;
int endswith (string s, string suffix) BUILTIN;
string substr (string s, int start, int len) BUILTIN;
string substr (string s, int start) { return substr (s, start, strlen(s)); }
+float strtof (string str) BUILTIN;
+int strtoi (string str) BUILTIN;
// Define concat in terms of shorter concat
string concat (string a, string b, string c) {
@@ -433,7 +443,10 @@ string concat (string a, string b, string c, string d, string e, string f) {
closure color diffuse(normal N) BUILTIN;
closure color oren_nayar(normal N, float sigma) BUILTIN;
+closure color diffuse_ramp(normal N, color colors[8]) BUILTIN;
closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
+closure color diffuse_toon(normal N, float size, float smooth) BUILTIN;
+closure color specular_toon(normal N, float size, float smooth) BUILTIN;
closure color translucent(normal N) BUILTIN;
closure color reflection(normal N) BUILTIN;
closure color refraction(normal N, float eta) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 9c79886fdca..1f4857c0924 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -301,6 +301,12 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_PARTICLE_INFO:
svm_node_particle_info(kg, sd, stack, node.y, node.z);
break;
+#ifdef __HAIR__
+ case NODE_HAIR_INFO:
+ svm_node_hair_info(kg, sd, stack, node.y, node.z);
+ break;
+#endif
+
#endif
case NODE_CONVERT:
svm_node_convert(sd, stack, node.y, node.z, node.w);
@@ -398,6 +404,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_RGB_CURVES:
svm_node_rgb_curves(kg, sd, stack, node, &offset);
break;
+ case NODE_VECTOR_CURVES:
+ svm_node_vector_curves(kg, sd, stack, node, &offset);
+ break;
case NODE_LIGHT_FALLOFF:
svm_node_light_falloff(sd, stack, node);
break;
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index ed70a6dc423..2beec995151 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -28,10 +28,15 @@ __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
/* find attribute by unique id */
uint id = node.y;
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+#ifdef __HAIR__
+ attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+#endif
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id)
- 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);
+ }
/* return result */
*elem = (AttributeElement)attr_map.y;
@@ -61,21 +66,21 @@ __device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uin
/* fetch and store attribute */
if(type == NODE_ATTR_FLOAT) {
if(mesh_type == NODE_ATTR_FLOAT) {
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL);
stack_store_float(stack, out_offset, f);
}
else {
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
stack_store_float(stack, out_offset, average(f));
}
}
else {
if(mesh_type == NODE_ATTR_FLOAT3) {
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
stack_store_float3(stack, out_offset, f);
}
else {
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL);
stack_store_float3(stack, out_offset, make_float3(f, f, f));
}
}
@@ -94,24 +99,24 @@ __device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *st
if(type == NODE_ATTR_FLOAT) {
if(mesh_type == NODE_ATTR_FLOAT) {
float dx;
- float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL);
stack_store_float(stack, out_offset, f+dx);
}
else {
float3 dx;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL);
stack_store_float(stack, out_offset, average(f+dx));
}
}
else {
if(mesh_type == NODE_ATTR_FLOAT3) {
float3 dx;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL);
stack_store_float3(stack, out_offset, f+dx);
}
else {
float dx;
- float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL);
stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
}
}
@@ -130,24 +135,24 @@ __device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *st
if(type == NODE_ATTR_FLOAT) {
if(mesh_type == NODE_ATTR_FLOAT) {
float dy;
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy);
stack_store_float(stack, out_offset, f+dy);
}
else {
float3 dy;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy);
stack_store_float(stack, out_offset, average(f+dy));
}
}
else {
if(mesh_type == NODE_ATTR_FLOAT3) {
float3 dy;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy);
stack_store_float3(stack, out_offset, f+dy);
}
else {
float dy;
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy);
stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
}
}
diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h
deleted file mode 100644
index 07927fe5691..00000000000
--- a/intern/cycles/kernel/svm/svm_bsdf.h
+++ /dev/null
@@ -1,268 +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.
- */
-
-#include "../closure/bsdf_ashikhmin_velvet.h"
-#include "../closure/bsdf_diffuse.h"
-#include "../closure/bsdf_oren_nayar.h"
-#include "../closure/bsdf_phong_ramp.h"
-#include "../closure/bsdf_microfacet.h"
-#include "../closure/bsdf_reflection.h"
-#include "../closure/bsdf_refraction.h"
-#include "../closure/bsdf_transparent.h"
-#ifdef __ANISOTROPIC__
-#include "../closure/bsdf_ward.h"
-#endif
-#include "../closure/bsdf_westin.h"
-
-CCL_NAMESPACE_BEGIN
-
-__device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
-{
- int label;
-
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- /*case CLOSURE_BSDF_PHONG_RAMP_ID:
- label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;*/
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#endif
- default:
- label = LABEL_NONE;
- break;
- }
-
- return label;
-}
-
-__device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
-{
- float3 eval;
-
- if(dot(sd->Ng, omega_in) >= 0.0f) {
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- /*case CLOSURE_BSDF_PHONG_RAMP_ID:
- eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;*/
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#endif
- default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
- break;
- }
- }
- else {
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#endif
- default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
- break;
- }
- }
-
- return eval;
-}
-
-__device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
-{
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_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_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;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- bsdf_microfacet_ggx_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- bsdf_microfacet_beckmann_blur(sc, roughness);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- bsdf_ward_blur(sc, roughness);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- bsdf_ashikhmin_velvet_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- bsdf_westin_backscatter_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- bsdf_westin_sheen_blur(sc, roughness);
- break;
-#endif
- default:
- break;
- }
-}
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index c4d03c1f948..a04f4ea0fa7 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -28,23 +28,7 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack,
case NODE_GEOM_P: data = sd->P; break;
case NODE_GEOM_N: data = sd->N; break;
#ifdef __DPDU__
- case NODE_GEOM_T: {
- /* try to create spherical tangent from generated coordinates */
- int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_GENERATED): ATTR_STD_NOT_FOUND;
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
- data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
- object_normal_transform(kg, sd, &data);
- data = cross(sd->N, normalize(cross(data, sd->N)));;
- }
- else {
- /* otherwise use surface derivatives */
- data = normalize(sd->dPdu);
- }
-
- break;
- }
+ case NODE_GEOM_T: data = primitive_tangent(kg, sd); break;
#endif
case NODE_GEOM_I: data = sd->I; break;
case NODE_GEOM_Ng: data = sd->Ng; break;
@@ -160,5 +144,36 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s
}
}
+#ifdef __HAIR__
+
+/* Hair Info */
+
+__device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
+{
+ float data;
+ float3 data3;
+
+ switch(type) {
+ case NODE_INFO_CURVE_IS_STRAND: {
+ data = (sd->segment != ~0);
+ stack_store_float(stack, out_offset, data);
+ break;
+ }
+ case NODE_INFO_CURVE_INTERCEPT:
+ break; /* handled as attribute */
+ case NODE_INFO_CURVE_THICKNESS: {
+ data = curve_thickness(kg, sd);
+ stack_store_float(stack, out_offset, data);
+ break;
+ }
+ case NODE_INFO_CURVE_TANGENT_NORMAL: {
+ data3 = curve_tangent_normal(kg, sd);
+ stack_store_float3(stack, out_offset, data3);
+ break;
+ }
+ }
+}
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h
index db3b8d3f763..c7cd5200cd0 100644
--- a/intern/cycles/kernel/svm/svm_math.h
+++ b/intern/cycles/kernel/svm/svm_math.h
@@ -18,73 +18,6 @@
CCL_NAMESPACE_BEGIN
-__device float safe_asinf(float a)
-{
- if(a <= -1.0f)
- return -M_PI_2_F;
- else if(a >= 1.0f)
- return M_PI_2_F;
-
- return asinf(a);
-}
-
-__device float safe_acosf(float a)
-{
- if(a <= -1.0f)
- return M_PI_F;
- else if(a >= 1.0f)
- return 0.0f;
-
- return acosf(a);
-}
-
-__device float compatible_powf(float x, float y)
-{
- /* GPU pow doesn't accept negative x, do manual checks here */
- if(x < 0.0f) {
- if(fmod(-y, 2.0f) == 0.0f)
- return powf(-x, y);
- else
- return -powf(-x, y);
- }
- else if(x == 0.0f)
- return 0.0f;
-
- return powf(x, y);
-}
-
-__device float safe_powf(float a, float b)
-{
- if(b == 0.0f)
- return 1.0f;
- if(a == 0.0f)
- return 0.0f;
- if(a < 0.0f && b != (int)b)
- return 0.0f;
-
- return compatible_powf(a, b);
-}
-
-__device float safe_logf(float a, float b)
-{
- if(a < 0.0f || b < 0.0f)
- return 0.0f;
-
- return logf(a)/logf(b);
-}
-
-__device float safe_divide(float a, float b)
-{
- float result;
-
- if(b == 0.0f)
- result = 0.0f;
- else
- result = a/b;
-
- return result;
-}
-
__device float svm_math(NodeMath type, float Fac1, float Fac2)
{
float Fac;
diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
index 224a1d96543..5ead6486dd6 100644
--- a/intern/cycles/kernel/svm/svm_noise.h
+++ b/intern/cycles/kernel/svm/svm_noise.h
@@ -84,9 +84,8 @@ __device uint phash(int kx, int ky, int kz, int3 p)
__device float floorfrac(float x, int* i)
{
- float f = floorf(x);
- *i = (int)f;
- return x - f;
+ *i = quick_floor(x);
+ return x - *i;
}
__device float fade(float t)
@@ -133,7 +132,10 @@ __device_noinline float perlin(float x, float y, float z)
grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )),
nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ),
grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f ))));
- return scale3(result);
+ float r = scale3(result);
+
+ /* can happen for big coordinates, things even out to 0.0 then anyway */
+ return (isfinite(r))? r: 0.0f;
}
__device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod)
@@ -162,7 +164,10 @@ __device_noinline float perlin_periodic(float x, float y, float z, float3 pperio
grad (phash (X+1, Y , Z+1, p), fx-1.0f, fy , fz-1.0f )),
nerp (u, grad (phash (X , Y+1, Z+1, p), fx , fy-1.0f, fz-1.0f ),
grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f ))));
- return scale3(result);
+ float r = scale3(result);
+
+ /* can happen for big coordinates, things even out to 0.0 then anyway */
+ return (isfinite(r))? r: 0.0f;
}
/* perlin noise in range 0..1 */
diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h
index c64413cbe84..054137fe7a3 100644
--- a/intern/cycles/kernel/svm/svm_ramp.h
+++ b/intern/cycles/kernel/svm/svm_ramp.h
@@ -63,9 +63,9 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac
float fac = stack_load_float(stack, fac_offset);
float3 color = stack_load_float3(stack, color_offset);
- float r = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.x).w).x;
- float g = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.y).w).y;
- float b = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.z).w).z;
+ float r = rgb_ramp_lookup(kg, *offset, color.x).x;
+ float g = rgb_ramp_lookup(kg, *offset, color.y).y;
+ float b = rgb_ramp_lookup(kg, *offset, color.z).z;
color = (1.0f - fac)*color + fac*make_float3(r, g, b);
stack_store_float3(stack, out_offset, color);
@@ -73,6 +73,25 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac
*offset += RAMP_TABLE_SIZE;
}
+__device void svm_node_vector_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+{
+ uint fac_offset = node.y;
+ uint color_offset = node.z;
+ uint out_offset = node.w;
+
+ float fac = stack_load_float(stack, fac_offset);
+ float3 color = stack_load_float3(stack, color_offset);
+
+ float r = rgb_ramp_lookup(kg, *offset, (color.x + 1.0f)*0.5f).x;
+ float g = rgb_ramp_lookup(kg, *offset, (color.y + 1.0f)*0.5f).y;
+ float b = rgb_ramp_lookup(kg, *offset, (color.z + 1.0f)*0.5f).z;
+
+ color = (1.0f - fac)*color + fac*make_float3(r*2.0f - 1.0f, g*2.0f - 1.0f, b*2.0f - 1.0f);
+ stack_store_float3(stack, out_offset, color);
+
+ *offset += RAMP_TABLE_SIZE;
+}
+
CCL_NAMESPACE_END
#endif /* __SVM_RAMP_H__ */
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 9f2d3367420..d793169261d 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -248,23 +248,27 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac
}
/* first try to get tangent attribute */
- int attr_offset = find_attribute(kg, sd, node.z);
- int attr_sign_offset = find_attribute(kg, sd, node.w);
+ AttributeElement attr_elem, attr_sign_elem, attr_normal_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
+ int attr_sign_offset = find_attribute(kg, sd, node.w, &attr_sign_elem);
+ int attr_normal_offset = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL, &attr_normal_elem);
- if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND) {
+ if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND || attr_normal_offset == ATTR_STD_NOT_FOUND) {
stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
return;
}
- /* ensure orthogonal and normalized (interpolation breaks it) */
- float3 tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
- float sign = triangle_attribute_float(kg, sd, ATTR_ELEMENT_CORNER, attr_sign_offset, NULL, NULL);
+ /* get _unnormalized_ interpolated normal and tangent */
+ float3 tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
+ float sign = primitive_attribute_float(kg, sd, attr_sign_elem, attr_sign_offset, NULL, NULL);
+ float3 normal = primitive_attribute_float3(kg, sd, attr_normal_elem, attr_normal_offset, NULL, NULL);
- object_normal_transform(kg, sd, &tangent);
- tangent = cross(sd->N, normalize(cross(tangent, sd->N)));;
+ /* apply normal map */
+ float3 B = sign * cross(normal, tangent);
+ N = normalize(color.x * tangent + color.y * B + color.z * normal);
- float3 B = sign * cross(sd->N, tangent);
- N = normalize(color.x * tangent + color.y * B + color.z * sd->N);
+ /* transform to world space */
+ object_normal_transform(kg, sd, &N);
}
else {
/* object, world space */
@@ -295,22 +299,24 @@ __device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack,
if(direction_type == NODE_TANGENT_UVMAP) {
/* UV map */
- int attr_offset = find_attribute(kg, sd, node.z);
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
if(attr_offset == ATTR_STD_NOT_FOUND)
tangent = make_float3(0.0f, 0.0f, 0.0f);
else
- tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+ tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
}
else {
/* radial */
- int attr_offset = find_attribute(kg, sd, node.z);
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
float3 generated;
if(attr_offset == ATTR_STD_NOT_FOUND)
generated = sd->P;
else
- generated = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+ generated = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
if(axis == NODE_TANGENT_AXIS_X)
tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index b41e34ab407..57177eec48f 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -88,6 +88,7 @@ typedef enum NodeType {
NODE_BRIGHTCONTRAST,
NODE_RGB_RAMP,
NODE_RGB_CURVES,
+ NODE_VECTOR_CURVES,
NODE_MIN_MAX,
NODE_LIGHT_FALLOFF,
NODE_OBJECT_INFO,
@@ -96,7 +97,8 @@ typedef enum NodeType {
NODE_CLOSURE_SET_NORMAL,
NODE_CLOSURE_AMBIENT_OCCLUSION,
NODE_TANGENT,
- NODE_NORMAL_MAP
+ NODE_NORMAL_MAP,
+ NODE_HAIR_INFO
} NodeType;
typedef enum NodeAttributeType {
@@ -131,6 +133,13 @@ typedef enum NodeParticleInfo {
NODE_INFO_PAR_ANGULAR_VELOCITY
} NodeParticleInfo;
+typedef enum NodeHairInfo {
+ NODE_INFO_CURVE_IS_STRAND,
+ NODE_INFO_CURVE_INTERCEPT,
+ NODE_INFO_CURVE_THICKNESS,
+ NODE_INFO_CURVE_TANGENT_NORMAL
+} NodeHairInfo;
+
typedef enum NodeLightPath {
NODE_LP_camera = 0,
NODE_LP_shadow,
@@ -312,6 +321,8 @@ typedef enum ClosureType {
CLOSURE_BSDF_DIFFUSE_ID,
CLOSURE_BSDF_OREN_NAYAR_ID,
+ CLOSURE_BSDF_DIFFUSE_RAMP_ID,
+ CLOSURE_BSDF_DIFFUSE_TOON_ID,
CLOSURE_BSDF_GLOSSY_ID,
CLOSURE_BSDF_REFLECTION_ID,
@@ -321,6 +332,7 @@ typedef enum ClosureType {
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
CLOSURE_BSDF_WESTIN_SHEEN_ID,
CLOSURE_BSDF_PHONG_RAMP_ID,
+ CLOSURE_BSDF_SPECULAR_TOON_ID,
CLOSURE_BSDF_TRANSMISSION_ID,
CLOSURE_BSDF_TRANSLUCENT_ID,
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index 7907061c19c..d67a686d1e8 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -31,6 +31,7 @@ set(SRC
object.cpp
osl.cpp
particles.cpp
+ curves.cpp
scene.cpp
session.cpp
shader.cpp
@@ -56,6 +57,7 @@ set(SRC_HEADERS
object.h
osl.h
particles.h
+ curves.h
scene.h
session.h
shader.h
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 95941c14b6c..b6f6ba47fe8 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -26,7 +26,7 @@ CCL_NAMESPACE_BEGIN
/* Attribute */
-void Attribute::set(ustring name_, TypeDesc type_, Element element_)
+void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
{
name = name_;
type = type_;
@@ -39,12 +39,30 @@ void Attribute::set(ustring name_, TypeDesc type_, Element element_)
type == TypeDesc::TypeNormal);
}
-void Attribute::reserve(int numverts, int numtris)
+void Attribute::reserve(int numverts, int numtris, int numcurves, int numkeys)
{
- buffer.resize(buffer_size(numverts, numtris), 0);
+ buffer.resize(buffer_size(numverts, numtris, numcurves, numkeys), 0);
}
-size_t Attribute::data_sizeof()
+void Attribute::add(const float& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
+void Attribute::add(const float3& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
+size_t Attribute::data_sizeof() const
{
if(type == TypeDesc::TypeFloat)
return sizeof(float);
@@ -52,19 +70,27 @@ size_t Attribute::data_sizeof()
return sizeof(float3);
}
-size_t Attribute::element_size(int numverts, int numtris)
+size_t Attribute::element_size(int numverts, int numtris, int numcurves, int numkeys) const
{
- if(element == VERTEX)
+ if(element == ATTR_ELEMENT_VALUE)
+ return 1;
+ if(element == ATTR_ELEMENT_VERTEX)
return numverts;
- else if(element == FACE)
+ else if(element == ATTR_ELEMENT_FACE)
return numtris;
- else
+ else if(element == ATTR_ELEMENT_CORNER)
return numtris*3;
+ else if(element == ATTR_ELEMENT_CURVE)
+ return numcurves;
+ else if(element == ATTR_ELEMENT_CURVE_KEY)
+ return numkeys;
+
+ return 0;
}
-size_t Attribute::buffer_size(int numverts, int numtris)
+size_t Attribute::buffer_size(int numverts, int numtris, int numcurves, int numkeys) const
{
- return element_size(numverts, numtris)*data_sizeof();
+ return element_size(numverts, numtris, numcurves, numkeys)*data_sizeof();
}
bool Attribute::same_storage(TypeDesc a, TypeDesc b)
@@ -84,18 +110,51 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
return false;
}
+const char *Attribute::standard_name(AttributeStandard std)
+{
+ if(std == ATTR_STD_VERTEX_NORMAL)
+ return "N";
+ else if(std == ATTR_STD_FACE_NORMAL)
+ return "Ng";
+ else if(std == ATTR_STD_UV)
+ return "uv";
+ else if(std == ATTR_STD_GENERATED)
+ return "generated";
+ else if(std == ATTR_STD_UV_TANGENT)
+ return "tangent";
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ return "tangent_sign";
+ else if(std == ATTR_STD_POSITION_UNDEFORMED)
+ return "undeformed";
+ else if(std == ATTR_STD_POSITION_UNDISPLACED)
+ return "undisplaced";
+ else if(std == ATTR_STD_MOTION_PRE)
+ return "motion_pre";
+ else if(std == ATTR_STD_MOTION_POST)
+ return "motion_post";
+ else if(std == ATTR_STD_PARTICLE)
+ return "particle";
+ else if(std == ATTR_STD_CURVE_TANGENT)
+ return "curve_tangent";
+ else if(std == ATTR_STD_CURVE_INTERCEPT)
+ return "curve_intercept";
+
+ return "";
+}
+
/* Attribute Set */
AttributeSet::AttributeSet()
{
- mesh = NULL;
+ triangle_mesh = NULL;
+ curve_mesh = NULL;
}
AttributeSet::~AttributeSet()
{
}
-Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element element)
+Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element)
{
Attribute *attr = find(name);
@@ -111,24 +170,22 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element ele
attributes.push_back(Attribute());
attr = &attributes.back();
- if(element == Attribute::VERTEX)
- attr->set(name, type, element);
- else if(element == Attribute::FACE)
- attr->set(name, type, element);
- else if(element == Attribute::CORNER)
- attr->set(name, type, element);
+ attr->set(name, type, element);
- if(mesh)
- attr->reserve(mesh->verts.size(), mesh->triangles.size());
+ /* this is weak .. */
+ if(triangle_mesh)
+ attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ if(curve_mesh)
+ attr->reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
return attr;
}
-Attribute *AttributeSet::find(ustring name)
+Attribute *AttributeSet::find(ustring name) const
{
- foreach(Attribute& attr, attributes)
+ foreach(const Attribute& attr, attributes)
if(attr.name == name)
- return &attr;
+ return (Attribute*)&attr;
return NULL;
}
@@ -154,41 +211,59 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
Attribute *attr = NULL;
if(name == ustring())
- name = attribute_standard_name(std);
-
- if(std == ATTR_STD_VERTEX_NORMAL)
- attr = add(name, TypeDesc::TypeNormal, Attribute::VERTEX);
- else if(std == ATTR_STD_FACE_NORMAL)
- attr = add(name, TypeDesc::TypeNormal, Attribute::FACE);
- else if(std == ATTR_STD_UV)
- attr = add(name, TypeDesc::TypePoint, Attribute::CORNER);
- else if(std == ATTR_STD_UV_TANGENT)
- attr = add(name, TypeDesc::TypeVector, Attribute::CORNER);
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- attr = add(name, TypeDesc::TypeFloat, Attribute::CORNER);
- else if(std == ATTR_STD_GENERATED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_MOTION_PRE)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_MOTION_POST)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else
- assert(0);
+ name = Attribute::standard_name(std);
+
+ if(triangle_mesh) {
+ if(std == ATTR_STD_VERTEX_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_FACE_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_FACE);
+ else if(std == ATTR_STD_UV)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_UV_TANGENT)
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_GENERATED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_POSITION_UNDEFORMED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_POSITION_UNDISPLACED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_MOTION_PRE)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_MOTION_POST)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else
+ assert(0);
+ }
+ else if(curve_mesh) {
+ if(std == ATTR_STD_UV)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
+ else if(std == ATTR_STD_GENERATED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
+ else if(std == ATTR_STD_MOTION_PRE)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_MOTION_POST)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_CURVE_TANGENT)
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_CURVE_INTERCEPT)
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
+ else
+ assert(0);
+ }
attr->std = std;
return attr;
}
-Attribute *AttributeSet::find(AttributeStandard std)
+Attribute *AttributeSet::find(AttributeStandard std) const
{
- foreach(Attribute& attr, attributes)
+ foreach(const Attribute& attr, attributes)
if(attr.std == std)
- return &attr;
+ return (Attribute*)&attr;
return NULL;
}
@@ -217,10 +292,14 @@ Attribute *AttributeSet::find(AttributeRequest& req)
return find(req.std);
}
-void AttributeSet::reserve(int numverts, int numtris)
+void AttributeSet::reserve()
{
- foreach(Attribute& attr, attributes)
- attr.reserve(numverts, numtris);
+ foreach(Attribute& attr, attributes) {
+ if(triangle_mesh)
+ attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ if(curve_mesh)
+ attr.reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
+ }
}
void AttributeSet::clear()
@@ -235,9 +314,13 @@ AttributeRequest::AttributeRequest(ustring name_)
name = name_;
std = ATTR_STD_NONE;
- type = TypeDesc::TypeFloat;
- element = ATTR_ELEMENT_NONE;
- offset = 0;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_element = ATTR_ELEMENT_NONE;
+ triangle_offset = 0;
+
+ curve_type = TypeDesc::TypeFloat;
+ curve_element = ATTR_ELEMENT_NONE;
+ curve_offset = 0;
}
AttributeRequest::AttributeRequest(AttributeStandard std_)
@@ -245,9 +328,13 @@ AttributeRequest::AttributeRequest(AttributeStandard std_)
name = ustring();
std = std_;
- type = TypeDesc::TypeFloat;
- element = ATTR_ELEMENT_NONE;
- offset = 0;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_element = ATTR_ELEMENT_NONE;
+ triangle_offset = 0;
+
+ curve_type = TypeDesc::TypeFloat;
+ curve_element = ATTR_ELEMENT_NONE;
+ curve_offset = 0;
}
/* AttributeRequestSet */
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index d05952edfd7..6c0c06d0425 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -21,7 +21,6 @@
#include "kernel_types.h"
-#include "util_attribute.h"
#include "util_list.h"
#include "util_param.h"
#include "util_types.h"
@@ -42,36 +41,34 @@ class Mesh;
class Attribute {
public:
- enum Element {
- VERTEX,
- FACE,
- CORNER
- };
-
ustring name;
AttributeStandard std;
TypeDesc type;
vector<char> buffer;
- Element element;
+ AttributeElement element;
Attribute() {}
- void set(ustring name, TypeDesc type, Element element);
- void reserve(int numverts, int numfaces);
+ void set(ustring name, TypeDesc type, AttributeElement element);
+ void reserve(int numverts, int numfaces, int numcurves, int numkeys);
- size_t data_sizeof();
- size_t element_size(int numverts, int numfaces);
- size_t buffer_size(int numverts, int numfaces);
+ size_t data_sizeof() const;
+ size_t element_size(int numverts, int numfaces, int numcurves, int numkeys) const;
+ size_t buffer_size(int numverts, int numfaces, int numcurves, int numkeys) const;
char *data() { return (buffer.size())? &buffer[0]: NULL; };
float3 *data_float3() { return (float3*)data(); }
float *data_float() { return (float*)data(); }
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
- const float3 *data_float3() const { return (float3*)data(); }
- const float *data_float() const { return (float*)data(); }
+ const float3 *data_float3() const { return (const float3*)data(); }
+ const float *data_float() const { return (const float*)data(); }
+
+ void add(const float& f);
+ void add(const float3& f);
static bool same_storage(TypeDesc a, TypeDesc b);
+ static const char *standard_name(AttributeStandard std);
};
/* Attribute Set
@@ -80,23 +77,24 @@ public:
class AttributeSet {
public:
- Mesh *mesh;
+ Mesh *triangle_mesh;
+ Mesh *curve_mesh;
list<Attribute> attributes;
AttributeSet();
~AttributeSet();
- Attribute *add(ustring name, TypeDesc type, Attribute::Element element);
- Attribute *find(ustring name);
+ Attribute *add(ustring name, TypeDesc type, AttributeElement element);
+ Attribute *find(ustring name) const;
void remove(ustring name);
Attribute *add(AttributeStandard std, ustring name = ustring());
- Attribute *find(AttributeStandard std);
+ Attribute *find(AttributeStandard std) const;
void remove(AttributeStandard std);
Attribute *find(AttributeRequest& req);
- void reserve(int numverts, int numfaces);
+ void reserve();
void clear();
};
@@ -104,7 +102,7 @@ public:
*
* Request from a shader to use a certain attribute, so we can figure out
* which ones we need to export from the host app end store for the kernel.
- * The attribute is found either by name or by standard. */
+ * The attribute is found either by name or by standard attribute type. */
class AttributeRequest {
public:
@@ -112,9 +110,9 @@ public:
AttributeStandard std;
/* temporary variables used by MeshManager */
- TypeDesc type;
- AttributeElement element;
- int offset;
+ TypeDesc triangle_type, curve_type;
+ AttributeElement triangle_element, curve_element;
+ int triangle_offset, curve_offset;
AttributeRequest(ustring name_);
AttributeRequest(AttributeStandard std);
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 3b61ccd176d..572cfae45cd 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -83,6 +83,7 @@ RenderTile::RenderTile()
w = 0;
h = 0;
+ sample = 0;
start_sample = 0;
num_samples = 0;
resolution = 0;
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index a78ede979b2..3ca19496b72 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -216,9 +216,9 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
/* motion blur */
#ifdef __CAMERA_MOTION__
- kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: 0.0f;
+ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: -1.0f;
#else
- kcam->shuttertime = 0.0f;
+ kcam->shuttertime = -1.0f;
#endif
/* type */
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 9696161180d..197a4da588c 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -90,7 +90,7 @@ public:
Transform worldtocamera;
Transform rastertocamera;
- Transform cameratoraster;;
+ Transform cameratoraster;
float3 dx;
float3 dy;
diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp
new file mode 100644
index 00000000000..9fa867ae723
--- /dev/null
+++ b/intern/cycles/render/curves.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "device.h"
+#include "curves.h"
+#include "mesh.h"
+#include "object.h"
+#include "scene.h"
+
+#include "util_foreach.h"
+#include "util_map.h"
+#include "util_progress.h"
+#include "util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Curve functions */
+
+void curvebounds(float *lower, float *upper, float3 *p, int dim)
+{
+ float *p0 = &p[0].x;
+ float *p1 = &p[1].x;
+ float *p2 = &p[2].x;
+ float *p3 = &p[3].x;
+ float fc = 0.71f;
+ float curve_coef[4];
+ curve_coef[0] = p1[dim];
+ curve_coef[1] = -fc*p0[dim] + fc*p2[dim];
+ curve_coef[2] = 2.0f * fc * p0[dim] + (fc - 3.0f) * p1[dim] + (3.0f - 2.0f * fc) * p2[dim] - fc * p3[dim];
+ curve_coef[3] = -fc * p0[dim] + (2.0f - fc) * p1[dim] + (fc - 2.0f) * p2[dim] + fc * p3[dim];
+ float discroot = curve_coef[2] * curve_coef[2] - 3 * curve_coef[3] * curve_coef[1];
+ float ta = -1.0f;
+ float tb = -1.0f;
+ if(discroot >= 0) {
+ discroot = sqrt(discroot);
+ ta = (-curve_coef[2] - discroot) / (3 * curve_coef[3]);
+ tb = (-curve_coef[2] + discroot) / (3 * curve_coef[3]);
+ ta = (ta > 1.0f || ta < 0.0f) ? -1.0f : ta;
+ tb = (tb > 1.0f || tb < 0.0f) ? -1.0f : tb;
+ }
+
+ *upper = max(p1[dim],p2[dim]);
+ *lower = min(p1[dim],p2[dim]);
+ float exa = p1[dim];
+ float exb = p2[dim];
+ float t2;
+ float t3;
+ if(ta >= 0.0f) {
+ t2 = ta * ta;
+ t3 = t2 * ta;
+ exa = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * ta + curve_coef[0];
+ }
+ if(tb >= 0.0f) {
+ t2 = tb * tb;
+ t3 = t2 * tb;
+ exb = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * tb + curve_coef[0];
+ }
+ *upper = max(*upper, max(exa,exb));
+ *lower = min(*lower, min(exa,exb));
+
+}
+
+/* Hair System Manager */
+
+CurveSystemManager::CurveSystemManager()
+{
+ primitive = CURVE_LINE_SEGMENTS;
+ line_method = CURVE_CORRECTED;
+ interpolation = CURVE_CARDINAL;
+ triangle_method = CURVE_CAMERA_TRIANGLES;
+ resolution = 3;
+ segments = 1;
+ subdivisions = 3;
+
+ normalmix = 1.0f;
+ encasing_ratio = 1.01f;
+
+ use_curves = true;
+ use_smooth = true;
+ use_parents = false;
+ use_encasing = true;
+ use_backfacing = false;
+ use_joined = false;
+ use_tangent_normal = false;
+ use_tangent_normal_geometry = false;
+ use_tangent_normal_correction = false;
+
+ need_update = true;
+ need_mesh_update = false;
+}
+
+CurveSystemManager::~CurveSystemManager()
+{
+}
+
+void CurveSystemManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ if(!need_update)
+ return;
+
+ device_free(device, dscene);
+
+ progress.set_status("Updating Hair settings", "Copying Hair settings to device");
+
+ KernelCurves *kcurve= &dscene->data.curve_kernel_data;
+
+ kcurve->curveflags = 0;
+
+ if(use_curves) {
+ if(primitive == CURVE_SEGMENTS || primitive == CURVE_RIBBONS)
+ kcurve->curveflags |= CURVE_KN_INTERPOLATE;
+ if(primitive == CURVE_RIBBONS)
+ kcurve->curveflags |= CURVE_KN_RIBBONS;
+
+ if(line_method == CURVE_ACCURATE)
+ kcurve->curveflags |= CURVE_KN_ACCURATE;
+ if(line_method == CURVE_CORRECTED)
+ kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION;
+ if(line_method == CURVE_POSTCORRECTED)
+ kcurve->curveflags |= CURVE_KN_POSTINTERSECTCORRECTION;
+
+ if(use_tangent_normal)
+ kcurve->curveflags |= CURVE_KN_TANGENTGNORMAL;
+ if(use_tangent_normal_correction)
+ kcurve->curveflags |= CURVE_KN_NORMALCORRECTION;
+ if(use_tangent_normal_geometry)
+ kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL;
+ if(use_joined)
+ kcurve->curveflags |= CURVE_KN_CURVEDATA;
+ if(use_backfacing)
+ kcurve->curveflags |= CURVE_KN_BACKFACING;
+ if(use_encasing)
+ kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER;
+
+ kcurve->normalmix = normalmix;
+ kcurve->encasing_ratio = encasing_ratio;
+ kcurve->subdivisions = subdivisions;
+ }
+
+ if(progress.get_cancel()) return;
+
+ need_update = false;
+}
+
+void CurveSystemManager::device_free(Device *device, DeviceScene *dscene)
+{
+
+}
+
+bool CurveSystemManager::modified(const CurveSystemManager& CurveSystemManager)
+{
+ return !(line_method == CurveSystemManager.line_method &&
+ interpolation == CurveSystemManager.interpolation &&
+ primitive == CurveSystemManager.primitive &&
+ use_encasing == CurveSystemManager.use_encasing &&
+ use_tangent_normal == CurveSystemManager.use_tangent_normal &&
+ use_tangent_normal_correction == CurveSystemManager.use_tangent_normal_correction &&
+ use_tangent_normal_geometry == CurveSystemManager.use_tangent_normal_geometry &&
+ encasing_ratio == CurveSystemManager.encasing_ratio &&
+ use_backfacing == CurveSystemManager.use_backfacing &&
+ normalmix == CurveSystemManager.normalmix &&
+ use_smooth == CurveSystemManager.use_smooth &&
+ triangle_method == CurveSystemManager.triangle_method &&
+ resolution == CurveSystemManager.resolution &&
+ use_curves == CurveSystemManager.use_curves &&
+ use_joined == CurveSystemManager.use_joined &&
+ segments == CurveSystemManager.segments &&
+ use_parents == CurveSystemManager.use_parents &&
+ subdivisions == CurveSystemManager.subdivisions);
+}
+
+bool CurveSystemManager::modified_mesh(const CurveSystemManager& CurveSystemManager)
+{
+ return !(primitive == CurveSystemManager.primitive &&
+ interpolation == CurveSystemManager.interpolation &&
+ use_parents == CurveSystemManager.use_parents &&
+ use_smooth == CurveSystemManager.use_smooth &&
+ triangle_method == CurveSystemManager.triangle_method &&
+ resolution == CurveSystemManager.resolution &&
+ use_curves == CurveSystemManager.use_curves &&
+ use_joined == CurveSystemManager.use_joined &&
+ segments == CurveSystemManager.segments);
+}
+
+void CurveSystemManager::tag_update(Scene *scene)
+{
+ need_update = true;
+}
+
+void CurveSystemManager::tag_update_mesh()
+{
+ need_mesh_update = true;
+}
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h
new file mode 100644
index 00000000000..3527998339c
--- /dev/null
+++ b/intern/cycles/render/curves.h
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+#ifndef __CURVES_H__
+#define __CURVES_H__
+
+#include "util_types.h"
+#include "util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+class Device;
+class DeviceScene;
+class Progress;
+class Scene;
+
+void curvebounds(float *lower, float *upper, float3 *p, int dim);
+
+typedef enum curve_presets {
+ CURVE_CUSTOM,
+ CURVE_FAST_PLANES,
+ CURVE_TANGENT_SHADING,
+ CURVE_TRUE_NORMAL,
+ CURVE_ACCURATE_PRESET,
+ CURVE_SMOOTH_CURVES
+} curve_presets;
+
+typedef enum curve_primitives {
+ CURVE_TRIANGLES,
+ CURVE_LINE_SEGMENTS,
+ CURVE_SEGMENTS,
+ CURVE_RIBBONS
+} curve_primitives;
+
+typedef enum curve_triangles {
+ CURVE_CAMERA_TRIANGLES,
+ CURVE_RIBBON_TRIANGLES,
+ CURVE_TESSELATED_TRIANGLES
+} curve_triangles;
+
+typedef enum curve_lines {
+ CURVE_ACCURATE,
+ CURVE_CORRECTED,
+ CURVE_POSTCORRECTED,
+ CURVE_UNCORRECTED
+} curve_lines;
+
+typedef enum curve_interpolation {
+ CURVE_LINEAR,
+ CURVE_CARDINAL,
+ CURVE_BSPLINE
+} curve_interpolation;
+
+class ParticleCurveData {
+
+public:
+
+ ParticleCurveData();
+ ~ParticleCurveData();
+
+ vector<int> psys_firstcurve;
+ vector<int> psys_curvenum;
+ vector<int> psys_shader;
+
+ vector<float> psys_rootradius;
+ vector<float> psys_tipradius;
+ vector<float> psys_shape;
+ vector<bool> psys_closetip;
+
+ vector<int> curve_firstkey;
+ vector<int> curve_keynum;
+ vector<float> curve_length;
+ vector<float3> curve_uv;
+ vector<float3> curve_vcol;
+
+ vector<float3> curvekey_co;
+ vector<float> curvekey_time;
+};
+
+/* HairSystem Manager */
+
+class CurveSystemManager {
+public:
+
+ int primitive;
+ int line_method;
+ int interpolation;
+ int triangle_method;
+ int resolution;
+ int segments;
+ int subdivisions;
+
+ float normalmix;
+ float encasing_ratio;
+
+ bool use_curves;
+ bool use_smooth;
+ bool use_parents;
+ bool use_encasing;
+ bool use_backfacing;
+ bool use_tangent_normal;
+ bool use_tangent_normal_correction;
+ bool use_tangent_normal_geometry;
+ bool use_joined;
+
+ bool need_update;
+ bool need_mesh_update;
+
+ CurveSystemManager();
+ ~CurveSystemManager();
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_free(Device *device, DeviceScene *dscene);
+ bool modified(const CurveSystemManager& CurveSystemManager);
+ bool modified_mesh(const CurveSystemManager& CurveSystemManager);
+
+ void tag_update(Scene *scene);
+ void tag_update_mesh();
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __CURVES_H__ */
+
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 14b219383d0..af27b46771c 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -708,7 +708,8 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
value2_in->value.x = 1.0f;
weight_out = math_node->output("Value");
- disconnect(weight_in);
+ if(weight_in->link)
+ disconnect(weight_in);
}
/* connected to closure mix weight */
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index b79167839ab..61b5bd83534 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -183,6 +183,9 @@ public:
virtual void compile(SVMCompiler& compiler) = 0;
virtual void compile(OSLCompiler& compiler) = 0;
+ virtual bool has_surface_emission() { return false; }
+ virtual bool has_surface_transparent() { return false; }
+
vector<ShaderInput*> inputs;
vector<ShaderOutput*> outputs;
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 230a12f9ff2..8e844bc788e 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -85,10 +85,24 @@ bool ImageManager::set_animation_frame_update(int frame)
return false;
}
-bool ImageManager::is_float_image(const string& filename)
+bool ImageManager::is_float_image(const string& filename, void *builtin_data, bool& is_linear)
{
- ImageInput *in = ImageInput::create(filename);
bool is_float = false;
+ is_linear = false;
+
+ if(builtin_data) {
+ if(builtin_image_info_cb) {
+ int width, height, channels;
+ builtin_image_info_cb(filename, builtin_data, is_float, width, height, channels);
+ }
+
+ if(is_float)
+ is_linear = true;
+
+ return is_float;
+ }
+
+ ImageInput *in = ImageInput::create(filename);
if(in) {
ImageSpec spec;
@@ -96,14 +110,30 @@ bool ImageManager::is_float_image(const string& filename)
if(in->open(filename, spec)) {
/* check the main format, and channel formats;
* if any take up more than one byte, we'll need a float texture slot */
- if(spec.format.basesize() > 1)
+ if(spec.format.basesize() > 1) {
is_float = true;
+ is_linear = true;
+ }
for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
- if(spec.channelformats[channel].basesize() > 1)
+ if(spec.channelformats[channel].basesize() > 1) {
is_float = true;
+ is_linear = true;
+ }
}
+ /* basic color space detection, not great but better than nothing
+ * before we do OpenColorIO integration */
+ if(is_float) {
+ string colorspace = spec.get_string_attribute("oiio:ColorSpace");
+
+ is_linear = !(colorspace == "sRGB" ||
+ colorspace == "GammaCorrected" ||
+ strcmp(in->format_name(), "png") == 0);
+ }
+ else
+ is_linear = false;
+
in->close();
}
@@ -113,13 +143,13 @@ bool ImageManager::is_float_image(const string& filename)
return is_float;
}
-int ImageManager::add_image(const string& filename, bool animated, bool& is_float)
+int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear)
{
Image *img;
size_t slot;
/* load image info and find out if we need a float texture */
- is_float = (pack_images)? false: is_float_image(filename);
+ is_float = (pack_images)? false: is_float_image(filename, builtin_data, is_linear);
if(is_float) {
/* find existing image */
@@ -150,6 +180,7 @@ int ImageManager::add_image(const string& filename, bool animated, bool& is_floa
/* add new image */
img = new Image();
img->filename = filename;
+ img->builtin_data = builtin_data;
img->need_load = true;
img->animated = animated;
img->users = 1;
@@ -184,6 +215,7 @@ int ImageManager::add_image(const string& filename, bool animated, bool& is_floa
/* add new image */
img = new Image();
img->filename = filename;
+ img->builtin_data = builtin_data;
img->need_load = true;
img->animated = animated;
img->users = 1;
@@ -197,12 +229,12 @@ int ImageManager::add_image(const string& filename, bool animated, bool& is_floa
return slot;
}
-void ImageManager::remove_image(const string& filename)
+void ImageManager::remove_image(const string& filename, void *builtin_data)
{
size_t slot;
for(slot = 0; slot < images.size(); slot++) {
- if(images[slot] && images[slot]->filename == filename) {
+ if(images[slot] && images[slot]->filename == filename && images[slot]->builtin_data == builtin_data) {
/* decrement user count */
images[slot]->users--;
assert(images[slot]->users >= 0);
@@ -220,7 +252,7 @@ void ImageManager::remove_image(const string& filename)
if(slot == images.size()) {
/* see if it's in a float texture slot */
for(slot = 0; slot < float_images.size(); slot++) {
- if(float_images[slot] && float_images[slot]->filename == filename) {
+ if(float_images[slot] && float_images[slot]->filename == filename && float_images[slot]->builtin_data == builtin_data) {
/* decrement user count */
float_images[slot]->users--;
assert(float_images[slot]->users >= 0);
@@ -242,27 +274,43 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
if(img->filename == "")
return false;
- /* load image from file through OIIO */
- ImageInput *in = ImageInput::create(img->filename);
+ ImageInput *in = NULL;
+ int width, height, components;
- if(!in)
- return false;
+ if(!img->builtin_data) {
+ /* load image from file through OIIO */
+ in = ImageInput::create(img->filename);
- ImageSpec spec;
+ if(!in)
+ return false;
- if(!in->open(img->filename, spec)) {
- delete in;
- return false;
+ ImageSpec spec;
+
+ if(!in->open(img->filename, spec)) {
+ delete in;
+ return false;
+ }
+
+ width = spec.width;
+ height = spec.height;
+ components = spec.nchannels;
+ }
+ else {
+ /* load image using builtin images callbacks */
+ if(!builtin_image_info_cb || !builtin_image_pixels_cb)
+ return false;
+
+ bool is_float;
+ builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components);
}
/* we only handle certain number of components */
- int width = spec.width;
- int height = spec.height;
- int components = spec.nchannels;
-
if(!(components == 1 || components == 3 || components == 4)) {
- in->close();
- delete in;
+ if(in) {
+ in->close();
+ delete in;
+ }
+
return false;
}
@@ -270,14 +318,19 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
uchar *pixels = (uchar*)tex_img.resize(width, height);
int scanlinesize = width*components*sizeof(uchar);
- in->read_image(TypeDesc::UINT8,
- (uchar*)pixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
+ if(in) {
+ in->read_image(TypeDesc::UINT8,
+ (uchar*)pixels + (height-1)*scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
- in->close();
- delete in;
+ in->close();
+ delete in;
+ }
+ else {
+ builtin_image_pixels_cb(img->filename, img->builtin_data, pixels);
+ }
if(components == 3) {
for(int i = width*height-1; i >= 0; i--) {
@@ -304,27 +357,42 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
if(img->filename == "")
return false;
- /* load image from file through OIIO */
- ImageInput *in = ImageInput::create(img->filename);
+ ImageInput *in = NULL;
+ int width, height, components;
- if(!in)
- return false;
+ if(!img->builtin_data) {
+ /* load image from file through OIIO */
+ in = ImageInput::create(img->filename);
- ImageSpec spec;
+ if(!in)
+ return false;
- if(!in->open(img->filename, spec)) {
- delete in;
- return false;
+ ImageSpec spec;
+
+ if(!in->open(img->filename, spec)) {
+ delete in;
+ return false;
+ }
+
+ /* we only handle certain number of components */
+ width = spec.width;
+ height = spec.height;
+ components = spec.nchannels;
}
+ else {
+ /* load image using builtin images callbacks */
+ if(!builtin_image_info_cb || !builtin_image_float_pixels_cb)
+ return false;
- /* we only handle certain number of components */
- int width = spec.width;
- int height = spec.height;
- int components = spec.nchannels;
+ bool is_float;
+ builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components);
+ }
if(!(components == 1 || components == 3 || components == 4)) {
- in->close();
- delete in;
+ if(in) {
+ in->close();
+ delete in;
+ }
return false;
}
@@ -332,14 +400,19 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
float *pixels = (float*)tex_img.resize(width, height);
int scanlinesize = width*components*sizeof(float);
- in->read_image(TypeDesc::FLOAT,
- (uchar*)pixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
+ if(in) {
+ in->read_image(TypeDesc::FLOAT,
+ (uchar*)pixels + (height-1)*scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
- in->close();
- delete in;
+ in->close();
+ delete in;
+ }
+ else {
+ builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels);
+ }
if(components == 3) {
for(int i = width*height-1; i >= 0; i--) {
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 4d177174971..b20ff23fbbb 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -51,9 +51,9 @@ public:
ImageManager();
~ImageManager();
- int add_image(const string& filename, bool animated, bool& is_float);
- void remove_image(const string& filename);
- bool is_float_image(const string& filename);
+ int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear);
+ void remove_image(const string& filename, void *builtin_data);
+ bool is_float_image(const string& filename, void *builtin_data, bool& is_linear);
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
@@ -65,6 +65,9 @@ public:
bool need_update;
+ boost::function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &channels)> builtin_image_info_cb;
+ boost::function<bool(const string &filename, void *data, unsigned char *pixels)> builtin_image_pixels_cb;
+ boost::function<bool(const string &filename, void *data, float *pixels)> builtin_image_float_pixels_cb;
private:
int tex_num_images;
int tex_num_float_images;
@@ -74,6 +77,7 @@ private:
struct Image {
string filename;
+ void *builtin_data;
bool need_load;
bool animated;
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 4173da453fd..47e9dd8e7f5 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -115,6 +115,8 @@ Light::Light()
spot_smooth = 0.0f;
cast_shadow = true;
+ use_mis = false;
+
shader = 0;
samples = 1;
}
@@ -141,7 +143,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* count */
size_t num_lights = scene->lights.size();
+ size_t num_background_lights = 0;
size_t num_triangles = 0;
+ size_t num_curve_segments = 0;
foreach(Object *object, scene->objects) {
Mesh *mesh = object->mesh;
@@ -169,10 +173,19 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(shader->sample_as_light && shader->has_surface_emission)
num_triangles++;
}
+
+ /* disabled for curves */
+#if 0
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ Shader *shader = scene->shaders[curve.shader];
+
+ if(shader->sample_as_light && shader->has_surface_emission)
+ num_curve_segments += curve.num_segments();
+#endif
}
}
- size_t num_distribution = num_triangles;
+ size_t num_distribution = num_triangles + num_curve_segments;
num_distribution += num_lights;
/* emission area */
@@ -188,8 +201,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
bool have_emission = false;
/* skip if we are not visible for BSDFs */
- if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT)))
+ if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT))) {
+ j++;
continue;
+ }
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
@@ -216,7 +231,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(shader->sample_as_light && shader->has_surface_emission) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
- distribution[offset].z = 1.0f;
+ distribution[offset].z = __int_as_float(~0);
distribution[offset].w = __int_as_float(object_id);
offset++;
@@ -234,6 +249,40 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
totarea += triangle_area(p1, p2, p3);
}
}
+
+ /*sample as light disabled for strands*/
+#if 0
+ size_t i = 0;
+
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ Shader *shader = scene->shaders[curve.shader];
+ int first_key = curve.first_key;
+
+ if(shader->sample_as_light && shader->has_surface_emission) {
+ for(int j = 0; j < curve.num_segments(); j++) {
+ distribution[offset].x = totarea;
+ distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code
+ distribution[offset].z = __int_as_float(j);
+ distribution[offset].w = __int_as_float(object_id);
+ offset++;
+
+ float3 p1 = mesh->curve_keys[first_key + j].loc;
+ float r1 = mesh->curve_keys[first_key + j].radius;
+ float3 p2 = mesh->curve_keys[first_key + j + 1].loc;
+ float r2 = mesh->curve_keys[first_key + j + 1].radius;
+
+ if(!transform_applied) {
+ p1 = transform_point(&tfm, p1);
+ p2 = transform_point(&tfm, p2);
+ }
+
+ totarea += M_PI_F * (r1 + r2) * len(p1 - p2);
+ }
+ }
+
+ i++;
+ }
+#endif
}
if(progress.get_cancel()) return;
@@ -245,13 +294,21 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* point lights */
float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
+ bool use_lamp_mis = false;
for(int i = 0; i < scene->lights.size(); i++, offset++) {
+ Light *light = scene->lights[i];
+
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(~(int)i);
distribution[offset].z = 1.0f;
- distribution[offset].w = scene->lights[i]->size;
+ distribution[offset].w = light->size;
totarea += lightarea;
+
+ if(light->size > 0.0f && light->use_mis)
+ use_lamp_mis = true;
+ if(light->type == LIGHT_BACKGROUND)
+ num_background_lights++;
}
/* normalize cumulative distribution functions */
@@ -270,6 +327,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* update device */
KernelIntegrator *kintegrator = &dscene->data.integrator;
+ KernelFilm *kfilm = &dscene->data.film;
kintegrator->use_direct_light = (totarea > 0.0f);
if(kintegrator->use_direct_light) {
@@ -279,6 +337,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* precompute pdfs */
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
+ kintegrator->inv_pdf_lights = 0.0f;
/* sample one, with 0.5 probability of light or triangle */
kintegrator->num_all_lights = num_lights;
@@ -293,8 +352,22 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->pdf_lights = 1.0f/num_lights;
if(trianglearea > 0.0f)
kintegrator->pdf_lights *= 0.5f;
+
+ kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights;
}
+ kintegrator->use_lamp_mis = use_lamp_mis;
+
+ /* bit of an ugly hack to compensate for emitting triangles influencing
+ * amount of samples we get for this pass */
+ kfilm->pass_shadow_scale = 1.0f;
+
+ if(kintegrator->pdf_triangles != 0.0f)
+ kfilm->pass_shadow_scale *= 0.5f;
+
+ if(num_background_lights < num_lights)
+ kfilm->pass_shadow_scale *= (float)(num_lights - num_background_lights)/(float)num_lights;
+
/* CDF */
device->tex_alloc("__light_distribution", dscene->light_distribution);
}
@@ -305,6 +378,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->num_all_lights = 0;
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
+ kintegrator->inv_pdf_lights = 0.0f;
+ kintegrator->use_lamp_mis = false;
+ kfilm->pass_shadow_scale = 1.0f;
}
}
@@ -431,21 +507,37 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
if(light->type == LIGHT_POINT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
+
+ if(light->use_mis && radius > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_DISTANT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float angle = atanf(radius);
+ float cosangle = cosf(angle);
+ float area = M_PI_F*radius*radius;
+ float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+
+ if(light->use_mis && area > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_BACKGROUND) {
shader_id &= ~SHADER_AREA_LIGHT;
+ shader_id |= SHADER_USE_MIS;
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
@@ -455,21 +547,31 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
else if(light->type == LIGHT_AREA) {
float3 axisu = light->axisu*(light->sizeu*light->size);
float3 axisv = light->axisv*(light->sizev*light->size);
+ float area = len(axisu)*len(axisv);
+ float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+
+ if(light->use_mis && area > 0.0f)
+ shader_id |= SHADER_USE_MIS;
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
- light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
}
else if(light->type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
float spot_angle = cosf(light->spot_angle*0.5f);
float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
+ if(light->use_mis && radius > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
- light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
}
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index 3cedde2596e..acd1692a41f 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -52,6 +52,7 @@ public:
float spot_smooth;
bool cast_shadow;
+ bool use_mis;
int shader;
int samples;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index bc782a78c60..8d12ace4252 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -43,6 +43,7 @@ Mesh::Mesh()
need_update = true;
transform_applied = false;
transform_negative_scaled = false;
+ transform_normal = transform_identity();
displacement_method = DISPLACE_BUMP;
bounds = BoundBox::empty;
@@ -51,7 +52,11 @@ Mesh::Mesh()
tri_offset = 0;
vert_offset = 0;
- attributes.mesh = this;
+ curve_offset = 0;
+ curvekey_offset = 0;
+
+ attributes.triangle_mesh = this;
+ curve_attributes.curve_mesh = this;
}
Mesh::~Mesh()
@@ -59,14 +64,18 @@ Mesh::~Mesh()
delete bvh;
}
-void Mesh::reserve(int numverts, int numtris)
+void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys)
{
/* reserve space to add verts and triangles later */
verts.resize(numverts);
triangles.resize(numtris);
shader.resize(numtris);
smooth.resize(numtris);
- attributes.reserve(numverts, numtris);
+ curve_keys.resize(numcurvekeys);
+ curves.resize(numcurves);
+
+ attributes.reserve();
+ curve_attributes.reserve();
}
void Mesh::clear()
@@ -77,33 +86,61 @@ void Mesh::clear()
shader.clear();
smooth.clear();
+ curve_keys.clear();
+ curves.clear();
+
attributes.clear();
+ curve_attributes.clear();
used_shaders.clear();
transform_applied = false;
transform_negative_scaled = false;
+ transform_normal = transform_identity();
}
void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
{
- Triangle t;
- t.v[0] = v0;
- t.v[1] = v1;
- t.v[2] = v2;
+ Triangle tri;
+ tri.v[0] = v0;
+ tri.v[1] = v1;
+ tri.v[2] = v2;
- triangles.push_back(t);
+ triangles.push_back(tri);
shader.push_back(shader_);
smooth.push_back(smooth_);
}
+void Mesh::add_curve_key(float3 co, float radius)
+{
+ CurveKey key;
+ key.co = co;
+ key.radius = radius;
+
+ curve_keys.push_back(key);
+}
+
+void Mesh::add_curve(int first_key, int num_keys, int shader)
+{
+ Curve curve;
+ curve.first_key = first_key;
+ curve.num_keys = num_keys;
+ curve.shader = shader;
+
+ curves.push_back(curve);
+}
+
void Mesh::compute_bounds()
{
BoundBox bnds = BoundBox::empty;
size_t verts_size = verts.size();
+ size_t curve_keys_size = curve_keys.size();
for(size_t i = 0; i < verts_size; i++)
bnds.grow(verts[i]);
+ for(size_t i = 0; i < curve_keys_size; i++)
+ bnds.grow(curve_keys[i].co, curve_keys[i].radius);
+
/* happens mostly on empty meshes */
if(!bnds.valid())
bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
@@ -116,7 +153,7 @@ void Mesh::add_face_normals()
/* don't compute if already there */
if(attributes.find(ATTR_STD_FACE_NORMAL))
return;
-
+
/* get attributes */
Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
float3 *fN = attr_fN->data_float3();
@@ -135,12 +172,25 @@ void Mesh::add_face_normals()
float3 v1 = verts_ptr[t.v[1]];
float3 v2 = verts_ptr[t.v[2]];
- fN[i] = normalize(cross(v1 - v0, v2 - v0));
+ float3 norm = cross(v1 - v0, v2 - v0);
+ float normlen = len(norm);
+ if(normlen == 0.0f)
+ fN[i] = make_float3(0.0f, 0.0f, 0.0f);
+ else
+ fN[i] = norm / normlen;
if(flip)
fN[i] = -fN[i];
}
}
+
+ /* expected to be in local space */
+ if(transform_applied) {
+ Transform ntfm = transform_inverse(transform_normal);
+
+ for(size_t i = 0; i < triangles_size; i++)
+ fN[i] = normalize(transform_direction(&ntfm, fN[i]));
+ }
}
void Mesh::add_vertex_normals()
@@ -148,7 +198,7 @@ void Mesh::add_vertex_normals()
/* don't compute if already there */
if(attributes.find(ATTR_STD_VERTEX_NORMAL))
return;
-
+
/* get attributes */
Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
@@ -192,10 +242,18 @@ void Mesh::pack_normals(Scene *scene, float4 *normal, float4 *vnormal)
size_t triangles_size = triangles.size();
uint *shader_ptr = (shader.size())? &shader[0]: NULL;
+ bool do_transform = transform_applied;
+ Transform ntfm = transform_normal;
+
for(size_t i = 0; i < triangles_size; i++) {
- normal[i].x = fN[i].x;
- normal[i].y = fN[i].y;
- normal[i].z = fN[i].z;
+ float3 fNi = fN[i];
+
+ if(do_transform)
+ fNi = normalize(transform_direction(&ntfm, fNi));
+
+ normal[i].x = fNi.x;
+ normal[i].y = fNi.y;
+ normal[i].z = fNi.z;
/* stuff shader id in here too */
if(shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
@@ -209,8 +267,14 @@ void Mesh::pack_normals(Scene *scene, float4 *normal, float4 *vnormal)
size_t verts_size = verts.size();
- for(size_t i = 0; i < verts_size; i++)
- vnormal[i] = make_float4(vN[i].x, vN[i].y, vN[i].z, 0.0f);
+ for(size_t i = 0; i < verts_size; i++) {
+ float3 vNi = vN[i];
+
+ if(do_transform)
+ vNi = normalize(transform_direction(&ntfm, vNi));
+
+ vnormal[i] = make_float4(vNi.x, vNi.y, vNi.z, 0.0f);
+ }
}
void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
@@ -243,6 +307,43 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
}
}
+void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
+{
+ size_t curve_keys_size = curve_keys.size();
+ CurveKey *keys_ptr = NULL;
+
+ /* pack curve keys */
+ if(curve_keys_size) {
+ keys_ptr = &curve_keys[0];
+
+ for(size_t i = 0; i < curve_keys_size; i++) {
+ float3 p = keys_ptr[i].co;
+ float radius = keys_ptr[i].radius;
+
+ curve_key_co[i] = make_float4(p.x, p.y, p.z, radius);
+ }
+ }
+
+ /* pack curve segments */
+ size_t curve_num = curves.size();
+
+ if(curve_num) {
+ Curve *curve_ptr = &curves[0];
+ int shader_id = 0;
+
+ for(size_t i = 0; i < curve_num; i++) {
+ Curve curve = curve_ptr[i];
+ shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false);
+
+ curve_data[i] = make_float4(
+ __int_as_float(curve.first_key + curvekey_offset),
+ __int_as_float(curve.num_keys),
+ __int_as_float(shader_id),
+ 0.0f);
+ }
+ }
+}
+
void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total)
{
if(progress->get_cancel())
@@ -327,7 +428,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
og->attribute_map.clear();
og->object_names.clear();
- og->attribute_map.resize(scene->objects.size());
+ og->attribute_map.resize(scene->objects.size()*ATTR_PRIM_TYPES);
for(size_t i = 0; i < scene->objects.size(); i++) {
/* set object name to object index map */
@@ -343,7 +444,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
osl_attr.elem = ATTR_ELEMENT_VALUE;
osl_attr.value = attr;
- og->attribute_map[i][attr.name()] = osl_attr;
+ og->attribute_map[i*ATTR_PRIM_TYPES][attr.name()] = osl_attr;
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr;
}
/* find mesh attributes */
@@ -357,27 +459,46 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
/* set object attributes */
foreach(AttributeRequest& req, attributes.requests) {
- if(req.element == ATTR_ELEMENT_NONE)
- continue;
-
OSLGlobals::Attribute osl_attr;
- osl_attr.elem = req.element;
- osl_attr.offset = req.offset;
-
- if(req.type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if(req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(attribute_standard_name(req.std)));
- og->attribute_map[i][stdname] = osl_attr;
+ if(req.triangle_element != ATTR_ELEMENT_NONE) {
+ osl_attr.elem = req.triangle_element;
+ osl_attr.offset = req.triangle_offset;
+
+ if(req.triangle_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if(req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i*ATTR_PRIM_TYPES][stdname] = osl_attr;
+ }
+ else if(req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i*ATTR_PRIM_TYPES][req.name] = osl_attr;
+ }
}
- else if(req.name != ustring()) {
- /* add lookup by mesh attribute name */
- og->attribute_map[i][req.name] = osl_attr;
+
+ if(req.curve_element != ATTR_ELEMENT_NONE) {
+ osl_attr.elem = req.curve_element;
+ osl_attr.offset = req.curve_offset;
+
+ if(req.curve_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if(req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr;
+ }
+ else if(req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr;
+ }
}
}
}
@@ -393,7 +514,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
int attr_map_stride = 0;
for(size_t i = 0; i < scene->meshes.size(); i++)
- attr_map_stride = max(attr_map_stride, mesh_attributes[i].size()+1);
+ attr_map_stride = max(attr_map_stride, (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES);
if(attr_map_stride == 0)
return;
@@ -404,12 +525,13 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
for(size_t i = 0; i < scene->objects.size(); i++) {
Object *object = scene->objects[i];
+ Mesh *mesh = object->mesh;
/* find mesh attributes */
size_t j;
for(j = 0; j < scene->meshes.size(); j++)
- if(scene->meshes[j] == object->mesh)
+ if(scene->meshes[j] == mesh)
break;
AttributeRequestSet& attributes = mesh_attributes[j];
@@ -425,14 +547,29 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
else
id = scene->shader_manager->get_attribute_id(req.std);
- attr_map[index].x = id;
- attr_map[index].y = req.element;
- attr_map[index].z = as_uint(req.offset);
+ if(mesh->triangles.size()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.triangle_element;
+ attr_map[index].z = as_uint(req.triangle_offset);
- if(req.type == TypeDesc::TypeFloat)
- attr_map[index].w = NODE_ATTR_FLOAT;
- else
- attr_map[index].w = NODE_ATTR_FLOAT3;
+ if(req.triangle_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
+ }
+
+ index++;
+
+ if(mesh->curves.size()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.curve_element;
+ attr_map[index].z = as_uint(req.curve_offset);
+
+ if(req.curve_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
+ }
index++;
}
@@ -442,6 +579,15 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
attr_map[index].y = 0;
attr_map[index].z = 0;
attr_map[index].w = 0;
+
+ index++;
+
+ attr_map[index].x = ATTR_STD_NONE;
+ attr_map[index].y = 0;
+ attr_map[index].z = 0;
+ attr_map[index].w = 0;
+
+ index++;
}
/* copy to device */
@@ -449,6 +595,60 @@ 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,
+ Attribute *mattr, TypeDesc& type, int& offset, AttributeElement& element)
+{
+ if(mattr) {
+ /* store element and type */
+ element = mattr->element;
+ type = mattr->type;
+
+ /* store attribute data in arrays */
+ size_t size = mattr->element_size(
+ mesh->verts.size(),
+ mesh->triangles.size(),
+ mesh->curves.size(),
+ mesh->curve_keys.size());
+
+ if(mattr->type == TypeDesc::TypeFloat) {
+ float *data = mattr->data_float();
+ offset = attr_float.size();
+
+ attr_float.resize(attr_float.size() + size);
+
+ for(size_t k = 0; k < size; k++)
+ attr_float[offset+k] = data[k];
+ }
+ else {
+ float3 *data = mattr->data_float3();
+ offset = attr_float3.size();
+
+ attr_float3.resize(attr_float3.size() + size);
+
+ for(size_t k = 0; k < size; k++)
+ attr_float3[offset+k] = float3_to_float4(data[k]);
+ }
+
+ /* mesh vertex/curve index is global, not per object, so we sneak
+ * a correction for that in here */
+ if(element == ATTR_ELEMENT_VERTEX)
+ offset -= mesh->vert_offset;
+ else if(element == ATTR_ELEMENT_FACE)
+ offset -= mesh->tri_offset;
+ else if(element == ATTR_ELEMENT_CORNER)
+ offset -= 3*mesh->tri_offset;
+ else if(element == ATTR_ELEMENT_CURVE)
+ offset -= mesh->curve_offset;
+ else if(element == ATTR_ELEMENT_CURVE_KEY)
+ offset -= mesh->curvekey_offset;
+ }
+ else {
+ /* attribute not found */
+ element = ATTR_ELEMENT_NONE;
+ offset = 0;
+ }
+}
+
void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
progress.set_status("Updating Mesh", "Computing attributes");
@@ -482,66 +682,24 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
/* 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 *mattr = mesh->attributes.find(req);
-
- /* todo: get rid of this exception */
- if(!mattr && req.std == ATTR_STD_GENERATED) {
- mattr = mesh->attributes.add(ATTR_STD_GENERATED);
+ Attribute *triangle_mattr = mesh->attributes.find(req);
+ Attribute *curve_mattr = mesh->curve_attributes.find(req);
+
+ /* todo: get rid of this exception, it's only here for giving some
+ * working texture coordinate for subdivision as we can't preserve
+ * any attributes yet */
+ if(!triangle_mattr && req.std == ATTR_STD_GENERATED) {
+ triangle_mattr = mesh->attributes.add(ATTR_STD_GENERATED);
if(mesh->verts.size())
- memcpy(mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
- }
-
- /* attribute not found */
- if(!mattr) {
- req.element = ATTR_ELEMENT_NONE;
- req.offset = 0;
- continue;
- }
-
- /* we abuse AttributeRequest to pass on info like element and
- * offset, it doesn't really make sense but is convenient */
-
- /* store element and type */
- if(mattr->element == Attribute::VERTEX)
- req.element = ATTR_ELEMENT_VERTEX;
- else if(mattr->element == Attribute::FACE)
- req.element = ATTR_ELEMENT_FACE;
- else if(mattr->element == Attribute::CORNER)
- req.element = ATTR_ELEMENT_CORNER;
-
- req.type = mattr->type;
-
- /* store attribute data in arrays */
- size_t size = mattr->element_size(mesh->verts.size(), mesh->triangles.size());
-
- if(mattr->type == TypeDesc::TypeFloat) {
- float *data = mattr->data_float();
- req.offset = attr_float.size();
-
- attr_float.resize(attr_float.size() + size);
-
- for(size_t k = 0; k < size; k++)
- attr_float[req.offset+k] = data[k];
+ memcpy(triangle_mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
}
- else {
- float3 *data = mattr->data_float3();
- req.offset = attr_float3.size();
- attr_float3.resize(attr_float3.size() + size);
-
- for(size_t k = 0; k < size; k++)
- attr_float3[req.offset+k] = float3_to_float4(data[k]);
- }
-
- /* mesh vertex/triangle index is global, not per object, so we sneak
- * a correction for that in here */
- if(req.element == ATTR_ELEMENT_VERTEX)
- req.offset -= mesh->vert_offset;
- else if(mattr->element == Attribute::FACE)
- req.offset -= mesh->tri_offset;
- else if(mattr->element == Attribute::CORNER)
- req.offset -= 3*mesh->tri_offset;
+ update_attribute_element_offset(mesh, attr_float, attr_float3, triangle_mattr,
+ req.triangle_type, req.triangle_offset, req.triangle_element);
+ update_attribute_element_offset(mesh, attr_float, attr_float3, curve_mattr,
+ req.curve_type, req.curve_offset, req.curve_element);
+
if(progress.get_cancel()) return;
}
}
@@ -573,39 +731,62 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
size_t vert_size = 0;
size_t tri_size = 0;
+ size_t curve_key_size = 0;
+ size_t curve_size = 0;
+
foreach(Mesh *mesh, scene->meshes) {
mesh->vert_offset = vert_size;
mesh->tri_offset = tri_size;
+ mesh->curvekey_offset = curve_key_size;
+ mesh->curve_offset = curve_size;
+
vert_size += mesh->verts.size();
tri_size += mesh->triangles.size();
+
+ curve_key_size += mesh->curve_keys.size();
+ curve_size += mesh->curves.size();
}
- if(tri_size == 0)
- return;
+ if(tri_size != 0) {
+ /* normals */
+ progress.set_status("Updating Mesh", "Computing normals");
- /* normals */
- progress.set_status("Updating Mesh", "Computing normals");
+ float4 *normal = dscene->tri_normal.resize(tri_size);
+ float4 *vnormal = dscene->tri_vnormal.resize(vert_size);
+ float4 *tri_verts = dscene->tri_verts.resize(vert_size);
+ float4 *tri_vindex = dscene->tri_vindex.resize(tri_size);
- float4 *normal = dscene->tri_normal.resize(tri_size);
- float4 *vnormal = dscene->tri_vnormal.resize(vert_size);
- float4 *tri_verts = dscene->tri_verts.resize(vert_size);
- float4 *tri_vindex = dscene->tri_vindex.resize(tri_size);
+ foreach(Mesh *mesh, scene->meshes) {
+ mesh->pack_normals(scene, &normal[mesh->tri_offset], &vnormal[mesh->vert_offset]);
+ mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset);
- foreach(Mesh *mesh, scene->meshes) {
- mesh->pack_normals(scene, &normal[mesh->tri_offset], &vnormal[mesh->vert_offset]);
- mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset);
+ if(progress.get_cancel()) return;
+ }
- if(progress.get_cancel()) return;
+ /* vertex coordinates */
+ progress.set_status("Updating Mesh", "Copying Mesh to device");
+
+ device->tex_alloc("__tri_normal", dscene->tri_normal);
+ device->tex_alloc("__tri_vnormal", dscene->tri_vnormal);
+ device->tex_alloc("__tri_verts", dscene->tri_verts);
+ device->tex_alloc("__tri_vindex", dscene->tri_vindex);
}
- /* vertex coordinates */
- progress.set_status("Updating Mesh", "Copying Mesh to device");
+ if(curve_size != 0) {
+ progress.set_status("Updating Mesh", "Copying Strands to device");
+
+ float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
+ float4 *curves = dscene->curves.resize(curve_size);
- device->tex_alloc("__tri_normal", dscene->tri_normal);
- device->tex_alloc("__tri_vnormal", dscene->tri_vnormal);
- device->tex_alloc("__tri_verts", dscene->tri_verts);
- device->tex_alloc("__tri_vindex", dscene->tri_vindex);
+ foreach(Mesh *mesh, scene->meshes) {
+ mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset);
+ if(progress.get_cancel()) return;
+ }
+
+ device->tex_alloc("__curve_keys", dscene->curve_keys);
+ device->tex_alloc("__curves", dscene->curves);
+ }
}
void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
@@ -642,6 +823,10 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
device->tex_alloc("__tri_woop", dscene->tri_woop);
}
+ if(pack.prim_segment.size()) {
+ dscene->prim_segment.reference((uint*)&pack.prim_segment[0], pack.prim_segment.size());
+ device->tex_alloc("__prim_segment", dscene->prim_segment);
+ }
if(pack.prim_visibility.size()) {
dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
device->tex_alloc("__prim_visibility", dscene->prim_visibility);
@@ -751,6 +936,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->bvh_nodes);
device->tex_free(dscene->object_node);
device->tex_free(dscene->tri_woop);
+ device->tex_free(dscene->prim_segment);
device->tex_free(dscene->prim_visibility);
device->tex_free(dscene->prim_index);
device->tex_free(dscene->prim_object);
@@ -758,6 +944,8 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->tri_vnormal);
device->tex_free(dscene->tri_vindex);
device->tex_free(dscene->tri_verts);
+ device->tex_free(dscene->curves);
+ device->tex_free(dscene->curve_keys);
device->tex_free(dscene->attributes_map);
device->tex_free(dscene->attributes_float);
device->tex_free(dscene->attributes_float3);
@@ -765,6 +953,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->bvh_nodes.clear();
dscene->object_node.clear();
dscene->tri_woop.clear();
+ dscene->prim_segment.clear();
dscene->prim_visibility.clear();
dscene->prim_index.clear();
dscene->prim_object.clear();
@@ -772,9 +961,21 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->tri_vnormal.clear();
dscene->tri_vindex.clear();
dscene->tri_verts.clear();
+ dscene->curves.clear();
+ dscene->curve_keys.clear();
dscene->attributes_map.clear();
dscene->attributes_float.clear();
dscene->attributes_float3.clear();
+
+#ifdef WITH_OSL
+ OSLGlobals *og = (OSLGlobals*)device->osl_memory();
+
+ if(og) {
+ og->object_name_map.clear();
+ og->attribute_map.clear();
+ og->object_names.clear();
+ }
+#endif
}
void MeshManager::tag_update(Scene *scene)
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 637143f5adf..dca1b00e1ff 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -50,6 +50,21 @@ public:
int v[3];
};
+ /* Mesh Curve */
+ struct Curve {
+ int first_key;
+ int num_keys;
+ uint shader;
+ uint pad;
+
+ int num_segments() { return num_keys - 1; }
+ };
+
+ struct CurveKey {
+ float3 co;
+ float radius;
+ };
+
/* Displacement */
enum DisplacementMethod {
DISPLACE_BUMP,
@@ -65,12 +80,17 @@ public:
vector<uint> shader;
vector<bool> smooth;
+ vector<CurveKey> curve_keys;
+ vector<Curve> curves;
+
vector<uint> used_shaders;
AttributeSet attributes;
+ AttributeSet curve_attributes;
BoundBox bounds;
bool transform_applied;
bool transform_negative_scaled;
+ Transform transform_normal;
DisplacementMethod displacement_method;
/* Update Flags */
@@ -82,13 +102,18 @@ public:
size_t tri_offset;
size_t vert_offset;
+ size_t curve_offset;
+ size_t curvekey_offset;
+
/* Functions */
Mesh();
~Mesh();
- void reserve(int numverts, int numfaces);
+ void reserve(int numverts, int numfaces, int numcurves, int numcurvekeys);
void clear();
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
+ void add_curve_key(float3 loc, float radius);
+ void add_curve(int first_key, int num_keys, int shader);
void compute_bounds();
void add_face_normals();
@@ -96,6 +121,7 @@ public:
void pack_normals(Scene *scene, float4 *normal, float4 *vnormal);
void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset);
+ void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
void compute_bvh(SceneParams *params, Progress *progress, int n, int total);
bool need_attribute(Scene *scene, AttributeStandard std);
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index dea694a811e..04267697b29 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -19,6 +19,7 @@
#include "device.h"
#include "mesh.h"
+#include "object.h"
#include "scene.h"
#include "shader.h"
@@ -41,11 +42,24 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
if(!has_displacement)
return false;
+ string msg = string_printf("Computing Displacement %s", mesh->name.c_str());
+ progress.set_status("Updating Mesh", msg);
+
+ /* find object index. todo: is arbitrary */
+ size_t object_index = ~0;
+
+ for(size_t i = 0; i < scene->objects.size(); i++) {
+ if(scene->objects[i]->mesh == mesh) {
+ object_index = i;
+ break;
+ }
+ }
+
/* setup input for device task */
vector<bool> done(mesh->verts.size(), false);
device_vector<uint4> d_input;
uint4 *d_input_data = d_input.resize(mesh->verts.size());
- size_t d_input_offset = 0;
+ size_t d_input_size = 0;
for(size_t i = 0; i < mesh->triangles.size(); i++) {
Mesh::Triangle t = mesh->triangles[i];
@@ -61,8 +75,8 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
done[t.v[j]] = true;
/* set up object, primitive and barycentric coordinates */
- /* when used, non-instanced convention: object = -object-1; */
- int object = ~0; /* todo */
+ /* when used, non-instanced convention: object = ~object */
+ int object = ~object_index;
int prim = mesh->tri_offset + i;
float u, v;
@@ -81,16 +95,16 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
/* back */
uint4 in = make_uint4(object, prim, __float_as_int(u), __float_as_int(v));
- d_input_data[d_input_offset++] = in;
+ d_input_data[d_input_size++] = in;
}
}
- if(d_input_offset == 0)
+ if(d_input_size == 0)
return false;
/* run device task */
device_vector<float4> d_output;
- d_output.resize(d_input.size());
+ d_output.resize(d_input_size);
device->mem_alloc(d_input, MEM_READ_ONLY);
device->mem_copy_to(d_input);
@@ -101,7 +115,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
task.shader_output = d_output.device_pointer;
task.shader_eval_type = SHADER_EVAL_DISPLACE;
task.shader_x = 0;
- task.shader_w = d_input.size();
+ task.shader_w = d_output.size();
device->task_add(task);
device->task_wait();
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 3f8055b3540..8ac12242e15 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -141,9 +141,11 @@ ImageTextureNode::ImageTextureNode()
image_manager = NULL;
slot = -1;
is_float = -1;
+ is_linear = false;
filename = "";
+ builtin_data = NULL;
color_space = ustring("Color");
- projection = ustring("Flat");;
+ projection = ustring("Flat");
projection_blend = 0.0f;
animated = false;
@@ -155,7 +157,7 @@ ImageTextureNode::ImageTextureNode()
ImageTextureNode::~ImageTextureNode()
{
if(image_manager)
- image_manager->remove_image(filename);
+ image_manager->remove_image(filename, builtin_data);
}
ShaderNode *ImageTextureNode::clone() const
@@ -164,6 +166,7 @@ ShaderNode *ImageTextureNode::clone() const
node->image_manager = NULL;
node->slot = -1;
node->is_float = -1;
+ node->is_linear = false;
return node;
}
@@ -176,7 +179,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(is_float == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, animated, is_float_bool);
+ slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear);
is_float = (int)is_float_bool;
}
@@ -188,7 +191,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
if(slot != -1) {
compiler.stack_assign(vector_in);
- int srgb = (is_float || color_space != "Color")? 0: 1;
+ int srgb = (is_linear || color_space != "Color")? 0: 1;
int vector_offset = vector_in->stack_offset;
if(!tex_mapping.skip()) {
@@ -237,10 +240,10 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
tex_mapping.compile(compiler);
if(is_float == -1)
- is_float = (int)image_manager->is_float_image(filename);
+ is_float = (int)image_manager->is_float_image(filename, NULL, is_linear);
compiler.parameter("filename", filename.c_str());
- if(is_float || color_space != "Color")
+ if(is_linear || color_space != "Color")
compiler.parameter("color_space", "Linear");
else
compiler.parameter("color_space", "sRGB");
@@ -270,7 +273,9 @@ EnvironmentTextureNode::EnvironmentTextureNode()
image_manager = NULL;
slot = -1;
is_float = -1;
+ is_linear = false;
filename = "";
+ builtin_data = NULL;
color_space = ustring("Color");
projection = ustring("Equirectangular");
animated = false;
@@ -283,7 +288,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
EnvironmentTextureNode::~EnvironmentTextureNode()
{
if(image_manager)
- image_manager->remove_image(filename);
+ image_manager->remove_image(filename, builtin_data);
}
ShaderNode *EnvironmentTextureNode::clone() const
@@ -292,6 +297,7 @@ ShaderNode *EnvironmentTextureNode::clone() const
node->image_manager = NULL;
node->slot = -1;
node->is_float = -1;
+ node->is_linear = false;
return node;
}
@@ -304,7 +310,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(slot == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, animated, is_float_bool);
+ slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear);
is_float = (int)is_float_bool;
}
@@ -316,7 +322,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
if(slot != -1) {
compiler.stack_assign(vector_in);
- int srgb = (is_float || color_space != "Color")? 0: 1;
+ int srgb = (is_linear || color_space != "Color")? 0: 1;
int vector_offset = vector_in->stack_offset;
if(!tex_mapping.skip()) {
@@ -354,11 +360,11 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler)
tex_mapping.compile(compiler);
if(is_float == -1)
- is_float = (int)image_manager->is_float_image(filename);
+ is_float = (int)image_manager->is_float_image(filename, NULL, is_linear);
compiler.parameter("filename", filename.c_str());
compiler.parameter("projection", projection);
- if(is_float || color_space != "Color")
+ if(is_linear || color_space != "Color")
compiler.parameter("color_space", "Linear");
else
compiler.parameter("color_space", "sRGB");
@@ -2240,6 +2246,63 @@ void ParticleInfoNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_particle_info");
}
+/* Hair Info */
+
+HairInfoNode::HairInfoNode()
+: ShaderNode("hair_info")
+{
+ add_output("Is Strand", SHADER_SOCKET_FLOAT);
+ add_output("Intercept", SHADER_SOCKET_FLOAT);
+ add_output("Thickness", SHADER_SOCKET_FLOAT);
+ add_output("Tangent Normal", SHADER_SOCKET_NORMAL);
+}
+
+void HairInfoNode::attributes(AttributeRequestSet *attributes)
+{
+ ShaderOutput *intercept_out = output("Intercept");
+
+ if(!intercept_out->links.empty())
+ attributes->add(ATTR_STD_CURVE_INTERCEPT);
+
+ ShaderNode::attributes(attributes);
+}
+
+void HairInfoNode::compile(SVMCompiler& compiler)
+{
+ ShaderOutput *out;
+
+ out = output("Is Strand");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, out->stack_offset);
+ }
+
+ out = output("Intercept");
+ if(!out->links.empty()) {
+ int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_ATTR, attr, out->stack_offset, NODE_ATTR_FLOAT);
+ }
+
+ out = output("Thickness");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, out->stack_offset);
+ }
+
+ out = output("Tangent Normal");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, out->stack_offset);
+ }
+
+}
+
+void HairInfoNode::compile(OSLCompiler& compiler)
+{
+ compiler.add(this, "node_hair_info");
+}
+
/* Value */
ValueNode::ValueNode()
@@ -3018,9 +3081,56 @@ void RGBCurvesNode::compile(SVMCompiler& compiler)
void RGBCurvesNode::compile(OSLCompiler& compiler)
{
+ float ramp[RAMP_TABLE_SIZE][3];
+
+ for (int i = 0; i < RAMP_TABLE_SIZE; ++i) {
+ ramp[i][0] = curves[i].x;
+ ramp[i][1] = curves[i].y;
+ ramp[i][2] = curves[i].z;
+ }
+
+ compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE);
compiler.add(this, "node_rgb_curves");
}
+/* VectorCurvesNode */
+
+VectorCurvesNode::VectorCurvesNode()
+: ShaderNode("rgb_curves")
+{
+ add_input("Fac", SHADER_SOCKET_FLOAT);
+ add_input("Vector", SHADER_SOCKET_VECTOR);
+ add_output("Vector", SHADER_SOCKET_VECTOR);
+}
+
+void VectorCurvesNode::compile(SVMCompiler& compiler)
+{
+ ShaderInput *fac_in = input("Fac");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *vector_out = output("Vector");
+
+ compiler.stack_assign(fac_in);
+ compiler.stack_assign(vector_in);
+ compiler.stack_assign(vector_out);
+
+ compiler.add_node(NODE_VECTOR_CURVES, fac_in->stack_offset, vector_in->stack_offset, vector_out->stack_offset);
+ compiler.add_array(curves, RAMP_TABLE_SIZE);
+}
+
+void VectorCurvesNode::compile(OSLCompiler& compiler)
+{
+ float ramp[RAMP_TABLE_SIZE][3];
+
+ for (int i = 0; i < RAMP_TABLE_SIZE; ++i) {
+ ramp[i][0] = curves[i].x;
+ ramp[i][1] = curves[i].y;
+ ramp[i][2] = curves[i].z;
+ }
+
+ compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE);
+ compiler.add(this, "node_vector_curves");
+}
+
/* RGBRampNode */
RGBRampNode::RGBRampNode()
@@ -3151,6 +3261,8 @@ void NormalMapNode::attributes(AttributeRequestSet *attributes)
attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
}
+
+ attributes->add(ATTR_STD_VERTEX_NORMAL);
}
ShaderNode::attributes(attributes);
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 67733142dd1..3609497e5ce 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -26,7 +26,7 @@
CCL_NAMESPACE_BEGIN
class ImageManager;
-class Shadr;
+class Shader;
/* Texture Mapping */
@@ -69,7 +69,9 @@ public:
ImageManager *image_manager;
int slot;
int is_float;
+ bool is_linear;
string filename;
+ void *builtin_data;
ustring color_space;
ustring projection;
float projection_blend;
@@ -88,7 +90,9 @@ public:
ImageManager *image_manager;
int slot;
int is_float;
+ bool is_linear;
string filename;
+ void *builtin_data;
ustring color_space;
ustring projection;
bool animated;
@@ -220,6 +224,8 @@ public:
class TransparentBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(TransparentBsdfNode)
+
+ bool has_surface_transparent() { return true; }
};
class VelvetBsdfNode : public BsdfNode {
@@ -255,6 +261,8 @@ class EmissionNode : public ShaderNode {
public:
SHADER_NODE_CLASS(EmissionNode)
+ bool has_surface_emission() { return true; }
+
bool total_power;
};
@@ -327,6 +335,13 @@ public:
void attributes(AttributeRequestSet *attributes);
};
+class HairInfoNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(HairInfoNode)
+
+ void attributes(AttributeRequestSet *attributes);
+};
+
class ValueNode : public ShaderNode {
public:
SHADER_NODE_CLASS(ValueNode)
@@ -455,6 +470,12 @@ public:
float4 curves[RAMP_TABLE_SIZE];
};
+class VectorCurvesNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(VectorCurvesNode)
+ float4 curves[RAMP_TABLE_SIZE];
+};
+
class RGBRampNode : public ShaderNode {
public:
SHADER_NODE_CLASS(RGBRampNode)
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index bd9f16d64ef..b31650c160a 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -19,6 +19,7 @@
#include "device.h"
#include "light.h"
#include "mesh.h"
+#include "curves.h"
#include "object.h"
#include "scene.h"
@@ -45,6 +46,7 @@ Object::Object()
motion.post = transform_identity();
use_motion = false;
use_holdout = false;
+ curverender = false;
}
Object::~Object()
@@ -82,34 +84,31 @@ void Object::apply_transform()
{
if(!mesh || tfm == transform_identity())
return;
-
+
+ float3 c0 = transform_get_column(&tfm, 0);
+ float3 c1 = transform_get_column(&tfm, 1);
+ float3 c2 = transform_get_column(&tfm, 2);
+ float scalar = pow(fabsf(dot(cross(c0, c1), c2)), 1.0f/3.0f);
+
for(size_t i = 0; i < mesh->verts.size(); i++)
mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
- Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
- Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
+ for(size_t i = 0; i < mesh->curve_keys.size(); i++) {
+ mesh->curve_keys[i].co = transform_point(&tfm, mesh->curve_keys[i].co);
+ /* scale for strand radius - only correct for uniform transforms*/
+ mesh->curve_keys[i].radius *= scalar;
+ }
- Transform ntfm = transform_transpose(transform_inverse(tfm));
+ /* store matrix to transform later. when accessing these as attributes we
+ * do not want the transform to be applied for consistency between static
+ * and dynamic BVH, so we do it on packing. */
+ mesh->transform_normal = transform_transpose(transform_inverse(tfm));
/* we keep normals pointing in same direction on negative scale, notify
* mesh about this in it (re)calculates normals */
if(transform_negative_scale(tfm))
mesh->transform_negative_scaled = true;
- if(attr_fN) {
- float3 *fN = attr_fN->data_float3();
-
- for(size_t i = 0; i < mesh->triangles.size(); i++)
- fN[i] = transform_direction(&ntfm, fN[i]);
- }
-
- if(attr_vN) {
- float3 *vN = attr_vN->data_float3();
-
- for(size_t i = 0; i < mesh->verts.size(); i++)
- vN[i] = transform_direction(&ntfm, vN[i]);
- }
-
if(bounds.valid()) {
mesh->compute_bounds();
compute_bounds(false, 0.0f);
@@ -133,6 +132,7 @@ void Object::tag_update(Scene *scene)
}
}
+ scene->curve_system_manager->need_update = true;
scene->mesh_manager->need_update = true;
scene->object_manager->need_update = true;
}
@@ -150,12 +150,17 @@ ObjectManager::~ObjectManager()
void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress)
{
- float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
+ float4 *objects;
+ float4 *objects_vector = NULL;
int i = 0;
map<Mesh*, float> surface_area_map;
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
bool have_motion = false;
+ objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
+ if(need_motion == Scene::MOTION_PASS)
+ objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size());
+
foreach(Object *ob, scene->objects) {
Mesh *mesh = ob->mesh;
uint flag = 0;
@@ -184,6 +189,20 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ int first_key = curve.first_key;
+
+ for(int i = 0; i < curve.num_segments(); i++) {
+ float3 p1 = mesh->curve_keys[first_key + i].co;
+ float r1 = mesh->curve_keys[first_key + i].radius;
+ float3 p2 = mesh->curve_keys[first_key + i + 1].co;
+ float r2 = mesh->curve_keys[first_key + i + 1].radius;
+
+ /* currently ignores segment overlaps*/
+ surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+ }
+ }
+
surface_area_map[mesh] = surface_area;
}
else
@@ -199,14 +218,31 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
+
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ int first_key = curve.first_key;
+
+ for(int i = 0; i < curve.num_segments(); i++) {
+ float3 p1 = mesh->curve_keys[first_key + i].co;
+ float r1 = mesh->curve_keys[first_key + i].radius;
+ float3 p2 = mesh->curve_keys[first_key + i + 1].co;
+ float r2 = mesh->curve_keys[first_key + i + 1].radius;
+
+ p1 = transform_point(&tfm, p1);
+ p2 = transform_point(&tfm, p2);
+
+ /* currently ignores segment overlaps*/
+ surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+ }
+ }
}
/* pack in texture */
int offset = i*OBJECT_SIZE;
memcpy(&objects[offset], &tfm, sizeof(float4)*3);
- memcpy(&objects[offset+3], &itfm, sizeof(float4)*3);
- objects[offset+6] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
+ memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
+ objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
if(need_motion == Scene::MOTION_PASS) {
/* motion transformations, is world/object space depending if mesh
@@ -220,8 +256,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
if(!mesh->attributes.find(ATTR_STD_MOTION_POST))
mtfm_post = mtfm_post * itfm;
- memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
- memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
+ 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);
}
#ifdef __OBJECT_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
@@ -230,20 +266,16 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
- memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
+ memcpy(&objects[offset], &decomp, sizeof(float4)*8);
flag |= SD_OBJECT_MOTION;
have_motion = true;
}
- else {
- float4 no_motion = make_float4(FLT_MAX);
- memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8);
- }
}
#endif
/* dupli object coords */
- objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
- objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
+ objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
+ objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
/* object flag */
if(ob->use_holdout)
@@ -256,6 +288,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
}
device->tex_alloc("__objects", dscene->objects);
+ if(need_motion == Scene::MOTION_PASS)
+ device->tex_alloc("__objects_vector", dscene->objects_vector);
dscene->data.bvh.have_motion = have_motion;
}
@@ -297,6 +331,9 @@ void ObjectManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->objects);
dscene->objects.clear();
+ device->tex_free(dscene->objects_vector);
+ dscene->objects_vector.clear();
+
device->tex_free(dscene->object_flag);
dscene->object_flag.clear();
}
@@ -349,6 +386,7 @@ void ObjectManager::apply_static_transforms(Scene *scene, uint *object_flag, Pro
void ObjectManager::tag_update(Scene *scene)
{
need_update = true;
+ scene->curve_system_manager->need_update = true;
scene->mesh_manager->need_update = true;
scene->light_manager->need_update = true;
}
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 9c9b11bc29c..9ba500ca4d6 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -48,6 +48,7 @@ public:
MotionTransform motion;
bool use_motion;
bool use_holdout;
+ bool curverender;
float3 dupli_generated;
float2 dupli_uv;
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index e4ee40d881e..56158278e29 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -47,17 +47,27 @@ OSLShaderManager::OSLShaderManager()
{
services = new OSLRenderServices();
- shading_system_init();
texture_system_init();
+ shading_system_init();
}
OSLShaderManager::~OSLShaderManager()
{
OSL::ShadingSystem::destroy(ss);
OSL::TextureSystem::destroy(ts);
+
delete services;
}
+void OSLShaderManager::reset(Scene *scene)
+{
+ OSL::ShadingSystem::destroy(ss);
+ delete services;
+
+ services = new OSLRenderServices();
+ shading_system_init();
+}
+
void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
if(!need_update)
@@ -76,18 +86,19 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
if(progress.get_cancel()) return;
- if(shader->sample_as_light && shader->has_surface_emission)
- scene->light_manager->need_update = true;
-
OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager);
compiler.background = (shader == scene->shaders[scene->default_background]);
compiler.compile(og, shader);
+
+ if(shader->sample_as_light && shader->has_surface_emission)
+ scene->light_manager->need_update = true;
}
/* setup shader engine */
og->ss = ss;
og->ts = ts;
og->services = services;
+
int background_id = scene->shader_manager->get_shader_id(scene->default_background);
og->background_state = og->surface_state[background_id & SHADER_MASK];
og->use = true;
@@ -202,8 +213,14 @@ static string shader_filepath_hash(const string& filepath, uint64_t modified_tim
const char *OSLShaderManager::shader_test_loaded(const string& hash)
{
- set<string>::iterator it = loaded_shaders.find(hash);
- return (it == loaded_shaders.end())? NULL: it->c_str();
+ map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
+ return (it == loaded_shaders.end())? NULL: it->first.c_str();
+}
+
+OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string& hash)
+{
+ map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
+ return (it == loaded_shaders.end())? NULL: &it->second;
}
const char *OSLShaderManager::shader_load_filepath(string filepath)
@@ -261,18 +278,59 @@ const char *OSLShaderManager::shader_load_filepath(string filepath)
if(!path_read_text(filepath, bytecode)) {
fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str());
- loaded_shaders.insert(bytecode_hash); /* to avoid repeat tries */
+ OSLShaderInfo info;
+ loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */
return NULL;
}
return shader_load_bytecode(bytecode_hash, bytecode);
}
+/* don't try this at home .. this is a template trick to use either
+ * LoadMemoryShader or LoadMemoryCompiledShader which are the function
+ * names in our custom branch and the official repository. */
+
+template<bool C, typename T = void> struct enable_if { typedef T type; };
+template<typename T> struct enable_if<false, T> { };
+
+template<typename T, typename Sign>
+struct has_LoadMemoryCompiledShader {
+ typedef int yes;
+ typedef char no;
+
+ template<typename U, U> struct type_check;
+ template<typename _1> static yes &chk(type_check<Sign, &_1::LoadMemoryCompiledShader>*);
+ template<typename > static no &chk(...);
+ static bool const value = sizeof(chk<T>(0)) == sizeof(yes);
+};
+
+template<typename T>
+typename enable_if<has_LoadMemoryCompiledShader<T,
+ bool(T::*)(const char*, const char*)>::value, bool>::type
+load_memory_shader(T *ss, const char *name, const char *buffer)
+{
+ return ss->LoadMemoryCompiledShader(name, buffer);
+}
+
+template<typename T>
+typename enable_if<!has_LoadMemoryCompiledShader<T,
+ bool(T::*)(const char*, const char*)>::value, bool>::type
+load_memory_shader(T *ss, const char *name, const char *buffer)
+{
+ return ss->LoadMemoryShader(name, buffer);
+}
+
const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode)
{
- ss->LoadMemoryShader(hash.c_str(), bytecode.c_str());
+ load_memory_shader(ss, hash.c_str(), bytecode.c_str());
- return loaded_shaders.insert(hash).first->c_str();
+ /* this is a bit weak, but works */
+ OSLShaderInfo info;
+ info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos);
+ info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos);
+ loaded_shaders[hash] = info;
+
+ return loaded_shaders.find(hash)->first.c_str();
}
/* Graph Compiler */
@@ -443,6 +501,16 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str());
}
}
+
+ /* test if we shader contains specific closures */
+ OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name);
+
+ if(info) {
+ if(info->has_surface_emission)
+ current_shader->has_surface_emission = true;
+ if(info->has_surface_transparent)
+ current_shader->has_surface_transparent = true;
+ }
}
void OSLCompiler::parameter(const char *name, float f)
@@ -598,9 +666,9 @@ void OSLCompiler::generate_nodes(const set<ShaderNode*>& nodes)
node->compile(*this);
done.insert(node);
- if(node->name == ustring("emission"))
+ if(node->has_surface_emission())
current_shader->has_surface_emission = true;
- if(node->name == ustring("transparent"))
+ if(node->has_surface_transparent())
current_shader->has_surface_transparent = true;
}
else
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index 9b58745bd46..4b4ed6cba00 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -36,7 +36,7 @@ class Device;
class DeviceScene;
class ImageManager;
class OSLRenderServices;
-class OSLGlobals;
+struct OSLGlobals;
class Scene;
class ShaderGraph;
class ShaderNode;
@@ -45,6 +45,18 @@ class ShaderOutput;
#ifdef WITH_OSL
+/* OSL Shader Info
+ * to auto detect closures in the shader for MIS and transparent shadows */
+
+struct OSLShaderInfo {
+ OSLShaderInfo()
+ : has_surface_emission(false), has_surface_transparent(false)
+ {}
+
+ bool has_surface_emission;
+ bool has_surface_transparent;
+};
+
/* Shader Manage */
class OSLShaderManager : public ShaderManager {
@@ -52,6 +64,8 @@ public:
OSLShaderManager();
~OSLShaderManager();
+ void reset(Scene *scene);
+
bool use_osl() { return true; }
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
@@ -65,6 +79,7 @@ public:
const char *shader_test_loaded(const string& hash);
const char *shader_load_bytecode(const string& hash, const string& bytecode);
const char *shader_load_filepath(string filepath);
+ OSLShaderInfo *shader_loaded_info(const string& hash);
protected:
void texture_system_init();
@@ -74,7 +89,7 @@ protected:
OSL::TextureSystem *ts;
OSLRenderServices *services;
OSL::ErrorHandler errhandler;
- set<string> loaded_shaders;
+ map<string, OSLShaderInfo> loaded_shaders;
};
#endif
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 8085cfdd3e6..7b82a91cae8 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -29,6 +29,7 @@
#include "mesh.h"
#include "object.h"
#include "particles.h"
+#include "curves.h"
#include "scene.h"
#include "svm.h"
#include "osl.h"
@@ -54,6 +55,7 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
integrator = new Integrator();
image_manager = new ImageManager();
particle_system_manager = new ParticleSystemManager();
+ curve_system_manager = new CurveSystemManager();
/* OSL only works on the CPU */
if(device_info_.type == DEVICE_CPU)
@@ -83,6 +85,12 @@ void Scene::free_memory(bool final)
foreach(ParticleSystem *p, particle_systems)
delete p;
+ shaders.clear();
+ meshes.clear();
+ objects.clear();
+ lights.clear();
+ particle_systems.clear();
+
if(device) {
camera->device_free(device, &dscene);
filter->device_free(device, &dscene);
@@ -96,8 +104,9 @@ void Scene::free_memory(bool final)
light_manager->device_free(device, &dscene);
particle_system_manager->device_free(device, &dscene);
+ curve_system_manager->device_free(device, &dscene);
- if(!params.persistent_images || final)
+ if(!params.persistent_data || final)
image_manager->device_free(device, &dscene);
}
@@ -112,15 +121,9 @@ void Scene::free_memory(bool final)
delete shader_manager;
delete light_manager;
delete particle_system_manager;
+ delete curve_system_manager;
delete image_manager;
}
- else {
- shaders.clear();
- meshes.clear();
- objects.clear();
- lights.clear();
- particle_systems.clear();
- }
}
void Scene::device_update(Device *device_, Progress& progress)
@@ -165,6 +168,11 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
+ progress.set_status("Updating Hair Systems");
+ curve_system_manager->device_update(device, &dscene, this, progress);
+
+ if(progress.get_cancel()) return;
+
progress.set_status("Updating Meshes");
mesh_manager->device_update(device, &dscene, this, progress);
@@ -242,11 +250,13 @@ bool Scene::need_reset()
|| filter->need_update
|| integrator->need_update
|| shader_manager->need_update
- || particle_system_manager->need_update);
+ || particle_system_manager->need_update
+ || curve_system_manager->need_update);
}
void Scene::reset()
{
+ shader_manager->reset(this);
shader_manager->add_default(this);
/* ensure all objects are updated */
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 92ef692b4b9..fc6b538af03 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -25,7 +25,6 @@
#include "kernel_types.h"
-#include "util_attribute.h"
#include "util_param.h"
#include "util_string.h"
#include "util_thread.h"
@@ -50,6 +49,7 @@ class Object;
class ObjectManager;
class ParticleSystemManager;
class ParticleSystem;
+class CurveSystemManager;
class Shader;
class ShaderManager;
class Progress;
@@ -62,6 +62,7 @@ public:
device_vector<float4> bvh_nodes;
device_vector<uint> object_node;
device_vector<float4> tri_woop;
+ device_vector<uint> prim_segment;
device_vector<uint> prim_visibility;
device_vector<uint> prim_index;
device_vector<uint> prim_object;
@@ -72,8 +73,12 @@ public:
device_vector<float4> tri_vindex;
device_vector<float4> tri_verts;
+ device_vector<float4> curves;
+ device_vector<float4> curve_keys;
+
/* objects */
device_vector<float4> objects;
+ device_vector<float4> objects_vector;
/* attributes */
device_vector<uint4> attributes_map;
@@ -120,7 +125,7 @@ public:
bool use_bvh_cache;
bool use_bvh_spatial_split;
bool use_qbvh;
- bool persistent_images;
+ bool persistent_data;
SceneParams()
{
@@ -141,7 +146,7 @@ public:
&& use_bvh_cache == params.use_bvh_cache
&& use_bvh_spatial_split == params.use_bvh_spatial_split
&& use_qbvh == params.use_qbvh
- && persistent_images == params.persistent_images); }
+ && persistent_data == params.persistent_data); }
};
/* Scene */
@@ -169,6 +174,7 @@ public:
MeshManager *mesh_manager;
ObjectManager *object_manager;
ParticleSystemManager *particle_system_manager;
+ CurveSystemManager *curve_system_manager;
/* default shaders */
int default_surface;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 1d1a3d54893..6ed14452c6b 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN
Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
- params.background == false || params.progressive_refine, params.background,
+ params.background == false || params.progressive_refine, params.background, params.tile_order,
max(params.device.multi_devices.size(), 1)),
stats()
{
@@ -132,6 +132,8 @@ bool Session::ready_to_reset()
void Session::reset_gpu(BufferParams& buffer_params, int samples)
{
+ thread_scoped_lock pause_lock(pause_mutex);
+
/* block for buffer acces and reset immediately. we can't do this
* in the thread, because we need to allocate an OpenGL buffer, and
* that only works in the main thread */
@@ -208,7 +210,12 @@ void Session::run_gpu()
* wait for pause condition notify to wake up again */
thread_scoped_lock pause_lock(pause_mutex);
- if(pause || no_tiles) {
+ if(!pause && !tile_manager.done()) {
+ /* reset could have happened after no_tiles was set, before this lock.
+ * in this case we shall not wait for pause condition
+ */
+ }
+ else if(pause || no_tiles) {
update_status_time(pause, no_tiles);
while(1) {
@@ -295,6 +302,7 @@ void Session::run_gpu()
void Session::reset_cpu(BufferParams& buffer_params, int samples)
{
thread_scoped_lock reset_lock(delayed_reset.mutex);
+ thread_scoped_lock pause_lock(pause_mutex);
display_outdated = true;
reset_time = time_dt();
@@ -357,7 +365,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
tile_lock.unlock();
- /* in case of a permant buffer, return it, otherwise we will allocate
+ /* in case of a permanent buffer, return it, otherwise we will allocate
* a new temporary buffer */
if(!params.background) {
tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
@@ -381,7 +389,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
buffer_params.get_offset_stride(rtile.offset, rtile.stride);
- RenderBuffers *tilebuffers = new RenderBuffers(tile_device);
+ RenderBuffers *tilebuffers;
/* allocate buffers */
if(params.progressive_refine) {
@@ -411,6 +419,12 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
rtile.rgba = 0;
rtile.buffers = tilebuffers;
+ /* this will tag tile as IN PROGRESS in blender-side render pipeline,
+ * which is needed to highlight currently rendering tile before first
+ * sample was processed for it
+ */
+ update_tile_sample(rtile);
+
return true;
}
@@ -478,7 +492,16 @@ void Session::run_cpu()
* wait for pause condition notify to wake up again */
thread_scoped_lock pause_lock(pause_mutex);
- if(pause || no_tiles) {
+ if(!pause && delayed_reset.do_reset) {
+ /* reset once to start */
+ thread_scoped_lock reset_lock(delayed_reset.mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock display_lock(display_mutex);
+
+ reset_(delayed_reset.params, delayed_reset.samples);
+ delayed_reset.do_reset = false;
+ }
+ else if(pause || no_tiles) {
update_status_time(pause, no_tiles);
while(1) {
@@ -546,7 +569,7 @@ void Session::run_cpu()
}
else if(need_tonemap) {
/* tonemap only if we do not reset, we don't we don't
- * wan't to show the result of an incomplete sample*/
+ * want to show the result of an incomplete sample*/
tonemap();
}
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index cfc1502287d..27073d2fd9c 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -51,6 +51,7 @@ public:
bool experimental;
int samples;
int2 tile_size;
+ int tile_order;
int start_resolution;
int threads;
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index d4421002ceb..b38e098e3cb 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -110,6 +110,8 @@ public:
static ShaderManager *create(Scene *scene, int shadingsystem);
virtual ~ShaderManager();
+ virtual void reset(Scene *scene) = 0;
+
virtual bool use_osl() { return false; }
/* device update */
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 4acd174e60f..5cb11a4ec1a 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -40,6 +40,10 @@ SVMShaderManager::~SVMShaderManager()
{
}
+void SVMShaderManager::reset(Scene *scene)
+{
+}
+
void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
if(!need_update)
@@ -478,9 +482,9 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
stack_clear_users(node, done);
stack_clear_temporary(node);
- if(node->name == ustring("emission"))
+ if(node->has_surface_emission())
current_shader->has_surface_emission = true;
- if(node->name == ustring("transparent"))
+ if(node->has_surface_transparent())
current_shader->has_surface_transparent = true;
/* end node is added outside of this */
@@ -538,9 +542,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
mix_weight_offset = SVM_STACK_INVALID;
- if(node->name == ustring("emission"))
+ if(node->has_surface_emission())
current_shader->has_surface_emission = true;
- if(node->name == ustring("transparent"))
+ if(node->has_surface_transparent())
current_shader->has_surface_transparent = true;
}
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index 0b15c5aaa1e..c1ce619e12a 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -45,6 +45,8 @@ public:
SVMShaderManager();
~SVMShaderManager();
+ void reset(Scene *scene);
+
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
};
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index bbcdb47260e..d62ecd8a88c 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -24,10 +24,11 @@
CCL_NAMESPACE_BEGIN
TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_,
- bool preserve_tile_device_, bool background_, int num_devices_)
+ bool preserve_tile_device_, bool background_, int tile_order_, int num_devices_)
{
progressive = progressive_;
tile_size = tile_size_;
+ tile_order = tile_order_;
start_resolution = start_resolution_;
num_devices = num_devices_;
preserve_tile_device = preserve_tile_device_;
@@ -165,6 +166,20 @@ void TileManager::set_tiles()
state.buffer.full_height = max(1, params.full_height/resolution);
}
+list<Tile>::iterator TileManager::next_viewport_tile(int device)
+{
+ list<Tile>::iterator iter;
+
+ int logical_device = preserve_tile_device? device: 0;
+
+ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
+ if(iter->device == logical_device && iter->rendering == false)
+ return iter;
+ }
+
+ return state.tiles.end();
+}
+
list<Tile>::iterator TileManager::next_center_tile(int device)
{
list<Tile>::iterator iter, best = state.tiles.end();
@@ -210,28 +225,53 @@ list<Tile>::iterator TileManager::next_center_tile(int device)
return best;
}
-list<Tile>::iterator TileManager::next_simple_tile(int device)
+list<Tile>::iterator TileManager::next_simple_tile(int device, int tile_order)
{
- list<Tile>::iterator iter;
+ list<Tile>::iterator iter, best = state.tiles.end();
+ int resolution = state.resolution_divider;
int logical_device = preserve_tile_device? device: 0;
+ int64_t cordx = max(1, params.width/resolution);
+ int64_t cordy = max(1, params.height/resolution);
+ int64_t mindist = cordx * cordy;
+
for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
- if(iter->device == logical_device && iter->rendering == false)
- return iter;
+ if(iter->device == logical_device && iter->rendering == false) {
+ Tile &cur_tile = *iter;
+
+ int64_t distx = cordx;
+
+ if (tile_order == TileManager::RIGHT_TO_LEFT)
+ distx = cordx - cur_tile.x;
+ else if (tile_order == TileManager::LEFT_TO_RIGHT)
+ distx = cordx + cur_tile.x;
+ else if (tile_order == TileManager::TOP_TO_BOTTOM)
+ distx = cordx - cur_tile.y;
+ else /* TileManager::BOTTOM_TO_TOP */
+ distx = cordx + cur_tile.y;
+
+ if(distx < mindist) {
+ best = iter;
+ mindist = distx;
+ }
+ }
}
- return state.tiles.end();
+ return best;
}
bool TileManager::next_tile(Tile& tile, int device)
{
list<Tile>::iterator tile_it;
-
- if(background)
- tile_it = next_center_tile(device);
+ if (background) {
+ if(tile_order == TileManager::CENTER)
+ tile_it = next_center_tile(device);
+ else
+ tile_it = next_simple_tile(device, tile_order);
+ }
else
- tile_it = next_simple_tile(device);
+ tile_it = next_viewport_tile(device);
if(tile_it != state.tiles.end()) {
tile_it->rendering = true;
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 6f7a8f20734..99cffb49c08 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -59,7 +59,7 @@ public:
} state;
TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution,
- bool preserve_tile_device, bool background, int num_devices = 1);
+ bool preserve_tile_device, bool background, int tile_order, int num_devices = 1);
~TileManager();
void reset(BufferParams& params, int num_samples);
@@ -68,12 +68,23 @@ public:
bool next_tile(Tile& tile, int device = 0);
bool done();
+ void set_tile_order(int tile_order_) { tile_order = tile_order_; }
protected:
+ /* Note: this should match enum_tile_order in properties.py */
+ enum {
+ CENTER = 0,
+ RIGHT_TO_LEFT = 1,
+ LEFT_TO_RIGHT = 2,
+ TOP_TO_BOTTOM = 3,
+ BOTTOM_TO_TOP = 4
+ } TileOrder;
+
void set_tiles();
bool progressive;
int num_samples;
int2 tile_size;
+ int tile_order;
int start_resolution;
int num_devices;
@@ -106,9 +117,12 @@ protected:
* mimics behavior of blender internal's tile order
*/
list<Tile>::iterator next_center_tile(int device);
+
+ /* returns simple tile order */
+ list<Tile>::iterator next_simple_tile(int device, int tile_order);
- /* returns first unhandled tile starting from left bottom corner of the image */
- list<Tile>::iterator next_simple_tile(int device);
+ /* returns first unhandled tile (for viewport) */
+ list<Tile>::iterator next_viewport_tile(int device);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 6920df9954c..48e6808bc38 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -47,7 +47,7 @@ void EdgeDice::reserve(int num_verts, int num_tris)
vert_offset = mesh->verts.size();
tri_offset = mesh->triangles.size();
- mesh->reserve(vert_offset + num_verts, tri_offset + num_tris);
+ mesh->reserve(vert_offset + num_verts, tri_offset + num_tris, 0, 0);
Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index dce417704cc..bcaaa9a71b9 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -9,7 +9,6 @@ set(INC_SYS
)
set(SRC
- util_attribute.cpp
util_cache.cpp
util_cuda.cpp
util_dynlib.cpp
@@ -33,7 +32,6 @@ endif()
set(SRC_HEADERS
util_algorithm.h
util_args.h
- util_attribute.h
util_boundbox.h
util_cache.h
util_cuda.h
diff --git a/intern/cycles/util/util_attribute.cpp b/intern/cycles/util/util_attribute.cpp
deleted file mode 100644
index 057fb6213e9..00000000000
--- a/intern/cycles/util/util_attribute.cpp
+++ /dev/null
@@ -1,51 +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.
- */
-
-#include "util_attribute.h"
-
-CCL_NAMESPACE_BEGIN
-
-const char *attribute_standard_name(AttributeStandard std)
-{
- if(std == ATTR_STD_VERTEX_NORMAL)
- return "N";
- else if(std == ATTR_STD_FACE_NORMAL)
- return "Ng";
- else if(std == ATTR_STD_UV)
- return "uv";
- else if(std == ATTR_STD_GENERATED)
- return "generated";
- else if(std == ATTR_STD_UV_TANGENT)
- return "tangent";
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- return "tangent_sign";
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- return "undeformed";
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- return "undisplaced";
- else if(std == ATTR_STD_MOTION_PRE)
- return "motion_pre";
- else if(std == ATTR_STD_MOTION_POST)
- return "motion_post";
- else if(std == ATTR_STD_PARTICLE)
- return "particle";
-
- return "";
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h
index 6dd1c6c71e8..7564c1f3c5c 100644
--- a/intern/cycles/util/util_boundbox.h
+++ b/intern/cycles/util/util_boundbox.h
@@ -61,8 +61,17 @@ public:
__forceinline void grow(const float3& pt)
{
- min = ccl::min(min, pt);
- max = ccl::max(max, pt);
+ /* the order of arguments to min is such that if pt is nan, it will not
+ * influence the resulting bounding box */
+ min = ccl::min(pt, min);
+ max = ccl::max(pt, max);
+ }
+
+ __forceinline void grow(const float3& pt, float border)
+ {
+ float3 shift = {border, border, border, 0.0f};
+ min = ccl::min(pt - shift, min);
+ max = ccl::max(pt + shift, max);
}
__forceinline void grow(const BoundBox& bbox)
diff --git a/intern/cycles/util/util_cache.h b/intern/cycles/util/util_cache.h
index e8f111a5397..deff05fff16 100644
--- a/intern/cycles/util/util_cache.h
+++ b/intern/cycles/util/util_cache.h
@@ -72,7 +72,7 @@ public:
buffers.push_back(buffer);
}
- void add(void *data, size_t size)
+ void add(const void *data, size_t size)
{
if(size) {
CacheBuffer buffer(data, size);
@@ -80,19 +80,19 @@ public:
}
}
- void add(int& data)
+ void add(const int& data)
{
CacheBuffer buffer(&data, sizeof(int));
buffers.push_back(buffer);
}
- void add(float& data)
+ void add(const float& data)
{
CacheBuffer buffer(&data, sizeof(float));
buffers.push_back(buffer);
}
- void add(size_t& data)
+ void add(const size_t& data)
{
CacheBuffer buffer(&data, sizeof(size_t));
buffers.push_back(buffer);
diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp
index 2716f00e173..6c9ee7c548f 100644
--- a/intern/cycles/util/util_cuda.cpp
+++ b/intern/cycles/util/util_cuda.cpp
@@ -376,28 +376,30 @@ bool cuLibraryInit()
/* cuda 4.0 */
CUDA_LIBRARY_FIND(cuCtxSetCurrent);
-#ifndef WITH_CUDA_BINARIES
-#ifdef _WIN32
- return false; /* runtime build doesn't work at the moment */
-#else
- if(cuCompilerPath() == "")
- return false;
-#endif
+ if(cuHavePrecompiledKernels())
+ result = true;
+#ifndef _WIN32
+ else if(cuCompilerPath() != "")
+ result = true;
#endif
- /* success */
- result = true;
-
return result;
}
+bool cuHavePrecompiledKernels()
+{
+ string cubins_path = path_get("lib");
+
+ return path_exists(cubins_path);
+}
+
string cuCompilerPath()
{
#ifdef _WIN32
- const char *defaultpath = "C:/CUDA/bin";
+ const char *defaultpaths[] = {"C:/CUDA/bin", NULL};
const char *executable = "nvcc.exe";
#else
- const char *defaultpath = "/usr/local/cuda/bin";
+ const char *defaultpaths[] = {"/Developer/NVIDIA/CUDA-4.2/bin", "/usr/local/cuda-4.2/bin", "/usr/local/cuda/bin", NULL};
const char *executable = "nvcc";
#endif
@@ -405,13 +407,17 @@ string cuCompilerPath()
string nvcc;
- if(binpath)
+ if(binpath) {
nvcc = path_join(binpath, executable);
- else
- nvcc = path_join(defaultpath, executable);
+ if(path_exists(nvcc))
+ return nvcc;
+ }
- if(path_exists(nvcc))
- return nvcc;
+ for(int i = 0; defaultpaths[i]; i++) {
+ nvcc = path_join(defaultpaths[i], executable);
+ if(path_exists(nvcc))
+ return nvcc;
+ }
#ifndef _WIN32
{
diff --git a/intern/cycles/util/util_cuda.h b/intern/cycles/util/util_cuda.h
index d9d956b7bd9..55feb3f84cb 100644
--- a/intern/cycles/util/util_cuda.h
+++ b/intern/cycles/util/util_cuda.h
@@ -30,6 +30,7 @@ CCL_NAMESPACE_BEGIN
* matrixMulDynlinkJIT in the CUDA SDK. */
bool cuLibraryInit();
+bool cuHavePrecompiledKernels();
string cuCompilerPath();
CCL_NAMESPACE_END
@@ -38,7 +39,7 @@ CCL_NAMESPACE_END
#define CUDA_VERSION 3020
-#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
+#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined(__LP64__)
typedef unsigned long long CUdeviceptr;
#else
typedef unsigned int CUdeviceptr;
@@ -205,7 +206,8 @@ typedef enum CUjit_target_enum
CU_TARGET_COMPUTE_13,
CU_TARGET_COMPUTE_20,
CU_TARGET_COMPUTE_21,
- CU_TARGET_COMPUTE_30
+ CU_TARGET_COMPUTE_30,
+ CU_TARGET_COMPUTE_35
} CUjit_target;
typedef enum CUjit_fallback_enum
diff --git a/intern/cycles/util/util_dynlib.cpp b/intern/cycles/util/util_dynlib.cpp
index 5836073a07a..3eaa16ab37d 100644
--- a/intern/cycles/util/util_dynlib.cpp
+++ b/intern/cycles/util/util_dynlib.cpp
@@ -22,7 +22,7 @@
#ifdef _WIN32
-#include <Windows.h>
+#include <windows.h>
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 70adee4385b..c37fa1a4dc6 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -1092,6 +1092,199 @@ __device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
return r;
}
+/* NaN-safe math ops */
+
+__device float safe_asinf(float a)
+{
+ if(a <= -1.0f)
+ return -M_PI_2_F;
+ else if(a >= 1.0f)
+ return M_PI_2_F;
+
+ return asinf(a);
+}
+
+__device float safe_acosf(float a)
+{
+ if(a <= -1.0f)
+ return M_PI_F;
+ else if(a >= 1.0f)
+ return 0.0f;
+
+ return acosf(a);
+}
+
+__device float compatible_powf(float x, float y)
+{
+ /* GPU pow doesn't accept negative x, do manual checks here */
+ if(x < 0.0f) {
+ if(fmod(-y, 2.0f) == 0.0f)
+ return powf(-x, y);
+ else
+ return -powf(-x, y);
+ }
+ else if(x == 0.0f)
+ return 0.0f;
+
+ return powf(x, y);
+}
+
+__device float safe_powf(float a, float b)
+{
+ if(b == 0.0f)
+ return 1.0f;
+ if(a == 0.0f)
+ return 0.0f;
+ if(a < 0.0f && b != (int)b)
+ return 0.0f;
+
+ return compatible_powf(a, b);
+}
+
+__device float safe_logf(float a, float b)
+{
+ if(a < 0.0f || b < 0.0f)
+ return 0.0f;
+
+ return logf(a)/logf(b);
+}
+
+__device float safe_divide(float a, float b)
+{
+ float result;
+
+ if(b == 0.0f)
+ result = 0.0f;
+ else
+ result = a/b;
+
+ return result;
+}
+
+/* Ray Intersection */
+
+__device bool ray_sphere_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 sphere_P, float sphere_radius,
+ float3 *isect_P, float *isect_t)
+{
+ float3 d = sphere_P - ray_P;
+ float radiussq = sphere_radius*sphere_radius;
+ float tsq = dot(d, d);
+
+ if(tsq > radiussq) { /* ray origin outside sphere */
+ float tp = dot(d, ray_D);
+
+ if(tp < 0.0f) /* dir points away from sphere */
+ return false;
+
+ float dsq = tsq - tp*tp; /* pythagoras */
+
+ if(dsq > radiussq) /* closest point on ray outside sphere */
+ return false;
+
+ float t = tp - sqrtf(radiussq - dsq); /* pythagoras */
+
+ if(t < ray_t) {
+ *isect_t = t;
+ *isect_P = ray_P + ray_D*t;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+__device bool ray_aligned_disk_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 disk_P, float disk_radius,
+ float3 *isect_P, float *isect_t)
+{
+ /* aligned disk normal */
+ float disk_t;
+ float3 disk_N = normalize_len(ray_P - disk_P, &disk_t);
+ float div = dot(ray_D, disk_N);
+
+ if(div == 0.0f)
+ return false;
+
+ /* compute t to intersection point */
+ float t = -disk_t/div;
+ if(t < 0.0f || t > ray_t)
+ return false;
+
+ /* test if within radius */
+ float3 P = ray_P + ray_D*t;
+ if(len_squared(P - disk_P) > disk_radius*disk_radius)
+ return false;
+
+ *isect_P = P;
+ *isect_t = t;
+
+ return true;
+}
+
+__device bool ray_triangle_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 v0, float3 v1, float3 v2,
+ float3 *isect_P, float *isect_t)
+{
+ /* Calculate intersection */
+ float3 e1 = v1 - v0;
+ float3 e2 = v2 - v0;
+ float3 s1 = cross(ray_D, e2);
+
+ const float divisor = dot(s1, e1);
+ if(divisor == 0.0f)
+ return false;
+
+ const float invdivisor = 1.0f/divisor;
+
+ /* compute first barycentric coordinate */
+ const float3 d = ray_P - v0;
+ const float u = dot(d, s1)*invdivisor;
+ if(u < 0.0f)
+ return false;
+
+ /* Compute second barycentric coordinate */
+ const float3 s2 = cross(d, e1);
+ const float v = dot(ray_D, s2)*invdivisor;
+ if(v < 0.0f)
+ return false;
+
+ const float b0 = 1.0f - u - v;
+ if(b0 < 0.0f)
+ return false;
+
+ /* compute t to intersection point */
+ const float t = dot(e2, s2)*invdivisor;
+ if(t < 0.0f || t > ray_t)
+ return false;
+
+ *isect_t = t;
+ *isect_P = ray_P + ray_D*t;
+
+ return true;
+}
+
+__device bool ray_quad_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 quad_P, float3 quad_u, float3 quad_v,
+ float3 *isect_P, float *isect_t)
+{
+ float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f;
+ float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f;
+ float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f;
+ float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f;
+
+ if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t))
+ return true;
+ else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t))
+ return true;
+
+ return false;
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H__ */
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index 2d9f0fffae6..4fda090e09e 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -136,7 +136,7 @@ struct CPUCapabilities {
bool fma4;
};
-bool system_cpu_support_optimized()
+static CPUCapabilities& system_cpu_capabilities()
{
static CPUCapabilities caps;
static bool caps_init = false;
@@ -182,7 +182,18 @@ bool system_cpu_support_optimized()
caps_init = true;
}
- /* optimization flags use these */
+ return caps;
+}
+
+bool system_cpu_support_sse2()
+{
+ CPUCapabilities& caps = system_cpu_capabilities();
+ return caps.sse && caps.sse2;
+}
+
+bool system_cpu_support_sse3()
+{
+ CPUCapabilities& caps = system_cpu_capabilities();
return caps.sse && caps.sse2 && caps.sse3;
}
diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h
index f25e009a250..257112883d1 100644
--- a/intern/cycles/util/util_system.h
+++ b/intern/cycles/util/util_system.h
@@ -26,7 +26,8 @@ CCL_NAMESPACE_BEGIN
int system_cpu_thread_count();
string system_cpu_brand_string();
int system_cpu_bits();
-bool system_cpu_support_optimized();
+bool system_cpu_support_sse2();
+bool system_cpu_support_sse3();
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp
index 8c4ec312256..43f15ba0ce6 100644
--- a/intern/cycles/util/util_task.cpp
+++ b/intern/cycles/util/util_task.cpp
@@ -152,7 +152,6 @@ void TaskPool::num_increase()
thread_mutex TaskScheduler::mutex;
int TaskScheduler::users = 0;
vector<thread*> TaskScheduler::threads;
-vector<int> TaskScheduler::thread_level;
volatile bool TaskScheduler::do_exit = false;
list<TaskScheduler::Entry> TaskScheduler::queue;
@@ -179,12 +178,9 @@ void TaskScheduler::init(int num_threads)
/* launch threads that will be waiting for work */
threads.resize(num_threads);
- thread_level.resize(num_threads);
- for(size_t i = 0; i < threads.size(); i++) {
+ for(size_t i = 0; i < threads.size(); i++)
threads[i] = new thread(function_bind(&TaskScheduler::thread_run, i));
- thread_level[i] = 0;
- }
}
users++;
@@ -208,7 +204,6 @@ void TaskScheduler::exit()
}
threads.clear();
- thread_level.clear();
}
}
diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h
index b795ca7524b..5bca3f255af 100644
--- a/intern/cycles/util/util_task.h
+++ b/intern/cycles/util/util_task.h
@@ -111,7 +111,6 @@ protected:
static thread_mutex mutex;
static int users;
static vector<thread*> threads;
- static vector<int> thread_level;
static volatile bool do_exit;
static list<Entry> queue;
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index a1c12ddf0e1..1f19f85f894 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -45,7 +45,7 @@ typedef struct Transform {
*
* For the DecompMotionTransform we drop scale from pre/post. */
-typedef struct MotionTransform {
+typedef struct __may_alias MotionTransform {
Transform pre;
Transform mid;
Transform post;
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 3d246104ddc..bb6de1197e7 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -39,12 +39,14 @@
#if defined(_WIN32) && !defined(FREE_WINDOWS)
#define __device_inline static __forceinline
#define __align(...) __declspec(align(__VA_ARGS__))
+#define __may_alias
#else
#define __device_inline static inline __attribute__((always_inline))
#ifndef FREE_WINDOWS64
#define __forceinline inline __attribute__((always_inline))
#endif
#define __align(...) __attribute__((aligned(__VA_ARGS__)))
+#define __may_alias __attribute__((__may_alias__))
#endif
#endif
@@ -446,24 +448,6 @@ __device_inline int4 make_int4(const float3& f)
#endif
-typedef enum AttributeStandard {
- ATTR_STD_NONE = 0,
- ATTR_STD_VERTEX_NORMAL,
- ATTR_STD_FACE_NORMAL,
- ATTR_STD_UV,
- ATTR_STD_UV_TANGENT,
- ATTR_STD_UV_TANGENT_SIGN,
- ATTR_STD_GENERATED,
- ATTR_STD_POSITION_UNDEFORMED,
- ATTR_STD_POSITION_UNDISPLACED,
- ATTR_STD_MOTION_PRE,
- ATTR_STD_MOTION_POST,
- ATTR_STD_PARTICLE,
- ATTR_STD_NUM,
-
- ATTR_STD_NOT_FOUND = ~0
-} AttributeStandard;
-
CCL_NAMESPACE_END
#endif /* __UTIL_TYPES_H__ */
diff --git a/intern/dualcon/SConscript b/intern/dualcon/SConscript
index 481e9ae7f5c..34df21a74c3 100644
--- a/intern/dualcon/SConscript
+++ b/intern/dualcon/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/dualcon/intern/MemoryAllocator.h b/intern/dualcon/intern/MemoryAllocator.h
index b704542d27b..e673d9498d2 100644
--- a/intern/dualcon/intern/MemoryAllocator.h
+++ b/intern/dualcon/intern/MemoryAllocator.h
@@ -43,6 +43,8 @@
class VirtualMemoryAllocator
{
public:
+virtual ~VirtualMemoryAllocator() {}
+
virtual void *allocate( ) = 0;
virtual void deallocate(void *obj) = 0;
virtual void destroy( ) = 0;
diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript
index 9c035c0c285..133f02e41bc 100644
--- a/intern/elbeem/SConscript
+++ b/intern/elbeem/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
Import('env')
diff --git a/intern/elbeem/intern/ntl_world.cpp b/intern/elbeem/intern/ntl_world.cpp
index dcc81dbe5cb..9ae5135b040 100644
--- a/intern/elbeem/intern/ntl_world.cpp
+++ b/intern/elbeem/intern/ntl_world.cpp
@@ -420,7 +420,12 @@ int ntlWorld::advanceSims(int framenum)
// Was: double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); - DG
double totalTime = 0.0, targetTime = 0.0;
for(size_t i = 0; i < mSimFrameCnt; i++)
- totalTime += (*mpSims)[mFirstSim]->getFrameTime(framenum);
+ {
+ /* We need an intermediate array "mSimFrameValue" because
+ otherwise if we don't start with starttime = 0,
+ the sim gets out of sync - DG */
+ totalTime += (*mpSims)[mFirstSim]->getFrameTime(mSimFrameValue[i]);
+ }
targetTime = totalTime + (*mpSims)[mFirstSim]->getFrameTime(framenum);
int gstate = 0;
@@ -468,6 +473,7 @@ int ntlWorld::advanceSims(int framenum)
sim->prepareVisualization();
}
+ mSimFrameValue.push_back(framenum);
mSimFrameCnt++;
return 0;
diff --git a/intern/elbeem/intern/ntl_world.h b/intern/elbeem/intern/ntl_world.h
index c207904cf75..6cec098132b 100644
--- a/intern/elbeem/intern/ntl_world.h
+++ b/intern/elbeem/intern/ntl_world.h
@@ -118,6 +118,7 @@ class ntlWorld
/*! count no. of frame for correct sim time */
int mSimFrameCnt;
+ vector<int> mSimFrameValue;
};
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index 37cde2c2837..c07dc869291 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -33,6 +33,7 @@
#include <libavcodec/avcodec.h>
#include <libavutil/rational.h>
#include <libavutil/opt.h>
+#include <libavutil/mathematics.h>
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
#define FFMPEG_HAVE_PARSE_UTILS 1
@@ -75,10 +76,68 @@
#define FFMPEG_FFV1_ALPHA_SUPPORTED
#endif
+#if ((LIBAVUTIL_VERSION_MAJOR < 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 22))
+static inline
+int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
+{
+ const AVOption *rv = NULL;
+ av_set_string3(obj, name, val, 1, &rv);
+ return rv != NULL;
+}
+
+static inline
+int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
+{
+ const AVOption *rv = NULL;
+ rv = av_set_int(obj, name, val);
+ return rv != NULL;
+}
+
+static inline
+int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
+{
+ const AVOption *rv = NULL;
+ rv = av_set_double(obj, name, val);
+ return rv != NULL;
+}
+
+#define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
+#define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
+#define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
+#define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
+#define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
+#define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
+#endif
+
#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24) && (LIBAVFORMAT_VERSION_MICRO < 2)))
#define avformat_close_input(x) av_close_input_file(*(x))
#endif
+#if ((LIBAVCODEC_VERSION_MAJOR < 53) || (LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 35))
+static inline
+int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
+{
+ /* TODO: no options are taking into account */
+ return avcodec_open(avctx, codec);
+}
+#endif
+
+#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR < 21))
+static inline
+AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
+{
+ /* TODO: no codec is taking into account */
+ return av_new_stream(s, 0);
+}
+
+static inline
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
+{
+ /* TODO: no options are taking into account */
+ return av_find_stream_info(ic);
+}
+#endif
+
#if ((LIBAVFORMAT_VERSION_MAJOR > 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && (LIBAVFORMAT_VERSION_MICRO >= 100)))
static inline
void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index ea09987c564..12dd4c0d3eb 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -271,6 +271,9 @@ elseif(UNIX)
if(WITH_X11_XINPUT)
add_definitions(-DWITH_X11_XINPUT)
+ list(APPEND INC_SYS
+ ${X11_Xinput_INCLUDE_PATH}
+ )
endif()
elseif(WIN32)
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index f886dfd9d7d..a92d0d33b65 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -149,6 +149,20 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
GHOST_TUns32 *height);
/**
+ * Returns the dimensions of all displays combine
+ * (the current workspace).
+ * No need to worrky about overlapping monitors.
+ * \param systemhandle The handle to the system
+ * \param width A pointer the width gets put in
+ * \param height A pointer the height gets put in
+ * \return void.
+ */
+extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
+ GHOST_TUns32 *width,
+ GHOST_TUns32 *height);
+
+
+/**
* Create a new window.
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
@@ -852,6 +866,16 @@ extern int GHOST_toggleConsole(int action);
*/
extern int GHOST_confirmQuit(GHOST_WindowHandle windowhandle);
+/**
+ * Use native pixel size (MacBook pro 'retina'), if supported.
+ */
+extern int GHOST_UseNativePixels(void);
+
+/**
+ * If window was opened using native pixel size, it returns scaling factor.
+ */
+extern float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle);
+
#ifdef __cplusplus
}
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index ad5d2379787..37e82c29f80 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -227,6 +227,12 @@ public:
virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const = 0;
/**
+ * Returns the combine dimensions of all monitors.
+ * \return The dimension of the workspace.
+ */
+ virtual void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const = 0;
+
+ /**
* Create a new window.
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
@@ -243,12 +249,13 @@ public:
* \return The new window (or 0 if creation failed).
*/
virtual 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 GHOST_TUns16 numOfAASamples = 0,
- const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
+ 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,
+ const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
/**
* Dispose a window.
@@ -271,8 +278,9 @@ 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,
- const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0) = 0;
+ virtual GHOST_TSuccess beginFullScreen(
+ const GHOST_DisplaySetting& setting, GHOST_IWindow **window,
+ const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0) = 0;
/**
* Updates the resolution while in fullscreen mode.
@@ -281,7 +289,8 @@ public:
*
* \return Indication of success.
*/
- virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window) = 0;
+ virtual GHOST_TSuccess updateFullScreen(
+ const GHOST_DisplaySetting& setting, GHOST_IWindow **window) = 0;
/**
* Ends full screen mode.
@@ -294,6 +303,11 @@ public:
* \return The current status.
*/
virtual bool getFullScreen(void) = 0;
+
+ /**
+ * Native pixel size support (MacBook 'retina').
+ */
+ virtual bool useNativePixel(void) = 0;
/***************************************************************************************
* Event management functionality
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 88f130aabe8..a2d3e9b91fb 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -305,6 +305,13 @@ public:
*/
virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]) { return GHOST_kSuccess; }
+ /** */
+ virtual GHOST_TSuccess beginFullScreen() const = 0;
+ virtual GHOST_TSuccess endFullScreen() const = 0;
+
+ virtual float getNativePixelSize(void) = 0;
+
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow")
#endif
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 868d787b5f9..35dff73f4af 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -183,6 +183,7 @@ typedef enum {
GHOST_kEventDraggingDropDone,
GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup
+ GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display
GHOST_kEventTimer,
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index 44882a64286..7e142c4aeab 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
@@ -93,7 +119,7 @@ else:
if env['WITH_BF_3DMOUSE']:
defs.append('WITH_INPUT_NDOF')
- if env['OURPLATFORM']=='linux':
+ if env['OURPLATFORM'] in ('linux','darwin'):
incs += ' ' + env['BF_3DMOUSE_INC']
else:
sources.remove('intern' + os.sep + 'GHOST_NDOFManager.cpp')
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 88d02c46f61..b73ff26c259 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -123,7 +123,14 @@ void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
system->getMainDisplayDimensions(*width, *height);
}
+void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
+ GHOST_TUns32 *width,
+ GHOST_TUns32 *height)
+{
+ GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
+ system->getAllDisplayDimensions(*width, *height);
+}
GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
const char *title,
@@ -145,7 +152,8 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
bstereoVisual = false;
return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
- state, type, bstereoVisual, numOfAASamples);
+ state, type, bstereoVisual, false,
+ numOfAASamples);
}
GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
@@ -878,3 +886,18 @@ int GHOST_confirmQuit(GHOST_WindowHandle windowhandle)
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->confirmQuit((GHOST_IWindow *) windowhandle);
}
+
+int GHOST_UseNativePixels(void)
+{
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->useNativePixel();
+}
+
+float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ if (window)
+ return window->getNativePixelSize();
+ return 1.0f;
+}
+
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index f0db1b3de8d..9292235a9c7 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -58,12 +58,23 @@
# define GHOST_PRINTF(x, ...)
#endif // GHOST_DEBUG
-
-#ifdef GHOST_DEBUG
+#ifdef WITH_ASSERT_ABORT
+# include <stdio.h> //for fprintf()
+# include <stdlib.h> //for abort()
+# define GHOST_ASSERT(x, info) \
+ { \
+ if (!(x)) { \
+ fprintf(stderr, "GHOST_ASSERT failed: "); \
+ fprintf(stderr, info); \
+ fprintf(stderr, "\n"); \
+ abort(); \
+ } \
+ } (void)0
+#elif defined(GHOST_DEBUG)
# define GHOST_ASSERT(x, info) \
{ \
if (!(x)) { \
- GHOST_PRINT("assertion failed: "); \
+ GHOST_PRINT("GHOST_ASSERT failed: "); \
GHOST_PRINT(info); \
GHOST_PRINT("\n"); \
} \
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp b/intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp
index 3f7d2102dac..25e9123dae6 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerCarbon.cpp
@@ -150,7 +150,7 @@ GHOST_TSuccess GHOST_DisplayManagerCarbon::setCurrentDisplaySetting(GHOST_TUns8
#endif // GHOST_DEBUG
CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
-
+
return err == CGDisplayNoErr ? GHOST_kSuccess : GHOST_kFailure;
}
@@ -158,19 +158,18 @@ GHOST_TSuccess GHOST_DisplayManagerCarbon::setCurrentDisplaySetting(GHOST_TUns8
long GHOST_DisplayManagerCarbon::getValue(CFDictionaryRef values, CFStringRef key) const
{
CFNumberRef numberValue = (CFNumberRef) CFDictionaryGetValue(values, key);
-
+
if (!numberValue)
{
return -1;
}
-
+
long intValue;
-
+
if (!CFNumberGetValue(numberValue, kCFNumberLongType, &intValue))
{
return -1;
}
-
+
return intValue;
}
-
diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
index 86f0380c8d6..0d077ebc204 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
@@ -39,7 +39,7 @@ GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system)
GHOST_DisplayManager(),
m_system(system)
{
- memset(&m_mode, 0, sizeof m_mode);
+ memset(&m_mode, 0, sizeof(m_mode));
}
GHOST_TSuccess
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
index 83df9971158..0bfc67a9126 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
@@ -52,11 +52,15 @@ GHOST_DisplayManagerWin32::GHOST_DisplayManagerWin32(void)
GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8& numDisplays) const
{
- // We do not support multiple monitors at the moment
numDisplays = ::GetSystemMetrics(SM_CMONITORS);
return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
}
+static BOOL get_dd(DWORD d, DISPLAY_DEVICE* dd)
+{
+ dd->cb = sizeof(DISPLAY_DEVICE);
+ return ::EnumDisplayDevices(NULL, d, dd, 0);
+}
/*
* When you call EnumDisplaySettings with iModeNum set to zero, the operating system
@@ -67,10 +71,12 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplays(GHOST_TUns8& numDisplay
*/
GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
{
- GHOST_ASSERT((display == kMainDisplay), "GHOST_DisplayManagerWin32::getNumDisplaySettings(): only main displlay is supported");
+ DISPLAY_DEVICE display_device;
+ if (!get_dd(display, &display_device)) return GHOST_kFailure;
+
numSettings = 0;
DEVMODE dm;
- while (::EnumDisplaySettings(NULL, numSettings, &dm)) {
+ while (::EnumDisplaySettings(display_device.DeviceName, numSettings, &dm)) {
numSettings++;
}
return GHOST_kSuccess;
@@ -79,10 +85,12 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 disp
GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
{
- GHOST_ASSERT((display == kMainDisplay), "GHOST_DisplayManagerWin32::getDisplaySetting(): only main display is supported");
+ DISPLAY_DEVICE display_device;
+ if (!get_dd(display, &display_device)) return GHOST_kFailure;
+
GHOST_TSuccess success;
DEVMODE dm;
- if (::EnumDisplaySettings(NULL, index, &dm)) {
+ if (::EnumDisplaySettings(display_device.DeviceName, index, &dm)) {
#ifdef GHOST_DEBUG
printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency);
#endif // GHOST_DEBUG
@@ -112,23 +120,23 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display,
GHOST_TSuccess GHOST_DisplayManagerWin32::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
{
- GHOST_ASSERT((display == kMainDisplay), "GHOST_DisplayManagerWin32::getCurrentDisplaySetting(): only main display is supported");
- return getDisplaySetting(kMainDisplay, ENUM_CURRENT_SETTINGS, setting);
+ return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting);
}
GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
{
- GHOST_ASSERT((display == kMainDisplay), "GHOST_DisplayManagerWin32::setCurrentDisplaySetting(): only main display is supported");
+ DISPLAY_DEVICE display_device;
+ if (!get_dd(display, &display_device)) return GHOST_kFailure;
GHOST_DisplaySetting match;
findMatch(display, setting, match);
DEVMODE dm;
int i = 0;
- while (::EnumDisplaySettings(NULL, i++, &dm)) {
- if ((dm.dmBitsPerPel == match.bpp) &&
- (dm.dmPelsWidth == match.xPixels) &&
- (dm.dmPelsHeight == match.yPixels) &&
+ while (::EnumDisplaySettings(display_device.DeviceName, i++, &dm)) {
+ if ((dm.dmBitsPerPel == match.bpp ) &&
+ (dm.dmPelsWidth == match.xPixels) &&
+ (dm.dmPelsHeight == match.yPixels) &&
(dm.dmDisplayFrequency == match.frequency))
{
break;
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
index 754218191a5..7830f42cbb7 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -40,7 +40,6 @@
#include "GHOST_SystemX11.h"
-
GHOST_DisplayManagerX11::
GHOST_DisplayManagerX11(
GHOST_SystemX11 *system
@@ -82,9 +81,9 @@ getNumDisplaySettings(
return GHOST_kFailure;
}
- /* The X11 man page says vidmodes needs to be freed, but doing so causes a
- * segfault. - z0r */
- XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes);
+ if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
+ XFree(vidmodes);
+ }
#else
/* We only have one X11 setting at the moment. */
@@ -95,6 +94,17 @@ getNumDisplaySettings(
return GHOST_kSuccess;
}
+/* from SDL2 */
+#ifdef WITH_X11_XF86VMODE
+static int
+calculate_rate(XF86VidModeModeInfo *info)
+{
+ return (info->htotal
+ && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
+ info->vtotal)) : 0;
+}
+#endif
+
GHOST_TSuccess
GHOST_DisplayManagerX11::
getDisplaySetting(
@@ -102,51 +112,46 @@ getDisplaySetting(
GHOST_TInt32 index,
GHOST_DisplaySetting& setting) const
{
+ Display *dpy = m_system->getXDisplay();
+
+ if (dpy == NULL)
+ return GHOST_kFailure;
#ifdef WITH_X11_XF86VMODE
int majorVersion, minorVersion;
- XF86VidModeModeInfo **vidmodes;
- Display *dpy = m_system->getXDisplay();
- int numSettings;
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- if (dpy == NULL)
- return GHOST_kFailure;
-
majorVersion = minorVersion = 0;
- if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
- fprintf(stderr, "Error: XF86VidMode extension missing!\n");
- return GHOST_kFailure;
- }
+ if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+ XF86VidModeModeInfo **vidmodes;
+ int numSettings;
- /* The X11 man page says vidmodes needs to be freed, but doing so causes a
- * segfault. - z0r */
- XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes);
- GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");
-
- setting.xPixels = vidmodes[index]->hdisplay;
- setting.yPixels = vidmodes[index]->vdisplay;
- setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
+ if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
+ GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");
-#else
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
-
- Display *x_display = m_system->getXDisplay();
+ setting.xPixels = vidmodes[index]->hdisplay;
+ setting.yPixels = vidmodes[index]->vdisplay;
+ setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
+ setting.frequency = calculate_rate(vidmodes[index]);
+ XFree(vidmodes);
- if (x_display == NULL) {
- return GHOST_kFailure;
+ return GHOST_kSuccess;
+ }
}
+ else {
+ fprintf(stderr, "Warning: XF86VidMode extension missing!\n");
+ /* fallback to non xf86vmode below */
+ }
+#endif /* WITH_X11_XF86VMODE */
- setting.xPixels = DisplayWidth(x_display, DefaultScreen(x_display));
- setting.yPixels = DisplayHeight(x_display, DefaultScreen(x_display));
- setting.bpp = DefaultDepth(x_display, DefaultScreen(x_display));
-#endif
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
- /* Don't think it's possible to get this value from X!
- * So let's guess!! */
- setting.frequency = 60;
+ setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy));
+ setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy));
+ setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
+ setting.frequency = 60.0f;
return GHOST_kSuccess;
}
@@ -171,15 +176,13 @@ setCurrentDisplaySetting(
const GHOST_DisplaySetting& setting)
{
#ifdef WITH_X11_XF86VMODE
- /* Mode switching code ported from Quake 2:
- * ftp: ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
- * See linux/gl_glx.c:GLimp_SetMode
+ /* Mode switching code ported from SDL:
+ * See: src/video/x11/SDL_x11modes.c:set_best_resolution
*/
int majorVersion, minorVersion;
XF86VidModeModeInfo **vidmodes;
Display *dpy = m_system->getXDisplay();
int scrnum, num_vidmodes;
- int best_fit, best_dist, dist, x, y;
if (dpy == NULL)
return GHOST_kFailure;
@@ -197,41 +200,62 @@ setCurrentDisplaySetting(
majorVersion, minorVersion);
# endif
- /* The X11 man page says vidmodes needs to be freed, but doing so causes a
- * segfault. - z0r */
- XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);
+ if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) {
+ int best_fit = -1;
+
+ for (int i = 0; i < num_vidmodes; i++) {
+ if (vidmodes[i]->hdisplay < setting.xPixels ||
+ vidmodes[i]->vdisplay < setting.yPixels)
+ {
+ continue;
+ }
+
+ if (best_fit == -1 ||
+ (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) ||
+ (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay &&
+ vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay))
+ {
+ best_fit = i;
+ continue;
+ }
+
+ if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) &&
+ (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay))
+ {
+ if (!setting.frequency) {
+ /* Higher is better, right? */
+ if (calculate_rate(vidmodes[i]) >
+ calculate_rate(vidmodes[best_fit]))
+ {
+ best_fit = i;
+ }
+ }
+ else {
+ if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) <
+ abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency))
+ {
+ best_fit = i;
+ }
+ }
+ }
+ }
- best_dist = 9999999;
- best_fit = -1;
+ if (best_fit != -1) {
+ # ifdef _DEBUG
+ printf("Switching to video mode %dx%d %dx%d %d\n",
+ vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay,
+ vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal,
+ calculate_rate(vidmodes[best_fit]));
+ # endif
- for (int i = 0; i < num_vidmodes; i++) {
- if (setting.xPixels > vidmodes[i]->hdisplay ||
- setting.yPixels > vidmodes[i]->vdisplay)
- continue;
+ /* change to the mode */
+ XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
- x = setting.xPixels - vidmodes[i]->hdisplay;
- y = setting.yPixels - vidmodes[i]->vdisplay;
- dist = (x * x) + (y * y);
- if (dist < best_dist) {
- best_dist = dist;
- best_fit = i;
+ /* Move the viewport to top left */
+ XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
}
- }
-
- if (best_fit != -1) {
-# ifdef _DEBUG
- int actualWidth, actualHeight;
- actualWidth = vidmodes[best_fit]->hdisplay;
- actualHeight = vidmodes[best_fit]->vdisplay;
- printf("Switching to video mode %dx%d\n",
- actualWidth, actualHeight);
-# endif
- /* change to the mode */
- XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
-
- /* Move the viewport to top left */
- XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
+ XFree(vidmodes);
}
else {
return GHOST_kFailure;
@@ -245,7 +269,3 @@ setCurrentDisplaySetting(
return GHOST_kSuccess;
#endif
}
-
-
-
-
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
index 89e9a91b34c..5288b77a3c6 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
@@ -32,7 +32,7 @@
#include "GHOST_Debug.h"
#include "GHOST_DropTargetWin32.h"
-#include <ShellApi.h>
+#include <shellapi.h>
#include "utf_winfunc.h"
#include "utfconv.h"
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
index d29dd4dd3e8..0d009e17561 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
@@ -27,7 +27,7 @@
#include "GHOST_SystemCocoa.h"
extern "C" {
- #include <3DconnexionClient/ConnexionClientAPI.h>
+ #include <ConnexionClientAPI.h>
#include <stdio.h>
}
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 8c6491bcbfd..5405fe7efe8 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -45,7 +45,8 @@
GHOST_System::GHOST_System()
- : m_displayManager(0),
+ : m_nativePixel(false),
+ m_displayManager(0),
m_timerManager(0),
m_windowManager(0),
m_eventManager(0)
@@ -151,7 +152,7 @@ GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting
success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting);
if (success == GHOST_kSuccess) {
//GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n");
- success = createFullScreenWindow((GHOST_Window **)window, stereoVisual, numOfAASamples);
+ success = createFullScreenWindow((GHOST_Window **)window, setting, stereoVisual, numOfAASamples);
if (success == GHOST_kSuccess) {
m_windowManager->beginFullScreen(*window, stereoVisual);
}
@@ -346,26 +347,22 @@ GHOST_TSuccess GHOST_System::exit()
return GHOST_kSuccess;
}
-
-GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const bool stereoVisual, const GHOST_TUns16 numOfAASamples)
+GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
+ const bool stereoVisual, const GHOST_TUns16 numOfAASamples)
{
- GHOST_TSuccess success;
+ /* 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");
- GHOST_DisplaySetting settings;
-
- success = m_displayManager->getCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, settings);
- if (success) {
- //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n");
- *window = (GHOST_Window *)createWindow(
- STR_String(""),
- 0, 0, settings.xPixels, settings.yPixels,
- GHOST_kWindowStateFullScreen,
- GHOST_kDrawingContextTypeOpenGL,
- stereoVisual,
- numOfAASamples);
- success = *window == 0 ? GHOST_kFailure : GHOST_kSuccess;
- }
- return success;
+ //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n");
+ *window = (GHOST_Window *)createWindow(
+ STR_String(""),
+ 0, 0, settings.xPixels, settings.yPixels,
+ GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL,
+ stereoVisual,
+ true, /* exclusive */
+ numOfAASamples);
+ return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess;
}
@@ -373,3 +370,10 @@ int GHOST_System::confirmQuit(GHOST_IWindow *window) const
{
return 1;
}
+
+bool GHOST_System::useNativePixel(void)
+{
+ m_nativePixel = true;
+ return 1;
+}
+
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index d2e3377f6ce..0d18dfe532f 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -167,6 +167,13 @@ public:
*/
virtual bool getFullScreen(void);
+
+ /**
+ * Native pixel size support (MacBook 'retina').
+ * \return The pixel size in float.
+ */
+ virtual bool useNativePixel(void);
+ bool m_nativePixel;
/***************************************************************************************
* Event management functionality
@@ -323,7 +330,7 @@ protected:
* \param window The window created.
* \return Indication of success.
*/
- virtual GHOST_TSuccess createFullScreenWindow(GHOST_Window **window,
+ virtual GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0);
/** The display manager (platform dependant). */
@@ -350,6 +357,7 @@ protected:
/** Settings of the display before the display went fullscreen. */
GHOST_DisplaySetting m_preFullScreenSetting;
+
};
inline GHOST_TimerManager *GHOST_System::getTimerManager() const
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index f5784c7d451..f7e035e890d 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -396,6 +396,11 @@ void GHOST_SystemCarbon::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUn
height = bnds.bottom - bnds.top;
}
+void GHOST_SystemCarbon::getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+{
+ /* TODO */
+ getMainDisplayDimensions(width, height);
+}
GHOST_IWindow *GHOST_SystemCarbon::createWindow(
const STR_String& title,
@@ -406,6 +411,7 @@ GHOST_IWindow *GHOST_SystemCarbon::createWindow(
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool stereoVisual,
+ const bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h
index 61e5a086a0f..9faf5423205 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.h
+++ b/intern/ghost/intern/GHOST_SystemCarbon.h
@@ -91,6 +91,12 @@ public:
* \return The dimension of the main display.
*/
virtual 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;
/**
* Create a new window.
@@ -115,6 +121,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
+ const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 9162b7ce4e0..cbb61f6e6ea 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -89,6 +89,11 @@ public:
*/
virtual 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;
+
/**
* Create a new window.
* The new window is added to the list of windows managed.
@@ -114,6 +119,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual = false,
+ const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
@@ -296,8 +302,6 @@ protected:
/** Multitouch trackpad availability */
bool m_hasMultiTouchTrackpad;
- /** Multitouch gesture in progress, useful to distinguish trackpad from mouse scroll events */
- bool m_isGestureInProgress;
};
#endif // __GHOST_SYSTEMCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 16edb4af575..bc3ec7ed71a 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -56,7 +56,7 @@
#include "AssertMacros.h"
#pragma mark KeyMap, mouse converters
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
/* Keycodes not defined in Tiger */
/*
* Summary:
@@ -360,7 +360,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA);
}
else {
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
KeyboardLayoutRef keyLayout;
UCKeyboardLayout *uchrData;
@@ -423,7 +423,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
#pragma mark defines for 10.6 api not documented in 10.5
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
enum {
/* The following event types are available on some hardware on 10.5.2 and later */
NSEventTypeGesture = 29,
@@ -551,7 +551,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
char *rstring = NULL;
m_modifierMask =0;
- m_isGestureInProgress = false;
m_cursorDelta_x=0;
m_cursorDelta_y=0;
m_outsideLoopEventProcessed = false;
@@ -575,13 +574,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
rstring = (char*)malloc( len );
sysctl( mib, 2, rstring, &len, NULL, 0 );
- //Hack on MacBook revision, as multitouch avail. function missing
- //MacbookAir or MacBook version >= 5 (retina is MacBookPro10,1)
- if (strstr(rstring,"MacBookAir") ||
- (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')) ||
- (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-4]>='1') && (rstring[strlen(rstring)-4]<='9')))
- m_hasMultiTouchTrackpad = true;
- else m_hasMultiTouchTrackpad = false;
+ m_hasMultiTouchTrackpad = false;
free( rstring );
rstring = NULL;
@@ -726,6 +719,11 @@ void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns
[pool drain];
}
+void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+{
+ /* TODO! */
+ getMainDisplayDimensions(width, height);
+}
GHOST_IWindow* GHOST_SystemCocoa::createWindow(
const STR_String& title,
@@ -736,6 +734,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool stereoVisual,
+ const bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
@@ -1030,8 +1029,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
if (!validWindow(window)) {
return GHOST_kFailure;
}
- switch(eventType)
- {
+ switch (eventType) {
case GHOST_kEventWindowClose:
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
break;
@@ -1045,6 +1043,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
break;
case GHOST_kEventWindowUpdate:
+ if (m_nativePixel) {
+ window->setNativePixelSize();
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window) );
+ }
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
break;
case GHOST_kEventWindowMove:
@@ -1058,9 +1060,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
//Mouse up event is trapped by the resizing event loop, so send it anyway to the window manager
pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonUp, window, convertButton(0)));
- m_ignoreWindowSizedMessages = true;
+ //m_ignoreWindowSizedMessages = true;
}
break;
+ case GHOST_kEventNativeResolutionChange:
+
+ if (m_nativePixel) {
+ window->setNativePixelSize();
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventNativeResolutionChange, window) );
+ }
+
default:
return GHOST_kFailure;
break;
@@ -1077,8 +1086,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
if (!validWindow(window)) {
return GHOST_kFailure;
}
- switch(eventType)
- {
+ switch (eventType) {
case GHOST_kEventDraggingEntered:
case GHOST_kEventDraggingUpdated:
case GHOST_kEventDraggingExited:
@@ -1446,17 +1454,47 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+enum {
+ NSEventPhaseNone = 0,
+ NSEventPhaseBegan = 0x1 << 0,
+ NSEventPhaseStationary = 0x1 << 1,
+ NSEventPhaseChanged = 0x1 << 2,
+ NSEventPhaseEnded = 0x1 << 3,
+ NSEventPhaseCancelled = 0x1 << 4,
+};
+typedef NSUInteger NSEventPhase;
+
+@interface NSEvent (AvailableOn1070AndLater)
+- (BOOL)hasPreciseScrollingDeltas;
+- (CGFloat)scrollingDeltaX;
+- (CGFloat)scrollingDeltaY;
+- (NSEventPhase)momentumPhase;
+- (BOOL)isDirectionInvertedFromDevice;
+- (NSEventPhase)phase;
+@end
+#endif
+
GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
{
NSEvent *event = (NSEvent *)eventPtr;
GHOST_WindowCocoa* window;
+ CocoaWindow *cocoawindow;
+ /* [event window] returns other windows if mouse-over, that's OSX input standard
+ however, if mouse exits window(s), the windows become inactive, until you click.
+ We then fall back to the active window from ghost */
window = (GHOST_WindowCocoa*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
if (!window) {
- //printf("\nW failure for event 0x%x",[event type]);
- return GHOST_kFailure;
+ window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
+ if (!window) {
+ //printf("\nW failure for event 0x%x",[event type]);
+ return GHOST_kFailure;
+ }
}
+ cocoawindow = (CocoaWindow *)window->getOSWindow();
+
switch ([event type]) {
case NSLeftMouseDown:
case NSRightMouseDown:
@@ -1509,7 +1547,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
break;
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
{
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x_mouse= mousePos.x;
GHOST_TInt32 y_mouse= mousePos.y;
GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y;
@@ -1555,9 +1593,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
default:
{
//Normal cursor operation: send mouse position in window
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
-
+
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
@@ -1569,10 +1607,24 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
}
break;
+ /* these events only happen on swiping trackpads or tablets */
+ /* warning: using tablet + trackpad at same time frustrates this static variable */
+ case NSEventTypeBeginGesture:
+ m_hasMultiTouchTrackpad = 1;
+ break;
+ case NSEventTypeEndGesture:
+ m_hasMultiTouchTrackpad = 0;
+ break;
+
case NSScrollWheel:
{
- /* Send trackpad event if inside a trackpad gesture, send wheel event otherwise */
- if (!m_hasMultiTouchTrackpad || !m_isGestureInProgress) {
+ int *momentum = NULL;
+
+ if ([event respondsToSelector:@selector(momentumPhase)])
+ momentum = (int *)[event momentumPhase];
+
+ /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */
+ if (!m_hasMultiTouchTrackpad && momentum == NULL) {
GHOST_TInt32 delta;
double deltaF = [event deltaY];
@@ -1584,11 +1636,28 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta));
}
else {
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
- double dx = [event deltaX];
- double dy = -[event deltaY];
+ double dx;
+ double dy;
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ int phase = [event phase];
+
+ /* with 10.7 nice scrolling deltas are supported */
+ dx = [event scrollingDeltaX];
+ dy = [event scrollingDeltaY];
+ /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */
+ if (phase == 0 && momentum==NULL) {
+ dx = [event deltaX];
+ dy = [event deltaY];
+ }
+
+#else
+ /* trying to pretend you have nice scrolls... */
+ dx = [event deltaX];
+ dy = -[event deltaY];
const double deltaMax = 50.0;
if ((dx == 0) && (dy == 0)) break;
@@ -1605,9 +1674,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
else dy += 0.5;
if (dy < -deltaMax) dy= -deltaMax;
else if (dy > deltaMax) dy= deltaMax;
-
- window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+
dy = -dy;
+#endif
+ window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
}
@@ -1616,7 +1686,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
case NSEventTypeMagnify:
{
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventMagnify, x, y,
@@ -1626,18 +1696,12 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
case NSEventTypeRotate:
{
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y,
-[event rotation] * 5.0, 0));
}
- case NSEventTypeBeginGesture:
- m_isGestureInProgress = true;
- break;
- case NSEventTypeEndGesture:
- m_isGestureInProgress = false;
- break;
default:
return GHOST_kFailure;
break;
diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h
index 63e3b5bc828..7021dea36dd 100644
--- a/intern/ghost/intern/GHOST_SystemNULL.h
+++ b/intern/ghost/intern/GHOST_SystemNULL.h
@@ -38,7 +38,7 @@ class GHOST_WindowNULL;
class GHOST_SystemNULL : public GHOST_System {
public:
- GHOST_SystemNULL( ) : GHOST_System() { /* nop */ }
+ GHOST_SystemNULL() : GHOST_System() { /* nop */ }
~GHOST_SystemNULL() { /* nop */ }
bool processEvents(bool waitForEvent) { return false; }
int toggleConsole(int action) { return 0; }
@@ -46,11 +46,12 @@ public:
GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const { return GHOST_kSuccess; }
GHOST_TUns8 *getClipboard(bool selection) const { return NULL; }
void putClipboard(GHOST_TInt8 *buffer, bool selection) const { /* nop */ }
- GHOST_TUns64 getMilliSeconds( ) const { return 0; }
- GHOST_TUns8 getNumDisplays( ) const { return GHOST_TUns8(1); }
- GHOST_TSuccess getCursorPosition( GHOST_TInt32& x, GHOST_TInt32& y ) const { return GHOST_kFailure; }
- GHOST_TSuccess setCursorPosition( GHOST_TInt32 x, GHOST_TInt32 y ) { return GHOST_kFailure; }
- void getMainDisplayDimensions( GHOST_TUns32& width, GHOST_TUns32& height ) const { /* nop */ }
+ GHOST_TUns64 getMilliSeconds() const { return 0; }
+ GHOST_TUns8 getNumDisplays() const { return GHOST_TUns8(1); }
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const { return GHOST_kFailure; }
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { return GHOST_kFailure; }
+ void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ }
+ void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ }
GHOST_TSuccess init() {
GHOST_TSuccess success = GHOST_System::init();
@@ -82,11 +83,4 @@ public:
}
};
-#endif
-
-
-
-
-
-
-
+#endif /* __GHOST_SYSTEMNULL_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
index fdc4f33b784..da1836d88a0 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.cpp
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -114,6 +114,20 @@ GHOST_SystemSDL::init() {
return GHOST_kFailure;
}
+/**
+ * Returns the dimensions of the main display on this system.
+ * \return The dimension of the main display.
+ */
+void
+GHOST_SystemSDL::getAllDisplayDimensions(GHOST_TUns32& width,
+ GHOST_TUns32& height) const
+{
+ SDL_DisplayMode mode;
+ SDL_GetDesktopDisplayMode(0, &mode); /* note, always 0 display */
+ width = mode.w;
+ height = mode.h;
+}
+
void
GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32& width,
GHOST_TUns32& height) const
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index 43c9129fdd8..776dc2f66a5 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -88,6 +88,10 @@ public:
GHOST_TInt32 y);
void
+ getAllDisplayDimensions(GHOST_TUns32& width,
+ GHOST_TUns32& height) const;
+
+ void
getMainDisplayDimensions(GHOST_TUns32& width,
GHOST_TUns32& height) const;
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 46c71f57c6f..b8a403578d2 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -215,12 +215,17 @@ void GHOST_SystemWin32::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns
height = ::GetSystemMetrics(SM_CYSCREEN);
}
+void GHOST_SystemWin32::getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+{
+ width = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
+ height = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
+}
GHOST_IWindow *GHOST_SystemWin32::createWindow(
const STR_String& title,
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
- bool stereoVisual, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow)
+ bool stereoVisual, const bool exclusive, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow)
{
GHOST_Window *window = 0;
window = new GHOST_WindowWin32(this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples, parentWindow);
@@ -291,6 +296,9 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent)
// Process all the events waiting for us
while (::PeekMessageW(&msg, 0, 0, 0, PM_REMOVE) != 0) {
+ // TranslateMessage doesn't alter the message, and doesn't change our raw keyboard data.
+ // Needed for MapVirtualKey or if we ever need to get chars from wm_ime_char or similar.
+ ::TranslateMessage(&msg);
::DispatchMessageW(&msg);
anyProcessed = true;
}
@@ -724,13 +732,17 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINP
int r;
GetKeyboardState((PBYTE)state);
- if ((r = ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout))) {
- if ((r > 0 && r < 3)) {
- utf16[r] = 0;
- conv_utf_16_to_8(utf16, utf8_char, 6);
- }
- else if (r == -1) {
- utf8_char[0] = '\0';
+ // don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical composition.
+ if (MapVirtualKeyW(vk,2) != 0) {
+ // todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). Could be up to 24 utf8 bytes.
+ if ((r = ToUnicodeEx(vk, raw.data.keyboard.MakeCode, state, utf16, 2, 0, system->m_keylayout))) {
+ if ((r > 0 && r < 3)) {
+ utf16[r] = 0;
+ conv_utf_16_to_8(utf16, utf8_char, 6);
+ }
+ else if (r == -1) {
+ utf8_char[0] = '\0';
+ }
}
}
@@ -761,6 +773,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_
if (type == GHOST_kEventWindowActivate) {
system->getWindowManager()->setActiveWindow(window);
+ ((GHOST_WindowWin32*)window)->bringTabletContextToFront();
}
return new GHOST_Event(system->getMilliSeconds(), type, window);
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 6a756d35872..c4b81677c18 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -100,7 +100,13 @@ public:
* \return The dimension of the main display.
*/
virtual 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;
+
/**
* Create a new window.
* The new window is added to the list of windows managed.
@@ -122,6 +128,7 @@ public:
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,
const GHOST_TEmbedderWindowID parentWindow = 0);
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 2d3cc4f88dc..d00265fbd9b 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -69,8 +69,13 @@
#include <stdio.h> /* for fprintf only */
#include <cstdlib> /* for exit */
-static GHOST_TKey
-convertXKey(KeySym key);
+/* for debugging - so we can breakpoint X11 errors */
+// #define USE_X11_ERROR_HANDLERS
+
+/* see [#34039] Fix Alt key glitch on Unity desktop */
+#define USE_UNITY_WORKAROUND
+
+static GHOST_TKey convertXKey(KeySym key);
/* these are for copy and select copy */
static char *txt_cut_buffer = NULL;
@@ -91,6 +96,11 @@ GHOST_SystemX11(
abort(); /* was return before, but this would just mean it will crash later */
}
+#ifdef USE_X11_ERROR_HANDLERS
+ (void) XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
+ (void) XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
+#endif
+
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
/* note -- don't open connection to XIM server here, because the locale
* has to be set before opening the connection but setlocale() has not
@@ -99,32 +109,37 @@ GHOST_SystemX11(
m_xim = NULL;
#endif
- m_delete_window_atom
- = XInternAtom(m_display, "WM_DELETE_WINDOW", True);
-
- m_wm_protocols = XInternAtom(m_display, "WM_PROTOCOLS", False);
- m_wm_take_focus = XInternAtom(m_display, "WM_TAKE_FOCUS", False);
- m_wm_state = XInternAtom(m_display, "WM_STATE", False);
- m_wm_change_state = XInternAtom(m_display, "WM_CHANGE_STATE", False);
- m_net_state = XInternAtom(m_display, "_NET_WM_STATE", False);
- m_net_max_horz = XInternAtom(m_display,
- "_NET_WM_STATE_MAXIMIZED_HORZ", False);
- m_net_max_vert = XInternAtom(m_display,
- "_NET_WM_STATE_MAXIMIZED_VERT", False);
- m_net_fullscreen = XInternAtom(m_display,
- "_NET_WM_STATE_FULLSCREEN", False);
- m_motif = XInternAtom(m_display, "_MOTIF_WM_HINTS", False);
- m_targets = XInternAtom(m_display, "TARGETS", False);
- m_string = XInternAtom(m_display, "STRING", False);
- m_compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
- m_text = XInternAtom(m_display, "TEXT", False);
- m_clipboard = XInternAtom(m_display, "CLIPBOARD", False);
- m_primary = XInternAtom(m_display, "PRIMARY", False);
- m_xclip_out = XInternAtom(m_display, "XCLIP_OUT", False);
- m_incr = XInternAtom(m_display, "INCR", False);
- m_utf8_string = XInternAtom(m_display, "UTF8_STRING", False);
- m_last_warp = 0;
+#define GHOST_INTERN_ATOM_IF_EXISTS(atom) { m_atom.atom = XInternAtom(m_display, #atom , True); } (void)0
+#define GHOST_INTERN_ATOM(atom) { m_atom.atom = XInternAtom(m_display, #atom , False); } (void)0
+
+ GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW);
+ GHOST_INTERN_ATOM(WM_PROTOCOLS);
+ GHOST_INTERN_ATOM(WM_TAKE_FOCUS);
+ GHOST_INTERN_ATOM(WM_STATE);
+ GHOST_INTERN_ATOM(WM_CHANGE_STATE);
+ GHOST_INTERN_ATOM(_NET_WM_STATE);
+ GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
+ GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
+
+ GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN);
+ GHOST_INTERN_ATOM(_MOTIF_WM_HINTS);
+ GHOST_INTERN_ATOM(TARGETS);
+ GHOST_INTERN_ATOM(STRING);
+ GHOST_INTERN_ATOM(COMPOUND_TEXT);
+ GHOST_INTERN_ATOM(TEXT);
+ GHOST_INTERN_ATOM(CLIPBOARD);
+ GHOST_INTERN_ATOM(PRIMARY);
+ GHOST_INTERN_ATOM(XCLIP_OUT);
+ GHOST_INTERN_ATOM(INCR);
+ GHOST_INTERN_ATOM(UTF8_STRING);
+#ifdef WITH_X11_XINPUT
+ m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False);
+#endif
+#undef GHOST_INTERN_ATOM_IF_EXISTS
+#undef GHOST_INTERN_ATOM
+
+ m_last_warp = 0;
/* compute the initial time */
timeval tv;
@@ -132,7 +147,7 @@ GHOST_SystemX11(
GHOST_ASSERT(false, "Could not instantiate timer!");
}
- /* Taking care not to overflow the tv.tv_sec*1000 */
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
@@ -146,6 +161,12 @@ GHOST_SystemX11(
XkbSetDetectableAutoRepeat(m_display, true, NULL);
}
+#ifdef WITH_X11_XINPUT
+ /* initialize incase X11 fails to load */
+ memset(&m_xtablet, 0, sizeof(m_xtablet));
+
+ initXInputDevices();
+#endif
}
GHOST_SystemX11::
@@ -157,6 +178,15 @@ GHOST_SystemX11::
}
#endif
+#ifdef WITH_X11_XINPUT
+ /* close tablet devices */
+ if (m_xtablet.StylusDevice)
+ XCloseDevice(m_display, m_xtablet.StylusDevice);
+
+ if (m_xtablet.EraserDevice)
+ XCloseDevice(m_display, m_xtablet.EraserDevice);
+#endif /* WITH_X11_XINPUT */
+
XCloseDisplay(m_display);
}
@@ -190,7 +220,7 @@ getMilliSeconds() const
GHOST_ASSERT(false, "Could not compute time!");
}
- /* Taking care not to overflow the tv.tv_sec*1000 */
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
}
@@ -212,6 +242,25 @@ getMainDisplayDimensions(
GHOST_TUns32& height) const
{
if (m_display) {
+ /* note, for this to work as documented,
+ * we would need to use Xinerama check r54370 for code that did thia,
+ * we've since removed since its not worth the extra dep - campbell */
+ getAllDisplayDimensions(width, height);
+ }
+}
+
+
+/**
+ * Returns the dimensions of the main display on this system.
+ * \return The dimension of the main display.
+ */
+void
+GHOST_SystemX11::
+getAllDisplayDimensions(
+ GHOST_TUns32& width,
+ GHOST_TUns32& height) const
+{
+ if (m_display) {
width = DisplayWidth(m_display, DefaultScreen(m_display));
height = DisplayHeight(m_display, DefaultScreen(m_display));
}
@@ -229,6 +278,8 @@ getMainDisplayDimensions(
* \param state The state of the window when opened.
* \param type The type of drawing context installed in this window.
* \param stereoVisual Stereo visual for quad buffered stereo.
+ * \param exclusive Use to show the window ontop and ignore others
+ * (used fullscreen).
* \param numOfAASamples Number of samples used for AA (zero if no AA)
* \param parentWindow Parent (embedder) window
* \return The new window (or 0 if creation failed).
@@ -243,7 +294,8 @@ createWindow(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- bool stereoVisual,
+ const bool stereoVisual,
+ const bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
@@ -256,7 +308,9 @@ createWindow(
window = new GHOST_WindowX11(this, m_display, title,
left, top, width, height,
- state, parentWindow, type, stereoVisual, numOfAASamples);
+ state, parentWindow, type,
+ stereoVisual, exclusive,
+ numOfAASamples);
if (window) {
/* Both are now handle in GHOST_WindowX11.cpp
@@ -474,6 +528,54 @@ processEvents(
processEvent(&xevent);
anyProcessed = true;
+
+
+#ifdef USE_UNITY_WORKAROUND
+ /* note: processEvent() can't include this code because
+ * KeymapNotify event have no valid window information. */
+
+ /* the X server generates KeymapNotify event immediately after
+ * every EnterNotify and FocusIn event. we handle this event
+ * to correct modifier states. */
+ if (xevent.type == FocusIn) {
+ /* use previous event's window, because KeymapNotify event
+ * has no window information. */
+ GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window);
+ if (window && XPending(m_display) >= 2) {
+ XNextEvent(m_display, &xevent);
+
+ if (xevent.type == KeymapNotify) {
+ XEvent xev_next;
+
+ /* check if KeyPress or KeyRelease event was generated
+ * in order to confirm the window is active. */
+ XPeekEvent(m_display, &xev_next);
+
+ if (xev_next.type == KeyPress || xev_next.type == KeyRelease) {
+ /* XK_Hyper_L/R currently unused */
+ const static KeySym modifiers[8] = {XK_Shift_L, XK_Shift_R,
+ XK_Control_L, XK_Control_R,
+ XK_Alt_L, XK_Alt_R,
+ XK_Super_L, XK_Super_R};
+
+ for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) {
+ KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
+ if (((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
+ pushEvent(new GHOST_EventKey(
+ getMilliSeconds(),
+ GHOST_kEventKeyDown,
+ window,
+ convertXKey(modifiers[i]),
+ '\0',
+ NULL));
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* USE_UNITY_WORKAROUND */
+
}
if (generateWindowExposeEvents()) {
@@ -494,12 +596,52 @@ processEvents(
#ifdef WITH_X11_XINPUT
/* set currently using tablet mode (stylus or eraser) depending on device ID */
-static void setTabletMode(GHOST_WindowX11 *window, XID deviceid)
+static void setTabletMode(GHOST_SystemX11 *system, GHOST_WindowX11 *window, XID deviceid)
+{
+ if (deviceid == system->GetXTablet().StylusID)
+ window->GetTabletData()->Active = GHOST_kTabletModeStylus;
+ else if (deviceid == system->GetXTablet().EraserID)
+ window->GetTabletData()->Active = GHOST_kTabletModeEraser;
+}
+#endif /* WITH_X11_XINPUT */
+
+#ifdef WITH_X11_XINPUT
+static bool checkTabletProximity(Display *display, XDevice *device)
{
- if (deviceid == window->GetXTablet().StylusID)
- window->GetXTablet().CommonData.Active = GHOST_kTabletModeStylus;
- else if (deviceid == window->GetXTablet().EraserID)
- window->GetXTablet().CommonData.Active = GHOST_kTabletModeEraser;
+ /* we could have true/false/not-found return value, but for now false is OK */
+
+ /* see: state.c from xinput, to get more data out of the device */
+ XDeviceState *state;
+
+ if (device == NULL) {
+ return false;
+ }
+
+ state = XQueryDeviceState(display, device);
+
+ if (state) {
+ XInputClass *cls = state->data;
+ // printf("%d class%s :\n", state->num_classes,
+ // (state->num_classes > 1) ? "es" : "");
+ for (int loop = 0; loop < state->num_classes; loop++) {
+ switch (cls->c_class) {
+ case ValuatorClass:
+ XValuatorState *val_state = (XValuatorState *)cls;
+ // printf("ValuatorClass Mode=%s Proximity=%s\n",
+ // val_state->mode & 1 ? "Absolute" : "Relative",
+ // val_state->mode & 2 ? "Out" : "In");
+
+ if ((val_state->mode & 2) == 0) {
+ XFreeDeviceState(state);
+ return true;
+ }
+ break;
+ }
+ cls = (XInputClass *) ((char *)cls + cls->length);
+ }
+ XFreeDeviceState(state);
+ }
+ return false;
}
#endif /* WITH_X11_XINPUT */
@@ -512,7 +654,23 @@ GHOST_SystemX11::processEvent(XEvent *xe)
if (!window) {
return;
}
-
+
+#ifdef WITH_X11_XINPUT
+ /* Proximity-Out Events are not reliable, if the tablet is active - check on each event
+ * this adds a little overhead but only while the tablet is in use.
+ * in the futire we could have a ghost call window->CheckTabletProximity()
+ * but for now enough parts of the code are checking 'Active'
+ * - campbell */
+ if (window->GetTabletData()->Active != GHOST_kTabletModeNone) {
+ if (checkTabletProximity(xe->xany.display, m_xtablet.StylusDevice) == false &&
+ checkTabletProximity(xe->xany.display, m_xtablet.EraserDevice) == false)
+ {
+ // printf("proximity disable\n");
+ window->GetTabletData()->Active = GHOST_kTabletModeNone;
+ }
+ }
+#endif /* WITH_X11_XINPUT */
+
switch (xe->type) {
case Expose:
{
@@ -537,7 +695,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
XMotionEvent &xme = xe->xmotion;
#ifdef WITH_X11_XINPUT
- bool is_tablet = window->GetXTablet().CommonData.Active != GHOST_kTabletModeNone;
+ bool is_tablet = window->GetTabletData()->Active != GHOST_kTabletModeNone;
#else
bool is_tablet = false;
#endif
@@ -811,7 +969,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XClientMessageEvent & xcme = xe->xclient;
- if (((Atom)xcme.data.l[0]) == m_delete_window_atom) {
+ if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) {
g_event = new
GHOST_Event(
getMilliSeconds(),
@@ -819,7 +977,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
window
);
}
- else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
+ else if (((Atom)xcme.data.l[0]) == m_atom.WM_TAKE_FOCUS) {
XWindowAttributes attr;
Window fwin;
int revert_to;
@@ -983,31 +1141,31 @@ GHOST_SystemX11::processEvent(XEvent *xe)
default: {
#ifdef WITH_X11_XINPUT
- if (xe->type == window->GetXTablet().MotionEvent) {
+ if (xe->type == m_xtablet.MotionEvent) {
XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe;
/* stroke might begin without leading ProxyIn event,
* this happens when window is opened when stylus is already hovering
* around tablet surface */
- setTabletMode(window, data->deviceid);
+ setTabletMode(this, window, data->deviceid);
- window->GetXTablet().CommonData.Pressure =
- data->axis_data[2] / ((float)window->GetXTablet().PressureLevels);
+ window->GetTabletData()->Pressure =
+ data->axis_data[2] / ((float)m_xtablet.PressureLevels);
/* the (short) cast and the &0xffff is bizarre and unexplained anywhere,
* but I got garbage data without it. Found it in the xidump.c source --matt */
- window->GetXTablet().CommonData.Xtilt =
- (short)(data->axis_data[3] & 0xffff) / ((float)window->GetXTablet().XtiltLevels);
- window->GetXTablet().CommonData.Ytilt =
- (short)(data->axis_data[4] & 0xffff) / ((float)window->GetXTablet().YtiltLevels);
+ window->GetTabletData()->Xtilt =
+ (short)(data->axis_data[3] & 0xffff) / ((float)m_xtablet.XtiltLevels);
+ window->GetTabletData()->Ytilt =
+ (short)(data->axis_data[4] & 0xffff) / ((float)m_xtablet.YtiltLevels);
}
- else if (xe->type == window->GetXTablet().ProxInEvent) {
+ else if (xe->type == m_xtablet.ProxInEvent) {
XProximityNotifyEvent *data = (XProximityNotifyEvent *)xe;
- setTabletMode(window, data->deviceid);
+ setTabletMode(this, window, data->deviceid);
}
- else if (xe->type == window->GetXTablet().ProxOutEvent) {
- window->GetXTablet().CommonData.Active = GHOST_kTabletModeNone;
+ else if (xe->type == m_xtablet.ProxOutEvent) {
+ window->GetTabletData()->Active = GHOST_kTabletModeNone;
}
#endif // WITH_X11_XINPUT
break;
@@ -1372,7 +1530,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
}
/* Send a selection request */
- XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime);
+ XConvertSelection(m_display, sel, target, m_atom.XCLIP_OUT, win, CurrentTime);
*context = XCLIB_XCOUT_SENTCONVSEL;
return;
@@ -1380,28 +1538,28 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
if (evt.type != SelectionNotify)
return;
- if (target == m_utf8_string && evt.xselection.property == None) {
+ if (target == m_atom.UTF8_STRING && evt.xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_UTF8;
return;
}
- else if (target == m_compound_text && evt.xselection.property == None) {
+ else if (target == m_atom.COMPOUND_TEXT && evt.xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_COMP;
return;
}
- else if (target == m_text && evt.xselection.property == None) {
+ else if (target == m_atom.TEXT && evt.xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_TEXT;
return;
}
/* find the size and format of the data in property */
- XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
+ XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
AnyPropertyType, &pty_type, &pty_format,
&pty_items, &pty_size, &buffer);
XFree(buffer);
- if (pty_type == m_incr) {
+ if (pty_type == m_atom.INCR) {
/* start INCR mechanism by deleting property */
- XDeleteProperty(m_display, win, m_xclip_out);
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
XFlush(m_display);
*context = XCLIB_XCOUT_INCR;
return;
@@ -1416,12 +1574,12 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
}
// not using INCR mechanism, just read the property
- XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
+ XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
False, AnyPropertyType, &pty_type,
&pty_format, &pty_items, &pty_size, &buffer);
/* finished with property, delete it */
- XDeleteProperty(m_display, win, m_xclip_out);
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
/* copy the buffer to the pointer for returned data */
ltxt = (unsigned char *) malloc(pty_items);
@@ -1454,7 +1612,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
return;
/* check size and format of the property */
- XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
+ XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
AnyPropertyType, &pty_type, &pty_format,
&pty_items, &pty_size, &buffer);
@@ -1463,14 +1621,14 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
* to tell the other X client that we have read
* it and to send the next property */
XFree(buffer);
- XDeleteProperty(m_display, win, m_xclip_out);
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
return;
}
if (pty_size == 0) {
/* no more data, exit from loop */
XFree(buffer);
- XDeleteProperty(m_display, win, m_xclip_out);
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
*context = XCLIB_XCOUT_NONE;
/* this means that an INCR transfer is now
@@ -1482,7 +1640,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
/* if we have come this far, the property contains
* text, we know the size. */
- XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
+ XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
False, AnyPropertyType, &pty_type, &pty_format,
&pty_items, &pty_size, &buffer);
@@ -1503,7 +1661,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
XFree(buffer);
/* delete property to get the next item */
- XDeleteProperty(m_display, win, m_xclip_out);
+ XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
XFlush(m_display);
return;
}
@@ -1513,7 +1671,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
{
Atom sseln;
- Atom target = m_utf8_string;
+ Atom target = m_atom.UTF8_STRING;
Window owner;
/* from xclip.c doOut() v0.11 */
@@ -1523,9 +1681,9 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
unsigned int context = XCLIB_XCOUT_NONE;
if (selection == True)
- sseln = m_primary;
+ sseln = m_atom.PRIMARY;
else
- sseln = m_clipboard;
+ sseln = m_atom.CLIPBOARD;
vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
@@ -1535,7 +1693,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
/* check if we are the owner. */
owner = XGetSelectionOwner(m_display, sseln);
if (owner == win) {
- if (sseln == m_clipboard) {
+ if (sseln == m_atom.CLIPBOARD) {
sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1);
strcpy((char *)sel_buf, txt_cut_buffer);
return sel_buf;
@@ -1560,19 +1718,19 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
/* fallback is needed. set XA_STRING to target and restart the loop. */
if (context == XCLIB_XCOUT_FALLBACK) {
context = XCLIB_XCOUT_NONE;
- target = m_string;
+ target = m_atom.STRING;
continue;
}
else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
/* utf8 fail, move to compouned text. */
context = XCLIB_XCOUT_NONE;
- target = m_compound_text;
+ target = m_atom.COMPOUND_TEXT;
continue;
}
else if (context == XCLIB_XCOUT_FALLBACK_COMP) {
/* compouned text faile, move to text. */
context = XCLIB_XCOUT_NONE;
- target = m_text;
+ target = m_atom.TEXT;
continue;
}
@@ -1589,7 +1747,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
memcpy((char *)tmp_data, (char *)sel_buf, sel_len);
tmp_data[sel_len] = '\0';
- if (sseln == m_string)
+ if (sseln == m_atom.STRING)
XFree(sel_buf);
else
free(sel_buf);
@@ -1610,8 +1768,8 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
if (buffer) {
if (selection == False) {
- XSetSelectionOwner(m_display, m_clipboard, m_window, CurrentTime);
- owner = XGetSelectionOwner(m_display, m_clipboard);
+ XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime);
+ owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD);
if (txt_cut_buffer)
free((void *)txt_cut_buffer);
@@ -1619,8 +1777,8 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
strcpy(txt_cut_buffer, buffer);
}
else {
- XSetSelectionOwner(m_display, m_primary, m_window, CurrentTime);
- owner = XGetSelectionOwner(m_display, m_primary);
+ XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime);
+ owner = XGetSelectionOwner(m_display, m_atom.PRIMARY);
if (txt_select_buffer)
free((void *)txt_select_buffer);
@@ -1648,3 +1806,208 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
);
}
#endif
+
+#ifdef WITH_X11_XINPUT
+/*
+ * 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.
+ */
+int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
+{
+ fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
+ theEvent->error_code, theEvent->request_code);
+
+ /* No exit! - but keep lint happy */
+ return 0;
+}
+
+int GHOST_X11_ApplicationIOErrorHandler(Display *display)
+{
+ fprintf(stderr, "Ignoring Xlib error: error IO\n");
+
+ /* No exit! - but keep lint happy */
+ return 0;
+}
+
+/* These C functions are copied from Wine 1.1.13's wintab.c */
+#define BOOL int
+#define TRUE 1
+#define FALSE 0
+
+static bool match_token(const char *haystack, const char *needle)
+{
+ const char *p, *q;
+ for (p = haystack; *p; )
+ {
+ while (*p && isspace(*p))
+ p++;
+ if (!*p)
+ break;
+
+ for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
+ p++;
+ if (!*q && (isspace(*p) || !*p))
+ return TRUE;
+
+ while (*p && !isspace(*p))
+ p++;
+ }
+ return FALSE;
+}
+
+
+/* Determining if an X device is a Tablet style device is an imperfect science.
+ * We rely on common conventions around device names as well as the type reported
+ * by Wacom tablets. This code will likely need to be expanded for alternate tablet types
+ *
+ * Wintab refers to any device that interacts with the tablet as a cursor,
+ * (stylus, eraser, tablet mouse, airbrush, etc)
+ * this is not to be confused with wacom x11 configuration "cursor" device.
+ * Wacoms x11 config "cursor" refers to its device slot (which we mirror with
+ * our gSysCursors) for puck like devices (tablet mice essentially).
+ */
+#if 0 // unused
+static BOOL is_tablet_cursor(const char *name, const char *type)
+{
+ int i;
+ static const char *tablet_cursor_whitelist[] = {
+ "wacom",
+ "wizardpen",
+ "acecad",
+ "tablet",
+ "cursor",
+ "stylus",
+ "eraser",
+ "pad",
+ NULL
+ };
+
+ for (i = 0; tablet_cursor_whitelist[i] != NULL; i++) {
+ if (name && match_token(name, tablet_cursor_whitelist[i]))
+ return TRUE;
+ if (type && match_token(type, tablet_cursor_whitelist[i]))
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+static BOOL is_stylus(const char *name, const char *type)
+{
+ int i;
+ static const char *tablet_stylus_whitelist[] = {
+ "stylus",
+ "wizardpen",
+ "acecad",
+ NULL
+ };
+
+ for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
+ if (name && match_token(name, tablet_stylus_whitelist[i]))
+ return TRUE;
+ if (type && match_token(type, tablet_stylus_whitelist[i]))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL is_eraser(const char *name, const char *type)
+{
+ if (name && match_token(name, "eraser"))
+ return TRUE;
+ if (type && match_token(type, "eraser"))
+ return TRUE;
+ return FALSE;
+}
+#undef BOOL
+#undef TRUE
+#undef FALSE
+/* end code copied from wine */
+
+void GHOST_SystemX11::initXInputDevices()
+{
+ static XErrorHandler old_handler = (XErrorHandler) 0;
+ static XIOErrorHandler old_handler_io = (XIOErrorHandler) 0;
+
+ XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
+
+ if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
+ if (version->present) {
+ int device_count;
+ XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
+ m_xtablet.StylusDevice = NULL;
+ m_xtablet.EraserDevice = NULL;
+
+ /* Install our error handler to override Xlib's termination behavior */
+ old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
+ old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
+
+ for (int i = 0; i < device_count; ++i) {
+ char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
+
+// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
+
+
+ if ((m_xtablet.StylusDevice == NULL) &&
+ (is_stylus(device_info[i].name, device_type) || (device_info[i].type == m_atom.TABLET)))
+ {
+// printf("\tfound stylus\n");
+ m_xtablet.StylusID = device_info[i].id;
+ m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
+
+ if (m_xtablet.StylusDevice != NULL) {
+ /* Find how many pressure levels tablet has */
+ XAnyClassPtr ici = device_info[i].inputclassinfo;
+ for (int j = 0; j < m_xtablet.StylusDevice->num_classes; ++j) {
+ if (ici->c_class == ValuatorClass) {
+// printf("\t\tfound ValuatorClass\n");
+ XValuatorInfo *xvi = (XValuatorInfo *)ici;
+ m_xtablet.PressureLevels = xvi->axes[2].max_value;
+
+ if (xvi->num_axes > 3) {
+ /* this is assuming that the tablet has the same tilt resolution in both
+ * positive and negative directions. It would be rather weird if it didn't.. */
+ m_xtablet.XtiltLevels = xvi->axes[3].max_value;
+ m_xtablet.YtiltLevels = xvi->axes[4].max_value;
+ }
+ else {
+ m_xtablet.XtiltLevels = 0;
+ m_xtablet.YtiltLevels = 0;
+ }
+
+ break;
+ }
+
+ ici = (XAnyClassPtr)(((char *)ici) + ici->length);
+ }
+ }
+ else {
+ m_xtablet.StylusID = 0;
+ }
+ }
+ else if ((m_xtablet.EraserDevice == NULL) &&
+ (is_eraser(device_info[i].name, device_type)))
+ {
+// printf("\tfound eraser\n");
+ m_xtablet.EraserID = device_info[i].id;
+ m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
+ if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID = 0;
+ }
+
+ if (device_type) {
+ XFree((void *)device_type);
+ }
+ }
+
+ /* Restore handler */
+ (void) XSetErrorHandler(old_handler);
+ (void) XSetIOErrorHandler(old_handler_io);
+
+ XFreeDeviceList(device_info);
+ }
+ XFree(version);
+ }
+}
+
+#endif /* WITH_X11_XINPUT */
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index 02c0109085a..6a492f64b41 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -39,11 +39,19 @@
#include "GHOST_System.h"
#include "../GHOST_Types.h"
+// For tablets
+#ifdef WITH_X11_XINPUT
+# include <X11/extensions/XInput.h>
+#endif
+
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
# define GHOST_X11_RES_NAME "Blender" /* res_name */
# define GHOST_X11_RES_CLASS "Blender" /* res_class */
#endif
+/* generic error handlers */
+int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent);
+int GHOST_X11_ApplicationIOErrorHandler(Display *display);
class GHOST_WindowX11;
@@ -109,6 +117,16 @@ public:
) const;
/**
+ * Returns the dimensions of all displays on this system.
+ * \return The dimension of the main display.
+ */
+ void
+ getAllDisplayDimensions(
+ GHOST_TUns32& width,
+ GHOST_TUns32& height
+ ) const;
+
+ /**
* Create a new window.
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
@@ -119,7 +137,9 @@ public:
* \param height The height the window.
* \param state The state of the window when opened.
* \param type The type of drawing context installed in this window.
- * \param stereoVisual Create a stereo visual for quad buffered stereo.
+ * \param stereoVisual Create a stereo visual for quad buffered stereo.
+ * \param exclusive Use to show the window ontop and ignore others
+ * (used fullscreen).
* \param parentWindow Parent (embedder) window
* \return The new window (or 0 if creation failed).
*/
@@ -133,6 +153,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
+ const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
@@ -256,33 +277,59 @@ public:
return 0;
}
- /**
- * Atom used for ICCCM, WM-spec and Motif.
- * We only need get this atom at the start, it's relative
- * to the display not the window and are public for every
- * window that need it.
- */
- Atom m_wm_state;
- Atom m_wm_change_state;
- Atom m_net_state;
- Atom m_net_max_horz;
- Atom m_net_max_vert;
- Atom m_net_fullscreen;
- Atom m_motif;
- Atom m_wm_take_focus;
- Atom m_wm_protocols;
- Atom m_delete_window_atom;
-
- /* Atoms for Selection, copy & paste. */
- Atom m_targets;
- Atom m_string;
- Atom m_compound_text;
- Atom m_text;
- Atom m_clipboard;
- Atom m_primary;
- Atom m_xclip_out;
- Atom m_incr;
- Atom m_utf8_string;
+#ifdef WITH_X11_XINPUT
+ typedef struct GHOST_TabletX11 {
+ XDevice *StylusDevice;
+ XDevice *EraserDevice;
+
+ XID StylusID, EraserID;
+
+ int MotionEvent;
+ int ProxInEvent;
+ int ProxOutEvent;
+
+ int PressureLevels;
+ int XtiltLevels, YtiltLevels;
+ } GHOST_TabletX11;
+
+ GHOST_TabletX11 &GetXTablet()
+ {
+ return m_xtablet;
+ }
+#endif // WITH_X11_XINPUT
+
+ struct {
+ /**
+ * Atom used for ICCCM, WM-spec and Motif.
+ * We only need get this atom at the start, it's relative
+ * to the display not the window and are public for every
+ * window that need it.
+ */
+ Atom WM_STATE;
+ Atom WM_CHANGE_STATE;
+ Atom _NET_WM_STATE;
+ Atom _NET_WM_STATE_MAXIMIZED_HORZ;
+ Atom _NET_WM_STATE_MAXIMIZED_VERT;
+ Atom _NET_WM_STATE_FULLSCREEN;
+ Atom _MOTIF_WM_HINTS;
+ Atom WM_TAKE_FOCUS;
+ Atom WM_PROTOCOLS;
+ Atom WM_DELETE_WINDOW;
+
+ /* Atoms for Selection, copy & paste. */
+ Atom TARGETS;
+ Atom STRING;
+ Atom COMPOUND_TEXT;
+ Atom TEXT;
+ Atom CLIPBOARD;
+ Atom PRIMARY;
+ Atom XCLIP_OUT;
+ Atom INCR;
+ Atom UTF8_STRING;
+#ifdef WITH_X11_XINPUT
+ Atom TABLET;
+#endif
+ } m_atom;
private:
@@ -291,6 +338,11 @@ private:
XIM m_xim;
#endif
+#ifdef WITH_X11_XINPUT
+ /* Tablet devices */
+ GHOST_TabletX11 m_xtablet;
+#endif
+
/// The vector of windows that need to be updated.
std::vector<GHOST_WindowX11 *> m_dirty_windows;
@@ -313,6 +365,10 @@ private:
bool openX11_IM();
#endif
+#ifdef WITH_X11_XINPUT
+ void initXInputDevices();
+#endif
+
GHOST_WindowX11 *
findGhostWindow(
Window xwind
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index fd3ff4f85f0..6c2d7350cd9 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -45,6 +45,7 @@ GHOST_Window::GHOST_Window(
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
+ const bool exclusive,
const GHOST_TUns16 numOfAASamples)
:
m_drawingContextType(type),
@@ -61,6 +62,8 @@ GHOST_Window::GHOST_Window(
m_cursorGrabAccumPos[0] = 0;
m_cursorGrabAccumPos[1] = 0;
+
+ m_nativePixelSize = 1.0f;
m_fullScreen = state == GHOST_kWindowStateFullScreen;
if (m_fullScreen) {
@@ -194,3 +197,4 @@ bool GHOST_Window::getModifiedState()
{
return m_isUnsavedChanges;
}
+
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index fd870327fd4..588de0911e3 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -80,6 +80,8 @@ public:
* \param state The state the window is initially opened with.
* \param type The type of drawing context installed in this window.
* \param stereoVisual Stereo visual for quad buffered stereo.
+ * \param exclusive Use to show the window ontop and ignore others
+ * (used fullscreen).
* \param numOfAASamples Number of samples used for AA (zero if no AA)
*/
GHOST_Window(
@@ -88,6 +90,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
const bool stereoVisual = false,
+ const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0);
/**
@@ -257,6 +260,13 @@ public:
{
m_userData = userData;
}
+
+ virtual float getNativePixelSize(void)
+ {
+ if (m_nativePixelSize > 0.0f)
+ return m_nativePixelSize;
+ return 1.0f;
+ }
protected:
/**
@@ -351,6 +361,9 @@ protected:
GHOST_TUns32 m_fullScreenWidth;
/** Full-screen height */
GHOST_TUns32 m_fullScreenHeight;
+
+ /* OSX only, retina screens */
+ float m_nativePixelSize;
};
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp
index 99d8854667e..36d45b4790c 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.cpp
+++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp
@@ -182,7 +182,8 @@ GHOST_WindowCarbon::GHOST_WindowCarbon(
(SInt32) this); // Store a pointer to the class in the refCon
#endif
//GHOST_PRINT("GHOST_WindowCarbon::GHOST_WindowCarbon(): creating full-screen OpenGL context\n");
- setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);; installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
+ setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);
+ installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
updateDrawingContext();
activateDrawingContext();
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.h b/intern/ghost/intern/GHOST_WindowCarbon.h
index d25d57156f6..16f305e93c5 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.h
+++ b/intern/ghost/intern/GHOST_WindowCarbon.h
@@ -220,6 +220,11 @@ public:
{
return m_tablet;
}
+
+ GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
+
+ GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
+
protected:
/**
* Tries to install a rendering context in this window.
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index 3e5c675d4a7..fe0830edeae 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -262,6 +262,15 @@ public:
* Hides the progress bar icon
*/
virtual GHOST_TSuccess endProgressBar();
+
+
+ virtual void setNativePixelSize(void);
+
+ GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
+
+ GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
+
+
protected:
/**
* Tries to install a rendering context in this window.
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 7a5bb8ab604..8d5f8bf89d5 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -28,7 +28,7 @@
#include <Cocoa/Cocoa.h>
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
//Use of the SetSystemUIMode function (64bit compatible)
#include <Carbon/Carbon.h>
#endif
@@ -58,24 +58,24 @@ extern "C" {
extern void wm_draw_update(bContext *C);
};*/
@interface CocoaWindowDelegate : NSObject
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
<NSWindowDelegate>
-#endif
{
GHOST_SystemCocoa *systemCocoa;
GHOST_WindowCocoa *associatedWindow;
}
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
-- (void)windowWillClose:(NSNotification *)notification;
- (void)windowDidBecomeKey:(NSNotification *)notification;
- (void)windowDidResignKey:(NSNotification *)notification;
- (void)windowDidExpose:(NSNotification *)notification;
- (void)windowDidResize:(NSNotification *)notification;
- (void)windowDidMove:(NSNotification *)notification;
- (void)windowWillMove:(NSNotification *)notification;
+- (BOOL)windowShouldClose:(id)sender;
+- (void)windowDidChangeBackingProperties:(NSNotification *)notification;
@end
+
@implementation CocoaWindowDelegate : NSObject
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
{
@@ -83,11 +83,6 @@ extern "C" {
associatedWindow = winCocoa;
}
-- (void)windowWillClose:(NSNotification *)notification
-{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
-}
-
- (void)windowDidBecomeKey:(NSNotification *)notification
{
systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow);
@@ -115,12 +110,12 @@ extern "C" {
- (void)windowDidResize:(NSNotification *)notification
{
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//if (![[notification object] inLiveResize]) {
//Send event only once, at end of resize operation (when user has released mouse button)
#endif
systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//}
#endif
/* Live resize ugly patch. Needed because live resize runs in a modal loop, not letting main loop run
@@ -132,6 +127,19 @@ extern "C" {
wm_draw_update(ghostC);
}*/
}
+
+- (void)windowDidChangeBackingProperties:(NSNotification *)notification
+{
+ systemCocoa->handleWindowEvent(GHOST_kEventNativeResolutionChange, associatedWindow);
+}
+
+- (BOOL)windowShouldClose:(id)sender;
+{
+ //Let Blender close the window rather than closing immediately
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
+ return false;
+}
+
@end
#pragma mark NSWindow subclass
@@ -287,7 +295,7 @@ extern "C" {
}
}
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
//Cmd+key are handled differently before 10.5
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
@@ -425,6 +433,14 @@ extern "C" {
#pragma mark initialization / finalization
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+@interface NSView (NSOpenGLSurfaceResolution)
+- (BOOL)wantsBestResolutionOpenGLSurface;
+- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
+- (NSRect)convertRectToBacking:(NSRect)bounds;
+@end
+#endif
+
NSOpenGLContext* GHOST_WindowCocoa::s_firstOpenGLcontext = nil;
GHOST_WindowCocoa::GHOST_WindowCocoa(
@@ -571,13 +587,20 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
[m_window setContentView:m_openGLView];
[m_window setInitialFirstResponder:m_openGLView];
- [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window
-
[m_window makeKeyAndOrderFront:nil];
setDrawingContextType(type);
updateDrawingContext();
activateDrawingContext();
+
+ if (m_systemCocoa->m_nativePixel) {
+ if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ [m_openGLView setWantsBestResolutionOpenGLSurface:YES];
+
+ NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
+ m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width;
+ }
+ }
m_tablet.Active = GHOST_kTabletModeNone;
@@ -587,6 +610,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
[m_window setAcceptsMouseMovedEvents:YES];
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+ NSView *view = [m_window contentView];
+ [view setAcceptsTouchEvents:YES];
+#endif
+
[m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
NSStringPboardType, NSTIFFPboardType, nil]];
@@ -609,20 +637,20 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
[m_openGLView release];
if (m_window) {
- // previously we called [m_window release], but on 10.8 this does not
- // remove the window from [NSApp orderedWindows] and perhaps other
- // places, leading to crashes. so instead we set setReleasedWhenClosed
- // back to YES right before closing
- [m_window setReleasedWhenClosed:YES];
[m_window close];
- m_window = nil;
}
- //Check for other blender opened windows and make the frontmost key
+ // Check for other blender opened windows and make the frontmost key
+ // Note: for some reason the closed window is still in the list
NSArray *windowsList = [NSApp orderedWindows];
- if ([windowsList count]) {
- [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
+ for (int a = 0; a < [windowsList count]; a++) {
+ if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) {
+ [[windowsList objectAtIndex:a] makeKeyWindow];
+ break;
+ }
}
+ m_window = nil;
+
[pool drain];
}
@@ -888,6 +916,19 @@ NSScreen* GHOST_WindowCocoa::getScreen()
return [m_window screen];
}
+/* called for event, when window leaves monitor to another */
+void GHOST_WindowCocoa::setNativePixelSize(void)
+{
+ /* make sure 10.6 keeps running */
+ if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
+
+ GHOST_Rect rect;
+ getClientBounds(rect);
+
+ m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth();
+ }
+}
/**
* \note Fullscreen switch is not actual fullscreen with display capture.
@@ -916,7 +957,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
* doesn't know view/window difference. */
m_fullScreen = true;
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//10.6 provides Cocoa functions to autoshow menu bar, and to change a window style
//Hide menu & dock if needed
if ([[m_window screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) {
@@ -943,7 +984,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Copy current window parameters
[tmpWindow setTitle:[m_window title]];
[tmpWindow setRepresentedFilename:[m_window representedFilename]];
- [tmpWindow setReleasedWhenClosed:NO];
[tmpWindow setAcceptsMouseMovedEvents:YES];
[tmpWindow setDelegate:[m_window delegate]];
[tmpWindow setSystemAndWindowCocoa:[m_window systemCocoa] windowCocoa:this];
@@ -956,9 +996,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Show the new window
[tmpWindow makeKeyAndOrderFront:m_openGLView];
//Close and release old window
- [m_window setDelegate:nil]; // To avoid the notification of "window closed" event
[m_window close];
- [m_window release];
m_window = tmpWindow;
#endif
@@ -975,7 +1013,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
m_fullScreen = false;
//Exit fullscreen
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//Show again menu & dock if needed
if ([[m_window screen] isEqual:[NSScreen mainScreen]]) {
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
@@ -1001,7 +1039,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Copy current window parameters
[tmpWindow setTitle:[m_window title]];
[tmpWindow setRepresentedFilename:[m_window representedFilename]];
- [tmpWindow setReleasedWhenClosed:NO];
[tmpWindow setAcceptsMouseMovedEvents:YES];
[tmpWindow setDelegate:[m_window delegate]];
[tmpWindow setSystemAndWindowCocoa:[m_window systemCocoa] windowCocoa:this];
@@ -1016,9 +1053,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Show the new window
[tmpWindow makeKeyAndOrderFront:nil];
//Close and release old window
- [m_window setDelegate:nil]; // To avoid the notification of "window closed" event
[m_window close];
- [m_window release];
m_window = tmpWindow;
#endif
@@ -1221,7 +1256,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
[dockIcon lockFocus];
NSRect progressBox = {{4, 4}, {120, 16}};
- [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0];
+ [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
// Track & Outline
[[NSColor blackColor] setFill];
@@ -1260,7 +1295,7 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
[dockIcon lockFocus];
- [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0];
+ [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
[dockIcon unlockFocus];
[NSApp setApplicationIconImage:dockIcon];
[dockIcon release];
diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp
index daf1c2f2d22..1f20e01ca73 100644
--- a/intern/ghost/intern/GHOST_WindowManager.cpp
+++ b/intern/ghost/intern/GHOST_WindowManager.cpp
@@ -130,12 +130,12 @@ GHOST_TSuccess GHOST_WindowManager::beginFullScreen(GHOST_IWindow *window,
m_fullScreenWindow = window;
m_activeWindowBeforeFullScreen = getActiveWindow();
setActiveWindow(m_fullScreenWindow);
+ m_fullScreenWindow->beginFullScreen();
success = GHOST_kSuccess;
}
return success;
}
-
GHOST_TSuccess GHOST_WindowManager::endFullScreen(void)
{
GHOST_TSuccess success = GHOST_kFailure;
@@ -143,6 +143,7 @@ GHOST_TSuccess GHOST_WindowManager::endFullScreen(void)
if (m_fullScreenWindow != 0) {
//GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n");
setWindowInactive(m_fullScreenWindow);
+ m_fullScreenWindow->endFullScreen();
delete m_fullScreenWindow;
//GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n");
m_fullScreenWindow = 0;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index fead1884f8a..7566e7fe71c 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -470,38 +470,22 @@ void GHOST_WindowWin32::getWindowBounds(GHOST_Rect& bounds) const
void GHOST_WindowWin32::getClientBounds(GHOST_Rect& bounds) const
{
RECT rect;
- GHOST_TWindowState state = this->getState();
- LONG_PTR result = ::GetWindowLongPtr(m_hWnd, GWL_STYLE);
- int sm_cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME);
- ::GetWindowRect(m_hWnd, &rect);
+ POINT coord;
+ ::GetClientRect(m_hWnd, &rect);
- if ((result & (WS_POPUP | WS_MAXIMIZE)) != (WS_POPUP | WS_MAXIMIZE)) {
- if (state == GHOST_kWindowStateMaximized) {
- // in maximized state we don't have borders on the window
- bounds.m_b = rect.bottom - GetSystemMetrics(SM_CYCAPTION) - sm_cysizeframe * 2;
- bounds.m_l = rect.left + sm_cysizeframe;
- bounds.m_r = rect.right - sm_cysizeframe;
- bounds.m_t = rect.top;
- }
- else if (state == GHOST_kWindowStateEmbedded) {
- bounds.m_b = rect.bottom;
- bounds.m_l = rect.left;
- bounds.m_r = rect.right;
- bounds.m_t = rect.top;
- }
- else {
- bounds.m_b = rect.bottom - GetSystemMetrics(SM_CYCAPTION) - sm_cysizeframe * 2;
- bounds.m_l = rect.left;
- bounds.m_r = rect.right - sm_cysizeframe * 2;
- bounds.m_t = rect.top;
- }
- }
- else {
- bounds.m_b = rect.bottom;
- bounds.m_l = rect.left;
- bounds.m_r = rect.right;
- bounds.m_t = rect.top;
- }
+ coord.x = rect.left;
+ coord.y = rect.top;
+ ::ClientToScreen(m_hWnd, &coord);
+
+ bounds.m_l = coord.x;
+ bounds.m_t = coord.y;
+
+ coord.x = rect.right;
+ coord.y = rect.bottom;
+ ::ClientToScreen(m_hWnd, &coord);
+
+ bounds.m_r = coord.x;
+ bounds.m_b = coord.y;
}
@@ -712,6 +696,7 @@ GHOST_TSuccess GHOST_WindowWin32::initMultisample(PIXELFORMATDESCRIPTOR pfd)
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB, pfd.cColorBits,
WGL_DEPTH_BITS_ARB, pfd.cDepthBits,
+ WGL_ALPHA_BITS_ARB, pfd.cAlphaBits,
WGL_STENCIL_BITS_ARB, pfd.cStencilBits,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
@@ -1192,6 +1177,16 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
}
}
+void GHOST_WindowWin32::bringTabletContextToFront()
+{
+ if (m_wintab) {
+ GHOST_WIN32_WTOverlap fpWTOverlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab, "WTOverlap");
+ if (fpWTOverlap) {
+ fpWTOverlap(m_tablet, TRUE);
+ }
+ }
+}
+
/** Reverse the bits in a GHOST_TUns8 */
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{
@@ -1311,6 +1306,9 @@ static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd)
weight += pfd.cColorBits - 8;
+ if (pfd.cAlphaBits > 0)
+ weight ++;
+
/* want swap copy capability -- it matters a lot */
if (pfd.dwFlags & PFD_SWAP_COPY) weight += 16;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 9e4377b8225..2af4b703930 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -58,6 +58,7 @@ typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX);
typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
+typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL);
/**
* GHOST window on M$ Windows OSs.
@@ -273,6 +274,11 @@ public:
void processWin32TabletInitEvent();
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
+ void bringTabletContextToFront();
+
+ GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
+
+ GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
protected:
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 156bc86869a..05ab24492c2 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -165,9 +165,10 @@ GHOST_WindowX11(
const GHOST_TEmbedderWindowID parentWindow,
GHOST_TDrawingContextType type,
const bool stereoVisual,
+ const bool exclusive,
const GHOST_TUns16 numOfAASamples
) :
- GHOST_Window(width, height, state, type, stereoVisual, numOfAASamples),
+ GHOST_Window(width, height, state, type, stereoVisual, exclusive, numOfAASamples),
m_context(NULL),
m_display(display),
m_normal_state(GHOST_kWindowStateNormal),
@@ -186,11 +187,6 @@ GHOST_WindowX11(
int natom;
int glxVersionMajor, glxVersionMinor; /* As in GLX major.minor */
-#ifdef WITH_X11_XINPUT
- /* initialize incase X11 fails to load */
- memset(&m_xtablet, 0, sizeof(m_xtablet));
-#endif
-
m_visual = NULL;
if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
@@ -218,6 +214,7 @@ GHOST_WindowX11(
attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
+ attributes[i++] = GLX_ALPHA_SIZE; attributes[i++] = 1;
/* GLX >= 1.4 required for multi-sample */
if (samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
@@ -258,6 +255,7 @@ GHOST_WindowX11(
* This seems pretty much a legacy feature as we are in rgba mode anyway. */
XSetWindowAttributes xattributes;
+ unsigned int xattributes_valuemask = (CWBorderPixel | CWColormap | CWEventMask);
memset(&xattributes, 0, sizeof(xattributes));
xattributes.colormap = XCreateColormap(m_display,
@@ -271,15 +269,19 @@ GHOST_WindowX11(
/* Specify which events we are interested in hearing. */
xattributes.event_mask =
- ExposureMask | StructureNotifyMask |
- KeyPressMask | KeyReleaseMask |
- EnterWindowMask | LeaveWindowMask |
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | FocusChangeMask | PropertyChangeMask;
+ ExposureMask | StructureNotifyMask |
+ KeyPressMask | KeyReleaseMask |
+ EnterWindowMask | LeaveWindowMask |
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | FocusChangeMask |
+ PropertyChangeMask | KeymapStateMask;
+
+ if (exclusive) {
+ xattributes_valuemask |= CWOverrideRedirect;
+ xattributes.override_redirect = True;
+ }
/* create the window! */
-
- ;
if (parentWindow == 0) {
m_window = XCreateWindow(m_display,
RootWindow(m_display, m_visual->screen),
@@ -291,7 +293,7 @@ GHOST_WindowX11(
m_visual->depth,
InputOutput,
m_visual->visual,
- CWBorderPixel | CWColormap | CWEventMask,
+ xattributes_valuemask,
&xattributes
);
}
@@ -320,7 +322,7 @@ GHOST_WindowX11(
m_visual->depth,
InputOutput,
m_visual->visual,
- CWBorderPixel | CWColormap | CWEventMask,
+ xattributes_valuemask,
&xattributes
);
@@ -334,6 +336,26 @@ GHOST_WindowX11(
GHOST_PRINT("Set drop target\n");
#endif
+ if (state == GHOST_kWindowStateMaximized || state == GHOST_kWindowStateFullScreen) {
+ Atom _NET_WM_STATE = XInternAtom(m_display, "_NET_WM_STATE", False);
+ Atom _NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
+ Atom _NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+ Atom _NET_WM_STATE_FULLSCREEN = XInternAtom(m_display, "_NET_WM_STATE_FULLSCREEN", False);
+ Atom atoms[2];
+ int count = 0;
+
+ if (state == GHOST_kWindowStateMaximized) {
+ atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
+ atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
+ }
+ else {
+ atoms[count++] = _NET_WM_STATE_FULLSCREEN;
+ }
+
+ XChangeProperty(m_display, m_window, _NET_WM_STATE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)atoms, count);
+ m_post_init = False;
+ }
/*
* One of the problem with WM-spec is that can't set a property
* to a window that isn't mapped. That is why we can't "just
@@ -345,7 +367,7 @@ GHOST_WindowX11(
* So, m_post_init indicate that we need wait for the MapNotify
* event and then set the Window state to the m_post_state.
*/
- if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
+ else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
m_post_init = True;
m_post_state = state;
}
@@ -381,16 +403,16 @@ GHOST_WindowX11(
XFree(xclasshint);
/* The basic for a good ICCCM "work" */
- if (m_system->m_wm_protocols) {
+ if (m_system->m_atom.WM_PROTOCOLS) {
natom = 0;
- if (m_system->m_delete_window_atom) {
- atoms[natom] = m_system->m_delete_window_atom;
+ if (m_system->m_atom.WM_DELETE_WINDOW) {
+ atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW;
natom++;
}
- if (m_system->m_wm_take_focus) {
- atoms[natom] = m_system->m_wm_take_focus;
+ if (m_system->m_atom.WM_TAKE_FOCUS) {
+ atoms[natom] = m_system->m_atom.WM_TAKE_FOCUS;
natom++;
}
@@ -461,6 +483,8 @@ GHOST_WindowX11(
#ifdef WITH_X11_XINPUT
initXInputDevices();
+
+ m_tabletData.Active = GHOST_kTabletModeNone;
#endif
/* now set up the rendering context. */
@@ -469,7 +493,12 @@ GHOST_WindowX11(
GHOST_PRINT("Created window\n");
}
- XMapWindow(m_display, m_window);
+ if (exclusive) {
+ XMapRaised(m_display, m_window);
+ }
+ else {
+ XMapWindow(m_display, m_window);
+ }
GHOST_PRINT("Mapped window\n");
XFlush(m_display);
@@ -511,206 +540,36 @@ bool GHOST_WindowX11::createX11_XIC()
EnterWindowMask | LeaveWindowMask |
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | FocusChangeMask |
- PropertyChangeMask | fevent);
+ PropertyChangeMask | KeymapStateMask | fevent);
return true;
}
#endif
#ifdef WITH_X11_XINPUT
-/*
- * 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.
- */
-static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
-{
- fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
- theEvent->error_code, theEvent->request_code);
-
- /* No exit! - but keep lint happy */
- return 0;
-}
-
-/* These C functions are copied from Wine 1.1.13's wintab.c */
-#define BOOL int
-#define TRUE 1
-#define FALSE 0
-
-static bool match_token(const char *haystack, const char *needle)
-{
- const char *p, *q;
- for (p = haystack; *p; )
- {
- while (*p && isspace(*p))
- p++;
- if (!*p)
- break;
-
- for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
- p++;
- if (!*q && (isspace(*p) || !*p))
- return TRUE;
-
- while (*p && !isspace(*p))
- p++;
- }
- return FALSE;
-}
-
-
-/* Determining if an X device is a Tablet style device is an imperfect science.
- * We rely on common conventions around device names as well as the type reported
- * by Wacom tablets. This code will likely need to be expanded for alternate tablet types
- *
- * Wintab refers to any device that interacts with the tablet as a cursor,
- * (stylus, eraser, tablet mouse, airbrush, etc)
- * this is not to be confused with wacom x11 configuration "cursor" device.
- * Wacoms x11 config "cursor" refers to its device slot (which we mirror with
- * our gSysCursors) for puck like devices (tablet mice essentially).
- */
-#if 0 // unused
-static BOOL is_tablet_cursor(const char *name, const char *type)
-{
- int i;
- static const char *tablet_cursor_whitelist[] = {
- "wacom",
- "wizardpen",
- "acecad",
- "tablet",
- "cursor",
- "stylus",
- "eraser",
- "pad",
- NULL
- };
-
- for (i = 0; tablet_cursor_whitelist[i] != NULL; i++) {
- if (name && match_token(name, tablet_cursor_whitelist[i]))
- return TRUE;
- if (type && match_token(type, tablet_cursor_whitelist[i]))
- return TRUE;
- }
- return FALSE;
-}
-#endif
-static BOOL is_stylus(const char *name, const char *type)
-{
- int i;
- static const char *tablet_stylus_whitelist[] = {
- "stylus",
- "wizardpen",
- "acecad",
- NULL
- };
-
- for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
- if (name && match_token(name, tablet_stylus_whitelist[i]))
- return TRUE;
- if (type && match_token(type, tablet_stylus_whitelist[i]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static BOOL is_eraser(const char *name, const char *type)
-{
- if (name && match_token(name, "eraser"))
- return TRUE;
- if (type && match_token(type, "eraser"))
- return TRUE;
- return FALSE;
-}
-#undef BOOL
-#undef TRUE
-#undef FALSE
-/* end code copied from wine */
-
void GHOST_WindowX11::initXInputDevices()
{
- static XErrorHandler old_handler = (XErrorHandler) 0;
XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
if (version->present) {
- int device_count;
- XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
- m_xtablet.StylusDevice = NULL;
- m_xtablet.EraserDevice = NULL;
- m_xtablet.CommonData.Active = GHOST_kTabletModeNone;
-
- /* Install our error handler to override Xlib's termination behavior */
- old_handler = XSetErrorHandler(ApplicationErrorHandler);
-
- for (int i = 0; i < device_count; ++i) {
- char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
-
-// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
-
-
- if (m_xtablet.StylusDevice == NULL && is_stylus(device_info[i].name, device_type)) {
-// printf("\tfound stylus\n");
- m_xtablet.StylusID = device_info[i].id;
- m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
-
- if (m_xtablet.StylusDevice != NULL) {
- /* Find how many pressure levels tablet has */
- XAnyClassPtr ici = device_info[i].inputclassinfo;
- for (int j = 0; j < m_xtablet.StylusDevice->num_classes; ++j) {
- if (ici->c_class == ValuatorClass) {
-// printf("\t\tfound ValuatorClass\n");
- XValuatorInfo *xvi = (XValuatorInfo *)ici;
- m_xtablet.PressureLevels = xvi->axes[2].max_value;
-
- /* this is assuming that the tablet has the same tilt resolution in both
- * positive and negative directions. It would be rather weird if it didn't.. */
- m_xtablet.XtiltLevels = xvi->axes[3].max_value;
- m_xtablet.YtiltLevels = xvi->axes[4].max_value;
- break;
- }
-
- ici = (XAnyClassPtr)(((char *)ici) + ici->length);
- }
- }
- else {
- m_xtablet.StylusID = 0;
- }
- }
- else if (m_xtablet.EraserDevice == NULL && is_eraser(device_info[i].name, device_type)) {
-// printf("\tfound eraser\n");
- m_xtablet.EraserID = device_info[i].id;
- m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
- if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID = 0;
- }
-
- if (device_type) {
- XFree((void *)device_type);
- }
- }
-
- /* Restore handler */
- (void) XSetErrorHandler(old_handler);
-
- XFreeDeviceList(device_info);
-
-
+ GHOST_SystemX11::GHOST_TabletX11 &xtablet = m_system->GetXTablet();
XEventClass xevents[10], ev;
int dcount = 0;
- if (m_xtablet.StylusDevice) {
- DeviceMotionNotify(m_xtablet.StylusDevice, m_xtablet.MotionEvent, ev);
+ if (xtablet.StylusDevice) {
+ DeviceMotionNotify(xtablet.StylusDevice, xtablet.MotionEvent, ev);
if (ev) xevents[dcount++] = ev;
- ProximityIn(m_xtablet.StylusDevice, m_xtablet.ProxInEvent, ev);
+ ProximityIn(xtablet.StylusDevice, xtablet.ProxInEvent, ev);
if (ev) xevents[dcount++] = ev;
- ProximityOut(m_xtablet.StylusDevice, m_xtablet.ProxOutEvent, ev);
+ ProximityOut(xtablet.StylusDevice, xtablet.ProxOutEvent, ev);
if (ev) xevents[dcount++] = ev;
}
- if (m_xtablet.EraserDevice) {
- DeviceMotionNotify(m_xtablet.EraserDevice, m_xtablet.MotionEvent, ev);
+ if (xtablet.EraserDevice) {
+ DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEvent, ev);
if (ev) xevents[dcount++] = ev;
- ProximityIn(m_xtablet.EraserDevice, m_xtablet.ProxInEvent, ev);
+ ProximityIn(xtablet.EraserDevice, xtablet.ProxInEvent, ev);
if (ev) xevents[dcount++] = ev;
- ProximityOut(m_xtablet.EraserDevice, m_xtablet.ProxOutEvent, ev);
+ ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEvent, ev);
if (ev) xevents[dcount++] = ev;
}
@@ -898,7 +757,7 @@ void GHOST_WindowX11::icccmSetState(int state)
xev.xclient.display = m_display;
xev.xclient.window = m_window;
xev.xclient.format = 32;
- xev.xclient.message_type = m_system->m_wm_change_state;
+ 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)),
False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
@@ -912,8 +771,8 @@ int GHOST_WindowX11::icccmGetState(void) const
int format_ret, st;
prop_ret = NULL;
- st = XGetWindowProperty(m_display, m_window, m_system->m_wm_state, 0,
- 0x7fffffff, False, m_system->m_wm_state, &type_ret,
+ st = XGetWindowProperty(m_display, m_window, m_system->m_atom.WM_STATE, 0,
+ 0x7fffffff, False, m_system->m_atom.WM_STATE, &type_ret,
&format_ret, &num_ret, &bytes_after, &prop_ret);
if ((st == Success) && (prop_ret) && (num_ret == 2))
@@ -934,7 +793,7 @@ void GHOST_WindowX11::netwmMaximized(bool set)
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = m_window;
- xev.xclient.message_type = m_system->m_net_state;
+ xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
xev.xclient.format = 32;
if (set == True)
@@ -942,8 +801,8 @@ void GHOST_WindowX11::netwmMaximized(bool set)
else
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
- xev.xclient.data.l[1] = m_system->m_net_max_horz;
- xev.xclient.data.l[2] = m_system->m_net_max_vert;
+ xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
+ 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)),
@@ -960,15 +819,15 @@ bool GHOST_WindowX11::netwmIsMaximized(void) const
prop_ret = NULL;
st = False;
- ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
+ ret = XGetWindowProperty(m_display, m_window, m_system->m_atom._NET_WM_STATE, 0,
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
&num_ret, &bytes_after, &prop_ret);
if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
count = 0;
for (i = 0; i < num_ret; i++) {
- if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_horz)
+ if (((unsigned long *) prop_ret)[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ)
count++;
- if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_vert)
+ if (((unsigned long *) prop_ret)[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT)
count++;
if (count == 2) {
st = True;
@@ -990,7 +849,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set)
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = m_window;
- xev.xclient.message_type = m_system->m_net_state;
+ xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
xev.xclient.format = 32;
if (set == True)
@@ -998,7 +857,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set)
else
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
- xev.xclient.data.l[1] = m_system->m_net_fullscreen;
+ xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
@@ -1016,12 +875,12 @@ bool GHOST_WindowX11::netwmIsFullScreen(void) const
prop_ret = NULL;
st = False;
- ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
+ ret = XGetWindowProperty(m_display, m_window, m_system->m_atom._NET_WM_STATE, 0,
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
&num_ret, &bytes_after, &prop_ret);
if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
for (i = 0; i < num_ret; i++) {
- if (((unsigned long *) prop_ret)[i] == m_system->m_net_fullscreen) {
+ if (((unsigned long *) prop_ret)[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) {
st = True;
break;
}
@@ -1043,8 +902,8 @@ void GHOST_WindowX11::motifFullScreen(bool set)
else
hints.decorations = 1;
- XChangeProperty(m_display, m_window, m_system->m_motif,
- m_system->m_motif, 32, PropModeReplace,
+ XChangeProperty(m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS,
+ m_system->m_atom._MOTIF_WM_HINTS, 32, PropModeReplace,
(unsigned char *) &hints, 4);
}
@@ -1059,8 +918,8 @@ bool GHOST_WindowX11::motifIsFullScreen(void) const
prop_ret = NULL;
state = False;
- st = XGetWindowProperty(m_display, m_window, m_system->m_motif, 0,
- 0x7fffffff, False, m_system->m_motif,
+ st = XGetWindowProperty(m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS, 0,
+ 0x7fffffff, False, m_system->m_atom._MOTIF_WM_HINTS,
&type_ret, &format_ret, &num_ret,
&bytes_after, &prop_ret);
if ((st == Success) && (prop_ret)) {
@@ -1089,12 +948,12 @@ GHOST_TWindowState GHOST_WindowX11::getState() const
*/
if ((state == IconicState) || (state == WithdrawnState))
state_ret = GHOST_kWindowStateMinimized;
- else if (netwmIsMaximized() == True)
- state_ret = GHOST_kWindowStateMaximized;
else if (netwmIsFullScreen() == True)
state_ret = GHOST_kWindowStateFullScreen;
else if (motifIsFullScreen() == True)
state_ret = GHOST_kWindowStateFullScreen;
+ else if (netwmIsMaximized() == True)
+ state_ret = GHOST_kWindowStateMaximized;
return (state_ret);
}
@@ -1341,15 +1200,6 @@ GHOST_WindowX11::
XFreeCursor(m_display, m_custom_cursor);
}
-#ifdef WITH_X11_XINPUT
- /* close tablet devices */
- if (m_xtablet.StylusDevice)
- XCloseDevice(m_display, m_xtablet.StylusDevice);
-
- if (m_xtablet.EraserDevice)
- XCloseDevice(m_display, m_xtablet.EraserDevice);
-#endif /* WITH_X11_XINPUT */
-
if (m_context != s_firstContext) {
glXDestroyContext(m_display, m_context);
}
@@ -1392,6 +1242,15 @@ installDrawingContext(
GHOST_TSuccess success;
switch (type) {
case GHOST_kDrawingContextTypeOpenGL:
+ {
+#ifdef WITH_X11_XINPUT
+ /* use our own event handlers to avoid exiting blender,
+ * this would happen for eg:
+ * if you open blender, unplug a tablet, then open a new window. */
+ XErrorHandler old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
+ XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
+#endif
+
m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
if (m_context != NULL) {
if (!s_firstContext) {
@@ -1406,12 +1265,18 @@ installDrawingContext(
success = GHOST_kFailure;
}
+#ifdef WITH_X11_XINPUT
+ /* Restore handler */
+ (void) XSetErrorHandler(old_handler);
+ (void) XSetIOErrorHandler(old_handler_io);
+#endif
break;
-
+ }
case GHOST_kDrawingContextTypeNone:
+ {
success = GHOST_kSuccess;
break;
-
+ }
default:
success = GHOST_kFailure;
}
@@ -1645,3 +1510,44 @@ setWindowCustomCursorShape(
return GHOST_kSuccess;
}
+
+
+GHOST_TSuccess
+GHOST_WindowX11::
+beginFullScreen() const
+{
+ {
+ Window root_return;
+ int x_return, y_return;
+ unsigned int w_return, h_return, border_w_return, depth_return;
+
+ XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
+ &w_return, &h_return, &border_w_return, &depth_return);
+
+ m_system->setCursorPosition(w_return / 2, h_return / 2);
+ }
+
+
+ /* Grab Keyboard & Mouse */
+ int err;
+
+ err = XGrabKeyboard(m_display, m_window, False,
+ GrabModeAsync, GrabModeAsync, CurrentTime);
+ if (err != GrabSuccess) printf("XGrabKeyboard failed %d\n", err);
+
+ err = XGrabPointer(m_display, m_window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
+ if (err != GrabSuccess) printf("XGrabPointer failed %d\n", err);
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess
+GHOST_WindowX11::
+endFullScreen() const
+{
+ XUngrabKeyboard(m_display, CurrentTime);
+ XUngrabPointer(m_display, CurrentTime);
+
+ return GHOST_kSuccess;
+}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 5b2ffced29c..b8471b41a11 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -87,6 +87,7 @@ public:
const GHOST_TEmbedderWindowID parentWindow,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
const bool stereoVisual = false,
+ const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0
);
@@ -196,32 +197,9 @@ public:
getXWindow(
);
#ifdef WITH_X11_XINPUT
- class XTablet
+ GHOST_TabletData *GetTabletData()
{
-public:
- GHOST_TabletData CommonData;
-
- XDevice *StylusDevice;
- XDevice *EraserDevice;
-
- XID StylusID, EraserID;
-
- int MotionEvent;
- int ProxInEvent;
- int ProxOutEvent;
-
- int PressureLevels;
- int XtiltLevels, YtiltLevels;
- };
-
- XTablet& GetXTablet()
- {
- return m_xtablet;
- }
-
- const GHOST_TabletData *GetTabletData()
- {
- return &m_xtablet.CommonData;
+ return &m_tabletData;
}
#else // WITH_X11_XINPUT
const GHOST_TabletData *GetTabletData()
@@ -253,6 +231,10 @@ public:
bool m_post_init;
GHOST_TWindowState m_post_state;
+ GHOST_TSuccess beginFullScreen() const;
+
+ GHOST_TSuccess endFullScreen() const;
+
protected:
/**
* Tries to install a rendering context in this window.
@@ -387,8 +369,7 @@ private:
#endif
#ifdef WITH_X11_XINPUT
- /* Tablet devices */
- XTablet m_xtablet;
+ GHOST_TabletData m_tabletData;
#endif
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript
index 74d6e07269f..0712e1c4489 100644
--- a/intern/guardedalloc/SConscript
+++ b/intern/guardedalloc/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 4a79f5d0de1..93cb2f6d4d1 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -52,6 +52,10 @@
# include <sys/mman.h>
#endif
+#if defined(_MSC_VER)
+# define __func__ __FUNCTION__
+#endif
+
#include "MEM_guardedalloc.h"
/* Only for debugging:
@@ -68,6 +72,17 @@
//#define DEBUG_MEMCOUNTER
+/* Only for debugging:
+ * defining DEBUG_THREADS will enable check whether memory manager
+ * is locked with a mutex when allocation is called from non-main
+ * thread.
+ *
+ * This helps troubleshooting memory issues caused by the fact
+ * guarded allocator is not thread-safe, however this check will
+ * fail to check allocations from openmp threads.
+ */
+//#define DEBUG_THREADS
+
#ifdef DEBUG_MEMCOUNTER
/* set this to the value that isn't being freed */
# define DEBUG_MEMCOUNTER_ERROR_VAL 0
@@ -110,6 +125,24 @@ typedef struct MemHead {
#endif
} MemHead;
+/* for openmp threading asserts, saves time troubleshooting
+ * we may need to extend this if blender code starts using MEM_
+ * functions inside OpenMP correctly with omp_set_lock() */
+
+#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
+#if defined(_OPENMP) && defined(DEBUG)
+# include <assert.h>
+# include <omp.h>
+# define DEBUG_OMP_MALLOC
+#endif
+#endif
+
+#ifdef DEBUG_THREADS
+# include <assert.h>
+# include <pthread.h>
+static pthread_t mainid;
+#endif
+
typedef struct MemTail {
int tag3, pad;
} MemTail;
@@ -194,6 +227,24 @@ static void print_error(const char *str, ...)
static void mem_lock_thread(void)
{
+#ifdef DEBUG_THREADS
+ static int initialized = 0;
+
+ if (initialized == 0) {
+ /* assume first allocation happens from main thread */
+ mainid = pthread_self();
+ initialized = 1;
+ }
+
+ if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
+ assert(!"Memory function is called from non-main thread without lock");
+ }
+#endif
+
+#ifdef DEBUG_OMP_MALLOC
+ assert(omp_in_parallel() == 0);
+#endif
+
if (thread_lock_callback)
thread_lock_callback();
}
@@ -214,8 +265,7 @@ int MEM_check_memory_integrity(void)
err_val = check_memlist(listend);
- if (err_val == NULL) return 0;
- return 1;
+ return (err_val != NULL);
}
@@ -314,6 +364,9 @@ void *MEM_reallocN(void *vmemh, size_t len)
MEM_freeN(vmemh);
}
+ else {
+ newp = MEM_mallocN(len, __func__);
+ }
return newp;
}
@@ -345,6 +398,9 @@ void *MEM_recallocN(void *vmemh, size_t len)
MEM_freeN(vmemh);
}
+ else {
+ newp = MEM_callocN(len, __func__);
+ }
return newp;
}
@@ -546,6 +602,8 @@ void MEM_printmemlist_stats(void)
qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
printf("\ntotal memory len: %.3f MB\n",
(double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n",
+ (double)peak_mem / (double)(1024 * 1024));
printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
for (a = 0, pb = printblock; a < totpb; a++, pb++) {
printf("%6d (%8.3f %8.3f) %s\n",
diff --git a/intern/iksolver/SConscript b/intern/iksolver/SConscript
index b88d3b1b713..ba973ad5fd5 100644
--- a/intern/iksolver/SConscript
+++ b/intern/iksolver/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/iksolver/extern/IK_solver.h b/intern/iksolver/extern/IK_solver.h
index a3f599e06c8..4de9f143e77 100644
--- a/intern/iksolver/extern/IK_solver.h
+++ b/intern/iksolver/extern/IK_solver.h
@@ -163,7 +163,7 @@ float IK_SolverGetPoleAngle(IK_Solver *solver);
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations);
-#define IK_STRETCH_STIFF_EPS 0.001f
+#define IK_STRETCH_STIFF_EPS 0.01f
#define IK_STRETCH_STIFF_MIN 0.001f
#define IK_STRETCH_STIFF_MAX 1e10
diff --git a/intern/itasc/SConscript b/intern/itasc/SConscript
index c1ad931c665..208fee5f2d3 100644
--- a/intern/itasc/SConscript
+++ b/intern/itasc/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/intern/itasc/kdl/chain.hpp b/intern/itasc/kdl/chain.hpp
index fde9d4ed23e..1776737fc7d 100644
--- a/intern/itasc/kdl/chain.hpp
+++ b/intern/itasc/kdl/chain.hpp
@@ -36,7 +36,7 @@ namespace KDL {
class Chain {
private:
#if defined(__APPLE__)
-# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
std::vector<Segment> segments;
# else
// Eigen allocator is needed for alignment of Eigen data types
diff --git a/intern/itasc/kdl/tree.hpp b/intern/itasc/kdl/tree.hpp
index a020c6cf2cf..82794f96b94 100644
--- a/intern/itasc/kdl/tree.hpp
+++ b/intern/itasc/kdl/tree.hpp
@@ -28,7 +28,7 @@
#include <string>
#include <map>
#if defined(__APPLE__)
-# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
//no include
# else
# include <Eigen/Core>
@@ -42,7 +42,7 @@ namespace KDL
//Forward declaration
class TreeElement;
#if defined(__APPLE__)
-# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
typedef std::map<std::string,TreeElement> SegmentMap;
# else
// Eigen allocator is needed for alignment of Eigen data types
diff --git a/intern/locale/SConscript b/intern/locale/SConscript
index df745f093ea..f60bd90fb38 100644
--- a/intern/locale/SConscript
+++ b/intern/locale/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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) 2012, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Bastien Montagne.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
index 939c66bad13..ebd2dd652c7 100644
--- a/intern/locale/boost_locale_wrapper.cpp
+++ b/intern/locale/boost_locale_wrapper.cpp
@@ -33,6 +33,7 @@
static std::string messages_path;
static std::string default_domain;
+static std::string locale_str;
void bl_locale_init(const char *_messages_path, const char *_default_domain)
{
@@ -52,47 +53,72 @@ void bl_locale_init(const char *_messages_path, const char *_default_domain)
void bl_locale_set(const char *locale)
{
boost::locale::generator gen;
+ std::locale _locale;
// Specify location of dictionaries.
gen.add_messages_path(messages_path);
gen.add_messages_domain(default_domain);
- //gen.set_default_messages_domain(default_domain);
+ //gen.set_default_messages_domain(default_domain);
- if (locale && locale[0]) {
- std::locale::global(gen(locale));
- }
- else {
-#if defined (__APPLE__)
- // workaround to get osx system locale from user defaults
- FILE* fp;
- std::string locale_osx = "";
- char result[16];
- int result_len = 0;
-
- fp = popen("defaults read .GlobalPreferences AppleLocale", "r");
-
- if(fp) {
- result_len = fread(result, 1, sizeof(result) - 1, fp);
-
- if(result_len > 0) {
- result[result_len-1] = '\0'; // \0 terminate and remove \n
- locale_osx = std::string(result) + std::string(".UTF-8");
- }
-
- pclose(fp);
+ try {
+ if (locale && locale[0]) {
+ _locale = gen(locale);
+ std::locale::global(_locale);
}
+ else {
+#ifdef __APPLE__
+ // workaround to get osx system locale from user defaults
+ FILE *fp;
+ std::string locale_osx = "";
+ char result[16];
+ int result_len = 0;
+
+ fp = popen("defaults read .GlobalPreferences AppleLocale", "r");
+
+ if (fp) {
+ result_len = fread(result, 1, sizeof(result) - 1, fp);
- if(locale_osx == "")
- fprintf(stderr, "Locale set: failed to read AppleLocale read from defaults\n");
+ if (result_len > 0) {
+ result[result_len - 1] = '\0'; // \0 terminate and remove \n
+ locale_osx = std::string(result) + std::string(".UTF-8");
+ }
- std::locale::global(gen(locale_osx.c_str()));
+ pclose(fp);
+ }
+
+ if (locale_osx == "")
+ fprintf(stderr, "Locale set: failed to read AppleLocale read from defaults\n");
+
+ _locale = gen(locale_osx.c_str());
+ std::locale::global(_locale);
#else
- std::locale::global(gen(""));
+ _locale = gen("");
+ std::locale::global(_locale);
#endif
+ }
+ // Note: boost always uses "C" LC_NUMERIC by default!
+ }
+ catch(std::exception const &e) {
+ std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
+ }
+
+ /* Generate the locale string (useful to know which locale we are actually using in case of "default" one). */
+#define LOCALE_INFO std::use_facet<boost::locale::info>(_locale)
+
+ locale_str = LOCALE_INFO.language();
+ if (LOCALE_INFO.country() != "") {
+ locale_str += "_" + LOCALE_INFO.country();
+ }
+ if (LOCALE_INFO.variant() != "") {
+ locale_str += "@" + LOCALE_INFO.variant();
}
- // Note: boost always uses "C" LC_NUMERIC by default!
}
-const char* bl_locale_pgettext(const char *msgctxt, const char *msgid)
+const char *bl_locale_get(void)
+{
+ return locale_str.c_str();
+}
+
+const char *bl_locale_pgettext(const char *msgctxt, const char *msgid)
{
// Note: We cannot use short stuff like boost::locale::gettext, because those return
// std::basic_string objects, which c_ptr()-returned char* is no more valid
@@ -107,8 +133,7 @@ const char* bl_locale_pgettext(const char *msgctxt, const char *msgid)
return msgid;
}
catch(std::exception const &e) {
-// std::cout << "boost_locale_pgettext: " << e.what() << " \n";
+// std::cout << "bl_locale_pgettext(" << msgctxt << ", " << msgid << "): " << e.what() << " \n";
return msgid;
}
-}
-
+} \ No newline at end of file
diff --git a/intern/locale/boost_locale_wrapper.h b/intern/locale/boost_locale_wrapper.h
index e7956d216f1..4e3a1f848d2 100644
--- a/intern/locale/boost_locale_wrapper.h
+++ b/intern/locale/boost_locale_wrapper.h
@@ -40,7 +40,8 @@ extern "C" {
void bl_locale_init(const char *messages_path, const char *default_domain);
void bl_locale_set(const char *locale);
-const char* bl_locale_pgettext(const char *msgctxt, const char *msgid);
+const char *bl_locale_get(void);
+const char *bl_locale_pgettext(const char *msgctxt, const char *msgid);
#ifdef __cplusplus
}
diff --git a/intern/memutil/SConscript b/intern/memutil/SConscript
index c9a03982615..95fa39eb9c5 100644
--- a/intern/memutil/SConscript
+++ b/intern/memutil/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/mikktspace/SConscript b/intern/mikktspace/SConscript
index 8f31f21a26f..fcb257a4ea0 100644
--- a/intern/mikktspace/SConscript
+++ b/intern/mikktspace/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Daniel Genrich
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = ['mikktspace.c']
diff --git a/intern/moto/SConscript b/intern/moto/SConscript
index ba257a33b14..34a0afe27f8 100644
--- a/intern/moto/SConscript
+++ b/intern/moto/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/source/blender/opencl/CMakeLists.txt b/intern/opencl/CMakeLists.txt
index b3c76db1bca..03855cfdf8b 100644
--- a/source/blender/opencl/CMakeLists.txt
+++ b/intern/opencl/CMakeLists.txt
@@ -39,4 +39,4 @@ set(SRC
)
-blender_add_lib(bf_opencl "${SRC}" "${INC}" "${INC_SYS}")
+blender_add_lib(bf_intern_opencl "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/opencl/OCL_opencl.h b/intern/opencl/OCL_opencl.h
index 4ee167b2fb4..4ee167b2fb4 100644
--- a/source/blender/opencl/OCL_opencl.h
+++ b/intern/opencl/OCL_opencl.h
diff --git a/intern/opencl/SConscript b/intern/opencl/SConscript
new file mode 100644
index 00000000000..41a6d720098
--- /dev/null
+++ b/intern/opencl/SConscript
@@ -0,0 +1,34 @@
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+Import ('env')
+
+sources = env.Glob('intern/*.c')
+
+incs = '.'
+
+env.BlenderLib ( 'bf_intern_opencl', sources, Split(incs), libtype=['core','player'], priority = [192,192] )
diff --git a/source/blender/opencl/intern/OCL_opencl.c b/intern/opencl/intern/OCL_opencl.c
index e3130e16bde..e3130e16bde 100644
--- a/source/blender/opencl/intern/OCL_opencl.c
+++ b/intern/opencl/intern/OCL_opencl.c
diff --git a/source/blender/opencl/intern/clew.c b/intern/opencl/intern/clew.c
index d68eb17288f..d68eb17288f 100644
--- a/source/blender/opencl/intern/clew.c
+++ b/intern/opencl/intern/clew.c
diff --git a/source/blender/opencl/intern/clew.h b/intern/opencl/intern/clew.h
index bb7e0134dcf..bb7e0134dcf 100644
--- a/source/blender/opencl/intern/clew.h
+++ b/intern/opencl/intern/clew.h
diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript
index a4d21f3e440..6e7c467f64f 100644
--- a/intern/opencolorio/SConscript
+++ b/intern/opencolorio/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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) 2012, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Sergey Sharybin.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 44c02d1442b..d01d8d4c8f4 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -331,7 +331,7 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *)
}
OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription");
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index 18fa4b7cb1b..4f839a61fad 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -238,12 +238,12 @@ void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
}
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
}
-void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
+void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
{
impl->OCIO_PackedImageDescRelease(id);
}
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 0ce5f8a1456..19fd8fe643b 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -105,9 +105,9 @@ void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_Const
void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes);
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes);
-void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
+void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void);
void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index 2d73d2ff56b..b073a038f0d 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -479,7 +479,7 @@ void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
}
OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
try {
void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__);
diff --git a/intern/opennl/SConscript b/intern/opennl/SConscript
index a0f02735748..f47dd560779 100644
--- a/intern/opennl/SConscript
+++ b/intern/opennl/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c') + env.Glob('superlu/*.c')
diff --git a/intern/raskter/SConscript b/intern/raskter/SConscript
index 7ad505d70e4..c7bf647b0e2 100644
--- a/intern/raskter/SConscript
+++ b/intern/raskter/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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) 2012, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Peter Larabell
+#
+# ***** END GPL LICENSE BLOCK *****
Import ('env')
diff --git a/source/gameengine/Physics/common/CMakeLists.txt b/intern/rigidbody/CMakeLists.txt
index 400e475f8a2..a323e55e570 100644
--- a/source/gameengine/Physics/common/CMakeLists.txt
+++ b/intern/rigidbody/CMakeLists.txt
@@ -19,36 +19,17 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Jacques Beaurain.
-#
# ***** END GPL LICENSE BLOCK *****
-set(INC
+SET(INC
.
- ../Dummy
-)
-
-set(INC_SYS
-
+ ../../extern/bullet2/src
)
set(SRC
- PHY_IMotionState.cpp
- PHY_IController.cpp
- PHY_IPhysicsController.cpp
- PHY_IGraphicController.cpp
- PHY_IPhysicsEnvironment.cpp
- PHY_IVehicle.cpp
-
- PHY_DynamicTypes.h
- PHY_ICharacter.h
- PHY_IController.h
- PHY_IGraphicController.h
- PHY_IMotionState.h
- PHY_IPhysicsController.h
- PHY_IPhysicsEnvironment.h
- PHY_IVehicle.h
- PHY_Pro.h
+ rb_bullet_api.cpp
+
+ RBI_api.h
)
-blender_add_lib(ge_phys_common "${SRC}" "${INC}" "${INC_SYS}")
+blender_add_lib(bf_intern_rigidbody "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
new file mode 100644
index 00000000000..e7c88d96873
--- /dev/null
+++ b/intern/rigidbody/RBI_api.h
@@ -0,0 +1,315 @@
+/*
+ * ***** 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) 2013 Blender Foundation,
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file RBI_api.h
+ * \ingroup RigidBody
+ * \brief Rigid Body API for interfacing with external Physics Engines
+ */
+
+#ifndef __RB_API_H__
+#define __RB_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API Notes:
+ * Currently, this API is optimised for Bullet RigidBodies, and doesn't
+ * take into account other Physics Engines. Some tweaking may be necessary
+ * to allow other systems to be used, in particular there may be references
+ * to datatypes that aren't used here...
+ *
+ * -- Joshua Leung (22 June 2010)
+ */
+
+/* ********************************** */
+/* Partial Type Defines - Aliases for the type of data we store */
+
+// ----------
+
+/* Dynamics World */
+typedef struct rbDynamicsWorld rbDynamicsWorld;
+
+/* Rigid Body */
+typedef struct rbRigidBody rbRigidBody;
+
+/* Collision Shape */
+typedef struct rbCollisionShape rbCollisionShape;
+
+/* Mesh Data (for Collision Shapes of Meshes) */
+typedef struct rbMeshData rbMeshData;
+
+/* Constraint */
+typedef struct rbConstraint rbConstraint;
+
+/* ********************************** */
+/* Dynamics World Methods */
+
+/* Setup ---------------------------- */
+
+/* Create a new dynamics world instance */
+// TODO: add args to set the type of constraint solvers, etc.
+extern rbDynamicsWorld *RB_dworld_new(const float gravity[3]);
+
+/* Delete the given dynamics world, and free any extra data it may require */
+extern void RB_dworld_delete(rbDynamicsWorld *world);
+
+/* Settings ------------------------- */
+
+/* Gravity */
+extern void RB_dworld_get_gravity(rbDynamicsWorld *world, float g_out[3]);
+extern void RB_dworld_set_gravity(rbDynamicsWorld *world, const float g_in[3]);
+
+/* Constraint Solver */
+extern void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iterations);
+/* Split Impulse */
+extern void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse);
+
+/* Simulation ----------------------- */
+
+/* Step the simulation by the desired amount (in seconds) with extra controls on substep sizes and maximum substeps */
+extern void RB_dworld_step_simulation(rbDynamicsWorld *world, float timeStep, int maxSubSteps, float timeSubStep);
+
+/* Export -------------------------- */
+
+/* Exports the dynamics world to physics simulator's serialisation format */
+void RB_dworld_export(rbDynamicsWorld *world, const char *filename);
+
+/* ********************************** */
+/* Rigid Body Methods */
+
+/* Setup ---------------------------- */
+
+/* Add RigidBody to dynamics world */
+extern void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *body, int col_groups);
+
+/* Remove RigidBody from dynamics world */
+extern void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *body);
+
+/* ............ */
+
+/* Create new RigidBody instance */
+extern rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4]);
+
+/* Delete the given RigidBody instance */
+extern void RB_body_delete(rbRigidBody *body);
+
+/* Settings ------------------------- */
+
+/* 'Type' */
+extern void RB_body_set_type(rbRigidBody *body, int type, float mass);
+
+/* ............ */
+
+/* Collision Shape */
+extern void RB_body_set_collision_shape(rbRigidBody *body, rbCollisionShape *shape);
+
+/* ............ */
+
+/* Mass */
+extern float RB_body_get_mass(rbRigidBody *body);
+extern void RB_body_set_mass(rbRigidBody *body, float value);
+
+/* Friction */
+extern float RB_body_get_friction(rbRigidBody *body);
+extern void RB_body_set_friction(rbRigidBody *body, float value);
+
+/* Restitution */
+extern float RB_body_get_restitution(rbRigidBody *body);
+extern void RB_body_set_restitution(rbRigidBody *body, float value);
+
+/* Damping */
+extern float RB_body_get_linear_damping(rbRigidBody *body);
+extern void RB_body_set_linear_damping(rbRigidBody *body, float value);
+
+extern float RB_body_get_angular_damping(rbRigidBody *body);
+extern void RB_body_set_angular_damping(rbRigidBody *body, float value);
+
+extern void RB_body_set_damping(rbRigidBody *object, float linear, float angular);
+
+/* Sleeping Thresholds */
+extern float RB_body_get_linear_sleep_thresh(rbRigidBody *body);
+extern void RB_body_set_linear_sleep_thresh(rbRigidBody *body, float value);
+
+extern float RB_body_get_angular_sleep_thresh(rbRigidBody *body);
+extern void RB_body_set_angular_sleep_thresh(rbRigidBody *body, float value);
+
+extern void RB_body_set_sleep_thresh(rbRigidBody *body, float linear, float angular);
+
+/* Linear Velocity */
+extern void RB_body_get_linear_velocity(rbRigidBody *body, float v_out[3]);
+extern void RB_body_set_linear_velocity(rbRigidBody *body, const float v_in[3]);
+
+/* Angular Velocity */
+extern void RB_body_get_angular_velocity(rbRigidBody *body, float v_out[3]);
+extern void RB_body_set_angular_velocity(rbRigidBody *body, const float v_in[3]);
+
+/* Linear/Angular Factor, used to lock translation/roation axes */
+extern void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z);
+extern void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z);
+
+/* Kinematic State */
+extern void RB_body_set_kinematic_state(rbRigidBody *body, int kinematic);
+
+/* RigidBody Interface - Rigid Body Activation States */
+extern int RB_body_get_activation_state(rbRigidBody *body);
+extern void RB_body_set_activation_state(rbRigidBody *body, int use_deactivation);
+extern void RB_body_activate(rbRigidBody *body);
+extern void RB_body_deactivate(rbRigidBody *body);
+
+
+/* Simulation ----------------------- */
+
+/* Get current transform matrix of RigidBody to use in Blender (OpenGL format) */
+extern void RB_body_get_transform_matrix(rbRigidBody *body, float m_out[4][4]);
+
+/* Set RigidBody's location and rotation */
+extern void RB_body_set_loc_rot(rbRigidBody *body, const float loc[3], const float rot[4]);
+/* Set RigidBody's local scaling */
+extern void RB_body_set_scale(rbRigidBody *body, const float scale[3]);
+
+/* ............ */
+
+/* Get RigidBody's position as vector */
+void RB_body_get_position(rbRigidBody *body, float v_out[3]);
+/* Get RigidBody's orientation as quaternion */
+void RB_body_get_orientation(rbRigidBody *body, float v_out[4]);
+
+/* ............ */
+
+extern void RB_body_apply_central_force(rbRigidBody *body, const float v_in[3]);
+
+/* ********************************** */
+/* Collision Shape Methods */
+
+/* Setup (Standard Shapes) ----------- */
+
+extern rbCollisionShape *RB_shape_new_box(float x, float y, float z);
+extern rbCollisionShape *RB_shape_new_sphere(float radius);
+extern rbCollisionShape *RB_shape_new_capsule(float radius, float height);
+extern rbCollisionShape *RB_shape_new_cone(float radius, float height);
+extern rbCollisionShape *RB_shape_new_cylinder(float radius, float height);
+
+/* Setup (Convex Hull) ------------ */
+
+extern rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed);
+
+/* Setup (Triangle Mesh) ---------- */
+
+/* 1 */
+extern rbMeshData *RB_trimesh_data_new(void);
+extern void RB_trimesh_add_triangle(rbMeshData *mesh, const float v1[3], const float v2[3], const float v3[3]);
+/* 2a - Triangle Meshes */
+extern rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh);
+/* 2b - GImpact Meshes */
+extern rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh);
+
+
+/* Cleanup --------------------------- */
+
+extern void RB_shape_delete(rbCollisionShape *shape);
+
+/* Settings --------------------------- */
+
+/* Collision Margin */
+extern float RB_shape_get_margin(rbCollisionShape *shape);
+extern void RB_shape_set_margin(rbCollisionShape *shape, float value);
+
+/* ********************************** */
+/* Constraints */
+
+/* Setup ----------------------------- */
+
+/* Add Rigid Body Constraint to simulation world */
+extern void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int disable_collisions);
+
+/* Remove Rigid Body Constraint from simulation world */
+extern void RB_dworld_remove_constraint(rbDynamicsWorld *world, rbConstraint *con);
+
+extern rbConstraint *RB_constraint_new_point(float pivot[3], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_fixed(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_hinge(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+
+/* ............ */
+
+/* Cleanup --------------------------- */
+
+extern void RB_constraint_delete(rbConstraint *con);
+
+/* Settings --------------------------- */
+
+/* Enable or disable constraint */
+extern void RB_constraint_set_enabled(rbConstraint *con, int enabled);
+
+/* Limits */
+#define RB_LIMIT_LIN_X 0
+#define RB_LIMIT_LIN_Y 1
+#define RB_LIMIT_LIN_Z 2
+#define RB_LIMIT_ANG_X 3
+#define RB_LIMIT_ANG_Y 4
+#define RB_LIMIT_ANG_Z 5
+/* Bullet uses the following convention:
+ * - lower limit == upper limit -> axis is locked
+ * - lower limit > upper limit -> axis is free
+ * - lower limit < upper limit -> axis is limited in given range
+ */
+extern void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper);
+extern void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper);
+extern void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper);
+extern void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper);
+
+/* 6dof spring specific */
+extern void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness);
+extern void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping);
+extern void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable);
+extern void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con);
+
+/* motors */
+extern void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang);
+extern void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang);
+extern void RB_constraint_set_target_velocity_motor(rbConstraint *con, float velocity_lin, float velocity_ang);
+
+/* Set number of constraint solver iterations made per step, this overrided world setting
+ * To use default set it to -1 */
+extern void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations);
+
+/* Set breaking impulse threshold, if constraint shouldn't break it can be set to FLT_MAX */
+extern void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold);
+
+/* ********************************** */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RB_API_H__ */
+
diff --git a/intern/rigidbody/SConscript b/intern/rigidbody/SConscript
new file mode 100644
index 00000000000..977281f8eef
--- /dev/null
+++ b/intern/rigidbody/SConscript
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+# $Id: SConscript $
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2010, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Joshua Leung
+#
+# ***** END GPL LICENSE BLOCK *****
+
+Import('env')
+
+# XXX: we need a contingency plan for when not compiling with Bullet,
+# since this module will always get included...
+# This problem will also apply to other engines at a later date too...
+sources = env.Glob('*.cpp')
+
+incs = [
+ '.',
+ '../../extern/bullet2/src',
+ ]
+
+env.BlenderLib('bf_intern_rigidbody', sources=sources,
+ includes=incs, defines=[],
+ libtype=['core', 'player'], priority=[180, 30])
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
new file mode 100644
index 00000000000..a628c35218c
--- /dev/null
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -0,0 +1,995 @@
+/*
+ * ***** 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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file rb_bullet_api.cpp
+ * \ingroup RigidBody
+ * \brief Rigid Body API implementation for Bullet
+ */
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* This file defines the "RigidBody interface" for the
+ * Bullet Physics Engine. This API is designed to be used
+ * from C-code in Blender as part of the Rigid Body simulation
+ * system.
+ *
+ * It is based on the Bullet C-API, but is heavily modified to
+ * give access to more data types and to offer a nicer interface.
+ *
+ * -- Joshua Leung, June 2010
+ */
+
+#include <stdio.h>
+
+#include "RBI_api.h"
+
+#include "btBulletDynamicsCommon.h"
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btScalar.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btConvexHullComputer.h"
+
+#include "BulletCollision/Gimpact/btGImpactShape.h"
+#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
+#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
+
+struct rbDynamicsWorld {
+ btDiscreteDynamicsWorld *dynamicsWorld;
+ btDefaultCollisionConfiguration *collisionConfiguration;
+ btDispatcher *dispatcher;
+ btBroadphaseInterface *pairCache;
+ btConstraintSolver *constraintSolver;
+ btOverlapFilterCallback *filterCallback;
+};
+struct rbRigidBody {
+ btRigidBody *body;
+ int col_groups;
+};
+
+struct rbCollisionShape {
+ btCollisionShape *cshape;
+ btTriangleMesh *mesh;
+};
+
+struct rbFilterCallback : public btOverlapFilterCallback
+{
+ virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
+ {
+ rbRigidBody *rb0 = (rbRigidBody *)((btRigidBody *)proxy0->m_clientObject)->getUserPointer();
+ rbRigidBody *rb1 = (rbRigidBody *)((btRigidBody *)proxy1->m_clientObject)->getUserPointer();
+
+ bool collides;
+ collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+ collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+ collides = collides && (rb0->col_groups & rb1->col_groups);
+
+ return collides;
+ }
+};
+
+static inline void copy_v3_btvec3(float vec[3], const btVector3 &btvec)
+{
+ vec[0] = (float)btvec[0];
+ vec[1] = (float)btvec[1];
+ vec[2] = (float)btvec[2];
+}
+static inline void copy_quat_btquat(float quat[3], const btQuaternion &btquat)
+{
+ quat[0] = btquat.getW();
+ quat[1] = btquat.getX();
+ quat[2] = btquat.getY();
+ quat[3] = btquat.getZ();
+}
+
+/* ********************************** */
+/* Dynamics World Methods */
+
+/* Setup ---------------------------- */
+
+rbDynamicsWorld *RB_dworld_new(const float gravity[3])
+{
+ rbDynamicsWorld *world = new rbDynamicsWorld;
+
+ /* collision detection/handling */
+ world->collisionConfiguration = new btDefaultCollisionConfiguration();
+
+ world->dispatcher = new btCollisionDispatcher(world->collisionConfiguration);
+ btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher *)world->dispatcher); // XXX: experimental
+
+ world->pairCache = new btDbvtBroadphase();
+
+ world->filterCallback = new rbFilterCallback();
+ world->pairCache->getOverlappingPairCache()->setOverlapFilterCallback(world->filterCallback);
+
+ /* constraint solving */
+ world->constraintSolver = new btSequentialImpulseConstraintSolver();
+
+ /* world */
+ world->dynamicsWorld = new btDiscreteDynamicsWorld(world->dispatcher,
+ world->pairCache,
+ world->constraintSolver,
+ world->collisionConfiguration);
+
+ RB_dworld_set_gravity(world, gravity);
+
+ return world;
+}
+
+void RB_dworld_delete(rbDynamicsWorld *world)
+{
+ /* bullet doesn't like if we free these in a different order */
+ delete world->dynamicsWorld;
+ delete world->constraintSolver;
+ delete world->pairCache;
+ delete world->dispatcher;
+ delete world->collisionConfiguration;
+ delete world->filterCallback;
+ delete world;
+}
+
+/* Settings ------------------------- */
+
+/* Gravity */
+void RB_dworld_get_gravity(rbDynamicsWorld *world, float g_out[3])
+{
+ copy_v3_btvec3(g_out, world->dynamicsWorld->getGravity());
+}
+
+void RB_dworld_set_gravity(rbDynamicsWorld *world, const float g_in[3])
+{
+ world->dynamicsWorld->setGravity(btVector3(g_in[0], g_in[1], g_in[2]));
+}
+
+/* Constraint Solver */
+void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iterations)
+{
+ btContactSolverInfo& info = world->dynamicsWorld->getSolverInfo();
+
+ info.m_numIterations = num_solver_iterations;
+}
+
+/* Split Impulse */
+void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
+{
+ btContactSolverInfo& info = world->dynamicsWorld->getSolverInfo();
+
+ info.m_splitImpulse = split_impulse;
+}
+
+/* Simulation ----------------------- */
+
+void RB_dworld_step_simulation(rbDynamicsWorld *world, float timeStep, int maxSubSteps, float timeSubStep)
+{
+ world->dynamicsWorld->stepSimulation(timeStep, maxSubSteps, timeSubStep);
+}
+
+/* Export -------------------------- */
+
+/* Exports entire dynamics world to Bullet's "*.bullet" binary format
+ * which is similar to Blender's SDNA system...
+ * < rbDynamicsWorld: dynamics world to write to file
+ * < filename: assumed to be a valid filename, with .bullet extension
+ */
+void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
+{
+ //create a large enough buffer. There is no method to pre-calculate the buffer size yet.
+ int maxSerializeBufferSize = 1024 * 1024 * 5;
+
+ btDefaultSerializer *serializer = new btDefaultSerializer(maxSerializeBufferSize);
+ world->dynamicsWorld->serialize(serializer);
+
+ FILE *file = fopen(filename, "wb");
+ fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
+ fclose(file);
+}
+
+/* ********************************** */
+/* Rigid Body Methods */
+
+/* Setup ---------------------------- */
+
+void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
+{
+ btRigidBody *body = object->body;
+ object->col_groups = col_groups;
+
+ world->dynamicsWorld->addRigidBody(body);
+}
+
+void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+
+ world->dynamicsWorld->removeRigidBody(body);
+}
+
+/* ............ */
+
+rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
+{
+ rbRigidBody *object = new rbRigidBody;
+ /* current transform */
+ btTransform trans;
+ trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
+ trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+
+ /* create motionstate, which is necessary for interpolation (includes reverse playback) */
+ btDefaultMotionState *motionState = new btDefaultMotionState(trans);
+
+ /* make rigidbody */
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
+
+ object->body = new btRigidBody(rbInfo);
+
+ object->body->setUserPointer(object);
+
+ return object;
+}
+
+void RB_body_delete(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+
+ /* motion state */
+ btMotionState *ms = body->getMotionState();
+ if (ms)
+ delete ms;
+
+ /* collision shape is done elsewhere... */
+
+ /* body itself */
+
+ /* manually remove constraint refs of the rigid body, normally this happens when removing constraints from the world
+ * but since we delete everything when the world is rebult, we need to do it manually here */
+ for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
+ btTypedConstraint *con = body->getConstraintRef(i);
+ body->removeConstraintRef(con);
+ }
+
+ delete body;
+ delete object;
+}
+
+/* Settings ------------------------- */
+
+void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
+{
+ btRigidBody *body = object->body;
+
+ /* set new collision shape */
+ body->setCollisionShape(shape->cshape);
+
+ /* recalculate inertia, since that depends on the collision shape... */
+ RB_body_set_mass(object, RB_body_get_mass(object));
+}
+
+/* ............ */
+
+float RB_body_get_mass(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+
+ /* there isn't really a mass setting, but rather 'inverse mass'
+ * which we convert back to mass by taking the reciprocal again
+ */
+ float value = (float)body->getInvMass();
+
+ if (value)
+ value = 1.0 / value;
+
+ return value;
+}
+
+void RB_body_set_mass(rbRigidBody *object, float value)
+{
+ btRigidBody *body = object->body;
+ btVector3 localInertia(0, 0, 0);
+
+ /* calculate new inertia if non-zero mass */
+ if (value) {
+ btCollisionShape *shape = body->getCollisionShape();
+ shape->calculateLocalInertia(value, localInertia);
+ }
+
+ body->setMassProps(value, localInertia);
+ body->updateInertiaTensor();
+}
+
+
+float RB_body_get_friction(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ return body->getFriction();
+}
+
+void RB_body_set_friction(rbRigidBody *object, float value)
+{
+ btRigidBody *body = object->body;
+ body->setFriction(value);
+}
+
+
+float RB_body_get_restitution(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ return body->getRestitution();
+}
+
+void RB_body_set_restitution(rbRigidBody *object, float value)
+{
+ btRigidBody *body = object->body;
+ body->setRestitution(value);
+}
+
+
+float RB_body_get_linear_damping(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ return body->getLinearDamping();
+}
+
+void RB_body_set_linear_damping(rbRigidBody *object, float value)
+{
+ RB_body_set_damping(object, value, RB_body_get_linear_damping(object));
+}
+
+float RB_body_get_angular_damping(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ return body->getAngularDamping();
+}
+
+void RB_body_set_angular_damping(rbRigidBody *object, float value)
+{
+ RB_body_set_damping(object, RB_body_get_linear_damping(object), value);
+}
+
+void RB_body_set_damping(rbRigidBody *object, float linear, float angular)
+{
+ btRigidBody *body = object->body;
+ body->setDamping(linear, angular);
+}
+
+
+float RB_body_get_linear_sleep_thresh(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ return body->getLinearSleepingThreshold();
+}
+
+void RB_body_set_linear_sleep_thresh(rbRigidBody *object, float value)
+{
+ RB_body_set_sleep_thresh(object, value, RB_body_get_angular_sleep_thresh(object));
+}
+
+float RB_body_get_angular_sleep_thresh(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ return body->getAngularSleepingThreshold();
+}
+
+void RB_body_set_angular_sleep_thresh(rbRigidBody *object, float value)
+{
+ RB_body_set_sleep_thresh(object, RB_body_get_linear_sleep_thresh(object), value);
+}
+
+void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
+{
+ btRigidBody *body = object->body;
+ body->setSleepingThresholds(linear, angular);
+}
+
+/* ............ */
+
+void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
+{
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getLinearVelocity());
+}
+
+void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3])
+{
+ btRigidBody *body = object->body;
+
+ body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
+}
+
+
+void RB_body_get_angular_velocity(rbRigidBody *object, float v_out[3])
+{
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getAngularVelocity());
+}
+
+void RB_body_set_angular_velocity(rbRigidBody *object, const float v_in[3])
+{
+ btRigidBody *body = object->body;
+
+ body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
+}
+
+void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z)
+{
+ btRigidBody *body = object->body;
+ body->setLinearFactor(btVector3(x, y, z));
+}
+
+void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
+{
+ btRigidBody *body = object->body;
+ body->setAngularFactor(btVector3(x, y, z));
+}
+
+/* ............ */
+
+void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
+{
+ btRigidBody *body = object->body;
+ if (kinematic)
+ body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ else
+ body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
+}
+
+/* ............ */
+
+void RB_body_set_activation_state(rbRigidBody *object, int use_deactivation)
+{
+ btRigidBody *body = object->body;
+ if (use_deactivation)
+ body->forceActivationState(ACTIVE_TAG);
+ else
+ body->setActivationState(DISABLE_DEACTIVATION);
+}
+void RB_body_activate(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ body->setActivationState(ACTIVE_TAG);
+}
+void RB_body_deactivate(rbRigidBody *object)
+{
+ btRigidBody *body = object->body;
+ body->setActivationState(ISLAND_SLEEPING);
+}
+
+/* ............ */
+
+
+
+/* Simulation ----------------------- */
+
+/* The transform matrices Blender uses are OpenGL-style matrices,
+ * while Bullet uses the Right-Handed coordinate system style instead.
+ */
+
+void RB_body_get_transform_matrix(rbRigidBody *object, float m_out[4][4])
+{
+ btRigidBody *body = object->body;
+ btMotionState *ms = body->getMotionState();
+
+ btTransform trans;
+ ms->getWorldTransform(trans);
+
+ trans.getOpenGLMatrix((btScalar *)m_out);
+}
+
+void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float rot[4])
+{
+ btRigidBody *body = object->body;
+ btMotionState *ms = body->getMotionState();
+
+ /* set transform matrix */
+ btTransform trans;
+ trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
+ trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+
+ ms->setWorldTransform(trans);
+}
+
+void RB_body_set_scale(rbRigidBody *object, const float scale[3])
+{
+ btRigidBody *body = object->body;
+
+ /* apply scaling factor from matrix above to the collision shape */
+ btCollisionShape *cshape = body->getCollisionShape();
+ if (cshape) {
+ cshape->setLocalScaling(btVector3(scale[0], scale[1], scale[2]));
+
+ /* GIimpact shapes have to be updated to take scaling into account */
+ if (cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
+ ((btGImpactMeshShape *)cshape)->updateBound();
+ }
+}
+
+/* ............ */
+/* Read-only state info about status of simulation */
+
+void RB_body_get_position(rbRigidBody *object, float v_out[3])
+{
+ btRigidBody *body = object->body;
+
+ copy_v3_btvec3(v_out, body->getWorldTransform().getOrigin());
+}
+
+void RB_body_get_orientation(rbRigidBody *object, float v_out[4])
+{
+ btRigidBody *body = object->body;
+
+ copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
+}
+
+/* ............ */
+/* Overrides for simulation */
+
+void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
+{
+ btRigidBody *body = object->body;
+
+ body->applyCentralForce(btVector3(v_in[0], v_in[1], v_in[2]));
+}
+
+/* ********************************** */
+/* Collision Shape Methods */
+
+/* Setup (Standard Shapes) ----------- */
+
+rbCollisionShape *RB_shape_new_box(float x, float y, float z)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btBoxShape(btVector3(x, y, z));
+ shape->mesh = NULL;
+ return shape;
+}
+
+rbCollisionShape *RB_shape_new_sphere(float radius)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btSphereShape(radius);
+ shape->mesh = NULL;
+ return shape;
+}
+
+rbCollisionShape *RB_shape_new_capsule(float radius, float height)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btCapsuleShapeZ(radius, height);
+ shape->mesh = NULL;
+ return shape;
+}
+
+rbCollisionShape *RB_shape_new_cone(float radius, float height)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btConeShapeZ(radius, height);
+ shape->mesh = NULL;
+ return shape;
+}
+
+rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
+ shape->mesh = NULL;
+ return shape;
+}
+
+/* Setup (Convex Hull) ------------ */
+
+rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed)
+{
+ btConvexHullComputer hull_computer = btConvexHullComputer();
+
+ // try to embed the margin, if that fails don't shrink the hull
+ if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
+ hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
+ *can_embed = false;
+ }
+
+ rbCollisionShape *shape = new rbCollisionShape;
+ btConvexHullShape *hull_shape = new btConvexHullShape(&(hull_computer.vertices[0].getX()), hull_computer.vertices.size());
+
+ shape->cshape = hull_shape;
+ shape->mesh = NULL;
+ return shape;
+}
+
+/* Setup (Triangle Mesh) ---------- */
+
+/* Need to call rbTriMeshNewData() followed by rbTriMeshAddTriangle() several times
+ * to set up the mesh buffer BEFORE calling rbShapeNewTriMesh(). Otherwise,
+ * we get nasty crashes...
+ */
+
+rbMeshData *RB_trimesh_data_new()
+{
+ // XXX: welding threshold?
+ return (rbMeshData *) new btTriangleMesh(true, false);
+}
+
+void RB_trimesh_add_triangle(rbMeshData *mesh, const float v1[3], const float v2[3], const float v3[3])
+{
+ btTriangleMesh *meshData = reinterpret_cast<btTriangleMesh*>(mesh);
+
+ /* cast vertices to usable forms for Bt-API */
+ btVector3 vtx1((btScalar)v1[0], (btScalar)v1[1], (btScalar)v1[2]);
+ btVector3 vtx2((btScalar)v2[0], (btScalar)v2[1], (btScalar)v2[2]);
+ btVector3 vtx3((btScalar)v3[0], (btScalar)v3[1], (btScalar)v3[2]);
+
+ /* add to the mesh
+ * - remove duplicated verts is enabled
+ */
+ meshData->addTriangle(vtx1, vtx2, vtx3, false);
+}
+
+rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ btTriangleMesh *tmesh = reinterpret_cast<btTriangleMesh*>(mesh);
+
+ /* triangle-mesh we create is a BVH wrapper for triangle mesh data (for faster lookups) */
+ // RB_TODO perhaps we need to allow saving out this for performance when rebuilding?
+ btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(tmesh, true, true);
+
+ shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
+ shape->mesh = tmesh;
+ return shape;
+}
+
+rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ /* interpret mesh buffer as btTriangleIndexVertexArray (i.e. an impl of btStridingMeshInterface) */
+ btTriangleMesh *tmesh = reinterpret_cast<btTriangleMesh*>(mesh);
+
+ btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(tmesh);
+ gimpactShape->updateBound(); // TODO: add this to the update collision margin call?
+
+ shape->cshape = gimpactShape;
+ shape->mesh = tmesh;
+ return shape;
+}
+
+/* Cleanup --------------------------- */
+
+void RB_shape_delete(rbCollisionShape *shape)
+{
+ if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
+ btBvhTriangleMeshShape *child_shape = ((btScaledBvhTriangleMeshShape *)shape->cshape)->getChildShape();
+ if (child_shape)
+ delete child_shape;
+ }
+ if (shape->mesh)
+ delete shape->mesh;
+ delete shape->cshape;
+ delete shape;
+}
+
+/* Settings --------------------------- */
+
+float RB_shape_get_margin(rbCollisionShape *shape)
+{
+ return shape->cshape->getMargin();
+}
+
+void RB_shape_set_margin(rbCollisionShape *shape, float value)
+{
+ shape->cshape->setMargin(value);
+}
+
+/* ********************************** */
+/* Constraints */
+
+/* Setup ----------------------------- */
+
+void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int disable_collisions)
+{
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
+
+ world->dynamicsWorld->addConstraint(constraint, disable_collisions);
+}
+
+void RB_dworld_remove_constraint(rbDynamicsWorld *world, rbConstraint *con)
+{
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
+
+ world->dynamicsWorld->removeConstraint(constraint);
+}
+
+/* ............ */
+
+static void make_constraint_transforms(btTransform &transform1, btTransform &transform2, btRigidBody *body1, btRigidBody *body2, float pivot[3], float orn[4])
+{
+ btTransform pivot_transform = btTransform();
+ pivot_transform.setOrigin(btVector3(pivot[0], pivot[1], pivot[2]));
+ pivot_transform.setRotation(btQuaternion(orn[1], orn[2], orn[3], orn[0]));
+
+ transform1 = body1->getWorldTransform().inverse() * pivot_transform;
+ transform2 = body2->getWorldTransform().inverse() * pivot_transform;
+}
+
+rbConstraint *RB_constraint_new_point(float pivot[3], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+
+ btVector3 pivot1 = body1->getWorldTransform().inverse() * btVector3(pivot[0], pivot[1], pivot[2]);
+ btVector3 pivot2 = body2->getWorldTransform().inverse() * btVector3(pivot[0], pivot[1], pivot[2]);
+
+ btTypedConstraint *con = new btPoint2PointConstraint(*body1, *body2, pivot1, pivot2);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_fixed(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btGeneric6DofConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
+
+ /* lock all axes */
+ for (int i = 0; i < 6; i++)
+ con->setLimit(i, 0, 0);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_hinge(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btHingeConstraint *con = new btHingeConstraint(*body1, *body2, transform1, transform2);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
+ con->setUpperAngLimit(-1.0f); // unlock rotation axis
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btTypedConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btTypedConstraint *con = new btGeneric6DofSpringConstraint(*body1, *body2, transform1, transform2, true);
+
+ return (rbConstraint *)con;
+}
+
+rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btGeneric6DofConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
+
+ /* unlock constraint axes */
+ for (int i = 0; i < 6; i++) {
+ con->setLimit(i, 0.0f, -1.0f);
+ }
+ /* unlock motor axes */
+ con->getTranslationalLimitMotor()->m_upperLimit.setValue(-1.0f, -1.0f, -1.0f);
+
+ return (rbConstraint*)con;
+}
+
+/* Cleanup ----------------------------- */
+
+void RB_constraint_delete(rbConstraint *con)
+{
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
+ delete constraint;
+}
+
+/* Settings ------------------------- */
+
+void RB_constraint_set_enabled(rbConstraint *con, int enabled)
+{
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
+
+ constraint->setEnabled(enabled);
+}
+
+void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper)
+{
+ btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint*>(con);
+
+ // RB_TODO expose these
+ float softness = 0.9f;
+ float bias_factor = 0.3f;
+ float relaxation_factor = 1.0f;
+
+ constraint->setLimit(lower, upper, softness, bias_factor, relaxation_factor);
+}
+
+void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper)
+{
+ btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint*>(con);
+
+ constraint->setLowerLinLimit(lower);
+ constraint->setUpperLinLimit(upper);
+}
+
+void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper)
+{
+ btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint*>(con);
+
+ constraint->setLowerLinLimit(lin_lower);
+ constraint->setUpperLinLimit(lin_upper);
+ constraint->setLowerAngLimit(ang_lower);
+ constraint->setUpperAngLimit(ang_upper);
+}
+
+void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper)
+{
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
+
+ constraint->setLimit(axis, lower, upper);
+}
+
+void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
+{
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+ constraint->setStiffness(axis, stiffness);
+}
+
+void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
+{
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+ // invert damping range so that 0 = no damping
+ constraint->setDamping(axis, 1.0f - damping);
+}
+
+void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable)
+{
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+ constraint->enableSpring(axis, enable);
+}
+
+void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
+{
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+ constraint->setEquilibriumPoint();
+}
+
+void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations)
+{
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
+
+ constraint->setOverrideNumSolverIterations(num_solver_iterations);
+}
+
+void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold)
+{
+ btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
+
+ constraint->setBreakingImpulseThreshold(threshold);
+}
+
+void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang)
+{
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
+
+ constraint->getTranslationalLimitMotor()->m_enableMotor[0] = enable_lin;
+ constraint->getRotationalLimitMotor(0)->m_enableMotor = enable_ang;
+}
+
+void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang)
+{
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
+
+ constraint->getTranslationalLimitMotor()->m_maxMotorForce.setX(max_impulse_lin);
+ constraint->getRotationalLimitMotor(0)->m_maxMotorForce = max_impulse_ang;
+}
+
+void RB_constraint_set_target_velocity_motor(rbConstraint *con, float velocity_lin, float velocity_ang)
+{
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
+
+ constraint->getTranslationalLimitMotor()->m_targetVelocity.setX(velocity_lin);
+ constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
+}
+
+/* ********************************** */
diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt
index 3b8a4c06e69..b6338f90ebc 100644
--- a/intern/smoke/CMakeLists.txt
+++ b/intern/smoke/CMakeLists.txt
@@ -29,7 +29,7 @@ set(INC
)
set(INC_SYS
- ../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
${PNG_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
)
diff --git a/intern/smoke/SConscript b/intern/smoke/SConscript
index 0511257d319..c4a579b22b3 100644
--- a/intern/smoke/SConscript
+++ b/intern/smoke/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Daniel Genrich
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/smoke/intern/FFT_NOISE.h b/intern/smoke/intern/FFT_NOISE.h
index 8b7e4f2728b..0d8be7db602 100644
--- a/intern/smoke/intern/FFT_NOISE.h
+++ b/intern/smoke/intern/FFT_NOISE.h
@@ -94,9 +94,9 @@ static void generatTile_FFT(float* const noiseTileData, std::string filename)
for (int x = 0; x < xRes; x++)
{
int index = x + y * xRes + z * xRes * yRes;
- float diff[] = {abs(x - xRes/2),
- abs(y - yRes/2),
- abs(z - zRes/2)};
+ float diff[] = {(float)abs(x - xRes / 2),
+ (float)abs(y - yRes / 2),
+ (float)abs(z - zRes / 2)};
float radius = sqrtf(diff[0] * diff[0] +
diff[1] * diff[1] +
diff[2] * diff[2]) / (xRes / 2);
diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp
index 4eb11a46f5b..5f0b2439200 100644
--- a/intern/smoke/intern/FLUID_3D.cpp
+++ b/intern/smoke/intern/FLUID_3D.cpp
@@ -1055,7 +1055,7 @@ void FLUID_3D::project()
for (x = 1; x < _xRes - 1; x++, index++)
{
float vMask[3] = {1.0f, 1.0f, 1.0f}, vObst[3] = {0, 0, 0};
- float vR = 0.0f, vL = 0.0f, vT = 0.0f, vB = 0.0f, vD = 0.0f, vU = 0.0f;
+ // float vR = 0.0f, vL = 0.0f, vT = 0.0f, vB = 0.0f, vD = 0.0f, vU = 0.0f; // UNUSED
float pC = _pressure[index]; // center
float pR = _pressure[index + 1]; // right
@@ -1654,7 +1654,7 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame
fuel[index] -= burning_rate * dt;
if (fuel[index] < 0.0f) fuel[index] = 0.0f;
/* process reaction coordinate */
- if (orig_fuel) {
+ if (orig_fuel > FLT_EPSILON) {
react[index] *= fuel[index]/orig_fuel;
react_coord = react[index];
}
@@ -1681,7 +1681,7 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame
heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max;
/* mix new color */
- if (r && smoke_emit) {
+ if (r && smoke_emit > FLT_EPSILON) {
float smoke_factor = smoke[index]/(orig_smoke+smoke_emit);
r[index] = (r[index] + _flame_smoke_color[0] * smoke_emit) * smoke_factor;
g[index] = (g[index] + _flame_smoke_color[1] * smoke_emit) * smoke_factor;
diff --git a/intern/smoke/intern/WAVELET_NOISE.h b/intern/smoke/intern/WAVELET_NOISE.h
index fce901b68aa..1b2fbfab58c 100644
--- a/intern/smoke/intern/WAVELET_NOISE.h
+++ b/intern/smoke/intern/WAVELET_NOISE.h
@@ -45,6 +45,8 @@
#include <MERSENNETWISTER.h>
+#include <string.h>
+
#ifdef WIN32
#include <float.h>
#define isnan _isnan
diff --git a/intern/string/SConscript b/intern/string/SConscript
index dac0ead8e61..8e14605b15d 100644
--- a/intern/string/SConscript
+++ b/intern/string/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/utfconv/SConscript b/intern/utfconv/SConscript
index 19a698b6a0b..875f6154d55 100644
--- a/intern/utfconv/SConscript
+++ b/intern/utfconv/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = ['utfconv.c']
diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c
index 18f0e808562..77209313926 100644
--- a/intern/utfconv/utf_winfunc.c
+++ b/intern/utfconv/utf_winfunc.c
@@ -29,7 +29,7 @@
#include "utf_winfunc.h"
#include <io.h>
-#include <Windows.h>
+#include <windows.h>
#include <wchar.h>
diff --git a/release/darwin/blender.app/Contents/Info.plist b/release/darwin/blender.app/Contents/Info.plist
index 064ffe5bc3f..ecea0e3ec76 100644
--- a/release/darwin/blender.app/Contents/Info.plist
+++ b/release/darwin/blender.app/Contents/Info.plist
@@ -50,5 +50,7 @@
</dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
</dict>
</plist>
diff --git a/release/darwin/blender.app/Contents/MacOS/blender b/release/darwin/blender.app/Contents/MacOS/blender
index 5e05e74a307..48cdce85287 100644
--- a/release/darwin/blender.app/Contents/MacOS/blender
+++ b/release/darwin/blender.app/Contents/MacOS/blender
@@ -1 +1 @@
-placeholder
+placeholder
diff --git a/release/darwin/blenderplayer.app/Contents/Info.plist b/release/darwin/blenderplayer.app/Contents/Info.plist
index c7b9ceb568e..91eb2d7e84d 100644
--- a/release/darwin/blenderplayer.app/Contents/Info.plist
+++ b/release/darwin/blenderplayer.app/Contents/Info.plist
@@ -45,5 +45,7 @@
</array>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
</dict>
</plist>
diff --git a/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
index 5e05e74a307..48cdce85287 100644
--- a/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
+++ b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
@@ -1 +1 @@
-placeholder
+placeholder
diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png
deleted file mode 100644
index b0d5e825738..00000000000
--- a/release/datafiles/blender_icons.png
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/blender_icons.sh b/release/datafiles/blender_icons.sh
new file mode 100755
index 00000000000..f923f02aee1
--- /dev/null
+++ b/release/datafiles/blender_icons.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# This script updates icons from the SVG file
+
+inkscape blender_icons.svg --export-dpi=90 --without-gui --export-png=blender_icons16.png
+inkscape blender_icons.svg --export-dpi=180 --without-gui --export-png=blender_icons32.png
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
new file mode 100644
index 00000000000..60c5ff92c55
--- /dev/null
+++ b/release/datafiles/blender_icons.svg
@@ -0,0 +1,84948 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="602"
+ height="640"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.2 r9819"
+ version="1.0"
+ sodipodi:docname="blender_icons.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ style="display:inline;enable-background:new"
+ inkscape:export-filename="blender_icons16.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <title
+ id="title49470">Blender icons v. 2.5.08</title>
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18134">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop18136" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop18138" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18118">
+ <stop
+ style="stop-color:#d297eb;stop-opacity:1;"
+ offset="0"
+ id="stop18120" />
+ <stop
+ style="stop-color:#a329d6;stop-opacity:1;"
+ offset="1"
+ id="stop18122" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18103">
+ <stop
+ id="stop18105"
+ offset="0"
+ style="stop-color:#42035d;stop-opacity:1" />
+ <stop
+ id="stop18108"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16367">
+ <stop
+ id="stop16369"
+ offset="0"
+ style="stop-color:#3c3c3c;stop-opacity:1" />
+ <stop
+ id="stop16371"
+ offset="1"
+ style="stop-color:#5a5a5a;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15806">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop15808" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1"
+ id="stop15810" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15796">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15798" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15800" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16595">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop16597" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop16599" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15647">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15649" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15651" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30139">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop30141" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop30143" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30131">
+ <stop
+ style="stop-color:#999999;stop-opacity:1;"
+ offset="0"
+ id="stop30133" />
+ <stop
+ style="stop-color:#999999;stop-opacity:0;"
+ offset="1"
+ id="stop30135" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30122">
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:1;"
+ offset="0"
+ id="stop30124" />
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:0;"
+ offset="1"
+ id="stop30127" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30390">
+ <stop
+ style="stop-color:#3d3d3d;stop-opacity:1"
+ offset="0"
+ id="stop30392" />
+ <stop
+ style="stop-color:#5d5d5d;stop-opacity:1"
+ offset="1"
+ id="stop30394" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29870">
+ <stop
+ id="stop29872"
+ offset="0"
+ style="stop-color:#989898;stop-opacity:1" />
+ <stop
+ id="stop29874"
+ offset="1"
+ style="stop-color:#3d3d3d;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29757">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29759" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29761" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16774" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16776" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16764">
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:1;"
+ offset="0"
+ id="stop16766" />
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:0;"
+ offset="1"
+ id="stop16768" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16723">
+ <stop
+ style="stop-color:#343434;stop-opacity:0.61960787;"
+ offset="0"
+ id="stop16725" />
+ <stop
+ style="stop-color:#3d3d3d;stop-opacity:1;"
+ offset="1"
+ id="stop16727" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient107519">
+ <stop
+ style="stop-color:#f8c5bd;stop-opacity:1"
+ offset="0"
+ id="stop107521" />
+ <stop
+ style="stop-color:#a42f0e;stop-opacity:1"
+ offset="1"
+ id="stop107523" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient107148">
+ <stop
+ id="stop107150"
+ offset="0"
+ style="stop-color:#ee7b68;stop-opacity:1" />
+ <stop
+ id="stop107152"
+ offset="1"
+ style="stop-color:#a42f0e;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient107142">
+ <stop
+ id="stop107144"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop107146"
+ offset="1"
+ style="stop-color:#f18d73;stop-opacity:0.2079646" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient106427">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop106429" />
+ <stop
+ style="stop-color:#030303;stop-opacity:1"
+ offset="1"
+ id="stop106431" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16504">
+ <stop
+ id="stop16506"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop16508"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17602">
+ <stop
+ id="stop17604"
+ offset="0"
+ style="stop-color:#592e00;stop-opacity:1" />
+ <stop
+ id="stop17606"
+ offset="1"
+ style="stop-color:#9e5200;stop-opacity:0.57431373" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17596">
+ <stop
+ style="stop-color:#ee7b00;stop-opacity:1"
+ offset="0"
+ id="stop17598" />
+ <stop
+ style="stop-color:#ffc280;stop-opacity:1"
+ offset="1"
+ id="stop17600" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17438">
+ <stop
+ style="stop-color:#ff9f37;stop-opacity:1"
+ offset="0"
+ id="stop17440" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop17442" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17430">
+ <stop
+ style="stop-color:#ff9f37;stop-opacity:1"
+ offset="0"
+ id="stop17432" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop17434" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30958">
+ <stop
+ id="stop30960"
+ offset="0"
+ style="stop-color:#fff9cf;stop-opacity:1;" />
+ <stop
+ id="stop30962"
+ offset="1"
+ style="stop-color:#c7bc52;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29312">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29314" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29316" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29304">
+ <stop
+ style="stop-color:#11233f;stop-opacity:1;"
+ offset="0"
+ id="stop29306" />
+ <stop
+ style="stop-color:#162d50;stop-opacity:0;"
+ offset="1"
+ id="stop29308" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27896">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27898" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27900" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27854">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27856" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27858" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24343">
+ <stop
+ id="stop24345"
+ offset="0"
+ style="stop-color:#184990;stop-opacity:1;" />
+ <stop
+ id="stop24347"
+ offset="1"
+ style="stop-color:#c1d5f3;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25417">
+ <stop
+ id="stop25419"
+ offset="0"
+ style="stop-color:#60553b;stop-opacity:1;" />
+ <stop
+ id="stop25421"
+ offset="1"
+ style="stop-color:#b0a17f;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25108">
+ <stop
+ id="stop25110"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop25112"
+ offset="1"
+ style="stop-color:#c6c6c6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient43807">
+ <stop
+ style="stop-color:#e31b1b;stop-opacity:1;"
+ offset="0"
+ id="stop43809" />
+ <stop
+ style="stop-color:#930000;stop-opacity:1;"
+ offset="1"
+ id="stop43811" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient38845">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38847" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38849" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38831">
+ <stop
+ style="stop-color:#182b42;stop-opacity:1;"
+ offset="0"
+ id="stop38833" />
+ <stop
+ id="stop38836"
+ offset="0.38971797"
+ style="stop-color:#598ac7;stop-opacity:1;" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1;"
+ offset="1"
+ id="stop38838" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38256">
+ <stop
+ id="stop38258"
+ offset="0"
+ style="stop-color:#e7e0c7;stop-opacity:1;" />
+ <stop
+ id="stop38260"
+ offset="1"
+ style="stop-color:#f1eddf;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient71814">
+ <stop
+ style="stop-color:#6e0d00;stop-opacity:1;"
+ offset="0"
+ id="stop71816" />
+ <stop
+ style="stop-color:#6f2913;stop-opacity:0;"
+ offset="1"
+ id="stop71818" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37667">
+ <stop
+ id="stop37669"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop37671"
+ offset="1"
+ style="stop-color:black;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39080">
+ <stop
+ style="stop-color:#1a2a3d;stop-opacity:1;"
+ offset="0"
+ id="stop39082" />
+ <stop
+ id="stop39084"
+ offset="0.5"
+ style="stop-color:#95b0d1;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop39086" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40703">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37925">
+ <stop
+ id="stop37927"
+ offset="0"
+ style="stop-color:#e7cbab;stop-opacity:1;" />
+ <stop
+ id="stop37929"
+ offset="1"
+ style="stop-color:#af7333;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient36273">
+ <stop
+ id="stop36275"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35411">
+ <stop
+ id="stop35414"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31356">
+ <stop
+ id="stop31358"
+ offset="0"
+ style="stop-color:#1a1a1a;stop-opacity:1" />
+ <stop
+ id="stop31360"
+ offset="1"
+ style="stop-color:#1a1a1a;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient28107"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7228842,8.5733105e-8,-9.4831885e-8,0.7995973,71.917045,14.582004)"
+ cx="256.49512"
+ cy="81.396774"
+ fx="256.49512"
+ fy="81.396774"
+ r="3.779551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28105"
+ gradientUnits="userSpaceOnUse"
+ x1="875.73486"
+ y1="422.77902"
+ x2="885.04938"
+ y2="427.01648" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28887"
+ id="linearGradient28103"
+ gradientUnits="userSpaceOnUse"
+ x1="873.09998"
+ y1="422.09964"
+ x2="881.01172"
+ y2="429.23453" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28101"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.6572588,1.2500456,-1.6473175,2.2058465,774.83033,-697.31982)"
+ cx="76.180473"
+ cy="500.20651"
+ fx="76.180473"
+ fy="500.20651"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28099"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient28887">
+ <stop
+ style="stop-color:#2158a7;stop-opacity:1;"
+ offset="0"
+ id="stop28889" />
+ <stop
+ style="stop-color:#2f73d5;stop-opacity:0.19607843;"
+ offset="1"
+ id="stop28891" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24168">
+ <stop
+ id="stop24170"
+ offset="0"
+ style="stop-color:#182437;stop-opacity:1;" />
+ <stop
+ id="stop24172"
+ offset="1"
+ style="stop-color:#2b4163;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24144">
+ <stop
+ id="stop24146"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.17958513"
+ id="stop24148" />
+ <stop
+ id="stop24150"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24101">
+ <stop
+ style="stop-color:#643400;stop-opacity:1;"
+ offset="0"
+ id="stop24103" />
+ <stop
+ id="stop24105"
+ offset="0.22606115"
+ style="stop-color:#ed983d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#fff0d5;stop-opacity:1;"
+ offset="1"
+ id="stop24107" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24081">
+ <stop
+ id="stop24083"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.3167825"
+ id="stop24085" />
+ <stop
+ id="stop24087"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23302">
+ <stop
+ id="stop23304"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.39332664"
+ id="stop23306" />
+ <stop
+ id="stop23308"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24735">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop24737" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop24739" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24727">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24729" />
+ <stop
+ id="stop24731"
+ offset="0.77520341"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24733" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24711">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24713" />
+ <stop
+ id="stop24715"
+ offset="0.21609697"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24717" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24695">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24697" />
+ <stop
+ id="stop24699"
+ offset="0.60401857"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24701" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24687">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24689" />
+ <stop
+ id="stop24691"
+ offset="0.59630167"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24693" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681" />
+ <stop
+ id="stop24683"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24671">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24673" />
+ <stop
+ id="stop24675"
+ offset="0.29527253"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24677" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23705">
+ <stop
+ id="stop23707"
+ offset="0"
+ style="stop-color:#d4d2bf;stop-opacity:1;" />
+ <stop
+ id="stop23709"
+ offset="1"
+ style="stop-color:#857f5d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23906">
+ <stop
+ id="stop23908"
+ offset="0"
+ style="stop-color:#ff921d;stop-opacity:1;" />
+ <stop
+ id="stop23910"
+ offset="1"
+ style="stop-color:#ffa751;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42459">
+ <stop
+ style="stop-color:#e7dfab;stop-opacity:1;"
+ offset="0"
+ id="stop42461" />
+ <stop
+ style="stop-color:#af9d33;stop-opacity:1;"
+ offset="1"
+ id="stop42463" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287"
+ y1="-276.1875"
+ x2="-281.4375"
+ y2="-271.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="171.42436"
+ y1="259.71194"
+ x2="170.20523"
+ y2="244.96393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24246"
+ gradientUnits="userSpaceOnUse"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(186,-105)"
+ x1="246.12868"
+ y1="283.63254"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287.56247"
+ y1="-276.71042"
+ x2="-282.59851"
+ y2="-271.35284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient24276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="190.33647"
+ y1="266.7905"
+ x2="170.9689"
+ y2="247.58694" />
+ <linearGradient
+ id="linearGradient24143">
+ <stop
+ id="stop24145"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669" />
+ <stop
+ id="stop24147"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24687"
+ id="linearGradient24238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,304.84783,-86.57833)"
+ x1="120.2969"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ id="linearGradient24642">
+ <stop
+ style="stop-color:#d0dbe8;stop-opacity:1;"
+ offset="0"
+ id="stop24644" />
+ <stop
+ style="stop-color:#6ca3e9;stop-opacity:0;"
+ offset="1"
+ id="stop24646" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24632">
+ <stop
+ style="stop-color:#28394f;stop-opacity:1;"
+ offset="0"
+ id="stop24634" />
+ <stop
+ id="stop24636"
+ offset="0.17637014"
+ style="stop-color:#0d386a;stop-opacity:0.78431374;" />
+ <stop
+ id="stop24638"
+ offset="0.35274029"
+ style="stop-color:#18437d;stop-opacity:0.47058824;" />
+ <stop
+ style="stop-color:#154e94;stop-opacity:0;"
+ offset="1"
+ id="stop24640" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="radialGradient23167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9934369,-0.1143813,0.1033636,0.8977446,-30.451879,30.134649)"
+ cx="-0.10810681"
+ cy="294.60239"
+ fx="-0.10810681"
+ fy="294.60239"
+ r="6.6750002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23201"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-61,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.25"
+ y2="245" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.5"
+ y2="245" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23189">
+ <g
+ transform="translate(-28,49)"
+ id="g23193">
+ <rect
+ y="237"
+ x="22"
+ height="16"
+ width="9"
+ id="rect23195"
+ style="fill:url(#linearGradient23199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ style="fill:url(#linearGradient23201);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23197"
+ width="9"
+ height="16"
+ x="-38"
+ y="237" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24208"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24206"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23379"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient23377"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient23375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="52.06274"
+ y1="96.767769"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient23373"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ id="linearGradient23974">
+ <stop
+ id="stop23976"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40983">
+ <stop
+ style="stop-color:#6a9ae0;stop-opacity:1;"
+ offset="0"
+ id="stop40985" />
+ <stop
+ style="stop-color:#5189db;stop-opacity:0;"
+ offset="1"
+ id="stop40987" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23280"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23278"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient23276"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient23274"
+ gradientUnits="userSpaceOnUse"
+ x1="144.8255"
+ y1="132.15414"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ id="linearGradient30777"
+ inkscape:collect="always">
+ <stop
+ id="stop30779"
+ offset="0"
+ style="stop-color:#acacac;stop-opacity:1" />
+ <stop
+ id="stop30781"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29485">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop29487" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop29489" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.55821538"
+ width="2.1164308"
+ y="-1.0219563"
+ height="3.0439126"
+ id="filter20578"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="2.0410255"
+ id="feGaussianBlur20580" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath20586">
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34889"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ 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(1.870472,0.1894819,-0.6587894,2.4281336,319.59052,-798.11661)" />
+ </clipPath>
+ <radialGradient
+ id="aigrd2"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop15566" />
+ <stop
+ offset="1.0000000"
+ style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
+ id="stop15568" />
+ </radialGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106">
+ <path
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850"
+ 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" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient58334">
+ <stop
+ id="stop58336"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8864">
+ <stop
+ id="stop8866"
+ offset="0"
+ style="stop-color:#b43214;stop-opacity:1;" />
+ <stop
+ id="stop8868"
+ offset="1"
+ style="stop-color:#e86830;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20324">
+ <stop
+ id="stop20326"
+ offset="0"
+ style="stop-color:#35241b;stop-opacity:1;" />
+ <stop
+ style="stop-color:#69390e;stop-opacity:0.8392157;"
+ offset="0.17637014"
+ id="stop20328" />
+ <stop
+ style="stop-color:#6c5b15;stop-opacity:0.67843139;"
+ offset="0.35274029"
+ id="stop20330" />
+ <stop
+ id="stop20332"
+ offset="1"
+ style="stop-color:#947b15;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37623">
+ <stop
+ id="stop37625"
+ offset="0"
+ style="stop-color:#e5e1ca;stop-opacity:1;" />
+ <stop
+ id="stop37627"
+ offset="1"
+ style="stop-color:#d6ca22;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient36116">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop36118" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop36120" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22852"
+ gradientUnits="userSpaceOnUse"
+ x1="133.94305"
+ y1="116.00471"
+ x2="117.29694"
+ y2="133.14267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22850"
+ gradientUnits="userSpaceOnUse"
+ x1="136.55727"
+ y1="125.87247"
+ x2="129.70895"
+ y2="118.00132" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22844"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ id="linearGradient22562">
+ <stop
+ style="stop-color:#001e50;stop-opacity:1;"
+ offset="0"
+ id="stop22564" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop22566" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient22842"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ id="linearGradient22556">
+ <stop
+ id="stop22558"
+ offset="0"
+ style="stop-color:#6a9bef;stop-opacity:1" />
+ <stop
+ style="stop-color:#bccee8;stop-opacity:0.58450705;"
+ offset="0.77941167"
+ id="stop22568" />
+ <stop
+ id="stop22560"
+ offset="1"
+ style="stop-color:#ccdaed;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22556"
+ id="linearGradient22840"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient22838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient22882">
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="0"
+ id="stop22884" />
+ <stop
+ id="stop22886"
+ offset="0.21233012"
+ style="stop-color:#323232;stop-opacity:0.49803922;" />
+ <stop
+ id="stop22888"
+ offset="0.54086536"
+ style="stop-color:#323232;stop-opacity:1;" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0.49803922;"
+ offset="0.83381736"
+ id="stop22890" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop22892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22880"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ id="linearGradient35407">
+ <stop
+ id="stop35409"
+ offset="0"
+ style="stop-color:#a17306;stop-opacity:1;" />
+ <stop
+ style="stop-color:#cca649;stop-opacity:1;"
+ offset="0.43277758"
+ id="stop35411" />
+ <stop
+ id="stop35413"
+ offset="1"
+ style="stop-color:#f9f5e9;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35391">
+ <stop
+ id="stop35393"
+ offset="0"
+ style="stop-color:#322800;stop-opacity:1;" />
+ <stop
+ id="stop35395"
+ offset="1"
+ style="stop-color:#6e4800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient34157">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop34159" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop34161" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient22457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-25.5"
+ y1="36.828632"
+ x2="-25.5"
+ y2="26.027344" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22455"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-354,-314.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22453"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-27.299919"
+ y1="37"
+ x2="-25.5"
+ y2="23.414351" />
+ <linearGradient
+ id="linearGradient21609">
+ <stop
+ id="stop21611"
+ offset="0"
+ style="stop-color:black;stop-opacity:1" />
+ <stop
+ id="stop21613"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21609"
+ id="linearGradient20961"
+ gradientUnits="userSpaceOnUse"
+ x1="162"
+ y1="103.71875"
+ x2="165"
+ y2="103.75" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask20957">
+ <rect
+ y="101"
+ x="162"
+ height="5"
+ width="8"
+ id="rect20959"
+ style="fill:url(#linearGradient20961);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32335"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <filter
+ inkscape:collect="always"
+ id="filter23214"
+ x="-0.48015866"
+ width="1.9603173"
+ y="-0.47984189"
+ height="1.9596838"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.53351805"
+ id="feGaussianBlur23216" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient19900">
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:1;"
+ offset="0"
+ id="stop19902" />
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:0;"
+ offset="1"
+ id="stop19904" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18105">
+ <stop
+ id="stop18107"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18056">
+ <stop
+ id="stop18058"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18060"
+ offset="1"
+ style="stop-color:#295498;stop-opacity:0.34057972;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19625">
+ <stop
+ id="stop19627"
+ offset="0"
+ style="stop-color:#2258a6;stop-opacity:1;" />
+ <stop
+ id="stop19629"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient20217"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient18821">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient29149">
+ <stop
+ id="stop29151"
+ offset="0"
+ style="stop-color:#76adff;stop-opacity:1;" />
+ <stop
+ id="stop29153"
+ offset="1"
+ style="stop-color:#a5c9ff;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient21820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient21818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21816"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21814"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient21741"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient21773"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9281768,0,0,0.9971589,401.42265,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22166"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22164"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22162"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22160"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22158"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient22156"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22154"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15809">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15811" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop15813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15437">
+ <stop
+ id="stop15439"
+ offset="0"
+ style="stop-color:#20529e;stop-opacity:1;" />
+ <stop
+ id="stop15441"
+ offset="1"
+ style="stop-color:#1d3f71;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15425">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15427" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14262">
+ <stop
+ id="stop14264"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath17188">
+ <path
+ style="fill:#d3d7cf;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 240.5,-19.90625 c -1.87005,0 -3.40625,1.536202 -3.40625,3.40625 l 0,2 c 0,1.87005 1.53621,3.40625 3.40625,3.40625 l 0,-2.8125 c -0.33932,0 -0.59375,-0.254431 -0.59375,-0.59375 l 0,-2 c 0,-0.339319 0.25443,-0.59375 0.59375,-0.59375 l 0,-2.8125 z"
+ id="path17190" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient18344">
+ <stop
+ style="stop-color:#6c6c6c;stop-opacity:1;"
+ offset="0"
+ id="stop18346" />
+ <stop
+ style="stop-color:#f0f0f0;stop-opacity:1;"
+ offset="1"
+ id="stop18348" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060">
+ <stop
+ id="stop5062"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient27957">
+ <stop
+ id="stop27959"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0.59290552"
+ id="stop27963" />
+ <stop
+ id="stop27961"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23647">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop23649" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop23651" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23390">
+ <stop
+ style="stop-color:#000000;stop-opacity:1.0000000"
+ offset="0.0000000"
+ id="stop23392" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000"
+ offset="1.0000000"
+ id="stop23400" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16359">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16361" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16363" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.26,-38.98429)"
+ x1="386.09836"
+ y1="230.09529"
+ x2="388.35962"
+ y2="248.10277" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15744"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="390.61163"
+ y1="229.34804"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15683"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.203777,0,0,0.903901,837.9645,-18.01568)"
+ x1="383.67041"
+ y1="225.94354"
+ x2="385.60632"
+ y2="248.55901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15681"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,839.2424,-18.01568)"
+ x1="391.80222"
+ y1="230.5647"
+ x2="387.94211"
+ y2="247.83209" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13545"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="137.11284"
+ y2="126.19643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15878"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient20756">
+ <stop
+ style="stop-color:#932200;stop-opacity:1;"
+ offset="0"
+ id="stop20758" />
+ <stop
+ style="stop-color:#f8420a;stop-opacity:1;"
+ offset="1"
+ id="stop20760" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient13543"
+ gradientUnits="userSpaceOnUse"
+ x1="126.45676"
+ y1="110.59049"
+ x2="134.94949"
+ y2="122.08995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15693"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="215.07817"
+ y1="109.00085"
+ x2="235.90916"
+ y2="121.88217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="217.22589"
+ y1="107.25085"
+ x2="235.90916"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15854"
+ gradientUnits="userSpaceOnUse"
+ x1="381.56296"
+ y1="234.59885"
+ x2="393"
+ y2="247.99632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient13639"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.987"
+ y1="259.26602"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52023"
+ gradientUnits="userSpaceOnUse"
+ x1="390.75"
+ y1="244.5312"
+ x2="395.9375"
+ y2="250.9062" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient14661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="400.88739"
+ y1="257.4874"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52025"
+ gradientUnits="userSpaceOnUse"
+ x1="391.01859"
+ y1="241.86644"
+ x2="396.79285"
+ y2="247.83134" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient15995"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.08661"
+ y1="257.41327"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15993"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15997"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ id="linearGradient47130">
+ <stop
+ style="stop-color:#ed7b00;stop-opacity:1;"
+ offset="0"
+ id="stop47132" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop47134" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52027"
+ gradientUnits="userSpaceOnUse"
+ x1="329.28757"
+ y1="244.97151"
+ x2="339.84518"
+ y2="254.18553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15436"
+ gradientUnits="userSpaceOnUse"
+ x1="319.75095"
+ y1="234.63918"
+ x2="333.94208"
+ y2="248.68198" />
+ <linearGradient
+ id="linearGradient32842">
+ <stop
+ style="stop-color:#183e75;stop-opacity:1;"
+ offset="0"
+ id="stop32844" />
+ <stop
+ style="stop-color:#1d3f71;stop-opacity:0;"
+ offset="1"
+ id="stop32846" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient13900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2541045,-1.3755453,0.900369,1.4754358,-3699.4512,2858.7)"
+ cx="2357.1072"
+ cy="826.77924"
+ fx="2357.1072"
+ fy="826.77924"
+ r="6.1896501" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40983"
+ id="linearGradient38692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2226.9963,823)"
+ x1="130.70599"
+ y1="18.44199"
+ x2="130.70599"
+ y2="21.94199" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15717"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15715"
+ gradientUnits="userSpaceOnUse"
+ x1="320.2735"
+ y1="25.109356"
+ x2="332.41409"
+ y2="37.468754" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15713"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15709"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="323.37836"
+ y1="30.3883"
+ x2="343.5636"
+ y2="53.758793" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15646"
+ gradientUnits="userSpaceOnUse"
+ x1="279.00009"
+ y1="-16.62501"
+ x2="291.93054"
+ y2="-6.3206272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15644"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-253)"
+ x1="25.437477"
+ y1="238.54002"
+ x2="51.01355"
+ y2="263.79816" />
+ <linearGradient
+ id="linearGradient20973">
+ <stop
+ id="stop20975"
+ offset="0"
+ style="stop-color:#15ff00;stop-opacity:1;" />
+ <stop
+ id="stop20977"
+ offset="1"
+ style="stop-color:#15ff00;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20962">
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:1;"
+ offset="0"
+ id="stop20965" />
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:0;"
+ offset="1"
+ id="stop20967" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20036">
+ <stop
+ style="stop-color:#ffb55e;stop-opacity:1;"
+ offset="0"
+ id="stop20038" />
+ <stop
+ style="stop-color:#ff8400;stop-opacity:0;"
+ offset="1"
+ id="stop20040" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15574"
+ gradientUnits="userSpaceOnUse"
+ x1="197.63152"
+ y1="169.14206"
+ x2="190.41687"
+ y2="160.02296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15358"
+ gradientUnits="userSpaceOnUse"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15362"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15360"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,39.669142,20)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14517"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3959732"
+ y1="216.62332"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16069"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="17.011419"
+ y2="82.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient16067"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,-440.36032,-147)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16063"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="6.9917974"
+ y1="219.61856"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16154"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16150"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.8504581"
+ y1="217.4549"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16174"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="2.911078"
+ y1="217.3624"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ id="linearGradient13998">
+ <stop
+ id="stop14000"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15705"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15703"
+ gradientUnits="userSpaceOnUse"
+ x1="146.80022"
+ y1="158.34668"
+ x2="150.08357"
+ y2="162.03282" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15701"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15699"
+ gradientUnits="userSpaceOnUse"
+ x1="122.84515"
+ y1="126.83902"
+ x2="149.88129"
+ y2="164.94562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15742"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="227.57907"
+ y1="118.47696"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="222.4996"
+ y1="110.37873"
+ x2="233.08319"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="230.95012"
+ y1="100.89436"
+ x2="230.74091"
+ y2="124.09359" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15778"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="135.54141"
+ y2="122.0597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15780"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10.767079)"
+ x1="132.35471"
+ y1="246.32236"
+ x2="129.81586"
+ y2="243.70523" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15774"
+ gradientUnits="userSpaceOnUse"
+ x1="103.53399"
+ y1="88.301094"
+ x2="136.3542"
+ y2="123.17216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15450"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15452"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15448"
+ gradientUnits="userSpaceOnUse"
+ x1="132.12782"
+ y1="246.32236"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15446"
+ gradientUnits="userSpaceOnUse"
+ x1="87.969383"
+ y1="69.87941"
+ x2="135.40274"
+ y2="121.19196" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15124"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient15122"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16025"
+ gradientUnits="userSpaceOnUse"
+ x1="192.11751"
+ y1="122.12527"
+ x2="184.43379"
+ y2="112.34031" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.395521,0,0,-0.3955,275.223,171.0515)"
+ x1="213.51967"
+ y1="121.417"
+ x2="204.05295"
+ y2="111.7235" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.607961,0,0,0.607967,64.49194,51.63899)"
+ x1="213.53587"
+ y1="122.66508"
+ x2="203.33264"
+ y2="112.67535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15748"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="349.04059"
+ y1="143.70836"
+ x2="336.72485"
+ y2="117.00745" />
+ <linearGradient
+ id="linearGradient10585">
+ <stop
+ id="stop10587"
+ offset="0.0000000"
+ style="stop-color:#d7d7d7;stop-opacity:1.0000000;" />
+ <stop
+ id="stop10595"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4138">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop4140" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop4142" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31320">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12678">
+ <stop
+ id="stop12680"
+ offset="0"
+ style="stop-color:#d40000;stop-opacity:1" />
+ <stop
+ id="stop12682"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13991"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13520"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.401389,-3.2412)"
+ x1="130.59862"
+ y1="121.2412"
+ x2="142.29109"
+ y2="133.53448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23215"
+ x1="147.07098"
+ y1="134.18185"
+ x2="129.67148"
+ y2="115.54105"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient23178">
+ <stop
+ style="stop-color:#ff992b;stop-opacity:1;"
+ offset="0"
+ id="stop23180" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop23182" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13973">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13938">
+ <stop
+ id="stop13940"
+ offset="0"
+ style="stop-color:#6e0c00;stop-opacity:1;" />
+ <stop
+ id="stop13942"
+ offset="1"
+ style="stop-color:#ee3800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14232">
+ <stop
+ style="stop-color:#fff32a;stop-opacity:1;"
+ offset="0"
+ id="stop14234" />
+ <stop
+ style="stop-color:#fff551;stop-opacity:0;"
+ offset="1"
+ id="stop14236" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter13996"
+ x="-0.23644176"
+ width="1.4728835"
+ y="-0.24368355"
+ height="1.4873672"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.29550651"
+ id="feGaussianBlur13998" />
+ </filter>
+ <linearGradient
+ id="linearGradient14418">
+ <stop
+ id="stop14420"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14935"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-26,2.9206276e-6)"
+ x1="474"
+ y1="73.999992"
+ x2="477.25"
+ y2="77.499992" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,1.4603138e-6)"
+ x1="474.84375"
+ y1="75"
+ x2="477.5"
+ y2="77.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18852"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18850"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18901"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(279.04534,461.00001)"
+ x1="151"
+ y1="-234"
+ x2="149.95467"
+ y2="-239.14549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.04419,461)"
+ x1="151"
+ y1="-234"
+ x2="150.25"
+ y2="-236.85815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.99885,461)"
+ x1="150.11926"
+ y1="-235.21587"
+ x2="145.20955"
+ y2="-241.85452" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,459)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17535"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17533"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17527"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18207">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18209" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop18211" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient18213"
+ x1="481.46063"
+ y1="219"
+ x2="519.44189"
+ y2="218.48816"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17506"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17504"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17502"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17500"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17498"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2078427,0,0,1.0516432,-357.40769,69.427229)"
+ x1="362.28571"
+ y1="-45.098213"
+ x2="352.46426"
+ y2="-54.124699" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18666">
+ <rect
+ y="6"
+ x="62.921577"
+ height="14.000001"
+ width="15.098035"
+ id="rect18668"
+ style="fill:url(#linearGradient18670);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15592"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15590"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="135.54628"
+ y2="120.58403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15596"
+ gradientUnits="userSpaceOnUse"
+ x1="124.52369"
+ y1="112.22441"
+ x2="131.10667"
+ y2="118.10129" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15594"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="134.62978"
+ y2="120.14633" />
+ <filter
+ inkscape:collect="always"
+ x="-0.71999419"
+ width="2.4399884"
+ y="-0.72000581"
+ height="2.4400115"
+ id="filter31351"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.83077614"
+ id="feGaussianBlur31353" />
+ </filter>
+ <linearGradient
+ id="linearGradient14219">
+ <stop
+ id="stop14221"
+ offset="0"
+ style="stop-color:#ff8605;stop-opacity:1;" />
+ <stop
+ id="stop14223"
+ offset="1"
+ style="stop-color:#9c6700;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31456">
+ <stop
+ style="stop-color:#2b1600;stop-opacity:1;"
+ offset="0"
+ id="stop31458" />
+ <stop
+ style="stop-color:#6e3900;stop-opacity:0;"
+ offset="1"
+ id="stop31460" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19425">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop19427" />
+ <stop
+ id="stop19431"
+ offset="0.63109845"
+ style="stop-color:#fffffe;stop-opacity:0.65789473;" />
+ <stop
+ style="stop-color:#fffffe;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop19429" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30208">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop30210" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop30212" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15782"
+ gradientUnits="userSpaceOnUse"
+ x1="125.19086"
+ y1="125.66204"
+ x2="132.98256"
+ y2="118" />
+ <linearGradient
+ id="linearGradient9030">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542">
+ <stop
+ id="stop37544"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30124">
+ <stop
+ style="stop-color:#1d4a8c;stop-opacity:1;"
+ offset="0"
+ id="stop30126" />
+ <stop
+ style="stop-color:#c1d4f2;stop-opacity:1;"
+ offset="1"
+ id="stop30128" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15893">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop15895" />
+ <stop
+ id="stop15897"
+ offset="0.37679368"
+ style="stop-color:#b5ccf0;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b5ccf0;stop-opacity:1;"
+ offset="0.59786767"
+ id="stop15899" />
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="1"
+ id="stop15901" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24000">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop24002" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop24004" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient32998">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop33000" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop33002" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21372"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="radialGradient21517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.891843,0,0,0.909224,-173.99085,171.21624)"
+ cx="350.5"
+ cy="14.5"
+ fx="350.5"
+ fy="14.5"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21641"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="133.62564"
+ y2="120.24665" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21643"
+ gradientUnits="userSpaceOnUse"
+ x1="126.15096"
+ y1="113.21745"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20796"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(159.9998,-41.00751)"
+ x1="261.44702"
+ y1="234.6606"
+ x2="274.30609"
+ y2="247.73561" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20798"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(199.9999,105.99249)"
+ x1="235.46884"
+ y1="103"
+ x2="228.71886"
+ y2="94.53125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.2344713"
+ y1="215.76874"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21864"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="19.011419"
+ y2="86" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3268692"
+ y1="215.35608"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21904"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-237)"
+ x1="24.374985"
+ y1="238.33629"
+ x2="55.384842"
+ y2="269.1373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,16)"
+ x1="278.55817"
+ y1="-16.978563"
+ x2="291.577"
+ y2="-5.8786855" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient31650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.816279,0,-3.646264e-6,0.779872,56.32029,28.34496)"
+ cx="306.55292"
+ cy="11.818644"
+ fx="306.55292"
+ fy="11.818644"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="radialGradient31652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.580596,1.138426,-0.692447,0.961382,-175.3891,-329.6844)"
+ cx="312.80765"
+ cy="10.620173"
+ fx="312.80765"
+ fy="10.620173"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20962"
+ id="radialGradient31654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.48445,-0.00657397,0.00734631,1.660903,-154.1629,19.305572)"
+ cx="313.74268"
+ cy="15.619254"
+ fx="313.74268"
+ fy="15.619254"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20973"
+ id="radialGradient31656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.756245,0,-3.378096e-6,0.722516,72.63115,31.07857)"
+ cx="309.0571"
+ cy="15.518281"
+ fx="309.0571"
+ fy="15.518281"
+ r="4.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31664"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8579582,0,0,0.9285714,7.397998,-211.96428)"
+ x1="-6.3249049"
+ y1="205.0083"
+ x2="32.351238"
+ y2="248.75177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9569715,-1,0,259,351.18743)"
+ x1="347.6467"
+ y1="216.75188"
+ x2="345.98633"
+ y2="243.92201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166667,0,0,0.9166667,24.364541,-55.041665)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9297203,-1.2117965,0,305.73028,342.22894)"
+ x1="346.15555"
+ y1="218.2382"
+ x2="346.58698"
+ y2="238.44429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31694"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient31696"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="64.998215"
+ y1="90.951675"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,105.5221,92.482413)"
+ x1="257.0376"
+ y1="10.838325"
+ x2="277.61203"
+ y2="31.019331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31934"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7827973,0,0,0.9989462,77.082208,42.08484)"
+ x1="332.03717"
+ y1="68.624634"
+ x2="346.08932"
+ y2="83.002625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31936"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(262,-125)"
+ x1="79.329903"
+ y1="236"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient33666"
+ gradientUnits="userSpaceOnUse"
+ x1="124.14184"
+ y1="126.23546"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33668"
+ gradientUnits="userSpaceOnUse"
+ x1="125.45158"
+ y1="125.94608"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33670"
+ gradientUnits="userSpaceOnUse"
+ x1="142.97318"
+ y1="107.64013"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33681"
+ gradientUnits="userSpaceOnUse"
+ x1="139.93341"
+ y1="110.56118"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient33700"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55772"
+ y1="98.630066"
+ x2="123.9021"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10540"
+ gradientUnits="userSpaceOnUse"
+ x1="130.95198"
+ y1="117.09563"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient11333"
+ gradientUnits="userSpaceOnUse"
+ x1="119.1647"
+ y1="106.08605"
+ x2="133.01006"
+ y2="119.79803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-425,393.99999)"
+ x1="225.6198"
+ y1="5.7625732"
+ x2="236.47855"
+ y2="14.103563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient28077"
+ x1="306.26187"
+ y1="272"
+ x2="307"
+ y2="263.55374"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="431.05026"
+ y1="121.42467"
+ x2="446.26407"
+ y2="110.49417" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28528"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="442.69827"
+ y1="107.56771"
+ x2="450.27414"
+ y2="122.95798" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-474,158.25)"
+ x1="437.57828"
+ y1="104.34499"
+ x2="447.96875"
+ y2="117.90625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28532"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10982"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10984"
+ x1="212.04637"
+ y1="182.09375"
+ x2="222.35799"
+ y2="182.77524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11762"
+ x1="371.98389"
+ y1="203"
+ x2="376.48389"
+ y2="203"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11764"
+ x1="366.98389"
+ y1="203"
+ x2="370.98389"
+ y2="202.75"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11766"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient12427"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14219"
+ id="radialGradient12429"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5007214,0.3131662,-0.3623683,0.5793905,300.02235,-93.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16359"
+ id="linearGradient12602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,456.04574,-116.51416)"
+ x1="88.079262"
+ y1="66.110847"
+ x2="95.954262"
+ y2="58.272621" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient12114"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1438.0001,-418)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1830.2675,-33.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1397.7474,-388.72044)"
+ x1="1984.5453"
+ y1="828.21777"
+ x2="1978.11"
+ y2="829.35315" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12215"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12217"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient12305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="257.24991"
+ y1="147.38998"
+ x2="262.24991"
+ y2="152.46707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient12307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="258.08322"
+ y1="147.87068"
+ x2="264.16571"
+ y2="153.8233" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13046"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-161.99999)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13041">
+ <rect
+ style="fill:url(#linearGradient13046);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect13043"
+ width="7"
+ height="8"
+ x="276"
+ y="-12" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-145.93749)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13052">
+ <rect
+ y="4.0625"
+ x="276"
+ height="8"
+ width="7"
+ id="rect13054"
+ style="fill:url(#linearGradient13056);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="443.86667"
+ y1="133.98936"
+ x2="451.98389"
+ y2="143.58749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="453.61005"
+ y2="133.00301" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="449.14645"
+ y1="136.18045"
+ x2="453.24457"
+ y2="138.7879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14173"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="454.31345"
+ y2="133.62801" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient13112"
+ gradientUnits="userSpaceOnUse"
+ x1="133.42287"
+ y1="120.62622"
+ x2="126.67323"
+ y2="113.20281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13114"
+ gradientUnits="userSpaceOnUse"
+ x1="120.77391"
+ y1="106.19939"
+ x2="144.64095"
+ y2="129.62753" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16027"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8289081,0,0,2.1560411,236.27148,-864.45588)"
+ x1="212"
+ y1="435.59741"
+ x2="211.99998"
+ y2="435.32159" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16031"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1035181,0,0,1,158.18497,-359.77344)"
+ x1="229.6875"
+ y1="440.51562"
+ x2="238.53125"
+ y2="440.57812" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23390"
+ id="radialGradient16034"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.8126517,-0.04317018,0.04642643,1.9485655,-18.817545,-774.28453)"
+ cx="224.32494"
+ cy="441.84744"
+ fx="224.32494"
+ fy="441.84744"
+ r="6.7191267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient16036"
+ gradientUnits="userSpaceOnUse"
+ x1="211.99998"
+ y1="435.7319"
+ x2="211.99998"
+ y2="436.07974"
+ gradientTransform="matrix(0.9803611,0,0,2.1560411,204.16345,-864.45588)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16039"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(182,-359.75)"
+ x1="221.96414"
+ y1="439.75"
+ x2="238.87605"
+ y2="448.88205" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17337"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0008786,0,0,1.081555,-21.021535,-187.45087)"
+ x1="-12.839478"
+ y1="201"
+ x2="44.522621"
+ y2="256.70349" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.099576,0,0,1.0999923,190.46996,204.85062)"
+ x1="9.6310225"
+ y1="76"
+ x2="15"
+ y2="81" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,370.43125,-83.863716)"
+ x1="-5.6700387"
+ y1="250.87607"
+ x2="-46.452946"
+ y2="251.42462" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17714"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,280.08766,104.72255)"
+ x1="102.61966"
+ y1="50.742527"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient12655"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12658"
+ gradientUnits="userSpaceOnUse"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13527"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13529"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(68.016116,127.00002)"
+ x1="97.983887"
+ y1="127.99998"
+ x2="88.983887"
+ y2="115.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14570"
+ gradientUnits="userSpaceOnUse"
+ x1="94.485573"
+ y1="122.13319"
+ x2="89.207298"
+ y2="125.83332" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14572"
+ gradientUnits="userSpaceOnUse"
+ x1="88.560204"
+ y1="127.88263"
+ x2="94.011101"
+ y2="123.83599" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient47130"
+ id="linearGradient13699"
+ x1="-162.89217"
+ y1="245"
+ x2="-174.18907"
+ y2="224.99274"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26282"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26284"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26286"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26288"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14198"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15195"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient15209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15211"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15363"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9999519,0,0,0.9998051,-33.993941,254.01926)"
+ x1="101.21339"
+ y1="68.783279"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15365"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,40.331334,244.81698)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10585"
+ id="linearGradient15367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.032977,0,0,1,128.82015,107.77516)"
+ x1="12.330792"
+ y1="246.97107"
+ x2="41.654194"
+ y2="247.3784" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient15383"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14377"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient16640"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="85.874489"
+ y1="501.74075"
+ x2="26.561054"
+ y2="498.48148" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16642"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16644"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,300.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient16648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient32447"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30231"
+ gradientUnits="userSpaceOnUse"
+ x1="441.48248"
+ y1="105.03784"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient30233"
+ gradientUnits="userSpaceOnUse"
+ x1="445.37457"
+ y1="112.86145"
+ x2="425.92511"
+ y2="84.928581" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30235"
+ gradientUnits="userSpaceOnUse"
+ x1="440.68439"
+ y1="106.0996"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30237"
+ gradientUnits="userSpaceOnUse"
+ x1="440.34833"
+ y1="105.74502"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30239"
+ gradientUnits="userSpaceOnUse"
+ x1="440.7211"
+ y1="104.97093"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23302"
+ id="linearGradient30241"
+ gradientUnits="userSpaceOnUse"
+ x1="414.99771"
+ y1="-35"
+ x2="414.99771"
+ y2="-36.625011" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24081"
+ id="linearGradient30243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.00461"
+ y1="-34"
+ x2="415.94211"
+ y2="-37.718761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient30247"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.41162"
+ y1="-34.342831"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30249"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30326"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30328"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30330"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30332"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30334"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30336"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30338"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30340"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30342"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30344"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30346"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30348"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30394"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30396"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30398"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30400"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30402"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30404"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30406"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30408"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30414"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30416"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ 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">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m -44,358 0,14 14,-14 -14,0 z"
+ id="path17572" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18682"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.9230835,365.8517,-147.63686)"
+ x1="27.405855"
+ y1="189.20862"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18690"
+ gradientUnits="userSpaceOnUse"
+ x1="29.972469"
+ y1="164"
+ x2="29.972469"
+ y2="168"
+ gradientTransform="translate(359.05264,-81.98142)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="30.435225"
+ y1="202.99998"
+ x2="30.435225"
+ y2="251.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18756"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18779"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6923077,0,0,-0.6923079,29.049874,351.11545)"
+ x1="7.9951181"
+ y1="264.90152"
+ x2="32.267426"
+ y2="237.9342" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-122.98388,276)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5384613,0,0,0.538461,-189.69233,224.07704)"
+ x1="29.142912"
+ y1="161.42842"
+ x2="29.142912"
+ y2="252.42851" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.538461,-193.81309,224.07705)"
+ x1="29.871567"
+ y1="153.99983"
+ x2="29.871567"
+ y2="252.4285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.461541,-193.81309,236.42243)"
+ x1="29.871567"
+ y1="174.58366"
+ x2="29.871567"
+ y2="259.08319" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18854"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2500001,0,0,2.2000001,-102.35484,177)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.8000001,-122.98388,285.5)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.0000001,0,0,1.6000003,163.54205,53.499972)"
+ x1="-60.266121"
+ y1="74.0625"
+ x2="-54.766121"
+ y2="84.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32725"
+ gradientUnits="userSpaceOnUse"
+ x1="-88.0625"
+ y1="364"
+ x2="-44.983891"
+ y2="411.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-117.02574,313.78567)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient32729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6666675,0,0,0.6666633,-101.32265,336.66698)"
+ x1="61.983898"
+ y1="88.999977"
+ x2="89.770271"
+ y2="121.709" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-122.97299,306.4115)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient32749"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.081988,0,0,1.0833333,-123.05997,-52.467545)"
+ x1="326.72092"
+ y1="33.927608"
+ x2="352.03485"
+ y2="60.463093" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32751"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="-46.417774"
+ y1="1.9796312"
+ x2="-21.988398"
+ y2="27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32753"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0983862,0,0,1.0999999,-128.47957,-53.059225)"
+ x1="324.13901"
+ y1="28.882492"
+ x2="333.96365"
+ y2="39.250004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(18,0)"
+ x1="-51.6875"
+ y1="442.6875"
+ x2="-42.377892"
+ y2="452.20007" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17177"
+ gradientUnits="userSpaceOnUse"
+ x1="28.322077"
+ y1="160.10768"
+ x2="32.679554"
+ y2="164.34546" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient17179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-6.8461644e-7,-1.8,1.1087755,0.00352366,-193.46828,187.54551)"
+ cx="4.351675"
+ cy="81.592964"
+ fx="4.351675"
+ fy="81.592964"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18344"
+ id="radialGradient17181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5123107,0.9569981,-0.5028837,0.7946898,-131.57281,-236.33663)"
+ cx="244.14325"
+ cy="-14.13948"
+ fx="244.14325"
+ fy="-14.13948"
+ r="3.4000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17214"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17216"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17218"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2859748,0,0,1,-272.87621,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4289612,0,0,1,-326.93899,144.5)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17222"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17224"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17226"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2868892,0,0,1,-644.69395,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="36.247395"
+ y2="249.62102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18712"
+ 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
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient18721"
+ 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"
+ id="linearGradient18728"
+ 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"
+ id="linearGradient18765"
+ 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="#linearGradient34157"
+ id="linearGradient35488"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35490"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient35492"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient35494"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35967"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.656002,0,0,0.656002,88.923481,27.003843)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath18524">
+ <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.1435655,0,0,1.1436475,512.11415,45.72091)"
+ 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="path18526"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69954133;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.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18634">
+ <path
+ sodipodi:nodetypes="ccccscc"
+ style="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"
+ d="m 207,134 0,14 11,0 0,-7.5625 c -1.97252,-0.24738 -3.5,-1.89814 -3.5,-3.9375 0,-0.94675 0.35614,-1.81444 0.90625,-2.5 L 207,134 z"
+ id="path18636" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient18478"
+ gradientUnits="userSpaceOnUse"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18480"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-97.983877,565.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35583"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="4.952816"
+ y2="-27.882322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35585"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="3.1666665"
+ y2="-29.550003" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35587"
+ gradientUnits="userSpaceOnUse"
+ x1="-3.5"
+ y1="-35.5"
+ x2="2.6932251"
+ y2="-29.488832" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35589"
+ gradientUnits="userSpaceOnUse"
+ x1="4.9341426"
+ y1="-29.678047"
+ x2="4.8398785e-16"
+ y2="-32.351803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35591"
+ gradientUnits="userSpaceOnUse"
+ x1="0.5079475"
+ y1="-32.317398"
+ x2="4.2000003"
+ y2="-28.597046" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient35593"
+ gradientUnits="userSpaceOnUse"
+ x1="2.8144052"
+ y1="-28.1"
+ x2="-4.375"
+ y2="-36.441402" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35595"
+ gradientUnits="userSpaceOnUse"
+ x1="-2.7708333"
+ y1="-35.5"
+ x2="1.1666667"
+ y2="-32" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient35740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,-206.46148,-296.13985)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="10.490564"
+ y2="176.41806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient35742"
+ gradientUnits="userSpaceOnUse"
+ x1="58.060974"
+ y1="-23.721956"
+ x2="40"
+ y2="-35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35744"
+ gradientUnits="userSpaceOnUse"
+ x1="46.1875"
+ y1="-28.59375"
+ x2="41.099998"
+ y2="-33.59375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36116"
+ id="linearGradient35746"
+ gradientUnits="userSpaceOnUse"
+ x1="46"
+ y1="-32"
+ x2="43.883884"
+ y2="-33.939339" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35748"
+ gradientUnits="userSpaceOnUse"
+ x1="41"
+ y1="-29"
+ x2="43"
+ y2="-27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35750"
+ gradientUnits="userSpaceOnUse"
+ x1="48.662914"
+ y1="-27.071922"
+ x2="43.47097"
+ y2="-32.337086" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6.3,-4.7)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.200001"
+ y2="-28.640625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(5.315625,-3.75)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.325001"
+ y2="-28.765625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35756"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(3.3,0.3)"
+ x1="38.700001"
+ y1="-31.299999"
+ x2="40.012501"
+ y2="-29.799999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35772"
+ gradientUnits="userSpaceOnUse"
+ x1="51.912914"
+ y1="-24.696922"
+ x2="40.75"
+ y2="-35.75"
+ gradientTransform="translate(-0.75,4.75)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51774"
+ gradientUnits="userSpaceOnUse"
+ x1="135.32962"
+ y1="120.04005"
+ x2="130.7244"
+ y2="116.31882" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51776"
+ gradientUnits="userSpaceOnUse"
+ x1="130.9015"
+ y1="115.23484"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient51804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.43697,300.37199)"
+ x1="107.78085"
+ y1="50.778313"
+ x2="111.53449"
+ y2="46.679707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.55698,300.497)"
+ x1="115.37703"
+ y1="51.021076"
+ x2="112.87534"
+ y2="51.021076" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.35699,300.55457)"
+ x1="110.57378"
+ y1="50.963791"
+ x2="108.07208"
+ y2="50.963791" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.36783,218.31526)"
+ x1="-13.691219"
+ y1="241.78653"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.13133,218.33837)"
+ x1="-9.0782614"
+ y1="249.96617"
+ x2="-2.9318311"
+ y2="240.68927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.5254431"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68939"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.091064"
+ y2="242.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68941"
+ gradientUnits="userSpaceOnUse"
+ x1="-41.065678"
+ y1="240.10526"
+ x2="-15.758821"
+ y2="244.11874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68943"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(440.2082,-188.0039)"
+ x1="-10.991813"
+ y1="237.9574"
+ x2="-7.0786314"
+ y2="246.7774" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.9582,-188.0039)"
+ x1="-5.1338587"
+ y1="244.08765"
+ x2="-14.193665"
+ y2="251.35759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient68947"
+ gradientUnits="userSpaceOnUse"
+ x1="-15.6"
+ y1="247.38559"
+ x2="-3.321322"
+ y2="245.68124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68949"
+ gradientUnits="userSpaceOnUse"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.7065439"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68951"
+ gradientUnits="userSpaceOnUse"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.125"
+ y2="242.81946" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68953"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.25,0.2058042)"
+ x1="-12.538609"
+ y1="240.79787"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68955"
+ gradientUnits="userSpaceOnUse"
+ x1="-7.20822"
+ y1="247.4906"
+ x2="-1.7751017"
+ y2="239.86711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient69009"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5466301,0,0,1.6489946,-293.01107,-16.485383)"
+ x1="582"
+ y1="49.294117"
+ x2="582"
+ y2="47.176472" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask69005">
+ <rect
+ style="fill:url(#linearGradient69009);fill-opacity:1;display:inline"
+ id="rect69007"
+ width="24.746082"
+ height="26.383913"
+ x="596.30127"
+ y="39.580433" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20269"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20275"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20283"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20303"
+ gradientUnits="userSpaceOnUse"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20309"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21567"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21594"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21596"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21647"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21649"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21979"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath22590">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22592"
+ width="12"
+ height="14"
+ x="-30"
+ y="490.00012" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ id="filter22979"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur22981" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter22999"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur23001" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter23007"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur23009" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter23015"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur23017" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23595"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.1666667,-737,357.33333)"
+ x1="771.0965"
+ y1="354.28479"
+ x2="772"
+ y2="358.85715" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23591">
+ <rect
+ mask="none"
+ style="fill:url(#linearGradient23595);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23593"
+ width="11"
+ height="14"
+ x="30"
+ y="768" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath23877">
+ <rect
+ transform="scale(1,-1)"
+ y="-540"
+ x="952"
+ height="6"
+ width="15"
+ id="rect23879"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23978"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23980"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320"
+ id="linearGradient23982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.733333,808.99997,-697.8)"
+ x1="150.5"
+ y1="239.9987"
+ x2="150.5"
+ y2="237" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29485"
+ id="linearGradient23986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,715,364)"
+ x1="147.0625"
+ y1="243.76387"
+ x2="142.9375"
+ y2="243.69914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30777"
+ id="linearGradient23988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2857143,364,645.14283)"
+ x1="148"
+ y1="244.11113"
+ x2="144"
+ y2="244.11113" />
+ <linearGradient
+ id="linearGradient3564"
+ inkscape:collect="always">
+ <stop
+ id="stop3566"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop3568"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39155">
+ <stop
+ id="stop39157"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39159"
+ offset="1"
+ style="stop-color:#dadada;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39171"
+ inkscape:collect="always">
+ <stop
+ id="stop39173"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39175"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient21442"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39155"
+ id="linearGradient21444"
+ gradientUnits="userSpaceOnUse"
+ x1="31.1875"
+ y1="18.875"
+ x2="29.875"
+ y2="34.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3564"
+ id="linearGradient21446"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.06818845,0,0,0.06818845,22.51112,27.02885)"
+ x1="185.9903"
+ y1="193.33229"
+ x2="190.46461"
+ y2="-458.05771" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39171"
+ id="radialGradient21448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.647222,0,0,1.26792,-15.47413,-5.79794)"
+ cx="26.109201"
+ cy="19.668886"
+ fx="26.109201"
+ fy="19.668886"
+ r="20.278975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39281"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="71"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39283"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1944456,0,0,1.2000039,-34.222431,-14.950295)"
+ x1="175.17659"
+ y1="74.972061"
+ x2="176.40117"
+ y2="76.182281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39285"
+ gradientUnits="userSpaceOnUse"
+ x1="165.19363"
+ y1="64.53186"
+ x2="176.15442"
+ y2="76.210785" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39287"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="172.30418"
+ y1="69.838829"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39289"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39291"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39293"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39008"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39010"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39012"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39014"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39016"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39018"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39022"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39024"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39026"
+ x1="1127.7983"
+ y1="448.375"
+ x2="1153.0486"
+ y2="430.25"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient57417"
+ gradientUnits="userSpaceOnUse"
+ x1="146.82516"
+ y1="134.65511"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient57419"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57421"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57423"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient57454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(258.00306,-231.00101)"
+ x1="75.25"
+ y1="393.25"
+ x2="73.5"
+ y2="391.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask57450">
+ <rect
+ y="154.99899"
+ x="326.00305"
+ height="15"
+ width="15"
+ id="rect57452"
+ style="fill:url(#linearGradient57454);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22891"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="174.99828"
+ y1="12.918247"
+ x2="167.59578"
+ y2="12.551482" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22893"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="169.47711"
+ y1="10.424105"
+ x2="169.47711"
+ y2="8.1183796" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22895"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.728189,0,0,1.727271,237.88848,243.63713)"
+ x1="169.41847"
+ y1="10.306772"
+ x2="169.4877"
+ y2="7.9604731" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="145.00008"
+ y1="11.99999"
+ x2="160.31258"
+ y2="19.34374" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="149.00008"
+ y1="10.924165"
+ x2="171.37508"
+ y2="19.12499" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient22901"
+ gradientUnits="userSpaceOnUse"
+ x1="-68.25"
+ y1="263"
+ x2="-56"
+ y2="265.53439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22903"
+ gradientUnits="userSpaceOnUse"
+ x1="-66"
+ y1="264"
+ x2="-57"
+ y2="264.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32998"
+ id="linearGradient22905"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="176.42079"
+ y1="12.946938"
+ x2="169.47711"
+ y2="12.36799" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient22933"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22935"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient22937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22939"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22941"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22970"
+ x1="-197.84375"
+ y1="399.90625"
+ x2="-191"
+ y2="409"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19625"
+ id="linearGradient23241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="476.76578"
+ y2="162.94037" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12678"
+ id="radialGradient23245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0982561,0,0,1.2662999,-45.858153,-42.45126)"
+ cx="470.15939"
+ cy="164.46814"
+ fx="470.15939"
+ fy="164.46814"
+ r="3.500145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23247"
+ gradientUnits="userSpaceOnUse"
+ x1="128.7561"
+ y1="115.77483"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23250"
+ gradientUnits="userSpaceOnUse"
+ x1="127.30917"
+ y1="111.48133"
+ x2="138.30522"
+ y2="124.69373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23445"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="475.50031"
+ y2="162.92206" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23447"
+ 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="#linearGradient23974"
+ id="linearGradient23531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.37032"
+ y1="12.147777"
+ x2="175.38158"
+ y2="15.699567" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23533"
+ gradientUnits="userSpaceOnUse"
+ x1="155.82454"
+ y1="16.845156"
+ x2="158.41653"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.727201,9.075096e-6,0,1.728246,-147.7149,-10.37485)"
+ x1="171.03941"
+ y1="11.121979"
+ x2="175.33569"
+ y2="16.202652" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.18394"
+ y1="11.912162"
+ x2="176.46956"
+ y2="16.427906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40847"
+ gradientUnits="userSpaceOnUse"
+ x1="156.00008"
+ y1="16.99999"
+ x2="159.00008"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40965"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,14)"
+ x1="62.107086"
+ y1="223.54628"
+ x2="96.812675"
+ y2="258.38593" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient40967"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-21,0)"
+ x1="79.04213"
+ y1="253.5"
+ x2="60.155113"
+ y2="234.7775" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24098"
+ x1="208.25"
+ y1="-133.89581"
+ x2="204.01923"
+ y2="-111.15749"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23510"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3008215,-8.6726798)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23512"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="110.16959"
+ y1="57.061836"
+ x2="117.55341"
+ y2="64.995972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23514"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3010161,-8.6726854)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="54.252415"
+ y2="100.44998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23550"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,0.01738631)"
+ x1="468.07968"
+ y1="275.27036"
+ x2="510"
+ y2="266.99997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient23555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,3.959006e-5)"
+ x1="492.95264"
+ y1="267.42996"
+ x2="496.73859"
+ y2="270.36874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23581"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,404.07104,216.722)"
+ x1="116.75796"
+ y1="52.264809"
+ x2="103.18628"
+ y2="55.747272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient23585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-1.0000037)"
+ x1="500.71924"
+ y1="270.24997"
+ x2="477"
+ y2="274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="radialGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="radialGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0009003,-1.5278593,1.1592123,0.7594114,-59.938837,957.7287)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23562"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,461.68129,182.37748)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="56.524509"
+ y2="101.25028" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,323.39462,186.24644)"
+ x1="115.45872"
+ y1="58.869785"
+ x2="106.20376"
+ y2="58.354706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,347.39462,166.24644)"
+ x1="110.54202"
+ y1="56.645538"
+ x2="115.53827"
+ y2="63.567348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2445337,0,0,1.5876961,523.20711,115.4619)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,503.28129,157.47747)"
+ x1="29.506693"
+ y1="100.66651"
+ x2="34.276955"
+ y2="105.98901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24054"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24066"
+ x1="202.5"
+ y1="143.84116"
+ x2="202.5"
+ y2="132.60213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-259,202)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient23738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23750"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,59.49999,53.45766)"
+ x1="445.5"
+ y1="148.90862"
+ x2="433.5"
+ y2="148.69533" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6499984,0,0,0.5439483,434.02514,137.87435)"
+ x1="113.71248"
+ y1="158.24995"
+ x2="91.499992"
+ y2="158.24994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0052083,0,0,0.5057472,778.49218,365.83334)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23914"
+ gradientUnits="userSpaceOnUse"
+ x1="29.200638"
+ y1="160.18758"
+ x2="32.928555"
+ y2="164.13913" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23916"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.02887268,-1.2550276,0.795821,0.01830762,8.763469,168.20647)"
+ cx="11.708446"
+ cy="81.275032"
+ fx="11.708446"
+ fy="81.275032"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.01269957,-0.9297674,1.1086869,0.01514236,-16.51473,165.70609)"
+ cx="4.7455525"
+ cy="82.433929"
+ fx="4.7455525"
+ fy="82.433929"
+ r="5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24460"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(383,-37.999994)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24456">
+ <rect
+ y="108"
+ x="299"
+ height="17"
+ width="7"
+ id="rect24458"
+ style="fill:url(#linearGradient24460);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-142.95536)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24466">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient24470);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24468"
+ width="7"
+ height="9"
+ x="276"
+ y="4.0625" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23971"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23973"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23975"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24099"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24539"
+ 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"
+ id="linearGradient24541"
+ 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"
+ id="linearGradient24543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="483.00034"
+ y1="163"
+ x2="476.68781"
+ y2="162.85956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24545"
+ 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"
+ id="linearGradient24547"
+ gradientUnits="userSpaceOnUse"
+ x1="475.00034"
+ y1="155"
+ x2="469.75034"
+ y2="155" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,-6e-5)"
+ x1="442.81525"
+ y1="290.49384"
+ x2="436.5"
+ y2="290.5249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient24551"
+ gradientUnits="userSpaceOnUse"
+ x1="445.99902"
+ y1="288.5"
+ x2="407.3793"
+ y2="288.5" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath24168">
+ <path
+ style="fill:#808080;fill-rule:evenodd;stroke:none"
+ d="m 134.27489,222.11125 c -3.9249,-6.46418 -7.61892,6.46419 -11.54381,0 l 0,0 -1.61614,0 0,8.77283 14.77608,0 0,-8.77283 -1.61613,0 z"
+ id="path24170"
+ sodipodi:nodetypes="cccccccc" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient24112"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24114"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="302.84085"
+ y1="243.23151"
+ x2="308.82889"
+ y2="244.70323" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6879084,0,0,0.6879446,216.19282,166.82605)"
+ x1="121.7408"
+ y1="115.90587"
+ x2="130.01318"
+ y2="116.60553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24121"
+ gradientUnits="userSpaceOnUse"
+ x1="135.698"
+ y1="122.92034"
+ x2="129.70906"
+ y2="117.15551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24123"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="162.61801"
+ y1="4.5569806"
+ x2="180.11391"
+ y2="23.410421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24192"
+ gradientUnits="userSpaceOnUse"
+ x1="167.43744"
+ y1="23.749996"
+ x2="175.06059"
+ y2="32.144764"
+ gradientTransform="translate(-94.937441,240)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="166.86487"
+ y1="12.306217"
+ x2="173.93744"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24268"
+ gradientUnits="userSpaceOnUse"
+ x1="186.74992"
+ y1="10.795519"
+ x2="189.24992"
+ y2="9.0189686"
+ gradientTransform="matrix(1,0,0,-0.985055,75.000075,275.63418)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24277"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient24395"
+ x1="-27.5"
+ y1="268.76776"
+ x2="-39.875"
+ y2="277.4375"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15893"
+ id="linearGradient41127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,594,-42.40625)"
+ x1="409.45645"
+ y1="52.77837"
+ x2="402.30673"
+ y2="55.86327" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27957"
+ id="linearGradient41129"
+ gradientUnits="userSpaceOnUse"
+ x1="180.20316"
+ y1="8.0551176"
+ x2="192.75177"
+ y2="12.942369" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41172"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="268.21783"
+ y1="200.66605"
+ x2="284.9375"
+ y2="224.1875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient41174"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42069"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="276.39999"
+ y1="215.3125"
+ x2="265.70886"
+ y2="196.576" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42115"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(60,-342)"
+ x1="206"
+ y1="535"
+ x2="212"
+ y2="549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="263"
+ y1="193.93752"
+ x2="296.25"
+ y2="239.89455" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="265.98389"
+ y1="195"
+ x2="290.98389"
+ y2="232" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40722"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9819031,0,0,0.9481466,-88.271503,-83.584533)"
+ x1="1.6577729"
+ y1="253.01927"
+ x2="-57.772419"
+ y2="253.62515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.977157,0,0,0.9835482,0.06815071,100.43848)"
+ x1="107.84375"
+ y1="57.374996"
+ x2="116.99999"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="241.17908"
+ y1="214.40446"
+ x2="279.89563"
+ y2="254.94975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6025789,0,0,0.668336,263.48819,85.675422)"
+ x1="49.543404"
+ y1="230.81766"
+ x2="73.932747"
+ y2="247.27646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9120445,0,0,1,25.749745,8.9261515)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="308.97327"
+ y2="242" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.584271,0,0,0.661005,267.80323,78.438648)"
+ x1="51.682816"
+ y1="229.19724"
+ x2="73.932762"
+ y2="247.35141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40742"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9103441,0,0,0.989031,29.299938,2.5312404)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="307.25021"
+ y2="241.62509" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40758"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.997359,-17.993456)"
+ x1="199.4335"
+ y1="294.81082"
+ x2="196.00264"
+ y2="259.99347" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40760"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,51.339144,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40762"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,59.339161,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40788"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="146.51619"
+ y1="217.52046"
+ x2="174.56255"
+ y2="252.52081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient40790"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18056"
+ id="linearGradient40792"
+ gradientUnits="userSpaceOnUse"
+ x1="170.42908"
+ y1="237.25"
+ x2="170.71698"
+ y2="249.15927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40794"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.5625"
+ y1="249.55817"
+ x2="168.5"
+ y2="240.10249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40545"
+ gradientUnits="userSpaceOnUse"
+ x1="279.38629"
+ y1="-16.946415"
+ x2="293.80472"
+ y2="-2.5475447" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40547"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9230687,0,0,0.9230801,261.38476,-234.15464)"
+ x1="43.921535"
+ y1="261.52924"
+ x2="29.429007"
+ y2="243.98439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23775"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9230769,0,0,-0.9258123,59.615385,471.81593)"
+ x1="-0.71355486"
+ y1="209.97131"
+ x2="37.5"
+ y2="252.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23777"
+ gradientUnits="userSpaceOnUse"
+ x1="72.698921"
+ y1="599.20789"
+ x2="77.111115"
+ y2="604.11108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23351"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23353"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23355"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23357"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23599"
+ x1="191"
+ y1="158.72728"
+ x2="196.59441"
+ y2="167.67831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.89375,0,0,0.89375,20.29375,17.10625)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22704"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23132"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23134"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23147"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23177"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23183"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23185"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23231"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23235"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23239"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23257"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23563"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23566"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23576"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23587"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23589"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23591"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23597"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23616"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23618"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23620"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23626"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23635"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23637"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23799"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23801"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23807"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23811"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23821"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23827"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23829"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23833"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23835"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23837"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23853"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23860"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42685"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient22892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22917"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22922"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="262.67139"
+ cy="74.072273"
+ fx="262.67139"
+ fy="74.072273"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient22954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37925"
+ id="linearGradient23890"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient23892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23906"
+ id="radialGradient23894"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0553103,1.0606182,-1.2516598,1.280294,67.321819,-297.60493)"
+ cx="262.07156"
+ cy="74.306007"
+ fx="262.07156"
+ fy="74.306007"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="radialGradient23898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient24090"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient24092"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24094"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="263.21707"
+ cy="74.441246"
+ fx="263.21707"
+ fy="74.441246"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient24102"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24104"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="66.954422"
+ y1="240.03282"
+ x2="68.458534"
+ y2="246.96069" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="244.37868"
+ y1="285.00754"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24695"
+ id="linearGradient24374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.97597"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-150.99992,596.00357)"
+ x1="199.87271"
+ y1="272.29477"
+ x2="212.22493"
+ y2="287.50357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24811"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.539974"
+ y1="421.80756"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24841"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24144"
+ id="linearGradient24843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="64.019142"
+ y1="419.06366"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24867"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24869"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24871"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.659767"
+ y1="422.46088"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24873"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25073"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25075"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient42055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.94298"
+ y1="281.27435"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient42057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42059"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient24132"
+ gradientUnits="userSpaceOnUse"
+ x1="445.77841"
+ y1="113.24564"
+ x2="426.11459"
+ y2="84.777061" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24599"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1489145,-0.69297,0.4772363,0.7912359,-113.08929,303.20064)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7236207,-0.7167103,1.004637,1.0143218,-131.254,253.93955)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient24797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.3967"
+ y1="310.77368"
+ x2="309.02371"
+ y2="308.51169" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24820"
+ x1="311.37668"
+ y1="311.88205"
+ x2="307.5"
+ y2="308.21875"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4011721,0.3766097,-0.7099042,0.7562044,179.21454,-58.566632)"
+ cx="207.04807"
+ cy="78.473343"
+ fx="207.04807"
+ fy="78.473343"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4543499,0.4687811,-0.6244606,0.6052369,161.562,-65.729731)"
+ cx="206.39249"
+ cy="78.443413"
+ fx="206.39249"
+ fy="78.443413"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="248.69196"
+ y1="279.72827"
+ x2="269.3085"
+ y2="303.10999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient62558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,-33.03632,32.03632)"
+ x1="289.61554"
+ y1="320.55179"
+ x2="250.22783"
+ y2="282.28745" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62560"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,59,638)"
+ x1="354.50601"
+ y1="283.61511"
+ x2="327.92044"
+ y2="300.96124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25381"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25383"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25385"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25387"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25369">
+ <g
+ id="g25371"
+ transform="translate(-21,-21)">
+ <path
+ style="fill:url(#linearGradient25381);fill-rule:evenodd;stroke:none"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ id="path25373"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="4" />
+ <path
+ inkscape:transform-center-y="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25375"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ style="fill:url(#linearGradient25383);fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:transform-center-x="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25377"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ style="fill:url(#linearGradient25385);fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:transform-center-y="4"
+ sodipodi:nodetypes="cccc"
+ id="path25379"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ style="fill:url(#linearGradient25387);fill-rule:evenodd;stroke:none" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.01321"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25579"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25561">
+ <g
+ transform="translate(-21,-21)"
+ id="g25563">
+ <path
+ inkscape:transform-center-x="4"
+ sodipodi:nodetypes="cccc"
+ id="path25565"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ style="fill:url(#linearGradient25573);fill-rule:evenodd;stroke:none" />
+ <path
+ style="fill:url(#linearGradient25575);fill-rule:evenodd;stroke:none"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ id="path25567"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="-4" />
+ <path
+ style="fill:url(#linearGradient25577);fill-rule:evenodd;stroke:none"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ id="path25569"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="-4" />
+ <path
+ style="fill:url(#linearGradient25579);fill-rule:evenodd;stroke:none"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ id="path25571"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="4" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25872"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,328.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25874"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,111)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="243.92192"
+ y1="-2.6686089"
+ x2="275.10107"
+ y2="26.600887" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25888"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25890"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25892"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25894"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-72.000001)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25927"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25929"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25931"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25957"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25961"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-112)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25984"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-88.000005)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient26011"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient26013"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26015"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,-76.000004)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient26077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26083"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26126"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26128"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26130"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="68.383354"
+ y1="239.95235"
+ x2="69.285805"
+ y2="247.29691" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27973"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27975"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28099"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient28107"
+ gradientUnits="userSpaceOnUse"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845"
+ gradientTransform="translate(-19,294.91429)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient27448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-19,294.91429)"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27450"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27540"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27544"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient27598"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient27600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27604"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient27606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient27610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient30389"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30391"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient30393"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient30395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient30397"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29129"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27767"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27769"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient27771"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="112.18942"
+ y1="114.71685"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27773"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient31865"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.986122,0,0,0.986122,2.8033684,0.804927)"
+ cx="202"
+ cy="58"
+ fx="202"
+ fy="58"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask31861">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient31865);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path31863"
+ sodipodi:cx="202"
+ sodipodi:cy="58"
+ sodipodi:rx="11"
+ sodipodi:ry="11"
+ d="m 213,58 a 11,11 0 1 1 -22,0 11,11 0 1 1 22,0 z" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath31849">
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 232.13187,93.950853 4.84276,0 4.23742,4.237465 0,4.842822 -9.08018,0 0,-9.080287 0,0 z"
+ id="path31851"
+ sodipodi:nodetypes="cccccc" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ id="filter30544"
+ x="-0.11968782"
+ width="1.2393756"
+ y="-0.12031381"
+ height="1.2406276"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.59634694"
+ id="feGaussianBlur30546" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30552"
+ x="-0.12"
+ width="1.24"
+ y="-0.12"
+ height="1.24"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.4"
+ id="feGaussianBlur30554" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30556"
+ x="-0.12"
+ width="1.24"
+ y="-0.12"
+ height="1.24"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.4"
+ id="feGaussianBlur30558" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30564"
+ x="-0.12000064"
+ width="1.2400013"
+ y="-0.11999936"
+ height="1.2399987"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.36320908"
+ id="feGaussianBlur30566" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30580"
+ x="-0.11981065"
+ width="1.2396213"
+ y="-0.12018995"
+ height="1.2403799"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.479335"
+ id="feGaussianBlur30582" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32298"
+ gradientUnits="userSpaceOnUse"
+ x1="-117.5"
+ y1="431.5"
+ x2="-119.5"
+ y2="429.5"
+ gradientTransform="translate(258,-96.99999)" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask32294">
+ <rect
+ y="323"
+ x="134"
+ height="16"
+ width="9"
+ id="rect32296"
+ style="fill:url(#linearGradient32298);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53119"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53123"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53125"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient53127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient53129"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="362.79037"
+ y1="-159.88834"
+ x2="373.83752"
+ y2="-150.41035" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53131"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9900316,0,0,1,2.450297,0.00704954)"
+ x1="343.51892"
+ y1="175.19124"
+ x2="350.97491"
+ y2="183.3365" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53133"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53139"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53141"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53143"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53145"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53147"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient53149"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient53151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,115.625,254.97076)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient53157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53159"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient53161"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,237.00668)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53163"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53165"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53171"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient50870"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2e-6,0)"
+ x1="-22.902081"
+ y1="448"
+ x2="-14.000002"
+ y2="448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33427"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="136.04924"
+ y2="121.25749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33429"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient33585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7071068,-0.7071068,0.7071067,0.7071067,-140.04288,401.30258)"
+ x1="458.99997"
+ y1="89.363937"
+ x2="452.63602"
+ y2="90.071045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31356"
+ id="linearGradient33831"
+ gradientUnits="userSpaceOnUse"
+ x1="134.00002"
+ y1="116"
+ x2="142.00002"
+ y2="108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33833"
+ gradientUnits="userSpaceOnUse"
+ x1="124.75568"
+ y1="112.24533"
+ x2="132.97911"
+ y2="120.16792" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33835"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="254.19829"
+ y1="2.1803131"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37475"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37477"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="275.62497"
+ y2="26.679274" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37479"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37481"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37483"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37485"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37487"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37489"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37491"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.5793179,0,-1.0159927e-7,-1.6412688,666.67947,207.37331)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37493"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37495"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37497"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37499"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37501"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37503"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37505"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37507"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37509"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3336259,0,-8.5793649e-8,-1.3859393,603.17514,187.32668)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3648614,0,-8.7803051e-8,-1.4184,611.24862,189.87526)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37517"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37519"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37521"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient37525"
+ gradientUnits="userSpaceOnUse"
+ x1="337.34329"
+ y1="43.328976"
+ x2="330.27045"
+ y2="35.276588" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37527"
+ gradientUnits="userSpaceOnUse"
+ x1="329.9158"
+ y1="35.5"
+ x2="335.27429"
+ y2="41.570362" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="166.89752"
+ y1="9.0567484"
+ x2="193.26451"
+ y2="38.642647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37531"
+ gradientUnits="userSpaceOnUse"
+ x1="127.93343"
+ y1="122.8346"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37533"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37535"
+ gradientUnits="userSpaceOnUse"
+ x1="122.86111"
+ y1="127.14286"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37537"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37539"
+ gradientUnits="userSpaceOnUse"
+ x1="266"
+ y1="659"
+ x2="285"
+ y2="659" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient37541"
+ gradientUnits="userSpaceOnUse"
+ x1="244.21062"
+ y1="600.74884"
+ x2="244.21062"
+ y2="602.96759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35407"
+ id="linearGradient37543"
+ gradientUnits="userSpaceOnUse"
+ x1="235.29379"
+ y1="588.43396"
+ x2="245.93307"
+ y2="604.52502" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37545"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37547"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37553"
+ gradientUnits="userSpaceOnUse"
+ x1="86.248604"
+ y1="32"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="81"
+ y1="27"
+ x2="64.5"
+ y2="9.0000019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient37557"
+ gradientUnits="userSpaceOnUse"
+ x1="70.78582"
+ y1="15.659542"
+ x2="79.465332"
+ y2="24.480759" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient37559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5997527,0.4726093,-0.6665451,0.8458611,35.480681,-28.765852)"
+ cx="63.013588"
+ cy="14.60904"
+ fx="63.013588"
+ fy="14.60904"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37571"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient37573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="83.261826"
+ y1="502.54196"
+ x2="41.311054"
+ y2="501.10059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient37575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37578"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37580"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2665671,0.04035316,-0.03648524,1.99062,-82.893589,-502.25433)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37584"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37586"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37588"
+ gradientUnits="userSpaceOnUse"
+ x1="264.10001"
+ y1="330.10001"
+ x2="264.89999"
+ y2="330.89999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient37590"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37592"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="51.37524"
+ y1="96.955269"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient37594"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37596"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient37612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37614"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37636"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="387.30396"
+ y1="126.23978"
+ x2="332.88193"
+ y2="123.61623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37640"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42322"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42324"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42326"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42328"
+ gradientUnits="userSpaceOnUse"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42330"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42332"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42334"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42336"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42338"
+ gradientUnits="userSpaceOnUse"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42340"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42342"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42344"
+ gradientUnits="userSpaceOnUse"
+ x1="-69.457596"
+ y1="31.914484"
+ x2="-76.564636"
+ y2="28.695114" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42346"
+ gradientUnits="userSpaceOnUse"
+ x1="-57.780041"
+ y1="48.005856"
+ x2="-78.812721"
+ y2="31" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42348"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42350"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.2998291,32.548709,64.760571)"
+ x1="51.497997"
+ y1="97.491707"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42352"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,79.011866)"
+ x1="51.497997"
+ y1="94.987144"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,83.013491)"
+ x1="51.497997"
+ y1="94.987129"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197983,83.013493)"
+ x1="48.998543"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42358"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197981,79.010163)"
+ x1="48.99855"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,42.19798,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196563,83.013493)"
+ x1="48.998539"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196561,79.010163)"
+ x1="48.998547"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,46.19656,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42368"
+ gradientUnits="userSpaceOnUse"
+ x1="-109.125"
+ y1="52.625"
+ x2="-121.73741"
+ y2="38.387074" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42370"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42372"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42374"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42376"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-41,98)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42378"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42380"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42382"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-57.134785,102.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42384"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-92.714287,177.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42386"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42388"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42390"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42392"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient42394"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1226244,0.04761823,-0.1611956,3.8002759,59.188894,-553.59611)"
+ cx="-215.0979"
+ cy="201.01204"
+ fx="-215.0979"
+ fy="201.01204"
+ r="5.8999949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42396"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,4)"
+ x1="-224"
+ y1="201"
+ x2="-214.39445"
+ y2="195.27762" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="209.05762"
+ y1="290.00357"
+ x2="215.34009"
+ y2="277.00357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42400"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42402"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42404"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42408"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42410"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42414"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="133.62697"
+ y2="120.49951" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42418"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42420"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-120,79)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42422"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-136.13478,83.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-171.71429,158.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient42430"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1664.4413"
+ y1="720.01788"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient42432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1977.4047"
+ y2="829.72656" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42436"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42438"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42440"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42442"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42444"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42446"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1658027,0,0,1.1657997,-354.28972,51.94393)"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42462"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42464"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42466"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8370074,0,0,0.8129865,84.784966,-149.92038)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,11.285548,8.325368)"
+ x1="111.03847"
+ y1="57.034107"
+ x2="117.16058"
+ y2="60.591385" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42472"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42474"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42477"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42479"
+ gradientUnits="userSpaceOnUse"
+ x1="-92.587807"
+ y1="-18.005362"
+ x2="-100.62162"
+ y2="-17.998919" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42481"
+ gradientUnits="userSpaceOnUse"
+ x1="-101"
+ y1="-16"
+ x2="-93"
+ y2="-17" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42483"
+ gradientUnits="userSpaceOnUse"
+ x1="-87.491188"
+ y1="-22.830606"
+ x2="-102.96513"
+ y2="-22.166544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42485"
+ gradientUnits="userSpaceOnUse"
+ x1="-98.997849"
+ y1="-23.173643"
+ x2="-98.997849"
+ y2="-25.872688" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42487"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42489"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42491"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42493"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5290924,0,0,0.5294132,-17.313533,46.110999)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42495"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5350034,0,0,0.5349052,24.446207,45.843517)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42497"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42499"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42501"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42503"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42505"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42507"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42509"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42511"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4749148,1.0023386,-1.2226848,-0.4749148,213.62384,41.735193)"
+ x1="118.95689"
+ y1="106.42961"
+ x2="135.14919"
+ y2="119.05286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5333554,1.1220467,-1.1447545,-0.5333554,196.63818,32.816067)"
+ x1="130.39502"
+ y1="116.31751"
+ x2="147.95374"
+ y2="134.687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient42517"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42519"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42521"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42523"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42525"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,26.488451,35.562258)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35408"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35414"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35418"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35420"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35422"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35424"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35468"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35470"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35476"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35478"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35480"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35482"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35484"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35486"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35488"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient34618"
+ gradientUnits="userSpaceOnUse"
+ x1="125.59209"
+ y1="112.6446"
+ x2="133.11621"
+ y2="119.21729" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient34620"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="141.83322"
+ y2="132.30261" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35446"
+ gradientUnits="userSpaceOnUse"
+ x1="31"
+ y1="60.000004"
+ x2="34"
+ y2="54.000004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35448"
+ gradientUnits="userSpaceOnUse"
+ x1="135.46967"
+ y1="118"
+ x2="121.4286"
+ y2="101.14284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35450"
+ gradientUnits="userSpaceOnUse"
+ x1="133.60002"
+ y1="118"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35452"
+ gradientUnits="userSpaceOnUse"
+ x1="132.30316"
+ y1="123.05057"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35454"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35718"
+ x1="28.130203"
+ y1="65.791054"
+ x2="32.5"
+ y2="55.066181"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient36452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,137.60085,-8.4035259)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,131.60084,3.5964741)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36458"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,143.60084,3.5964739)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37095"
+ gradientUnits="userSpaceOnUse"
+ x1="125.75312"
+ y1="111.40558"
+ x2="143.16118"
+ y2="129.27902" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="185.89514"
+ y1="30.343155"
+ x2="197.03207"
+ y2="42.717522" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="188"
+ y1="40.25"
+ x2="180.8125"
+ y2="32.46875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="187.8125"
+ y1="33.9375"
+ x2="184.25"
+ y2="30.15625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3.0999952,2.9000005)"
+ x1="177.85001"
+ y1="33.537502"
+ x2="186.00626"
+ y2="43.381248" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,6.188671,1.0072576)"
+ x1="182.20605"
+ y1="39.645184"
+ x2="172.36885"
+ y2="31.368597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36656"
+ gradientUnits="userSpaceOnUse"
+ x1="181.14906"
+ y1="32.701904"
+ x2="186.00002"
+ y2="37.415516" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,9.438677,-2.4927424)"
+ x1="181.9404"
+ y1="40.924297"
+ x2="175.82253"
+ y2="34.272892" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient36470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36713"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36715"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36721"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36727"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37396"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37398"
+ gradientUnits="userSpaceOnUse"
+ x1="389.51059"
+ y1="241.72565"
+ x2="388.20074"
+ y2="242.55887"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,0)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,-582)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38561">
+ <g
+ id="g38563">
+ <rect
+ y="278"
+ x="-23"
+ height="13"
+ width="16"
+ id="rect38565"
+ style="fill:url(#linearGradient38570);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:url(#linearGradient38572);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38567"
+ width="16"
+ height="13"
+ x="-23"
+ y="-304" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-1" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-7-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-4-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-4-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-8-3" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7-6"
+ id="linearGradient39048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="96"
+ y1="42"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-4-2"
+ id="linearGradient39050"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="65"
+ y1="20"
+ x2="66"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-4"
+ id="linearGradient39052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="67.25"
+ y1="18"
+ x2="68"
+ y2="16" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-4-27"
+ id="linearGradient39835-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8422958,0,0,0.8364537,82.535678,2.9394266)"
+ x1="89.975014"
+ y1="-32.339718"
+ x2="88.492455"
+ y2="-33.303608" />
+ <linearGradient
+ id="linearGradient35411-4-27">
+ <stop
+ id="stop35414-0-9"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-9-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39837-4"
+ gradientUnits="userSpaceOnUse"
+ x1="131.02808"
+ y1="123.49161"
+ x2="128.7139"
+ y2="115.97001" />
+ <linearGradient
+ id="linearGradient35411-8-1-3">
+ <stop
+ id="stop35414-2-7-1"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-4-1-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39839-3"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-5-4"
+ id="linearGradient39841-3"
+ gradientUnits="userSpaceOnUse"
+ x1="115.15884"
+ y1="88.476723"
+ x2="109.18613"
+ y2="82.308861" />
+ <linearGradient
+ id="linearGradient23974-5-4">
+ <stop
+ id="stop23976-27-1"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-6-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-8"
+ id="linearGradient39843-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="101"
+ y1="84.25"
+ x2="97.75"
+ y2="81.5" />
+ <linearGradient
+ id="linearGradient1610-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-77"
+ id="linearGradient39845-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="87.44548"
+ y1="81.439644"
+ x2="96.592278"
+ y2="89.708977" />
+ <linearGradient
+ id="linearGradient319-77">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-31" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41540"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient23974-4">
+ <stop
+ id="stop23976-20"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-9"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-37"
+ id="linearGradient32529-7"
+ gradientUnits="userSpaceOnUse"
+ x1="139.2112"
+ y1="111.35809"
+ x2="125.18381"
+ y2="128" />
+ <linearGradient
+ id="linearGradient319-37">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-60" />
+ </linearGradient>
+ <linearGradient
+ y2="125.77761"
+ x2="139.07738"
+ y1="115.76797"
+ x1="129.62384"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient41582"
+ xlink:href="#linearGradient23974-4"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient41666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient41670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41674"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41676"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42432"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42435"
+ gradientUnits="userSpaceOnUse"
+ x1="135.45557"
+ y1="122.90726"
+ x2="130.54761"
+ y2="116.54932" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42437"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath42711">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42713"
+ width="8.7252884"
+ height="17.464855"
+ x="127.4093"
+ y="214.76154" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient38796-7-9">
+ <stop
+ style="stop-color:#fc9694;stop-opacity:1;"
+ offset="0"
+ id="stop38798-6-8" />
+ <stop
+ style="stop-color:#e71609;stop-opacity:1;"
+ offset="1"
+ id="stop38800-1-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-87">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-78" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679-1">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681-0" />
+ <stop
+ id="stop24683-7"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38719"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38722"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient38724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.46314"
+ y1="113.45913"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38726"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38007"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-1">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-7"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43410-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-0">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-4" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43412-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38796-7-9"
+ id="linearGradient40270"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="59.622501"
+ y1="54.1525"
+ x2="60.981617"
+ y2="55.566177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="57.789688"
+ y2="54.130001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="56"
+ y2="52.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.54625,-1)"
+ x1="63.666252"
+ y1="37.960625"
+ x2="60.676094"
+ y2="34.685287" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679-1"
+ id="linearGradient40278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="52.17437"
+ y1="65.644958"
+ x2="50.371208"
+ y2="62.960247" />
+ <linearGradient
+ id="linearGradient24143-0">
+ <stop
+ id="stop24145-0"
+ offset="0"
+ style="stop-color:#2c2c2c;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669-1" />
+ <stop
+ id="stop24147-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-3-7"
+ id="linearGradient39686-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-70.605209"
+ y1="-121.58411"
+ x2="-28.177105"
+ y2="-89.026711" />
+ <linearGradient
+ id="linearGradient1610-3-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-9-4"
+ id="linearGradient39688-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-74"
+ y1="-124"
+ x2="-55.5975"
+ y2="-103.2075" />
+ <linearGradient
+ id="linearGradient319-5-9-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-24-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-6">
+ <stop
+ id="stop37544-18"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-92"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-3" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-41" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-1">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-9" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient59371">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop59373" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop59375" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-9-1"
+ id="linearGradient42965-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(301.02752,449.99999)"
+ x1="25.963812"
+ y1="155.66899"
+ x2="29.972469"
+ y2="168" />
+ <linearGradient
+ id="linearGradient319-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-92-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-55-5" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter24186-3-2"
+ x="-0.12810811"
+ width="1.2562162"
+ y="-0.11285714"
+ height="1.2257143"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.395"
+ id="feGaussianBlur24188-3-7" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-06-1"
+ id="linearGradient42967-6"
+ gradientUnits="userSpaceOnUse"
+ x1="335.96875"
+ y1="607.09375"
+ x2="337.04251"
+ y2="628.20752" />
+ <linearGradient
+ id="linearGradient1610-06-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-1-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41266"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41268"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41270"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient41272"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient40920"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40922"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40924"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40926"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,404.60763,237.35923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient40928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9435203,-2.1990242,1.1704696,1.0049395,-665.14472,173.40654)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40930"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient40932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-6"
+ id="linearGradient36549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1511102,0,0,-1.1511102,152.68442,762.00423)"
+ x1="-16.608393"
+ y1="199.5118"
+ x2="30.713354"
+ y2="245.13458" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="radialGradient36551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6959954,0.116912,-0.04402498,0.2620878,107.60035,414.99606)"
+ cx="32.193073"
+ cy="243.37001"
+ fx="32.193073"
+ fy="243.37001"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143-0"
+ id="linearGradient36553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,147.99998,720.60935)"
+ x1="32.204613"
+ y1="233.6039"
+ x2="35.615856"
+ y2="251.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36555"
+ gradientUnits="userSpaceOnUse"
+ x1="148.76726"
+ y1="134.53409"
+ x2="114.11786"
+ y2="101.28939" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809"
+ id="linearGradient36557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="481.60803"
+ y1="163.09677"
+ x2="477.10818"
+ y2="163.00024" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient59371"
+ id="linearGradient36559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500181,0,0,0.8546123,-235.38338,339.18935)"
+ x1="473.79471"
+ y1="164.64572"
+ x2="463.90472"
+ y2="160.80888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-1"
+ id="linearGradient36561"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36563"
+ gradientUnits="userSpaceOnUse"
+ x1="138.46678"
+ y1="124.90586"
+ x2="126.18426"
+ y2="116.14438" />
+ <linearGradient
+ id="linearGradient9030-7-8-6">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-4-9-2" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-0-2-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809-2-2">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811-1-6" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813-4-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-7-5-5">
+ <stop
+ id="stop20057-1-7-7"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-1-6-8"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-4-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-8-5-8" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-8-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37829">
+ <stop
+ id="stop37831"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop37833" />
+ <stop
+ id="stop37835"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39254"
+ 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="#linearGradient40578-4-8"
+ id="radialGradient39256"
+ 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="#linearGradient58334"
+ id="linearGradient39258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ id="linearGradient40455-7">
+ <stop
+ id="stop40457-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36657"
+ 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="#linearGradient40578-4-8"
+ id="radialGradient36659"
+ 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="#linearGradient58334"
+ id="linearGradient36661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient36663"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37829"
+ id="linearGradient37089"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,165.4,716.20935)"
+ x1="261.17639"
+ y1="247.85646"
+ x2="253.86414"
+ y2="288.70752" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39080"
+ id="linearGradient37091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.888884,0,0,-0.8730569,136.66557,688.20759)"
+ x1="261.60016"
+ y1="247.008"
+ x2="263.60016"
+ y2="262.27994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-124.99991,219.9903)"
+ x1="19.923029"
+ y1="232.59058"
+ x2="50.485012"
+ y2="265.9697" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809-2-2"
+ id="linearGradient37096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="199.26254"
+ y1="144.5041"
+ x2="193.7029"
+ y2="144.5041" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-7-5-5"
+ id="linearGradient37098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="579.625"
+ y1="54.299286"
+ x2="576.4375"
+ y2="49.84375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="582.79974"
+ y1="56.363762"
+ x2="575.70361"
+ y2="49.87711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37102"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37104"
+ gradientUnits="userSpaceOnUse"
+ x1="140.78264"
+ y1="123.96156"
+ x2="132.25548"
+ y2="116.40535" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7"
+ id="radialGradient37553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.135666"
+ cy="95.970413"
+ fx="-73.135666"
+ fy="95.970413"
+ r="4.9999957" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37667"
+ id="radialGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4604901,-0.4901463,0.6187826,0.5813434,279.52277,457.42224)"
+ cx="756.98285"
+ cy="206.8443"
+ fx="756.98285"
+ fy="206.8443"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient37558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37561"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-94.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758.62622"
+ y2="305.53677" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1"
+ id="radialGradient37553-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.227486"
+ cy="95.949913"
+ fx="-73.227486"
+ fy="95.949913"
+ r="4.9999957" />
+ <linearGradient
+ id="linearGradient40455-7-1">
+ <stop
+ id="stop40457-6-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-7"
+ id="radialGradient37555-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4769848,-0.5257394,0.6056598,0.5494938,269.68012,490.96577)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-9"
+ id="linearGradient37558-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-9">
+ <stop
+ id="stop58336-27"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="300.83292"
+ x1="754.28558"
+ gradientTransform="translate(1,-94.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37610-3"
+ xlink:href="#linearGradient16500-4"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71834"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient71836"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient37188"
+ gradientUnits="userSpaceOnUse"
+ x1="-22"
+ y1="36.47311"
+ x2="-18.85"
+ y2="22.485678"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.00015,169.99998)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37201"
+ gradientUnits="userSpaceOnUse"
+ x1="-26"
+ y1="38"
+ x2="-27"
+ y2="30.200407"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ id="linearGradient1610-7409">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-488" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-5" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-17" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-1">
+ <stop
+ id="stop58336-5"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-27"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-14">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-23" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-22" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7409"
+ id="linearGradient37317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="272.92456"
+ y2="26.239208" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-5"
+ id="radialGradient37319"
+ 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="#linearGradient58334-1"
+ id="linearGradient37321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-14"
+ id="linearGradient37323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.1275"
+ y1="301.01553"
+ x2="758.77625"
+ y2="305.51749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37338"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(461.00015,453)"
+ x1="37"
+ y1="53"
+ x2="36.74033"
+ y2="44.322407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37132"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37134"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ id="linearGradient40455-7-1-7">
+ <stop
+ id="stop40457-6-6-4"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-0"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient38362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,2.85168,-84)"
+ x1="-9.3937483"
+ y1="203.3882"
+ x2="28.275171"
+ y2="249.73875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1-7"
+ id="radialGradient38364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1033468,0.01995877,-0.02366572,0.9281732,7.8124646,13.285893)"
+ cx="-73.972397"
+ cy="94.935921"
+ fx="-73.972397"
+ fy="94.935921"
+ r="4.9999957" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38367"
+ gradientUnits="userSpaceOnUse"
+ x1="19.210167"
+ y1="143.17894"
+ x2="38.580528"
+ y2="167.11429"
+ gradientTransform="matrix(1,0,0,0.8461542,0,25.615323)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-7">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-1"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-6">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-49" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38051"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37534"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ id="linearGradient1610-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-18" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-92" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient38254"
+ gradientUnits="userSpaceOnUse"
+ x1="124.19057"
+ y1="111.30384"
+ x2="134.62978"
+ y2="120.14633" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37509"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient37613"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37615"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38073-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-14.752135"
+ y1="101.82622"
+ x2="-45.074585"
+ y2="68.279541" />
+ <linearGradient
+ id="linearGradient15425-4-9-8">
+ <stop
+ style="stop-color:#960000;stop-opacity:1;"
+ offset="0"
+ id="stop15427-5-8-24" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429-8-2-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-1"
+ id="linearGradient38075-5"
+ gradientUnits="userSpaceOnUse"
+ x1="137.33838"
+ y1="124.67571"
+ x2="131.35606"
+ y2="118.00494" />
+ <linearGradient
+ id="linearGradient5060-1">
+ <stop
+ id="stop5062-7"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-1"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient38077-1"
+ gradientUnits="userSpaceOnUse"
+ x1="127.15736"
+ y1="111.48302"
+ x2="146.01884"
+ y2="136.15825" />
+ <linearGradient
+ id="linearGradient319-52">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-7614" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-232" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38079-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-15"
+ y1="101"
+ x2="-22"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418-6"
+ id="linearGradient14433-1"
+ gradientUnits="userSpaceOnUse"
+ x1="139.29807"
+ y1="127.35454"
+ x2="130.33557"
+ y2="115.81818" />
+ <linearGradient
+ id="linearGradient14418-6">
+ <stop
+ id="stop14420-8"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422-5"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14435-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.36379"
+ y1="110.81054"
+ x2="135.22182"
+ y2="120.76331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14437-6"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="141.43347"
+ y2="127.52184" />
+ <filter
+ inkscape:collect="always"
+ id="filter15421-1"
+ x="-0.23999846"
+ width="1.4799969"
+ y="-0.24000154"
+ height="1.4800031"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.29233622"
+ id="feGaussianBlur15423-8" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-2"
+ id="linearGradient14439-9"
+ gradientUnits="userSpaceOnUse"
+ x1="125.20553"
+ y1="111.38132"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ id="linearGradient10069-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-79" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14441-4"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient48327-1"
+ id="radialGradient38306-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4461753,0.01083717,0.0036163,6.752143,-191.34795,-740.3814)"
+ cx="131.99811"
+ cy="126.63337"
+ fx="131.99811"
+ fy="126.63337"
+ r="9.1978254" />
+ <linearGradient
+ id="linearGradient48327-1">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop48329-23" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop48331-3" />
+ </linearGradient>
+ <linearGradient
+ y2="118.69846"
+ x2="132.35237"
+ y1="111.38132"
+ x1="125.20553"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37646-4"
+ xlink:href="#linearGradient10069-74-1"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient10069-74-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-0-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-9-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-7409-3-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-48-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-82-6-27" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient38313-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient37677"
+ gradientUnits="userSpaceOnUse"
+ x1="130.60338"
+ y1="115.87343"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ id="linearGradient319-19">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-8-3-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-95-2-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-43-7-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327-6">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-8-4">
+ <stop
+ id="stop20057-8-0"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-2-0"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39088">
+ <stop
+ id="stop39090"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop39092"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-83">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-24" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-11" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-95">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-10" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-64" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-87" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-42" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40173"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40175"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40282"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40284"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38693"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38703"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38706"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-157,821.03125)"
+ x1="-90.5"
+ y1="413.51562"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38720"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3846148,0,0,1,-211.38442,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,821.03125)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-2.4825165)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,824.54874)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39201"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39203"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39205"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39207"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39246"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39248"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39255"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39259"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient38961"
+ gradientUnits="userSpaceOnUse"
+ x1="488.5"
+ y1="568"
+ x2="495"
+ y2="568" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38956">
+ <rect
+ style="fill:url(#linearGradient38961);stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38958"
+ width="16"
+ height="12"
+ x="488"
+ y="560"
+ rx="0"
+ ry="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient39115"
+ gradientUnits="userSpaceOnUse"
+ x1="487.2518"
+ y1="531.95105"
+ x2="490.65796"
+ y2="580.63715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39117"
+ gradientUnits="userSpaceOnUse"
+ x1="496.49335"
+ y1="537.78113"
+ x2="498.40021"
+ y2="540.13623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39119"
+ gradientUnits="userSpaceOnUse"
+ x1="495.85294"
+ y1="541.69116"
+ x2="495.25"
+ y2="539.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-3"
+ id="linearGradient39122"
+ gradientUnits="userSpaceOnUse"
+ x1="494.38467"
+ y1="532.42651"
+ x2="496.21078"
+ y2="541.02698" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703"
+ id="linearGradient39261"
+ gradientUnits="userSpaceOnUse"
+ x1="122.25188"
+ y1="106.08706"
+ x2="147.08464"
+ y2="134.12131" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39263"
+ gradientUnits="userSpaceOnUse"
+ x1="116.75861"
+ y1="97.375854"
+ x2="145.729"
+ y2="137.52937" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39265"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient319-46">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-03" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-62" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-46"
+ id="linearGradient39508"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,0)"
+ x1="39.102718"
+ y1="641.73358"
+ x2="58.680996"
+ y2="661.93829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43807"
+ id="linearGradient39518"
+ gradientUnits="userSpaceOnUse"
+ x1="648.09674"
+ y1="355.85541"
+ x2="634.09503"
+ y2="341.23715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39088"
+ id="linearGradient39520"
+ gradientUnits="userSpaceOnUse"
+ x1="696.63055"
+ y1="403.93069"
+ x2="643.71313"
+ y2="349.93216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-95"
+ id="linearGradient39523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.8461523,99.385524,54.308237)"
+ x1="633.10468"
+ y1="338.95337"
+ x2="649.69073"
+ y2="354.92981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39716"
+ gradientUnits="userSpaceOnUse"
+ x1="121.80637"
+ y1="106.4641"
+ x2="142.1468"
+ y2="132.44617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39718"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40297"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask40306">
+ <path
+ id="path40308"
+ d="m 195,11.00001 0,14 0.5,0 13.5,-13.5 0,-0.5 -14,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703-5-5"
+ id="linearGradient39261-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="128.09367"
+ y1="112.43961"
+ x2="145.20987"
+ y2="133.4879" />
+ <linearGradient
+ id="linearGradient40703-5-5">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705-8-2" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707-8-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38252-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38254-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38256-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient40511-7-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ id="linearGradient1610-74-9-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-0-8-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-9-3-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient40507-4-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-8-6-5">
+ <stop
+ id="stop58336-8-9-2"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-24-8-7"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient40649-2-6-6"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-5-6-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-17-2-4" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-11-3-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient40502-7-8-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40635-7-2-2"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ id="linearGradient319-5-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-2-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-7-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40637-9-5-8"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <filter
+ inkscape:collect="always"
+ id="filter13996-9-7-7"
+ x="-0.23644176"
+ width="1.4728835"
+ y="-0.24368355"
+ height="1.4873672"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.29550651"
+ id="feGaussianBlur13998-5-8-6" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973-3-7-8"
+ id="linearGradient40639-1-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.2239"
+ y1="112.62726"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ id="linearGradient13973-3-7-8">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975-1-8-9" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977-2-0-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40641-9-2-7"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient41638-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient41640-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient41642-5-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient41644-5-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40875-3-9-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ id="linearGradient37542-3-0-7-6">
+ <stop
+ id="stop37544-1-6-6-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-2-1-7-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40877-5-5-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ id="linearGradient319-34-8-7-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-11-9-8-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-38-3-1-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40879-9-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="171.50414"
+ y2="248.54021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40881-8-0-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-7-6-7-4"
+ id="radialGradient40883-4-0-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.06118084,-0.8594818,2.4629674,-0.1753088,-259.40057,190.15309)"
+ cx="77.721619"
+ cy="104.09358"
+ fx="77.721619"
+ fy="104.09358"
+ r="3.9999998" />
+ <linearGradient
+ id="linearGradient10069-7-6-7-4">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-81-3-2-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-6-7-5-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39136-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39138-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39140-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="174.35753"
+ y2="250.6842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39143-0-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <linearGradient
+ id="linearGradient319-17-1-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40679"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25417"
+ id="linearGradient40731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.997161,-259.00079,67.35344)"
+ x1="280.0918"
+ y1="129.28557"
+ x2="267.20212"
+ y2="116.41341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40733"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-7"
+ id="linearGradient40733-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-8"
+ id="linearGradient40733-03"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40897">
+ <rect
+ y="198"
+ x="-41"
+ height="16"
+ width="15"
+ id="rect40899"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40902">
+ <rect
+ y="197"
+ x="-22"
+ height="17"
+ width="15"
+ id="rect40904"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38478"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(254.01612,-211.00101)"
+ x1="96.824379"
+ y1="393.90298"
+ x2="94.246101"
+ y2="391.21976" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38474">
+ <rect
+ style="fill:url(#linearGradient38478);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38476"
+ width="15"
+ height="15"
+ x="343.01611"
+ y="174.99901" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44318"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44320"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42992"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7"
+ id="linearGradient42994"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(4.9999967,20)"
+ x1="-114.75"
+ y1="546.5"
+ x2="-110.5"
+ y2="542.5" />
+ <linearGradient
+ id="linearGradient44627">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop44629" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop44631" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9-7-4-74">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44402"
+ gradientUnits="userSpaceOnUse"
+ x1="351.15625"
+ y1="108.35222"
+ x2="345.40625"
+ y2="108.00847" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44404"
+ gradientUnits="userSpaceOnUse"
+ x1="351.71875"
+ y1="106.93575"
+ x2="347.1875"
+ y2="106.7795" />
+ <filter
+ inkscape:collect="always"
+ id="filter44473"
+ x="-0.12578467"
+ width="1.2515693"
+ y="-0.11472401"
+ height="1.229448"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.81235925"
+ id="feGaussianBlur44475" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter44477"
+ x="-0.12176471"
+ width="1.2435294"
+ y="-0.11828571"
+ height="1.2365714"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.8625"
+ id="feGaussianBlur44479" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44485"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="284.5"
+ y2="106.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44942"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="351.71875"
+ y1="106.93575"
+ x2="339.125"
+ y2="105.092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44944"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,698,183)"
+ x1="351.15625"
+ y1="108.35222"
+ x2="336.40625"
+ y2="106.19597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44950"
+ gradientUnits="userSpaceOnUse"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102"
+ gradientTransform="matrix(-1,0,0,1,593.02125,-1.8e-6)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44954"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath45147">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccc"
+ id="path45149"
+ d="m 5,261 13,0 0,1 -1,0 0,1 1,0 0,1 -1,0 0,1 -1,0 0,2 2,0 0,-1 1,0 0,-1 1,0 0,1 1,0 0,-1 1,0 0,13 -17,0 0,-17 z"
+ style="opacity:0.2;fill:#3771c8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient45220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,221,10)"
+ x1="115.84575"
+ y1="10.8125"
+ x2="106.125"
+ y2="19.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45283"
+ gradientUnits="userSpaceOnUse"
+ x1="125.86876"
+ y1="111.85698"
+ x2="130.88379"
+ y2="121.70699" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45285"
+ gradientUnits="userSpaceOnUse"
+ x1="134.78751"
+ y1="122.29202"
+ x2="132.60205"
+ y2="117.96092" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74"
+ id="radialGradient45309"
+ cx="336.42892"
+ cy="611.10455"
+ fx="336.42892"
+ fy="611.10455"
+ r="5.9852905"
+ gradientTransform="matrix(1.0070601,0.03386866,-0.03770425,1.1211085,20.665977,-85.772965)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627"
+ id="linearGradient43826"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,1444.9824,-215)"
+ x1="689.47357"
+ y1="427"
+ x2="685.47357"
+ y2="427" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43822">
+ <rect
+ y="208"
+ x="754"
+ height="9"
+ width="12"
+ id="rect43824"
+ style="opacity:0.93999993;fill:url(#linearGradient43826);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient43856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient43858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46780"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46782"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46784"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46786"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46822"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46824"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46992"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46994"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46998"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient47000"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25106"
+ gradientUnits="userSpaceOnUse"
+ x1="408.91928"
+ y1="373.01221"
+ x2="410.55432"
+ y2="375.5058" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25117"
+ gradientUnits="userSpaceOnUse"
+ x1="411.05389"
+ y1="375.39175"
+ x2="407.62576"
+ y2="370.21317" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient25449"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25451"
+ gradientUnits="userSpaceOnUse"
+ x1="436.54755"
+ y1="524.30481"
+ x2="434.49387"
+ y2="519.46057" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25453"
+ gradientUnits="userSpaceOnUse"
+ x1="432.0849"
+ y1="524.97125"
+ x2="433"
+ y2="526" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="410.73904"
+ cy="370.11554"
+ fx="410.73904"
+ fy="370.11554"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="292.25"
+ y1="106.5"
+ x2="289.5"
+ y2="109.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24341"
+ x1="413.9498"
+ y1="386.45807"
+ x2="406.7699"
+ y2="374.42419"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24349"
+ gradientUnits="userSpaceOnUse"
+ x1="403.9577"
+ y1="367.62839"
+ x2="413.98795"
+ y2="374.07153" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6"
+ id="radialGradient24354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6402148,-1.1088846,0.8413297,0.4857498,104.42892,800.46622)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient24511"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24513"
+ gradientUnits="userSpaceOnUse"
+ x1="256.90005"
+ y1="80.100891"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient24515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24519"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6691529,0,4.3047361e-8,0.6954014,84.50351,24.951375)"
+ cx="259.02887"
+ cy="77.962585"
+ fx="259.02887"
+ fy="77.962585"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3879142,0,8.9286134e-8,1.4423572,-101.87942,-32.970267)"
+ cx="259.55096"
+ cy="77.188034"
+ fx="259.55096"
+ fy="77.188034"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="240.70209"
+ y1="-9.4293213"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient25056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient25058"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25060"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient29407"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29409"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29411"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient29413"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient44939-8-7-1-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient37396-1"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ id="linearGradient37542-7">
+ <stop
+ id="stop37544-40"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-94"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient15742-5"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998"
+ gradientTransform="matrix(0,1,-1,0,634.98585,-146.00607)" />
+ <linearGradient
+ id="linearGradient37542-5">
+ <stop
+ id="stop37544-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-71"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27860"
+ x1="392.02036"
+ y1="241.13428"
+ x2="386.30408"
+ y2="241.31801"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient27872"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27874"
+ gradientUnits="userSpaceOnUse"
+ x1="390.87131"
+ y1="241.13428"
+ x2="386.74603"
+ y2="242.46706"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient27886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,146.99795,-188.00607)"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27896"
+ id="linearGradient27902"
+ x1="388.70071"
+ y1="244.85669"
+ x2="391.17557"
+ y2="249.54126"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient10069-9-71">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-2">
+ <stop
+ id="stop23976-2"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath28964">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient28968);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 117.50984,228.63415 0,-15.01646 11.71735,5.49383 0,15.38271 -11.71735,-5.86008 z"
+ id="path28966" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-2"
+ id="linearGradient28968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ id="linearGradient319-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-26.511335"
+ y1="257.99881"
+ x2="-30.075666"
+ y2="259.87677" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29419">
+ <path
+ id="path29422"
+ d="m 117.50984,229.00041 0,-15.38272 11.71735,5.49383 0,15.74897 -11.71735,-5.86008 z"
+ style="opacity:0.5;fill:url(#linearGradient29424);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient29988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-35.153767"
+ y1="271.58572"
+ x2="-23.636715"
+ y2="252.03563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5"
+ id="linearGradient29990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-113.93222,176.71918)"
+ x1="446.93222"
+ y1="105.28082"
+ x2="441.93222"
+ y2="120.28082" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-71"
+ id="linearGradient29994"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="131.72171"
+ y2="118.18078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6-8"
+ id="linearGradient29773-5"
+ gradientUnits="userSpaceOnUse"
+ x1="124.78239"
+ y1="111.13178"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ id="linearGradient21327-6-8">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3-4" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient28526">
+ <stop
+ id="stop28528"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop28530"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-52-2">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-32-8" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-46-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient29334"
+ gradientUnits="userSpaceOnUse"
+ x1="121.74819"
+ y1="104.14172"
+ x2="140.18503"
+ y2="126.89457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient29336"
+ gradientUnits="userSpaceOnUse"
+ x1="155.10138"
+ y1="91.071259"
+ x2="122.40444"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient29338"
+ gradientUnits="userSpaceOnUse"
+ x1="124.66362"
+ y1="126.19594"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29340"
+ gradientUnits="userSpaceOnUse"
+ x1="124.28249"
+ y1="126.88889"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29342"
+ gradientUnits="userSpaceOnUse"
+ x1="147.25899"
+ y1="101.45953"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1138.1963"
+ y1="287.70486"
+ x2="1146.6705"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1286)"
+ x1="757.2467"
+ y1="367.52411"
+ x2="740.30865"
+ y2="405.3895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="745.48267"
+ y1="396.45972"
+ x2="737.62225"
+ y2="401.90442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient28583"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-239.00001,1286)"
+ x1="743"
+ y1="402"
+ x2="752"
+ y2="400" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38845"
+ id="linearGradient28589"
+ gradientUnits="userSpaceOnUse"
+ x1="162.41054"
+ y1="413.87982"
+ x2="161.83331"
+ y2="406.47784"
+ gradientTransform="matrix(0,1,-1,0,574.99991,384.00001)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="743.87036"
+ y1="396.04428"
+ x2="744.1059"
+ y2="423.54419" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,719.99999,383.00001)"
+ x1="148.56801"
+ y1="544.21143"
+ x2="163.11441"
+ y2="569.18829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28603"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1141.2856"
+ y1="288.19919"
+ x2="1146.2682"
+ y2="291.35333" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-52-2"
+ id="radialGradient29805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.94105289,0.01178942,-0.01073736,0.8570756,238.4669,249.70522)"
+ cx="-30.028414"
+ cy="19.425121"
+ fx="-30.028414"
+ fy="19.425121"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29801">
+ <rect
+ style="opacity:0.35;color:#000000;fill:url(#radialGradient29805);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.71217775;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect29803"
+ width="15"
+ height="16"
+ x="204"
+ y="257" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29884"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29886"
+ gradientUnits="userSpaceOnUse"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath50172-0">
+ <path
+ id="path50174-8"
+ d="m -177.34375,498 a 1.001098,1.001098 0 1 0 0.0937,2 l 3.65625,0 -4.25,5.9375 a 1.0001,1.0001 0 0 0 -0.1875,0.59375 l 0,0.5 a 1.0001,1.0001 0 0 0 1,1 L -171.75,508 a 1.0001,1.0001 0 1 0 0,-2 l -3.6875,0.0312 4.25,-5.9375 A 1.0001,1.0001 0 0 0 -171,499.5 l 0,-0.5 a 1.0001,1.0001 0 0 0 -1,-1 l -5.25,0 a 1.0001,1.0001 0 0 0 -0.0937,0 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
+ </clipPath>
+ <filter
+ color-interpolation-filters="sRGB"
+ inkscape:collect="always"
+ id="filter50168-9"
+ x="-0.26459751"
+ width="1.529195"
+ y="-0.21958679"
+ height="1.4391736">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.0769376"
+ id="feGaussianBlur50170-2" />
+ </filter>
+ <radialGradient
+ id="radialGradient16142-7"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16144-4" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16146-0" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient37542-78">
+ <stop
+ id="stop37544-2"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-78"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-0" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-89" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-04-82">
+ <stop
+ id="stop37544-9-0"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-4-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-38-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-6-7" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-9-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30766-8"
+ inkscape:collect="always">
+ <stop
+ id="stop30768-7"
+ offset="0"
+ style="stop-color:#be0000;stop-opacity:1" />
+ <stop
+ id="stop30770-8"
+ offset="1"
+ style="stop-color:#ff5108;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30752-0">
+ <stop
+ style="stop-color:#0c1b63;stop-opacity:1;"
+ offset="0"
+ id="stop30754-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop30756-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-64,-10)"
+ x1="18.773417"
+ y1="6.2494373"
+ x2="6.9718256"
+ y2="17.82831" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.701513,0.712657,0.712657,0.701513,50.5916,-449.6745)"
+ x1="385.62408"
+ y1="244.3396"
+ x2="401.63013"
+ y2="244.38875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-65.00001,-10.749995)"
+ x1="61.032951"
+ y1="5.9830923"
+ x2="46.491322"
+ y2="20.147326" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32146"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.199998,0,0,1.199999,-74.19988,-12.499988)"
+ x1="59.02124"
+ y1="6.0129876"
+ x2="44.509518"
+ y2="20.110929" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32148"
+ gradientUnits="userSpaceOnUse"
+ x1="47.348152"
+ y1="-25.553123"
+ x2="53.567928"
+ y2="-31.095215" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142-7"
+ id="linearGradient31946"
+ gradientUnits="userSpaceOnUse"
+ x1="-176.1799"
+ y1="508.33572"
+ x2="-193.07495"
+ y2="482.27924" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142"
+ id="linearGradient31948"
+ gradientUnits="userSpaceOnUse"
+ x1="-178.00789"
+ y1="505.36523"
+ x2="-194.90294"
+ y2="479.30875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-78"
+ id="linearGradient31950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="155.37498"
+ y1="230.51552"
+ x2="181.25543"
+ y2="269.24564" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-04-82"
+ id="linearGradient31954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-354.13606,119.42158)"
+ x1="148.47061"
+ y1="217.28368"
+ x2="171.77303"
+ y2="250.87756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-38-2"
+ id="linearGradient31956"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="-259.99872"
+ y1="340.81195"
+ x2="-253.90541"
+ y2="345.10736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30766-8"
+ id="linearGradient31958"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0017964,0,0,0.99629977,-0.31613165,0.94171311)"
+ x1="167.51979"
+ y1="252.44223"
+ x2="170.78137"
+ y2="261.69635" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31960"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.473038"
+ y1="238.21507"
+ x2="89.889603"
+ y2="243.80345" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30752-0"
+ id="linearGradient31962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.53265"
+ y1="244.52007"
+ x2="168.53265"
+ y2="239.5473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-237.5,45.5045)"
+ x1="263.35254"
+ y1="19.495501"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31966"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-238,44.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-243.5,51.5045)"
+ x1="260.25369"
+ y1="11.017987"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31970"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-244,50.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31972"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-57.00003,-165.99191)"
+ x1="85.853188"
+ y1="239.5473"
+ x2="90.563423"
+ y2="242.99191" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31974"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-51,-172)"
+ x1="88"
+ y1="240.90625"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28526"
+ id="linearGradient32236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-175.72238"
+ y1="66.323799"
+ x2="-183.03308"
+ y2="66.235535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-8-4"
+ id="linearGradient32238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-174.51762"
+ y1="66.654762"
+ x2="-183.58472"
+ y2="65.917358" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62"
+ id="linearGradient32240"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,406.86085,228.58514)"
+ x1="-180.7581"
+ y1="63.445515"
+ x2="-169.07387"
+ y2="62.182106" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.861107"
+ y2="-15.138513" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.705353"
+ y2="-15.562586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29312"
+ id="linearGradient32246"
+ gradientUnits="userSpaceOnUse"
+ x1="242.99834"
+ y1="291.5047"
+ x2="244.75"
+ y2="291.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29304"
+ id="linearGradient32248"
+ gradientUnits="userSpaceOnUse"
+ x1="245.20622"
+ y1="294.49902"
+ x2="243.5"
+ y2="294.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32299"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32301"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.000005,-120)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32303"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-9.025729,344.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient32305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-14.983875,337)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32353"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32355"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32357"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,39.488451,313.56226)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32359"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32426"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32428"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32430"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.77915445,-6.9426235e-4,0.00527501,0.79821029,158.94945,341.39422)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7"
+ id="linearGradient32434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31019"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31025"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="84.95932"
+ y2="122.23821" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.14826,118.6716)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.74301467,-0.74301467,0.74301467,0.74301467,250.58064,118.02214)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-19-1"
+ id="linearGradient32854-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1666676,0,0,-1.1666676,119.15081,827.66691)"
+ x1="262.04343"
+ y1="233.0448"
+ x2="273.85818"
+ y2="247.32738" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-19-1">
+ <stop
+ id="stop37544-48-6-1-8-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-6-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-7-8-3-0-3"
+ id="linearGradient32856-3-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,-249.10439,522.04547)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient44939-8-4-7-8-3-0-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-40-2-4-2-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-9-4-9-8-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-5-4-6-5-0-3"
+ id="linearGradient32858-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,144.9138,-563.9364)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient10069-9-7-5-4-6-5-0-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-58-5-9-1-2-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-4-0-8-0-4-9" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52637-8-8">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52641-2-8);fill-opacity:1;stroke:none;stroke-width:2.79999995000000010;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52639-8-9"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52641-2-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-361.27885,-161.73915)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-0-9-9">
+ <stop
+ id="stop37544-48-6-1-4-1-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-9-3-3"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient52998-5-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-307"
+ y1="475"
+ x2="-303.00003"
+ y2="463.92236" />
+ <linearGradient
+ id="linearGradient319-31-8-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-23-2-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-34-4-4-2" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52879-0-5">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52883-6-8);fill-opacity:1;stroke:none;stroke-width:2.79999995000000010;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52881-7-3"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354.95001"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52883-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-362.22886,-161.73912)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient53000-3-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-308.7684"
+ y1="476.0105"
+ x2="-304.76843"
+ y2="464.93286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34488-1-8"
+ id="linearGradient53002-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-839.95,-273.25)"
+ x1="469.49295"
+ y1="-101.22778"
+ x2="470.7515"
+ y2="-102.52942" />
+ <linearGradient
+ id="linearGradient34488-1-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop34490-0-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop34492-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32877-9-6-8"
+ id="linearGradient32896-0-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-217.1391"
+ y1="626.39844"
+ x2="-213.69197"
+ y2="623.21643" />
+ <linearGradient
+ id="linearGradient32877-9-6-8">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0"
+ id="stop32879-8-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop32881-4-3-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-4-9-5"
+ id="linearGradient32899-8-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-180.37465"
+ y1="650.94128"
+ x2="-177.70576"
+ y2="653.27765" />
+ <linearGradient
+ id="linearGradient33058-4-9-5">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-3-3-9" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-9-4-7" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32901-4-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1748275,-1.7208853,0.51495275,0.35155123,-289.20197,69.961171)"
+ cx="-197.66467"
+ cy="630.61389"
+ fx="-197.66467"
+ fy="630.61389"
+ r="7.03125" />
+ <linearGradient
+ id="linearGradient44939-8-4-8-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-0-0-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-8-6-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-2-7-1-7"
+ id="linearGradient32903-6-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-218.31921"
+ y1="624.84143"
+ x2="-215.31401"
+ y2="628.46533" />
+ <linearGradient
+ id="linearGradient33058-2-7-1-7">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-1-8-8-5" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-4-3-4-5" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32905-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.62164476,0.39733376,-0.55111069,0.86222272,269.0477,166.72227)"
+ cx="-202.18748"
+ cy="627"
+ fx="-202.18748"
+ fy="627"
+ r="7.03125" />
+ <linearGradient
+ y2="-102.52942"
+ x2="470.73633"
+ y1="-101.3037"
+ x1="469.52335"
+ gradientTransform="translate(-829.95,-273.25)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient58927"
+ xlink:href="#linearGradient34488-1-8"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-71-6-9-7"
+ id="linearGradient21875-7-1-0-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="278.34866"
+ y2="32.902874" />
+ <linearGradient
+ id="linearGradient1610-71-6-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-26-8-5-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-04-8-8-0" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106-9-2-9-9">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850-4-7-0-4"
+ 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" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011-6-7-0-8"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013-0-1-0-8" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-6-6-2-4"
+ id="linearGradient21877-3-2-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ id="linearGradient5060-6-6-2-4">
+ <stop
+ id="stop5062-2-0-5-5"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-4-4-5-5"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4671-6-4-1-7"
+ id="linearGradient34959-9-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1666.1765"
+ y1="639.65356"
+ x2="1659.0875"
+ y2="629.23273" />
+ <linearGradient
+ id="linearGradient4671-6-4-1-7">
+ <stop
+ id="stop4673-7-6-4-1"
+ offset="0"
+ style="stop-color:#ffd43b;stop-opacity:1;" />
+ <stop
+ id="stop4675-8-0-8-1"
+ offset="1"
+ style="stop-color:#ffe873;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4689-1-6-4-2"
+ id="linearGradient34961-3-6-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1641.4773"
+ y1="607.50525"
+ x2="1663.2872"
+ y2="626.40344" />
+ <linearGradient
+ id="linearGradient4689-1-6-4-2">
+ <stop
+ id="stop4691-6-2-6-7"
+ offset="0"
+ style="stop-color:#5a9fd4;stop-opacity:1;" />
+ <stop
+ id="stop4693-0-4-8-6"
+ offset="1"
+ style="stop-color:#306998;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34963-5-9-1"
+ gradientUnits="userSpaceOnUse"
+ x1="922.89703"
+ y1="339.66599"
+ x2="924.10608"
+ y2="344.10001" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-88-8-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-2-5-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34965-1-5-2"
+ gradientUnits="userSpaceOnUse"
+ x1="919.09998"
+ y1="345.42163"
+ x2="922.104"
+ y2="355.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-8-9-5-5"
+ id="linearGradient34967-4-1-8"
+ gradientUnits="userSpaceOnUse"
+ x1="922.64624"
+ y1="342.71866"
+ x2="921.82654"
+ y2="341.98108" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-8-9-5-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-9-8-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-0-2-8-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34969-4-4-1"
+ gradientUnits="userSpaceOnUse"
+ x1="917.75"
+ y1="355.5"
+ x2="917.25"
+ y2="353" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34971-5-0-9"
+ gradientUnits="userSpaceOnUse"
+ x1="923"
+ y1="343.75"
+ x2="923"
+ y2="344.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="radialGradient34973-2-5-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4166677,-7.678944e-6,1.853542e-6,0.58333478,-1309.0016,145.80659)"
+ cx="924"
+ cy="349.20001"
+ fx="924"
+ fy="349.20001"
+ r="6" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34975-9-4-9"
+ gradientUnits="userSpaceOnUse"
+ x1="921.34045"
+ y1="341.34042"
+ x2="922.16492"
+ y2="342.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-4-6-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-2-4-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-3-5-0-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-2-6-4-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-1-1-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-6-5-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-45-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-5-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-1-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-1-1-9-4-7-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-74-7-2-2-2-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-09-4-7-5-1-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-4-0-5-2-4-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-8-9-4-6-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-8-4-3-8-9-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-24-8-2-6-0-2">
+ <stop
+ id="stop58336-55-8-3-6-3-3"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-17-2-3-3-0-2"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-11-1-4-3-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-5-1-5-5-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-27-3-6-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-1-7-5-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-7-4-3-6-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-1-2-5-7-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-5-7-6-8-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-2-9-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-7-3-4-6-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-8-9-6-4-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-2-8-2-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-4-6-6-1-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-4"
+ id="linearGradient15131"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9999519,0,0,0.9998051,-33.244333,253.26813)"
+ x1="101.21339"
+ y1="68.783279"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ id="linearGradient37542-4">
+ <stop
+ id="stop37544-180"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-62"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-2"
+ id="linearGradient15133"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0910287,0,0,1.0900105,41.555722,244.97315)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ id="linearGradient319-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-72" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10585-5"
+ id="linearGradient15135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.032977,0,0,1,128.82015,107.77516)"
+ x1="12.330792"
+ y1="246.97107"
+ x2="41.654194"
+ y2="247.3784" />
+ <linearGradient
+ id="linearGradient10585-5">
+ <stop
+ id="stop10587-5"
+ offset="0.0000000"
+ style="stop-color:#d7d7d7;stop-opacity:1.0000000;" />
+ <stop
+ id="stop10595-5"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-0"
+ id="linearGradient15123"
+ 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" />
+ <linearGradient
+ id="linearGradient1610-0">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-6" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-42" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-0"
+ id="radialGradient15125"
+ 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
+ id="linearGradient40578-4-8-0">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-61" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-46"
+ id="linearGradient15127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-46">
+ <stop
+ id="stop58336-9"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-5"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-46"
+ id="linearGradient15129"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-46">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-4" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0-4"
+ id="linearGradient14559-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="56.069553" />
+ <linearGradient
+ id="linearGradient319-19-0-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865-0-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0-4"
+ id="linearGradient14561-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14482-2"
+ id="linearGradient14563-3"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55806"
+ y1="94.884857"
+ x2="149.53032"
+ y2="101.436" />
+ <linearGradient
+ id="linearGradient14482-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14484-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14486-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7-1-2"
+ id="linearGradient14565-5"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ id="linearGradient319-95-2-7-1-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.75675678;"
+ offset="0"
+ id="stop320-43-7-3-3-3" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4-1-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3-0-3"
+ id="linearGradient14567-8"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ id="linearGradient10069-8-3-3-0-3">
+ <stop
+ style="stop-color:#764511;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7-1-8" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1-0-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-19-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14482">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14484" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14486" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-95-2-7-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.75675678;"
+ offset="0"
+ id="stop320-43-7-3-3" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-8-3-3-0">
+ <stop
+ style="stop-color:#764511;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7-1" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15098">
+ <stop
+ style="stop-color:#646464;stop-opacity:1;"
+ offset="0"
+ id="stop15100" />
+ <stop
+ style="stop-color:#fcfcfc;stop-opacity:1;"
+ offset="1"
+ id="stop15102" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7-0"
+ id="linearGradient26282-0-8"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ id="linearGradient13998-7-0">
+ <stop
+ id="stop14000-1-1"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002-0-0"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7-0"
+ id="linearGradient26284-9-6"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7-2"
+ id="linearGradient26286-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ id="linearGradient319-7-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-5-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-5-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7-2"
+ id="linearGradient26288-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7"
+ id="linearGradient26282-0"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ id="linearGradient13998-7">
+ <stop
+ id="stop14000-1"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002-0"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7"
+ id="linearGradient26284-9"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7"
+ id="linearGradient26286-4"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ id="linearGradient319-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7"
+ id="linearGradient26288-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74-8"
+ id="radialGradient45309-0"
+ cx="336.42892"
+ cy="611.10455"
+ fx="336.42892"
+ fy="611.10455"
+ r="5.9852905"
+ gradientTransform="matrix(1.0070601,0.03386866,-0.03770425,1.1211085,20.665977,-85.772965)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient10069-9-7-4-74-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-0-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-9-1-2"
+ id="linearGradient42965-7-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(301.02752,449.99999)"
+ x1="25.963812"
+ y1="155.66899"
+ x2="29.972469"
+ y2="168" />
+ <linearGradient
+ id="linearGradient319-9-1-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-92-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-55-5-8" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter24186-3-2-5"
+ x="-0.12810811"
+ width="1.2562162"
+ y="-0.11285714"
+ height="1.2257143"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.395"
+ id="feGaussianBlur24188-3-7-6" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-06-1-5"
+ id="linearGradient42967-6-4"
+ gradientUnits="userSpaceOnUse"
+ x1="335.96875"
+ y1="607.09375"
+ x2="337.04251"
+ y2="628.20752" />
+ <linearGradient
+ id="linearGradient1610-06-1-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-4-2" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-1-2-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-12-5"
+ id="linearGradient42487-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ id="linearGradient319-12-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-34-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-81-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-8-7"
+ id="linearGradient42489-5-9"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ id="linearGradient15425-8-7">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15427-5-9" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429-7-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-12-5"
+ id="linearGradient42491-0-9"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-8-7"
+ id="linearGradient17232-8"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="141.64546"
+ y2="130.81215" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-31-8"
+ id="radialGradient37501-4-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ id="linearGradient319-35-31-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-38-14-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-94-6-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-31-8"
+ id="linearGradient37503-1-1-1"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-08-1"
+ id="radialGradient37501-4-9-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ id="linearGradient319-35-08-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-38-1-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-94-1-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-08-1"
+ id="linearGradient37503-1-9-9"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-0"
+ id="radialGradient37501-4-64"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ id="linearGradient319-35-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-38-15" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-94-19" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-0"
+ id="linearGradient37503-1-7"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ id="linearGradient18105-2-9">
+ <stop
+ id="stop18107-8-4"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109-1-4"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15531-9-5">
+ <stop
+ style="stop-color:#20539d;stop-opacity:1"
+ offset="0"
+ id="stop15534-1-3" />
+ <stop
+ style="stop-color:#bdc9df;stop-opacity:1"
+ offset="1"
+ id="stop15537-7-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-27-5">
+ <stop
+ id="stop23976-25-8"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-48-3"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient27277-1-8">
+ <stop
+ id="stop27279-5-2"
+ offset="0"
+ style="stop-color:#444444;stop-opacity:1;" />
+ <stop
+ id="stop27281-4-1"
+ offset="1"
+ style="stop-color:#adadad;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327-63-5">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-9-2" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-6-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27301-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27303-3-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27305-7-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15530-7"
+ id="linearGradient15537-5"
+ x1="223.00443"
+ y1="252.2876"
+ x2="222.72559"
+ y2="247.07268"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.1092502,-0.02900917)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15530-7">
+ <stop
+ style="stop-color:#16396d;stop-opacity:1"
+ offset="0"
+ id="stop15533-4" />
+ <stop
+ style="stop-color:#739ad4;stop-opacity:1"
+ offset="1"
+ id="stop15535-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-40-9">
+ <stop
+ id="stop37544-6-0"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1" />
+ <stop
+ id="stop37546-3-3"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-84-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-78-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-30-96" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-84-3-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-78-3-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-30-9-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38342-8"
+ id="linearGradient15502-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1386698,0,0,1.1421744,-30.9218,-35.447285)"
+ x1="214.40482"
+ y1="253.6573"
+ x2="225.75406"
+ y2="244.98485" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient38342-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38344-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38346-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15482-65"
+ id="linearGradient15474-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.625,0,0,1,355.875,184)"
+ x1="-174.15565"
+ y1="68.784225"
+ x2="-185.42635"
+ y2="63.762562" />
+ <linearGradient
+ id="linearGradient15482-65">
+ <stop
+ id="stop15484-4"
+ offset="0"
+ style="stop-color:#2869ab;stop-opacity:1" />
+ <stop
+ id="stop15486-2"
+ offset="1"
+ style="stop-color:#a7c8f0;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6-11"
+ id="linearGradient15467-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.56865388,0,0,0.77023595,345.79076,197.07321)"
+ x1="-182.5201"
+ y1="63.631611"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ id="linearGradient319-6-11">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-73-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-51-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15595-7"
+ id="linearGradient15601-9"
+ x1="248.04936"
+ y1="256.02081"
+ x2="238.4982"
+ y2="243.66418"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient15595-7">
+ <stop
+ style="stop-color:#1b4685;stop-opacity:1;"
+ offset="0"
+ id="stop15597-5" />
+ <stop
+ style="stop-color:#183e75;stop-opacity:0;"
+ offset="1"
+ id="stop15599-3" />
+ </linearGradient>
+ <linearGradient
+ y2="65.529938"
+ x2="-162.92078"
+ y1="62.360832"
+ x1="-191.30537"
+ gradientTransform="matrix(0.56865388,0,0,0.9414558,346.44835,191.39968)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient15576-5"
+ xlink:href="#linearGradient319-6-1-5"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-6-1-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-73-4-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-51-8-0" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(-0.04936017,-0.02079917)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient15614-7"
+ id="linearGradient15620-8"
+ x1="194.98087"
+ y1="238.83058"
+ x2="195.88264"
+ y2="253.1198"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15614-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15616-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15618-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-64-7"
+ id="linearGradient42432-3-3"
+ gradientUnits="userSpaceOnUse"
+ x1="248.20378"
+ y1="275.71143"
+ x2="238.40068"
+ y2="262.12378" />
+ <linearGradient
+ id="linearGradient1610-64-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-29-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15275-9"
+ id="linearGradient15281-5"
+ gradientUnits="userSpaceOnUse"
+ x1="238.25577"
+ y1="263.93561"
+ x2="244.04422"
+ y2="281.74426" />
+ <linearGradient
+ id="linearGradient15275-9">
+ <stop
+ id="stop15277-2"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop15279-1"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath42711-8-1">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42713-4-3"
+ width="8.7252884"
+ height="17.464855"
+ x="127.4093"
+ y="214.76154" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15361-7"
+ id="linearGradient15368-7"
+ x1="132.26923"
+ y1="125.62637"
+ x2="132.11778"
+ y2="119.48639"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient15361-7">
+ <stop
+ style="stop-color:#2766a6;stop-opacity:1;"
+ offset="0"
+ id="stop15363-7" />
+ <stop
+ style="stop-color:#6ba2e5;stop-opacity:1;"
+ offset="1"
+ id="stop15365-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15320-0"
+ id="linearGradient15326-8"
+ x1="134.91025"
+ y1="122.37094"
+ x2="129.09338"
+ y2="113.63851"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient15320-0">
+ <stop
+ style="stop-color:#0868f5;stop-opacity:1;"
+ offset="0"
+ id="stop15322-3" />
+ <stop
+ style="stop-color:#fbfdfe;stop-opacity:1;"
+ offset="1"
+ id="stop15324-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-0-2">
+ <stop
+ id="stop23976-22-8"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-4-5"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31320-4-3">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322-9-2" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324-3-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14262-95-2">
+ <stop
+ id="stop14264-2-2"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266-7-2"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-40-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-95-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-16-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-28-0-5">
+ <stop
+ id="stop23976-64-2-3"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-5-3-7"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-23-4"
+ id="radialGradient53141-5-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ id="linearGradient319-23-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-65-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-3-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-48-9"
+ id="linearGradient53143-6-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ id="linearGradient23974-48-9">
+ <stop
+ id="stop23976-13-7"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-28-3"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756-2-0"
+ id="linearGradient53145-1-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-27.086565"
+ y1="177.33885"
+ x2="-28.929489"
+ y2="175.48488" />
+ <linearGradient
+ id="linearGradient20756-2-0">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop20758-7-2" />
+ <stop
+ style="stop-color:#b5ccf0;stop-opacity:1;"
+ offset="1"
+ id="stop20760-0-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-23-4"
+ id="linearGradient53147-9-4"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28399-4"
+ id="linearGradient28405-0"
+ x1="329.46249"
+ y1="-104.63468"
+ x2="331.51218"
+ y2="-102.69718"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient28399-4">
+ <stop
+ style="stop-color:#0b1728;stop-opacity:1;"
+ offset="0"
+ id="stop28401-2" />
+ <stop
+ style="stop-color:#0b1728;stop-opacity:0;"
+ offset="1"
+ id="stop28403-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-1-2"
+ id="linearGradient18721-1-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,244.3928,19.4113)"
+ x1="-87.329895"
+ y1="-122.61974"
+ x2="-80.592239"
+ y2="-126.83872" />
+ <linearGradient
+ id="linearGradient23974-1-2">
+ <stop
+ id="stop23976-3-3"
+ offset="0"
+ style="stop-color:#3e7dd7;stop-opacity:0" />
+ <stop
+ style="stop-color:#8faedb;stop-opacity:1"
+ offset="0.48394433"
+ id="stop28407-8" />
+ <stop
+ id="stop23978-26-7"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-0-3"
+ id="linearGradient18728-6-0"
+ 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-0-3">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322-4-5" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324-9-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-97-5"
+ id="linearGradient18765-0-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,309.42934,-349.44584)"
+ x1="-20.377066"
+ y1="250.63214"
+ x2="-23.077509"
+ y2="252.61113" />
+ <linearGradient
+ id="linearGradient14262-97-5">
+ <stop
+ id="stop14264-0-6"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266-6-3"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-406-5"
+ id="linearGradient18712-0-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="111.30827"
+ y1="56.21777"
+ x2="106.06621"
+ y2="52.58638" />
+ <linearGradient
+ id="linearGradient319-406-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop320-76-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop321-36-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15539-2"
+ id="linearGradient15545-5"
+ x1="220.10603"
+ y1="248.22742"
+ x2="219.99527"
+ y2="254.01555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.1092502,-0.02900917)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15539-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15541-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15543-1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(-0.04936017,-0.02079917)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient15547-6"
+ id="linearGradient15553-4"
+ x1="216.16943"
+ y1="248.86955"
+ x2="216.65909"
+ y2="252.40509"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15547-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15549-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15551-1" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38363-7"
+ id="radialGradient15517-8"
+ cx="217.74739"
+ cy="253.99704"
+ fx="217.74739"
+ fy="253.99704"
+ r="9.0099697"
+ gradientTransform="matrix(2.3861605,-0.28739765,0.07141566,0.59293888,-320.08363,164.28237)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient38363-7">
+ <stop
+ id="stop38365-1"
+ offset="0"
+ style="stop-color:#1d4d91;stop-opacity:1" />
+ <stop
+ style="stop-color:#658fd4;stop-opacity:1;"
+ offset="0.44217443"
+ id="stop15519-3" />
+ <stop
+ id="stop38367-1"
+ offset="1"
+ style="stop-color:#c3d7ff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38342-8"
+ id="linearGradient38716-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1386698,0,0,1.1421744,-30.97116,-35.468084)"
+ x1="209.90396"
+ y1="249.06081"
+ x2="234.13614"
+ y2="251.62866" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-56-4"
+ id="linearGradient17222-4-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ id="linearGradient37542-56-4">
+ <stop
+ id="stop37544-88-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-9-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-528-2"
+ id="linearGradient17224-0-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ id="linearGradient319-528-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-68-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-86-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-24-4">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-3-2" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-4-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-67-6"
+ id="linearGradient42519-8-7"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ id="linearGradient1610-67-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-75-5" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-31-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-41-5"
+ id="linearGradient42523-5-8"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient9030-41-5">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-2-0" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-10-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-76-2"
+ id="linearGradient42521-3-0"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ id="linearGradient319-76-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-3-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-18-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679-9-1"
+ id="linearGradient25927-1-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ id="linearGradient24679-9-1">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681-7-0" />
+ <stop
+ id="stop24683-6-7"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685-4-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671-1-3"
+ id="linearGradient25929-7-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ id="linearGradient24671-1-3">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24673-7-4" />
+ <stop
+ id="stop24675-7-4"
+ offset="0.29527253"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24677-5-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-16-6"
+ id="linearGradient15963-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="425.5929"
+ y1="179.08949"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ id="linearGradient319-16-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-683-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-08-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-86-8"
+ id="linearGradient15744-9-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="390.61163"
+ y1="229.34804"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ id="linearGradient37542-86-8">
+ <stop
+ id="stop37544-39-4"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-0-3"
+ id="linearGradient10982-8-5"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient319-0-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-31" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-3" />
+ </linearGradient>
+ <linearGradient
+ y2="121"
+ x2="235.90916"
+ y1="107.25085"
+ x1="217.22589"
+ gradientTransform="matrix(1.0222226,0,0,0.73333282,-29.133504,-14.766607)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16268-9"
+ xlink:href="#linearGradient37542-86-0-1"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient37542-86-0-1">
+ <stop
+ id="stop37544-39-8-4"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-1-1"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="118.5"
+ x2="235"
+ y1="118.5"
+ x1="228.5468"
+ gradientTransform="matrix(0,1.253963,1,0,-46.30656,-81.941791)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16302-5"
+ xlink:href="#linearGradient319-0-2-5"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-0-2-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-0-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-86-2-7"
+ id="linearGradient15744-9-0-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="388.85464"
+ y1="230.24152"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ id="linearGradient37542-86-2-7">
+ <stop
+ id="stop37544-39-5-3"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-2-9"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-0-4-4"
+ id="linearGradient10982-8-9-5"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient319-0-4-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-2-9" />
+ </linearGradient>
+ <linearGradient
+ y2="121"
+ x2="235.90916"
+ y1="107.25085"
+ x1="217.22589"
+ gradientTransform="matrix(1.0222226,0,0,0.73333282,-29.2335,-145.66661)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16268-5-0"
+ xlink:href="#linearGradient37542-86-0-6-8"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient37542-86-0-6-8">
+ <stop
+ id="stop37544-39-8-7-4"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-1-5-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="118.5"
+ x2="235"
+ y1="118.5"
+ x1="228.5468"
+ gradientTransform="matrix(0,1.253963,-1,0,177.20656,-82.04179)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16302-3-4"
+ xlink:href="#linearGradient319-0-2-3-8"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-0-2-3-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-0-0-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-9-5-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15859-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15861-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15863-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17523-0-7-7"
+ id="linearGradient27998-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(214.99838,108.99542)"
+ x1="87.765633"
+ y1="16.828125"
+ x2="85.033081"
+ y2="18.891191" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17523-0-7-7">
+ <stop
+ style="stop-color:#323232;stop-opacity:1;"
+ offset="0"
+ id="stop17525-0-3-1" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop17527-5-9-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17515-1-4-4"
+ id="linearGradient28000-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(206.99837,-42.004575)"
+ x1="95.812523"
+ y1="167.78125"
+ x2="93.152969"
+ y2="169.77431" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17515-1-4-4">
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:1;"
+ offset="0"
+ id="stop17517-7-4-5" />
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:0;"
+ offset="1"
+ id="stop17519-6-7-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17532-0-9-1"
+ id="linearGradient28002-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(206.99837,-42.004575)"
+ x1="95.322037"
+ y1="167.49391"
+ x2="92.640839"
+ y2="169.55806" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17532-0-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop17534-2-2-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop17536-3-0-8" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-5-1-4-8"
+ id="radialGradient28004-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ id="linearGradient10069-5-1-4-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-18-9-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-252-1-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-2-3"
+ id="linearGradient28006-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,344.60085,-50.387906)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-4-2-3">
+ <stop
+ id="stop36275-9-0-3-3"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-3-5-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-22-0"
+ id="linearGradient28008-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,350.57878,-38.420763)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-4-22-0">
+ <stop
+ id="stop36275-9-0-6-7"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-3-6-9"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17523-8"
+ id="linearGradient27963-5"
+ gradientUnits="userSpaceOnUse"
+ x1="87.765633"
+ y1="16.828125"
+ x2="85.033081"
+ y2="18.891191" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17523-8">
+ <stop
+ style="stop-color:#323232;stop-opacity:1;"
+ offset="0"
+ id="stop17525-7" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop17527-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17515-0"
+ id="linearGradient27965-1"
+ gradientUnits="userSpaceOnUse"
+ x1="95.812523"
+ y1="167.78125"
+ x2="93.152969"
+ y2="169.77431" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17515-0">
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:1;"
+ offset="0"
+ id="stop17517-3" />
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:0;"
+ offset="1"
+ id="stop17519-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17532-4"
+ id="linearGradient27967-9"
+ gradientUnits="userSpaceOnUse"
+ x1="95.322037"
+ y1="167.49391"
+ x2="92.640839"
+ y2="169.55806" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17532-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop17534-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop17536-4" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-5-1-8"
+ id="radialGradient27969-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ id="linearGradient10069-5-1-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-18-3" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-252-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-8"
+ id="linearGradient27971-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,137.60085,-8.4035259)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-4-8">
+ <stop
+ id="stop36275-9-0-0"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-3-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-8"
+ id="linearGradient27973-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,143.60084,3.5964739)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17523-0-5"
+ id="linearGradient17973-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(176.0221,109.0221)"
+ x1="87.765633"
+ y1="16.828125"
+ x2="85.033081"
+ y2="18.891191" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17523-0-5">
+ <stop
+ style="stop-color:#323232;stop-opacity:1;"
+ offset="0"
+ id="stop17525-0-6" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop17527-5-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17515-1-9"
+ id="linearGradient17975-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.02209,-41.977903)"
+ x1="95.812523"
+ y1="167.78125"
+ x2="93.152969"
+ y2="169.77431" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17515-1-9">
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:1;"
+ offset="0"
+ id="stop17517-7-9" />
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:0;"
+ offset="1"
+ id="stop17519-6-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17532-0-8"
+ id="linearGradient17977-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.02209,-41.977903)"
+ x1="95.322037"
+ y1="167.49391"
+ x2="92.640839"
+ y2="169.55806" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17532-0-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop17534-2-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop17536-3-8" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-5-12"
+ id="radialGradient17979-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ id="linearGradient10069-5-12">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-9"
+ id="linearGradient17981-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,305.60083,-50.403526)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-9">
+ <stop
+ id="stop36275-9-8"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-35"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-9"
+ id="linearGradient17983-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,311.60082,-38.403526)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-4-6-0"
+ id="linearGradient32430-7-9-7"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient9030-4-6-0">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-3-3-8" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-1-6-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7-2-5-2"
+ id="linearGradient32434-5-8-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ id="linearGradient44939-8-7-1-7-2-5-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4-7-8-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0-1-0-2" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1-6-0"
+ id="radialGradient15137-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.227486"
+ cy="95.949913"
+ fx="-73.227486"
+ fy="95.949913"
+ r="4.9999957" />
+ <linearGradient
+ id="linearGradient40455-7-1-6-0">
+ <stop
+ id="stop40457-6-6-8-7"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-7-9"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-7-5-3"
+ id="radialGradient15139-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4769848,-0.5257394,0.6056598,0.5494938,269.68012,490.96577)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-7-5-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6-1-7" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1-8-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-9-6-7"
+ id="linearGradient15141-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-9-6-7">
+ <stop
+ id="stop58336-27-3-0"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9-5-0"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-1-4"
+ id="linearGradient15143-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-94.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4-1-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31-1-1" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23-1-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-0-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-7-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8-0-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-1-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-3-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25108-1-0">
+ <stop
+ id="stop25110-8-5"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop25112-1-0"
+ offset="1"
+ style="stop-color:#c6c6c6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8-7-1-7-2-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4-7-86" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0-1-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7-2-4"
+ id="linearGradient55624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15098"
+ id="linearGradient55656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,221,10)"
+ x1="115.01612"
+ y1="12"
+ x2="106.125"
+ y2="19.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108-1-0"
+ id="linearGradient55785"
+ gradientUnits="userSpaceOnUse"
+ x1="436.54755"
+ y1="524.30481"
+ x2="434.49387"
+ y2="519.46057" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108-1-0"
+ id="linearGradient55787"
+ gradientUnits="userSpaceOnUse"
+ x1="432.0849"
+ y1="524.97125"
+ x2="433"
+ y2="526" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0"
+ id="linearGradient55950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="56.069553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0"
+ id="linearGradient55952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14482"
+ id="linearGradient55954"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55806"
+ y1="94.884857"
+ x2="149.53032"
+ y2="101.436" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7-1"
+ id="linearGradient55956"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3-0"
+ id="linearGradient55958"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-0-9"
+ id="linearGradient55988"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="284.5"
+ y2="106.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-6-2"
+ id="linearGradient55990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,593.02125,-1.8e-6)"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient56084"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(210.99996,-273.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-08"
+ id="linearGradient56084-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(210.99996,-273.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ id="linearGradient319-08">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-36" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-21" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-08"
+ id="linearGradient29129-4"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-71"
+ id="linearGradient56084-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(210.99996,-273.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ id="linearGradient319-71">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-33" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-71"
+ id="linearGradient29129-1"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-24-4"
+ id="linearGradient56401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2868892,0,0,1,-249.7433,-143.02079)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-76-2"
+ id="linearGradient56428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,27.439091,-300.45853)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15859-1"
+ id="linearGradient14951"
+ gradientUnits="userSpaceOnUse"
+ x1="4.1933641"
+ y1="199.12067"
+ x2="17.16466"
+ y2="211.01585" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15859-1-3"
+ id="linearGradient14951-4"
+ gradientUnits="userSpaceOnUse"
+ x1="12.602254"
+ y1="206.13333"
+ x2="26.167894"
+ y2="220.66356" />
+ <linearGradient
+ id="linearGradient15859-1-3">
+ <stop
+ style="stop-color:#ff992b;stop-opacity:1"
+ offset="0"
+ id="stop15861-1-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15863-7-73" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-28-0-5"
+ id="linearGradient15989"
+ gradientUnits="userSpaceOnUse"
+ x1="94.485573"
+ y1="122.13319"
+ x2="89.207298"
+ y2="125.83332" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-4-3"
+ id="linearGradient15994"
+ 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="#linearGradient319-40-7"
+ id="linearGradient16002"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,69.29396,203.19342)"
+ x1="103.65562"
+ y1="49.547874"
+ x2="120.79755"
+ y2="57.84819" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-95-2"
+ id="linearGradient16005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,139.37998,3.53336)"
+ x1="-26.207859"
+ y1="252.77303"
+ x2="-5.4963508"
+ y2="253.15045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-0-2"
+ id="linearGradient16010"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,74.34344,372.3905)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27301-6-2"
+ id="linearGradient16558"
+ gradientUnits="userSpaceOnUse"
+ x1="497"
+ y1="264"
+ x2="507.125"
+ y2="276.75"
+ gradientTransform="translate(-0.04936017,-0.04091017)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-63-5"
+ id="linearGradient16561"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,0.97920913)"
+ x1="500.71924"
+ y1="270.24997"
+ x2="477"
+ y2="274" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27277-1-8"
+ id="linearGradient16564"
+ 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="#linearGradient23974-27-5"
+ id="linearGradient16567"
+ 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="#linearGradient15531-9-5"
+ id="linearGradient16570"
+ 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="#linearGradient18105-2-9"
+ id="linearGradient16573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,1.9792524)"
+ x1="492.95264"
+ y1="267.42996"
+ x2="496.73859"
+ y2="270.36874" />
+ <linearGradient
+ id="linearGradient1610-3-7-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-4-3" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6-0-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-5-9-4-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-8-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-24-8-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-3-7-4"
+ id="linearGradient16887"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-70.605209"
+ y1="-121.58411"
+ x2="-28.177105"
+ y2="-89.026711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-9-4-2"
+ id="linearGradient16889"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-74"
+ y1="-124"
+ x2="-55.5975"
+ y2="-103.2075" />
+ <linearGradient
+ id="linearGradient319-95">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-242" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-44" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-43"
+ id="linearGradient22933-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ id="linearGradient37542-43">
+ <stop
+ id="stop37544-7"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-12"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48"
+ id="linearGradient22935-6"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ id="linearGradient319-48">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-59"
+ id="linearGradient22937-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ id="linearGradient10069-59">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-30" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48"
+ id="linearGradient22939-8"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ y2="460.6622"
+ x2="264"
+ y1="452"
+ x1="264"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17039"
+ xlink:href="#linearGradient319-48"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-43-6"
+ id="linearGradient22933-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ id="linearGradient37542-43-6">
+ <stop
+ id="stop37544-7-2"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-12-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-6"
+ id="linearGradient22935-6-2"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ id="linearGradient319-48-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-59-3"
+ id="linearGradient22937-4-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ id="linearGradient10069-59-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-30-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-3-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-6"
+ id="linearGradient22939-8-6"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ y2="460.6622"
+ x2="264"
+ y1="452"
+ x1="264"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17172"
+ xlink:href="#linearGradient319-48-6"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-48-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-43-3"
+ id="linearGradient22933-6-87"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ id="linearGradient37542-43-3">
+ <stop
+ id="stop37544-7-8"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-12-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-5"
+ id="linearGradient22935-6-22"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ id="linearGradient319-48-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6-50" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-59-8"
+ id="linearGradient22937-4-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ id="linearGradient10069-59-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-30-2" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-3-06" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-5"
+ id="linearGradient22939-8-3"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ y2="460.6622"
+ x2="264"
+ y1="452"
+ x1="264"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17172-9"
+ xlink:href="#linearGradient319-48-5"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17438"
+ id="linearGradient17582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="267.125"
+ y1="462.1875"
+ x2="267.25"
+ y2="450" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17596"
+ id="linearGradient17584"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-26.918331,340)"
+ x1="245.91833"
+ y1="101"
+ x2="246.02513"
+ y2="94.443054" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-4"
+ id="linearGradient17586"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17602"
+ id="linearGradient17588"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-29.000001,340)"
+ x1="247"
+ y1="102"
+ x2="247"
+ y2="95.409012" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17430"
+ id="linearGradient17590"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="270.5"
+ y1="464.0625"
+ x2="270.125"
+ y2="447.0625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-4"
+ id="linearGradient17592"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-4"
+ id="linearGradient17594"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.6,-47,163.8)"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622" />
+ <linearGradient
+ id="linearGradient37542-1">
+ <stop
+ id="stop37544-62"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-75">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-39" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-1"
+ id="linearGradient17715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88913256,0,0,0.96231883,-17.039429,-158.76811)"
+ x1="30.435225"
+ y1="202.99998"
+ x2="30.435225"
+ y2="251.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-75"
+ id="linearGradient17717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.92839719,0,0,1.1347062,0.81276468,-9.2113636)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.903511"
+ y2="81.589714" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95"
+ id="linearGradient17932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,627.46943,130.00389)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ id="linearGradient37542-49">
+ <stop
+ id="stop37544-8"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-99"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-995">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-08" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-273" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49"
+ id="linearGradient20080"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,-379,416.1659)"
+ x1="42.033173"
+ y1="164.51399"
+ x2="75.32457"
+ y2="164.51399" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-995"
+ id="linearGradient20084"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,685.50001,836.08335)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49-3"
+ id="linearGradient20080-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,-379,416.1659)"
+ x1="42.033173"
+ y1="164.51399"
+ x2="75.32457"
+ y2="164.51399" />
+ <linearGradient
+ id="linearGradient37542-49-3">
+ <stop
+ id="stop37544-8-7"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-99-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49-3"
+ id="linearGradient20082-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(216,445.00002)"
+ x1="118.1319"
+ y1="157.11609"
+ x2="85.577972"
+ y2="157.54283" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-995-3"
+ id="linearGradient20084-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,685.50001,836.08335)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ id="linearGradient319-995-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-08-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-273-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49"
+ id="linearGradient20199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(209.99848,445.06252)"
+ x1="118.1319"
+ y1="157.11609"
+ x2="85.577972"
+ y2="157.54283" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-66-0-4-7"
+ id="linearGradient16783-1-6-0-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,290.55464,214.86015)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="17.012707"
+ y2="172.79289" />
+ <linearGradient
+ id="linearGradient37542-66-0-4-7">
+ <stop
+ id="stop37544-85-0-9-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-15-9-5-7"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4343-1-1-9-1"
+ id="linearGradient16778-3-5-3-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5990464,-0.03583042,0.03242597,0.6546824,306.65287,109.38342)"
+ x1="-12.264804"
+ y1="333.22653"
+ x2="-10.869003"
+ y2="334.86029" />
+ <linearGradient
+ id="linearGradient4343-1-1-9-1">
+ <stop
+ id="stop4345-2-9-5-6"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop4347-1-5-5-1"
+ offset="1"
+ style="stop-color:#fff9f9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-73-3-4-6"
+ id="linearGradient16775-4-9-5-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(497.01612,511)"
+ x1="-190.37566"
+ y1="-180.13821"
+ x2="-189.34792"
+ y2="-182" />
+ <linearGradient
+ id="linearGradient319-73-3-4-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87-5-2-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-66-3-7-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-65-4-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-14-9-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-49-3-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8"
+ id="linearGradient17904-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-97,-102)"
+ x1="386.88852"
+ y1="409.84152"
+ x2="389.14081"
+ y2="412.45016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8"
+ id="linearGradient17893-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-106,-102)"
+ x1="387"
+ y1="409.86362"
+ x2="388.86676"
+ y2="411.88974" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8"
+ id="linearGradient18148"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-102,-94)"
+ x1="387"
+ y1="410"
+ x2="388.78125"
+ y2="411.78125" />
+ <linearGradient
+ id="linearGradient23974-3">
+ <stop
+ id="stop23976-6"
+ offset="0"
+ style="stop-color:#a3a3a3;stop-opacity:1" />
+ <stop
+ id="stop23978-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-47">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-85" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-48" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-3-78">
+ <stop
+ id="stop23976-6-5"
+ offset="0"
+ style="stop-color:#a3a3a3;stop-opacity:1" />
+ <stop
+ id="stop23978-2-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16504-0">
+ <stop
+ id="stop16506-3"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop16508-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-47-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-85-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-48-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-5"
+ id="linearGradient17833-9"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078"
+ gradientTransform="translate(144,188)" />
+ <linearGradient
+ id="linearGradient1610-36-6-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-6" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-7"
+ id="linearGradient17833-8"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078"
+ gradientTransform="translate(144,188)" />
+ <linearGradient
+ id="linearGradient1610-36-6-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-87" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-96"
+ id="linearGradient20796-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(159.9998,-41.00751)"
+ x1="261.44702"
+ y1="234.6606"
+ x2="274.30609"
+ y2="247.73561" />
+ <linearGradient
+ id="linearGradient37542-96">
+ <stop
+ id="stop37544-7-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-37"
+ id="linearGradient20798-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(199.9999,105.99249)"
+ x1="235.46884"
+ y1="103"
+ x2="228.71886"
+ y2="94.53125" />
+ <linearGradient
+ id="linearGradient10069-37">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-9"
+ id="linearGradient39254-3"
+ 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" />
+ <linearGradient
+ id="linearGradient1610-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-4-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-09" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-9"
+ id="radialGradient39256-2"
+ 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
+ id="linearGradient40578-4-8-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-0" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-2"
+ id="linearGradient39258-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-2">
+ <stop
+ id="stop58336-97"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-90"
+ 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="linearGradient16151"
+ xlink:href="#linearGradient16500-49"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-49">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-16" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-19-1-1"
+ id="linearGradient79029"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1666676,0,0,-1.1666676,795.08409,370.66085)"
+ x1="262.04343"
+ y1="233.0448"
+ x2="273.85818"
+ y2="247.32738" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-19-1-1">
+ <stop
+ id="stop37544-48-6-1-8-9-3"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-6-8-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-7-8-3-0-3-6"
+ id="linearGradient79025"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,426.82889,65.03941)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient44939-8-4-7-8-3-0-3-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-40-2-4-2-4-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-9-4-9-8-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-5-4-6-5-0-3-6"
+ id="linearGradient79020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.53706486,0,0,-0.53706486,531.01948,106.93034)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient10069-9-7-5-4-6-5-0-3-6">
+ <stop
+ style="stop-color:#252525;stop-opacity:1"
+ offset="0"
+ id="stop10071-5-4-58-5-9-1-2-1-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-4-0-8-0-4-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient81143-4"
+ id="linearGradient80406-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.58017143,0,0,0.92830994,410.31278,270.33169)"
+ x1="-187.57428"
+ y1="63.340904"
+ x2="-157.37125"
+ y2="79.243309" />
+ <linearGradient
+ id="linearGradient81143-4">
+ <stop
+ style="stop-color:#2561b7;stop-opacity:1"
+ offset="0"
+ id="stop81145-0" />
+ <stop
+ style="stop-color:#f9fbff;stop-opacity:1"
+ offset="1"
+ id="stop81147-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15487-1-8-4-3"
+ id="linearGradient80403-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.92827429,0,0,0.92830994,60.469415,101.37929)"
+ x1="254.19243"
+ y1="237.48314"
+ x2="273.92343"
+ y2="254.49823" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15487-1-8-4-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15489-3-2-3-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15491-4-4-1-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-40-9"
+ id="linearGradient81258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99995186,0,0,0.99980511,154.9567,150.99846)"
+ x1="123.80291"
+ y1="90.165237"
+ x2="142.64377"
+ y2="105.8204" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-84-1"
+ id="linearGradient81260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,229.31341,141.82572)"
+ x1="45.107925"
+ y1="91.099701"
+ x2="51.546276"
+ y2="96.026611" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-84-3-2"
+ id="linearGradient81262"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,235.27474,141.76351)"
+ x1="46.007988"
+ y1="90.678802"
+ x2="50.907307"
+ y2="95.401253" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14829"
+ id="linearGradient14814"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-722.19531,285.57729)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ id="linearGradient14829">
+ <stop
+ id="stop14831"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop14833"
+ offset="1"
+ style="stop-color:#757575;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14632"
+ id="linearGradient14816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-214.43013,42.779961)"
+ x1="148.54834"
+ y1="301.96149"
+ x2="166.33298"
+ y2="317.25269" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient14632">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14634" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14636" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106-0">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850-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" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011-8"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013-0" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-9"
+ id="linearGradient14818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-233.12445,-35.715412)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ id="linearGradient5060-9">
+ <stop
+ id="stop5062-0"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-7"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821-9"
+ id="radialGradient14820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient18821-9">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823-1" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39155-5"
+ id="linearGradient14822"
+ gradientUnits="userSpaceOnUse"
+ x1="31.1875"
+ y1="18.875"
+ x2="29.875"
+ y2="34.375" />
+ <linearGradient
+ id="linearGradient39155-5">
+ <stop
+ id="stop39157-4"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39159-1"
+ offset="1"
+ style="stop-color:#dadada;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3564-9"
+ id="linearGradient14825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.06818845,0,0,0.06818845,22.51112,27.02885)"
+ x1="185.9903"
+ y1="193.33229"
+ x2="190.46461"
+ y2="-458.05771" />
+ <linearGradient
+ id="linearGradient3564-9"
+ inkscape:collect="always">
+ <stop
+ id="stop3566-9"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop3568-2"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39171-8"
+ id="radialGradient14827"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.647222,0,0,1.26792,-15.47413,-5.79794)"
+ cx="26.109201"
+ cy="19.668886"
+ fx="26.109201"
+ fy="19.668886"
+ r="20.278975" />
+ <linearGradient
+ id="linearGradient39171-8"
+ inkscape:collect="always">
+ <stop
+ id="stop39173-9"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39175-5"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14829"
+ id="linearGradient14800"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-169.92789,274.92229)"
+ x1="243.92192"
+ y1="-2.6686089"
+ x2="275.10107"
+ y2="26.600887" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14605"
+ id="linearGradient14802"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-13.427886,57.417785)"
+ x1="87"
+ y1="241.125"
+ x2="90.764404"
+ y2="243.87347" />
+ <linearGradient
+ id="linearGradient14605">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.56485355;"
+ offset="0"
+ id="stop14607" />
+ <stop
+ style="stop-color:#fffffe;stop-opacity:0;"
+ offset="1"
+ id="stop14609" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath22590-7">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22592-5-0"
+ width="12"
+ height="14"
+ x="-30"
+ y="490.00012" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-5"
+ id="linearGradient14804"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ id="linearGradient13998-5">
+ <stop
+ id="stop14000-00"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002-54"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-5"
+ id="linearGradient14806"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-53"
+ id="linearGradient14808"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ id="linearGradient319-53">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-61" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-53"
+ id="linearGradient14810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-41" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-4" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="299.83005"
+ x1="753.39417"
+ gradientTransform="translate(-683.42789,-5.5822151)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient20368"
+ xlink:href="#linearGradient16500-1"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-41-8-0-7-1"
+ id="linearGradient16663-3-0-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="184.95361"
+ y1="115.79691"
+ x2="235.24524"
+ y2="119.04691" />
+ <linearGradient
+ id="linearGradient37542-41-8-0-7-1">
+ <stop
+ id="stop37544-5-2-6-6-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-8-6-8-7-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-41-8-0-7-4"
+ id="linearGradient16663-3-0-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="179.3838"
+ y1="116.92558"
+ x2="235.24524"
+ y2="119.04691" />
+ <linearGradient
+ id="linearGradient37542-41-8-0-7-4">
+ <stop
+ id="stop37544-5-2-6-6-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-8-6-8-7-3"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7-8-6-0"
+ id="radialGradient106344-5"
+ cx="386.68588"
+ cy="247.46175"
+ fx="386.68588"
+ fy="247.46175"
+ r="2.3794625"
+ gradientTransform="matrix(4.5687397,-0.29531319,0.13355055,5.747731,-1415.8878,-1055.5606)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient37542-7-8-6-0">
+ <stop
+ id="stop37544-40-1-3-9"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop37546-94-7-0-7"
+ offset="1"
+ style="stop-color:#030303;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ y2="245.04375"
+ x2="400.77301"
+ y1="243.97655"
+ x1="385.67264"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient106307-2"
+ xlink:href="#linearGradient319-488-8-2"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-488-8-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-13-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-67-2-2" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient106427"
+ id="radialGradient106433"
+ cx="383.96912"
+ cy="249.87636"
+ fx="383.96912"
+ fy="249.87636"
+ r="2.3794624"
+ gradientTransform="matrix(4.5686863,-0.29541184,0.13359632,5.7477127,-1403.7889,-1070.199)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7-8-6-0-8"
+ id="radialGradient106344-5-2"
+ cx="386.68588"
+ cy="247.46175"
+ fx="386.68588"
+ fy="247.46175"
+ r="2.3794625"
+ gradientTransform="matrix(4.5687397,-0.29531319,0.13355055,5.747731,-1415.8878,-1055.5606)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient37542-7-8-6-0-8">
+ <stop
+ id="stop37544-40-1-3-9-3"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop37546-94-7-0-7-1"
+ offset="1"
+ style="stop-color:#030303;stop-opacity:1" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient106427-3"
+ id="radialGradient106433-4"
+ cx="383.96912"
+ cy="249.87636"
+ fx="383.96912"
+ fy="249.87636"
+ r="2.3794625"
+ gradientTransform="matrix(4.5686863,-0.29541184,0.13359632,5.7477127,-1403.7889,-1070.199)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient106427-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop106429-1" />
+ <stop
+ style="stop-color:#030303;stop-opacity:1"
+ offset="1"
+ id="stop106431-0" />
+ </linearGradient>
+ <linearGradient
+ y2="245.04375"
+ x2="400.77301"
+ y1="243.97655"
+ x1="385.67264"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient106307-2-4"
+ xlink:href="#linearGradient319-488-8-2-0"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-488-8-2-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-13-8-8-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-67-2-2-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-36-6-7-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-4-5" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-87-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-36-6-7-9-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-4-5-0" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-87-3-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-7-9"
+ id="linearGradient106628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(64,338)"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-7-9-4"
+ id="linearGradient106641"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(39.8125,337.625)"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-1-1-9-4-7-1"
+ id="linearGradient106804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.40161"
+ y2="29.679312" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-4-0-5-2-4-7"
+ id="radialGradient106806"
+ 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="#linearGradient58334-24-8-2-6-0-2"
+ id="linearGradient106808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-11-1-4-3-1"
+ id="linearGradient106810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-1-7-5-7-7"
+ id="linearGradient106812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-5-7-6-8-9"
+ id="linearGradient106814"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient106816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient106818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="219"
+ y1="604.31494"
+ x2="221"
+ y2="609.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-4-6-7-7"
+ id="linearGradient106820"
+ gradientUnits="userSpaceOnUse"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-2-6-4-4"
+ id="linearGradient106822"
+ gradientUnits="userSpaceOnUse"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ id="linearGradient106824"
+ gradientUnits="userSpaceOnUse"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ id="linearGradient106826"
+ gradientUnits="userSpaceOnUse"
+ x1="219"
+ y1="604.31494"
+ x2="221"
+ y2="609.36218" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107148"
+ id="radialGradient107138"
+ gradientUnits="userSpaceOnUse"
+ cx="12.465761"
+ cy="353.51611"
+ fx="12.465761"
+ fy="353.51611"
+ r="2.91875"
+ gradientTransform="matrix(0.84360011,0.04170664,-0.04937856,0.99878013,19.37109,-0.08239219)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107142"
+ id="linearGradient107140"
+ gradientUnits="userSpaceOnUse"
+ x1="11.695067"
+ y1="352.60217"
+ x2="16.773348"
+ y2="358.90598" />
+ <radialGradient
+ r="2.91875"
+ fy="353.59497"
+ fx="12.128428"
+ cy="353.59497"
+ cx="12.128428"
+ gradientTransform="matrix(0.2864009,1.1071441,-1.0639391,0.27522442,384.79448,242.64422)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient107490"
+ xlink:href="#linearGradient107519"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15097-0-8"
+ id="radialGradient15836-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.14826933,2.1671891,-2.0135104,-0.13775545,-42.975294,-475.30953)"
+ cx="327.72662"
+ cy="-102.09388"
+ fx="327.72662"
+ fy="-102.09388"
+ r="3.3160801" />
+ <linearGradient
+ id="linearGradient15097-0-8">
+ <stop
+ style="stop-color:#c4c4c4;stop-opacity:1"
+ offset="0"
+ id="stop15099-1-83" />
+ <stop
+ style="stop-color:#868686;stop-opacity:1"
+ offset="1"
+ id="stop15101-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-5-2-6-6"
+ id="linearGradient15851-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.2185076,0,0,1.1902393,14.075854,397.20828)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ id="linearGradient23974-5-2-6-6">
+ <stop
+ id="stop23976-9-2-7-6"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-3-1-6-0"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-5-2-6-7"
+ id="linearGradient15818-5"
+ 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-5-2-6-7">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322-5-4-5-8" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324-0-8-5-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-9-5-9-4"
+ id="linearGradient15846-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.2185076,0,0,1.1902393,92.990431,-50.358654)"
+ x1="-20.864969"
+ y1="250.35432"
+ x2="-34.640823"
+ y2="264.67712" />
+ <linearGradient
+ id="linearGradient14262-9-5-9-4">
+ <stop
+ id="stop14264-5-2-9-0"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266-0-4-4-2"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-92-8-5-0"
+ id="linearGradient15843-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99098745,0,0,1.0233007,7.9488742,191.90653)"
+ x1="113.17896"
+ y1="49.395184"
+ x2="111.81031"
+ y2="62.520573" />
+ <linearGradient
+ id="linearGradient319-92-8-5-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-40-7-9-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-93-7-0-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-92-8-5-0"
+ id="linearGradient16562-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99098745,0,0,1.0233007,7.9488742,191.90653)"
+ x1="114.36164"
+ y1="22.752264"
+ x2="104.74062"
+ y2="65.241188" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15959-9-5"
+ id="linearGradient15773-7"
+ gradientUnits="userSpaceOnUse"
+ x1="113.07384"
+ y1="252.04327"
+ x2="119.9112"
+ y2="249.41632"
+ gradientTransform="matrix(1.2133883,0,0,1.2133883,-25.22919,-53.154498)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15959-9-5">
+ <stop
+ style="stop-color:#4d4d4d;stop-opacity:1;"
+ offset="0"
+ id="stop15961-9-6" />
+ <stop
+ style="stop-color:#4d4d4d;stop-opacity:0;"
+ offset="1"
+ id="stop15963-8-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16723"
+ id="linearGradient16730"
+ x1="112.5"
+ y1="252.5"
+ x2="116.5"
+ y2="250"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient16800"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.64335,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient16802"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ 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"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ id="linearGradient23705-0">
+ <stop
+ id="stop23707-9"
+ offset="0"
+ style="stop-color:#d4d2bf;stop-opacity:1;" />
+ <stop
+ id="stop23709-4"
+ offset="1"
+ style="stop-color:#857f5d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168-8"
+ id="linearGradient22954-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <linearGradient
+ id="linearGradient24168-8">
+ <stop
+ id="stop24170-2"
+ offset="0"
+ style="stop-color:#182437;stop-opacity:1;" />
+ <stop
+ id="stop24172-4"
+ offset="1"
+ style="stop-color:#2b4163;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="radialGradient22952-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="262.67139"
+ cy="74.072273"
+ fx="262.67139"
+ fy="74.072273"
+ r="3.5" />
+ <linearGradient
+ id="linearGradient319-51">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="linearGradient22928-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <linearGradient
+ id="linearGradient29791">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29793" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29795" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821-2"
+ id="radialGradient22950-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient18821-2">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823-7" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825-6" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="radialGradient22922-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ id="linearGradient29802">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29804" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29806" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-2"
+ id="linearGradient22917-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <linearGradient
+ id="linearGradient5060-2">
+ <stop
+ id="stop5062-3"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-2"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="radialGradient23727-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ id="linearGradient29813">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29815" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29817" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107519"
+ id="radialGradient30077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2864009,1.1071441,-1.0639391,0.27522442,384.79448,242.64422)"
+ cx="12.128428"
+ cy="353.59497"
+ fx="12.128428"
+ fy="353.59497"
+ r="2.91875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient30079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.64335,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient30081"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ y2="360.82117" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107519"
+ id="radialGradient30090"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2864009,1.1071441,-1.0639391,0.27522442,384.79448,242.64422)"
+ cx="12.128428"
+ cy="353.59497"
+ fx="12.128428"
+ fy="353.59497"
+ r="2.91875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient30092"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.64335,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient30094"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ y2="360.82117" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient30097"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ y2="360.82117"
+ gradientTransform="matrix(-1,0,0,1,112.28991,0.1875)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient30100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.28991,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30122"
+ id="linearGradient30129"
+ x1="48.5"
+ y1="354.75"
+ x2="51"
+ y2="360.25"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30131"
+ id="linearGradient30137"
+ x1="60.289909"
+ y1="361.0625"
+ x2="63.789909"
+ y2="354.0625"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30139"
+ id="linearGradient30145"
+ x1="63.789909"
+ y1="355.0625"
+ x2="61.039909"
+ y2="360.0625"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-7-9-4-3"
+ id="linearGradient106641-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(39.8125,337.625)"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ id="linearGradient1610-36-6-7-9-4-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-4-5-0-6" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-87-3-7-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27496"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27498"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ id="linearGradient37542-9">
+ <stop
+ id="stop37544-6"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15541">
+ <stop
+ id="stop15543"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop15545"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-41-8-0-7-1-3">
+ <stop
+ id="stop37544-5-2-6-6-5-3"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-8-6-8-7-2-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-1-7"
+ id="linearGradient15721-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="227.57907"
+ y1="118.47696"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ id="linearGradient319-1-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0" />
+ </linearGradient>
+ <linearGradient
+ y2="118.5"
+ x2="235"
+ y1="118.47696"
+ x1="227.57907"
+ gradientTransform="translate(265.62095,336.21475)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient15670-3"
+ xlink:href="#linearGradient319-1-7-2"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-1-7-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-41-8-0-7-4-0">
+ <stop
+ id="stop37544-5-2-6-6-9-0"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-8-6-8-7-3-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15647-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15649-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15651-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-2-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-0-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-5-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15647-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15649-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15651-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-1-7-2-7"
+ id="linearGradient15975-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(267.4022,339.9335)"
+ x1="227.57907"
+ y1="118.47696"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ id="linearGradient319-1-7-2-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-0-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-5-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15647-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15649-12" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15651-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-00" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-2-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-0-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-5-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-7-0">
+ <stop
+ id="stop37544-40-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-94-1"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-06" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15647-14">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15649-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15651-72" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-02">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-48" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-2-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-0-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-5-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-04">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-7">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-28">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-23" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16389">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16391" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16393" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15647-14-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15649-7-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15651-72-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-02-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-8-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-48-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-2-4-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-0-4-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-5-7-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-1-7-5"
+ id="linearGradient16591-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(266.10421,337.79176)"
+ x1="224.37904"
+ y1="118.78525"
+ x2="236.37904"
+ y2="118.78525" />
+ <linearGradient
+ id="linearGradient319-1-7-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15796"
+ id="linearGradient15802"
+ x1="192.4323"
+ y1="348.13098"
+ x2="208.33328"
+ y2="359.81409"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15806"
+ id="linearGradient15804"
+ x1="212.0226"
+ y1="361.34204"
+ x2="194.68611"
+ y2="348.34918"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient319-715">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-74" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-58" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15840">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15842" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15844" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15847">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15849" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15851" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-75">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-17" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-64" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15858">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15860" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15862" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060-97">
+ <stop
+ id="stop5062-5"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-5"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15869">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15871" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15873" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-8"
+ id="linearGradient35740-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,-206.46148,-296.13985)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="10.490564"
+ y2="176.41806" />
+ <linearGradient
+ id="linearGradient37542-8">
+ <stop
+ id="stop37544-64"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-93"
+ id="linearGradient35742-9"
+ gradientUnits="userSpaceOnUse"
+ x1="58.060974"
+ y1="-23.721956"
+ x2="40"
+ y2="-35" />
+ <linearGradient
+ id="linearGradient1610-93">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-83" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-75"
+ id="linearGradient35744-6"
+ gradientUnits="userSpaceOnUse"
+ x1="46.1875"
+ y1="-28.59375"
+ x2="41.099998"
+ y2="-33.59375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36116-7"
+ id="linearGradient35746-7"
+ gradientUnits="userSpaceOnUse"
+ x1="46"
+ y1="-32"
+ x2="43.883884"
+ y2="-33.939339" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient36116-7">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop36118-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop36120-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-75"
+ id="linearGradient35750-3"
+ gradientUnits="userSpaceOnUse"
+ x1="48.662914"
+ y1="-27.071922"
+ x2="43.47097"
+ y2="-32.337086" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient35752-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6.3,-4.7)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.200001"
+ y2="-28.640625" />
+ <linearGradient
+ id="linearGradient15902">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15904" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15906" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient35754-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(5.315625,-3.75)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.325001"
+ y2="-28.765625" />
+ <linearGradient
+ id="linearGradient15909">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15911" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15913" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient35756-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(3.3,0.3)"
+ x1="38.700001"
+ y1="-31.299999"
+ x2="40.012501"
+ y2="-29.799999" />
+ <linearGradient
+ id="linearGradient15916">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15918" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15920" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-75"
+ id="linearGradient35772-6"
+ gradientUnits="userSpaceOnUse"
+ x1="51.912914"
+ y1="-24.696922"
+ x2="40.75"
+ y2="-35.75"
+ gradientTransform="translate(-0.75,4.75)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient35748-0"
+ gradientUnits="userSpaceOnUse"
+ x1="41"
+ y1="-29"
+ x2="43"
+ y2="-27" />
+ <linearGradient
+ id="linearGradient15930">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15932" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15934" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient16186"
+ gradientUnits="userSpaceOnUse"
+ x1="41"
+ y1="-29"
+ x2="43"
+ y2="-27"
+ gradientTransform="translate(412,489)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-75"
+ id="linearGradient16189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(411.25,493.75)"
+ x1="51.912914"
+ y1="-24.696922"
+ x2="40.75"
+ y2="-35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient16194"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(415.3,489.3)"
+ x1="38.700001"
+ y1="-31.299999"
+ x2="40.012501"
+ y2="-29.799999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient16197"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(417.31562,485.25)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.325001"
+ y2="-28.765625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient16200"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(418.3,484.3)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.200001"
+ y2="-28.640625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-75"
+ id="linearGradient16203"
+ gradientUnits="userSpaceOnUse"
+ x1="48.662914"
+ y1="-27.071922"
+ x2="43.47097"
+ y2="-32.337086"
+ gradientTransform="translate(412,489)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36116-7"
+ id="linearGradient16208"
+ gradientUnits="userSpaceOnUse"
+ x1="46"
+ y1="-32"
+ x2="43.883884"
+ y2="-33.939339"
+ gradientTransform="translate(412,489)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-75"
+ id="linearGradient16211"
+ gradientUnits="userSpaceOnUse"
+ x1="46.1875"
+ y1="-28.59375"
+ x2="41.099998"
+ y2="-33.59375"
+ gradientTransform="translate(412,489)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-93"
+ id="linearGradient16214"
+ gradientUnits="userSpaceOnUse"
+ x1="58.060974"
+ y1="-23.721956"
+ x2="40"
+ y2="-35"
+ gradientTransform="translate(412,489)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-715"
+ id="linearGradient16252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(417.31562,485.25)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.325001"
+ y2="-28.765625" />
+ <linearGradient
+ id="linearGradient319-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-64" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15804-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15806" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15808-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15811">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15813-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15815" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15818">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15820" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15822" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15825">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15827" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15829" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient15998"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-65.00001,-10.749995)"
+ x1="61.032951"
+ y1="5.9830923"
+ x2="46.491322"
+ y2="20.147326" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient16000"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.199998,0,0,1.199999,-74.19988,-12.499988)"
+ x1="59.02124"
+ y1="6.0129876"
+ x2="44.509518"
+ y2="20.110929" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient16003"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-64,-10)"
+ x1="18.773417"
+ y1="6.2494373"
+ x2="6.9718256"
+ y2="17.82831" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient16006"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.701513,0.712657,0.712657,0.701513,50.5916,-449.6745)"
+ x1="385.62408"
+ y1="244.3396"
+ x2="401.63013"
+ y2="244.38875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient16056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-64,-10)"
+ x1="18.773417"
+ y1="6.2494373"
+ x2="6.9718256"
+ y2="17.82831" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient16058"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.701513,0.712657,0.712657,0.701513,50.5916,-449.6745)"
+ x1="385.62408"
+ y1="244.3396"
+ x2="401.63013"
+ y2="244.38875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient16084"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-65.00001,-10.749995)"
+ x1="61.032951"
+ y1="5.9830923"
+ x2="46.491322"
+ y2="20.147326" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6"
+ id="linearGradient16086"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.199998,0,0,1.199999,-74.19988,-12.499988)"
+ x1="59.02124"
+ y1="6.0129876"
+ x2="44.509518"
+ y2="20.110929" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25417-9"
+ id="linearGradient40731-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.997161,-259.00079,67.35344)"
+ x1="280.0918"
+ y1="129.28557"
+ x2="267.20212"
+ y2="116.41341" />
+ <linearGradient
+ id="linearGradient25417-9">
+ <stop
+ id="stop25419-9"
+ offset="0"
+ style="stop-color:#60553b;stop-opacity:1;" />
+ <stop
+ id="stop25421-2"
+ offset="1"
+ style="stop-color:#b0a17f;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-6"
+ id="linearGradient40733-04"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-6-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-64-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16451">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16453" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16455" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-6-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-64-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16520">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16522" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16524" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-6-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-64-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-6-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-64-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16838">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16840" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16842" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-6-40">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-64-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16838-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16840-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16842-8" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18666-3">
+ <rect
+ y="6"
+ x="62.921577"
+ height="14.000001"
+ width="15.098035"
+ id="rect18668-4"
+ style="fill:url(#linearGradient18670-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.50000000000000000;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-08"
+ id="linearGradient18670-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2078427,0,0,1.0516432,-357.40769,69.427229)"
+ x1="362.28571"
+ y1="-45.098213"
+ x2="352.46426"
+ y2="-54.124699" />
+ <linearGradient
+ id="linearGradient1610-08">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-2" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-48" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-33">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-36" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17205">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop17207" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop17209" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-0">
+ <stop
+ id="stop37544-77"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-14">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-27" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-629" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-0">
+ <stop
+ id="stop23976-205"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-6"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-5-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-8-1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath28964-0">
+ <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:url(#linearGradient28968);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 117.50984,228.63415 0,-15.01646 11.71735,5.49383 0,15.38271 -11.71735,-5.86008 z"
+ id="path28966-5" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29419-5">
+ <path
+ inkscape:connector-curvature="0"
+ id="path29422-9"
+ d="m 117.50984,229.00041 0,-15.38272 11.71735,5.49383 0,15.74897 -11.71735,-5.86008 z"
+ style="opacity:0.50000000000000000;fill:url(#linearGradient29424-4);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7-8"
+ id="linearGradient29424-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-26.511335"
+ y1="257.99881"
+ x2="-30.075666"
+ y2="259.87677" />
+ <linearGradient
+ id="linearGradient37542-7-8">
+ <stop
+ id="stop37544-40-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-94-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327-6-8-9">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3-4-7" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4-0-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9-71-7">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-1-6" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-5-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9-71-7-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-1-6-2" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-5-4-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18118-8">
+ <stop
+ style="stop-color:#cd8ce9;stop-opacity:1"
+ offset="0"
+ id="stop18120-5" />
+ <stop
+ style="stop-color:#9425c1;stop-opacity:1"
+ offset="1"
+ id="stop18122-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18103-9">
+ <stop
+ id="stop18105-3"
+ offset="0"
+ style="stop-color:#42035d;stop-opacity:1" />
+ <stop
+ id="stop18108-4"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134-9"
+ id="linearGradient18140-0"
+ x1="121.48092"
+ y1="105.24046"
+ x2="137.67349"
+ y2="126.34584"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18134-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop18136-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop18138-9" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118-8"
+ id="radialGradient18260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6671799,6.7886038e-8,-6.7869731e-8,0.66734014,43.604995,38.604049)"
+ cx="129.99182"
+ cy="114.84092"
+ fx="129.99182"
+ fy="114.84092"
+ r="8.781251" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134-9"
+ id="linearGradient18262"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="137.67349"
+ y2="126.34584" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18103"
+ id="linearGradient18264"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="130.94904"
+ y2="118.11919" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118"
+ id="radialGradient18266"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.09893643,0.88659058,-0.70877161,0.07913125,199.3109,-8.5183197)"
+ cx="129.83784"
+ cy="115.58929"
+ fx="129.83784"
+ fy="115.58929"
+ r="8.7812506" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134"
+ id="linearGradient18268"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="136.95143"
+ y2="123.69764" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath31849-4">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 232.13187,93.950853 4.84276,0 4.23742,4.237465 0,4.842822 -9.08018,0 0,-9.080287 0,0 z"
+ id="path31851-6"
+ sodipodi:nodetypes="cccccc" />
+ </clipPath>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118-8-8"
+ id="radialGradient18260-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6671799,6.7886038e-8,-6.7869731e-8,0.66734014,43.604995,38.604049)"
+ cx="129.99182"
+ cy="114.84092"
+ fx="129.99182"
+ fy="114.84092"
+ r="8.781251" />
+ <linearGradient
+ id="linearGradient18118-8-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop18120-5-0" />
+ <stop
+ style="stop-color:#7b7b7b;stop-opacity:1;"
+ offset="1"
+ id="stop18122-5-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134-9-1"
+ id="linearGradient18262-3"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="137.67349"
+ y2="126.34584" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18134-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop18136-5-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop18138-9-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18103-1"
+ id="linearGradient18264-4"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="130.94904"
+ y2="118.11919" />
+ <linearGradient
+ id="linearGradient18103-1">
+ <stop
+ id="stop18105-2"
+ offset="0"
+ style="stop-color:#42035d;stop-opacity:1" />
+ <stop
+ id="stop18108-8"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118-0"
+ id="radialGradient18266-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.09893643,0.88659058,-0.70877161,0.07913125,199.3109,-8.5183197)"
+ cx="129.83784"
+ cy="115.58929"
+ fx="129.83784"
+ fy="115.58929"
+ r="8.781251" />
+ <linearGradient
+ id="linearGradient18118-0">
+ <stop
+ style="stop-color:#d297eb;stop-opacity:1;"
+ offset="0"
+ id="stop18120-4" />
+ <stop
+ style="stop-color:#a329d6;stop-opacity:1;"
+ offset="1"
+ id="stop18122-52" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134-0"
+ id="linearGradient18268-0"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="136.95143"
+ y2="123.69764" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18134-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop18136-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop18138-5" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118-8"
+ id="radialGradient19005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6671799,6.7886038e-8,-6.7869731e-8,0.66734014,43.604995,38.604049)"
+ cx="129.99182"
+ cy="114.84092"
+ fx="129.99182"
+ fy="114.84092"
+ r="8.781251" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134-9"
+ id="linearGradient19007"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="137.67349"
+ y2="126.34584" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18103"
+ id="linearGradient19009"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="130.94904"
+ y2="118.11919" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118"
+ id="radialGradient19011"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.09893643,0.88659058,-0.70877161,0.07913125,199.3109,-8.5183197)"
+ cx="129.83784"
+ cy="115.58929"
+ fx="129.83784"
+ fy="115.58929"
+ r="8.7812506" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134"
+ id="linearGradient19013"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="136.95143"
+ y2="123.69764" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118-8"
+ id="radialGradient19034"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6671799,6.7886038e-8,-6.7869731e-8,0.66734014,43.604995,38.604049)"
+ cx="129.99182"
+ cy="114.84092"
+ fx="129.99182"
+ fy="114.84092"
+ r="8.781251" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134-9"
+ id="linearGradient19036"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="137.67349"
+ y2="126.34584" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18103"
+ id="linearGradient19038"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="130.94904"
+ y2="118.11919" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18118"
+ id="radialGradient19040"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.09893643,0.88659058,-0.70877161,0.07913125,199.3109,-8.5183197)"
+ cx="129.83784"
+ cy="115.58929"
+ fx="129.83784"
+ fy="115.58929"
+ r="8.7812506" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18134"
+ id="linearGradient19042"
+ gradientUnits="userSpaceOnUse"
+ x1="121.48092"
+ y1="105.24046"
+ x2="136.95143"
+ y2="123.69764" />
+ <linearGradient
+ id="linearGradient40455-7-1-5">
+ <stop
+ id="stop40457-6-6-2"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-5"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-7-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6-8" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-9-6">
+ <stop
+ id="stop58336-27-0"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9-7"
+ 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(1,-94.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37610-3-9"
+ xlink:href="#linearGradient16500-4-9"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31-5" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40455-7-1-5-1">
+ <stop
+ id="stop40457-6-6-2-9"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-5-0"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-7-6-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6-8-2" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1-2-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-9-6-3">
+ <stop
+ id="stop58336-27-0-6"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9-7-0"
+ 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(1,-94.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient15428-6"
+ xlink:href="#linearGradient16500-4-9-3"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4-9-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31-5-8" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23-4-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-8-6">
+ <stop
+ id="stop37544-64-8"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-5-9"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-93-2">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-83-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-715-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-74-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-58-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15669">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15671" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15673" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15683-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15685" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15687" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-715-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-74-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-58-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15876">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15878" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15880" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15883">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15885" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15887" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15894">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15896" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15898" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060-97-8">
+ <stop
+ id="stop5062-5-3"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-5-0"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15905">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15907" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15909" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-8-7">
+ <stop
+ id="stop37544-64-6"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-5-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-93-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-83-5" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-715-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-74-63" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-58-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16099">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16101" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16103-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16113">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16115" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16117" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-8-78">
+ <stop
+ id="stop37544-64-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-5-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-93-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-83-8" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-715-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-74-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-58-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16099-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16101-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16103-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16113-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16115-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16117-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15806"
+ id="linearGradient15581"
+ gradientUnits="userSpaceOnUse"
+ x1="212.0226"
+ y1="361.34204"
+ x2="189.32315"
+ y2="340.89514" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15796"
+ id="linearGradient15583"
+ gradientUnits="userSpaceOnUse"
+ x1="192.4323"
+ y1="348.13098"
+ x2="208.33328"
+ y2="359.81409" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15796"
+ id="linearGradient16354"
+ gradientUnits="userSpaceOnUse"
+ x1="189.32315"
+ y1="340.89514"
+ x2="205.17293"
+ y2="357.81213" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15806"
+ id="linearGradient16399"
+ gradientUnits="userSpaceOnUse"
+ x1="212.0226"
+ y1="361.34204"
+ x2="189.32315"
+ y2="340.89514" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15796"
+ id="linearGradient16401"
+ gradientUnits="userSpaceOnUse"
+ x1="189.32315"
+ y1="340.89514"
+ x2="205.17293"
+ y2="357.81213" />
+ <linearGradient
+ id="linearGradient319-57">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-20" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-83" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15625">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15627" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15629" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15632">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15634" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15636" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-3-78-2">
+ <stop
+ id="stop23976-6-5-7"
+ offset="0"
+ style="stop-color:#a3a3a3;stop-opacity:1" />
+ <stop
+ id="stop23978-2-4-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16504-0-4">
+ <stop
+ id="stop16506-3-6"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop16508-0-1"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-47-9-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-85-3-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-48-3-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-12-5-0"
+ id="linearGradient42487-4-5-2"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ id="linearGradient319-12-5-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-34-1-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-81-9-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-8-7-5"
+ id="linearGradient42489-5-9-1"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ id="linearGradient15425-8-7-5">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15427-5-9-7" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429-7-2-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-12-5-0"
+ id="linearGradient42491-0-9-1"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ id="linearGradient15695">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15697" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15699" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-8-7-5"
+ id="linearGradient17232-8-1"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="141.64546"
+ y2="130.81215" />
+ <linearGradient
+ id="linearGradient15702">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15704" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15706" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-0"
+ id="linearGradient42326-4"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ id="linearGradient10069-0">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-75" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-44"
+ id="linearGradient42328-9"
+ gradientUnits="userSpaceOnUse"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-44">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-2" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-54"
+ id="linearGradient42330-3"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ id="linearGradient319-54">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-68" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-54"
+ id="linearGradient16613"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-07"
+ id="linearGradient14167-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="443.86667"
+ y1="133.98936"
+ x2="451.98389"
+ y2="143.58749" />
+ <linearGradient
+ id="linearGradient37542-07">
+ <stop
+ id="stop37544-66"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138-3"
+ id="linearGradient14169-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="453.61005"
+ y2="133.00301" />
+ <linearGradient
+ id="linearGradient4138-3">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop4140-2" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop4142-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-07"
+ id="linearGradient14171-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="449.14645"
+ y1="136.18045"
+ x2="453.24457"
+ y2="138.7879" />
+ <linearGradient
+ id="linearGradient16636">
+ <stop
+ id="stop16638"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop16640"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138-3"
+ id="linearGradient14173-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="454.31345"
+ y2="133.62801" />
+ <linearGradient
+ id="linearGradient16643">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop16645" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop16647" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-2"
+ id="linearGradient14167-87"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="443.86667"
+ y1="133.98936"
+ x2="451.98389"
+ y2="143.58749" />
+ <linearGradient
+ id="linearGradient37542-2">
+ <stop
+ id="stop37544-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-1"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138-39"
+ id="linearGradient14169-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="453.61005"
+ y2="133.00301" />
+ <linearGradient
+ id="linearGradient4138-39">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop4140-0" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop4142-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-2"
+ id="linearGradient14171-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="449.14645"
+ y1="136.18045"
+ x2="453.24457"
+ y2="138.7879" />
+ <linearGradient
+ id="linearGradient16738">
+ <stop
+ id="stop16740"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop16742"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138-39"
+ id="linearGradient14173-89"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="454.31345"
+ y2="133.62801" />
+ <linearGradient
+ id="linearGradient16745">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop16747" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop16749" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-07-7"
+ id="linearGradient14167-8-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="443.86667"
+ y1="133.98936"
+ x2="451.98389"
+ y2="143.58749" />
+ <linearGradient
+ id="linearGradient37542-07-7">
+ <stop
+ id="stop37544-66-6"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-6-7"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138-3-7"
+ id="linearGradient14169-0-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="453.61005"
+ y2="133.00301" />
+ <linearGradient
+ id="linearGradient4138-3-7">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop4140-2-0" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop4142-0-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-07-7"
+ id="linearGradient14171-2-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="449.14645"
+ y1="136.18045"
+ x2="453.24457"
+ y2="138.7879" />
+ <linearGradient
+ id="linearGradient16840">
+ <stop
+ id="stop16842-2"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop16844"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138-3-7"
+ id="linearGradient14173-8-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="454.31345"
+ y2="133.62801" />
+ <linearGradient
+ id="linearGradient16847">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop16849" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop16851" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-9"
+ id="linearGradient42346-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-57.780041"
+ y1="48.005856"
+ x2="-78.812721"
+ y2="31" />
+ <linearGradient
+ id="linearGradient319-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-98" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-56" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-9"
+ id="linearGradient42344-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-69.457596"
+ y1="31.914484"
+ x2="-76.564636"
+ y2="28.695114" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-21" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-22"
+ id="linearGradient42346-5"
+ gradientUnits="userSpaceOnUse"
+ x1="-57.780041"
+ y1="48.005856"
+ x2="-78.812721"
+ y2="31" />
+ <linearGradient
+ id="linearGradient319-22">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-61" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-3" />
+ </linearGradient>
+ <linearGradient
+ y2="31"
+ x2="-78.812721"
+ y1="48.005856"
+ x1="-57.780041"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17071"
+ xlink:href="#linearGradient319-22"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-91">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-01" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13938-6">
+ <stop
+ id="stop13940-6"
+ offset="0"
+ style="stop-color:#6e0c00;stop-opacity:1;" />
+ <stop
+ id="stop13942-0"
+ offset="1"
+ style="stop-color:#ee3800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29073">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29075" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29077" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16595-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop16597-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop16599-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-1-7-5-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-4-4-3-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-0-0-8-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-3" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-2" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-93">
+ <stop
+ id="stop58336-4"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-1"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5"
+ id="linearGradient39260-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-311" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-5" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43050-6">
+ <rect
+ y="-122"
+ x="-24"
+ height="14"
+ width="16"
+ id="rect43052-3"
+ style="opacity:0.5;fill:url(#linearGradient43054-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="linearGradient43054-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333333,0,0,1.2727273,2.6666667,29.454545)"
+ x1="-4.2231579"
+ y1="-92.440941"
+ x2="-18.697306"
+ y2="-115.04018" />
+ <linearGradient
+ id="linearGradient44627-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop44629-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop44631-0" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-5-1-8-2-5"
+ id="radialGradient24295-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1558466,-0.5928702,0.3902392,0.7608013,47.408342,-36.891937)"
+ cx="-14.226811"
+ cy="-115.06647"
+ fx="-14.226811"
+ fy="-115.06647"
+ r="7.1500001" />
+ <linearGradient
+ id="linearGradient10069-9-5-1-8-2-5">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-43-3-0-0-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-1-8-2-5-2" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-5-1-8-2-5"
+ id="radialGradient24297-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3236133,-0.01520056,0.01787935,0.3806433,-7.6938144,-72.764853)"
+ cx="-20.110701"
+ cy="-125.53457"
+ fx="-20.110701"
+ fy="-125.53457"
+ r="7.1500001" />
+ <linearGradient
+ id="linearGradient13837">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop13839" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop13841" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74-1"
+ id="radialGradient24299-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.0312701,-2.5000045,2.468554,-0.03087567,251.90641,-216.06454)"
+ cx="-39.154209"
+ cy="-118.1383"
+ fx="-39.154209"
+ fy="-118.1383"
+ r="1" />
+ <linearGradient
+ id="linearGradient10069-9-7-4-74-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-0-5" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-9-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74-1"
+ id="linearGradient33126-9"
+ gradientUnits="userSpaceOnUse"
+ x1="110.81759"
+ y1="99.274445"
+ x2="131.81595"
+ y2="116.38528" />
+ <linearGradient
+ id="linearGradient13848">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop13850" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop13852" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-5"
+ id="linearGradient33128-2"
+ gradientUnits="userSpaceOnUse"
+ x1="128.0486"
+ y1="112.48544"
+ x2="135.0885"
+ y2="121.2344" />
+ <linearGradient
+ id="linearGradient44939-8-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-7" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask48816-8">
+ <rect
+ y="-84"
+ x="-44"
+ height="14"
+ width="13"
+ id="rect48818-4"
+ style="opacity:0.85;fill:url(#radialGradient48820-9);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="radialGradient48820-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.0769231,0,5.9230769)"
+ cx="-31"
+ cy="-83.5"
+ fx="-31"
+ fy="-83.5"
+ r="6.5" />
+ <linearGradient
+ id="linearGradient13861">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop13863" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop13865" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24279-6"
+ gradientUnits="userSpaceOnUse"
+ x1="122.80294"
+ y1="107.95783"
+ x2="133.00108"
+ y2="118.79662" />
+ <linearGradient
+ id="linearGradient10069-9-7-4-4">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-8" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24281-3"
+ gradientUnits="userSpaceOnUse"
+ x1="127.94764"
+ y1="111.77869"
+ x2="139.37589"
+ y2="126.95278" />
+ <linearGradient
+ id="linearGradient44939-09">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-0" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13875">
+ <rect
+ y="-84"
+ x="-44"
+ height="14"
+ width="13"
+ id="rect13877"
+ style="opacity:0.85;fill:url(#radialGradient48820-9);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="radialGradient13879"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.0769231,0,5.9230769)"
+ cx="-31"
+ cy="-83.5"
+ fx="-31"
+ fy="-83.5"
+ r="6.5" />
+ <linearGradient
+ id="linearGradient13881">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop13883" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop13885" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24283-7"
+ gradientUnits="userSpaceOnUse"
+ x1="122.80294"
+ y1="107.95783"
+ x2="133.00108"
+ y2="118.79662" />
+ <linearGradient
+ id="linearGradient13888">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop13890" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop13892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24285-8"
+ gradientUnits="userSpaceOnUse"
+ x1="127.94764"
+ y1="111.77869"
+ x2="139.90622"
+ y2="126.33406" />
+ <linearGradient
+ id="linearGradient13895">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop13897" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop13899" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask28585-8">
+ <rect
+ style="opacity:0.85;fill:url(#radialGradient28589-9);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect28587-2"
+ width="13"
+ height="14"
+ x="-44"
+ y="-84" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="radialGradient28589-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.0769231,0,5.9230769)"
+ cx="-30.28125"
+ cy="-84.341515"
+ fx="-30.28125"
+ fy="-84.341515"
+ r="6.5" />
+ <linearGradient
+ id="linearGradient13904">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop13906" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop13908" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24287-1"
+ gradientUnits="userSpaceOnUse"
+ x1="122.80294"
+ y1="107.95783"
+ x2="133.00108"
+ y2="118.79662" />
+ <linearGradient
+ id="linearGradient13911">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop13913" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop13915" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24289-3"
+ gradientUnits="userSpaceOnUse"
+ x1="127.94764"
+ y1="111.77869"
+ x2="141.05528"
+ y2="129.25089" />
+ <linearGradient
+ id="linearGradient13918">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop13920" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop13922" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24241-6"
+ gradientUnits="userSpaceOnUse"
+ x1="128.72093"
+ y1="113.87833"
+ x2="134.73141"
+ y2="121.3562" />
+ <linearGradient
+ id="linearGradient13925">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop13927" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop13929" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24243-1"
+ gradientUnits="userSpaceOnUse"
+ x1="127.94764"
+ y1="111.77869"
+ x2="140.59081"
+ y2="129.0453" />
+ <linearGradient
+ id="linearGradient13932">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop13934" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop13936" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24245-3"
+ gradientUnits="userSpaceOnUse"
+ x1="122.85946"
+ y1="108.45374"
+ x2="132.08098"
+ y2="118.71043" />
+ <linearGradient
+ id="linearGradient13939">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop13941" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop13943" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24247-8"
+ gradientUnits="userSpaceOnUse"
+ x1="127.94764"
+ y1="111.77869"
+ x2="142.87355"
+ y2="131.66185" />
+ <linearGradient
+ id="linearGradient13946">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop13948" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop13950" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43271-3"
+ id="linearGradient24249-9"
+ gradientUnits="userSpaceOnUse"
+ x1="-38.5"
+ y1="-52.5"
+ x2="-37"
+ y2="-54" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43271-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43273-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43275-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43271-3"
+ id="linearGradient24251-6"
+ gradientUnits="userSpaceOnUse"
+ x1="-43.5"
+ y1="-56"
+ x2="-39"
+ y2="-52" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24253-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2489483,0,0,0.2448135,-72.383415,-81.330431)"
+ x1="135.91603"
+ y1="121.04676"
+ x2="125.4409"
+ y2="99.924934" />
+ <linearGradient
+ id="linearGradient13964">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop13966" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop13968" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43271-3"
+ id="linearGradient24255-6"
+ gradientUnits="userSpaceOnUse"
+ x1="130.92398"
+ y1="110.40864"
+ x2="122.93221"
+ y2="108.93221" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24257-6"
+ gradientUnits="userSpaceOnUse"
+ x1="122.80294"
+ y1="107.95783"
+ x2="133.00108"
+ y2="118.79662" />
+ <linearGradient
+ id="linearGradient13978">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop13980" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop13982" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24259-1"
+ gradientUnits="userSpaceOnUse"
+ x1="127.94764"
+ y1="111.77869"
+ x2="144.59082"
+ y2="133.6703" />
+ <linearGradient
+ id="linearGradient13985">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop13987" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop13989" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43040-7">
+ <rect
+ style="opacity:0.5;fill:url(#linearGradient43044-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43042-9"
+ width="15"
+ height="16"
+ x="-45.04018"
+ y="-24"
+ rx="0"
+ ry="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43760-6-4"
+ id="linearGradient43044-5"
+ gradientUnits="userSpaceOnUse"
+ x1="-44.709698"
+ y1="-8.4836445"
+ x2="-37.784756"
+ y2="-18.517523"
+ gradientTransform="translate(-0.04018164,0)" />
+ <linearGradient
+ id="linearGradient43760-6-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop43762-7-3" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop43764-8-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-71-3"
+ id="linearGradient24236-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-242.99992,269.00357)"
+ x1="202.85626"
+ y1="276.47174"
+ x2="212.82164"
+ y2="288.37567" />
+ <linearGradient
+ id="linearGradient9030-71-3">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-15-3" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-276-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-5-1-1"
+ id="linearGradient24239-1"
+ gradientUnits="userSpaceOnUse"
+ x1="125.93652"
+ y1="111.8362"
+ x2="132.65851"
+ y2="117.92533" />
+ <linearGradient
+ id="linearGradient10069-9-5-1-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-43-3-3" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-1-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-5-1-1"
+ id="linearGradient24230-5"
+ gradientUnits="userSpaceOnUse"
+ x1="117.00603"
+ y1="104.51898"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ id="linearGradient14006">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop14008" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop14010" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-2-8"
+ id="linearGradient24232-9"
+ gradientUnits="userSpaceOnUse"
+ x1="128.0486"
+ y1="112.48544"
+ x2="139.58116"
+ y2="126.8241" />
+ <linearGradient
+ id="linearGradient44939-2-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-7-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-7-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-5-1-1"
+ id="linearGradient24234-7"
+ gradientUnits="userSpaceOnUse"
+ x1="117.00603"
+ y1="104.51898"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ id="linearGradient14017">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop14019" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop14021" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask45865-7">
+ <g
+ id="g45867-3"
+ transform="translate(-14,0)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssssc"
+ id="path45869-7"
+ d="m -25.801826,-135.3217 c -0.907684,-0.32824 -0.906457,-1.55361 -0.440107,-2.23642 0.834186,-1.22138 2.593738,-1.15244 3.63669,-0.26277 1.530569,1.30563 1.388406,3.6923 0.08107,5.09763 -1.742467,1.8731 -4.73519,1.65156 -6.47424,-0.0993 -2.188413,-2.20322 -1.889457,-5.85971 0.277965,-7.95885 2.625036,-2.54234 6.931515,-2.199 9.311783,0.46129 2.764074,3.08924 2.372937,7.82808 -0.06591,10.77438"
+ style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ mask="none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path45871-2"
+ d="m -19.40866,-140.32008 c 2.764074,3.08924 2.372937,7.82808 -0.06591,10.77438"
+ style="fill:none;stroke:url(#linearGradient45875-0);stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ inkscape:connector-curvature="0"
+ mask="none"
+ style="fill:none;stroke:url(#radialGradient45877-1);stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -25.801826,-135.3217 c -0.907684,-0.32824 -0.906457,-1.55361 -0.440107,-2.23642 0.834186,-1.22138 2.593738,-1.15244 3.63669,-0.26277"
+ id="path45873-6"
+ sodipodi:nodetypes="css" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43760-7"
+ id="linearGradient45875-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(14,0)"
+ x1="-34.051685"
+ y1="-129.32457"
+ x2="-32.542458"
+ y2="-139.90228" />
+ <linearGradient
+ id="linearGradient43760-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop43762-79" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop43764-3" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43760-7"
+ id="radialGradient45877-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1099414,-0.9422316,0.4519816,0.05273803,38.220416,-152.21215)"
+ cx="-25.452209"
+ cy="-136.46503"
+ fx="-25.452209"
+ fy="-136.46503"
+ r="8.0066185" />
+ <linearGradient
+ id="linearGradient14033">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14035" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14037" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask45447-7">
+ <rect
+ ry="0"
+ style="opacity:0.8;fill:url(#radialGradient45451-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45449-4"
+ width="15"
+ height="15"
+ x="216"
+ y="366" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43760-7"
+ id="radialGradient45451-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9952162,167.99999,-60.91415)"
+ cx="59.000011"
+ cy="440.0191"
+ fx="59.000011"
+ fy="440.0191"
+ r="6.5080619" />
+ <linearGradient
+ id="linearGradient14042">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14044" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14046" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-42-9"
+ id="linearGradient24218-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ id="linearGradient319-42-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-32-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-21-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-0"
+ id="linearGradient24220-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ id="linearGradient10069-9-7-0">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-2" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-42-9"
+ id="linearGradient24222-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ id="linearGradient14057">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14059" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14061" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-0"
+ id="radialGradient24224-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9952162,0,2.085841)"
+ cx="60.007744"
+ cy="441.04678"
+ fx="60.007744"
+ fy="441.04678"
+ r="6.5080619" />
+ <linearGradient
+ id="linearGradient14064">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop14066" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop14068" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24226-2"
+ gradientUnits="userSpaceOnUse"
+ x1="113.01286"
+ y1="99.778664"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ id="linearGradient14071">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop14073" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop14075" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24228-5"
+ gradientUnits="userSpaceOnUse"
+ x1="128.0486"
+ y1="112.48544"
+ x2="136.08115"
+ y2="122.99075" />
+ <linearGradient
+ id="linearGradient14078">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14080" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14082" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-4"
+ id="linearGradient24214-1"
+ gradientUnits="userSpaceOnUse"
+ x1="118.73534"
+ y1="106.55459"
+ x2="133.00108"
+ y2="118.79662" />
+ <linearGradient
+ id="linearGradient14085">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop14087" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop14089" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-09"
+ id="linearGradient24216-4"
+ gradientUnits="userSpaceOnUse"
+ x1="127.94764"
+ y1="111.77869"
+ x2="140.59081"
+ y2="129.0453" />
+ <linearGradient
+ id="linearGradient14092">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14094" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14096" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43135-6">
+ <path
+ inkscape:connector-curvature="0"
+ id="path43137-1"
+ d="m -46,52 16,-16 -16,0 0,16 z"
+ style="opacity:0.5;fill:#ffff00;fill-rule:evenodd;stroke:none" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43188-4">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:url(#linearGradient43192-3);fill-rule:evenodd;stroke:none"
+ d="m -46,52 16,-16 -16,0 0,16 z"
+ id="path43190-2" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-5-2"
+ id="linearGradient43192-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-47"
+ y1="44"
+ x2="-43"
+ y2="44" />
+ <linearGradient
+ id="linearGradient1610-5-2">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-17-2" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-115-1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43178-6">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:#ffff00;fill-rule:evenodd;stroke:none"
+ d="m -30,36 -1,0 -15,15 0,1 16,0 0,-16 z"
+ id="path43180-8"
+ sodipodi:nodetypes="cccccc" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43182-5">
+ <path
+ inkscape:connector-curvature="0"
+ id="path43184-7"
+ d="m -46,52 0,-1 15,-15 1,0 0,16 -16,0 z"
+ style="opacity:0.5;fill:url(#linearGradient43186-6);fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-5-2"
+ id="linearGradient43186-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,6,6)"
+ x1="-47"
+ y1="44"
+ x2="-43"
+ y2="44" />
+ <linearGradient
+ id="linearGradient14111">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14113" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14115" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath14117">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:#ffff00;fill-rule:evenodd;stroke:none"
+ d="m -30,36 -1,0 -15,15 0,1 16,0 0,-16 z"
+ id="path14119"
+ sodipodi:nodetypes="cccccc" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask14121">
+ <path
+ inkscape:connector-curvature="0"
+ id="path14123"
+ d="m -46,52 0,-1 15,-15 1,0 0,16 -16,0 z"
+ style="opacity:0.5;fill:url(#linearGradient43186-6);fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-5-2"
+ id="linearGradient14125"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,6,6)"
+ x1="-47"
+ y1="44"
+ x2="-43"
+ y2="44" />
+ <linearGradient
+ id="linearGradient14127">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14129" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14131" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath14133">
+ <path
+ inkscape:connector-curvature="0"
+ id="path14135"
+ d="m -46,52 16,-16 -16,0 0,16 z"
+ style="opacity:0.5;fill:#ffff00;fill-rule:evenodd;stroke:none" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask14137">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:url(#linearGradient43192-3);fill-rule:evenodd;stroke:none"
+ d="m -46,52 16,-16 -16,0 0,16 z"
+ id="path14139" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-5-2"
+ id="linearGradient14141"
+ gradientUnits="userSpaceOnUse"
+ x1="-47"
+ y1="44"
+ x2="-43"
+ y2="44" />
+ <linearGradient
+ id="linearGradient14143">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14145" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14147" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74-1"
+ id="linearGradient24210-1"
+ gradientUnits="userSpaceOnUse"
+ x1="110.81759"
+ y1="99.274445"
+ x2="131.81595"
+ y2="116.38528" />
+ <linearGradient
+ id="linearGradient14150">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop14152" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop14154" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-5"
+ id="linearGradient24212-8"
+ gradientUnits="userSpaceOnUse"
+ x1="128.0486"
+ y1="112.48544"
+ x2="135.0885"
+ y2="121.2344" />
+ <linearGradient
+ id="linearGradient14157">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14159" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14161" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="linearGradient24044-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="44.380783"
+ y1="251.66991"
+ x2="36.415714"
+ y2="247.47705" />
+ <linearGradient
+ id="linearGradient14164">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14166" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14168" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="linearGradient24046-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="35.434578"
+ y1="250.11682"
+ x2="34"
+ y2="244" />
+ <linearGradient
+ id="linearGradient14171-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14173" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14175" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25021-4">
+ <rect
+ style="fill:url(#radialGradient25025-8);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25023-8"
+ width="13"
+ height="14"
+ x="26"
+ y="243" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="radialGradient25025-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8918342,0,0,0.8918344,-15.699877,27.900732)"
+ cx="49"
+ cy="254.64285"
+ fx="49"
+ fy="254.64285"
+ r="6.5" />
+ <linearGradient
+ id="linearGradient14180">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14182" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14184" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="radialGradient24048-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0474269,0.00526965,-0.00503098,0.9999873,-0.01415572,-0.141212)"
+ cx="27.411026"
+ cy="255.58899"
+ fx="27.411026"
+ fy="255.58899"
+ r="5.9250002" />
+ <linearGradient
+ id="linearGradient14187">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14189" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14191" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627-7"
+ id="radialGradient24050-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0474269,0.00526965,-0.00503098,0.9999873,-0.01415572,-0.141212)"
+ cx="27.411026"
+ cy="255.58899"
+ fx="27.411026"
+ fy="255.58899"
+ r="5.9250002" />
+ <linearGradient
+ id="linearGradient14194">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14196" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14198" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-5"
+ id="linearGradient24053-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="44.751385"
+ y1="254.98178"
+ x2="34.110981"
+ y2="244.60397" />
+ <linearGradient
+ id="linearGradient14201">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14203" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14205" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74-1"
+ id="linearGradient24055-1"
+ gradientUnits="userSpaceOnUse"
+ x1="110.81759"
+ y1="99.274445"
+ x2="131.81595"
+ y2="116.38528" />
+ <linearGradient
+ id="linearGradient14208">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop14210" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop14212" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-5"
+ id="linearGradient24057-7"
+ gradientUnits="userSpaceOnUse"
+ x1="128.0486"
+ y1="112.48544"
+ x2="137.44791"
+ y2="125.06842" />
+ <linearGradient
+ id="linearGradient14215">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14217" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14219" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-5-5"
+ id="linearGradient24022-6"
+ gradientUnits="userSpaceOnUse"
+ x1="-33.912659"
+ y1="-143.20003"
+ x2="-35.580078"
+ y2="-159.1228" />
+ <linearGradient
+ id="linearGradient10069-9-7-5-5">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-58-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-4-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-5-2"
+ id="linearGradient24024-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-41.5"
+ y1="-161.74199"
+ x2="-40.654259"
+ y2="-147.07195" />
+ <linearGradient
+ id="linearGradient14226">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop14228" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop14230" />
+ </linearGradient>
+ <linearGradient
+ y2="-156.42979"
+ x2="-37.567211"
+ y1="-148.8125"
+ x1="-34.09375"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient61917"
+ xlink:href="#linearGradient319-76-2-0"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-76-2-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-142-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-32-0" />
+ </linearGradient>
+ <linearGradient
+ y2="-156.42979"
+ x2="-37.567211"
+ y1="-148.8125"
+ x1="-34.09375"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient14482-7"
+ xlink:href="#linearGradient319-76-2-0"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10000"
+ objecttolerance="10000"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.2953846"
+ inkscape:cx="449.16029"
+ inkscape:cy="319"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer3"
+ showgrid="false"
+ inkscape:window-width="1280"
+ inkscape:window-height="750"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:snap-nodes="false"
+ inkscape:snap-bbox="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:object-nodes="false"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-intersection-grid-guide="false"
+ inkscape:window-maximized="1"
+ inkscape:bbox-paths="false"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-grids="true"
+ inkscape:snap-to-guides="false"
+ inkscape:snap-page="false"
+ units="pt"
+ inkscape:snap-center="false"
+ inkscape:snap-object-midpoints="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid17394"
+ visible="true"
+ enabled="true"
+ spacingx="0.25px"
+ spacingy="0.25px"
+ empspacing="4"
+ color="#808080"
+ opacity="0.09803922"
+ dotted="false"
+ empcolor="#7f7f7f"
+ empopacity="0.25098039"
+ snapvisiblegridlinesonly="true"
+ originx="0px"
+ originy="-2.7755576e-17px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Blender icons v. 2.5.08</dc:title>
+ <dc:date>21.05.2012</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:coverage />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-nc-sa/3.0/" />
+ <dc:description>This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed.</dc:description>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-nc-sa/3.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:prohibits
+ rdf:resource="http://creativecommons.org/ns#CommercialUse" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer3"
+ inkscape:label="bckgrnd"
+ style="display:none"
+ sodipodi:insensitive="true">
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect20607"
+ width="1083.874"
+ height="650"
+ x="-4"
+ y="-4" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;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"
+ id="path23417"
+ sodipodi:nodetypes="cc"
+ d="" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23347"
+ sodipodi:nodetypes="cc"
+ d="" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer5"
+ inkscape:label="grid"
+ style="opacity:0.3;display:inline"
+ sodipodi:insensitive="true">
+ <g
+ id="g40174"
+ transform="translate(0,2)">
+ <g
+ id="g22995">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22955"
+ width="1"
+ height="7"
+ x="422"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="401"
+ height="7"
+ width="1"
+ id="rect22957"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22959"
+ width="1"
+ height="7"
+ x="380"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="359"
+ height="7"
+ width="1"
+ id="rect22961"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22963"
+ width="1"
+ height="7"
+ x="338"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="317"
+ height="7"
+ width="1"
+ id="rect22965"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22967"
+ width="1"
+ height="7"
+ x="296"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="275"
+ height="7"
+ width="1"
+ id="rect22969"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22971"
+ width="1"
+ height="7"
+ x="254"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="233"
+ height="7"
+ width="1"
+ id="rect22973"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22975"
+ width="1"
+ height="7"
+ x="212"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="191"
+ height="7"
+ width="1"
+ id="rect22977"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22979"
+ width="1"
+ height="7"
+ x="170"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="149"
+ height="7"
+ width="1"
+ id="rect22981"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22983"
+ width="1"
+ height="7"
+ x="128"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="107"
+ height="7"
+ width="1"
+ id="rect22985"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22987"
+ width="1"
+ height="7"
+ x="86"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="65"
+ height="7"
+ width="1"
+ id="rect22989"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22991"
+ width="1"
+ height="7"
+ x="44"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="23"
+ height="7"
+ width="1"
+ id="rect22993"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="506"
+ height="7"
+ width="1"
+ id="rect23024"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23026"
+ width="1"
+ height="7"
+ x="485"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="464"
+ height="7"
+ width="1"
+ id="rect23028"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23030"
+ width="1"
+ height="7"
+ x="443"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect10985"
+ width="1"
+ height="7"
+ x="527"
+ y="0"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g24954">
+ <g
+ id="g23711"
+ transform="translate(0,462)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23713"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23715">
+ <path
+ id="path23717"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23719"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23721"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23723"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23725"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23727"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23729"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23731"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23733"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23735"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23737"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23739"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23741"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23743"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23745"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23747"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23749"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23751"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23753"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23755"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23757"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23759"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23761"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23763"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10987"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23765"
+ transform="translate(0,441)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect23767"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23769">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23771"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23773"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23775"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23777"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23779"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23781"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23783"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23785"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23787"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23789"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23791"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23793"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23795"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23797"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23799"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23801"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23803"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23805"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23807"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23809"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23811"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23813"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23815"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23817"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10990"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23819"
+ transform="translate(0,420)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23821"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23823">
+ <path
+ id="path23825"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23827"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23829"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23831"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23833"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23835"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23837"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23839"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23841"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23843"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23845"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23847"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23849"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23851"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23853"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23855"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23857"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23859"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23861"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23863"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23865"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23867"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23869"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23871"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10992"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23873"
+ transform="translate(0,399)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect23875"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23877">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23879"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23881"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23883"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23885"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23887"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23889"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23891"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23893"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23895"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23897"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23899"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23901"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23903"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23905"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23907"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23909"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23911"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23913"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23915"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23917"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23919"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23921"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23923"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23925"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10994"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23927"
+ transform="translate(0,378)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23929"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23931">
+ <path
+ id="path23933"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23935"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23937"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23939"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23941"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23943"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23945"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23947"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23949"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23951"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23953"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23955"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23957"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23959"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23961"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23963"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23965"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23967"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23969"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23971"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23973"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23975"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23977"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23979"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10996"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23981"
+ transform="translate(0,357)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23983"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23985">
+ <path
+ id="path23987"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23989"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23991"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23993"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23995"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23997"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23999"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24001"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24003"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24005"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24007"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24009"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24011"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24013"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24015"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24017"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24019"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24021"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24023"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24025"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24027"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24029"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24031"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24033"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10998"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24035"
+ transform="translate(0,336)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24037"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24039">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24041"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24043"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24045"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24047"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24049"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24051"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24053"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24055"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24057"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24059"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24061"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24063"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24065"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24067"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24069"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24071"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24073"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24075"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24077"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24079"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24081"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24083"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24085"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24087"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11000"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24089"
+ transform="translate(0,315)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24091"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24093">
+ <path
+ id="path24095"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24097"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24099"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24101"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24103"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24105"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24107"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24109"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24111"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24113"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24115"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24117"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24119"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24121"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24123"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24125"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24127"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24129"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24131"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24133"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24135"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24137"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24139"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24141"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11002"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24143"
+ transform="translate(0,294)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24145"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24147">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24149"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24151"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24153"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24155"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24157"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24159"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24161"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24163"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24165"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24167"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24169"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24171"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24173"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24175"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24177"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24179"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24181"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24183"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24185"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24187"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24189"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24191"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24193"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24195"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11004"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24197"
+ transform="translate(0,273)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24199"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24201">
+ <path
+ id="path24203"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24205"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24207"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24209"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24211"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24213"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24215"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24217"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24219"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24221"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24223"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24225"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24227"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24229"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24231"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24233"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24235"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24237"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24239"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24241"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24243"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24245"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24247"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24249"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11006"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24251"
+ transform="translate(0,252)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24253"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24255">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24257"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24259"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24261"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24263"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24265"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24267"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24269"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24271"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24273"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24275"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24277"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24279"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24281"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24283"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24285"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24287"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24289"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24291"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24293"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24295"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24297"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24299"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24301"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24303"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11008"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24305"
+ transform="translate(0,231)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24307"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24309">
+ <path
+ id="path24311"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24313"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24315"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24317"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24319"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24321"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24323"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24325"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24327"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24329"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24331"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24333"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24335"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24337"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24339"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24341"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24343"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24345"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24347"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24349"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24351"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24353"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24355"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24357"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11010"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24359"
+ transform="translate(0,210)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24361"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24363">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24365"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24367"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24369"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24371"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24373"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24375"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24377"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24379"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24381"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24383"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24385"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24387"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24389"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24391"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24393"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24395"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24397"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24399"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24401"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24403"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24405"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24407"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24409"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24411"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11012"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24413"
+ transform="translate(0,189)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24415"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24417">
+ <path
+ id="path24419"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24421"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24423"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24425"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24427"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24429"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24431"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24433"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24435"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24437"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24439"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24441"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24443"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24445"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24447"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24449"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24451"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24453"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24455"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24457"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24459"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24461"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24463"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24465"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11014"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24467"
+ transform="translate(0,168)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24469"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24471">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24473"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24475"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24477"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24479"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24481"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24483"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24485"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24487"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24489"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24491"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24493"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24495"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24497"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24499"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24501"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24503"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24505"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24507"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24509"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24511"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24513"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24515"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24517"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24519"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11016"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24521"
+ transform="translate(0,147)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24523"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24525">
+ <path
+ id="path24527"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24529"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24531"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24533"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24535"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24537"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24539"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24541"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24543"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24545"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24547"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24549"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24551"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24553"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24555"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24557"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24559"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24561"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24563"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24565"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24567"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24569"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24571"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24573"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11018"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24575"
+ transform="translate(0,126)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24577"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24579">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24581"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24583"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24585"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24587"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24589"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24591"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24593"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24595"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24597"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24599"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24601"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24603"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24605"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24607"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24609"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24611"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24613"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24615"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24617"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24619"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24621"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24623"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24625"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24627"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11020"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24630"
+ transform="translate(0,105)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24632"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24634">
+ <path
+ id="path24636"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24638"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24640"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24642"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24644"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24646"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24648"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24650"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24652"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24654"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24656"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24658"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24660"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24662"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24664"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24666"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24668"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24670"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24672"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24674"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24676"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24678"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24680"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24682"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11022"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24684"
+ transform="translate(0,84)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24686"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24688">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24690"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24692"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24694"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24696"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24698"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24700"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24702"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24704"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24706"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24708"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24710"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24712"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24714"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24716"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24718"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24720"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24722"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24724"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24726"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24728"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24730"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24732"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24734"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24736"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11024"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24738"
+ transform="translate(0,63)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24740"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24742">
+ <path
+ id="path24744"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24746"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24748"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24750"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24752"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24754"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24756"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24758"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24760"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24762"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24764"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24766"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24768"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24770"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24772"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24774"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24776"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24778"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24780"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24782"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24784"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24786"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24788"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24790"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11026"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24792"
+ transform="translate(0,42)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24794"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24796">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24798"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24800"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24802"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24804"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24806"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24808"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24810"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24812"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24814"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24816"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24818"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24820"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24822"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24824"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24826"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24828"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24830"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24832"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24834"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24836"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24838"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24840"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24842"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24844"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11028"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24846"
+ transform="translate(0,21)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24848"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24850">
+ <path
+ id="path24852"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24854"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24856"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24858"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24860"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24862"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24864"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24866"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24868"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24870"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24872"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24874"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24876"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24878"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24880"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24882"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24884"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24886"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24888"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24890"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24892"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24894"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24896"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24898"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11030"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24900">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24902"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24904">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24906"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24908"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24910"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24912"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24914"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24916"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24918"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24920"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24922"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24924"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24926"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24928"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24930"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24932"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24934"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24936"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24938"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24940"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24942"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24944"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24946"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24948"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24950"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24952"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11032"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,483)"
+ id="g39833">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect39835"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39837">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39840"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39842"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39844"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39846"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39848"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39850"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39852"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39854"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39856"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39858"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39860"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39862"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39864"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39866"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39868"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39870"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39872"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39874"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39876"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39878"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39880"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39882"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39884"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39888"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39890"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39892"
+ transform="translate(0,504)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39894"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g39896">
+ <path
+ id="path39898"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39900"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39902"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39904"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39907"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39909"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39911"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39913"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39915"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39917"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39919"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39921"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39923"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39925"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39927"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39929"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39931"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39933"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39935"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39937"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39939"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39941"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39943"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39945"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39947"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,525)"
+ id="g39949">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect39951"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39953">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39955"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39957"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39959"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39961"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39963"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39965"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39967"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39969"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39971"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39973"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39975"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39977"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39979"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39981"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39983"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39985"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39987"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39989"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39991"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39993"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39995"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39997"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39999"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40001"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40003"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g40005"
+ transform="translate(0,546)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40007"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g40009">
+ <path
+ id="path40011"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40013"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40015"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40017"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40019"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40021"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40023"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40025"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40027"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40029"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40031"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40033"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40035"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40038"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40040"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40042"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40044"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40046"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40048"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40050"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40052"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40054"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40056"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40058"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40060"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,567)"
+ id="g40062">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect40064"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g40066">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40068"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40070"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40072"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40074"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40076"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40078"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40080"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40082"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40084"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40086"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40088"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40090"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40092"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40094"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40096"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40098"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40100"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40102"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40104"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40106"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40108"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40110"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40112"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40114"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40116"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g40118"
+ transform="translate(0,588)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40120"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g40122">
+ <path
+ id="path40124"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40126"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40128"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40130"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40132"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40134"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40136"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40138"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40140"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40142"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40144"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40146"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40148"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40150"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40152"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40154"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40156"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40158"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40160"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40162"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40164"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40166"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40168"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40170"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40172"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(0,633)"
+ id="g25954">
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="422"
+ height="7"
+ width="1"
+ id="rect25956"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25958"
+ width="1"
+ height="7"
+ x="401"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="380"
+ height="7"
+ width="1"
+ id="rect25960"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25962"
+ width="1"
+ height="7"
+ x="359"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="338"
+ height="7"
+ width="1"
+ id="rect25964"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25966"
+ width="1"
+ height="7"
+ x="317"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="296"
+ height="7"
+ width="1"
+ id="rect25968"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25970"
+ width="1"
+ height="7"
+ x="275"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="254"
+ height="7"
+ width="1"
+ id="rect25972"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25974"
+ width="1"
+ height="7"
+ x="233"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="212"
+ height="7"
+ width="1"
+ id="rect25976"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25978"
+ width="1"
+ height="7"
+ x="191"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="170"
+ height="7"
+ width="1"
+ id="rect25980"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25982"
+ width="1"
+ height="7"
+ x="149"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="128"
+ height="7"
+ width="1"
+ id="rect25984"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25986"
+ width="1"
+ height="7"
+ x="107"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="86"
+ height="7"
+ width="1"
+ id="rect25988"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25990"
+ width="1"
+ height="7"
+ x="65"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="44"
+ height="7"
+ width="1"
+ id="rect25992"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25994"
+ width="1"
+ height="7"
+ x="23"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25996"
+ width="1"
+ height="7"
+ x="506"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="485"
+ height="7"
+ width="1"
+ id="rect25998"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26000"
+ width="1"
+ height="7"
+ x="464"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="443"
+ height="7"
+ width="1"
+ id="rect26002"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="527"
+ height="7"
+ width="1"
+ id="rect11034"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g30515"
+ transform="translate(-121.95685,2)">
+ <rect
+ ry="0"
+ rx="0"
+ y="488"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect26734"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26788"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="467"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="446"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect26842"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26896"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="425"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="404"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect26950"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="383"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27004"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27058"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="362"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="341"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27112"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27166"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="320"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="299"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27220"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27274"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="278"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="257"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27328"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27382"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="236"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="215"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27436"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27490"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="194"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="173"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27544"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27598"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="152"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="131"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27652"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27706"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="110"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="89"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27760"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27814"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="68"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="47"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27868"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27922"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="26"
+ rx="0"
+ ry="0" />
+ </g>
+ <rect
+ style="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="rect28448"
+ width="0"
+ height="0"
+ x="217.25"
+ y="263.5" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer4"
+ inkscape:label="sheet layout"
+ style="display:inline"
+ sodipodi:insensitive="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path19551-18-8"
+ d="m 585,613.25 1,0 0,0.5 1,0 0,-0.5 1,0 0,0.75 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,0.75 -1,0 0,-0.5 -1,0 0,0.5 -1,0 0,1.5 z m 1,-0.25 0,-1 1,0 0,1 -1,0 z m 2,0 0,-1 1,0 0,1 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19551-18-1"
+ d="m 907.75,209 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ 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" />
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ id="g28552-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 536,14 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28554-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 539,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28556-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 544,14 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -2,-1 0,-3 -1,0 0,3 1,0 z"
+ id="path28558-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 553,14 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ id="path28560-9"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28562-4"
+ width="1"
+ height="1"
+ x="548"
+ y="18" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28564-8"
+ width="1"
+ height="5"
+ x="557"
+ y="14" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 559,14 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path28566-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 565.75,14 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28568-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 570,14 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path28570-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 573,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28572-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21.98523,3)"
+ id="g28574-5">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 534,74 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28576-1"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28578-7"
+ width="1"
+ height="5"
+ x="538"
+ y="74" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 540,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path28580-1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28582-1"
+ d="m 544,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28584-5"
+ d="m 551,74 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28586-2"
+ d="m 554,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 558,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path28588-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 562,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28590-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 567,74 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path28592-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 570,74 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28594-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ id="g28596-2">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 535,119 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ id="path28598-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 539,119 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28600-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 545,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ id="path28602-2"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28604-1"
+ width="1"
+ height="5"
+ x="549"
+ y="119" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 551,119 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28606-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 555,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ id="path28608-8"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(16,1)"
+ id="g28610-5">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 540,160 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28612-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 544,160 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28614-6"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28616-1"
+ width="1"
+ height="5"
+ x="548"
+ y="160" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 550,160 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28618-8"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="160"
+ x="554"
+ height="5"
+ width="1"
+ id="rect28620-9"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 556,160 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28622-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 562,160 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -0.99999,0 0,1.25 -1.00001,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path28624-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ id="g28626-9">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 535.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28628-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 539,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28630-4"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28632-3"
+ width="1"
+ height="5"
+ x="544"
+ y="224" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 546,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path28634-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 552.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28636-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 556,224 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28638-3"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="224"
+ x="560"
+ height="5"
+ width="1"
+ id="rect28640-3"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 563,224 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28642-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 567,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28644-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(22,-10)"
+ id="g28646-1">
+ <path
+ id="path28648-3"
+ d="m 535,267 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28650-8"
+ d="m 542,267 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 546,267 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28652-7"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28654-4"
+ width="1"
+ height="5"
+ x="550"
+ y="267" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 552,267 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28656-2"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28658-7"
+ width="1"
+ height="5"
+ x="556"
+ y="267" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 558,267 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28660-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 562,267 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28662-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 567,267 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28664-3"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(25,-1)"
+ id="g28666-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 532,36 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28668-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 539.75,36 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28670-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 543,36 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28672-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 547,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28674-5"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28676-0"
+ d="m 555,36 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 558,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28678-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 562,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28680-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28682-6"
+ d="m 566,36 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"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28684-0"
+ d="m 570,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 535,36 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path28686-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(19,125)"
+ id="g28688-4">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 538,299 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28690-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 542,299 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path28692-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 547,299 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28694-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 551,299 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path28696-0"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28698-9"
+ width="1"
+ height="5"
+ x="555"
+ y="299" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 557,299 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28700-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 562,299 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28702-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 566,299 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28704-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,128)"
+ id="g28706-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 539.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28708-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 535,359 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28710-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 543,359 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28712-9"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28714-3"
+ d="m 547.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(22,125)"
+ id="g28716-4">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 545,393 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28718-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 549,393 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28720-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 534,393 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path28722-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 541,393 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28724-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 554,393 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28726-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(22.01477,127)"
+ id="g28728-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 538,412 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28730-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 534,412 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28732-4"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28734-9"
+ width="1"
+ height="5"
+ x="542"
+ y="412" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 549,412 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28736-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 553,412 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28738-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 558,412 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28740-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 544,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28742-8"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(22.01477,127)"
+ id="g28744-8">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 534,434 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path28746-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 556,434 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28748-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 552,434 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28750-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 562,434 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28752-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 543,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28754-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 538,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path28756-9"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28758-8"
+ d="m 547,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(19,127)"
+ id="g28760-4">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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="rect28762-0"
+ width="1"
+ height="5"
+ x="542"
+ y="486" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;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 537,486 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path28764-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10763-6"
+ transform="translate(21,0)">
+ <path
+ id="path10757-3"
+ d="m 536,14 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10759-6"
+ d="m 539,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10761-1"
+ d="m 544,14 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -2,-1 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10763-5"
+ d="m 553,14 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="18"
+ x="548"
+ height="1"
+ width="1"
+ id="rect10765-4"
+ 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
+ y="14"
+ x="557"
+ height="5"
+ width="1"
+ id="rect10767-2"
+ 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" />
+ <path
+ id="path10769-0"
+ d="m 559,14 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10771-9"
+ d="m 565.75,14 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10773-7"
+ d="m 570,14 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10775-3"
+ d="m 573,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10815-7"
+ transform="translate(21.98523,3)">
+ <path
+ id="path10799-2"
+ d="m 534,74 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="74"
+ x="538"
+ height="5"
+ width="1"
+ id="rect10801-6"
+ 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" />
+ <path
+ id="path10803-0"
+ d="m 540,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 544,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path10805-1"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 551,74 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path10807-6"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 554,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path10809-5"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10811-7"
+ d="m 558,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10813-5"
+ d="m 562,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10815-4"
+ d="m 567,74 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10817-1"
+ d="m 570,74 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10827-2"
+ transform="translate(21,0)">
+ <path
+ id="path10672-0"
+ d="m 535,119 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10678-0"
+ d="m 539,119 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10680-1"
+ d="m 545,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="119"
+ x="549"
+ height="5"
+ width="1"
+ id="rect10682-4"
+ 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" />
+ <path
+ id="path10684-6"
+ d="m 551,119 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10686-0"
+ d="m 555,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10835-7"
+ transform="translate(16,1)">
+ <path
+ id="path10688-1"
+ d="m 540,160 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10690-7"
+ d="m 544,160 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="160"
+ x="548"
+ height="5"
+ width="1"
+ id="rect10692-7"
+ 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" />
+ <path
+ id="path10694-7"
+ d="m 550,160 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <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="rect10696-7"
+ width="1"
+ height="5"
+ x="554"
+ y="160" />
+ <path
+ id="path10698-3"
+ d="m 556,160 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10700-3"
+ d="m 562,160 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -0.99999,0 0,1.25 -1.00001,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10846-5"
+ transform="translate(21,0)">
+ <path
+ id="path10703-9"
+ d="m 535.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10705-9"
+ d="m 539,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="224"
+ x="544"
+ height="5"
+ width="1"
+ id="rect10708-8"
+ 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" />
+ <path
+ id="path10711-1"
+ d="m 546,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10714-8"
+ d="m 552.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10716-2"
+ d="m 556,224 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <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="rect10718-6"
+ width="1"
+ height="5"
+ x="560"
+ y="224" />
+ <path
+ id="path10734-6"
+ d="m 563,224 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10736-0"
+ d="m 567,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10857-3"
+ transform="translate(22,-10)">
+ <path
+ 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"
+ d="m 535,267 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path10744-8"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 542,267 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path10746-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10748-1"
+ d="m 546,267 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="267"
+ x="550"
+ height="5"
+ width="1"
+ id="rect10750-2"
+ 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" />
+ <path
+ id="path10752-5"
+ d="m 552,267 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="267"
+ x="556"
+ height="5"
+ width="1"
+ id="rect10754-0"
+ 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" />
+ <path
+ id="path10756-9"
+ d="m 558,267 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10758-4"
+ d="m 562,267 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10760-7"
+ d="m 567,267 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10803-8"
+ transform="translate(25,-1)">
+ <path
+ id="path10777-3"
+ d="m 532,36 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10781-5"
+ d="m 539.75,36 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10783-1"
+ d="m 543,36 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10785-2"
+ d="m 547,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 555,36 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ id="path10787-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10789-1"
+ d="m 558,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10791-6"
+ d="m 562,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 566,36 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"
+ id="path10795-4"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 570,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path10797-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10800-6"
+ d="m 535,36 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10885-1"
+ transform="translate(19,125)">
+ <path
+ id="path10869-8"
+ d="m 538,299 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10871-9"
+ d="m 542,299 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10873-8"
+ d="m 547,299 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10875-4"
+ d="m 551,299 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="299"
+ x="555"
+ height="5"
+ width="1"
+ id="rect10877-1"
+ 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" />
+ <path
+ id="path10879-4"
+ d="m 557,299 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10881-3"
+ d="m 562,299 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10883-9"
+ d="m 566,299 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10921-8"
+ transform="translate(21,128)">
+ <path
+ id="path10895-8"
+ d="m 539.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10897-0"
+ d="m 535,359 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10899-8"
+ d="m 543,359 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 547.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path10901-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10914-7"
+ transform="translate(22,125)">
+ <path
+ id="path10903-8"
+ d="m 545,393 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10906-3"
+ d="m 549,393 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10908-8"
+ d="m 534,393 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10910-3"
+ d="m 541,393 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10912-7"
+ d="m 554,393 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10942-1"
+ transform="translate(22.01477,127)">
+ <path
+ id="path10928-0"
+ d="m 538,412 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10930-7"
+ d="m 534,412 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="412"
+ x="542"
+ height="5"
+ width="1"
+ id="rect10932-3"
+ 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" />
+ <path
+ id="path10934-4"
+ d="m 549,412 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10936-9"
+ d="m 553,412 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10938-6"
+ d="m 558,412 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10940-5"
+ d="m 544,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10966-1"
+ transform="translate(22.01477,127)">
+ <path
+ id="path10951-0"
+ d="m 534,434 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10953-9"
+ d="m 556,434 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10956-9"
+ d="m 552,434 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10958-6"
+ d="m 562,434 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10960-8"
+ d="m 543,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10962-3"
+ d="m 538,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 547,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path10964-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10980-8"
+ transform="translate(19,127)">
+ <rect
+ y="486"
+ x="542"
+ height="5"
+ width="1"
+ id="rect10975-4"
+ 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" />
+ <path
+ id="path10978-9"
+ d="m 537,486 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544,133 0,1 9,0 0,62 -9,0 0,1 9,0 1,0 0,-33 1,0 0,-1 -1,0 0,-30 -1,0 -9,0 z"
+ id="rect11044-9"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <a
+ style="display:inline;enable-background:new"
+ id="a28530-2">
+ <g
+ style="fill:#b3b3b3"
+ transform="translate(-3e-6,1)"
+ id="g11054-5">
+ <path
+ id="path19464-5"
+ d="m 1.75,13 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19466-3"
+ d="m 1,34 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 L 3,34 2,34 1,34 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19468-3"
+ d="m 2,55.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19470-3"
+ d="m 1,76 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 L 3,76 1,76 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19472-7"
+ d="m 1,98 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19474-4"
+ d="m 1,118 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19476-3"
+ d="m 2,139 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19478-8"
+ d="m 1,160 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#b3b3b3;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
+ y="182"
+ x="2"
+ height="5"
+ width="1"
+ id="rect19480-0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path19482-8"
+ d="m 3,202 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19484-8"
+ d="m 1,223 0,5 1,0 0,-1.75 1,0 0,-1.5 -1,0 0,-1.75 -1,0 z m 2,1.75 1,0 0,-1.75 -1,0 0,1.75 z m 0,1.5 0,1.75 1,0 0,-1.75 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19486-0"
+ d="m 1,244 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19488-6"
+ d="m 3e-6,265 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 0,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 0,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19490-8"
+ d="m 1,286 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19492-1"
+ d="m 2,307 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m -1,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19494-9"
+ d="m 1,328 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19496-8"
+ d="m 2,349 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -1,-1 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19498-9"
+ d="m 1,370 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19500-7"
+ d="m 2,391 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19502-2"
+ d="m 1,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19504-2"
+ d="m 1,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19506-8"
+ d="m 1,455 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path19508-2"
+ d="m 3e-6,475 0,3.25 1,0 0,1.75 1,0 0,-1.75 0.999997,0 0,1.75 1.000003,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 L 3,478 l 0,-2 -0.999997,0 0,2 -1,0 0,-3 -1,0 0,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1,497 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"
+ id="rect19510-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.750003,556 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38399-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.000003,577 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 0,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path38401-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 2.000003,598.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 0,0 z"
+ id="path38403-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.000003,619 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 0,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path38405-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38411-1"
+ d="m 1.750003,563 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path38413-5"
+ d="m 1.750003,584 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.750003,605 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38415-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38417-6"
+ d="m 1.750003,626 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path38419-1"
+ d="m 548.75,556 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path38421-2"
+ d="m 548,577 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path38423-4"
+ d="m 549,598.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ id="path38425-2"
+ d="m 548,619 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548.75,563 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38427-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548.75,584 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38429-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38431-6"
+ d="m 548.75,605 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548.75,626 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38433-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ </a>
+ <path
+ inkscape:connector-curvature="0"
+ id="path19537-6"
+ d="m 12,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19539-5"
+ d="m 33,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 L 35,2 33,2 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19541-3"
+ d="m 54,2 0,1 2,0 0,1 1,0 0,-1.25 -1,0 L 56,2 54,2 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 L 57,5 56,5 z"
+ style="fill:#b3b3b3;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="path19543-9"
+ d="m 75,2 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="fill:#b3b3b3;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="path19545-2"
+ d="m 96,2 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;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="path19547-4"
+ d="m 118,2 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19549-6"
+ d="m 138,2 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="fill:#b3b3b3;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="path19551-18"
+ d="m 159.75,2 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19553-2"
+ d="m 180.75,2 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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"
+ sodipodi:nodetypes="cccccccccccccccccc"
+ id="path19555-1"
+ d="m 202.75,2 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#b3b3b3;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="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 514,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path19559-1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 476,2 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ id="path19561-9" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 497,2 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ id="path19563-7" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518,2 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path19565-6" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19577-2"
+ d="m 200,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19579-9"
+ d="m 244,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19581-5"
+ d="m 265,2 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ style="fill:#b3b3b3;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="path19583-2"
+ d="m 286,2 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="fill:#b3b3b3;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="path19585-0"
+ d="m 307,2 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;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="path19587-0"
+ d="m 329,2 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19589-3"
+ d="m 349,2 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="fill:#b3b3b3;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="path19591-9"
+ d="m 370.75,2 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19593-1"
+ d="m 391.75,2 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19595-8"
+ d="m 413.75,2 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="fill:#b3b3b3;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="path19597-1"
+ d="m 221,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ id="path19599-9" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19601-5"
+ d="m 242,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19603-3"
+ d="m 263,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19605-2"
+ d="m 284,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19607-5"
+ d="m 305,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19609-2"
+ d="m 326,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19611-5"
+ d="m 347,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19613-8"
+ d="m 368,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19615-6"
+ d="m 389,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19617-7"
+ d="m 409,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19619-7"
+ d="m 435,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;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="path19621-2"
+ d="m 430,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19623-2"
+ d="m 451,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 455,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path19625-9" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19627-4"
+ d="m 472,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="path19629-1"
+ d="m 493,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="path11036-9"
+ d="m 536,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;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="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 541,2 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ id="path11038-6" />
+ <g
+ id="g11125-9"
+ transform="translate(547,1)"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ id="path11128-8"
+ d="m 1.75,13 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11130-2"
+ d="m 1,34 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 L 3,34 2,34 1,34 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11132-5"
+ d="m 2,55.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11134-5"
+ d="m 1,76 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 L 3,76 1,76 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11136-4"
+ d="m 1,98 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11138-9"
+ d="m 1,118 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11140-1"
+ d="m 2,139 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11142-2"
+ d="m 1,160 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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
+ y="182"
+ x="2"
+ height="5"
+ width="1"
+ id="rect11144-5"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11146-0"
+ d="m 3,202 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11148-8"
+ d="m 1,223 0,5 1,0 0,-1.75 1,0 0,-1.5 -1,0 0,-1.75 -1,0 z m 2,1.75 1,0 0,-1.75 -1,0 0,1.75 z m 0,1.5 0,1.75 1,0 0,-1.75 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11150-3"
+ d="m 1,244 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11152-9"
+ d="m 1,265 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11154-3"
+ d="m 1,286 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11156-9"
+ d="m 2,307 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m -1,0 0,-3 -1,0 0,3 1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11158-6"
+ d="m 1,328 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11160-7"
+ d="m 2,349 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -1,-1 0,-3 -1,0 0,3 1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11162-9"
+ d="m 1,370 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11164-9"
+ d="m 2,391 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11166-7"
+ d="m 1,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11168-6"
+ d="m 1,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11170-9"
+ d="m 1,455 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path11172-3"
+ d="m 3e-6,474.75 0,3.25 1,0 0,1.75 1,0 0,-1.75 L 3,478 l 0,1.75 1.000003,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1.000003,0 0,-2 -0.999997,0 0,2 -1,0 0,-3 -1,0 0,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1,497 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"
+ id="path11174-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path38393-7"
+ d="m 1,518 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path38395-6"
+ d="m 1,539 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"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548,518 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path38435-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548,539 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"
+ id="path38437-5"
+ inkscape:connector-curvature="0" />
+ <g
+ style="color:#000000;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="g41041-8"
+ transform="translate(0,634)">
+ <path
+ id="path41043-2"
+ d="m 12,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41045-5"
+ d="m 33,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 L 35,1 33,1 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41047-4"
+ d="m 54,1 0,1 2,0 0,1 1,0 0,-1.25 -1,0 L 56,1 54,1 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 L 57,4 56,4 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41049-4"
+ d="m 75,1 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41051-1"
+ d="m 96,1 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41053-6"
+ d="m 118,1 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41055-1"
+ d="m 138,1 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41057-6"
+ d="m 159.75,1 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41059-3"
+ d="m 180.75,1 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccc"
+ id="path41061-3"
+ d="m 202.75,1 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 514,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path41063-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 476,1 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ id="path41065-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 497,1 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ id="path41067-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518,1 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path41069-2"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41071-8"
+ d="m 200,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41073-2"
+ d="m 244,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41075-5"
+ d="m 265,1 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41077-3"
+ d="m 286,1 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41079-6"
+ d="m 307,1 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41081-1"
+ d="m 329,1 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41083-8"
+ d="m 349,1 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41085-6"
+ d="m 370.75,1 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41087-2"
+ d="m 391.75,1 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41089-1"
+ d="m 413.75,1 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41091-4"
+ d="m 221,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ id="path41093-6"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41095-2"
+ d="m 242,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41097-9"
+ d="m 263,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41099-1"
+ d="m 284,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41101-5"
+ d="m 305,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41103-0"
+ d="m 326,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41105-3"
+ d="m 347,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41107-6"
+ d="m 368,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41109-4"
+ d="m 389,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41111-9"
+ d="m 409,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41113-2"
+ d="m 435,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41116-9"
+ d="m 430,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41118-3"
+ d="m 451,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 455,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path41120-4"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41122-4"
+ d="m 472,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41124-0"
+ d="m 493,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ id="path41126-5"
+ d="m 536,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;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" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 541,1 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ id="path41128-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path30643-6"
+ d="m 585,617.25 1,0 0,0.75 3,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -3,0 0,0.75 -1,0 0,1.5 z m 1,-0.25 0,-1 3,0 0,1 -3,0 z m 1,-0.25 1,0 0,-0.5 -1,0 0,0.5 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path30647-3"
+ d="m 585,630 1,0 0,-2 1,0 0,1 1,0 0,-1 -0.75,0 0,-1 -1.5,0 0,1 -0.75,0 0,2 z m 3,-1 0,1 1,0 1,0 0,-3 -1,0 0,2 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path30649-4"
+ d="m 585,624 3,0 0,-1 0,-1 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 -1.5,0 0,1 -0.75,0 0,1 -1,0 0,-2 -1,0 0,2 0,1 z"
+ 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
+ y="589"
+ x="-626"
+ height="1"
+ width="1"
+ id="rect30651-2"
+ 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"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <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="rect30653-8"
+ width="1"
+ height="1"
+ x="-620"
+ y="589"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ y="589"
+ x="-634"
+ height="1"
+ width="1"
+ id="rect30725-87"
+ 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"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path30723-5"
+ d="m 587,638 2.25,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -2.25,0 0,1 2,0 0,1 -2,0 0,1 z"
+ 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"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ id="path30643-7-0"
+ d="m 903.75,209 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path30647-6-1"
+ d="m 891,209 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path30649-7-4"
+ d="m 897,209 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="213"
+ x="895"
+ height="1"
+ width="1"
+ id="rect30651-8-6"
+ 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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30653-7-0"
+ width="1"
+ height="1"
+ x="901"
+ y="213" />
+ <rect
+ y="213"
+ x="887"
+ height="1"
+ width="1"
+ id="rect30725-8-7"
+ 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" />
+ <path
+ id="path30723-1-1"
+ d="m 883,211 0,2.25 1,0 0,0.75 1,0 0,-0.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(810,316)"
+ id="g72798"
+ style="opacity:0.5;display:inline;enable-background:new">
+ <g
+ id="g72716">
+ <path
+ id="path72434"
+ d="m 186,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-127"
+ x="219"
+ height="5"
+ width="1"
+ id="rect72436"
+ 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" />
+ <path
+ id="path72438"
+ d="m 144,-127 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72440"
+ d="m 189,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72442"
+ d="m 165,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72446"
+ d="m 130,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72448"
+ d="m 154,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72450"
+ d="m 133,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72452"
+ d="m 138,-127 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72454"
+ d="m 151,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72456"
+ d="m 146,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 209,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path72458"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 160,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path72460" />
+ <path
+ id="path72462"
+ d="m 171,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72464"
+ d="m 175,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 179,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path72466" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 194,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path72468" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 202,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72470" />
+ <path
+ id="path72472"
+ d="m 205,-127 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path72474"
+ d="m 215,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 222,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72476" />
+ <path
+ id="path72478"
+ d="m 225,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 229,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path72480" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 235,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72482" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 238,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path72484" />
+ <path
+ id="path72486"
+ d="m 242.75,-123 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32008-7"
+ d="m 72,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32010-4"
+ d="m 76,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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
+ y="-127"
+ x="80"
+ height="5"
+ width="1"
+ id="rect32012-0"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32015-9"
+ d="m 83,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32017-4"
+ d="m 89,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32019-8"
+ d="m 97,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32021-8"
+ d="m 93,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32023-2"
+ d="m 102,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32026-4"
+ d="m 106,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 110,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path32029-5" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 115,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path32031-5" />
+ <rect
+ y="-127"
+ x="121"
+ height="5"
+ width="1"
+ id="rect32033-1"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 124,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path32035-7" />
+ </g>
+ <g
+ id="g72757">
+ <path
+ id="path72562"
+ d="m 78,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="82"
+ height="5"
+ width="1"
+ id="rect72564"
+ 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" />
+ <path
+ id="path72576"
+ d="m 72,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72578"
+ d="m 130,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72580"
+ d="m 94.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72582"
+ d="m 85,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 88,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path72588" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 99,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72590" />
+ <path
+ id="path72592"
+ d="m 103,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 107,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path72594" />
+ <path
+ id="path72596"
+ d="m 111,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 117,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path72598" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 121.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path72600" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 125,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path72602" />
+ <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="rect72604"
+ width="1"
+ height="5"
+ x="136"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 138,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path72606" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 144.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path72608" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path72610"
+ d="m 148,-119 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 153,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path72612" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 157,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path72614" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 163,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72616" />
+ <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="rect72618"
+ width="1"
+ height="5"
+ x="174"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 168,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ id="path72620" />
+ <path
+ id="path72622"
+ d="m 180,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72624"
+ d="m 176,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32207-9-7"
+ d="m 187,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32209-6-7"
+ d="m 191,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32211-3-7"
+ d="m 195,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32213-7-3"
+ d="m 199,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32216-8-3"
+ d="m 203,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32218-8-5"
+ width="1"
+ height="5"
+ x="207"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32220-2-9"
+ d="m 210,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32222-9-9"
+ d="m 213,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32224-1-8"
+ d="m 217,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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" />
+ <path
+ id="path72678"
+ d="m 225,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 235,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path72680"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="223"
+ height="5"
+ width="1"
+ id="rect72682"
+ 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
+ y="-115"
+ x="239"
+ height="1"
+ width="1"
+ id="rect72684"
+ 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" />
+ <path
+ id="path72686"
+ d="m 230,-119 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(810,316)"
+ style="display:inline;enable-background:new"
+ id="g72880">
+ <g
+ transform="translate(231,-90)"
+ id="g32242-4">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m -12.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32244-2" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m -9,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path32246-0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m -3,-17 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path32248-9" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 1,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32250-7" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 6,-17 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path32252-3" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 10,-17 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"
+ id="path32254-7" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m -43.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32256-2" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32258-6"
+ d="m -40,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32260-0"
+ d="m -35,-17 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m -31,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32262-1" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m -27,-17 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"
+ id="path32264-6" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32266-5"
+ d="m -23,-17 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32268-7"
+ d="m -17,-17 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ 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
+ y="-19"
+ x="11"
+ height="1"
+ width="1"
+ id="rect32270-5"
+ 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" />
+ </g>
+ <g
+ id="g21967-4"
+ transform="translate(111.96875,-88)">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 48,-20 0,0.75 -1,0 0,0.25 -0.25,0 0,1 -0.75,0 0,3 0.75,0 0,1 0.25,0 0,0.25 1,0 0,0.75 3,0 0,-0.75 1,0 0,-0.25 0.25,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -0.25,0 0,-0.25 -1,0 0,-0.75 -3,0 z m 0,1 3,0 0,1 1,0 0,3 -1,0 0,1 -3,0 0,-1 -1,0 0,-3 1,0 0,-1 z"
+ id="path32272-1"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32274-2"
+ d="m 49,-18 0,0.75 -1,0 0,1.5 1,0 0,0.75 1.25,0 0,-1 -1.25,0 0,-1 1.25,0 0,-1 -1.25,0 z"
+ 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"
+ sodipodi:nodetypes="ccccccccccccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 171.71875,-107 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ id="path72688" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 175.96875,-107 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ id="path72690" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 177.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path72692" />
+ <path
+ id="path72694"
+ d="m 166.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 182.96875,-106 0,1 1,0 0,-1 -1,0 z m -0.21875,3 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ id="path72696" />
+ </g>
+ <g
+ style="opacity:0.4;display:inline;enable-background:new"
+ id="g73280"
+ transform="matrix(0,-1,1,0,722,710)">
+ <g
+ id="g73282">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 186,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73284" />
+ <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="rect73286"
+ width="1"
+ height="5"
+ x="219"
+ y="-127" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 144,-127 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ id="path73288" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 189,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73290" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 165,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path73292" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 130,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path73294" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 154,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73296" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 133,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path73298" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 138,-127 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path73300" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 151,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73302" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 146,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73304" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path73306"
+ d="m 209,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ 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" />
+ <path
+ id="path73308"
+ d="m 160,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 171,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73310" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 175,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73312" />
+ <path
+ id="path73314"
+ d="m 179,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73316"
+ d="m 194,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73318"
+ d="m 202,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 205,-127 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73320" />
+ <path
+ 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"
+ d="m 215,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path73322"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73324"
+ d="m 222,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 225,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73326" />
+ <path
+ id="path73328"
+ d="m 229,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73330"
+ d="m 235,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73332"
+ d="m 238,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 242.75,-123 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ id="path73334" />
+ <path
+ 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"
+ d="m 72,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73336"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 76,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73338"
+ inkscape:connector-curvature="0" />
+ <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="rect73340"
+ width="1"
+ height="5"
+ x="80"
+ y="-127" />
+ <path
+ 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"
+ d="m 83,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path73342"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 89,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73344"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 97,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73346"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 93,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path73348"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 102,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73350"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 106,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73352"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73354"
+ d="m 110,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73356"
+ d="m 115,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <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="rect73358"
+ width="1"
+ height="5"
+ x="121"
+ y="-127" />
+ <path
+ id="path73360"
+ d="m 124,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g73362"
+ transform="translate(175,-8)">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 78,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73364" />
+ <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="rect73366"
+ width="1"
+ height="5"
+ x="82"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 72,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ id="path73368" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 130,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73370" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 94.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73372" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 85,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73374" />
+ <path
+ id="path73376"
+ d="m 88,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73378"
+ d="m 99,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 103,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73380" />
+ <path
+ id="path73382"
+ d="m 107,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 111,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path73384" />
+ <path
+ id="path73386"
+ d="m 117,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73388"
+ d="m 121.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73390"
+ d="m 125,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="136"
+ height="5"
+ width="1"
+ id="rect73392"
+ 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" />
+ <path
+ id="path73394"
+ d="m 138,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73396"
+ d="m 144.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 148,-119 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path73398"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73400"
+ d="m 153,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73402"
+ d="m 157,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73404"
+ d="m 163,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="174"
+ height="5"
+ width="1"
+ id="rect73406"
+ 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" />
+ <path
+ id="path73408"
+ d="m 168,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 180,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73410" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 176,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73412" />
+ <path
+ 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"
+ d="m 187,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73414"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 191,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path73416"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 195,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73418"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 199,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73420"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 203,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73422"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="207"
+ height="5"
+ width="1"
+ id="rect73424"
+ 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" />
+ <path
+ 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"
+ d="m 210,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73426"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 213,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73428"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 217,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73430"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 225,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73432" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path73434"
+ d="m 235,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73436"
+ width="1"
+ height="5"
+ x="223"
+ y="-119" />
+ <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="rect73438"
+ width="1"
+ height="1"
+ x="239"
+ y="-115" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 230,-119 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73440" />
+ </g>
+ </g>
+ <g
+ id="g73442"
+ style="display:inline;enable-background:new"
+ transform="matrix(0,-1,1,0,692,540.96875)">
+ <g
+ id="g73444"
+ transform="translate(231,-90)">
+ <path
+ id="path73446"
+ d="m -12.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73448"
+ d="m -9,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73450"
+ d="m -3,-17 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73452"
+ d="m 1,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73454"
+ d="m 6,-17 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73456"
+ d="m 10,-17 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"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73458"
+ d="m -43.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m -40,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73460"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m -35,-17 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path73462"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73464"
+ d="m -31,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73466"
+ d="m -27,-17 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"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m -23,-17 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73468"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m -17,-17 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ id="path73470"
+ inkscape:connector-curvature="0" />
+ <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="rect73472"
+ width="1"
+ height="1"
+ x="11"
+ y="-19" />
+ </g>
+ <g
+ transform="translate(111.96875,-88)"
+ id="g73474">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccc"
+ id="path73476"
+ d="m 48,-20 0,0.75 -1,0 0,0.25 -0.25,0 0,1 -0.75,0 0,3 0.75,0 0,1 0.25,0 0,0.25 1,0 0,0.75 3,0 0,-0.75 1,0 0,-0.25 0.25,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -0.25,0 0,-0.25 -1,0 0,-0.75 -3,0 z m 0,1 3,0 0,1 1,0 0,3 -1,0 0,1 -3,0 0,-1 -1,0 0,-3 1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ 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"
+ d="m 49,-18 0,0.75 -1,0 0,1.5 1,0 0,0.75 1.25,0 0,-1 -1.25,0 0,-1 1.25,0 0,-1 -1.25,0 z"
+ id="path73478"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path73480"
+ d="m 171.71875,-107 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73482"
+ d="m 175.96875,-107 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73484"
+ d="m 177.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 166.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path73486" />
+ <path
+ id="path73488"
+ d="m 182.96875,-106 0,1 1,0 0,-1 -1,0 z m -0.21875,3 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 545,238 0,1 9,0 0,41 -9,0 0,1 9,0 1,0 0,-21 1,0 0,-1 -1,0 0,-21 -1,0 z"
+ id="rect11044-9-4"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ inkscape:label="ICONS"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline">
+ <g
+ transform="matrix(0,1,1,0,-174,194)"
+ style="display:inline;enable-background:new"
+ id="g106468-0">
+ <g
+ 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.9535916,0,0,1.1712921,1176.1968,319.2322)"
+ id="g29877-5-3-1-8"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path29879-5-0-9-1"
+ d="m 392.96689,241.84215 -0.56915,0 -3.5287,2.84782 0,1.13912 3.5287,2.84781 0.56915,0 0,-6.83475 0,0 0,0 z"
+ style="color:#000000;fill:url(#radialGradient106344-5-2);fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient106433-4);stroke-width:0.66107476px;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
+ sodipodi:nodetypes="cccc"
+ id="path29881-5-6-0-4"
+ d="m 392.96688,248.67221 -0.57173,0 -3.51515,-2.83619 -0.008,-1.21916"
+ style="fill:none;stroke:url(#linearGradient106307-2-4);stroke-width:0.66107482px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="598"
+ x="404"
+ height="16"
+ width="16"
+ id="rect24491-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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ inkscape:export-ydpi="90"
+ 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">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ id="g14715"
+ transform="translate(-320.42789,5.4177849)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14717"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g14719">
+ <g
+ transform="translate(480,287.5)"
+ id="g14721"
+ 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
+ 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"
+ transform="translate(-118.5,-200.5)"
+ id="g14723" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g14725" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14727"
+ width="16"
+ height="16"
+ x="68.572113"
+ y="294.41779"
+ rx="0"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient14800);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 72.738774,294.91779 10.33334,0 0,14.99999 -13,0 -1e-5,-11.99999 2.66667,-3 z"
+ id="path14729"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path14731"
+ style="fill:none;stroke:url(#linearGradient14802);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 71.072114,299.41778 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path14733"
+ d="m 69.572114,298.41778 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:0.75490196;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path14735"
+ 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 70.072114,297.41779 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ clip-path="url(#clipPath22590-7)"
+ mask="none"
+ transform="translate(100.57211,-194.58234)"
+ id="g14737"
+ style="display:inline"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <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="rect14739"
+ width="16"
+ height="16"
+ x="-29"
+ y="491.00012" />
+ <g
+ id="g14741">
+ <g
+ id="g14743">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ 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:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ 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"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path14747"
+ style="fill:none;stroke:#000000;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path14749"
+ 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:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -8.5,5.00012 3.5,-3.5"
+ sodipodi:nodetypes="cccc" />
+ </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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path14751"
+ style="fill:none;stroke:url(#linearGradient14804);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -26.5,501.50012 -21.5,496.5 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient14806);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14753" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path14755"
+ sodipodi:cx="13.5"
+ 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"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path14757"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient14808);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14759"
+ sodipodi:cx="13.5"
+ 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"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -6.734366,7.94478 3.280183,-3.10926 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient14810);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path14761" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient20368);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 74.072114,296.91778 0,2 -2,0"
+ id="path14763"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ 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"
+ 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="rect18813"
+ width="16"
+ height="16"
+ x="257"
+ y="176" />
+ <g
+ transform="translate(254.01612,148.99638)"
+ id="g10120"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="czc"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 4.4999991,39.491912 c 4.0000009,0 3.4999969,-7 5.9999989,-7 2.500002,0 2.000002,7 5.999999,7"
+ id="path10122"
+ 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="path10124"
+ d="m 4.4999991,39.491912 c 4.0000009,0 3.4999969,-7 5.9999989,-7 2.500002,0 2.000002,7 5.999999,7"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="czc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g20291"
+ 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="rect18821"
+ width="16"
+ height="16"
+ x="341"
+ y="176" />
+ <g
+ transform="translate(258.01612,148.99638)"
+ id="g10158"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#000000;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 85.500006,38.5 90.478251,33.099997 95.456495,38.5"
+ id="path10160"
+ 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="path10162"
+ d="M 85.500006,38.5 90.478251,33.099997 95.456495,38.5"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.5;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>
+ </g>
+ <g
+ id="g20301"
+ transform="translate(0,2)">
+ <rect
+ y="176"
+ x="320"
+ height="16"
+ width="16"
+ id="rect18819"
+ 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(257.01612,148.99638)"
+ id="g10164"
+ style="display:inline">
+ <path
+ id="path10166"
+ d="M 65.500015,38.5 C 68.5,37 70,35 70.560871,31.5 71,35 72.5,37 75.621727,38.5"
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="ccc"
+ 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"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#e6e6e6;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 65.500015,38.5 C 68.5,37 70,35 70.560871,31.5 71,35 72.5,37 75.621727,38.5"
+ id="path10168"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g20337"
+ transform="translate(0,2)">
+ <rect
+ y="176"
+ x="278"
+ height="16"
+ width="16"
+ id="rect18815"
+ 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(255.01612,148.99638)"
+ id="g10170"
+ style="display:inline">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;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="path10172"
+ sodipodi:cx="30.5"
+ 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"
+ sodipodi:start="0"
+ sodipodi:end="3.1415927"
+ 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"
+ transform="matrix(1,0,0,-1,0,78.5)" />
+ <path
+ transform="matrix(1,0,0,-1,0,78.5)"
+ 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"
+ 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"
+ sodipodi:ry="6"
+ sodipodi:rx="6"
+ sodipodi:cy="40"
+ sodipodi:cx="30.5"
+ id="path10174"
+ style="fill:none;stroke:#e6e6e6;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"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g20311"
+ 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="rect18817"
+ width="16"
+ height="16"
+ x="299"
+ y="176" />
+ <g
+ transform="translate(256.01612,148.99638)"
+ id="g10176"
+ style="display:inline">
+ <path
+ 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"
+ sodipodi:ry="6"
+ sodipodi:rx="6"
+ sodipodi:cy="40"
+ sodipodi:cx="30.5"
+ id="path10178"
+ style="fill:none;stroke:#000000;stroke-width:2.65631413;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: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"
+ transform="matrix(0.833333,0,0,-1.333333,25.08333,92.82524)" />
+ <path
+ transform="matrix(0.833333,0,0,-1.333333,25.08333,92.82524)"
+ 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:#e6e6e6;stroke-width:1.32815707;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="path10181"
+ sodipodi:cx="30.5"
+ 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"
+ sodipodi:start="0"
+ sodipodi:end="3.1415927"
+ sodipodi:open="true" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g18862"
+ transform="translate(259,151)">
+ <rect
+ y="28"
+ x="103"
+ height="16"
+ width="16"
+ id="rect18823"
+ 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.01612368,-0.00361762)"
+ id="g10183"
+ style="display:inline">
+ <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="path10185"
+ d="m 104.5,37.503635 0,-4.000017 12,0 0,4"
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#d7d7d7;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 104.5,37.503635 0,-4.000017 12,0 0,4"
+ id="path10187"
+ 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>
+ </g>
+ <g
+ style="display:inline"
+ id="g18856"
+ 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"
+ id="rect18825"
+ width="16"
+ height="16"
+ x="123"
+ y="28" />
+ <g
+ transform="translate(0.01612368,-0.00361762)"
+ id="g10189"
+ style="display:inline">
+ <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="cssssc"
+ style="fill:none;stroke:#000000;stroke-width:2.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 124.5,39.491912 c 0.99099,0 0.85013,-1.626312 1.08378,-2.386485 0.35579,-1.15753 1.07105,-1.19962 1.4919,-0.197292 1.2357,2.943014 1.5163,-5.054472 2.42432,-6.416223 1.00014,-1.499896 0.90687,8.170836 3,4 1.95704,-3.899658 1.50039,4.999088 4,5"
+ id="path10191"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10193"
+ d="m 124.5,39.491912 c 0.99099,0 0.85013,-1.626312 1.08378,-2.386485 0.35579,-1.15753 1.07105,-1.19962 1.4919,-0.197292 1.2357,2.943014 1.5163,-5.054472 2.42432,-6.416223 1.00014,-1.499896 0.90687,8.170836 3,4 1.95704,-3.899658 1.50039,4.999088 4,5"
+ style="fill:none;stroke:#e6e6e6;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"
+ sodipodi:nodetypes="cssssc"
+ 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>
+ </g>
+ <g
+ id="g33683"
+ transform="translate(0,2)">
+ <rect
+ y="176"
+ x="446"
+ height="16"
+ width="16"
+ id="rect18831"
+ 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(263.91329,149.04559)"
+ id="g11360"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient37097);fill-opacity:1;fill-rule:nonzero;stroke:#11243e;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 190.07108,29.454411 c -3.02619,0 -5.48439,2.463313 -5.48438,5.5 0,3.036688 2.45819,5.500001 5.48438,5.5 3.02619,0 5.48437,-2.46331 5.48437,-5.5 0,-3.036689 -2.45818,-5.500001 -5.48437,-5.5 z m 0,2.98305 c 1.36546,0 2.53849,1.100464 2.53848,2.454803 0,1.354341 -1.17303,2.501413 -2.53848,2.501412 -1.36546,0 -2.47581,-1.14707 -2.47581,-2.501412 0,-1.354341 1.11035,-2.454805 2.47581,-2.454803 z"
+ id="path11362"
+ 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="csssccsssc" />
+ <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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path11364"
+ style="fill:none;stroke:url(#linearGradient15782);stroke-width:1.77120221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.566689,0,0,-0.562497,115.2063,101.3747)" />
+ <path
+ transform="matrix(0.4330916,0,0,-0.424074,132.95389,85.01929)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33681);stroke-width:2.33340454;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path11366"
+ 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\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"
+ 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="rect18829"
+ width="16"
+ height="16"
+ x="425"
+ y="176" />
+ <g
+ transform="translate(263,148.99995)"
+ id="g11368"
+ style="display:inline">
+ <g
+ id="g11370"
+ 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.786268,0,0,0.7877987,82.392071,-41.848894)">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37095);fill-opacity:1;fill-rule:nonzero;stroke:#11243e;stroke-width:1.16319752;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="path11372"
+ 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.874026,0,0,0.873701,-3.948211,-5.552958)" />
+ <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="path11374"
+ style="fill:none;stroke:url(#linearGradient33700);stroke-width:3.20095801;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.398744,0,0,-0.395524,58.82401,144.1804)" />
+ </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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path11376"
+ style="fill:none;stroke:url(#linearGradient33666);stroke-width:5.31599474;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.186538,0,0,-0.189699,145.3693,57.36304)" />
+ <path
+ transform="matrix(0.566689,0,0,-0.562497,95.23056,101.3747)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33668);stroke-width:1.77120221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path11378"
+ 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\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.424906,0,0,-0.424074,114.01316,85.183325)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33670);stroke-width:2.35577321;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path11380"
+ 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\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"
+ 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"
+ id="rect17412"
+ width="16.000002"
+ height="16"
+ x="5"
+ y="302" />
+ <g
+ transform="translate(-316.99999,374)"
+ id="g19609"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cccccc"
+ 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="path17384"
+ style="fill:none;stroke:#2c1700;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 330.02726,-62.5 4.63639,3 m -4.63639,-3 -4.63634,3 m 4.60909,-3 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ 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:#2c1700;stroke-width:1.80000007;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 329,-70 0,2 1.99999,0 0,-2 L 329,-70 z m -5,10 10e-6,2 2,0 -10e-6,-2 -2,0 z m 9.99999,0 0,2 2,0 0,-2 -2,0 z"
+ id="path17386"
+ 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"
+ 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"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path17388"
+ style="fill:url(#radialGradient12427);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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"
+ sodipodi:nodetypes="cccc"
+ d="m 330.02726,-62.5 4.63639,3"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffddb9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17390"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 330.02724,-62.5 4.63639,3 m -4.63639,-3 -4.63634,3 m 4.60909,-3 0,-6"
+ style="opacity:0.8;fill:none;stroke:url(#radialGradient12429);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17392"
+ 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="cccccc"
+ 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"
+ sodipodi:nodetypes="ccccc"
+ id="path17394"
+ d="m 333.99999,-60 0,2 2,0 0,-2 -2,0 z"
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;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"
+ sodipodi:nodetypes="cccc"
+ id="path17396"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#be6200;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 330.02726,-62.5 -4.63634,3"
+ 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"
+ sodipodi:nodetypes="cc"
+ id="path17398"
+ style="fill:none;stroke:#ff921d;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 330.00001,-62.5 0,-6"
+ 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"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 329,-70 0,2 1.99999,0 0,-2 L 329,-70 z"
+ id="path17400"
+ 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"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e07400;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 324.00001,-60 0,2 1.99999,0 0,-2 -1.99999,0 z"
+ id="path17402"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-63.75"
+ x="328.25"
+ height="3.5"
+ width="3.5000002"
+ id="rect17404"
+ style="opacity:0.05;fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path17406"
+ d="m 324.49999,-58.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1.00000083px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ 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:#ffe680;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000107px;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 329.49999,-68.5 0,-0.967392 0.99998,0"
+ id="path17408"
+ sodipodi:nodetypes="ccc"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path17410"
+ d="m 334.5,-58.499999 0,-1 1,0"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000107px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 334,-60.5 -3,-1.870665"
+ id="path17415"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#784e21;stroke-width:1.00000036px;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 333.5,-59.499999 0,-1 1,0"
+ id="path17417"
+ sodipodi:nodetypes="ccc"
+ 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
+ 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="cc"
+ id="path17419"
+ d="m 329.49999,-67.5 1,0"
+ style="opacity:0.4;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#8c5b27;stroke-width:1.00000107px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path17421"
+ d="m 326.49995,-59.500011 0,-1 -1,0"
+ style="opacity:0.4;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#8c5b27;stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.27999998;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 326,-60.5 3,-1.870665"
+ id="path17423"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17425"
+ d="m 329.5,-67.5 0,4"
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-63"
+ x="329.06403"
+ height="2"
+ width="2"
+ id="rect17427"
+ style="fill:#fff1d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24997"
+ transform="translate(0,128)">
+ <rect
+ ry="0"
+ rx="0"
+ y="302"
+ x="47"
+ height="16"
+ width="16"
+ id="rect17065"
+ 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="g24983">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="313.5"
+ x="49.5"
+ height="3"
+ width="2.9998772"
+ id="rect17067"
+ 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="rect17069"
+ width="2.9998772"
+ height="3"
+ x="52.500122"
+ y="303.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path17071"
+ d="m 51,315 c 4.5365,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:#2b1600;stroke-width:3.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"
+ inkscape:connector-curvature="0" />
+ <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 51,315 c 4.49647,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path17073"
+ sodipodi:nodetypes="csc"
+ 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"
+ 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\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path17075"
+ d="m 51,315 c 4.49647,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:url(#linearGradient24436);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"
+ 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="path17077"
+ d="m 51.999878,314 c -0.67541,0 -1.35081,10e-6 -2.02623,10e-6 0,0.66939 0,1.33877 0,2.00817 0.67542,0 1.35082,-10e-6 2.02623,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffca91;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="fill:#ffad55;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 55,304 c -0.65334,0 -1.30668,10e-6 -1.96003,10e-6 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-10e-6 1.96003,-10e-6 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path17081"
+ 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.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 53.5,305.5 0,-1 1,0"
+ id="path17083"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17085"
+ d="m 50.473648,315.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ 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="path17087"
+ d="m 53,315.66293 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.55431 0,-1.1086 0,-1.66292 0.32001,0 0.64002,10e-6 0.96003,10e-6 0,0.55431 0,1.10861 0,1.66292 z"
+ style="opacity:0.25;fill:#783e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path17089"
+ d="m 56,306.51208 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.63982 0,-1.27964 0,-1.91948 0.32001,0 0.64002,1e-5 0.96003,1e-5 0,0.63983 0,1.27966 0,1.91948 z"
+ style="opacity:0.15;fill:#783e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#783e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 53,316 c -0.32001,0 -0.64002,0 -0.96003,0 0,-0.21055 0,-0.42107 0,-0.63162 0.32001,0 0.64002,0 0.96003,0 0,0.21055 0,0.42107 0,0.63162 z"
+ id="path17091"
+ 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>
+ </g>
+ <g
+ id="g10687"
+ 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"
+ id="rect17348"
+ width="16"
+ height="16"
+ x="47"
+ y="281"
+ rx="0"
+ ry="0" />
+ <g
+ id="g10677">
+ <g
+ id="g18285"
+ style="opacity:0.7;display:inline"
+ transform="translate(-290.00001,409.99343)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path18233"
+ d="m 341.00001,-115.99343 c 4.5365,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:#1a1a1a;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;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 341.00001,-115.99343 c 4.49647,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path18235"
+ sodipodi:nodetypes="csc"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g17345"
+ transform="translate(-189.02763,408)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-115.5"
+ x="238.52776"
+ height="3"
+ width="2.9998772"
+ id="rect17355"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path17358"
+ d="m 241.02763,-115 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;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" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect17360"
+ width="2.9998772"
+ height="3"
+ x="241.52776"
+ y="-125.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;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 244.02763,-125 c -0.65334,0 -1.30668,1e-5 -1.96003,1e-5 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-1e-5 1.96003,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path17362"
+ 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>
+ </g>
+ </g>
+ <g
+ id="g21376"
+ 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="rect21362"
+ width="16"
+ height="16"
+ x="131"
+ y="71" />
+ <g
+ transform="translate(-71,-61)"
+ id="g9875"
+ style="display:inline">
+ <g
+ id="g9889"
+ transform="translate(0,1.00001)">
+ <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="path9891"
+ d="m 210,135.5 6.5,0 0,11 -9,0 0,-8.5 2.5,-2.5 z"
+ style="fill:url(#linearGradient21370);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient21372);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ sodipodi:nodetypes="ccc"
+ id="path9893"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path9895"
+ d="m 207,138.99999 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ 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 207.5,138 0,8.5 9,0 0,-11 -6.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="path9897"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path9899"
+ style="fill:none;stroke:url(#linearGradient21374);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 208.5,139.49999 0,6.00001 m 3,-9.00001 4,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g9877"
+ transform="translate(-4,-3)"
+ style="opacity:0.4">
+ <path
+ style="fill:url(#linearGradient21364);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient21366);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ d="m 210,135.5 6.5,0 0,11 -9,0 0,-8.5 2.5,-2.5 z"
+ id="path9879"
+ 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
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path9881"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 207,138.99999 4,0 0,-4 -4,4 z"
+ id="path9883"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path9885"
+ 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 207.5,138 0,8.5 9,0 0,-11 -6.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"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 208.5,139.49999 0,6.00001 m 3,-9.00001 4,0"
+ style="fill:none;stroke:url(#linearGradient21368);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path9887"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g10203"
+ transform="translate(-211.20006,170)" />
+ <g
+ id="g21567"
+ transform="translate(-0.9687515,1.9789998)">
+ <g
+ transform="matrix(1.0019536,0,0,1,-173.76637,169.95095)"
+ id="g10199"
+ style="stroke:none">
+ <rect
+ y="6.0700502"
+ x="325.10001"
+ height="15.979"
+ width="16.000004"
+ id="rect10201"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="g21550">
+ <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="path10205"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667691;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.5769158,0,0,0.5769218,86.73182,118.78861)" />
+ <g
+ 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"
+ transform="matrix(0.769221,0,0,0.769229,59.2704,9.1909)"
+ id="g10207"
+ style="display:inline">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10209"
+ 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
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)"
+ 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="path10211"
+ style="opacity:0.4;fill:url(#linearGradient21641);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ 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="g10213"
+ transform="translate(-215.99994,222.97281)"
+ style="display:inline">
+ <rect
+ style="opacity:0.1;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;display:inline"
+ id="rect10215"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.495766"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="40.991806"
+ x="372.99994"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect10217"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10219"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.49577"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ <g
+ style="display:inline"
+ id="g10221"
+ transform="matrix(0.769221,0,0,0.769229,64.0398,14.9217)"
+ 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: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="path10224"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.91227174;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7125226,0,0,0.7125021,34.447023,139.42475)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient21643);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10226"
+ 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.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ </g>
+ <g
+ 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="display:inline"
+ transform="translate(-211.00001,228.97281)"
+ id="g10228">
+ <rect
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="-43.495766"
+ x="372.49994"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect10230"
+ style="opacity:0.1;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;display:inline" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect10232"
+ width="2.0000861"
+ height="2.0000756"
+ x="372.99994"
+ y="40.991806"
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)" />
+ <rect
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="-43.49577"
+ x="372.49994"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect10234"
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g21647"
+ 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"
+ id="rect21645"
+ width="16"
+ height="16"
+ x="173"
+ y="176" />
+ <g
+ transform="translate(-209.00002,169.98079)"
+ id="g10236"
+ 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
+ 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"
+ transform="matrix(0.769221,0,0,0.769229,289.2704,-160.7881)"
+ id="g10238"
+ style="display:inline">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10240"
+ 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
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)"
+ 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="path10242"
+ style="opacity:0.4;fill:url(#linearGradient15590);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ style="display:inline"
+ id="g10244"
+ transform="matrix(0.769221,0,0,0.769229,294.0398,-155.0573)"
+ 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: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="path10246"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient15592);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10248"
+ 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.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ </g>
+ <g
+ 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="g10250"
+ transform="translate(16.000061,55.993807)"
+ style="display:inline">
+ <rect
+ style="opacity:0.25;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;display:inline"
+ id="rect10252"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.495766"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="40.991806"
+ x="372.99994"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect10254"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10256"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.49577"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g21623"
+ transform="translate(-0.9999786,1.9982099)">
+ <g
+ transform="matrix(0.9999986,0,0,1,-170.19957,169.98079)"
+ id="g10260">
+ <g
+ transform="translate(39.10005,-0.04905017)"
+ id="g10262">
+ <rect
+ y="6.0700502"
+ x="325.10001"
+ height="15.979"
+ width="16.000025"
+ id="rect10264"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="g10266" />
+ </g>
+ <g
+ id="g21602">
+ <path
+ transform="matrix(0.5769158,0,0,0.5769218,128.71244,118.78864)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667691;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path10268"
+ 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" />
+ <g
+ style="opacity:0.45;display:inline"
+ id="g10270"
+ transform="matrix(0.769221,0,0,0.769229,101.2704,9.19269)"
+ 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">
+ <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="path10272"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient15594);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10275"
+ 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.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.769221,0,0,0.769229,106.0398,14.92349)"
+ id="g10277"
+ style="display:inline">
+ <path
+ transform="matrix(0.7119136,0,0,0.7119136,34.527408,139.4942)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.91303903;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="path10279"
+ 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
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.28576)"
+ 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="path10281"
+ style="opacity:0.4;fill:url(#linearGradient15596);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <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"
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="179.47975"
+ x="198.49991"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect10283"
+ style="opacity:0.05;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#6a6a6a;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline" />
+ <rect
+ style="opacity:0.1;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;display:inline"
+ id="rect10285"
+ width="3.0000761"
+ height="2.9999874"
+ x="203.49991"
+ y="185.47972"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="-187.9819"
+ x="203.99991"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect10287"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10289"
+ width="3.0000761"
+ height="2.9999874"
+ x="203.49991"
+ y="185.47972"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ </g>
+ <g
+ id="g21519"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect10293"
+ width="16"
+ height="16"
+ x="131"
+ y="176" />
+ <g
+ transform="translate(0.8812553,-0.8570429)"
+ id="g21511">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 142.1,184.4 2.5,0 m -9.5,0 -2.5,0 m 6,-3.5 0,-2.5 m 0,9.5 0,2.5"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path10295"
+ 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"
+ 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"
+ sodipodi:ry="9.0860729"
+ sodipodi:rx="9.0863705"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10297"
+ style="fill:none;stroke:#000000;stroke-width:8.3510685;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.383132,0,0,0.383237,88.0266,139.17807)" />
+ <path
+ id="path10299"
+ style="fill:none;stroke:url(#radialGradient21517);stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 142.1,184.4 2.5,0 m -9.5,0 -2.5,0 m 6,-3.5 0,-2.5 m 0,9.5 0,2.5"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.383132,0,0,0.383237,88.0266,139.17807)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#ffffff;stroke-width:4.69747591;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10301"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ 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="rect22465"
+ width="16"
+ height="16"
+ x="425"
+ y="113" />
+ <g
+ id="g14791"
+ transform="translate(-38,43.987183)"
+ style="display:inline">
+ <rect
+ style="fill:#f09432;fill-opacity:1;fill-rule:nonzero;stroke:#462400;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14793"
+ width="4.0018005"
+ height="3.9871812"
+ x="468.5"
+ y="74.512817"
+ rx="1.4768832"
+ ry="1.4768832" />
+ <rect
+ y="75.5"
+ x="469.5018"
+ height="2.012816"
+ width="1.9981995"
+ id="rect14795"
+ style="fill:none;stroke:url(#linearGradient14841);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.49075836"
+ rx="0.49075836" />
+ </g>
+ </g>
+ <g
+ id="g11718"
+ transform="translate(0,2)">
+ <rect
+ y="113"
+ x="404"
+ height="16"
+ width="16"
+ id="rect22463"
+ 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="g14927"
+ transform="translate(-39,43.987183)"
+ style="opacity:0.9;display:inline">
+ <rect
+ ry="1.5045315"
+ rx="1.5045315"
+ y="74.512817"
+ x="448.5"
+ height="3.9871812"
+ width="4.0018005"
+ id="rect14929"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient14935);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14931"
+ width="1.9981995"
+ height="2.012816"
+ x="449.5018"
+ y="75.5"
+ rx="0.5299269"
+ ry="0.5299269" />
+ </g>
+ </g>
+ <g
+ id="g11764"
+ transform="translate(0,2)">
+ <rect
+ y="113"
+ x="341"
+ height="16"
+ width="16"
+ id="rect22331"
+ 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(-81,-103)"
+ id="g22313"
+ style="display:inline">
+ <g
+ id="g22243">
+ <g
+ transform="translate(-0.9546587,1e-5)"
+ id="g18888"
+ style="opacity:0.85">
+ <path
+ sodipodi:nodetypes="cssc"
+ d="m 430.45466,223.24999 c -2.76033,0 -5,1.88345 -5,3.25 0,1.5 2.5,3 5.5,3 0.15891,0 4,0.25 6,-2.5"
+ style="fill:none;stroke:url(#linearGradient18896);stroke-width:3.29999995;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="path18757"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18762"
+ style="fill:none;stroke:url(#linearGradient18898);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;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 434.20466,226.49999 3.25115,2e-5 -10e-4,2.99998"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 433.25,226.5 3.25,0 0,2.99999"
+ style="fill:none;stroke:url(#linearGradient18904);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;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="path18764"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18766"
+ style="fill:none;stroke:url(#linearGradient18901);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;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 429.5,223.25 c -2.76033,0 -5,1.88345 -5,3.25 0,1.5 2.5,3 5.5,3 0,0 4,0.25 6,-2.5"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(278.02661,459.99999)"
+ id="g18768">
+ <path
+ id="path18770"
+ d="m 151,-240.5 c -2.48519,0 -4.49999,0.89481 -4.5,2 l 0,1 c 0,1.10519 2.0148,2 4.5,2 2.48519,0 4.5,-0.8948 4.5,-2 l 0,-1 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ style="fill:url(#linearGradient18843);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.68242937;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient18845);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151.00029,-243.51106 c -1.9309,0 -3.5,0.66961 -3.5,1.5 L 147.5,-240 c 0,0.83039 1.5691,1.5 3.5,1.5 1.9309,0 3.5,-0.66961 3.5,-1.5 l 2.9e-4,-2.01106 c 0,-0.83039 -1.5691,-1.5 -3.5,-1.5 z"
+ id="path18779"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18848);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 148.5,-241.75 0,2.70352 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875 l 0,-2.70352"
+ id="path18787"
+ sodipodi:nodetypes="ccssscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient18850);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18789"
+ sodipodi:cx="108"
+ 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"
+ transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)" />
+ <path
+ sodipodi:nodetypes="cssss"
+ id="path18791"
+ d="m 154.5,-239 c 0,0.18405 -0.0775,0.36038 -0.21919,0.52335 -0.49587,0.57019 -1.77826,0.97665 -3.28081,0.97665 -1.48659,0 -2.75767,-0.39787 -3.26474,-0.95854 C 147.58334,-238.62651 147.5,-238.80911 147.5,-239"
+ style="fill:none;stroke:url(#linearGradient18852);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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18798"
+ d="m 151,-243.5 c -1.9309,1e-5 -3.52661,0.41962 -3.52661,1.25001 L 147.5,-239.75 c -0.61542,0.34205 -1,0.77768 -1,1.25 l -0.0266,1.25001 c 0,1.10519 2.04141,1.74999 4.52661,1.74999 2.48519,0 4.47339,-0.64479 4.47339,-1.74999 L 155.5,-238.5 c 0,-0.47232 -0.38458,-0.90795 -1,-1.25 l -0.0266,-2.49999 c 0,-0.83038 -1.54249,-1.25001 -3.47339,-1.25001 l -1e-5,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.60000002;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="cccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path18800"
+ d="m 148.5,-239.04648 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875"
+ style="fill:none;stroke:#0066ff;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g11730"
+ transform="translate(0,2)">
+ <rect
+ y="113"
+ x="383"
+ height="16"
+ width="16"
+ id="rect22455"
+ 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(-79,-103)"
+ id="g22283"
+ style="display:inline">
+ <g
+ transform="translate(318.02661,459.99999)"
+ id="g17510">
+ <path
+ id="path17512"
+ d="m 151,-240.5 c -2.48519,0 -4.49999,0.89481 -4.5,2 l 0,1 c 0,1.10519 2.0148,2 4.5,2 2.48519,0 4.5,-0.8948 4.5,-2 l 0,-1 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ style="fill:url(#linearGradient17527);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.68242937;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient17529);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151.00029,-243.51106 c -1.9309,0 -3.5,0.66961 -3.5,1.5 L 147.5,-240 c 0,0.83039 1.5691,1.5 3.5,1.5 1.9309,0 3.5,-0.66961 3.5,-1.5 l 2.9e-4,-2.01106 c 0,-0.83039 -1.5691,-1.5 -3.5,-1.5 z"
+ id="path17514"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17531);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 148.5,-241.75 0,2.70352 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875 l 0,-2.70352"
+ id="path17516"
+ sodipodi:nodetypes="ccssscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient17533);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17518"
+ sodipodi:cx="108"
+ 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"
+ transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)" />
+ <path
+ sodipodi:nodetypes="cssss"
+ id="path17520"
+ d="m 154.5,-239 c 0,0.18405 -0.0775,0.36038 -0.21919,0.52335 -0.49587,0.57019 -1.77826,0.97665 -3.28081,0.97665 -1.48659,0 -2.75767,-0.39787 -3.26474,-0.95854 C 147.58334,-238.62651 147.5,-238.80911 147.5,-239"
+ style="fill:none;stroke:url(#linearGradient17535);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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17522"
+ d="m 151,-243.5 c -1.9309,1e-5 -3.52661,0.41962 -3.52661,1.25001 L 147.5,-239.75 c -0.61542,0.34205 -1,0.77768 -1,1.25 l -0.0266,1.25001 c 0,1.10519 2.04141,1.74999 4.52661,1.74999 2.48519,0 4.47339,-0.64479 4.47339,-1.74999 L 155.5,-238.5 c 0,-0.47232 -0.38458,-0.90795 -1,-1.25 l -0.0266,-2.49999 c 0,-0.83038 -1.54249,-1.25001 -3.47339,-1.25001 l -1e-5,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.60000002;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="cccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path17524"
+ d="m 148.5,-239.04648 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875"
+ style="fill:none;stroke:#0066ff;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g22254">
+ <g
+ transform="translate(20.029029,0)"
+ style="opacity:0.85"
+ id="g17822">
+ <path
+ d="m 446.75,226.25 -2.25,2.25 2.25,2.25 m 7.5,-4.5 2.25,2.25 -2.25,2.25"
+ style="fill:none;stroke:url(#linearGradient17817);stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:miter;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="path17811"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17809"
+ d="m 444.54256,228.5 11.66489,0 0,0"
+ style="fill:none;stroke:url(#linearGradient17819);stroke-width:2.5;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" />
+ </g>
+ <g
+ transform="translate(20.029029,0)"
+ id="g17801">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 444.54256,228.5 11.95744,0"
+ id="path17024"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path17796"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 446.75,226.25 -2.25,2.25 2.25,2.25 m 7.5,-4.5 2.25,2.25 -2.25,2.25"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g11749"
+ 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="rect22453"
+ width="16"
+ height="16"
+ x="362"
+ y="113" />
+ <g
+ transform="translate(-81,-103)"
+ id="g22300"
+ style="display:inline">
+ <g
+ id="g17482"
+ transform="translate(298.02661,466.04648)">
+ <path
+ style="fill:url(#linearGradient17498);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.68242937;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151,-240.5 c -2.48519,0 -4.49999,0.89481 -4.5,2 l 0,1 c 0,1.10519 2.0148,2 4.5,2 2.48519,0 4.5,-0.8948 4.5,-2 l 0,-1 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ id="path17484"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path17486"
+ d="m 151.00029,-243.51106 c -1.9309,0 -3.5,0.66961 -3.5,1.5 L 147.5,-240 c 0,0.83039 1.5691,1.5 3.5,1.5 1.9309,0 3.5,-0.66961 3.5,-1.5 l 2.9e-4,-2.01106 c 0,-0.83039 -1.5691,-1.5 -3.5,-1.5 z"
+ style="fill:url(#linearGradient17500);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccssscc"
+ id="path17488"
+ d="m 148.5,-241.75 0,2.70352 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875 l 0,-2.70352"
+ style="fill:none;stroke:url(#linearGradient17502);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ 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"
+ sodipodi:ry="1.2798798"
+ sodipodi:rx="3.3084693"
+ sodipodi:cy="-222"
+ sodipodi:cx="108"
+ id="path17490"
+ style="fill:url(#linearGradient17504);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17506);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"
+ d="m 154.5,-239 c 0,0.18405 -0.0775,0.36038 -0.21919,0.52335 -0.49587,0.57019 -1.77826,0.97665 -3.28081,0.97665 -1.48659,0 -2.75767,-0.39787 -3.26474,-0.95854 C 147.58334,-238.62651 147.5,-238.80911 147.5,-239"
+ id="path17492"
+ sodipodi:nodetypes="cssss"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccsccccc"
+ style="fill:none;stroke:#000000;stroke-width:0.60000002;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 151,-243.5 c -1.9309,1e-5 -3.52661,0.41962 -3.52661,1.25001 L 147.5,-239.75 c -0.61542,0.34205 -1,0.77768 -1,1.25 l -0.0266,1.25001 c 0,1.10519 2.04141,1.74999 4.52661,1.74999 2.48519,0 4.47339,-0.64479 4.47339,-1.74999 L 155.5,-238.5 c 0,-0.47232 -0.38458,-0.90795 -1,-1.25 l -0.0266,-2.49999 c 0,-0.83038 -1.54249,-1.25001 -3.47339,-1.25001 l -1e-5,0 z"
+ id="path17494"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0066ff;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 148.5,-239.04648 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875"
+ id="path17496"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g22250">
+ <path
+ style="opacity:0.85;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 456.5,218.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ id="path17828"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17826"
+ d="m 456.5,218.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ style="fill:url(#linearGradient18213);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g23801"
+ 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="rect22457"
+ width="16"
+ height="16"
+ x="320"
+ y="113" />
+ <g
+ mask="url(#mask18666)"
+ style="display:inline"
+ 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="g18026"
+ transform="matrix(0.927273,0,0,1,260.65455,106)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 70.499967,14.5 4.284298,2.5 m -4.284298,-2.5 -4.34315,2.5 m 4.313724,-2.5 0,-4.5"
+ style="fill:none;stroke:#000000;stroke-width:3.42696857;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path18028"
+ 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
+ id="path18030"
+ d="m 69.39211,8 0,2 2.156862,0 0,-2 -2.156862,0 z m -4.313742,8 1.8e-5,2 2.156862,0 -1.8e-5,-2 -2.156862,0 z m 8.627466,0 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.55771327;stroke-linecap:square;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"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient23738);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path18032"
+ sodipodi:cx="70.5"
+ 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"
+ 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"
+ inkscape:export-ydpi="90" />
+ <path
+ id="path18035"
+ style="fill:none;stroke:#91ae42;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.470541,14.5 74.784265,17"
+ sodipodi:nodetypes="cc"
+ 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="fill:#91ae42;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 73.705834,16 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path18037"
+ sodipodi:nodetypes="ccccc"
+ 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
+ id="path18039"
+ d="m 69.39211,8 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#4989e9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ 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
+ id="path18041"
+ d="m 65.078405,16 0,2 2.156844,0 0,-2 -2.156844,0 z"
+ style="fill:#ef6529;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ 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
+ d="M 70.470541,14.5 66.156817,17"
+ style="fill:none;stroke:#ef6529;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path18043"
+ sodipodi:nodetypes="cc"
+ 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
+ d="m 70.470541,14.5 0,-4.5"
+ style="fill:none;stroke:#4989e9;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path18045"
+ sodipodi:nodetypes="cc"
+ 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
+ transform="matrix(0.699335,0,0,0.602252,21.19685,5.767346)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path18047"
+ sodipodi:cx="70.5"
+ 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"
+ 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
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1.03847623px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 65.617602,17.5 0,-1 1.078431,0"
+ id="path18049"
+ sodipodi:nodetypes="ccc"
+ 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"
+ id="path18051"
+ d="m 69.93132,9.5 0,-0.9673924 1.078413,0"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1.03847599px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ 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.5;fill:none;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 74.24505,17.500004 0,-1 1.078431,0"
+ id="path18053"
+ sodipodi:nodetypes="ccc"
+ 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
+ transform="translate(-162,-102)"
+ id="g18124">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.70588235;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 495.5,226 c 0,0 0,-1.75 0,-1.75 0,-0.96333 -0.75,-1.75 -2,-1.75 -1.25,0 -2,0.78667 -2,1.75 l 0,1.75"
+ id="path18055"
+ sodipodi:nodetypes="csccc"
+ 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
+ y="225.48849"
+ x="489.5"
+ height="5.0114956"
+ width="7.9999995"
+ id="rect18057"
+ style="fill:url(#linearGradient23750);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.70588235;stroke-dasharray:none;stroke-dashoffset:0;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="csccc"
+ id="path18059"
+ d="m 495.5,226 c 0,0 0,-1.75 0,-1.75 0,-0.96333 -0.75,-1.75 -2,-1.75 -1.25,0 -2,0.78667 -2,1.75 l 0,1.75"
+ style="fill:none;stroke:url(#linearGradient23752);stroke-width:1.39999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient23754);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect18061"
+ width="6.0312495"
+ height="3.0344827"
+ x="490.5"
+ y="226.5"
+ rx="0"
+ 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"
+ 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"
+ id="rect20632"
+ width="16"
+ height="16"
+ x="68"
+ y="428" />
+ <g
+ style="display:inline"
+ transform="translate(-15.161301,338)"
+ 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="g10762">
+ <path
+ d="m 86.5,100.53983 4.342131,0.008 c 5.188235,0.0101 5.335295,-2.04831 3.335293,-4.04831 -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ 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:7.40000034;display:inline"
+ id="path10764"
+ sodipodi:nodetypes="czszcccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czszcccc"
+ id="path10766"
+ style="fill:none;stroke:url(#linearGradient13991);stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="m 86.5,100.53983 4.342131,0.008 C 96.03037,100.55844 96.17743,98.5 94.177424,96.5 c -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g10534"
+ transform="translate(0,128.00001)">
+ <rect
+ y="428"
+ x="193.9839"
+ height="16"
+ width="16"
+ id="rect20642"
+ 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(-29.016109,339.00751)"
+ id="g20606">
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10953">
+ <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="cccccccccccccccccccccccccccccccccccccc"
+ style="fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.25,-1.53125 -1,-1 -1.53125,1.25 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ id="path10955"
+ 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"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ id="path10957"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.5,-1.78125 -1,-1 -1.78125,1.5 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ style="fill:url(#linearGradient20796);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 434.9998,198.49249 -1.5,1.25 m -2,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.01806,0.29269 -1.5172,0.50569 m -1.49,1.50752 c -0.20864,0.49552 -0.41426,1.14284 -0.4928,1.48679 l -1.5,0 0,1 m 1.5,-5 -0.5,0.5 m 1.25,6.5 -1.25,1.5 m 6.5,-5.5 0,3.5 -3.5,0 m -3,-6 0.5,-0.5 1.5,1.25"
+ style="fill:none;stroke:#f9f9f9;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ id="path10959"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10961">
+ <rect
+ ry="0"
+ rx="0"
+ y="202.46629"
+ x="430.49979"
+ height="8.1236582"
+ width="7.0000763"
+ id="rect10963"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;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" />
+ <path
+ d="m 432.53795,204.5065 2.96201,0 m -2.96201,1.993 2.96201,0 m -2.96201,1.993 2.96201,0"
+ style="fill:none;stroke:#000000;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path10965"
+ 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" />
+ <rect
+ ry="0"
+ rx="0"
+ y="202.48912"
+ x="430.49661"
+ height="8.0067444"
+ width="7.0067482"
+ id="rect10967"
+ style="fill:none;stroke:url(#linearGradient20798);stroke-width:0.99325603;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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g10512"
+ 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"
+ id="rect20640"
+ width="16"
+ height="16"
+ x="173"
+ y="428" />
+ <g
+ transform="translate(-29.98389,338.00045)"
+ 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="g11077"
+ style="display:inline">
+ <g
+ id="g11079"
+ 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"
+ transform="matrix(0.965527,0,0,0.993394,8.273839,0.460629)">
+ <g
+ id="g11081"
+ transform="matrix(1.086383,0,0,1.082072,-19.43307,-7.852041)">
+ <g
+ 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"
+ transform="matrix(0.833341,0,0,0.829252,85.1747,-87.30584)"
+ id="g11083" />
+ <g
+ style="stroke:#000000;stroke-width:1.13287878;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="g11085"
+ transform="matrix(0.833341,0,0,0.829252,85.1747,-87.30584)"
+ 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
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path23208"
+ style="fill:#dad727;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.92361271;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"
+ 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.929498,0,0,0.910458,28.4835,116.0319)" />
+ <path
+ transform="matrix(0.8580178,0,0,0.8424365,37.918882,124.05843)"
+ 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:type="arc"
+ style="fill:url(#linearGradient23215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.92361271;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23213"
+ 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" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 210.20333,98.981214 0,-1.914298 1.90698,0 0,1.914298 -1.90698,0 z"
+ id="path11089"
+ sodipodi:nodetypes="ccccc"
+ 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
+ id="g11091">
+ <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="ccccc"
+ inkscape:transform-center-y="-3.3687892"
+ id="path11093"
+ d="m 208.05857,93.345302 2.18641,2.891627 c 0.50125,-0.147037 1.16637,-0.122617 1.82389,-0.02056 l 2.18648,-2.87107 c -1.9067,-1.162873 -4.29008,-1.162873 -6.19678,0 l 0,3e-6 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:transform-center-y="2.4548853"
+ id="path11095"
+ d="m 208.53524,102.88086 1.43003,-3.336509 c -0.67737,-0.380664 -0.53518,-1.067385 -0.59136,-1.547136 l -3.93706,-4.21e-4 c 0,2.093176 1.43003,4.186346 3.09839,4.884066 l 0,0 0,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="3.3187399"
+ 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"
+ inkscape:transform-center-x="-3.318739"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 213.77867,102.88086 -1.43002,-3.336509 c 0.67738,-0.380664 0.53486,-1.067385 0.59105,-1.547136 l 3.93736,-4.21e-4 c 0,2.325746 -1.43003,4.186346 -3.09839,4.884066 z"
+ id="path11097"
+ inkscape:transform-center-y="2.4548853"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </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"
+ sodipodi:ry="7.7241406"
+ sodipodi:rx="7.7074003"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11099"
+ style="fill:none;stroke:url(#linearGradient13520);stroke-width:1.40287328;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ 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"
+ transform="matrix(0.713599,0,0,0.712048,116.8049,13.97832)" />
+ <g
+ 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"
+ transform="translate(-160.2001,83.979)"
+ id="g11101">
+ <g
+ transform="translate(39.10005,-0.04905017)"
+ id="g11103" />
+ <g
+ id="g11105" />
+ </g>
+ <g
+ id="g11107"
+ style="opacity:0.3;display:inline"
+ transform="matrix(1.0489321,0,0,1.0749238,-10.489315,-7.3395414)">
+ <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="ccccc"
+ inkscape:transform-center-y="-3.3687892"
+ id="path11109"
+ d="m 208.05857,93.345302 2.18641,2.891627 c 0.50125,-0.147037 1.16637,-0.122617 1.82389,-0.02056 l 2.18648,-2.87107 c -1.9067,-1.162873 -4.29008,-1.162873 -6.19678,0 l 0,3e-6 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:transform-center-y="2.4548853"
+ id="path11111"
+ d="m 208.53524,102.88086 1.43003,-3.336509 c -0.67737,-0.380664 -0.53518,-1.067385 -0.59136,-1.547136 l -3.93706,-4.21e-4 c 0,2.093176 1.43003,4.186346 3.09839,4.884066 l 0,0 0,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="3.3187399"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21197"
+ 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"
+ id="rect21195"
+ width="16"
+ height="16"
+ x="363"
+ y="174" />
+ <g
+ transform="matrix(0.68898,0.688545,-0.68898,0.688545,503.65632,-65.53941)"
+ id="g11065"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccczcczccccscsccscscc"
+ id="path11067"
+ d="m 85.658035,278.19867 c 1.5,0 2.00279,1.00232 2.00279,2.00232 l 1.14e-4,0.36297 c 0,0.75 -0.916764,1.9289 -1.666764,1.9289 -0.75,0 -0.858674,0.24559 -2.129469,-1.0252 -0.5,0 -0.22594,-2.3e-4 -0.72594,-2.3e-4 -1.269993,1.26999 -1.394591,1.02543 -2.144591,1.02543 -0.75,0 -1.681542,-1.18154 -1.681542,-1.93154 l -1.15e-4,-0.36297 c 0,-1 0.489879,-2.00105 1.989879,-2.00105 l -0.01948,-5.74221 c -1.5,0 -1.97318,-1.05691 -1.973496,-2.05693 l -1.14e-4,-0.36297 c 0,-0.75 0.855204,-1.89751 1.666764,-1.9289 0.71584,-0.0277 0.873337,-0.24811 2.144133,1.02268 l 0.725939,2.3e-4 c 1.088566,-1.08856 1.396658,-1.02291 2.129928,-1.02291 0.75,0 1.681542,1.18154 1.681542,1.93154 l 1.15e-4,0.36297 c 1.58e-4,0.5 -0.519172,2.05566 -2.019172,2.05566 l 0.01948,5.74221 -10e-7,0 0,0 0,0 z"
+ style="fill:url(#linearGradient15748);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.821307;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 82.032098,271.66942 0.0023,7.25939"
+ id="path11069"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1.02663434px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 85.299056,272.39639 -1,0"
+ id="path11071"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11073"
+ d="m 85.310309,278.21333 -1,0"
+ style="fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 82.397361,278.92893 c -2.4948,-0.75001 -2.539872,2.90296 -0.906565,2.72199"
+ id="path11075"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path24253"
+ d="m 82.395068,271.66953 c -2.548534,0.53612 -2.178736,-2.90444 -0.908284,-2.72256"
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:transform-center-x="-0.32852741"
+ inkscape:transform-center-y="-1.3911103"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 82.5437,278.0941 -1,0"
+ id="path24290"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24294"
+ d="m 82.532207,272.51355 -1,0"
+ style="opacity:0.6;fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path33682"
+ d="m 84.394211,280.56292 0.726168,0.72617"
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 84.390887,270.0368 0.72571,-0.72571"
+ id="path33684"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24682"
+ transform="translate(-166,402)">
+ <rect
+ y="217"
+ x="402"
+ height="16"
+ width="16"
+ id="rect24679"
+ 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="g9450"
+ 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.6171649,0,0,0.6170324,328.7006,73.30195)"
+ style="opacity:0.8;display:inline">
+ <g
+ style="display:inline"
+ id="g9452"
+ 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">
+ <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="path9454"
+ style="fill:url(#linearGradient15446);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.00075221;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 m 3.23019,3.23013 0,-6.46025"
+ style="fill:none;stroke:url(#linearGradient15448);stroke-width:4.86145973;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ id="path9456"
+ 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 130.96632,248.2677 0,-6.46025"
+ style="fill:none;stroke:#000000;stroke-width:2.10663271;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path9458"
+ inkscape:connector-curvature="0" />
+ <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.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g9460"
+ style="fill:none;stroke:url(#linearGradient15452);stroke-width:1.91174495;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.8478042,0,0,0.8531716,59.60482,122.34129)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15450);stroke-width:2.43795967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path9462"
+ 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" />
+ </g>
+ <path
+ id="path9465"
+ style="fill:none;stroke:#000000;stroke-width:2.10663271;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 134.19651,245.03757 -6.46038,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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24609"
+ transform="translate(307.00001,487.05412)">
+ <rect
+ y="111"
+ x="202"
+ height="16"
+ width="16"
+ id="rect24481"
+ 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(1.7e-4,10.00012)"
+ id="g9996"
+ style="display:inline">
+ <path
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.91431391;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 209.99983,115.99988 c 3.86419,0 6.99999,-3.13578 6.99999,-6.99996 0,-3.86418 -3.1358,-6.99997 -6.99999,-6.99997 -3.86419,0 -6.99998,3.13579 -6.99998,6.99997 0,3.86418 3.13579,6.99996 6.99998,6.99996 z m 0,-4.66664 c -1.45833,0 -2.33333,-0.875 -2.33333,-2.33332 0,-1.45833 0.875,-2.33332 2.33333,-2.33332 1.45833,0 2.33333,0.87499 2.33333,2.33332 0,1.45832 -0.875,2.33332 -2.33333,2.33332 z"
+ id="path9998"
+ sodipodi:nodetypes="csssccsssc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g10000"
+ transform="matrix(-2.005135,0,0,-2.005129,595.3141,357.6101)">
+ <path
+ style="fill:none;stroke:url(#linearGradient15578);stroke-width:0.59846401;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"
+ d="m 192.16369,120.79528 c -1.76189,0 -3.19179,1.42994 -3.1918,3.19182 0,1.76188 1.42991,3.19183 3.1918,3.19183 1.76188,0 3.19179,-1.42995 3.1918,-3.19183 0,-1.76188 -1.42992,-3.19182 -3.1918,-3.19182 l 0,0 0,0 0,0 z"
+ id="path10002"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path10004"
+ d="m 192.16376,122.51797 c -0.81098,0 -1.46916,0.65815 -1.46916,1.46907 0,0.81094 0.65818,1.46907 1.46916,1.46907 0.81097,0 1.46913,-0.65813 1.46913,-1.46907 0,-0.81092 -0.65816,-1.46907 -1.46913,-1.46907 z"
+ style="fill:none;stroke:url(#linearGradient15580);stroke-width:0.59846407;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g106468">
+ <g
+ 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.9535916,0,0,1.1712921,1176.1968,319.2322)"
+ id="g29877-5-3-1"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path29879-5-0-9"
+ d="m 392.96689,241.84215 -0.56915,0 -3.5287,2.84782 0,1.13912 3.5287,2.84781 0.56915,0 0,-6.83475 0,0 0,0 z"
+ style="color:#000000;fill:url(#radialGradient106344-5);fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient106433);stroke-width:0.66107476px;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
+ sodipodi:nodetypes="cccc"
+ id="path29881-5-6-0"
+ d="m 392.96688,248.67221 -0.57173,0 -3.51515,-2.83619 -0.008,-1.21916"
+ style="fill:none;stroke:url(#linearGradient106307-2);stroke-width:0.66107482px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="598"
+ x="404"
+ height="16"
+ width="16"
+ id="rect24491"
+ 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">
+ <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"
+ id="rect29875"
+ width="16"
+ height="16"
+ x="619"
+ y="-441" />
+ <g
+ 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(0,-2.196282,-1.316799,0,755.9575,1484.5661)"
+ id="g29877"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path29879"
+ d="m 392.96689,241.84215 -0.56915,0 -3.5287,2.84782 0,1.13912 3.5287,2.84781 0.56915,0 0,-6.83475 0,0 0,0 z"
+ style="color:#000000;fill:url(#linearGradient29884);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.58802557px;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
+ sodipodi:nodetypes="ccc"
+ id="path29881"
+ d="m 392.51157,247.53778 0,-4.93622 -3.18721,2.46812"
+ style="fill:none;stroke:url(#linearGradient29886);stroke-width:0.58802563px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24559"
+ transform="translate(259,508.00001)">
+ <rect
+ y="111"
+ x="103"
+ height="16"
+ width="16"
+ id="rect24489"
+ 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
+ transform="matrix(-0.248353,0.02816779,0.02830718,0.248422,140.45214,86.01031)"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10768"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ style="display:inline"
+ id="g24623"
+ 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"
+ id="rect24479"
+ width="16"
+ height="16"
+ x="243"
+ y="111" />
+ <g
+ transform="translate(0.01612278,6)"
+ id="g10870"
+ style="display:inline">
+ <rect
+ style="fill:url(#linearGradient15719);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect10872"
+ width="11.000006"
+ height="2.9999976"
+ x="245.48387"
+ y="111.49999"
+ rx="0"
+ ry="1.4769578"
+ 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
+ style="fill:none;stroke:url(#linearGradient15721);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 254.47577,112.49191 -7.99189,0.008 0.0242,1"
+ id="path10874"
+ 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="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24617"
+ transform="translate(-113,487.00001)">
+ <rect
+ y="111"
+ x="223"
+ height="16"
+ width="16"
+ id="rect24477"
+ 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,6)"
+ id="g10876"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient15723);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 225.48388,111.49999 4.01612,-0.008 -0.0161,-3.99192 3,0 0.0161,3.99192 3.98388,0.008 0,3 -3.98388,-0.008 -0.0161,4.008 -3,0 0.0161,-4.008 -4.01612,0.008 0,-3 z"
+ id="path10878"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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
+ id="path10880"
+ d="m 232.48388,112.49999 3,0 m -5,2 0,3 m 1,-9 -1,0 0.0161,3.99192 -4.01612,0.008 0.0242,1"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccccccc"
+ 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>
+ <g
+ style="display:inline"
+ id="g24629"
+ transform="translate(-128,487.00001)">
+ <rect
+ y="132"
+ x="322"
+ height="16"
+ width="16"
+ id="rect24475"
+ 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="g11344"
+ 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.9261989,0,0,0.928757,209.23303,-98.08036)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g11346"
+ 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">
+ <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="path11348"
+ style="fill:url(#linearGradient15774);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.06496322;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,130.45005)" />
+ </g>
+ <path
+ d="m 134.19651,255.80467 -6.46038,0 m 3.23019,3.23013 0,-6.46025"
+ style="fill:none;stroke:url(#linearGradient15776);stroke-width:3.2301569;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ id="path11350"
+ 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 130.96632,259.0348 0,-6.46025"
+ style="fill:none;stroke:#000000;stroke-width:1.07819378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path11352"
+ inkscape:connector-curvature="0" />
+ <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.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g11354"
+ style="fill:none;stroke:url(#linearGradient15780);stroke-width:1.27024341;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.858314,0,0,0.863791,58.21752,134.9089)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15778);stroke-width:1.60000753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path11356"
+ 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" />
+ </g>
+ <path
+ id="path11358"
+ style="fill:none;stroke:#000000;stroke-width:1.07819378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 134.19651,255.80467 -6.46038,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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24604"
+ transform="translate(305,487.00001)">
+ <rect
+ y="111"
+ x="183"
+ height="16"
+ width="16"
+ id="rect24483"
+ 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(-1,0,0,-1,382.01612,238.00006)"
+ id="g54036"
+ style="display:inline">
+ <path
+ sodipodi:type="arc"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient16025);stroke-width:1.94115818;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"
+ id="path54038"
+ sodipodi:cx="190.5"
+ 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"
+ transform="matrix(0.61819,0,0,0.618186,73.23488,45.12681)" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24582"
+ transform="translate(114.02028,508.00993)">
+ <rect
+ y="111"
+ x="143"
+ height="16"
+ width="16"
+ id="rect24487"
+ 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="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"
+ sodipodi:ry="2.7944512"
+ sodipodi:rx="2.7944512"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path15084"
+ 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 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="path15086"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient15122);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(#linearGradient15124);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="path15099"
+ 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.288521,0,0,-1.2885339,576.8463,164.73299)" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.6;display:inline"
+ id="g24923"
+ 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"
+ id="rect24905"
+ width="16"
+ height="16"
+ x="43"
+ y="69" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10995"
+ style="display:inline">
+ <g
+ style="fill:none;display:inline"
+ 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(-0.608695,0,0,0.604849,289.36339,-70.36932)"
+ id="g10997">
+ <path
+ id="path10999"
+ d="m 394.08819,237.85988 -6.57143,6.61322 6.57143,6.61322 1.23215,0 -10e-6,-13.22644 -1.23214,0 z"
+ style="fill:none;stroke:#000000;stroke-width:1.64807379;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path11001"
+ d="m 49.233877,73.74999 3.75,3.75 -3.75,3.75 -0.25,0 0,-7.5 0.25,0 z"
+ style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:#ffffff;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 57.25,606.75 -3.75,3.75 -0.5,0"
+ id="path35403"
+ sodipodi:nodetypes="cc"
+ transform="translate(-4.0161228,-529.00001)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24911"
+ 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"
+ id="rect24909"
+ width="16"
+ height="16"
+ x="82"
+ y="69" />
+ <g
+ style="display:inline"
+ transform="matrix(0,-1,1,0,-153.98989,467.9919)"
+ id="g11003"
+ 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
+ id="path11005"
+ d="m 392.49192,239.48989 -5.00001,4.75 0,0.5 5.00001,4.75 1,0 0,-10 -1,0 z"
+ style="color:#000000;fill:url(#linearGradient15742-5);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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11007"
+ d="m 392.49191,248.23989 0,-7.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24917"
+ 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"
+ id="rect24907"
+ width="16"
+ height="16"
+ x="62"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g11009"
+ transform="matrix(-1,0,0,1,461.01011,-167)"
+ 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="fill:url(#linearGradient15742);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 392.5,239.5 -4.98989,4.74999 0,0.5 4.98989,4.75001 1.01011,-1e-5 0.0368,-9.96874 L 392.5,239.5 z"
+ id="path11011"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient27860);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.51011,248.24999 0,-7.5 -4,3.75"
+ id="path11013"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25461"
+ transform="translate(444,424.00001)">
+ <rect
+ y="174"
+ x="23"
+ height="16"
+ width="16"
+ id="rect25118"
+ 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="g25451">
+ <g
+ id="use25367"
+ transform="translate(24.016123,6)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25447"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25449"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <g
+ id="use25369"
+ transform="translate(28.016123,6)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25441"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25443"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <rect
+ y="184.50003"
+ x="26.516125"
+ height="3.0000005"
+ width="1.0000005"
+ id="rect25373"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25375"
+ width="1"
+ height="3"
+ x="25.516123"
+ y="183.5" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25412"
+ transform="translate(443,424.00001)">
+ <rect
+ y="174"
+ x="3"
+ height="16"
+ width="16"
+ id="rect25116"
+ 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="g25401">
+ <g
+ id="use9783"
+ transform="translate(4.0161228,0)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25397"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25399"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <g
+ id="use9785"
+ transform="translate(8.0161228,0)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25391"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25393"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <g
+ id="g9787"
+ transform="translate(0.01612278,0)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect9789"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect9791"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25528"
+ 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"
+ id="rect25526"
+ width="16"
+ height="16"
+ x="143"
+ y="153" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10844"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient15699);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 144.5,163.5 13,0 0,-1 c 0,-2.25 -0.5,-3 -4,-3 -0.5,-1.25 -1.5,-3 -4,-3 l -1,0 c -3.75,0 -4,2.25 -4,5 l 0,2 z"
+ id="path10846"
+ sodipodi:nodetypes="ccscsccc"
+ 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:type="arc"
+ style="fill:url(#linearGradient15701);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.46666667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path10848"
+ sodipodi:cx="147"
+ 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"
+ 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"
+ 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"
+ sodipodi:nodetypes="csccc"
+ id="path10850"
+ d="m 150,157.5 -1.5,0 c -3,0 -3,1.5 -3,5 m 10.99996,-0.71441 c 0,-1.60712 5e-5,-1.28559 -2.99996,-1.28559"
+ style="fill:none;stroke:url(#linearGradient15703);stroke-width:1;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.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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="165"
+ sodipodi:cx="147"
+ id="path10852"
+ style="fill:url(#linearGradient15705);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.46666667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g35472"
+ 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"
+ id="rect25724"
+ width="16"
+ height="16"
+ x="89"
+ y="470" />
+ <g
+ id="g35249">
+ <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="path12027"
+ d="m 94.5,480.5 1.25,-1.25"
+ style="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:transform-center-y="-6.245879"
+ inkscape:transform-center-x="-6.2091889"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.62898993;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path12029"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ <path
+ style="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 90.863188,484.13807 94.25,480.75"
+ id="path12031"
+ 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:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 94.5,480.5 1.25,-1.25"
+ id="path12033"
+ 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
+ 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.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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path35965"
+ style="opacity:0.5;fill:url(#radialGradient35967);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.55910218;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.2091889"
+ inkscape:transform-center-y="-6.245879" />
+ <g
+ id="g12035"
+ 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.0005769,0,0,0.9999104,-69.113516,270.01809)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35488);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient35490);stroke-width:0.87477797;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path12037"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path35287"
+ style="opacity:0.25;fill:url(#radialGradient35492);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
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient35494);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35289"
+ 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)" />
+ </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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path12041"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.993526,0,0,1.026234,103.4315,65.484747)" />
+ </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="path12043"
+ d="m 90.75,484.25 3.5,-3.5"
+ style="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.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.25,484 94,480.25"
+ id="path12045"
+ 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>
+ </g>
+ <g
+ style="display:inline"
+ id="g21566"
+ 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"
+ id="rect21528"
+ width="16"
+ height="16"
+ x="463"
+ y="236" />
+ <g
+ transform="translate(459.98858,167)"
+ style="display:inline"
+ id="g14449">
+ <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="path14451"
+ d="m 17.51142,84.5 -13.988585,0 -0.011415,-14 14,0 0,14 z"
+ style="fill:url(#linearGradient16063);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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path14523"
+ style="fill:none;stroke:url(#linearGradient16067);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 6.0097,77.5 6.00172,0 m 1,0 4,0 m -6,-2 6,0 m -3,-2 3,0 m -11.00172,0 7.00172,0 m -7.00172,2 4.00172,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="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient16069);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51142,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 0,0 0,0 0,0 z"
+ id="path14459"
+ 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>
+ <g
+ style="display:inline"
+ id="g21557"
+ transform="translate(-205,-205)">
+ <rect
+ y="236"
+ x="483"
+ height="16"
+ width="16"
+ id="rect21548"
+ 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="g21749">
+ <g
+ transform="translate(479.98859,167)"
+ style="display:inline"
+ id="g14498">
+ <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="path14500"
+ d="m 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ style="fill:url(#linearGradient14511);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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient14517);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51141,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 z"
+ id="path14508"
+ 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>
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ 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 486,246.5 7.03916,0 m -2.03916,2 -5,0 m 0.0392,-6 5,0 m -5,-2 6,0 m -6,4 3,0"
+ style="fill:none;stroke:url(#linearGradient21531);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path15300"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21497"
+ 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"
+ id="rect21493"
+ width="16"
+ height="16"
+ x="223"
+ y="26" />
+ <g
+ id="g21465">
+ <g
+ style="display:inline"
+ id="g10969"
+ 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="translate(0.1889228,-16)">
+ <g
+ 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="g10971"
+ transform="matrix(1.083333,0,0,1.083326,-149.75,-207.0817)">
+ <g
+ id="g10973">
+ <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="path10975"
+ d="m 356.53857,243.30784 -11.07692,0 0,-11.07699 11.07692,0 0,11.07699 z"
+ style="fill:url(#linearGradient15734);fill-opacity:1;fill-rule:evenodd;stroke:#333333;stroke-width:0.92307967px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.92307913px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 346.38485,242.26935 -1.3e-4,-9.11543 9.14632,0"
+ id="path10977"
+ 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>
+ </g>
+ <path
+ id="path10979"
+ d="m 227,49 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 231,47 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z"
+ id="path10981"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g16140"
+ style="display:inline"
+ transform="translate(219.98859,-43)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient16150);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 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ id="path16142"
+ 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
+ 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="path16148"
+ d="m 16.51141,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 z"
+ style="fill:none;stroke:url(#linearGradient16154);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path16156"
+ d="m 227,33 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 231,31 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z"
+ id="path16158"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21514"
+ transform="translate(96.030183,5)">
+ <rect
+ y="26"
+ x="202.96982"
+ height="16"
+ width="16"
+ id="rect21491"
+ 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="g21479">
+ <g
+ transform="translate(-19.811077,-16)"
+ 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="g10983"
+ style="display:inline">
+ <g
+ transform="matrix(1.083333,0,0,1.083326,-149.75,-207.0817)"
+ id="g10985"
+ 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="g10987">
+ <path
+ style="fill:url(#linearGradient15736);fill-opacity:1;fill-rule:evenodd;stroke:#333333;stroke-width:0.92307967px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 356.53857,243.30784 -11.07692,0 0,-11.07699 11.07692,0 0,11.07699 z"
+ id="path10989"
+ 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" />
+ <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="path10991"
+ d="m 346.38485,242.26935 -1.3e-4,-9.11543 9.14632,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.92307913px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 231,47 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z m -7,-2 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ id="path10993"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(199.98859,-43)"
+ style="display:inline"
+ id="g16160">
+ <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="path16162"
+ d="m 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ style="fill:url(#linearGradient16170);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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient16174);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51141,71.5 -12,0 -1e-6,12 12.000001,0 0,-12 z"
+ id="path16168"
+ 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>
+ <path
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 211,31 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z m -7,-2 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ id="path16178"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g11969"
+ 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="rect21607"
+ width="16"
+ height="16"
+ x="362"
+ y="29" />
+ <g
+ id="g11961">
+ <g
+ transform="translate(358.98859,-40)"
+ style="display:inline"
+ id="g14938">
+ <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="path14940"
+ d="m 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ style="fill:url(#linearGradient21902);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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient21904);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51141,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 z"
+ id="path14942"
+ 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>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccc"
+ id="path14947"
+ d="m 366,33.03125 0,1 -1,0 0,1 1,0 0,2 1,0 0,-4 -1,0 z M 365,39 l 0,1 2.3295,0 0,-1 L 365,39 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0.0594,1 -1.05938,0 0,1 -1,0 0,1 3,0 0,-1 -1.44062,0 0.5,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 369,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ id="path14953"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 370,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ id="path14955"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g11979"
+ 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="rect21605"
+ width="16"
+ height="16"
+ x="341"
+ y="29" />
+ <g
+ id="g11953">
+ <g
+ id="g14924"
+ style="display:inline"
+ transform="translate(337.98858,-40)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient21862);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 17.500005,84.5 -13.988585,0 -1e-7,-14 14.0000001,0 -0.01141,14 -5e-6,0 0,0 0,0 z"
+ id="path14929"
+ 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
+ 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="path14933"
+ d="m 16.51142,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient21864);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g11949">
+ <path
+ id="path14967"
+ d="m 344,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path14971"
+ d="m 345,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </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">
+ <g
+ id="g22274"
+ transform="translate(-30,0)">
+ <rect
+ ry="0"
+ rx="0"
+ y="-127"
+ x="200"
+ height="16"
+ width="16"
+ id="rect22276"
+ 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
+ style="fill:none;stroke:#0b1728;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"
+ d="m 204,-114 c 4.5365,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path22282"
+ sodipodi:nodetypes="csc"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;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="rect22278"
+ width="2.9998772"
+ height="3"
+ x="202.50012"
+ y="-115.5"
+ ry="1.4999387"
+ rx="1.4843137" />
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-125.5"
+ x="205.50012"
+ height="3"
+ width="2.9998772"
+ id="rect22280"
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path22284"
+ d="m 204,-114 c 4.49647,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:url(#linearGradient24098);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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#afc6e9;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 205,-115 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path22288"
+ 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="path22291"
+ d="m 208,-125 c -0.65334,0 -1.30668,1e-5 -1.96003,1e-5 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-1e-5 1.96003,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#87aade;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" />
+ </g>
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 176.5,-123.5 0,-1 1,0"
+ id="path22293"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22295"
+ d="m 173.5,-113.5 0,-1 1,0"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ 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="path22297"
+ d="m 176,-113.25657 c -0.33333,0 -0.66667,-1e-5 -1,-1e-5 0,-0.55431 0,-1.1086 0,-1.66292 0.33333,0 0.66667,1e-5 1,1e-5 0,0.55431 0,1.10861 0,1.66292 z"
+ style="opacity:0.35;fill:#002255;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path22299"
+ d="m 179,-122.48792 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.63982 0,-1.27964 0,-1.91948 0.32001,0 0.64002,1e-5 0.96003,1e-5 0,0.63983 0,1.27966 0,1.91948 z"
+ style="opacity:0.2;fill:#002255;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#00112b;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 176,-113 c -0.33333,0 -0.66667,0 -1,0 0,-0.21055 0,-0.42107 0,-0.63162 0.33333,0 0.66667,0 1,0 0,0.21055 0,0.42107 0,0.63162 z"
+ id="path22302"
+ 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>
+ <g
+ style="display:inline"
+ id="g31233"
+ 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"
+ id="rect31205"
+ width="16"
+ height="16"
+ x="63"
+ y="48" />
+ <g
+ id="g9148"
+ 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"
+ transform="matrix(1.0003553,0,0,0.9995949,18.983834,-41.953346)">
+ <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"
+ style="fill:url(#linearGradient15356);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect9150"
+ width="12.995382"
+ height="13.003749"
+ x="45.5"
+ y="91.491928" />
+ <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:url(#linearGradient15358);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 46.49945,103.49527 0,-11.002747 10.996287,0 0,11.002747 -10.996287,0 z"
+ id="path9152"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g31226"
+ 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"
+ id="rect31207"
+ width="16"
+ height="16"
+ x="83"
+ y="48" />
+ <g
+ style="display:inline"
+ id="g9154"
+ transform="matrix(1.1658027,0,0,1.1657997,-59.289717,-204.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
+ 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="path9156"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23686159;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient15360);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path9158"
+ 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.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)" />
+ <path
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15362);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path9160"
+ 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" />
+ </g>
+ </g>
+ <g
+ id="g31393"
+ 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="rect31391"
+ width="16"
+ height="16"
+ x="110"
+ y="29" />
+ <g
+ transform="translate(-73,-123.96875)"
+ id="g9974"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:none"
+ d="M 186.2503,165.73428 C 185.16882,164.6489 184.5,163.15208 184.5,161.5 c 0,-3.312 2.688,-6 6,-6 1.65758,0 3.15886,0.67328 4.24511,1.76111 l -8.49481,8.47317 z"
+ id="path9976"
+ sodipodi:nodetypes="csscc"
+ 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="path23601"
+ d="m 188,154 0,2 6,0 0,-2 -6,0 z m 6,2 0,2 1.96875,0 0,6 -1.96875,0 0,1.96875 -6,0 0,-1.96875 -2,0 0,2 2,0 0,1.96875 6,0 0,-1.96875 2,0 0,-2 1.96875,0 0,-6 -1.96875,0 0,-2 -2,0 z m -8,8 0,-6 -2,0 0,6 2,0 z m 0,-6 2,0 0,-2 -2,0 0,2 z"
+ style="opacity:0.1;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 188,154 0,2 6,0 0,-2 -6,0 z m 6,2 0,2 1.96875,0 0,6 -1.96875,0 0,1.96875 -6,0 0,-1.96875 -2,0 0,2 2,0 0,1.96875 6,0 0,-1.96875 2,0 0,-2 1.96875,0 0,-6 -1.96875,0 0,-2 -2,0 z m -8,8 0,-6 -2,0 0,6 2,0 z m 0,-6 2,0 0,-2 -2,0 0,2 z"
+ id="path9978"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:url(#linearGradient15574);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 186,158 2,0 0,-2 6,0 0,2 2,0 0,6 -2,0 0,2 -6,0 0,-2 -2,0 0,-6 z"
+ id="path9980"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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"
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path23596"
+ d="m 186.5,158.46875 2,0 0,-2 5,0 0,2 2,0 0,5 -2,0 0,2 -5,0 0,-2 -2,0 0,-5 z"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient23599);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g31442"
+ 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"
+ id="rect31425"
+ width="16"
+ height="16"
+ x="282"
+ y="6" />
+ <g
+ 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="translate(0.01612278,22)"
+ id="g10456"
+ style="display:inline">
+ <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="path10458"
+ d="m 296.49991,-1.4999999 -13.00008,0 0,-12.9999991 13.00008,0 0,12.9999991 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient15644);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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15646);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 284.50009,-2.5000021 0,-11.0000069 11.00001,0"
+ id="path10460"
+ 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
+ id="path10462"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 286.42863,-12.4 -0.84311,0 m 2.83879,3 -0.83163,0 m 2.83056,3 -0.82626,0 m 2.78967,1 -0.80293,0 m 3.77084,1 -1.74082,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g31515"
+ transform="translate(18,130)">
+ <rect
+ y="27"
+ x="323"
+ height="16"
+ width="16"
+ id="rect31510"
+ 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="g10854"
+ style="display:inline">
+ <rect
+ style="fill:url(#linearGradient15707);fill-opacity:1;fill-rule:nonzero;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="rect10856"
+ width="12"
+ height="12"
+ x="324.50003"
+ y="41.500015" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient15709);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10858"
+ 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.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"
+ d="m 335.50002,42.500013 -10,0 0,10 L 335.5,52.5 l 0,-10"
+ id="path10860"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15713);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="path10862"
+ 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(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" />
+ <g
+ style="display:inline"
+ id="g27528"
+ transform="translate(0.01612278,-12)">
+ <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" />
+ </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" />
+ <g
+ transform="translate(0.01612278,0)"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path10866"
+ style="fill:url(#linearGradient15715);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87499601;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="fill:none;stroke:url(#linearGradient15717);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="path10868"
+ 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(0.857099,0,0,0.857147,67.228993,5.071249)" />
+ </g>
+ </g>
+ <g
+ id="g31658"
+ 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"
+ id="rect31549"
+ width="16"
+ height="16"
+ x="26"
+ y="8" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient31664);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 40.499999,22.499999 -12.999999,0 0,-12.999999 12.982741,0 0.01726,12.999999 -2e-6,0 z"
+ id="path31555"
+ 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="cccccccccccccccccccccccccccccccccccc"
+ id="path31559"
+ d="M 36.5,11.548223 36.5,19 l 0,-7.451777 z M 37.5,16 l 0,3 0,-3 z m -3,-2 0,5 0,-5 z m 1,0 0,5 0,-5 z m -3,1 0,4 0,-4 z m 6,0 0,4 0,-4 z m -5,1 0,3 0,-3 z m -3,1 0,2 0,-2 z m 9,1.578539 0,0.421461 0,-0.421461 z M 31.5,18 l 0,1 0,-1 z m -3,-0.52573 0,1.52573 0,-1.52573 z m 1,1.087098 0,0.438632 0,-0.438632 z"
+ style="fill:none;stroke:url(#linearGradient31666);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient31672);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 28.5,19.5 11,0"
+ id="path31670"
+ sodipodi:nodetypes="cc"
+ 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="path31557"
+ d="m 39.5,10.500004 -11,0 0,11 11.000001,0 -10e-7,-11 z"
+ style="fill:none;stroke:url(#linearGradient31668);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g31429"
+ transform="translate(-234,4)">
+ <rect
+ y="6"
+ x="302"
+ height="16"
+ width="16"
+ id="rect31427"
+ 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,-16)"
+ id="g13262"
+ style="display:inline">
+ <g
+ 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="translate(20.00009,22)"
+ id="g13264">
+ <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="path13266"
+ d="m 296.49991,14.5 -13.00008,0 0,-12.999999 13.00008,0 0,12.999999 z"
+ style="fill:url(#linearGradient31646);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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient31648);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 284.50009,13.499998 0,-11.000007 11.00001,0"
+ id="path13268"
+ 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>
+ <path
+ id="path13270"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 310,34 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g13272"
+ transform="translate(0,-10)"
+ style="stroke-width:1.10000002;stroke-miterlimit:4;stroke-dasharray:none">
+ <path
+ id="path13274"
+ style="fill:none;stroke:url(#radialGradient31650);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 310,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ d="m 310,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ style="fill:none;stroke:url(#radialGradient31652);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path13276"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13278"
+ style="fill:none;stroke:url(#radialGradient31654);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 310,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ d="m 309.98388,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ style="fill:none;stroke:url(#radialGradient31656);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path13280"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-21,-418)"
+ id="g31674">
+ <rect
+ y="428"
+ x="47"
+ height="16"
+ width="16"
+ id="rect31676"
+ 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="g31678">
+ <rect
+ ry="0"
+ style="fill:#ececec;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="rect31680"
+ width="13.016124"
+ height="12.953857"
+ x="48.499996"
+ y="429.54614" />
+ <rect
+ y="430"
+ x="50.016117"
+ height="11.046139"
+ width="11.000001"
+ id="rect31682"
+ style="fill:url(#linearGradient31694);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
+ style="fill:url(#linearGradient31696);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 49,430 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,0 0,3 3,0 0,-3 -3,0 z m 0,3 -3,0 0,3 3,0 0,-3 z m 0,3 0,3 3,0 0,-3 -3,0 z m -3,0 -3,0 0,3 3,0 0,-3 z m -3,0 0,-3 -3,0 0,3 3,0 z"
+ id="path31684"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient31698);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 60.517703,430.5 -11.017704,0 0,11 11.017704,0 0,-11"
+ id="path31686"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g11938"
+ transform="translate(0,2)">
+ <rect
+ y="8"
+ x="278"
+ height="16"
+ width="16"
+ id="rect31906"
+ 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(-64.983874,-102.97791)"
+ id="g14768"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient31932);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 348.18876,112.47791 8.33334,0 0,13 -11,0 -1e-5,-10 2.66667,-3 0,0 0,0 0,0 z"
+ id="path14575"
+ 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
+ style="fill:#666666;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 349,114 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 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 0,-2 2,0 0,-2 -2,0 0,2 z m 0,-2 0,-2 -2,0 0,2 2,0 z"
+ id="rect14548"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path14579"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,409.54887,-222.56021)"
+ 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:url(#linearGradient31934);stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 354.58387,114.50843 -7.05183,-0.0551 0.007,9.11382"
+ id="path14581"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 345,116 4,0 0,-4 -4,4 z"
+ id="path14583"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 346.5,117.00001 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient31936);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path14585"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path14587"
+ 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 345.5221,114.97791 0,10.5 11,0 0,-13 -8.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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g10845"
+ 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="rect31964"
+ width="16"
+ height="16"
+ x="26"
+ y="260" />
+ <g
+ transform="translate(-2322.9523,-570.94199)"
+ id="g12799"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cczcccc"
+ id="path12801"
+ d="m 2349.9523,841.94199 c 2.0093,-2.0093 3.5347,-3.43269 5.544,-5.44199 3.25,-3.25 9,-2 9,2 -4.5,-2.5 -7.044,3.94199 -0.544,3.94199 l 0,1.5 -14,0 0,-2 z"
+ style="opacity:0.8;fill:url(#linearGradient38692);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:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 2349.5,842.49627 c 1.9988,-1.99875 3.9535,-4.05552 5.9523,-6.05428 3.25,-3.25 9.044,-1.94199 9.044,2.05801 -4.5,-2.5 -6.544,4.94199 0,4"
+ id="path12805"
+ sodipodi:nodetypes="cczc"
+ 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"
+ sodipodi:nodetypes="ccs"
+ id="path12807"
+ d="m 2351,842.51381 c 1.67,-1.67002 3.34,-3.34005 5.0101,-5.01008 2.1922,-2.31174 5.9422,-2.81174 7.4422,-0.0617"
+ style="fill:none;stroke:url(#radialGradient13900);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g13136"
+ transform="translate(0,2)">
+ <rect
+ y="260"
+ x="131"
+ height="16"
+ width="16"
+ id="rect32039"
+ 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="g13125">
+ <g
+ id="g12811"
+ transform="translate(-70.98388,253.6)"
+ 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="opacity:0.4">
+ <g
+ 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"
+ transform="matrix(1.090908,0,0,1.083334,-60.5905,-148.5)"
+ id="g12813">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path12815"
+ d="m 253.9851,154.06144 0.0148,-7.98461 -5.97312,2.67692 c 0,2.37037 -0.0149,8.01803 -0.0149,8.53832 l 5.97323,-3.23063 -1e-5,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ 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"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 242.06842,154.06144 0,-8.21538 5.95834,2.90769 0,8.30769 -5.95834,-3 z"
+ id="path12817"
+ 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="path12819"
+ d="m 242.06842,146.21529 5.95834,-2.67692 5.95834,2.67692 -5.95834,2.53846 -5.95834,-2.53846 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ 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
+ sodipodi:nodetypes="ccccccccc"
+ 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="path12821"
+ 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 209.98388,21.9 -6.5,-3.5 0,-8.5 m 6.5,12 6.5,-3.5 0,-8.5 m 0,0 -6.5,-2.75 -6.5,2.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g12823"
+ transform="matrix(0.668332,0,0,0.668394,53.64412,108.1139)"
+ 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\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="path12825"
+ style="fill:url(#linearGradient13112);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.60044813;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8412876,0,0,0.8414582,16.661932,139.91818)" />
+ <path
+ transform="matrix(0.654253,0,0,0.6543912,41.350498,161.99208)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient13114);stroke-width:2.28663301;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path27909"
+ 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" />
+ </g>
+ </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"
+ 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"
+ id="rect12049"
+ width="16"
+ height="16"
+ x="47.000004"
+ y="387" />
+ <g
+ transform="translate(-336.01611,233)"
+ id="g22979">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 391.01611,155 -6.00001,2.125 0,7.65625 6.00001,3.21875 6,-3.21875 0,-7.65625 -6,-2.125 z"
+ id="path12053"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path12063"
+ d="m 397.01609,164.76992 0,-7.6298 -6,-2.14012 c 0,2.58362 8.3e-4,12.47266 8.3e-4,13.03976 l 5.99917,-3.26984 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17712);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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="path12065"
+ d="m 385.01609,164.75 0,-7.5 6,-2.25 c 0,2.37037 0,12.47971 0,13 l -6,-3.25 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99989706;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="path12067"
+ d="m 385.01658,157.14012 6.00034,-2.17997 5.99917,2.17997 -5.99975,2.72493 -5.99976,-2.72493 z"
+ style="fill:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
+ id="path12835"
+ d="m 385.01612,158 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,-0.5 -2,-0.5 0,1 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,1 2,1 0,-2 -2,0 z m -2,-2 0,-2 -2,0 0,2 2,0 z"
+ style="fill:#c81700;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17714);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 385.51625,164.52217 0,-7.03525 5.49627,-2.01007 5.49628,2.01007 0,7.03525 -5.49628,3.01511 -5.49627,-3.01511 z"
+ id="path12069"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23022"
+ 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"
+ id="rect23020"
+ width="16"
+ height="16"
+ x="343"
+ y="237" />
+ <g
+ id="g9430"
+ transform="translate(19.991123,0.02506982)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path9432"
+ d="m 330.5,240.5 5,5 -5,5 -5,-5 5,-5 z"
+ style="fill:url(#linearGradient15436);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.85000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ <path
+ 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.5"
+ d="m 327,245.5 3.5,-3.5"
+ id="path9434"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23028"
+ transform="translate(18.067322,-17)">
+ <rect
+ y="237"
+ x="322.93268"
+ height="16"
+ width="16"
+ id="rect23018"
+ 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"
+ transform="translate(0.04112278,0.02506982)"
+ id="g12077">
+ <path
+ style="fill:url(#linearGradient52027);fill-opacity:1;fill-rule:nonzero;stroke:#341b00;stroke-width:0.85000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m 330.5,240.5 5,5 -5,5 -5,-5 5,-5 z"
+ id="path12079"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path12081"
+ d="m 327,245.5 3.5,-3.5"
+ 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.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23056"
+ transform="translate(118,4)">
+ <rect
+ y="216"
+ x="181"
+ height="16"
+ width="16"
+ id="rect23010"
+ 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,1,1,0,-56.06114,-164)"
+ id="g13176"
+ 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">
+ <path
+ id="path13178"
+ d="m 392.53018,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ style="opacity:0.2;fill:none;stroke:#ff982a;stroke-width:5;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="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.7;fill:none;stroke:#ff982a;stroke-width:3.5;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 392.5,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ id="path13180"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13182"
+ d="m 392.5,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ style="fill:url(#linearGradient52023);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient13639);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"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path13184"
+ d="m 389,244.5 2.5,-2.5"
+ style="opacity:0.9;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23048"
+ 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"
+ id="rect23012"
+ width="16"
+ height="16"
+ x="201"
+ y="215.03018" />
+ <g
+ transform="matrix(0,1,1,0,-35.015077,-166)"
+ id="g13216"
+ 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">
+ <path
+ id="path13218"
+ d="m 395.53018,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ style="opacity:0.2;fill:none;stroke:#ff982a;stroke-width:5;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="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.75;fill:none;stroke:#ff982a;stroke-width:3.5;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 395.5,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ id="path13220"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13222"
+ d="m 391.5,239.5312 -9,4 9,4 4,-4 -4,-4 z"
+ style="fill:url(#linearGradient52025);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient14661);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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path13224"
+ d="m 385,243.5312 6.25,-2.75"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23040"
+ transform="translate(36,4.96982)">
+ <rect
+ y="215.03018"
+ x="221"
+ height="16"
+ width="16"
+ id="rect23014"
+ 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"
+ 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="g13226"
+ transform="matrix(0,1,1,0,-15.015077,-166)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.2;fill:none;stroke:#ff982a;stroke-width:5;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 395.53018,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ id="path13228"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13230"
+ d="m 395.53018,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ style="opacity:0.75;fill:none;stroke:#ff982a;stroke-width:3.5;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="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient15993);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient15995);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 391.5,239.5312 -9,4 9,4 4,-4 -4,-4 z"
+ id="path13232"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 385,243.5312 6.25,-2.75"
+ id="path13234"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23034"
+ transform="translate(37,5)">
+ <rect
+ y="215"
+ x="241"
+ height="16"
+ width="16"
+ id="rect23016"
+ 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,1,1,0,4.9849228,-166)"
+ id="g13236"
+ 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">
+ <path
+ id="path13238"
+ d="m 391.5,239.5312 -9,4 9,4 4,-4 -4,-4 z"
+ style="fill:url(#linearGradient15997);fill-opacity:1;fill-rule:evenodd;stroke:#000000;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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path13240"
+ d="m 385,243.5312 6.25,-2.75"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23114"
+ transform="translate(-81,46)">
+ <rect
+ y="174"
+ x="401"
+ height="16"
+ width="16"
+ id="rect23112"
+ 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"
+ 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="g11747"
+ transform="matrix(0,1,1,0,163.98492,-206)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:url(#linearGradient15854);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.5,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ id="path11749"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 389,244.5 2.5,-2.5"
+ id="path11751"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23160"
+ 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"
+ id="rect23130"
+ width="16"
+ height="16"
+ x="364"
+ y="195" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10790"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient15681);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 364.48388,198.5 0,9 1,0 5,-3.75 0,3.75 1,0 5.01612,-3.71875 0,3.71875 2,0 0,-9 -2,0 0,3.71875 -5.01612,-3.71875 -1,0 0,3.75 -5,-3.75 -1,0 z"
+ id="path10792"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10794"
+ d="m 365.48388,206.5 0,-6.75 4.25,3.25"
+ style="fill:none;stroke:url(#linearGradient11764);stroke-width:0.99999952px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient11762);stroke-width:0.99999952px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 371.48388,206.5 0,-6.75 4.5,3.25"
+ id="path10796"
+ sodipodi:nodetypes="ccc"
+ 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:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 377.23388,206.75 0.0161,-7.5"
+ id="path10798"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path11760"
+ d="m 377.98388,200 -1.25,0 0,-1 1.25,0 0,1 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23168"
+ transform="translate(-315.95126,25)">
+ <rect
+ y="195"
+ x="382.95126"
+ height="16"
+ width="16"
+ id="rect23132"
+ 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.01597308,0.03124949)"
+ 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="g10800"
+ style="display:inline">
+ <g
+ id="g10802"
+ transform="matrix(-1,0,0,1,762.9688,2.086163e-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
+ style="fill:url(#linearGradient15683);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 365.53351,198.46875 -1,0 0,9 1,0 5,-3.75 0,3.75755 1,0 5.00539,-3.71875 0,3.71875 1.99461,0 0,-9 -1.99461,0 0,3.71875 -5.00539,-3.71875 -1,0 0,3.74245 -5,-3.75 z"
+ id="path10804"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path10806"
+ d="m 369.28351,202.71875 -3.5,-2.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 375.28351,202.71875 -3.5,-2.75"
+ id="path10808"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path10986"
+ d="m 377.03351,199.9763 1.25,0 0,-1 -1.25,0 0,1 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path10810"
+ d="m 385.18529,206.7263 0,-7.5"
+ 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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23154"
+ transform="translate(-317,25)">
+ <rect
+ y="195"
+ x="343"
+ height="16"
+ width="16"
+ id="rect23128"
+ 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="g10812"
+ transform="matrix(-2.196282,0,0,1.316799,1208.5661,-118.9575)"
+ 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="color:#000000;fill:url(#linearGradient37396-1);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.58802557px;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 392.96689,239.5639 -0.56915,0 -4.43932,4.36665 0,1.13912 4.43932,4.36665 0.56915,0 0,-9.87242 0,0 0,0 z"
+ id="path10814"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient11766);stroke-width:0.58802563px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.51157,248.2972 0,-7.97389 -4.09783,3.98695"
+ id="path10816"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23136"
+ 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"
+ id="rect23134"
+ width="16"
+ height="16"
+ x="283"
+ y="195" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10818"
+ style="display:inline">
+ <g
+ id="g10820"
+ transform="translate(0,8)">
+ <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"
+ ry="1.9320945"
+ rx="0"
+ y="286.5"
+ x="189.49994"
+ height="3"
+ width="11.000029"
+ id="rect10822"
+ style="fill:url(#linearGradient15687);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ transform="matrix(0,1,1,0,0,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="path10824"
+ d="m 287.5,199.27782 0,-8.77775 1,-7e-5"
+ style="fill:none;stroke:url(#linearGradient15689);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(6,8)"
+ id="g10826">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:url(#linearGradient15691);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect10828"
+ width="11.000029"
+ height="3"
+ x="189.49994"
+ y="286.5"
+ rx="0"
+ ry="1.9320945"
+ 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
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:url(#linearGradient15693);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 287.5,199.27782 0,-8.77775 1,-7e-5"
+ id="path10830"
+ 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>
+ </g>
+ <g
+ style="display:inline"
+ id="g23146"
+ 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"
+ id="rect23126"
+ width="16"
+ height="16"
+ x="323"
+ y="195" />
+ <g
+ style="display:inline"
+ id="g11898"
+ 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.714947,0,0,0.714947,237.35342,27.84315)">
+ <g
+ style="display:inline"
+ id="g11900"
+ 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">
+ <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="path11903"
+ style="fill:url(#linearGradient13543);fill-opacity:1;fill-rule:nonzero;stroke:#552200;stroke-width:1.77777624;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.847956,0,0,0.858716,59.65221,121.6111)" />
+ </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.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g11905"
+ style="fill:none;stroke:url(#linearGradient15878);stroke-width:1.65010214;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.780492,0,0,0.786646,68.5413,130.1431)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient13545);stroke-width:2.28401804;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path11907"
+ 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" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g24423">
+ <rect
+ y="220"
+ x="131"
+ height="16"
+ width="16"
+ id="rect23008"
+ 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"
+ transform="translate(-71.046377,45.90625)"
+ 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="g11015">
+ <path
+ style="fill:url(#linearGradient15744);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 205.54638,177.59375 -1,0 0,9 1,0 5,-3.75 0,3.75 1,0 5,-3.75 0,-1.5 -5,-3.75 -1,0 0,3.75 -5,-3.75 z"
+ id="path11017"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path11019"
+ d="m 205.54638,185.34375 0,-6.5 4.25,3.25"
+ style="fill:none;stroke:url(#linearGradient10982);stroke-width:1.10000002;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient10984);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 211.54638,185.34375 0,-6.5 4,3"
+ id="path11021"
+ sodipodi:nodetypes="ccc"
+ 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>
+ <g
+ style="display:inline"
+ id="g23235"
+ 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"
+ id="rect23226"
+ width="16"
+ height="16"
+ x="184"
+ y="174" />
+ <g
+ style="display:inline"
+ 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,0,0,1,402.07862,-0.09375)"
+ id="g11023">
+ <path
+ id="path11025"
+ d="m 205.57862,177.59375 -1,0 0,9 1,0 5,-3.75 0,3.75 1,0 5,-3.75 0,-1.5 -5,-3.75 -1,0 0,3.75 -5,-3.75 z"
+ style="fill:url(#linearGradient15746);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"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 209.57862,181.84375 -4,-3"
+ id="path11027"
+ sodipodi:nodetypes="cc"
+ 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"
+ sodipodi:nodetypes="cc"
+ id="path11029"
+ d="m 215.57862,181.84375 -4,-3"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </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">
+ <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)" />
+ <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="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"
+ sodipodi:type="arc"
+ transform="matrix(0.4812861,0,0,0.4822895,65.395173,166.1609)" />
+ </g>
+ </g>
+ <g
+ id="g16279"
+ transform="translate(318,7.00009)" />
+ <g
+ id="g28089"
+ transform="translate(0,2)">
+ <rect
+ y="260"
+ x="-315"
+ height="16"
+ width="16"
+ id="rect16267"
+ 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
+ id="g28079">
+ <g
+ id="g51539"
+ style="opacity:0.4">
+ <path
+ id="path51537"
+ d="m 300.5,270.5 5,4 0,1 2,0 0,-1 6,-4 1,0 0,-2 -2,0 0,1 -11,0 0,-1 -2,0 0,2 1,0 z"
+ style="fill:#ffffff;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccc"
+ d="m 299.5,268.5 0,2 2,10e-6 0,-2 -2,-10e-6 z m 13,0 0,2 2,10e-6 0,-2 -2,-10e-6 z m -7,4.99999 0,2 2,10e-6 0,-2 -2,-10e-6 z m 7,-3.99999 -11,0 m -0.75,1 4.75,3.878 m 2.08359,0.122 5.66641,-4"
+ style="fill:none;stroke:url(#linearGradient28077);stroke-width:0.99999952;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path16283"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g28004"
+ transform="translate(501,-139)">
+ <path
+ id="path16269"
+ d="m -200,401 12,0 -6.4,7.99999 L -200,401 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#162d50;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccc"
+ 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="path16271"
+ d="m -199.75,401 11.75,0 -6.5,7.99999 L -199.75,401 z"
+ style="fill:url(#linearGradient28057);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccc"
+ 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\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path16273"
+ d="m -189.5,401.5 -9.25,0 4.25,6.5"
+ style="opacity:0.87999998;fill:none;stroke:url(#linearGradient22970);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="rect16275"
+ width="2.0172491"
+ height="2.0328345"
+ x="-201.51724"
+ y="399.46716" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="rect16285"
+ width="2.0172396"
+ height="2.0000157"
+ x="-195.5"
+ y="408.49997" />
+ <rect
+ y="399.49997"
+ x="-188.51724"
+ height="2.0000157"
+ width="2.0172396"
+ id="rect16287"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
+ </g>
+ </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"
+ 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"
+ id="rect28314"
+ width="16"
+ height="16"
+ x="-293.99997"
+ y="280.99994"
+ transform="scale(-1,1)" />
+ <g
+ id="g28424">
+ <g
+ id="g28320"
+ transform="translate(318.99999,17.49994)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient24395);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -33,272.25 0,-7 6,2.75 0,7.25 -6,-3 z"
+ id="path28322"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28324"
+ d="m -33,272.25 0,-7 6,2.75 0,7.25 -6,-3 z"
+ style="fill:url(#linearGradient28532);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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path28326"
+ d="m -27.25,274.75 0,-6.5 -5.5,-2.5 0,6.25"
+ style="fill:none;stroke:url(#linearGradient28530);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g28414"
+ style="opacity:0.8"
+ transform="translate(0.25,0.25)">
+ <path
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.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"
+ d="m 280,285.25 5.5,-2.5"
+ id="path28410"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path28376"
+ d="m 280,285.25 5.5,-2.5"
+ style="fill:none;stroke:#ffc655;stroke-width:1px;stroke-linecap:round;stroke-linejoin:bevel;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.6"
+ id="g28418"
+ transform="translate(0,-7.5)">
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.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"
+ d="m 286.5,296 5.5,-3"
+ id="path28420"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28422"
+ d="m 286.5,296 5.5,-3"
+ style="fill:#ff8080;fill-rule:evenodd;stroke:#ffc655;stroke-width:1px;stroke-linecap:round;stroke-linejoin:bevel;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:#0b1728;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 279.99999,292.9999 0,-7 6,2.75004 0,7.25 -6,-3.00004 z"
+ id="path28328"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g28402"
+ style="opacity:0.8">
+ <path
+ id="path28398"
+ d="m 286.5,296 5.5,-3"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ff8080;fill-rule:evenodd;stroke:#ffc655;stroke-width:1px;stroke-linecap:round;stroke-linejoin:bevel;stroke-opacity:1;display:inline"
+ d="m 286.5,296 5.5,-3"
+ id="path28374"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-161.00001,168.99994)"
+ id="g28338">
+ <g
+ id="g28340">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path28342"
+ d="m 441,123.99996 0,-7 6,2.75004 0,7.25 -6,-3.00004 z"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#162d50;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path28344"
+ d="m 441.00001,124.00006 0,-7 6,2.74994 c 0,2.37037 0,6.72971 0,7.25 l -6,-2.99994 z"
+ style="fill:url(#linearGradient28474);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.09488797;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
+ style="fill:#22467e;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 441,117 0,2.25 2,0 0,-1.25 -2,-1 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,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,1.25 2,1 0,-2.25 -2,0 z m -2,-2 0,-2 -2,0 0,2 2,0 z"
+ id="path28346"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path28348"
+ d="m 446.75,126.5 0,-6.5 -5.5,-2.5 0,6.25 5.5,2.75 z"
+ style="fill:none;stroke:url(#linearGradient28528);stroke-width:0.75;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>
+ </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"
+ style="display:inline">
+ <rect
+ y="-183"
+ x="563"
+ height="16"
+ width="16"
+ id="rect12620"
+ 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="g12622">
+ <g
+ transform="translate(476.04566,-283.51773)"
+ id="g12624"
+ style="opacity:0.7">
+ <path
+ style="fill:none;stroke:#1a1a1a;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"
+ d="m 89.95451,104.01774 5,9.5 5,-9.5 -10,0 z"
+ id="path12626"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12628"
+ d="m 89.95451,103.98095 5,9.5 5,-9.5 -10,0 z"
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;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>
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect12630"
+ width="2.9998772"
+ height="3"
+ x="574.50031"
+ y="-181.49998"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-181.49998"
+ x="564.50043"
+ height="3"
+ width="2.9998772"
+ id="rect12632"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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:#000000;stroke-width:1.5;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="rect12634"
+ width="2.9998772"
+ height="3"
+ x="569.5"
+ y="-171.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <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="path12636"
+ d="m 577.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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 572.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="path12638"
+ 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;display:inline"
+ d="m 567.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="path12640"
+ 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>
+ </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"
+ transform="translate(-21,128)">
+ <rect
+ y="302"
+ x="-231"
+ height="16"
+ width="16"
+ id="rect12012"
+ 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
+ id="g12045">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.9;fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#2b1600;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 218,313.25 c -0.99997,-6.5 5.99997,-2.75 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ id="path12014"
+ 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"
+ id="path12016"
+ d="m 218,313.25 c -0.99997,-6.5 5.99997,-3.25 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ style="opacity:0.95;fill:#ff9f37;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:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.75;fill:url(#radialGradient12116);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218,313.25 c -0.99997,-6.5 5.99997,-3.25 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ id="path12020"
+ 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"
+ id="path12018"
+ d="m 218,313.25 c -0.99997,-6.5 5.99997,-3.25 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ style="opacity:0.7;fill:url(#linearGradient12114);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient12118);stroke-width:1;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 223.24994,304.5 4.25003,1.75 c 1,5.75 -5.50003,2 -5.08025,8.84783 l -4.04773,-2.23212"
+ id="path12022"
+ 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"
+ id="path12024"
+ d="m 223.24994,304.5 4.25003,1.75"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g12219"
+ transform="translate(-20.999998,128)">
+ <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="rect12147"
+ width="16.000032"
+ height="16"
+ x="-231.00003"
+ y="281" />
+ <g
+ transform="translate(235.00016,-1)"
+ id="g12149">
+ <g
+ id="g12151"
+ transform="translate(-376,510)"
+ style="opacity:0.8">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path12153"
+ d="m 358.99997,-216.75 c -0.99997,-6.5 6.00003,-2.75 5,-9.25 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="fill:none;stroke:#1a1a1a;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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#b3b3b3;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 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path12155"
+ 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"
+ style="opacity:0.7;fill:url(#linearGradient12213);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path12157"
+ 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"
+ id="path12159"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="opacity:0.75;fill:url(#radialGradient12215);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ 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="path12161"
+ d="m 364.24984,-225.5 4.25016,1.75 c 1,5.75 -5.50003,2 -5.08381,8.85761 l -4.04561,-2.26888"
+ style="fill:none;stroke:url(#linearGradient12217);stroke-width:1;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"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;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 364.24997,-225.5 4.25003,1.75"
+ id="path12163"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-399.2499,383.75)"
+ id="g12165">
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect12167"
+ width="2.9998772"
+ height="3"
+ x="391.75"
+ y="-99.25"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;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 394.24987,-98.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path12169"
+ 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>
+ <g
+ id="g12171"
+ transform="translate(-406.2499,380.75)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-98.25"
+ x="392.74988"
+ height="3"
+ width="2.9998772"
+ id="rect12173"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12175"
+ d="m 395.24974,-97.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.666663 0,1.333317 0,1.99999 0.66668,0 1.33333,-1e-5 2,-1e-5 0,-0.666663 0,-1.333327 0,-1.99999 z"
+ style="fill:#ffffff;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" />
+ </g>
+ <path
+ style="opacity:0.3;fill:#ffffff;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 -11.00003,286 c -0.66668,0 -1.33332,0 -2,0 0,-0.33334 0,-0.66666 0,-1 0.66668,0 1.33332,0 2,0 0,0.33334 0,0.66667 0,1 z"
+ id="path12177"
+ 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="path12179"
+ d="m -7.00003,285.53933 c -0.33334,0 -0.66666,10e-6 -1,10e-6 0,0.82281 0,1.64561 0,2.46844 0.33334,0 0.66666,-1e-5 1,-1e-5 0,-0.82282 0,-1.64562 0,-2.46844 l 0,0 0,0 0,0 z"
+ style="opacity:0.3;fill:#ffffff;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
+ 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="path12187"
+ d="m -9.972188,286 c -0.342621,0 -0.685221,0 -1.027842,0 0,-0.66873 0,-1.33742 0,-2.00616 0.342621,0 0.685221,0 1.027842,0 0,0.66874 0,1.33745 0,2.00616 z"
+ style="opacity:0.3;fill:#ffffff;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.3;fill:#ffffff;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 -6.000162,287 c -0.33334,0 -0.66666,0 -1,0 0,0.33428 0,0.66856 0,1.00284 0.33334,0 0.66666,0 1,0 0,-0.33428 0,-0.66856 0,-1.00284 z"
+ id="path12239"
+ 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>
+ </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"
+ transform="translate(0,2)">
+ <rect
+ y="260"
+ x="257"
+ height="16"
+ width="16"
+ id="rect28219"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999875;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24279">
+ <rect
+ transform="matrix(1,5.257811e-6,0,1,0,0)"
+ y="261.49863"
+ x="258.5"
+ height="7.007431"
+ width="6.9999733"
+ id="rect28121"
+ style="fill:url(#linearGradient24272);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.89999998;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g12274"
+ transform="translate(6.2265309e-7,0.00746971)">
+ <g
+ style="opacity:0.4"
+ id="g11480"
+ transform="matrix(1,0,0,-0.985055,81.000076,281.63418)">
+ <rect
+ transform="matrix(1,-5.3375811e-6,0,-1,0,0)"
+ y="-14.357183"
+ x="183.49992"
+ height="7.1213336"
+ width="7.000011"
+ id="rect11482"
+ style="fill:url(#linearGradient12305);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00755596;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.00755763px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 184.49992,8.2651727 0,5.0306663 5,0.04519"
+ id="path11484"
+ 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="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-0.985055,78.000075,278.62671)"
+ id="g11472">
+ <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"
+ style="fill:url(#linearGradient12307);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.90680158;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect11474"
+ width="6.9999948"
+ height="7.1137514"
+ x="183.49992"
+ y="-14.349599"
+ transform="matrix(1,-5.3375811e-6,0,-1,0,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="path11476"
+ d="m 184.49993,8.3103653 -1e-5,5.0230827 5,0"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.00755763px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <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"
+ style="fill:url(#linearGradient24277);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect24275"
+ width="6.8437233"
+ height="6.8198147"
+ x="258.65625"
+ y="261.68613"
+ transform="matrix(1,5.257811e-6,0,1,0,0)" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24268);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 259.5,267.5 0,-5 5,0 0,5 -5,0 z"
+ id="path28123"
+ 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
+ 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="path12295"
+ d="m 266.5,265.5 0,3.94801 -4,0"
+ style="opacity:0.2;fill:none;stroke:#162d50;stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ 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)" />
+ <g
+ id="g17375"
+ 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"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect17377"
+ width="16"
+ height="16"
+ x="162.99997"
+ y="237.5" />
+ <g
+ transform="translate(73,-319.5)"
+ id="g17379"
+ style="fill:#ffcc00;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline">
+ <path
+ style="fill:none;stroke:#2b1600;stroke-width:1.20000005;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ transform="translate(262.99997,326)"
+ id="rect17381"
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:#ffcc00;display:inline"
+ id="g17395"
+ transform="translate(73,-319.5)">
+ <path
+ style="fill:url(#linearGradient13699)"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ id="rect17397"
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ transform="translate(262.99997,326)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.85;fill:#ffffff;display:inline"
+ d="m 198,304 0,1 0.5,0 0,-1 -0.5,0 z m 1,1 0,10 0.65625,0 0,-10 L 199,305 z m 7,0 0,1 0.5,0 0,-1 -0.5,0 z m -2,4 0,1 0.5,0 0,-1 -0.5,0 z m 0,2 0,1 0.5,0 0,-1 -0.5,0 z m -6,4 0,1 0.5,0 0,-1 -0.5,0 z"
+ id="path17411"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ transform="translate(-31.000031,-64.5)"
+ 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"
+ transform="translate(289,331.00001)">
+ <rect
+ y="183"
+ x="-158"
+ height="16"
+ width="16"
+ id="rect14146"
+ 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(36,0)"
+ id="g14148">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path14151"
+ d="m -187,192 4,-4"
+ style="fill:none;stroke:#162d50;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m -191,198 0.76562,0.21876 4.73438,-4.71876 0,-3 -3,0 -4,4 -0.75,0.75 0.25,0.75 2,2 z"
+ style="fill:url(#linearGradient14167);fill-opacity:1;fill-rule:evenodd;stroke:#162d50;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path14153"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path14155"
+ d="m -190.5,197.5 -2,-2"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ id="path14157"
+ d="m -179.48388,187.51562 c 2.75,-1.75 -1.25,-5.75 -3,-3 L -183,186.5 l -1.48388,0.0156 -0.26612,0.73438 -0.73388,0.26562 0.98388,-0.0156 0,1 1,1 1,0 0.0161,1.01562 0.23388,-0.76562 0.76612,-0.23438 L -181.5,188 l 2.01612,-0.48438 z"
+ style="fill:url(#linearGradient14169);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient14171);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -186.5,191.5 2,-2"
+ id="path14159"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient14173);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -180,187.5 c 2.49911,-1.20238 -0.79146,-5.05796 -2.25,-2.75 l -0.75,1.75 -1.25,0.25 -0.75,0.75 2.75,2.75 0.75,-1 0,-1.25 1.5,-0.5 z"
+ id="path14161"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path14163"
+ d="M -180.23388,184.53124 C -181.75937,183.83967 -182,185 -182.5,186.75 l -1.98388,0.53124"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -192.5,195.5 4.26612,-4.23438 1.75,0 2,-2"
+ id="path14165"
+ inkscape:connector-curvature="0" />
+ </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"
+ 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="rect17322"
+ width="16"
+ height="16"
+ x="47"
+ y="29" />
+ <g
+ transform="translate(116,-325)"
+ id="g17324">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path17326"
+ d="m -55,358.25 -6,-2.25 -6,2.25 0,7.5 6,3.25 6,-3.25 0,-7.5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path17328"
+ d="m -55,365.75 0,-7.5 -6,2.75 c 0,2.58363 8.34e-4,7.47325 8.34e-4,8.04035 L -55,365.75 z"
+ style="fill:url(#linearGradient17337);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
+ sodipodi:nodetypes="ccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -67,365.75 0,-7.5 6,2.75 8.34e-4,8.04035 L -67,365.75 z"
+ id="path17330"
+ 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="path17332"
+ d="m -67,358.25 6,-2.25 6,2.25 -6,2.75 -6,-2.75 z"
+ style="fill:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17339);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -66.499841,365.52276 -66.5,358.5 l 5.5,-2 5.5,2 0,7 -5.5,3 -5.499841,-2.97724 z"
+ id="path17334"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g17610"
+ transform="translate(-20.999893,190.97867)"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="281.02133"
+ x="193.99989"
+ height="16"
+ width="16"
+ id="rect17612"
+ 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="g17614">
+ <rect
+ y="285.52133"
+ x="198.49976"
+ height="2"
+ width="8"
+ id="rect17616"
+ style="fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(191.9999,212.02134)"
+ id="g17618"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient17656);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 16.499049,83.47866 -12.999056,0 -10e-8,-12.97866 13.0114221,0 -0.01237,12.97866 4e-6,0 z"
+ id="path17620"
+ 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>
+ <rect
+ style="fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17622"
+ width="8"
+ height="2"
+ x="198.49976"
+ y="289.52136" />
+ <rect
+ y="283"
+ x="195.99989"
+ height="12"
+ width="12.000107"
+ id="rect17624"
+ style="opacity:0.1;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17626"
+ transform="translate(-31.00024,484.0498)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 237.5,-198.52846 0,1 -8.99987,0"
+ id="path17628"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path17630"
+ d="m 228.55567,-198.51423 8.88878,0"
+ style="fill:none;stroke:#4d4d4d;stroke-width:0.99999994px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g17632"
+ transform="translate(-16.999997,0.9739989)">
+ <rect
+ transform="scale(-1,1)"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:evenodd;stroke:#5f8dd3;stroke-width:0.99999982;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="rect17634"
+ width="2"
+ height="3.0120413"
+ x="-253.5"
+ y="-200.474" />
+ <path
+ id="path17636"
+ d="m 251.49999,-197.47154 2,0 0,-3"
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 251.99999,-196.47154 2.5,0 0,-3.5"
+ id="path17638"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g17640"
+ transform="translate(-31.00024,484.0498)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17642"
+ d="m 237.5,-192.60425 0,1 -8.99987,0.026"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 228.50013,-192.60425 8.99987,0.026"
+ id="path17644"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g17646"
+ transform="translate(-19.014593,0.97154)">
+ <rect
+ y="-194.51543"
+ x="-251.5"
+ height="2.9940825"
+ width="2.0000002"
+ id="rect17648"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:evenodd;stroke:#5f8dd3;stroke-width:0.99999994;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="scale(-1,1)" />
+ <path
+ id="path17650"
+ d="m 249.49999,-191.52134 2,0 0,-3"
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17652"
+ d="m 250.01459,-190.52134 2.5,0 0,-3.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ 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="path17654"
+ d="m 196.4999,294.5 0.0303,-11 11.01349,0 -0.0303,11 -11.01349,0 z"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient17658);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g13494"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(0,128.00001)">
+ <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"
+ style="fill:#e6e6e6;fill-opacity:0.23529412;fill-rule:nonzero;stroke:none"
+ id="rect16876"
+ width="8.0127983"
+ height="8.012805"
+ x="260.99997"
+ y="473.98718"
+ ry="0.4193894"
+ rx="0.4193894" />
+ <rect
+ ry="0.82841855"
+ y="473.48724"
+ x="260.50003"
+ height="9.0127392"
+ width="9.0127354"
+ id="rect16878"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient12658);stroke-width:1.00002468;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"
+ rx="0.82841796" />
+ <rect
+ rx="0.80560946"
+ 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="opacity:0.4;fill:none;stroke:url(#linearGradient12655);stroke-width:1.00002468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect16880"
+ width="9.0127354"
+ height="9.0127392"
+ x="-269.51276"
+ y="-482.5"
+ ry="0.83038348"
+ transform="scale(-1,-1)" />
+ </g>
+ <g
+ id="g28870"
+ 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"
+ transform="translate(0,128.00001)">
+ <g
+ transform="translate(20.999991,0)"
+ id="g13503">
+ <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"
+ style="fill:#e6e6e6;fill-opacity:0.23529412;fill-rule:nonzero;stroke:none"
+ id="rect13505"
+ width="8.0127983"
+ height="8.012805"
+ x="260.99997"
+ y="473.98718"
+ ry="0.4193894"
+ rx="0.4193894" />
+ <rect
+ ry="0.82841855"
+ y="473.48724"
+ x="260.50003"
+ height="9.0127392"
+ width="9.0127354"
+ id="rect13507"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient13511);stroke-width:1.00002468;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"
+ rx="0.82841796" />
+ <rect
+ rx="0.80560946"
+ 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="opacity:0.4;fill:none;stroke:url(#linearGradient13513);stroke-width:1.00002468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect13509"
+ width="9.0127354"
+ height="9.0127392"
+ x="-269.51276"
+ y="-482.5"
+ ry="0.83038348"
+ transform="scale(-1,-1)" />
+ </g>
+ <path
+ d="m 283.5,478.5 1.99999,2 m 3.75,-4.75 c -1.28654,1.14367 -2.78042,2.75628 -3.75,4.75"
+ style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ id="path16507"
+ 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" />
+ <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" />
+ </g>
+ </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"
+ 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="rect18695"
+ width="16"
+ height="16"
+ x="236"
+ y="260" />
+ <g
+ id="g18697"
+ 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"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18719"
+ 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(#linearGradient18721);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"
+ transform="translate(179,-179)">
+ <path
+ id="path18707"
+ d="m 146.0019,73.295281 5,-1.894157 5,1.894157 -5,2.073959 -5,-2.073959 z"
+ style="fill:url(#linearGradient18728);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"
+ d="m 335,-105.5 -5,2 0,6.75 5,-2.75 0,-6 z"
+ style="fill:url(#linearGradient18765);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path18709"
+ 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(#linearGradient18712);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18758"
+ 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"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g14548"
+ transform="translate(0,23)">
+ <rect
+ y="239"
+ x="152"
+ height="16"
+ width="16"
+ id="rect14326"
+ 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="g14538">
+ <path
+ sodipodi:nodetypes="css"
+ id="path14330"
+ d="m 155.51612,249.67445 c 0,3.70073 8,3.70073 8,0 0,-2.71386 -4,-1.727 -4,-5.67444"
+ style="fill:none;stroke:#0b1728;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ 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"
+ sodipodi:ry="1.25"
+ sodipodi:rx="1.75"
+ sodipodi:cy="125"
+ sodipodi:cx="91.5"
+ id="path14332"
+ style="fill:#e6e6e6;fill-opacity:1;stroke:#0b1728;stroke-width:2.74424219;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient14568);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 155.51612,249.75002 c 0,3.75 8,3.75 8,0 0,-2.75 -4,-1.75 -4,-5.75"
+ id="path14334"
+ sodipodi:nodetypes="css"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;stroke:url(#linearGradient14570);stroke-width:1.28417933;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path14336"
+ sodipodi:cx="91.5"
+ 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"
+ 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"
+ sodipodi:ry="1.25"
+ sodipodi:rx="1.75"
+ sodipodi:cy="125"
+ sodipodi:cx="91.5"
+ id="path14338"
+ style="fill:none;stroke:url(#linearGradient14572);stroke-width:1.28417933;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ sodipodi:type="arc" />
+ <rect
+ y="241"
+ x="158.99884"
+ height="2"
+ width="2.0011597"
+ id="rect14340"
+ style="opacity:0.75;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" />
+ <path
+ sodipodi:nodetypes="cs"
+ id="path14342"
+ d="m 155.95084,249.59135 c 0,3.34488 7.13055,3.34488 7.13055,0"
+ style="opacity:0.45;fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(349,127.99988)"
+ id="g26256">
+ <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"
+ width="16"
+ height="16"
+ x="-29"
+ y="491.00012" />
+ <g
+ id="g26260">
+ <g
+ id="g26262">
+ <path
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26264"
+ 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"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26266"
+ style="fill:none;stroke:#28170b;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path26268"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -9.5,6 6,-6"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26270"
+ style="fill:none;stroke:url(#linearGradient26282);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -27.5,502.5 l 6,-6 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient26284);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26272"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path26274"
+ sodipodi:cx="13.5"
+ 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"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26276"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient26286);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26278"
+ sodipodi:cx="13.5"
+ 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"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -7.704183,9.08552 4.25,-4.25 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient26288);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path26280"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g15201"
+ 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"
+ id="rect15183"
+ width="16"
+ height="16"
+ x="215"
+ y="365" />
+ <g
+ id="g15185"
+ transform="translate(167.99999,-62.999991)">
+ <rect
+ y="429.54614"
+ x="48.499996"
+ height="12.953857"
+ width="13.016124"
+ id="rect15187"
+ style="fill:#ececec;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(#linearGradient15195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15189"
+ width="11.000001"
+ height="11.046139"
+ x="50.016117"
+ y="430" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ id="path15191"
+ d="m 49,430 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,0 0,3 3,0 0,-3 -3,0 z m 0,3 -3,0 0,3 3,0 0,-3 z m 0,3 0,3 3,0 0,-3 -3,0 z m -3,0 -3,0 0,3 3,0 0,-3 z m -3,0 0,-3 -3,0 0,3 3,0 z"
+ style="fill:url(#linearGradient15209);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" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15193"
+ d="m 60.517703,430.5 -11.017704,0 0,11 11.017704,0 0,-11"
+ style="fill:none;stroke:url(#linearGradient15211);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-174.00091,22.99815)"
+ id="g15532" />
+ <g
+ id="g15356"
+ transform="translate(-21,128.00001)">
+ <rect
+ y="344"
+ x="89"
+ height="16"
+ width="16"
+ id="rect15319"
+ 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="g15351">
+ <rect
+ y="345.50153"
+ x="90.5"
+ height="12.998481"
+ width="13"
+ id="rect15323"
+ style="fill:url(#linearGradient15363);fill-opacity:1;fill-rule:nonzero;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: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
+ sodipodi:nodetypes="ccc"
+ id="path15326"
+ d="m 91.499805,357.49999 0,-10.99829 11.000195,0 0,10.99829 -11.000195,0 z"
+ style="fill:none;stroke:url(#linearGradient15365);stroke-width:0.99999982px;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"
+ 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"
+ sodipodi:nodetypes="cszzcc"
+ id="path15332"
+ d="m 103.5,353.27516 c -0.37083,-1.1875 -1.21031,-1.72293 -1.9,-1.72929 -1.39235,-0.0134 -1.47709,3.98814 -2.999997,4 -1.491657,0.0119 -2.001315,-7 -3.5,-7 -1.52993,-10e-4 -1.18608,5.00645 -3.5,4.97929 l -1,0"
+ style="fill:none;stroke:url(#linearGradient15367);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ 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">
+ <rect
+ y="237.5"
+ x="162.99997"
+ height="16"
+ width="16"
+ id="rect15371"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <g
+ style="fill:#ffcc00;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline"
+ id="g15373"
+ transform="translate(73,-319.5)">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ id="path15375"
+ transform="translate(262.99997,326)"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(73,-319.5)"
+ id="g15377"
+ style="fill:#ffcc00;display:inline">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ id="path15379"
+ transform="translate(262.99997,326)"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ style="fill:url(#linearGradient15383)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="translate(-31.000031,-64.5)"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ id="path15381"
+ d="m 198,304 0,1 0.5,0 0,-1 -0.5,0 z m 1,1 0,10 0.65625,0 0,-10 L 199,305 z m 7,0 0,1 0.5,0 0,-1 -0.5,0 z m -2,4 0,1 0.5,0 0,-1 -0.5,0 z m 0,2 0,1 0.5,0 0,-1 -0.5,0 z m -6,4 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="opacity:0.85;fill:#ffffff;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g14355"
+ transform="translate(0,128.00001)">
+ <rect
+ y="428"
+ x="68"
+ height="16"
+ width="16"
+ id="rect14357"
+ 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="g14359"
+ 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="translate(-15.161301,338)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="czszcccc"
+ id="path14368"
+ 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:7.40000034;display:inline"
+ d="m 86.5,100.53983 4.342131,0.008 c 5.188235,0.0101 5.335295,-2.04831 3.335293,-4.04831 -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 86.5,100.53983 4.342131,0.008 C 96.03037,100.55844 96.17743,98.5 94.177424,96.5 c -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ style="fill:none;stroke:url(#linearGradient14377);stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path14375"
+ sodipodi:nodetypes="czszcccc"
+ inkscape:connector-curvature="0" />
+ </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"
+ 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"
+ id="rect16520"
+ width="16"
+ height="16"
+ x="110"
+ y="492"
+ rx="0"
+ ry="0" />
+ <g
+ id="g16522">
+ <rect
+ ry="1.7356256"
+ y="494.5"
+ x="110.5"
+ height="12"
+ width="15"
+ id="rect16524"
+ style="fill:url(#linearGradient16638);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
+ sodipodi:nodetypes="ccccccccc"
+ id="path16527"
+ d="M 111,498.48148 111,504 c 0,0.56404 0.36784,1.00001 0.84375,1 l 12.3125,0 C 124.63216,505 125,504.56405 125,504 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(#linearGradient16640);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="rect16530"
+ width="15"
+ height="2"
+ x="110.5"
+ y="494.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="rect16532"
+ width="15"
+ height="12"
+ x="110.5"
+ y="494.5"
+ ry="1.503511"
+ rx="1.503511" />
+ <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="path16535"
+ 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,11.18333,-121.72474)" />
+ <rect
+ rx="0.5078125"
+ ry="0.4910686"
+ y="495.5"
+ x="111.5"
+ height="10"
+ width="13.000001"
+ id="rect16537"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path16540"
+ 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="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient16642);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="path16542"
+ 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,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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path16544"
+ 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(#linearGradient16644);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="path16546"
+ 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,57.870479,107.05649)" />
+ <g
+ id="g16548"
+ transform="matrix(0.7547901,0,0,1,59.021765,-1)">
+ <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="path16550"
+ 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.7901234,0,0,0.2000006,9.8760061,395.5997)" />
+ <path
+ sodipodi:nodetypes="csccc"
+ id="path16554"
+ 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="rect16556"
+ width="2.6497433"
+ height="1"
+ x="70.189362"
+ y="495" />
+ </g>
+ <rect
+ y="496.5"
+ x="122"
+ height="1.5"
+ width="2"
+ id="rect16558"
+ 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(#radialGradient16646);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16562"
+ width="2"
+ height="1.5"
+ x="122"
+ y="496.5" />
+ <rect
+ y="497"
+ x="115"
+ height="1"
+ width="1"
+ id="rect16564"
+ 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" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient16648);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="path16566"
+ 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,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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path16568"
+ style="fill:url(#radialGradient16650);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
+ 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="path16570"
+ 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,103.0926,401.10045)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#radialGradient32447);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32441"
+ 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.8867575,0.06148883,-0.06130315,-0.8840797,219.44126,941.51187)" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21847"
+ transform="translate(24,422.99999)"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21291"
+ width="16"
+ height="16"
+ x="464"
+ y="7"
+ rx="0"
+ ry="0" />
+ <g
+ id="g21822">
+ <rect
+ ry="1.5909902"
+ y="10.5"
+ x="465.5"
+ height="10"
+ width="12"
+ id="rect21295"
+ style="fill:url(#linearGradient21776);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5909902" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path21297"
+ d="m 465.46685,13.40909 0,4.59375 c 0,0.56244 0.34142,0.99717 0.78315,0.99716 l 10.5,0.01065 c 0.44173,0 0.78315,-0.43471 0.78315,-0.99716 l 0,-4.59375 c -0.29118,0.37073 -0.71398,0.59091 -1.16022,0.59091 L 466.62707,14 c -0.44624,0 -0.86904,-0.22018 -1.16022,-0.59091 l 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient21773);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.362712"
+ 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="rect21299"
+ width="12"
+ height="2.0056314"
+ x="465.5"
+ y="10.494369"
+ ry="1.0028157" />
+ <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="rect21301"
+ width="12"
+ height="10"
+ x="465.5"
+ y="10.5"
+ ry="1.3782184"
+ rx="1.3782184" />
+ <rect
+ rx="0.39062494"
+ ry="0.44196323"
+ y="11.5"
+ x="466.5"
+ height="7.999999"
+ width="9.9998779"
+ id="rect21303"
+ 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="g21305"
+ transform="matrix(0.7547901,0,0,1,414.01868,-484.99999)">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#999999;stroke-width:2.90780973;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="path21307"
+ 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.7834486,0,0,0.2000006,10.413535,395.5997)" />
+ <path
+ sodipodi:nodetypes="csccc"
+ id="path21309"
+ d="m 69.531013,495.51105 0,-0.50001 c 0,-0.276 0.890314,-0.5 1.987308,-0.5 1.096993,0 1.987307,0.224 1.987307,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="rect21311"
+ width="2.6497409"
+ height="1"
+ x="70.193451"
+ y="495.01105" />
+ </g>
+ <g
+ transform="matrix(1,0,0,0.6666667,331,-319.00002)"
+ id="g21313">
+ <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="rect21315"
+ width="2"
+ height="1.5"
+ x="143"
+ y="496.5" />
+ <rect
+ y="496.5"
+ x="143"
+ height="1.5"
+ width="2"
+ id="rect21317"
+ style="fill:url(#radialGradient21741);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ y="13"
+ x="468"
+ height="1"
+ width="1"
+ id="rect21319"
+ 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" />
+ <g
+ id="g21804"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21323"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89240623;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.25;fill:none;stroke:#000000;stroke-width:0.71801031;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="path21325"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21327"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient21814);stroke-width:1.11641002;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:1.00804472;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="path21329"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21331"
+ style="fill:none;stroke:url(#linearGradient21816);stroke-width:1.69505489;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(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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21333"
+ style="fill:none;stroke:url(#radialGradient21818);stroke-width:0.80110824;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:url(#radialGradient21820);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path21335"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21337"
+ style="opacity:0.2;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" />
+ <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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22185"
+ style="opacity:0.7;fill:url(#radialGradient22187);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
+ style="opacity:0.05;fill:none;stroke:#ffffff;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 476.49997,11.941967 0,7.174103"
+ id="rect21642"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(45,422.99999)"
+ id="g22102"
+ style="opacity:0.25;display:inline">
+ <rect
+ ry="0"
+ rx="0"
+ y="7"
+ x="464"
+ height="16"
+ width="16"
+ id="rect22104"
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22106">
+ <rect
+ style="fill:url(#linearGradient22154);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22108"
+ width="12"
+ height="10"
+ x="465.5"
+ y="10.5"
+ ry="1.5909902"
+ rx="1.5909902" />
+ <path
+ style="fill:url(#linearGradient22156);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 465,13.40909 0,4.59375 c 0,0.56244 0.36784,0.99717 0.84375,0.99716 l 11.3125,0.01065 c 0.47591,0 0.84375,-0.43471 0.84375,-0.99716 l 0,-4.59375 c -0.31371,0.37073 -0.76923,0.59091 -1.25,0.59091 L 466.25,14 c -0.48077,0 -0.93629,-0.22018 -1.25,-0.59091 l 0,0 0,0 0,0 z"
+ id="path22110"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="1"
+ y="10.494369"
+ x="465"
+ height="2"
+ width="13"
+ id="rect22112"
+ 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.4762714" />
+ <rect
+ ry="1.3782184"
+ y="10.5"
+ x="465.5"
+ height="10"
+ width="12"
+ id="rect22114"
+ style="fill:none;stroke:#000000;stroke-width:1;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"
+ rx="1.3782184" />
+ <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="rect22116"
+ width="9.9998779"
+ height="7.999999"
+ x="466.5"
+ y="11.5"
+ ry="0.44196323"
+ rx="0.39062494" />
+ <g
+ transform="matrix(0.7547901,0,0,1,414.01868,-484.99999)"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22120"
+ style="fill:none;stroke:#999999;stroke-width:2.90780973;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
+ 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.531013,495.51105 0,-0.50001 c 0,-0.276 0.890314,-0.5 1.987308,-0.5 1.096993,0 1.987307,0.224 1.987307,0.5 l 0,0.50001"
+ id="path22122"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="495.01105"
+ x="70.193451"
+ height="1"
+ width="2.6497409"
+ id="rect22124"
+ 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
+ id="g22126"
+ transform="matrix(1,0,0,0.6666667,331,-319.00002)">
+ <rect
+ y="496.5"
+ x="143"
+ height="1.5"
+ width="2"
+ id="rect22128"
+ 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(#radialGradient22158);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22130"
+ width="2"
+ height="1.5"
+ x="143"
+ y="496.5" />
+ </g>
+ <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="rect22132"
+ width="1"
+ height="1"
+ x="468"
+ y="13" />
+ <g
+ transform="translate(1.1408497e-7,0.5000446)"
+ id="g22134">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89240623;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="path22136"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22138"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.71801031;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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient22160);stroke-width:1.11641002;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="path22140"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22142"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:1.00804472;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(#linearGradient22162);stroke-width:1.69505489;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="path22144"
+ 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.591154,0,0,0.5887513,425.87219,-279.05319)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient22164);stroke-width:0.80110824;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="path22146"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22148"
+ style="fill:url(#radialGradient22166);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
+ 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="path22150"
+ 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,456.07844,-84.89955)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22152"
+ d="m 476.49997,11.941967 0,7.174103"
+ style="opacity:0.05;fill:none;stroke:#ffffff;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-272,478.06251)"
+ id="g30185"
+ style="opacity:0.98000004;display:inline"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="-48"
+ x="403"
+ height="16"
+ width="16"
+ id="rect30187"
+ 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" />
+ <path
+ transform="matrix(1.3340954,0,0,1.3333333,-178.16901,-188.16667)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#2b1600;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30189"
+ sodipodi:cx="443.5"
+ 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" />
+ <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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30191"
+ style="fill:none;stroke:#2b1600;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30193"
+ style="fill:url(#linearGradient24132);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccc"
+ id="path30195"
+ d="m 409.5,-39.50001 -2,2.000003 -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 -4,-1e-5 0,0 0,0 0,0 z"
+ style="fill:#f89a35;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="8.1340281"
+ sodipodi:start="3.0449434"
+ transform="matrix(1.0812107,0,0,1.082338,-66.018179,-160.93645)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30231);stroke-width:0.92440742;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30197"
+ sodipodi:cx="443.5"
+ 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" />
+ <path
+ transform="matrix(1.1662469,0,0,1.1666676,-109.73384,-169.08343)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30233);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30199"
+ sodipodi:cx="443.5"
+ 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" />
+ <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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30201"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30235);stroke-width:0.9380942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.0655819,0,0,1.0664004,-65.085308,-158.20716)" />
+ <rect
+ y="-41"
+ x="409"
+ height="2.0000005"
+ width="4.0000658"
+ id="rect30203"
+ style="fill:#c8955e;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(0.3352674,0,0,0.3357219,258.80309,-78.928541)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30237);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30205"
+ sodipodi:cx="443.5"
+ 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" />
+ <rect
+ y="-43"
+ x="407"
+ height="1.0000002"
+ width="1"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30209"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30239);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.3352674,0,0,0.3357219,264.80311,-79.91866)" />
+ <rect
+ 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"
+ id="rect30211"
+ width="1"
+ height="1.0000002"
+ x="413.00003"
+ y="-43.99012" />
+ <rect
+ y="-37"
+ x="413"
+ height="2"
+ width="3.99542"
+ id="rect30213"
+ style="fill:url(#linearGradient30241);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30215"
+ d="m 416.49542,-37 1.5,-1 0,4 -1.5,-1 0,-2 z"
+ style="fill:url(#linearGradient30243);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30217"
+ d="m 415.99542,-37 1,-0.5 0,3 -1,-0.5 0,-2 z"
+ style="fill:url(#linearGradient30245);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" />
+ <path
+ style="fill:url(#linearGradient30247);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 413,-37 1,0 0,2 -1,0 0,-2 z"
+ id="path30219"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path30221"
+ d="m 409.75,-38.5 2.75,0 0,4 -4,0 0,-2.75 1.25,-1.25 z"
+ style="fill:#ec8f2c;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient30249);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="1.2544428"
+ y="-37.821297"
+ x="407"
+ height="2.6761446"
+ width="2.8293107"
+ id="rect30223"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient20217);stroke-width:1.00000024;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"
+ rx="1.2544428" />
+ <rect
+ style="fill:#ffdbb5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30225"
+ width="3"
+ height="1"
+ x="406"
+ y="-37.000008" />
+ <rect
+ style="fill:#634321;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30227"
+ width="4"
+ height="1"
+ x="409"
+ y="-40" />
+ </g>
+ <g
+ style="opacity:0.98000004;display:inline"
+ id="g30282"
+ 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"
+ id="rect30284"
+ width="16"
+ height="16"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30286"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.3340954,0,0,1.3333333,-178.16901,-188.16667)" />
+ <path
+ transform="matrix(1.3340954,0,0,1.3333333,-184.1736,-187.16666)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30288"
+ sodipodi:cx="443.5"
+ 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" />
+ <path
+ transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30326);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30290"
+ sodipodi:cx="443.5"
+ 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" />
+ <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"
+ id="path30292"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30294"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30328);stroke-width:0.92440742;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.0812107,0,0,1.082338,-66.018179,-160.93645)"
+ sodipodi:start="3.0449434"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30296"
+ style="fill:url(#linearGradient30330);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.1662469,0,0,1.1666676,-109.73384,-169.08343)" />
+ <path
+ transform="matrix(1.0655819,0,0,1.0664004,-65.085308,-158.20716)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30332);stroke-width:0.9380942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30298"
+ sodipodi:cx="443.5"
+ 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"
+ sodipodi:start="0.96146912"
+ sodipodi:end="5.930273"
+ sodipodi:open="true" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30300"
+ width="4.0000658"
+ height="2.0000005"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30302"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30334);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.3352674,0,0,0.3357219,258.80309,-78.928541)" />
+ <rect
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30304"
+ width="1"
+ height="1.0000002"
+ x="407"
+ y="-43" />
+ <path
+ transform="matrix(0.3352674,0,0,0.3357219,264.80311,-79.91866)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30336);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30306"
+ sodipodi:cx="443.5"
+ 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" />
+ <rect
+ y="-43.99012"
+ x="413.00003"
+ height="1.0000002"
+ width="1"
+ id="rect30308"
+ style="fill:#333333;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(#linearGradient30338);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30310"
+ width="3.99542"
+ height="2"
+ x="413"
+ y="-37" />
+ <path
+ style="fill:url(#linearGradient30340);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 416.49542,-37 1.5,-1 0,4 -1.5,-1 0,-2 z"
+ id="path30312"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient30342);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.99542,-37 1,-0.5 0,3 -1,-0.5 0,-2 z"
+ id="path30314"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30316"
+ d="m 413,-37 1,0 0,2 -1,0 0,-2 z"
+ style="fill:url(#linearGradient30344);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" />
+ <path
+ style="fill:none;stroke:url(#linearGradient30346);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 409.75,-38.5 2.75,0 0,4 -4,0 0,-2.75 1.25,-1.25 z"
+ id="path30318"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient30348);stroke-width:1.00000024;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"
+ id="rect30320"
+ width="2.8293107"
+ height="2.6761446"
+ x="407"
+ y="-37.821297"
+ ry="1.2544428"
+ rx="1.2544428" />
+ <rect
+ y="-37.000008"
+ x="406"
+ height="1"
+ width="3"
+ id="rect30322"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-40"
+ x="409"
+ height="1"
+ width="4"
+ id="rect30324"
+ 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>
+ <g
+ style="opacity:0.98000004;display:inline"
+ id="g30350"
+ 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"
+ id="rect30352"
+ width="16"
+ height="16"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30354"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.3340954,0,0,1.3333333,-178.16901,-188.16667)" />
+ <path
+ transform="matrix(1.3340954,0,0,1.3333333,-184.1736,-187.16666)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30356"
+ sodipodi:cx="443.5"
+ 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" />
+ <path
+ transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30394);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30358"
+ sodipodi:cx="443.5"
+ 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" />
+ <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"
+ id="path30360"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30362"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30396);stroke-width:0.92440742;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.0812107,0,0,1.082338,-66.018179,-160.93645)"
+ sodipodi:start="3.0449434"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30364"
+ style="fill:url(#linearGradient30398);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.1662469,0,0,1.1666676,-109.73384,-169.08343)" />
+ <path
+ transform="matrix(1.0655819,0,0,1.0664004,-65.085308,-158.20716)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30400);stroke-width:0.9380942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30366"
+ sodipodi:cx="443.5"
+ 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"
+ sodipodi:start="0.96146912"
+ sodipodi:end="5.930273"
+ sodipodi:open="true" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30368"
+ width="4.0000658"
+ height="2.0000005"
+ 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"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30370"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30402);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.3352674,0,0,0.3357219,258.80309,-78.928541)" />
+ <rect
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30372"
+ width="1"
+ height="1.0000002"
+ x="407"
+ y="-43" />
+ <path
+ transform="matrix(0.3352674,0,0,0.3357219,264.80311,-79.91866)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30404);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30374"
+ sodipodi:cx="443.5"
+ 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" />
+ <rect
+ y="-43.99012"
+ x="413.00003"
+ height="1.0000002"
+ width="1"
+ id="rect30376"
+ style="fill:#333333;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(#linearGradient30406);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30378"
+ width="3.99542"
+ height="2"
+ x="413"
+ y="-37" />
+ <path
+ style="fill:url(#linearGradient30408);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 416.49542,-37 1.5,-1 0,4 -1.5,-1 0,-2 z"
+ id="path30380"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient30410);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.99542,-37 1,-0.5 0,3 -1,-0.5 0,-2 z"
+ id="path30382"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30384"
+ d="m 413,-37 1,0 0,2 -1,0 0,-2 z"
+ style="fill:url(#linearGradient30412);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" />
+ <path
+ style="fill:none;stroke:url(#linearGradient30414);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 409.75,-38.5 2.75,0 0,4 -4,0 0,-2.75 1.25,-1.25 z"
+ id="path30386"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient30416);stroke-width:1.00000024;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"
+ id="rect30388"
+ width="2.8293107"
+ height="2.6761446"
+ x="407"
+ y="-37.821297"
+ ry="1.2544428"
+ rx="1.2544428" />
+ <rect
+ y="-37.000008"
+ x="406"
+ height="1"
+ width="3"
+ id="rect30390"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-40"
+ x="409"
+ height="1"
+ width="4"
+ 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)">
+ <g
+ id="g17368"
+ transform="translate(16,-32)">
+ <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(#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" />
+ <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" />
+ </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"
+ transform="translate(9.471,32.00923)">
+ <rect
+ y="-22.009235"
+ x="226.52901"
+ height="16"
+ width="16"
+ id="rect17382"
+ 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="-20.509235"
+ x="228.04515"
+ height="13"
+ width="12.983856"
+ id="rect17384"
+ style="fill:url(#linearGradient32749);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" />
+ <rect
+ transform="translate(271.529,-379.00923)"
+ style="fill:url(#linearGradient32751);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17387"
+ width="12"
+ height="12"
+ x="-43"
+ y="359"
+ mask="url(#mask17570)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17389"
+ d="m 240.029,-19.509225 -10.98386,0 0,11.0000002 10.98384,-10e-6 0,-11.0000002"
+ style="fill:none;stroke:url(#linearGradient32753);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" />
+ </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"
+ 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"
+ id="rect18439"
+ width="16"
+ height="16"
+ x="-124"
+ y="325"
+ rx="0"
+ ry="0" />
+ <g
+ transform="translate(-11,154.99966)"
+ id="g18441"
+ style="opacity:0.7">
+ <g
+ transform="translate(-99,-97.999673)"
+ id="g18443"
+ style="display:inline">
+ <g
+ transform="translate(41.011415,162)"
+ style="display:inline"
+ id="g18445">
+ <g
+ transform="translate(-80,-48)"
+ id="g18447">
+ <path
+ style="fill:#d7d7d7;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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 36.488585,166.3823 -0.25,1.1177 -9.499995,0 -1.25,-1.25 -5e-6,-10.75 11,0 0,10.8823 z"
+ id="path18449"
+ 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
+ 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="path18451"
+ d="m 34.988585,166.00001 -8,0 0,-1.00001 8,0 0,1.00001 z"
+ style="fill:#4d4d4d;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
+ 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="path18453"
+ d="m 35.47469,156.50008 -8.986105,-8e-5 5e-6,10 8.999995,0 -0.01389,-9.99992 -5e-6,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient17177);stroke-width:0.99999923px;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="ccccc"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="165.00002"
+ x="27.988585"
+ height="1.0000023"
+ width="1"
+ id="rect18455"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1,0,0,-1,0,320)"
+ id="g18457"
+ style="fill:#ee0000;fill-opacity:1" />
+ </g>
+ </g>
+ </g>
+ <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="path18459"
+ d="m -101,181 -10,0 0,-8 10,0 0,8 z"
+ style="opacity:0.5;fill:url(#radialGradient17179);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-11,154.99966)"
+ id="g18461">
+ <g
+ id="g18463"
+ transform="translate(-347,193.00032)">
+ <path
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#e1e1e1;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 246.5,-15.5 c -1.65264,0 -3,1.347359 -3,3 l 0,2 c 0,1.6526411 1.34737,3 3,3 l 0,0 c 1.65264,0 3,-1.3473589 3,-3 l -0.0312,-1.96875 c 0,-1.652641 -1.31612,-3.03125 -2.96875,-3.03125 l 0,0 -5e-5,0 z m 0,2 c 0.554,0 1,0.446 1,1 l 0,2 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-2 c 0,-0.554 0.446,-1 1,-1 z"
+ id="path18465"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18467"
+ d="m 246.5,-19.5 c -1.65264,0 -3,1.347359 -3,3 l 0,2 c 0,1.652641 1.34737,3 3,3 l 0,0 c 1.65264,0 3,-1.347359 3,-3 l 0,-2 c 0,-1.652641 -1.34737,-3 -3,-3 l 0,0 z m 0,2 c 0.554,0 1,0.446 1,1 l 0,2 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-2 c 0,-0.554 0.446,-1 1,-1 z"
+ style="fill:url(#radialGradient17181);fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(6,0)"
+ clip-path="url(#clipPath17188)"
+ id="path18473"
+ d="m 240.5,-15.5 c -1.65264,0 -3,1.347359 -3,3 l 0,2 c 0,1.6526411 1.34737,3 3,3 l 0,0 c 1.65264,0 3,-1.3473589 3,-3 l -0.0312,-1.96875 c 0,-1.652641 -1.31612,-3.03125 -2.96875,-3.03125 l 0,0 -5e-5,0 z m 0,2 c 0.554,0 1,0.446 1,1 l 0,2 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-2 c 0,-0.554 0.446,-1 1,-1 z"
+ style="fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-14.06875"
+ x="244"
+ height="2.5"
+ width="1"
+ id="rect18475"
+ style="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" />
+ <rect
+ style="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"
+ id="rect18477"
+ width="1"
+ height="1"
+ x="245"
+ y="-15.06875" />
+ </g>
+ <g
+ id="g18479" />
+ </g>
+ </g>
+ <g
+ id="g18489"
+ transform="translate(287,-54.93125)">
+ <g
+ id="g18491"
+ transform="translate(0,-3.2e-4)"
+ style="opacity:0.7">
+ <g
+ style="display:inline"
+ id="g18493"
+ transform="translate(-79,-97.999673)">
+ <g
+ id="g18495"
+ style="display:inline"
+ transform="translate(41.011415,162)">
+ <g
+ id="g18497"
+ transform="translate(-80,-48)">
+ <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"
+ id="path18499"
+ d="m 36.488585,166.3823 -0.25,1.1177 -9.499995,0 -1.25,-1.25 -5e-6,-10.75 11,0 0,10.8823 z"
+ style="fill:#d7d7d7;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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#4d4d4d;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 34.988585,165.99999 -8,0 0,-1 8,0 0,1 z"
+ id="path18501"
+ 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"
+ style="fill:none;stroke:url(#linearGradient23914);stroke-width:0.99999923px;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 35.47469,156.50008 -8.986105,-8e-5 5e-6,10 8.999995,0 -0.01389,-9.99992 -5e-6,0 0,0 0,0 z"
+ id="path18503"
+ 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:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18505"
+ width="1"
+ height="1.000007"
+ x="27.988585"
+ y="165"
+ 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="fill:#ee0000;fill-opacity:1"
+ id="g18507"
+ transform="matrix(1,0,0,-1,0,320)" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-157,18.000328)"
+ style="opacity:0.5"
+ id="g18509">
+ <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="path18511"
+ d="m 76,164 -10,0 0,-9 10,0 0,9 z"
+ style="opacity:0.8;fill:url(#radialGradient23916);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#radialGradient23918);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 76,164 -10,0 0,-9 10,0 0,9 z"
+ id="path18513"
+ 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>
+ <g
+ id="g18515"
+ transform="translate(0,-3.2e-4)">
+ <g
+ id="g18517">
+ <g
+ transform="translate(-360,181.00032)"
+ id="g18519"
+ mask="url(#mask13041)">
+ <path
+ id="path18521"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.316109 -2.96875,2.96875 l 0,1.0625 c 0,1.6526411 1.31612,2.96875 2.96875,2.96875 l 0.0625,0 c 1.65264,0 2.96875,-1.3161089 2.96875,-2.96875 l 0,-1.0625 c 0,-1.652641 -1.31612,-2.96875 -2.96875,-2.96875 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.446 1,1 l 0,1 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-1 c 0,-0.554 0.446,-1 1,-1 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="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"
+ id="rect18523"
+ width="1"
+ height="2.5"
+ x="277"
+ y="-10" />
+ <rect
+ y="-11"
+ x="278"
+ height="1"
+ width="1"
+ id="rect18525"
+ style="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" />
+ </g>
+ <g
+ id="g18527"
+ transform="translate(-360,191.06282)"
+ mask="url(#mask13052)">
+ <path
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.316109 -2.96875,2.96875 l 0,1.0625 c 0,1.6526411 1.31612,2.96875 2.96875,2.96875 l 0.0625,0 c 1.65264,0 2.96875,-1.3161089 2.96875,-2.96875 l 0,-1.0625 c 0,-1.652641 -1.31612,-2.96875 -2.96875,-2.96875 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.446 1,1 l 0,1 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-1 c 0,-0.554 0.446,-1 1,-1 z"
+ id="path18529"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-10"
+ x="277"
+ height="2.5"
+ width="1"
+ id="rect18531"
+ style="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" />
+ <rect
+ style="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"
+ id="rect18533"
+ width="1"
+ height="1"
+ x="278"
+ y="-11" />
+ </g>
+ </g>
+ <g
+ id="g18535" />
+ </g>
+ </g>
+ <g
+ id="g18658"
+ transform="translate(-147.04123,1.9815)">
+ <rect
+ y="71.018501"
+ x="383.04123"
+ height="16"
+ width="16"
+ id="rect18661"
+ 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="g18663">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient18682);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 397.54124,84.25 -1.25,1.25 -10.5,0 -1.24999,-1.25 0,-11.75 12.99999,0 0,11.75 z"
+ id="path18665"
+ 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="path18667"
+ d="m 396.04123,84.0185 -10,0 0,-1.0185 10,0 0,1.0185 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" />
+ <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"
+ y="83.018501"
+ x="387.04123"
+ height="0.99999702"
+ width="0.99998772"
+ id="rect18671"
+ style="fill:#e6e6e6;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(-39.85994,-165.9815)"
+ id="g18674">
+ <path
+ sodipodi:nodetypes="csssccc"
+ d="m 430.24956,241.60271 -0.86957,2.62878 c -1.04667,3.16416 -1.3885,3.86937 -2.40118,2.64949 -0.37662,-0.45369 -1.31958,0.42592 -0.85102,0.66654 2.9195,1.49927 3.83448,-0.99495 4.73215,-3.56602 l 0.75,-2.37879 -1.36038,0 0,0 0,0 0,0 z"
+ id="path18676"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.33455,240.97335 c -0.77131,0.0353 -1.46745,0.21844 -2.3658,0.6829 -0.74329,0.3843 -1.31497,1.26096 -1.28125,1.75 0.0247,0.35816 0.29068,0.65625 0.65625,0.65625 0.36558,0 0.6936,-0.30765 0.6781,-0.65797 C 428,242.91083 427.68952,243 427.84375,242.625 c 0.11839,-0.28788 0.47629,-0.71901 0.90625,-0.83455 0.61327,-0.1648 1.873,0.18401 2.5,0.20955 1.75215,0.0714 3.67097,-0.15759 4.5,-1 -0.24423,0.0241 -2.49503,0.0675 -2.75,0.0625 -1.06533,-0.0208 -1.89414,-0.12444 -2.66545,-0.0891 l 0,-5e-5 z"
+ id="path18678"
+ sodipodi:nodetypes="cssssssscss"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ d="m 430.47881,243.98149 c 1.25,0 2.77121,0.0774 3.52119,0.0185 -0.28977,0.34542 -1.08416,0.80085 -1.5,0.89651 -0.84895,0.19531 -2.02119,-0.033 -2.89006,0.0468 l 0.86887,-0.96184 0,3e-5 z"
+ id="path18680"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:url(#linearGradient18690);stroke-width:0.99999923px;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 396.54123,73.51858 -10.98611,-8e-5 -0.0139,11.00008 11,0 0,-11 10e-6,0 z"
+ id="path18688"
+ 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>
+ </g>
+ <g
+ transform="translate(2,529.00001)"
+ id="g18738"
+ 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="rect18740"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g18742"
+ transform="translate(0.01612278,0)">
+ <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"
+ 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"
+ d="M 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient18752);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"
+ sodipodi:nodetypes="ccccccc"
+ 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"
+ d="M 15.983877,81.999998 7.7338772,82 l 0,-0.999998 8.2499998,-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(#linearGradient18756);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ id="path18748"
+ 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"
+ width="1"
+ height="1"
+ x="5.9838772"
+ y="80.999992"
+ 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>
+ <g
+ transform="translate(256.9902,446.00001)"
+ id="g18759"
+ 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="rect18761"
+ width="16"
+ height="16"
+ x="42.0098"
+ y="173" />
+ <g
+ style="display:inline"
+ id="g18763"
+ 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="translate(-0.00161682,-3.9821186e-5)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ 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="path41276"
+ d="m 56.511417,178.50003 -10,0 0,9 8.75,0 1.25,-1.25 0,-7.75 z"
+ style="opacity:0.15;fill:#000000;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18765"
+ d="m 55.011418,177.00004 -10.000001,-1e-5 0,9 10.000001,1e-5 0,-9 z"
+ style="opacity:0.85;fill:url(#linearGradient18779);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ 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 55.501617,177.75004 -1.25,-1.25 -8.4902,-1e-5 -1.25,1.25 0,7.5 1.25,1.25 8.4902,1e-5 1.25,-1.25 0,-7.5 z"
+ id="path18767"
+ 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="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#4d4d4d;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 54.011419,178.00004 -8.000002,-1e-5 0,0.99996 8.000002,1e-5 0,-0.99996 z"
+ id="path18773"
+ 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" />
+ </g>
+ <path
+ 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="path18860"
+ d="m 54.5098,177.5 0,8 -9,-1e-5 0,-8 9,1e-5 z"
+ style="fill:none;stroke:url(#linearGradient18862);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g18864"
+ transform="translate(210,253.00005)">
+ <rect
+ y="345"
+ x="-184"
+ height="16"
+ width="16"
+ id="rect18694"
+ 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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18698"
+ d="m -176.47247,352.5 -0.59149,0 -5.43604,0 0.0161,-6.00003 6.01141,0 0,6.00003 2e-5,0 0,0 0,0 z"
+ style="fill:url(#linearGradient18846);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"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient18841);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 -176.5,358.5 -1,1 -3.73388,0 -1.25,-1.25 0,-5.74999 6.01141,0 L -176.5,358.5 z"
+ id="path18702"
+ 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="ccccccc"
+ 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="path18710"
+ d="m -169.5133,358.25 -1.2367,1.25 -4.75,0 -1,-1 0,-12 7.00001,0 -0.0133,11.75 -10e-6,0 z"
+ style="fill:url(#linearGradient18831);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"
+ 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="path18712"
+ d="m -171,358 -4,0 0,-1.00004 4,0 0,1.00004 z"
+ style="color:#000000;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"
+ 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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18718"
+ d="m -177.5,353.5 0,5 -4,0 0,-5 4,0 z"
+ style="fill:none;stroke:url(#linearGradient18823);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -178,358.00004 -3,0 0,-1.00004 3,0 0,1.00004 z"
+ id="path18850"
+ 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="fill:none;stroke:url(#linearGradient18854);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -170.5,347.5 0,11.00001 -5,0 0,-11.00001 5,0 z"
+ id="path18852"
+ 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" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18858);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -177.5,347.50001 0,4 -4,0 0,-4 4,0 z"
+ id="path18856"
+ 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" />
+ <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="path17395"
+ d="m -178,358.00004 -3,0 0,-1.00004 3,0 0,1.00004 z"
+ style="color:#000000;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g17204"
+ transform="translate(290,-291)">
+ <g
+ transform="translate(-204,295)"
+ id="g18875"
+ 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="rect18877"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g18879"
+ transform="translate(0.01612278,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="path18881"
+ d="M 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17222);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"
+ 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="path18883"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17224);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ id="path18885"
+ 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:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18887"
+ width="1"
+ height="1"
+ x="6.9838772"
+ y="81"
+ 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
+ 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 -197.50001,368.5 9,0 m -9,2 9,0 m -9,2 9,0"
+ style="fill:none;stroke:url(#linearGradient17226);stroke-width:0.9999994px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ id="path19108"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g17183"
+ transform="translate(294,-291)">
+ <g
+ style="display:inline"
+ id="g19069"
+ transform="translate(-187,295)">
+ <rect
+ y="69"
+ x="3"
+ height="16"
+ width="16"
+ id="rect19071"
+ 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,0)"
+ id="g19073"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient17214);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 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ id="path19075"
+ 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="ccccc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ id="path19077"
+ 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="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="path19079"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ style="fill:none;stroke:url(#linearGradient17216);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <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="81"
+ x="6.9838772"
+ height="1"
+ width="1"
+ id="rect19081"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ id="path19112"
+ style="fill:none;stroke:url(#linearGradient17218);stroke-width:0.99999946px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ d="m -173.49999,372.5 2,0 m -2,-2 2,0 m -2,-2 2,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"
+ 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"
+ d="m -180.5,372.5 3,0 m -3,-2 3,0 m -3,-2 3,0"
+ style="fill:none;stroke:url(#linearGradient17220);stroke-width:0.99999952px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ id="path19116"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#999999;fill-opacity:0.75;fill-rule:evenodd;stroke:#808080;stroke-width:0.99999928px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m -175.39386,374.49044 0,-7.03646"
+ id="path19120"
+ 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="cc"
+ 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="path19122"
+ d="m -174.39384,374.5 0,-8.00012 2.89384,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.9999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g41473">
+ <g
+ id="g20803"
+ transform="translate(-116.99998,424.00001)">
+ <g
+ transform="translate(-340.00002,-121.00001)"
+ id="g20805">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9e9af;stroke-width:0.49999988;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="path32699"
+ sodipodi:cx="464.5"
+ 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"
+ 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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path32701"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e1e08a;stroke-width:0.69999987;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:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#adac2f;stroke-width:1.16666663;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="path32703"
+ sodipodi:cx="464.5"
+ 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"
+ transform="matrix(0.8571429,0,0,0.8571429,67.857123,27.999992)" />
+ </g>
+ <rect
+ y="71"
+ x="125"
+ height="2"
+ width="2"
+ id="rect20813"
+ style="fill:#f4f4d7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g41392">
+ <g
+ transform="translate(-456.00027,338.00001)"
+ id="g20782">
+ <path
+ style="fill:url(#linearGradient23241);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.66961 -3,1.5 l 0,7 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 0,-7 c 0,-0.83039 -1.0691,-1.5 -3,-1.5 z"
+ id="path20784"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23243);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 470.50029,158.5 0,6.45352 c 0,0.54648 1.28413,0.46583 2,0.54648 1,0 2,0 2,-0.55753 l 0,-6.45352"
+ id="path20786"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:url(#radialGradient23245);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.5 -3,1.5 l 0,7 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 0,-7 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ id="path20788"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#eff6ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path20790"
+ sodipodi:cx="108"
+ 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"
+ transform="matrix(0.9067635,0,0,1.3047091,374.56954,447.97555)" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path20793"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.5 -3,1.5 l 0,7 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 0,-7 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ style="fill:none;stroke:#162d50;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-116.99998,424.00001)"
+ id="g32690">
+ <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="path32692"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.05875278;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4371593,0,0,0.4371565,71.294972,28.418283)" />
+ <path
+ transform="matrix(-0.3851128,-0.04237784,0.04389507,-0.3737467,174.55414,129.70537)"
+ 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="path32694"
+ style="opacity:0.6;fill:url(#linearGradient23247);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <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="path20801"
+ style="fill:none;stroke:url(#linearGradient23250);stroke-width:3.99999762;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.3000001,0,0,0.3000002,89.398992,44.603723)" />
+ </g>
+ <rect
+ y="493"
+ x="5"
+ height="16"
+ width="16"
+ id="rect20815"
+ style="fill:none;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g17123"
+ transform="translate(207.01492,72.000007)">
+ <rect
+ y="442"
+ x="-34"
+ height="16"
+ width="16"
+ id="rect17125"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="czsccccccccccccccccccccccccccccs"
+ id="path17128"
+ d="m -21.25,443.25 c -1.25,-1.25 -3.5,0.25 -7.5,4 -4,3.75 -5.25,6.25 -4,7.5 1.013195,1.01319 3.75,2.5 3.75,2.5 l 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 c 0,0 -2,-3.25 -2.5,-3.75 z"
+ style="fill:none;stroke:#000000;stroke-width:1.60000002;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:url(#linearGradient17135);fill-rule:evenodd;stroke:none"
+ d="m -21.25,443.25 c -0.5,-0.5 -3.5,0.25 -7.5,4 -4,3.75 -4.5,7 -4,7.5 0.5,0.5 3.5,2.75 3.5,2.75 l 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 c 0,0 -2.249997,-3 -2.75,-3.5 z"
+ id="path17131"
+ sodipodi:nodetypes="czsccccccccccccccccccccccs"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -21.75,443.75 c -1,-1 -3.5,1 -6.5,4 -3,3 -5,5.5 -4,6.5"
+ id="path17133"
+ sodipodi:nodetypes="czs"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g17299"
+ transform="translate(-21,128.00001)">
+ <g
+ transform="translate(464,422)"
+ id="g17228"
+ 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="rect17230"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g17232"
+ transform="translate(0.01612278,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="path17234"
+ d="m 17.453876,82.25 -1.219999,1.25 -10.4999998,0 -1.25,-1.25 -1e-7,-11.75 12.9814139,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17242);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"
+ sodipodi:nodetypes="ccccccc"
+ 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="path17236"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17244);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 5.4838772,82.5 0,-11 10.9999998,0 0,11 -10.9999998,0 z"
+ id="path17238"
+ 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:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17240"
+ width="1"
+ height="1"
+ x="6.9838772"
+ y="81"
+ 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>
+ <g
+ transform="translate(20.96875,0)"
+ id="g17279">
+ <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"
+ d="m 450.70226,498 6.81386,0 m -4.98487,-2.5 -1.82899,2.5 m 1.82899,2.5 -1.82899,-2.5"
+ style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17281"
+ sodipodi:nodetypes="czcccc"
+ 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"
+ sodipodi:nodetypes="cc"
+ id="path17283"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 453.28125,496 -0.75,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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 452.78125,499 4.76119,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.50000006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17286"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </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"
+ 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"
+ id="rect33081"
+ width="16"
+ height="16"
+ x="162"
+ y="90" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;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="rect33085"
+ width="2.5"
+ height="1.75"
+ x="165.74995"
+ y="96.749977" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path33087"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,2.75 -5.99999,3.24999 -6.00001,-3.24999 0,-2.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="91.999977"
+ x="170.98643"
+ height="7"
+ width="2"
+ id="rect32743"
+ style="opacity:0.96000001;fill:none;stroke:#1a1a1a;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" />
+ <path
+ id="path33091"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 0,-0.56558 z"
+ style="fill:#808080;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"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 164.99997,101.74998 -1e-5,-2.25 6,3 0.01,2.49885 -6.00995,-3.24885 -4e-5,0 0,0 0,0 z"
+ id="path33093"
+ 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="path33095"
+ d="m 176.99996,101.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.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" />
+ <rect
+ style="fill:#aa0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33097"
+ width="2"
+ height="1"
+ x="165.99995"
+ y="97.999977" />
+ <rect
+ y="96.999977"
+ x="165.99995"
+ height="1"
+ width="2"
+ id="rect32749"
+ style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;fill:#ffaaaa;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32751"
+ width="1"
+ height="2"
+ x="165.99995"
+ y="96.999977" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path32753"
+ d="m 165.49996,99.49998 0,0 0,2 5.5,3 5.5,-3 0,-2"
+ style="fill:none;stroke:url(#linearGradient22081);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-114.00004,-232.99999)"
+ id="g32755">
+ <rect
+ style="opacity:0.3;fill:none;stroke:#1a1a1a;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"
+ id="rect33103"
+ width="2"
+ height="3.9642856"
+ x="285"
+ 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"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="325"
+ sodipodi:cx="286"
+ id="path33105"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#550000;stroke-width:0.59999985;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:type="arc" />
+ <rect
+ style="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="rect32759"
+ width="2"
+ height="3.5000324"
+ x="285"
+ y="328.49997" />
+ <rect
+ y="328.49997"
+ x="285"
+ height="3.5000324"
+ width="1"
+ id="rect32761"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient32335);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.59999985;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32763"
+ sodipodi:cx="286"
+ 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"
+ transform="matrix(1.333351,0,0,1.333345,-95.338377,-107.33714)" />
+ <rect
+ y="331"
+ x="284"
+ height="1"
+ width="1"
+ id="rect32765"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;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="rect32767"
+ width="2"
+ height="1"
+ x="285"
+ y="332" />
+ <rect
+ style="opacity:0.5;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="rect32769"
+ width="1"
+ height="1"
+ x="287"
+ y="331" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path48963"
+ d="m 165.49996,98.99998 5.5,2.75"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask20957)"
+ id="g21598">
+ <path
+ mask="none"
+ sodipodi:nodetypes="cccc"
+ id="path21596"
+ d="m 168.25,102.75 -0.75,0.75 c -1,1 -0.75,1 -2,1 l -2.25,0"
+ style="opacity:0.7;fill:none;stroke:#1a1a1a;stroke-width:2.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ececec;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 168.25,102.75 -0.75,0.75 c -1.25,1.17188 -0.75,1 -2,1 l -3,0"
+ id="path21594"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g34058"
+ transform="translate(0,12)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path32379"
+ d="m 35.5,65.5 6,0 0,11 -9,0 0,-8 3,-3 z"
+ style="fill:url(#linearGradient31964);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient31966);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(0,-10)"
+ id="g34026">
+ <path
+ style="fill:url(#linearGradient31968);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient31970);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ d="m 29.5,71.5 6,0 0,11 -9,0 0,-8 3,-3 z"
+ id="path32383"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="73"
+ x="27.984795"
+ height="8"
+ width="6.0303202"
+ id="rect32389"
+ 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
+ style="fill:#fa0000;fill-opacity:1"
+ transform="matrix(-1,0,0,1,217.99997,-167)"
+ id="g32391">
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ id="g32393">
+ <path
+ style="fill:#b41500;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 187.03125,239 0,2 2,0 0,-2 -2,0 z m 2,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 0,-2 0,-2 -2,0 0,2 2,0 z"
+ transform="matrix(-1,0,0,1,375.01609,1)"
+ id="path32395"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ id="g32397"
+ transform="translate(2,-2)" />
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ transform="translate(0,-4)"
+ id="g32399" />
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ id="g32401"
+ transform="translate(2,-6)" />
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ transform="translate(0,-8)"
+ id="g32403" />
+ </g>
+ <path
+ mask="none"
+ clip-path="none"
+ transform="matrix(1.499975,0,0,1.4959551,100.24881,-314.20841)"
+ sodipodi:nodetypes="ccc"
+ id="path32405"
+ style="fill:none;stroke:#000000;stroke-width:0.66757292px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter23214)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path32407"
+ style="opacity:0.98999999;fill:none;stroke:url(#linearGradient31972);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 27.5,76 -3e-5,5.5081 M 31,72.5 l 3.49997,0.0081"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path32409"
+ d="m 25.99997,75.00809 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 26.5,64 0,8.5 6,0 -0.01513,4 9.01513,0 0,-11 -5.98487,0 -0.01513,-4 -6.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"
+ id="path32414"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-158,-135)"
+ id="g33249">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccc"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 35,78 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z m -1,2 0,1 6,0 0,-1 -6,0 z m 5,2 0,1 1,0 0,-1 -1,0 z"
+ transform="translate(158,125)"
+ id="rect33241"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 33.5,73.25 0,2.25001 M 36.25,66.5 l 4.25,0"
+ style="fill:none;stroke:url(#linearGradient31974);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path33301"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g22429"
+ transform="translate(542.99004,484.00118)">
+ <rect
+ y="9"
+ x="-34"
+ height="16"
+ width="16"
+ id="rect22431"
+ 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" />
+ <g
+ id="g22433">
+ <path
+ 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 -32,17 7,-3 6,2.5 0,3.74998 -6.99999,3.74999 L -32,20.74998 -32,17 z"
+ id="path22435"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ 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 -32,17 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 L -32,17 z"
+ id="path22437"
+ 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:#2c281a;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 -24.99004,20.99883 -25,14.00002 -32,17 l 3.5,1.75 3.50996,2.24883 0,0 0,0 0,0 z"
+ id="path22439"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22441"
+ d="M -24.99004,20.99883 -25,14 l 6,2.5 -3.5,1.75 -2.49004,2.74883 0,0 0,0 0,0 z"
+ style="fill:#716844;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
+ style="fill:none;stroke:url(#linearGradient22453);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M -19.5,16.5 -25,14.25 -31.5,17"
+ id="path22443"
+ sodipodi:nodetypes="ccc"
+ 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="path22445"
+ d="M -31.99999,20.74998 -32,17.5 l 6,3 0.01,3.49883 -6.00995,-3.24885 -4e-5,0 0,0 0,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"
+ 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:#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 -19,20.25 0,-3.24998 -7,3.49998 c 0,2.58362 0,2.93288 0,3.49998 L -19,20.25 z"
+ id="path22447"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient22455);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.5,17.5 0,2.99998 5.5,3 6.5,-3.49998 0,-2.99998"
+ id="path22449"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path22451"
+ d="m -31.5,17.5 5.5,3 6.5,-3.5"
+ style="fill:none;stroke:url(#linearGradient22457);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ 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"
+ 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"
+ id="rect18472"
+ width="16"
+ height="16"
+ x="164"
+ y="592" />
+ <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="cccccc"
+ d="m 169.51126,596.5 c 3.98874,3.75 3.98874,7.5 3.98874,9 m 1.01472,-11 c 3.48528,5 2.98528,9.5 2.98874,11 M 166.5,600.5 c 2,1 3,3 3.00692,5"
+ style="fill:none;stroke:url(#linearGradient18478);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path18474"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18476"
+ style="fill:none;stroke:url(#linearGradient18480);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 169.51126,596.5 c 3.98874,3.75 3.98874,7 3.98874,9 m 1.01472,-11 c 3.48528,5 2.98528,9.5 2.98874,11 M 166.5,600.5 c 2,1 3,3 3.00692,5"
+ 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" />
+ </g>
+ <g
+ style="display:inline"
+ id="g22771"
+ transform="translate(-186,487.00001)">
+ <g
+ id="g21832"
+ style="opacity:0.85">
+ <rect
+ transform="scale(-1,1)"
+ y="82"
+ x="-433.5"
+ height="3"
+ width="7.8166504"
+ id="rect22717"
+ style="opacity:0.5;fill:url(#linearGradient22880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ y="83"
+ x="-434"
+ height="1"
+ width="8.9931746"
+ id="rect21783"
+ style="fill:url(#linearGradient22848);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ y="83"
+ x="-430.5"
+ height="1"
+ width="2"
+ id="rect22877"
+ style="fill:#333333;fill-opacity:0.81960784;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="opacity:0.8"
+ id="g22652">
+ <rect
+ y="69"
+ x="422"
+ height="16"
+ width="16"
+ id="rect22589"
+ style="opacity:0.05;fill:url(#radialGradient22838);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22619">
+ <path
+ sodipodi:nodetypes="csscccc"
+ id="path21775"
+ d="m 422.51387,74.4375 c 2.14278,1.6383 5.29475,5.652 6.25,7.5625 0.5,1 1.05394,1.01957 1.5,0 0.875,-2 3.25,-4.75 4.75,-6 l -3.5,-4 c -1.25,1.83839 -2,3.25 -2.75,4.63304 -1.71617,-1.72583 -4.35859,-3.39262 -6.25,-4.13304"
+ style="fill:url(#linearGradient22840);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient22842);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" />
+ </g>
+ </g>
+ <g
+ id="g22626">
+ <g
+ id="g22622">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path21777"
+ d="m 422.51387,73.5 c 1.93909,0.815624 4.07262,1.664731 6,4 l 0.75,0 c 0.82427,-1.547027 1.51287,-2.596571 2.16161,-3.5"
+ style="fill:none;stroke:url(#linearGradient22844);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22846);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 422.51387,73.5 c 1.93909,0.815624 5.41183,5.25 7,8 1.5,-3 2.75,-4 4.75,-6.25"
+ id="path21779"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22896);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 428.5,78.5 c 0.95165,-1.519624 1.88025,-3.040081 2.92548,-4.5"
+ id="path22894"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g22592"
+ transform="translate(434.01387,-281)">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient22850);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82784271;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="path21781"
+ 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.4380641,0,0,0.4372851,-57.820839,302.39978)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient22852);stroke-width:4.11671448;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="path21785"
+ 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.2913522,0,0,0.2916372,38.453823,319.58486)" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g35565"
+ transform="translate(147,527.00001)"
+ inkscape:export-filename="/home/wolter/Documenten/Blender/Icons/Fake2.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="71"
+ x="215"
+ height="16"
+ width="16"
+ id="rect34912"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g35549">
+ <g
+ transform="translate(167,137)"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34918"
+ style="fill:none;stroke:#1a1a1a;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"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.56022131;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="path34920"
+ sodipodi:cx="0"
+ 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"
+ transform="matrix(1.4285714,0,0,1.4274429,55.5,-11.825777)" />
+ </g>
+ <g
+ id="g34922"
+ transform="matrix(1.1068703,0,0,1.0981766,160.5341,122.19554)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34924"
+ sodipodi:cx="0"
+ 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"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34926"
+ style="fill:none;stroke:url(#linearGradient35583);stroke-width:1.17982781;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"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35585);stroke-width:1.16643703;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="path34928"
+ sodipodi:cx="0"
+ 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"
+ transform="matrix(0.774689,0,0,0.7805148,56.890573,-14.812697)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35587);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99581552;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34930"
+ sodipodi:cx="0"
+ 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"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34932"
+ style="fill:url(#linearGradient35589);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99581552;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ transform="translate(167,137)"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34936"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35591);stroke-width:1.40000081;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="path34938"
+ sodipodi:cx="0"
+ 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"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34940"
+ style="fill:none;stroke:url(#linearGradient35593);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"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35595);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34942"
+ sodipodi:cx="0"
+ 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"
+ transform="matrix(0.8571429,0,0,0.8571429,58.032932,-32.409816)" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g35712"
+ transform="translate(307,636)"
+ inkscape:export-filename="/home/wolter/Documenten/Blender/Icons/Fake1.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="-38"
+ x="34"
+ height="16"
+ width="16"
+ id="rect35714"
+ 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(231.01612,149)"
+ id="g34102"
+ style="opacity:0.96000001;display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35717"
+ d="m -187.24592,-178.75235 -5.0202,5.00235 -3,2 -1,-1 2,-3 5.0202,-5.00235 2,2 z"
+ style="fill:url(#linearGradient35740);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -187.24592,-178.75235 -5.2702,5.25235 -3,2 -1,-1 2,-3 5.2702,-5.25235 2,2 z"
+ id="path34105"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path34107"
+ d="m -195.4858,-172.48532 1.46968,-2.51468 4.26612,-4.25"
+ style="fill:none;stroke:#ffffff;stroke-width:0.85000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path35721"
+ d="m 44.5,-37.5 -2,2 1,1 -2,2 -4,0 -1,1 7,7 1,-1 0,-4 2,-2 1,1 1.5098,-1.5098 0.4902,-0.4902 -5,-5 z"
+ style="fill:url(#linearGradient35742);fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35723"
+ d="m 44.5,-29.5 -3,-3"
+ style="fill:none;stroke:url(#linearGradient35744);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35725"
+ d="m 46.5,-31.5 -3,-3"
+ style="fill:none;stroke:url(#linearGradient35746);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path35729"
+ d="m 43.5,-33.5 -1.75,1.75 -4,0 -0.25,0.25"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35731"
+ d="m 43.5,-35.5 1,-1"
+ style="fill:none;stroke:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35733"
+ d="m 42,-32 0,0 2,-2 2.5,2.5 -2,2 L 42,-32"
+ style="fill:url(#linearGradient35750);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient35752);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 44.55,-36.45 3.95,3.95"
+ id="path34886"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path34890"
+ d="m 43.5,-35.5 3.715625,3.66875"
+ style="fill:none;stroke:url(#linearGradient35754);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient35756);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 41.55,-31.45 2.2,2.2"
+ id="path34894"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;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 45.5,-31.5 -1.25,1.25"
+ id="path34906"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path34908"
+ d="M 48.65,-32.65 47.4,-31.4"
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient35772);fill-rule:evenodd;stroke:none"
+ d="m 41.5,-32.25 -4.25,0 6.5,6.25 0,-4"
+ id="path35770"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path35727"
+ d="m 38.25,-31.25 5.5,5.5"
+ style="fill:none;stroke:url(#linearGradient35748);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ 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"
+ 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"
+ d="m 433.14375,58.950006 -2.75,2.75"
+ id="path11878"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11880"
+ d="m 425.39375,56.700006 2.75,-2.75"
+ style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68939);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g11883"
+ transform="translate(0,-0.044194)">
+ <path
+ transform="translate(459.95822,-187.9558)"
+ sodipodi:nodetypes="czzc"
+ id="path11885"
+ d="m -32.20822,242.24999 2,-2 c 3.74999,-3.75 8.74999,1.25 5,5 l -2,2"
+ style="fill:none;stroke:url(#linearGradient68941);stroke-width:2.20000005;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:connector-curvature="0" />
+ <rect
+ y="48"
+ x="423"
+ height="16"
+ width="16"
+ id="rect51637"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
+ <g
+ transform="translate(440,-188)"
+ id="g11891">
+ <path
+ transform="translate(-440,188.0442)"
+ id="path11895"
+ d="m 432.125,49.03125 c -1.30818,0.127946 -2.64484,0.727176 -3.75,1.8125 l -4.78125,4.6875 2.8125,2.875 4.78125,-4.71875 c 1.25772,-1.235151 1.98833,-0.85542 2.53125,-0.3125 0.54292,0.542919 0.91397,1.2336 -0.34375,2.46875 l -4.78125,4.6875 2.8125,2.875 4.78125,-4.71875 c 2.52607,-2.480751 2.30083,-6.16792 0.34375,-8.125 -0.97854,-0.978541 -2.36579,-1.53434 -3.84375,-1.53125 -0.18474,3.86e-4 -0.37562,-0.01828 -0.5625,0 z m 0.5625,0.875 c 1.23689,8.8e-4 2.39931,0.461809 3.21875,1.28125 1.63889,1.63889 1.89928,4.676909 -0.34375,6.875 l -4.28125,4.1875 -1.5625,-1.5625 4.3125,-4.21875 c 1.54471,-1.51377 1.17361,-2.857641 0.3125,-3.71875 -0.86111,-0.86111 -2.23654,-1.201271 -3.78125,0.3125 l -4.28125,4.1875 -1.5625,-1.5625 4.3125,-4.21875 c 1.12152,-1.09905 2.41936,-1.563381 3.65625,-1.5625 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path11897"
+ d="m -3.4321903,240.29419 c 0.82637,1.47069 0.7752067,3.63228 -0.8178097,5.23203 l -2.2237373,2.23314"
+ style="opacity:0.3;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.6"
+ id="g11899">
+ <path
+ sodipodi:nodetypes="czs"
+ id="path11901"
+ d="m 425.25,55.75 4.25,-4.25 c 1.59639,-1.596386 4.02931,-1.32637 5.5,-0.5"
+ style="fill:none;stroke:url(#linearGradient68943);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient68945);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 435,56 -4.75,4.75"
+ id="path11905"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-313,109)"
+ id="g51645"
+ 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"
+ id="rect11909"
+ width="16"
+ height="16"
+ x="423"
+ y="48" />
+ <g
+ id="g11911"
+ transform="translate(440,-187.9558)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.79999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -15,245 4.79178,-4.70581 c 3.7837908,-3.7159 8.7837908,1.2841 5,5 L -10,250"
+ id="path51649"
+ sodipodi:nodetypes="czzc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czzc"
+ id="path51651"
+ d="m -14.5,244.5 4.29178,-4.20581 c 3.7877432,-3.71186 8.7877432,1.28814 5,5 L -9.5,249.5"
+ style="fill:none;stroke:url(#linearGradient68947);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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68949);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"
+ d="M -6.75,246.75 -9.5,249.5"
+ id="path51653"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path51655"
+ d="m -14.5,244.5 2.75,-2.75"
+ style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68951);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#481608;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -10.95822,242.99999 -2,-2"
+ id="path11922"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient68953);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -14.70822,243.74999 4.25,-4.25 c 1.5,-1.49999 3.5,-1.5 5,-0.75"
+ id="path11924"
+ sodipodi:nodetypes="czs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11926"
+ d="m -5.95822,247.99999 -2,-2"
+ style="fill:none;stroke:#481608;stroke-width:1;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:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11928"
+ d="m -4.95822,243.99999 -4.5,4.5"
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient68955);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cs"
+ id="path11930"
+ d="m -4.0503493,245.73202 c 1.5801026,-1.61251 1.6441797,-3.76134 0.8178097,-5.23203"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g28545"
+ transform="translate(21,-19)">
+ <g
+ style="opacity:0.8;display:inline"
+ mask="url(#mask69005)"
+ transform="matrix(0.646567,0,0,0.644332,-233.54872,129.49706)"
+ id="g36675">
+ <g
+ style="display:inline"
+ id="g36677"
+ transform="matrix(1.8217829,0,0,1.8217829,375.38164,-343.68741)"
+ 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\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="path36680"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.14285731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7428442,0,0,0.7454212,30.426387,135.62554)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient51774);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path36682"
+ 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.6852904,-0.07823249,0.07810925,-0.6899628,209.72326,315.34566)" />
+ <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="path36684"
+ style="fill:none;stroke:url(#linearGradient51776);stroke-width:1.33333385;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6367237,0,0,0.6389323,44.434295,148.19125)" />
+ </g>
+ </g>
+ <g
+ transform="translate(-61.375,-188.625)"
+ id="g51790"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill-opacity:1;display:inline"
+ id="rect22754"
+ width="16"
+ height="16"
+ x="213.375"
+ y="343.625" />
+ <g
+ id="g51778">
+ <path
+ sodipodi:nodetypes="czscc"
+ id="path22715"
+ d="m 219.36593,351.65 0,-3.5 c 0,-2.025 1.25907,-2.525 2.50907,-2.525 1.25,0 2.5,0.5 2.49092,2.525 l 0,3.5"
+ style="fill:none;stroke:#000000;stroke-width:3.79999995;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient51804);stroke-width:2.5;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 219.36593,351.65 0.009,-3.275 c 0.006,-2.25 1.24773,-2.74375 2.5,-2.75 1.25227,-0.006 2.5,0.5 2.50907,2.725 l -0.0182,3.3"
+ id="path22717"
+ sodipodi:nodetypes="czscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22719"
+ d="m 224.35595,351.24375 0,0.53125"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient51806);stroke-width:2.5;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient51808);stroke-width:2.5;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 219.40595,351.72527 0,-0.50027"
+ id="path22721"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22723"
+ d="m 220.7625,350.275 -2,0"
+ style="fill:none;stroke:#803300;stroke-width:1;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:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#803300;stroke-width:1.00000024;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 225.61593,350.15 -2.25,0"
+ id="path22725"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path22727"
+ d="m 218.61592,352.15 0,-4 c 0,-2.025 1.21963,-2.89049 2.75,-3.25"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient51810);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient51812);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 223.61593,352.15 0,-3.75115 c 0,-1.35618 -0.49093,-2.02385 -1.24093,-2.02385"
+ id="path22730"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.05;fill:none;stroke:#000000;stroke-width:0.73376155;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 225.24243,350.48448 c -0.001,-0.14034 0.0155,-2.61281 0,-2.75 -0.10562,-0.93297 -0.53761,-1.74673 -1.11525,-2.29782"
+ id="path22732"
+ sodipodi:nodetypes="css"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22738"
+ d="m 220.11593,347.65 0,3.125"
+ style="opacity:0.02000002;fill:none;stroke:#000000;stroke-width:0.84999996;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g20285"
+ transform="translate(0,107.00001)">
+ <rect
+ y="449"
+ x="257"
+ height="16"
+ width="16"
+ id="rect19373"
+ 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="opacity:0.6;stroke:#162d50"
+ id="g19375"
+ transform="translate(14.081669,359)">
+ <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="cc"
+ id="path19377"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ style="opacity:0.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path19379"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <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="cc"
+ id="path19381"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ style="opacity:0.9;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19385"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ style="fill:url(#linearGradient20275);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path19455"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ style="fill:none;stroke:url(#linearGradient20309);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ 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="opacity:0.5;fill:none;stroke:url(#linearGradient20269);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 260.5,454.5 0,4.9091"
+ id="path19387"
+ 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"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,455.5 1,0"
+ id="path19389"
+ 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="path19391"
+ d="m 262.59506,453.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19393"
+ d="m 258.5,454.63598 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,454.5 1,-1"
+ id="path19395"
+ 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.9;fill:none;stroke:#ffffff;stroke-width:1.29999995;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 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path19397"
+ sodipodi:nodetypes="cc"
+ 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
+ id="path20281"
+ d="m 263.5,452.5 0,9"
+ style="fill:none;stroke:url(#linearGradient20283);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient20303);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 258.5,454.3 0,5.4"
+ id="path20301"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g38213"
+ transform="translate(0,-1.00005)">
+ <rect
+ y="513.99988"
+ x="26"
+ height="16"
+ width="16"
+ id="rect38641"
+ 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="g36101">
+ <g
+ id="g22740"
+ style="opacity:0.7"
+ transform="translate(-116,424.99975)">
+ <g
+ transform="translate(-179,199.50012)"
+ id="g38620">
+ <path
+ id="path38622"
+ d="m 329.5,-108.25 -5.5,1.75 0,7.74988 6,2.09544 5,-2.84532 0,-6.75 -5.5,-2 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000167;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="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#cccccc;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 324,-99.00012 0,-7.49988 6,-1.75 0,11.5 -0.5,0.25 -5.5,-2.50012 z"
+ id="path38624"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g38626">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#787878;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 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path38628"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;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 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path38630"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient38718);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.25012 0,-7.24988"
+ id="path38632"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient38721);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 145.5,93.25012 c 0,0 5,2.25 5,2.25 l 5,-2.25"
+ id="path38634"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.19199997;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38636"
+ width="1"
+ height="7.75"
+ x="150"
+ y="95.000122" />
+ <rect
+ y="95.25"
+ x="151"
+ height="7.75"
+ width="1"
+ id="rect22687"
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ rx="0"
+ ry="0"
+ y="526.49988"
+ x="33.5"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect38643"
+ style="fill:none;stroke:#783e00;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
+ rx="0"
+ ry="0"
+ y="516.49988"
+ x="27.5"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect38645"
+ style="fill:none;stroke:#783e00;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:none;stroke:#783e00;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="rect38647"
+ width="2.9999485"
+ height="3.0001416"
+ x="27.5"
+ y="524.49969"
+ ry="0"
+ rx="0" />
+ <rect
+ style="fill:none;stroke:#783e00;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="rect38649"
+ width="2.9999485"
+ height="3.0001416"
+ x="33.5"
+ y="518.49969"
+ ry="0"
+ rx="0" />
+ <rect
+ style="opacity:0.06000001;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="rect38754"
+ width="3.9785564"
+ height="4"
+ x="34.021442"
+ y="519.00006" />
+ <rect
+ rx="0"
+ ry="0"
+ y="518.99976"
+ x="34"
+ height="2.0000772"
+ width="1.9999485"
+ id="rect39152"
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="rect28386"
+ d="m 28,519.50001 -0.5,0 0,-3.00014 2.99995,0"
+ style="fill:none;stroke:#462500;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#462500;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"
+ d="m 28,524.50001 -0.5,0 0,3.00014 2.99995,0"
+ id="path28390"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path28392"
+ d="m 33.5,527.75001 -9e-5,1.75004 3.00014,0 -5e-5,-1.75004"
+ style="fill:none;stroke:#462500;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="517.00006"
+ x="28.021444"
+ height="4"
+ width="3.9785564"
+ id="rect37868-0-2"
+ 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" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28536"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000046"
+ y="517"
+ ry="0"
+ rx="0" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28538"
+ width="1.9999485"
+ height="2.0000772"
+ x="34.000046"
+ y="527"
+ ry="0"
+ rx="0" />
+ <rect
+ y="525.00006"
+ x="28.021444"
+ height="1.9999889"
+ width="3.9785564"
+ id="rect38756"
+ 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" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28540"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000046"
+ y="525"
+ ry="0"
+ rx="0" />
+ </g>
+ </g>
+ <g
+ id="g39255"
+ 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"
+ id="rect39088"
+ width="16"
+ height="16"
+ x="173"
+ y="70.976562" />
+ <g
+ id="g39227">
+ <g
+ transform="translate(1.0000047,-0.02344036)"
+ id="g39109">
+ <g
+ transform="translate(8,8)"
+ id="g39113">
+ <rect
+ ry="0"
+ y="72.5"
+ x="173.5"
+ height="6"
+ width="5"
+ id="rect39115"
+ style="fill:url(#linearGradient39281);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;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
+ style="fill:#333333"
+ transform="matrix(-1,0,0,-1,352,144)"
+ id="g39117" />
+ <rect
+ ry="0"
+ style="fill:none;stroke:url(#linearGradient39283);stroke-width:0.99999994;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="rect39119"
+ width="2.9999952"
+ height="4.0000029"
+ x="174.52599"
+ y="73.523438" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path39123"
+ d="m 183.25,82.5 c 0.25,0 1.5,0 1.5,0 l -1.5,0 z m 0,2 1.5,0 -1.5,0 z"
+ style="fill:none;stroke:#333333;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-6.9999953,-9.0234404)"
+ id="g39125">
+ <g
+ id="g39127"
+ transform="translate(8,8)">
+ <rect
+ style="fill:url(#linearGradient39285);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;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="rect39129"
+ width="5"
+ height="6"
+ x="173.5"
+ y="72.5"
+ ry="0" />
+ <g
+ id="g39131"
+ transform="matrix(-1,0,0,-1,352,144)"
+ style="fill:#333333" />
+ <path
+ style="fill:#666666;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 177,73.02344 0,1 -1,0 0,-1 1,0 z m -1,1 0,1 -1,0 0,-1 1,0 z m -1,0 -1,0 0,-1 1,0 0,1 z m 0,1 0,1 -1,0 0,-1 1,0 z m 0,1 1,0 0,1 -1,0 0,-1 z m 0,1 0,1 -1,-1 1,0 z m 1,0 1,0 0,1 -1,0 0,-1 z m 1,0 0,-1 1,0 0,1 -1,0 z m 0,-1 -1,0 0,-1 1,0 0,1 z m 0,-1 0,-1 1,0 0,1 -1,0 z"
+ id="rect39177"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39287);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 174.52599,77.52344 0,-4.000002 2.99999,0"
+ id="rect39133"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39149"
+ transform="translate(1,-9)">
+ <g
+ transform="translate(8,8)"
+ id="g39151">
+ <rect
+ ry="0"
+ y="72.5"
+ x="173.5"
+ height="6"
+ width="5"
+ id="rect39153"
+ style="fill:url(#linearGradient39289);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;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
+ style="fill:#333333"
+ transform="matrix(-1,0,0,-1,352,144)"
+ id="g39155" />
+ <rect
+ ry="0"
+ style="fill:none;stroke:url(#linearGradient39291);stroke-width:0.99999994;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="rect39157"
+ width="2.9999952"
+ height="4.0000029"
+ x="174.52599"
+ y="73.523438" />
+ </g>
+ </g>
+ <g
+ transform="translate(-7,0)"
+ id="g39163">
+ <g
+ id="g39165"
+ transform="translate(8,8)">
+ <rect
+ style="fill:url(#linearGradient39293);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;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="rect39167"
+ width="5"
+ height="6"
+ x="173.5"
+ y="72.5"
+ ry="0" />
+ <g
+ id="g39169"
+ transform="matrix(-1,0,0,-1,352,144)"
+ style="fill:#333333" />
+ <rect
+ y="73.523438"
+ x="174.52599"
+ height="4.0000029"
+ width="2.9999952"
+ id="rect39171"
+ style="fill:none;stroke:url(#linearGradient39295);stroke-width:0.99999994;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"
+ ry="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="translate(168,-37)"
+ id="g39106">
+ <g
+ style="opacity:0.5;display:inline"
+ id="g39108"
+ transform="translate(69,-142)">
+ <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="rect39110"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
+ <g
+ transform="translate(1,0)"
+ id="g39112">
+ <g
+ transform="translate(-386,446.5)"
+ id="g39114">
+ <path
+ id="path39116"
+ 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="path39118"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g39120">
+ <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="path39122"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path39124"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient39008);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="path39126"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient39010);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39128"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39012);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="path39130"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="197"
+ x="7.0214434"
+ height="4"
+ width="3.9785564"
+ id="rect37868-0-11"
+ 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" />
+ <rect
+ y="204"
+ x="7.0214434"
+ height="3"
+ width="3.9785564"
+ id="rect37868-0-7"
+ 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
+ style="display:inline"
+ id="g39132"
+ transform="matrix(0.8303712,0,0,0.8404094,-87.641227,155.05106)">
+ <g
+ id="g39134">
+ <path
+ id="path39136"
+ d="m 115.18474,49.326679 0.0443,0 c 0.98532,0 1.77856,0.793241 1.77856,1.778566 l 0,1.46e-4 c 0,0.985326 -0.79324,1.778566 -1.77856,1.778566 l -0.0443,0 c -0.98533,0 -1.77857,-0.79324 -1.77857,-1.778566 l 0,-1.46e-4 c 0,-0.985325 0.79324,-1.778566 1.77857,-1.778566 z"
+ style="fill:none;stroke:#000000;stroke-width:1.78961492;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"
+ 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="path39138"
+ d="m 116.40772,49.919572 c -0.80364,0 -1.60728,1.2e-5 -2.41092,1.2e-5 0,0.793735 0,1.587459 0,2.381206 0.80364,0 1.60728,-1.2e-5 2.41092,-1.2e-5 0,-0.793735 0,-1.587471 0,-2.381206 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.78961492;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 115.18474,57.651268 0.0443,0 c 0.98532,0 1.77856,0.793241 1.77856,1.778566 l 0,1.46e-4 c 0,0.985326 -0.79324,1.778566 -1.77856,1.778566 l -0.0443,0 c -0.98533,0 -1.77857,-0.79324 -1.77857,-1.778566 l 0,-1.46e-4 c 0,-0.985325 0.79324,-1.778566 1.77857,-1.778566 z"
+ id="path37768"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 116.40772,58.244161 c -0.80364,0 -1.60728,1.2e-5 -2.41092,1.2e-5 0,0.793735 0,1.587459 0,2.381206 0.80364,0 1.60728,-1.2e-5 2.41092,-1.2e-5 0,-0.793735 0,-1.587471 0,-2.381206 z"
+ id="path37770"
+ 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>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="translate(168,-37)"
+ id="g39140">
+ <g
+ transform="translate(90,-142)"
+ id="g39142"
+ style="opacity:0.5;display:inline">
+ <rect
+ y="336"
+ x="-64"
+ height="16"
+ width="16"
+ id="rect39144"
+ 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="g39146"
+ transform="translate(1,0)">
+ <g
+ id="g39148"
+ 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="path39150"
+ 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="path39152"
+ 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" />
+ <g
+ id="g39154"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39156"
+ 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" />
+ <path
+ id="path39158"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39160"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient39014);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect39162"
+ style="fill:url(#linearGradient39016);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path39164"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient39018);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="198"
+ x="29"
+ height="8"
+ width="2.0000007"
+ id="rect37868-0-14"
+ 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" />
+ <rect
+ y="201"
+ x="32.021442"
+ height="7"
+ width="3.9785564"
+ id="rect37868-0-3"
+ 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
+ transform="translate(-1081.9421,-238.02038)"
+ style="fill:#ffeeaa;display:inline"
+ id="g39166">
+ <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:#d5e5ff;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;display:inline"
+ id="rect39168"
+ width="1.9820247"
+ height="8.0116062"
+ x="1109.4872"
+ y="435.4964"
+ transform="matrix(1,2.1226448e-5,0,1,0,0)" />
+ <rect
+ transform="matrix(1,3.6759233e-5,0,1,0,0)"
+ y="435.97955"
+ x="1109.958"
+ height="7.0000257"
+ width="0.99999994"
+ id="rect39170"
+ style="fill:#ffffff;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" />
+ <rect
+ transform="matrix(1,2.1226448e-5,0,1,0,0)"
+ y="438.49628"
+ x="1114.4713"
+ height="8.0116062"
+ width="1.9820247"
+ id="rect37773"
+ style="fill:#d5e5ff;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;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:#ffffff;fill-opacity:1;fill-rule:nonzero;display:inline"
+ id="rect37775"
+ width="0.99999994"
+ height="7.0000257"
+ x="1114.9421"
+ y="438.97937"
+ transform="matrix(1,3.6759233e-5,0,1,0,0)" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="translate(168,-37)"
+ id="g39172">
+ <g
+ style="opacity:0.5;display:inline"
+ id="g39174"
+ transform="translate(111,-142)">
+ <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="rect39176"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
+ <g
+ transform="translate(1,0)"
+ id="g39178">
+ <g
+ transform="translate(-386,446.5)"
+ id="g39180">
+ <path
+ id="path39182"
+ 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="path39184"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g39186">
+ <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="path39188"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path39190"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient39020);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="path39192"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient39022);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39194"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39024);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="path39196"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="201"
+ x="54"
+ height="7"
+ width="2.9785564"
+ id="rect37868-0-57"
+ 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
+ transform="translate(-1080.9861,-240)"
+ style="fill:#ffeeaa;display:inline"
+ id="g39198">
+ <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="path39200"
+ d="m 1130.4859,445.25 0,-7.5 6,2.75 0,8 -6,-3.25 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient39026);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="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g28811"
+ transform="translate(0,128.00001)">
+ <rect
+ y="365"
+ x="194"
+ height="16"
+ width="16"
+ id="rect28809"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g23255"
+ 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,-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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23257"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.86138636;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"
+ 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.81218,0,0,0.815735,163.7897,-27.2907)" />
+ <path
+ style="fill:#b3b3b3;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 270.98701,62.965769 0.0109,7.256732 c -1.99907,0 -3.99814,-0.250925 -6.00812,-1.234549 0,-3.324245 2.68676,-6.022183 5.99722,-6.022183 l 0,0 0,0 0,0 z m 0.0109,7.256732 c 1.99908,0 3.99815,-0.250925 5.98632,-1.234549 0,3.324245 -2.68675,6.022182 -5.99722,6.022182 l 0.0109,-4.787633 0,0 0,0 0,0 z"
+ id="path23259"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient23274);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path23261"
+ 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.749782,0,0,0.752489,172.03052,-19.77379)" />
+ <path
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)"
+ 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="path23263"
+ style="opacity:0.1;fill:url(#linearGradient23276);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.624782,0,0,0.627489,188.53052,-5.0185058)"
+ 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="path23265"
+ style="opacity:0.8;fill:url(#linearGradient23278);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.40226042;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.70545,67.406839 c 0.34141,-0.888253 0.96594,-1.399916 1.66978,-1.680902"
+ id="path23267"
+ sodipodi:nodetypes="cs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23269"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.6;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;filter:url(#filter13996)"
+ 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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path23271"
+ style="fill:none;stroke:url(#linearGradient23280);stroke-width:1.45689511;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6875,0,0,0.6875,180.25,-12.125)" />
+ </g>
+ </g>
+ <g
+ id="g40234">
+ <rect
+ y="514.00012"
+ x="5"
+ height="15.99988"
+ width="16"
+ id="rect40163"
+ style="opacity:0;fill:#f6d0a6;fill-opacity:1;fill-rule:evenodd;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g40089"
+ transform="translate(70,178)">
+ <g
+ id="g40091"
+ transform="translate(-386,446.5)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#422200;fill-opacity:1;fill-rule:evenodd;stroke:#281500;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="path40093"
+ 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="path40095"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ style="fill:#efa351;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g40097"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40099"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ style="fill:#915515;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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="path40101"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ style="fill:#f5ca9b;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40103"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient40171);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect40106"
+ style="fill:url(#linearGradient40173);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path40109"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient40175);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g57337"
+ transform="translate(10,254)" />
+ <g
+ style="display:inline"
+ id="g57399"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path57401"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.86138636;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"
+ 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.81218,0,0,0.815735,163.7897,-27.2907)" />
+ <path
+ style="fill:#b3b3b3;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 270.98701,62.965769 0.0109,7.256732 c -1.99907,0 -3.99814,-0.250925 -6.00812,-1.234549 0,-3.324245 2.68676,-6.022183 5.99722,-6.022183 l 0,0 0,0 0,0 z m 0.0109,7.256732 c 1.99908,0 3.99815,-0.250925 5.98632,-1.234549 0,3.324245 -2.68675,6.022182 -5.99722,6.022182 l 0.0109,-4.787633 0,0 0,0 0,0 z"
+ id="path57403"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient57417);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path57405"
+ 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.749782,0,0,0.752489,172.03052,-19.77379)" />
+ <path
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)"
+ 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="path57407"
+ style="opacity:0.1;fill:url(#linearGradient57419);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.624782,0,0,0.627489,188.53052,-5.0185058)"
+ 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="path57409"
+ style="opacity:0.8;fill:url(#linearGradient57421);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.40226042;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.70545,67.406839 c 0.34141,-0.888253 0.96594,-1.399916 1.66978,-1.680902"
+ id="path57411"
+ sodipodi:nodetypes="cs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path57413"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.6;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;filter:url(#filter13996)"
+ 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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path57415"
+ style="fill:none;stroke:url(#linearGradient57423);stroke-width:1.45689511;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6875,0,0,0.6875,180.25,-12.125)" />
+ </g>
+ <g
+ style="display:inline"
+ id="g22832"
+ 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"
+ id="rect22222"
+ width="16"
+ height="16"
+ x="-68"
+ y="256" />
+ <g
+ id="g22818">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m -66.5,257.5 5,0 c 0,1 3,1 3,0 l 5,0 0,5 -2,0 -2.9e-4,8 -8.99971,-5e-5 0,-7.99995 -2,0 0,-5 z"
+ id="path22864"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="rect22236"
+ d="m -66.5,257.5 4.75,0 c -0.5,3.25 4,3.25 3.5,0 l 4.75,0 0,5 -2,0 -2.9e-4,8 -8.99971,-5e-5 0,-7.99995 -2,0 0,-5 z"
+ style="fill:url(#linearGradient22905);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.69999999;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient22891);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -66,258 4,0 c 0,2.5 4,2.5 4,0 l 4,0 0,4 -2,0 0,8 -8,0 0,-8 -2,0 0,-4 z"
+ id="path23050"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path23055"
+ d="m -66,258 4,0 c 0,0.61505 0.242101,1.07878 0.607179,1.3912 L -61.5,259.5 -64,262 l -2,0 0,-4 z"
+ style="fill:url(#linearGradient22893);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient22895);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -54,258 -4,0 c 0,0.61505 -0.242101,1.07878 -0.607179,1.3912 L -58.5,259.5 l 2.5,2.5 2,0 0,-4 z"
+ id="path23059"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient22897);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -56.5,262.75 0,6.75 -7,0 0,-7.5"
+ id="path22238"
+ 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
+ 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="path22276"
+ d="m -56.5,269.5 -7,0 m -2,-8 0,-3 m 11,0 0,3 m -8,-3 c 0.5,2.75 4.5,2.75 5,0"
+ style="fill:none;stroke:url(#linearGradient22899);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23065"
+ d="m -63.5,264.5 c 0.75,3.5 4.25,5.5 7,3"
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient22901);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient22903);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-opacity:1;stroke-dasharray:none"
+ d="m -63.5,263.5 c 1,3.5 4.25,5.5 7,3"
+ id="path23063"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g23071"
+ transform="translate(0,1)"
+ style="opacity:0.9">
+ <path
+ style="opacity:0.4;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -60.5,262.5 1,0 0,2.75"
+ id="path23069"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path23067"
+ d="m -60.5,262.5 1,0 0,2.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-105,-229)"
+ id="g22900"
+ 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="rect22902"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904"
+ style="opacity:0.6;stroke:#162d50">
+ <path
+ style="opacity:0.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906"
+ sodipodi:nodetypes="cc"
+ 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.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908"
+ sodipodi:nodetypes="cc"
+ 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>
+ <path
+ style="opacity:0.9;fill:none;stroke:#d5e5ff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22910"
+ sodipodi:nodetypes="cc"
+ 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="ccccccccccccc"
+ style="fill:url(#linearGradient22933);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937);stroke-width:1;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920"
+ 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
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922"
+ 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="path22924"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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"
+ sodipodi:nodetypes="cc"
+ id="path22926"
+ d="m 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#d5e5ff;stroke-width:1.29999995;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:none;stroke:url(#linearGradient22939);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient22941);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23411"
+ transform="translate(-399,-19)">
+ <rect
+ transform="scale(-1,1)"
+ y="260"
+ x="-441"
+ height="16"
+ width="16"
+ id="rect22167"
+ 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="g23378">
+ <g
+ transform="translate(-36.00033,108.00006)"
+ id="g22183">
+ <path
+ style="fill:url(#linearGradient23445);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.66961 -3,1.5 l 0,8 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 0,-8 c 0,-0.83039 -1.0691,-1.5 -3,-1.5 z"
+ id="path22187"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23447);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 470.50029,158.5 0,7.51105 c 0,0.54648 1,0.54648 2,0.54648 1,0 2,0 2,-0.55753 l 0,-7.51105"
+ id="path22189"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#eff6ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22199"
+ sodipodi:cx="108"
+ 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"
+ transform="matrix(0.9067635,0,0,1.3047091,374.56954,447.97555)" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path22203"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.5 -3,1.5 l 0,8 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 0,-8 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cssc"
+ id="path23068"
+ d="m 436.5,265.5 0,-0.75 c 0,-4.25 -7,-4.25 -7,0 l 0,2.75"
+ style="opacity:0.55;fill:none;stroke:#0b1728;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"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.1;fill:none;stroke:#e1e08e;stroke-width:4;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="rect22214"
+ width="2.9999998"
+ height="3"
+ x="428"
+ y="266"
+ rx="1.2002208"
+ ry="1.2002208" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#0b1728;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"
+ d="m 436.5,265.5 0,-0.75"
+ id="path23343"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#d7e3f4;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 436.5,265.5 0,-0.75 c 0,-4.25 -7,-4.25 -7,0 l 0,2.75"
+ id="path22210"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.2002209"
+ y="266"
+ x="428"
+ height="3"
+ width="3"
+ id="rect22216"
+ style="opacity:0.4;fill:#a09f2c;fill-opacity:1;fill-rule:nonzero;stroke:#d6d562;stroke-width:2;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.2002209" />
+ <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="path23005"
+ d="m 427,266 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;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"
+ d="m 427,270 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23007"
+ 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="path23009"
+ d="m 430.99994,270 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;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"
+ d="m 430.99994,266.00006 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23012"
+ 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:#545306;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 428.25,266.25 0.75,-0.75 1,0 0.75,0.75 0.75,0.75 0,1 -0.75,0.75 -0.75,0.75 -1,0 -0.75,-0.75 -0.75,-0.75 0,-1 0.75,-0.75 z"
+ id="rect23002"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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="path22218"
+ d="m 428,267 c 1,0 1.99998,10e-6 2.99998,10e-6 0,0.33335 0,0.6667 0,1.00005 -1,0 -1.99998,-1e-5 -2.99998,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 428.99996,269 c 0,-0.99999 1e-5,-1.99995 1e-5,-2.99994 0.33335,0 0.6667,0 1.00005,0 0,0.99999 -1e-5,1.99995 -1e-5,2.99994 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path22220"
+ 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;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 427,266 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23312"
+ 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="path23314"
+ d="m 427,270 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 430.99994,270 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23316"
+ 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="path23318"
+ d="m 430.99994,266.00006 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.65"
+ id="g23333"
+ transform="translate(464,-83)">
+ <g
+ id="g23320">
+ <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="path23014"
+ d="m -38,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ style="fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#504f14;stroke-width:1.20000005;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#504f14;stroke-width:1.20000005;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"
+ d="m -32.000059,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 l 0,0 0,0 0,0 z"
+ id="path23016"
+ 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="path23018"
+ d="m -35,354 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ style="fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#504f14;stroke-width:1.20000005;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23325"
+ style="fill:#ffffff;stroke:none">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -38,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ id="path23327"
+ 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="path23329"
+ d="m -32.000059,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -35,354 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ id="path23331"
+ 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>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g22853"
+ transform="translate(4.2e-4,2.056923)">
+ <g
+ style="display:inline"
+ 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="g22355"
+ transform="translate(296.99995,249.99998)">
+ <rect
+ transform="matrix(1,5.248259e-6,0,1,0,0)"
+ y="15.999177"
+ x="155.00008"
+ height="3.9999785"
+ width="4.0000005"
+ id="rect22359"
+ style="fill:url(#linearGradient23531);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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
+ 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:#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="rect22365"
+ width="4.9999776"
+ height="4.9999595"
+ x="154.50008"
+ y="15.499179"
+ transform="matrix(1,5.248259e-6,0,1,0,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="path22367"
+ d="m 155.50007,19.49999 -5.5e-4,-3.000005 2.99988,5e-6 6.8e-4,3 -3.00001,0 0,0 0,0 0,0 z"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient23533);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(187.99958,-21.0368)"
+ id="g23427">
+ <g
+ transform="translate(170.04549,179.51905)"
+ id="g23429"
+ style="opacity:0.7">
+ <path
+ style="fill:none;stroke:#214478;stroke-width:2.5;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 90.45451,103.98095 0,11 11,0 0,-11 -11,0 z"
+ id="path23431"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23433"
+ d="m 90.45451,103.98095 0,11 11,0 0,-11 -11,0 z"
+ style="fill:none;stroke:#afc6e9;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>
+ <g
+ id="g23435">
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="293.5"
+ x="270.49985"
+ height="3"
+ width="2.9998772"
+ id="rect23438"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.5;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:#0b1728;stroke-width:1.5;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="rect23440"
+ width="2.9998772"
+ height="3"
+ x="258.50024"
+ y="281.5368"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="293.49997"
+ x="258.49969"
+ height="3"
+ width="2.9998772"
+ id="rect23442"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.5;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
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 273,294 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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="path23444"
+ 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="path23446"
+ d="m 261,294 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path23448"
+ d="m 261.00042,282.0368 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.5;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="rect23450"
+ width="2.9998772"
+ height="3"
+ x="270.49985"
+ y="281.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <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="path23452"
+ d="m 273,282 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g40939"
+ 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="rect31966"
+ width="16"
+ height="16"
+ x="47"
+ y="260" />
+ <g
+ transform="translate(0,21)"
+ id="g40631">
+ <rect
+ style="fill:#87aade;fill-opacity:1;fill-rule:nonzero;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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40597"
+ width="5"
+ height="3"
+ x="56.500004"
+ y="240.5" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40599"
+ d="m 48.5,244.5 5,0 0,3 8,0 0,6 -13,0 0,-9 z"
+ style="fill:url(#linearGradient40965);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ d="m 49,250.5 12,0 m -4.5,-2.5 0,2.5 m -5,-2.5 0,2.5 m 2,2.5 0,-2.5 m 5,2.5 0,-2.5 m -5.5,-3 -4,0"
+ style="fill:none;stroke:url(#linearGradient40967);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ id="path40601"
+ inkscape:connector-curvature="0" />
+ <path
+ 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:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 48.5,244.5 5,0 0,3 8,0 0,6 -13,0 0,-9 z"
+ id="path40603"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40605"
+ d="m 49.5,246.5 0,-1 3,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 49.5,249.5 0,-1 1,0"
+ id="path40615"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 57.5,242.5 0,-1 3,0"
+ id="use40619"
+ inkscape:connector-curvature="0" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40963"
+ transform="translate(3,3)"
+ width="600"
+ height="512" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40969"
+ transform="translate(8,3)"
+ width="600"
+ height="512"
+ style="opacity:0.9" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40971"
+ transform="translate(0,6)"
+ width="600"
+ height="512" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40973"
+ transform="translate(5,6)"
+ width="600"
+ height="512" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40615"
+ id="use40975"
+ transform="translate(10,3)"
+ width="600"
+ height="512"
+ style="opacity:0.9" />
+ </g>
+ </g>
+ <g
+ id="g40825"
+ transform="translate(0,1)">
+ <rect
+ y="260"
+ x="215"
+ height="16"
+ width="16"
+ id="rect40827"
+ 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"
+ 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="g40829"
+ transform="translate(67.999923,253.00001)">
+ <path
+ style="fill:url(#linearGradient40843);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 148.50005,9.5 7.00001,3.68e-5 1e-5,2.9999632 -4,0 0,4 -3.00002,0.0039 0,-7.00391 0,10e-6 z"
+ id="path40831"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(1,5.248259e-6,0,1,0,0)"
+ y="14.499187"
+ x="153.49606"
+ height="6.9999576"
+ width="7.004014"
+ id="rect40833"
+ style="fill:url(#linearGradient40845);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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
+ sodipodi:nodetypes="ccccccc"
+ id="path40835"
+ d="m 148.50005,9.5 7.00001,3.68e-5 1e-5,2.9999632 -4,0 0,4 -3.00002,0.0039 0,-7.00391 0,10e-6 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 149.50015,15.500012 7e-5,-5.000011 4.99993,0"
+ id="path40837"
+ 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" />
+ <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"
+ 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:7.40000265;display:inline"
+ id="rect40839"
+ width="7.004014"
+ height="6.9999576"
+ x="153.49606"
+ y="14.499187"
+ transform="matrix(1,5.248259e-6,0,1,0,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="path40841"
+ d="m 154.50063,20.499995 6e-5,-4.999998 4.99933,0 6e-5,4.999993 -4.99945,5e-6 z"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient40847);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23613" />
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(404,214.02012)"
+ id="g13021">
+ <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"
+ width="16"
+ height="16"
+ x="63"
+ y="48" />
+ <g
+ id="g12991"
+ 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"
+ transform="matrix(1.0003553,0,0,0.9995949,19.983834,-40.953347)">
+ <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"
+ style="opacity:0.35;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect13004"
+ width="10.996093"
+ height="11.004457"
+ x="45.5"
+ y="91.49041" />
+ <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="opacity:0.2;fill:none;stroke:url(#linearGradient23510);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 46.499645,101.49618 0,-9.003652 8.996803,-0.0017 0,9.003642 -8.996803,0.002 0,-2.9e-4 0,0 0,0 z"
+ id="path13009"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient23512);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 53.247247,91.490409 3.248846,0.0015 0,11.002931 -10.996093,1e-5 0,-3.251316 7.747247,-7.753141 0,1.6e-5 z"
+ id="rect12993"
+ sodipodi:nodetypes="cccccc"
+ 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:url(#linearGradient23514);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 46.499451,101.49446 1.94e-4,-1.750708 7.247425,-7.252938 1.749378,0 10e-7,9.001936 -8.996998,0.002 0,-2.9e-4 0,0 0,0 z"
+ id="path12995"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </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"
+ transform="translate(-42.01991,-103.9242)">
+ <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"
+ id="rect23589"
+ width="16"
+ height="16"
+ x="-382.01102"
+ y="403.99695" />
+ <g
+ id="g23591">
+ <rect
+ style="fill:none;stroke:#04090f;stroke-width:2.89999986;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23594"
+ width="8.4671335"
+ height="5.6703448"
+ x="-33.946648"
+ y="-559.34406"
+ ry="2.143424"
+ rx="2.1489482"
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)" />
+ <rect
+ rx="2.1489475"
+ ry="2.1434233"
+ y="-557.84644"
+ x="-28.308893"
+ height="5.5734196"
+ width="8.5043812"
+ id="rect23596"
+ style="fill:none;stroke:#04090f;stroke-width:2.89999986;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24349);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 411.51991,375.4242 -0.5,-0.5 c -0.69131,-0.69131 -0.87523,-2.06255 1.2e-4,-2.92851 l 3.01169,-2.97968 c 0.87526,-0.86596 2.29698,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ id="path23598"
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:0.10736198;fill-rule:nonzero;stroke:#04090f;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.50000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 408.98474,371.9281 c 0.84182,-0.84182 2.19551,-0.84356 3.03517,-0.004"
+ id="path23561"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ id="path24352"
+ d="m 411.51991,375.4242 -0.5,-0.5 c -0.69131,-0.69131 -0.87523,-2.06255 1.2e-4,-2.92851 l 3.01169,-2.97968 c 0.87526,-0.86596 2.29698,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ style="opacity:0.68999999;fill:none;stroke:url(#radialGradient24354);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23600"
+ style="fill:none;stroke:url(#linearGradient24341);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 407.52985,379.36839 c 0.5623,0.50813 1.81497,0.33519 2.49825,-0.3481 l 2.95063,-3.084 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.95063,3.08399 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 1e-5,-9e-5 0,0 0,0 z"
+ sodipodi:nodetypes="ccccccczz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccczz"
+ d="m 407.52985,379.36839 c 0.5623,0.50813 1.81497,0.33519 2.49825,-0.3481 l 2.95063,-3.084 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.95063,3.08399 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 1e-5,-9e-5 0,0 0,0 z"
+ style="fill:none;stroke:url(#radialGradient23610);stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path23602"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:0.10736198;fill-rule:nonzero;stroke:#04090f;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.50000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.01991,375.9242 c -0.84182,0.84182 -2.16034,0.83966 -3,0"
+ id="path23563"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssssc"
+ id="path23604"
+ d="m 417.52541,369.52542 0.49841,0.4984 c 0.68807,0.68805 0.86671,2.11766 -0.004,2.98828 l -2.99178,2.99178 c -0.68328,0.68328 -1.74799,0.71589 -2.49825,0.34809 -0.18628,-0.0913 -0.37463,-0.2925 -0.51148,-0.42936 l -0.7484,-0.74841"
+ style="fill:none;stroke:url(#radialGradient23612);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g22800"
+ transform="translate(-21,2)">
+ <rect
+ y="260"
+ x="530"
+ height="16"
+ width="16"
+ id="rect23587"
+ 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
+ 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="opacity:0.35;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect23591"
+ width="4.0000005"
+ height="15"
+ x="533.5"
+ y="260.5" />
+ <path
+ style="fill:url(#linearGradient22847);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 533.5,275.5 4,0 0,-1 c 0,-2.5 2,-5 5,-5 l 1,0 0,-4 -1,0 c -5.17135,0 -9,3.25 -9,9 l 0,1 z"
+ id="path23595"
+ sodipodi:nodetypes="ccssccssc"
+ 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="opacity:0.2;fill:none;stroke:url(#linearGradient22849);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 534.50003,274.5 0,-12.99752 1.99998,-0.002 0,12.99752 -1.99998,0.002 z"
+ id="path23593"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23709"
+ d="m 542.5,266.5 c -4.89085,0.22833 -7.75,2.75 -8,8"
+ style="fill:none;stroke:url(#linearGradient22851);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>
+ <g
+ id="g23347"
+ transform="translate(251.98387,128)"
+ style="display:inline">
+ <rect
+ y="428"
+ x="26.016129"
+ height="16.000002"
+ width="16.000006"
+ id="rect23350"
+ 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" />
+ <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="rect23352"
+ width="16"
+ height="16"
+ x="26"
+ y="428" />
+ <g
+ style="display:inline"
+ id="g23354"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23356"
+ style="fill:#724c4c;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10749674;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"
+ 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.81218,0,0,0.815735,163.7897,-27.2907)" />
+ <path
+ transform="matrix(0.7480284,0,0,0.7480284,172.26025,-19.267349)"
+ sodipodi:type="arc"
+ style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.16363633;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23358"
+ 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
+ transform="matrix(0.7478104,0,0,0.7510504,172.29077,-19.598754)"
+ 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="path23360"
+ style="opacity:0.6;fill:url(#linearGradient23373);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ id="path40668"
+ d="m 269.98748,62.965763 c -1.39411,0.455357 -2.67784,0.634788 -4.24803,3.011091 l 2.24896,0 1.99907,-3.011091 0,0 0,0 0,0 z m 0.99954,0 0,3.011091 2.99861,0 -1.99908,-3.011091 -0.99953,0 z m 2.99861,3.011091 0.99953,3.011091 1.99907,0 c 0.006,-0.929403 -0.1914,-1.917894 -0.74965,-3.011091 l -2.24895,0 0,0 0,0 0,0 z m 0.99953,3.011091 -3.99814,0 0,3.011092 2.49884,0 1.4993,-3.011092 z m -3.99814,3.011092 -2.99861,0 1.99907,3.011091 0.99954,0 0,-3.011091 0,0 0,0 0,0 z m -2.99861,0 -0.99954,-3.011092 -1.99907,0 c -0.006,0.929404 0.1914,1.917895 0.74965,3.011092 l 2.24896,0 0,0 0,0 0,0 z m -0.99954,-3.011092 3.99815,0 0,-3.011091 -2.49884,0 -1.49931,3.011091 0,0 0,0 0,0 z m 7.24312,3.011092 -1.85125,3.011091 c 1.3675,-0.485137 2.19971,-0.728674 3.85384,-3.011091 l -2.00259,0 z"
+ style="fill:url(#linearGradient23375);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" />
+ <path
+ style="fill:#990d18;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 274.00069,72.011668 0.005,0.97479 -0.99045,0.01431 -0.0223,1.019377 -0.481,0.837285 c 0.77072,-0.321774 2.72643,-1.067855 3.69499,-2.816464 l -2.20604,-0.0293 -2e-4,2e-6 0,0 0,0 z"
+ id="path23365"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient23377);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path40671"
+ 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.749782,0,0,0.752489,172.03052,-19.77379)" />
+ <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="path23369"
+ style="fill:none;stroke:url(#linearGradient23379);stroke-width:1.14049816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.7010701,0,0,0.7040938,178.4346,-14.083074)" />
+ <path
+ id="path23371"
+ d="m 268.98793,64.973163 0,0.407752 -0.93706,0 0,0.595945 -0.56224,0 0,1.003697 -0.49977,0 0,1.505546 0.99953,0 0,-1.505546 0.4373,0 0,-0.595945 0.56224,0 0,-0.407752 1.53054,0 0,-1.003697 -1.53054,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#aaccff;stroke-width:0;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" />
+ </g>
+ </g>
+ <g
+ id="g22826"
+ transform="translate(21,-18.979877)">
+ <rect
+ y="281"
+ x="509"
+ height="16"
+ width="16"
+ id="rect22743"
+ 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="g22808">
+ <g
+ id="g23567">
+ <path
+ style="fill:url(#linearGradient23565);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 511.5,282.5 1.25,0 1.5,1 5.5,0 1.5,-1 1.25,0 0,8.25 c 0,6.25 -11,6.25 -11,0 l 0,-8.25 z"
+ id="path22751"
+ sodipodi:nodetypes="ccccccccc"
+ 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:url(#linearGradient23562);stroke-width:0.99999982px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 512.5,291 0,-7.25 c 0.8354,1.24437 8.04784,1.12713 9,0 l 0,7.25 c 0,4.5 -9,4.5 -9,0 z"
+ id="path22753"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23624"
+ style="opacity:0.5">
+ <g
+ id="g23620">
+ <rect
+ y="286"
+ x="514"
+ height="3"
+ width="3"
+ id="rect23592"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.0220957"
+ ry="1.1453303" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518.8317,286 1.3366,0 c 0.46076,0 0.8317,0.49209 0.8317,1.10334 l 0,0.79332 C 521,288.50791 520.62906,289 520.1683,289 l -1.3366,0 C 518.37094,289 518,288.50791 518,287.89666 l 0,-0.79332 C 518,286.49209 518.37094,286 518.8317,286 z"
+ id="rect23595"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23614">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23599"
+ width="2"
+ height="2"
+ x="514"
+ y="290" />
+ <rect
+ y="291"
+ x="515"
+ height="2"
+ width="4.5"
+ id="rect23601"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;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:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23607"
+ width="1.25"
+ height="2"
+ x="519.5"
+ y="290" />
+ </g>
+ </g>
+ <path
+ style="fill:#0b1728;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 514,287.25 1.25,-1.25 0.75,0 0,2 -2,0 0,-0.75 z"
+ id="rect23575"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="290"
+ x="514"
+ height="1"
+ width="1"
+ id="rect23577"
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23579"
+ width="4"
+ height="1"
+ x="515"
+ y="291" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23583"
+ width="1"
+ height="1"
+ x="519"
+ y="290" />
+ <path
+ style="fill:#0b1728;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 520,286 -0.75,0 -1.25,1.25 0,0.75 2,0 0,-2 z"
+ id="rect23597"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24003"
+ transform="translate(210,-37)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g24005"
+ transform="translate(90,-142)">
+ <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="rect24007"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
+ <g
+ transform="translate(1,0)"
+ id="g24009">
+ <g
+ transform="translate(-386,446.5)"
+ id="g24011">
+ <path
+ id="path24028"
+ 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:#1a1a1a;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="path24030"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g24032">
+ <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="path24034"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path24036"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient24052);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="path24039"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient24054);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24041"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24056);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="path24044"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24062"
+ d="m 202.5,135.71875 -6,2.18085 0,7.36038 6,3.27127 6,-3.27127 0,-7.36038 -6,-2.18085 z"
+ style="opacity:0.65;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(-259,202)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:none;stroke:url(#linearGradient24066);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -56.5,337.71875 -6,2.18085 0,7.36038 6,3.27127 6,-3.27127 0,-7.36038 -6,-2.18085 z"
+ id="path24058"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24046"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-1081.9421,-238.02038)" />
+ </g>
+ <g
+ id="g24311"
+ transform="translate(-16.99965,-228.99997)">
+ <g
+ style="opacity:0.55"
+ transform="translate(21.0003,-3e-5)"
+ id="g24226">
+ <g
+ transform="translate(43.04504,242.48228)"
+ id="g24228">
+ <path
+ style="opacity:0.8;fill:none;stroke:#333333;stroke-width:2.5;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 90.45451,103.98095 0,7 7.00045,0.0368 0,-7 -7.00045,-0.0368 z"
+ id="path24230"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path24232"
+ d="m 90.45451,103.98095 4.5e-4,7.03677 7,0 -4.5e-4,-7.03677 -7,0 z"
+ style="fill:#989898;fill-opacity:1;fill-rule:evenodd;stroke:#e6e6e6;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>
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect24234"
+ width="2.9998772"
+ height="3"
+ x="139.50012"
+ y="352.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="344.50003"
+ x="131.4998"
+ height="3"
+ width="2.9998772"
+ id="rect24236"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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="rect24238"
+ width="2.9998772"
+ height="3"
+ x="131.50012"
+ y="352.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <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="path24240"
+ d="m 142.00027,353 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 134.00042,353.00003 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="path24242"
+ 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;display:inline"
+ d="m 133.99997,345.00003 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="path24244"
+ 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
+ rx="1.4999386"
+ ry="1.4999386"
+ y="344.5"
+ x="139.49985"
+ height="3"
+ width="2.9998772"
+ id="rect24246"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 142,345 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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="path24248"
+ 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>
+ <g
+ id="g24250"
+ transform="translate(16.999682,3.99994)">
+ <g
+ id="g24252"
+ transform="translate(43.04504,242.48228)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path24254"
+ d="m 90.45451,103.98095 0,7 7.00045,0.0368 0,-7 -7.00045,-0.0368 z"
+ style="opacity:0.8;fill:none;stroke:#333333;stroke-width:2.5;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:#c3c3c3;fill-opacity:1;fill-rule:evenodd;stroke:#e6e6e6;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 90.45451,103.98095 4.5e-4,7.03677 7,0 -4.5e-4,-7.03677 -7,0 z"
+ id="path24256"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="352.5"
+ x="139.50012"
+ height="3"
+ width="2.9998772"
+ id="rect24258"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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="rect24260"
+ width="2.9998772"
+ height="3"
+ x="131.4998"
+ y="344.50003"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="352.5"
+ x="131.50012"
+ height="3"
+ width="2.9998772"
+ id="rect24262"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 142.00027,353 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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="path24264"
+ 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="path24266"
+ d="m 134.00042,353.00003 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path24268"
+ d="m 133.99997,345.00003 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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="rect24270"
+ width="2.9998772"
+ height="3"
+ x="139.49985"
+ y="344.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <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="path24272"
+ d="m 142,345 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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"
+ transform="translate(-60,60)">
+ <rect
+ y="-29"
+ x="128"
+ height="16"
+ width="16"
+ id="rect23087"
+ 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" />
+ <g
+ id="g23937">
+ <path
+ sodipodi:nodetypes="cscc"
+ d="m 140,-21 c 1.125,1 3.5,0.25 3.5,-1 0,-1.5 0.47443,-1.637992 -2,-1.5 -0.1033,1.43128 -0.66697,1.819388 -1.5,2.5 z"
+ style="fill:#999999;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23906"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23099"
+ style="fill:#e6e6e6;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 132,-21 c -1.125,1 -3.5,0.25 -3.5,-1 0,-1.5 -0.47443,-1.637992 2,-1.5 0.1033,1.43128 0.66697,1.819388 1.5,2.5 z"
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23090"
+ style="fill:url(#linearGradient23971);fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 135.75,-25.5 -1.25,-2 -0.75,0 -3.25,2.75 0,1.25 c 0.15379,2.182132 1.3678,1.901463 3,4 l 0,4.5 c 0,1.5 1.5,1.5 2.5,1.5 1,0 2.5,0 2.5,-1.5 l 0,-4.5 c 1.62605,-2.090636 2.83897,-1.844587 3,-4 l 0,-1.25 -3.25,-2.75 -0.75,0 -1.25,2"
+ sodipodi:nodetypes="cccccccsccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23876"
+ width="2"
+ height="1"
+ x="135"
+ y="-16" />
+ <rect
+ y="-21"
+ x="135"
+ height="2"
+ width="2.75"
+ id="rect23881"
+ style="fill:url(#linearGradient24099);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="1"
+ rx="1" />
+ <rect
+ 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"
+ id="rect23883"
+ width="2"
+ height="1"
+ x="135"
+ y="-21" />
+ <path
+ sodipodi:type="arc"
+ style="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"
+ id="path23902"
+ sodipodi:cx="133"
+ 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"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path23125"
+ style="fill:none;stroke:url(#linearGradient23973);stroke-width:0.93034029;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: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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path23900"
+ style="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"
+ sodipodi:type="arc" />
+ <rect
+ y="-15"
+ x="135"
+ height="1"
+ width="2"
+ id="rect23914"
+ 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" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccs"
+ d="m 131.88556,-21.103144 c 0.4583,0.371362 1.00745,1.072735 1.61444,1.853144 l 0,3.75 c 0,1.5 1.5,2 2.5,2 1,0 2.5,-0.5 2.5,-2 l 0,-3.75 c 0.64842,-0.833678 1.23114,-1.545786 1.70766,-1.936772 M 130.5,-23.5 l 0,-1.25 3,-2.75 1,0 1.25,1.75 0.5,0 1.25,-1.75 1,0 3,2.75 0,1.25"
+ 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="path23924"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient23975);stroke-width:0.94079971;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="path23960"
+ sodipodi:cx="133"
+ 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"
+ transform="matrix(1.2116904,0,0,1.1282344,-22.693138,2.3776257)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23970"
+ sodipodi:cx="133"
+ 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"
+ 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"
+ d="M 136.75,-24.75 138,-26.5"
+ id="path23929"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23978"
+ d="m 129.25,-22.25 0.5,-0.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 142.75,-22.5 -0.25,-0.25"
+ id="path23980"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24504"
+ 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"
+ id="rect23149"
+ width="16"
+ height="16"
+ x="-441"
+ y="281"
+ transform="scale(-1,1)" />
+ <g
+ id="g24488">
+ <g
+ id="g24377"
+ 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"
+ transform="matrix(-1.0003553,0,0,0.9995949,486.01617,193.04665)">
+ <path
+ style="fill:url(#linearGradient24539);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.70001745;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 55.496449,92.490815 4.998228,0.0015 -1e-6,6.000906 -4.998227,-4e-6 m -5.997869,0 -3.99858,10e-7 10e-7,-6.002432 3.998579,0"
+ id="path24388"
+ sodipodi:nodetypes="cccccccc"
+ 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:url(#linearGradient24541);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 55.496399,97.494124 3.998631,4.3e-4 10e-7,-4.003331 -3.998582,-3e-6 m -5.997771,-8.55e-4 -2.999032,8.54e-4 -1.96e-4,4.001622 2.99913,0"
+ id="path24390"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.5"
+ id="g23153"
+ transform="translate(-39.00033,129)">
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path23156"
+ d="m 472.50033,152.49994 c -1.9309,0 -3,0.66961 -3,1.5 L 469.50029,166 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 4e-5,-12.00006 c 0,-0.83039 -1.0691,-1.5 -3,-1.5 z"
+ style="fill:url(#linearGradient24543);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23158"
+ d="m 470.50033,153.99994 -4e-5,12.01111 c 0,0.54648 1,0.54648 2,0.54648 1,0 2,0 2,-0.55753 l 4e-5,-12.01111"
+ style="fill:none;stroke:url(#linearGradient24545);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ 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"
+ sodipodi:ry="1.2798798"
+ sodipodi:rx="3.3084693"
+ sodipodi:cy="-222"
+ sodipodi:cx="108"
+ id="path23160"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#1a1a1a;stroke-width:0.69999999;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50033,152.49994 c -0.62477,0 -1.15931,0.0523 -1.5966,0.15704 -0.91421,0.21887 -1.4034,0.66652 -1.4034,1.34296 L 469.50029,166 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 4e-5,-12.00006 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ id="path23163"
+ sodipodi:nodetypes="csccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24547);stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 469.50033,154 c 0,1.5 1.0691,1.5 3,1.5 1.9309,0 3,-0.25 3,-1.5"
+ id="path24484"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path24404"
+ style="fill:url(#linearGradient24549);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 436.5,292 c -2.9e-4,-0.74999 -2.9e-4,-6.75005 0,-6.00006 2.9e-4,0.74999 -1.0691,1.5 -3,1.5 -1.9309,0 -3,-0.66961 -3,-1.5 0,-0.83039 0,5.16967 0,6.00006 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 z"
+ sodipodi:nodetypes="ccsccsc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.75001,287.5 c 0,0.54447 0.98001,0.98352 2.75,0.98352 1.77,0 2.75027,-0.49177 2.75,-0.98352"
+ id="path24464"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24472"
+ style="fill:none;stroke:url(#linearGradient24551);stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.5,285.75 0,5.5 m 6,-5.5 0,5.5"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path24424"
+ d="m 430.5,285.5 0,0.5 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 0,-0.5"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.5,291.5 0,0.75 c 0,0.75 1.0691,1.25 3,1.25 1.9309,0 3,-0.5 3,-1.25 l 0,-0.75"
+ id="path24470"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24095"
+ transform="translate(126,23)">
+ <g
+ style="opacity:0.45;display:inline"
+ id="g23290"
+ transform="translate(216,191)">
+ <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="rect23292"
+ width="16"
+ height="16"
+ x="83"
+ y="48" />
+ <g
+ style="display:inline"
+ id="g23294"
+ transform="matrix(1.1658027,0,0,1.1657997,-59.289717,-204.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
+ 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="path23297"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient24112);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path23299"
+ 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.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)" />
+ <path
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient24114);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path23301"
+ 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" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,-1)"
+ id="g23266"
+ style="display:inline;enable-background:new">
+ <g
+ id="g24238">
+ <path
+ style="opacity:0.7;fill:url(#linearGradient24116);fill-opacity:1;fill-rule:nonzero;stroke:#132747;stroke-width:0.69999999;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 313.25,246.5 c -2.13129,3.51035 -4.20028,0.92659 -6.75,0 -2.5,-0.90852 -5.25,-1.69675 -5.75,-0.25 -1,3.5 1.75,8.25 6.25,8.25 4.5,0 7.25,-4.5 6.25,-8 z"
+ id="path24164"
+ sodipodi:nodetypes="csczc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path24220"
+ d="M 301.49346,248.00351 C 300.75,245 304.5,246.75 307.5,247.5"
+ style="fill:none;stroke:url(#linearGradient24118);stroke-width:1.00000083;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ 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.0828313,0,0,1.0828897,167.85295,5.9780113)"
+ id="g24116"
+ style="display:inline;enable-background:new"
+ clip-path="url(#clipPath24168)">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient24121);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.98504531;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="path24134"
+ 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
+ transform="matrix(0.6352868,0,0,0.6352859,44.642106,148.53594)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient24123);stroke-width:1.45364487;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path24144"
+ 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" />
+ </g>
+ <path
+ sodipodi:nodetypes="cs"
+ id="path24166"
+ d="m 306.9667,246.52825 c -1.63301,1.38546 -3.26623,2.75322 -4.93069,1.49745"
+ style="fill:none;stroke:#132747;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 313.25,246.25 c -1,-3.5 -4.2097,-1.48101 -6.2833,0.27825"
+ id="path24198"
+ sodipodi:nodetypes="cs"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41107"
+ 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="rect41109"
+ width="16"
+ height="16"
+ x="110"
+ y="260" />
+ <g
+ style="display:inline"
+ id="g41111"
+ transform="translate(-92.033883,254)">
+ <g
+ id="g41113"
+ transform="translate(20.05,-0.09375)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41115"
+ d="m 195.7,12.34375 -8.21612,8.25"
+ style="fill:none;stroke:#0b1728;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.941788,0.336207,-0.336207,0.941788,16.5539,-62.39971)"
+ id="g41117">
+ <path
+ sodipodi:nodetypes="csccsc"
+ id="path41119"
+ d="m 191.82819,15.661146 c -2.50169,-2.892812 -3.51599,-3.257525 -5.63502,-2.501059 -1.55469,0.555005 -3.0441,1.883066 -4.82641,-0.135198 l 3.04462,-5.5995832 c 1.58362,1.6624741 2.57888,1.2029919 3.73322,0.7909034 1.64813,-0.5883624 2.98174,-0.5189446 6.10591,2.3329558"
+ style="fill:url(#linearGradient41127);fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient41129);stroke-width:0.85000008;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 184.59619,8.6865928 -2.20359,4.2375362 c 0.98797,0.735441 2.20267,0.01003 3.54842,-0.470383 2.11902,-0.756466 3.52208,-0.551271 5.62148,1.765004 l 1.625,-3.46875 c -2.19923,-2.2239943 -3.61351,-2.2477085 -5.02619,-1.7433979 -1.08094,0.3858805 -2.30419,0.5856276 -3.56512,-0.3200093 z"
+ id="path41121"
+ sodipodi:nodetypes="ccsccsc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#6593d4;fill-opacity:1;fill-rule:evenodd;stroke:#87aade;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 195.7,12.34375 -8.21612,8.25"
+ id="path41123"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41125"
+ d="m 191.6399,15.190092 3.2987,-3.242382"
+ style="opacity:0.5;fill:#6593d4;fill-opacity:1;fill-rule:evenodd;stroke:#2c5aa0;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41132"
+ transform="translate(237.98389,298.06154)">
+ <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"
+ y="195"
+ x="124.01612"
+ height="16"
+ width="16"
+ id="rect41134"
+ 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="g41136">
+ <path
+ id="path41138"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 131.51612,200.41538 0,3.2 3,1.88462 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9.08462 3,0.0846 2,-3 m -10.75,0.25 2.25,2.66538 3.5,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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:#acacac;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect41140"
+ width="2"
+ height="1.9692308"
+ x="130.01611"
+ y="196.96924"
+ 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
+ y="196.96924"
+ x="130.01611"
+ height="1.9692308"
+ width="2"
+ id="rect41142"
+ style="opacity:0.95;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;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" />
+ <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="path41144"
+ style="fill:none;stroke:url(#linearGradient41170);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 125.76612,197.75 2.25,2.75 3.5,0 m 0,0 0,3 3,2 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9 3,0 2,-3"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41146"
+ 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"
+ id="rect41148"
+ width="16"
+ height="16"
+ x="263"
+ y="194" />
+ <g
+ id="g41150"
+ transform="translate(0,-1)">
+ <path
+ id="path41152"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ sodipodi:nodetypes="ccccccc"
+ 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:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect41154"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196"
+ 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"
+ sodipodi:nodetypes="ccccccc"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23087"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ style="fill:none;stroke:url(#linearGradient41172);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path41157"
+ 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
+ y="196"
+ x="269.76608"
+ height="2.75"
+ width="2.4999998"
+ id="rect41159"
+ style="opacity:0.5;fill:none;stroke:url(#radialGradient41174);stroke-width:2;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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect41161"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;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" />
+ </g>
+ </g>
+ <g
+ transform="translate(28.983879,319.02657)"
+ id="g41999"
+ 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="rect42001"
+ width="16"
+ height="16"
+ x="124.01612"
+ y="195"
+ 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="translate(6.71875e-6,0.03077095)"
+ style="display:inline;enable-background:new"
+ id="g42059">
+ <path
+ id="path42061"
+ style="fill:none;stroke:#000000;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 131.51612,200.41538 0,3.2 3,1.88462 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 -0.002,3.68505 m 3.00187,-8.76967 3,0.0846 2,-3 m -10.75,0.25 2.25,2.66538 3.5,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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:#acacac;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42063"
+ width="2"
+ height="1.9692308"
+ x="130.01611"
+ y="196.97343"
+ 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
+ y="196.97343"
+ x="130.01611"
+ height="1.9692308"
+ width="2"
+ id="rect42065"
+ style="opacity:0.95;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;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" />
+ <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="path42067"
+ style="fill:none;stroke:url(#linearGradient42069);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 125.76612,197.75 2.25,2.75 3.5,0 m 0,0 0,3 3,2 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 -0.002,3.68505 m 3.00187,-8.68505 3,0 2,-3"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-19.00001,-0.03076)"
+ style="display:inline;enable-background:new"
+ id="g42015">
+ <g
+ id="g42017"
+ transform="translate(-1.999999,-8.9958)">
+ <path
+ id="path42019"
+ d="m 145.99053,204.49753 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ style="fill:none;stroke:#964e00;stroke-width:1.49505997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ 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="path42021"
+ d="m 147.00606,204.9958 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ style="fill:#ffd4a5;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>
+ <g
+ id="g42023"
+ transform="translate(0,-1)">
+ <path
+ style="fill:none;stroke:#964e00;stroke-width:1.49505997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156.00059,196.50173 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ id="path42025"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 157.01612,197 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ id="path42027"
+ 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>
+ </g>
+ </g>
+ <g
+ transform="translate(120,68)"
+ id="g42071"
+ style="display:inline;enable-background:new">
+ <rect
+ y="194"
+ x="263"
+ height="16"
+ width="16"
+ id="rect42073"
+ 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,-1)"
+ id="g42075">
+ <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="ccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ style="fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:3.0999999;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="path42077"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect42079"
+ style="fill:none;stroke:#0b1728;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ id="path42081"
+ style="fill:none;stroke:#0b1728;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"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccc"
+ 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="path42083"
+ style="fill:none;stroke:url(#linearGradient42093);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 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <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="opacity:0.5;fill:none;stroke:url(#radialGradient42091);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42085"
+ width="2.4999998"
+ height="2.75"
+ x="269.76608"
+ y="196" />
+ <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:#c8d8f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42087"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196" />
+ </g>
+ </g>
+ <g
+ transform="translate(-111,236)"
+ id="g42095"
+ style="display:inline;enable-background:new">
+ <rect
+ y="194"
+ x="263"
+ height="16"
+ width="16"
+ id="rect42097"
+ 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,-1)"
+ id="g42099">
+ <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="ccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ style="fill:none;stroke:#241300;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42101"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect42103"
+ style="fill:none;stroke:#2b1600;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ id="path42105"
+ style="fill:none;stroke:#241300;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccc"
+ 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="path42107"
+ style="fill:none;stroke:#ffad55;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 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <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="opacity:0.5;fill:none;stroke:url(#radialGradient42115);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42109"
+ width="2.4999998"
+ height="2.75"
+ x="269.76608"
+ y="196" />
+ <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:#ffb769;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42111"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ style="fill:none;stroke:url(#linearGradient42121);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"
+ id="path42117"
+ 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>
+ </g>
+ <g
+ transform="translate(113.22629,214.3098)"
+ id="g42123"
+ 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="rect42125"
+ width="16"
+ height="16"
+ x="124.01612"
+ y="195"
+ 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="g42127"
+ style="opacity:0.8">
+ <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="ccccccccccccc"
+ d="m 131.51612,200.41538 0,3.2 3,1.88462 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9.08462 3,0.0846 2,-3 m -10.75,0.25 2.25,2.66538 3.5,0"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42129"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="196.96924"
+ x="130.01611"
+ height="1.9692308"
+ width="2"
+ id="rect42131"
+ style="fill:#acacac;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <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="opacity:0.95;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect42133"
+ width="2"
+ height="1.9692308"
+ x="130.01611"
+ y="196.96924" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ d="m 125.76612,197.75 2.25,2.75 3.5,0 m 0,0 0,3 3,2 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9 3,0 2,-3"
+ style="fill:none;stroke:url(#linearGradient42155);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42135"
+ 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>
+ <g
+ id="g42161"
+ transform="translate(-128.99942,340.96539)"
+ style="display:inline;enable-background:new">
+ <g
+ id="g42163"
+ transform="translate(-1.999997,-8)">
+ <path
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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 256,-137.52519 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ id="path42165"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;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 257.01553,-137.02692 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ id="path42167"
+ 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>
+ <g
+ id="g42169">
+ <path
+ id="path42171"
+ d="m 265.98447,-145.52519 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ 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="path42173"
+ d="m 267,-145.02692 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ style="fill:#ffffff;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" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g42258"
+ transform="translate(0,86)">
+ <g
+ transform="translate(-111,129)"
+ id="g42260"
+ style="opacity:0.9;display:inline;enable-background:new">
+ <rect
+ y="194"
+ x="263"
+ height="16"
+ width="16"
+ id="rect42262"
+ 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,-1)"
+ id="g42264"
+ style="opacity:0.8">
+ <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="ccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42266"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect42268"
+ style="fill:none;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ id="path42270"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccc"
+ 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="path42272"
+ style="fill:none;stroke:url(#linearGradient42290);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <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="opacity:0.5;fill:none;stroke:url(#radialGradient42292);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42274"
+ width="2.4999998"
+ height="2.75"
+ x="269.76608"
+ y="196" />
+ <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:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect42276"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42278"
+ transform="translate(-83.0076,464.0087)">
+ <path
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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 236.98447,-138.49827 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ id="path42280"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;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 238,-138 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ id="path42282"
+ 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>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42284"
+ transform="translate(-81,470)">
+ <path
+ id="path42286"
+ d="m 246.98447,-144.49827 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ 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="path42288"
+ d="m 248,-144 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ style="fill:#ffffff;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" />
+ </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"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="1.767767"
+ y="596.5"
+ x="69.5"
+ height="13"
+ width="13"
+ id="rect23677"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;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"
+ rx="1.767767" />
+ <g
+ style="display:inline"
+ id="g23438"
+ transform="translate(45,357.99031)">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:url(#linearGradient23775);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 25,239.50969 0.5,-0.5 11,0 0.5,0.5 0,11 -0.5,0.5 -11,0 -0.5,-0.5 0,-11 z"
+ id="path23673"
+ 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="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="rect23655"
+ width="16"
+ height="16"
+ x="23"
+ y="237.00969" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.9999997px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 25.499991,250.49338 0,-11.00155 10.999993,0"
+ id="path23447"
+ 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
+ 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"
+ sodipodi:ry="4.1666665"
+ sodipodi:rx="4.1666665"
+ sodipodi:cy="603"
+ sodipodi:cx="76"
+ id="path23605"
+ style="fill:#dad9d9;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient23777);stroke-width:0.8888889;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:type="arc" />
+ <rect
+ y="602"
+ x="74"
+ height="2"
+ width="1"
+ id="rect23613"
+ style="fill:#000000;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:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23615"
+ width="1"
+ height="2"
+ 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"
+ transform="translate(0,128.00001)">
+ <rect
+ y="427.99997"
+ x="215"
+ height="16"
+ width="16"
+ id="rect51640"
+ 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="rect18676"
+ 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="g23292">
+ <g
+ id="g23271">
+ <g
+ id="g23265">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use22458"
+ 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(#linearGradient23257);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="use22460"
+ 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(#linearGradient23254);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="use22462"
+ 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(#linearGradient23251);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="path22465"
+ 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(#linearGradient23248);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" />
+ </g>
+ <g
+ id="g23259">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path22585"
+ 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(#linearGradient23244);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="use22587"
+ 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(#linearGradient23239);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="use22589"
+ 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(#linearGradient23235);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="use22591"
+ 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(#linearGradient23231);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="g19146">
+ <rect
+ y="628.25"
+ x="85"
+ height="2.5"
+ width="1"
+ id="rect19148"
+ 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="rect19150"
+ width="1"
+ height="2.5"
+ x="629"
+ y="-86.75" />
+ </g>
+ </g>
+ <g
+ id="g23162"
+ transform="translate(0,-4)">
+ <g
+ id="g23156">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24185"
+ d="m 224.75,442.5 0,0 -3.5,-0.75 -1.5,0 0,1.5 1.5,0 3.5,-0.75 z"
+ style="fill:none;stroke:url(#linearGradient23177);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="use24187"
+ d="m 220.5,446.75 0,0 0.75,-3.5 0,-1.5 -1.5,0 0.25,1.5 0.5,3.5 z"
+ style="fill:none;stroke:url(#linearGradient23179);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="use24189"
+ d="m 216.25,442.5 0,0 3.5,0.75 1.5,0 0,-1.5 -1.5,0 -3.5,0.75 z"
+ style="fill:none;stroke:url(#linearGradient23181);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="path24197"
+ d="m 220.5,438 0,-0.15625 -0.75,3.90625 0,1.5 1.5,0 0,-1.5 -0.75,-3.75 z"
+ style="fill:none;stroke:url(#linearGradient23183);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="g23150">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path24201"
+ 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(#linearGradient23185);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="use24203"
+ 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(#linearGradient23187);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="use24205"
+ 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(#linearGradient23189);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="use24207"
+ 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(#linearGradient23191);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="g24209">
+ <rect
+ y="628"
+ x="85"
+ height="2.9999599"
+ width="1"
+ id="rect24211"
+ 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="rect24213"
+ width="1"
+ height="3"
+ x="629"
+ y="-87" />
+ </g>
+ </g>
+ <g
+ id="g23052"
+ transform="translate(0,4)">
+ <path
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path24226"
+ 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(#linearGradient22715);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(#linearGradient22711);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="use24228"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22707);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="use24230"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22704);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="use24232"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.49998"
+ id="path24236"
+ 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(#linearGradient22701);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(#linearGradient22698);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="use24238"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient22695);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="use24240"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient22692);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="use24242"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(133.00004,-201.99996)"
+ id="g24244">
+ <rect
+ y="628.5"
+ x="85"
+ height="2"
+ width="1"
+ id="rect24249"
+ 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="rect24251"
+ width="1"
+ height="2"
+ x="629"
+ y="-86.5" />
+ </g>
+ </g>
+ <g
+ id="g23116"
+ transform="translate(0,-4)">
+ <g
+ transform="translate(0,-6.4549394)"
+ id="g23090">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24445"
+ 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(#linearGradient23132);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" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24447"
+ 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(#linearGradient23134);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" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24449"
+ 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(#linearGradient23136);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" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23138);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="path24452"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23110">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path22819"
+ 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(#linearGradient23140);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="path22821"
+ 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(#linearGradient23142);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="path22823"
+ 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(#linearGradient23144);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="path22825"
+ 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(#linearGradient23147);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="g23105">
+ <g
+ transform="translate(141.99999,-184.99353)"
+ id="g24264">
+ <rect
+ y="628.5"
+ x="85"
+ height="2"
+ width="1"
+ id="rect24266"
+ 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="rect24268"
+ width="1"
+ height="2"
+ x="629"
+ y="-86.5" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g23415"
+ 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"
+ id="rect23417"
+ 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="rect23419"
+ 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="g23422">
+ <g
+ id="g23424">
+ <g
+ id="g23426">
+ <path
+ style="fill:none;stroke:url(#linearGradient23563);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="path23430"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23566);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="path23432"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23568);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="path23434"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23570);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,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="path23437"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23439">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23572);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="path23441"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23574);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="path23443"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23576);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="path23449"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23578);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="path23453"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23455"
+ 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="rect23457"
+ width="1"
+ height="2.5"
+ x="85"
+ y="628.25" />
+ <rect
+ y="-86.75"
+ x="629"
+ height="2.5"
+ width="1"
+ id="rect23463"
+ 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="g23465">
+ <g
+ id="g23467">
+ <path
+ style="fill:none;stroke:url(#linearGradient23580);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.49999,-0.75 -1.50001,0 0,1.5 1.50001,0 3.49999,-0.75 z"
+ id="path23469"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23582);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="path23472"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23587);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="path23474"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23589);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.5 -1e-5,1.5 1.5,0 1e-5,-1.5 -0.75001,-3.5 z"
+ id="path23476"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23479">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23591);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="path23481"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23593);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="path23484"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23597);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="path23486"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23600);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="path23488"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23491"
+ 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="rect23493"
+ width="1"
+ height="2.9999599"
+ x="85"
+ y="628" />
+ <rect
+ y="-87"
+ x="629"
+ height="3"
+ width="1"
+ id="rect23496"
+ 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="g23498">
+ <path
+ style="fill:none;stroke:url(#linearGradient23602);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="path23500"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path23502"
+ 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(#linearGradient23606);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
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path23504"
+ 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(#linearGradient23608);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
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path23506"
+ 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(#linearGradient23610);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
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23612);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="path23508"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.49998"
+ id="path23510"
+ 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(#linearGradient23616);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.49998"
+ id="path23512"
+ 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(#linearGradient23618);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.49998"
+ id="path23514"
+ 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(#linearGradient23620);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
+ id="g23517"
+ transform="translate(133.00004,-201.99996)">
+ <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="rect23520"
+ width="1"
+ height="2"
+ x="85"
+ y="628.5" />
+ <rect
+ y="-86.5"
+ x="629"
+ height="2"
+ width="1"
+ id="rect23522"
+ 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="g23524">
+ <g
+ id="g23526"
+ transform="translate(0,-6.4549394)">
+ <path
+ style="fill:none;stroke:url(#linearGradient23622);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="path23529"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23624);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="path23531"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23626);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="path23533"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23535"
+ 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(#linearGradient23628);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" />
+ </g>
+ <g
+ id="g23538">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23630);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="path23541"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23632);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="path23544"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23635);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="path23549"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23637);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="path23551"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23555">
+ <g
+ id="g23557"
+ 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="rect23559"
+ width="1"
+ height="2"
+ x="85"
+ y="628.5" />
+ <rect
+ y="-86.5"
+ x="629"
+ height="2"
+ width="1"
+ id="rect23561"
+ 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
+ transform="translate(-21.000008,-166)"
+ id="g23639">
+ <rect
+ y="427.99997"
+ x="215"
+ height="16"
+ 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" />
+ <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>
+ <g
+ id="g23686"
+ transform="translate(0,-4)">
+ <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" />
+ </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" />
+ </g>
+ </g>
+ <g
+ id="g23757"
+ transform="translate(0,-4)">
+ <g
+ transform="translate(0,-6.4549394)"
+ id="g23759">
+ <path
+ inkscape:transform-center-y="-1.75"
+ 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" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ 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" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ 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" />
+ <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"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23778">
+ <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"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <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" />
+ <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" />
+ <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">
+ <g
+ transform="translate(141.99999,-184.99353)"
+ id="g23791">
+ <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"
+ width="1"
+ height="2"
+ x="629"
+ y="-86.5" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g24300"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ y="529"
+ x="117"
+ height="16"
+ width="16"
+ id="rect24298"
+ 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" />
+ <g
+ transform="translate(28.71596,210.64282)"
+ id="g41346"
+ style="display:inline">
+ <rect
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect41308"
+ width="14"
+ height="6.0000124"
+ x="88.784042"
+ y="326.84842"
+ ry="2.0305908"
+ rx="2.0305908"
+ 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
+ rx="1.029202"
+ ry="1.029202"
+ y="327.84842"
+ x="89.784042"
+ height="4.00875"
+ width="12"
+ id="rect41626"
+ style="fill:none;stroke:url(#linearGradient24317);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ 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="2.0154257"
+ ry="2.0154257"
+ y="319.85718"
+ x="88.784042"
+ height="4.9999971"
+ width="14"
+ id="rect41313"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new" />
+ <rect
+ rx="0.97821051"
+ ry="0.97821051"
+ y="320.85718"
+ x="89.784042"
+ height="2.9999971"
+ width="12.000008"
+ id="rect41629"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24319);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ 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:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41631"
+ width="8"
+ height="3.9999919"
+ x="89.284042"
+ y="320.35718"
+ rx="0"
+ ry="0" />
+ <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"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient24321);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect41633"
+ width="12.000008"
+ height="2.9999971"
+ x="89.784042"
+ y="320.85718"
+ ry="0.97821051"
+ rx="0.97821051" />
+ <rect
+ style="opacity:0.6;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41635"
+ width="0.99999988"
+ height="3.0000272"
+ x="96.284042"
+ y="320.85718"
+ rx="0"
+ ry="0" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ transform="matrix(-1,0,0,1,193.28404,-130.61032)"
+ id="g41637">
+ <g
+ id="g41639">
+ <rect
+ transform="matrix(-1,0,0,1,194,-1.1e-6)"
+ ry="0"
+ rx="0"
+ y="459.9675"
+ x="91"
+ height="1"
+ width="1"
+ id="rect41641"
+ style="fill:#000000;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(-1,0,0,1,194,-1.1e-6)"
+ style="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="rect24094"
+ width="1"
+ height="3"
+ x="92"
+ y="458.9675"
+ rx="0"
+ ry="0" />
+ <rect
+ style="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="rect24096"
+ width="1"
+ height="1"
+ x="92"
+ y="459.9675"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="458.9675"
+ x="93"
+ height="3"
+ width="1"
+ id="rect24098"
+ style="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>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g24339"
+ transform="translate(0,128.00001)">
+ <rect
+ y="407"
+ x="194"
+ height="16"
+ width="16"
+ id="rect24195"
+ 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" />
+ <g
+ transform="translate(-230,238.99245)"
+ id="g41674"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient24238);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 424.5,170.5 0,10.5 1.5,1.5 9.5,0 0,-11 -7,0 0,-1 -4,0 z"
+ id="path24199"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline"
+ id="g41677"
+ transform="translate(-26,49.00749)">
+ <rect
+ ry="0"
+ rx="0"
+ y="120.50006"
+ x="456.5"
+ height="7.9999371"
+ width="7.0000038"
+ id="rect41679"
+ style="fill:url(#linearGradient24276);fill-opacity:1;fill-rule:nonzero;stroke:#4d4d4d;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <g
+ id="g41681">
+ <path
+ style="fill:#c80000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 192,239 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z"
+ transform="translate(267,-117.99994)"
+ id="path41683"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ ry="0"
+ rx="0"
+ y="121.5"
+ x="457.5"
+ height="5.9999981"
+ width="5.0000038"
+ id="rect41685"
+ style="fill:none;stroke:url(#linearGradient24278);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
+ </g>
+ <path
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient24244);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 427.5,175.5 12,0.008 0,5.5 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.00755 0,-9e-4 z"
+ id="path41687"
+ 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 426.5,181.5 -1.01563,-0.98437 0,-9.02344 2,0 0,1 2.17355,0.0154"
+ id="path41689"
+ inkscape:connector-curvature="0" />
+ <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 428,181.50755 9.5,0"
+ id="path41691"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41693"
+ d="m 438.5,176.50755 -10,-0.008 0,4.00755 -1.5,1.5 -1.5,-1.5"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24246);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 428,171.00755 0,2 -3,0 0,-2 3,0 z"
+ id="path24228"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24230"
+ transform="translate(270,-408)"
+ style="fill:#d45500;fill-opacity:1;display:inline" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path24234"
+ d="m 424.5,170.5 0,10.5 1.5,1.5 12,0.008 1.5,-1.49245 0,-5.5 -2,-0.008 0,-6 -7,0 0,2 -2,-0.008 0,-1 -4,0 0,4.5e-4 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" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#d40000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 189.5,244.14308 0,-5.64308 7,0 0,5.64842"
+ id="path41698"
+ sodipodi:nodetypes="cccc"
+ transform="translate(241,-68.99245)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(-65,-169.00755)"
+ id="g24176" />
+ <g
+ id="g24393"
+ 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"
+ transform="translate(0,128.00001)">
+ <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="rect24152"
+ width="16"
+ height="16"
+ x="89"
+ y="407" />
+ <g
+ id="g24378">
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path41754"
+ d="m 89.5,409.49245 0,10.5 1.5,1.5 9.5,0 0,-11 -7,0 0,-1 -4,0 z"
+ style="fill:url(#linearGradient24374);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline"
+ id="g41756"
+ transform="translate(-361,287.99994)">
+ <rect
+ ry="0"
+ rx="0"
+ y="120.50006"
+ x="456.5"
+ height="7.9999371"
+ width="7.0000038"
+ id="rect24160"
+ style="fill:url(#linearGradient41721);fill-opacity:1;fill-rule:nonzero;stroke:#333333;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="121.5"
+ x="457.5"
+ height="5.9999981"
+ width="5.0000038"
+ id="rect24162"
+ style="fill:none;stroke:url(#linearGradient41723);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
+ <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="cccc"
+ id="path41760"
+ style="opacity:0.65;fill:none;stroke:#333333;stroke-width:0.9999997px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 458.49992,122.50172 3.00006,0 m -3.00006,1.99301 3.00006,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path41762"
+ d="m 92.5,414.49245 12,0.008 0,5.5 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.00755 0,-9e-4 z"
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient24367);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" />
+ <path
+ id="path41764"
+ d="m 91.5,420.49245 -1.01563,-0.98437 0,-9.02344 2,0 0,1 2.17355,0.0154"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41766"
+ d="m 93,420.5 9.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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24362);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 103.5,415.5 -10,-0.008 0,4.00755 -1.5,1.5 -1.5,-1.5"
+ id="path41768"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path24174"
+ d="m 93,410 0,2 -3,0 0,-2 3,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ 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,409.49245 0,10.5 1.5,1.5 12,0.008 1.5,-1.49245 0,-5.5 -2,-0.008 0,-6 -7,0 0,2 -2,-0.008 0,-1 -4,0 0,4.5e-4 z"
+ id="path24178"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path24190"
+ d="m 95.5,410.5 0,-2 7,0 0,5.92967"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g22846"
+ transform="translate(84,86)">
+ <rect
+ ry="0"
+ y="323"
+ x="26"
+ height="16"
+ width="16"
+ id="rect22783"
+ 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" />
+ <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" />
+ </g>
+ </g>
+ <g
+ id="g23767"
+ 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"
+ id="rect23769"
+ width="16"
+ height="16"
+ x="26"
+ y="323"
+ ry="0" />
+ <g
+ id="g23771">
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path23788"
+ 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:#ff8400;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b1600;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="path23802"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23808"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.765625"
+ rx="0.765625"
+ y="333.25"
+ x="31"
+ height="4.75"
+ width="6"
+ id="rect23810"
+ style="fill:#2b1600;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:#846544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23812"
+ width="4"
+ height="3"
+ x="32"
+ y="334" />
+ <path
+ sodipodi:nodetypes="cssssccccsccsssc"
+ id="path23816"
+ 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(#linearGradient23890);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path23819"
+ 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
+ id="path23821"
+ 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"
+ inkscape:connector-curvature="0" />
+ <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="rect23824"
+ width="0.25"
+ height="1"
+ x="37"
+ y="336" />
+ <rect
+ y="334"
+ x="36.96875"
+ height="1.099999"
+ width="0.28125"
+ id="rect23826"
+ 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="rect23828"
+ 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="rect23830"
+ width="0.28125"
+ height="1.099999"
+ x="30.90625"
+ y="333.95001" />
+ <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(#linearGradient23892);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23838"
+ 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="path23840"
+ style="opacity:0.95;fill:url(#radialGradient23894);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
+ id="path23842"
+ style="fill:none;stroke:url(#linearGradient23896);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" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient23898);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23844"
+ 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.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
+ <path
+ transform="matrix(0.99567,0,-0.00787885,1,-30.654936,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="path23846"
+ sodipodi:cx="64"
+ 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"
+ 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
+ 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(#radialGradient23900);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path23848"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.85;fill:#503416;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23850"
+ width="5"
+ height="0.75"
+ x="31.5"
+ y="333" />
+ <path
+ style="fill:#552c00;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="path23852"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:url(#linearGradient23902);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="path23860"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <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="rect23862"
+ width="1"
+ height="1"
+ x="32"
+ y="328" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path23866"
+ style="fill:none;stroke:url(#radialGradient23904);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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path23873"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <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="rect23877"
+ width="2"
+ height="1"
+ x="33"
+ y="329" />
+ <rect
+ y="328"
+ x="35"
+ height="1"
+ width="1"
+ id="rect23888"
+ 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
+ id="g23912"
+ 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"
+ id="rect23915"
+ width="16"
+ height="16"
+ x="26"
+ y="323"
+ ry="0" />
+ <g
+ id="g23917">
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path23920"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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: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="path23927"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23931"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.765625"
+ rx="0.765625"
+ y="333.25"
+ x="31"
+ height="4.75"
+ width="6"
+ id="rect23933"
+ 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:#a89858;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23935"
+ width="4"
+ height="3"
+ x="32"
+ y="334" />
+ <path
+ sodipodi:nodetypes="cssssccccsccsssc"
+ id="path23948"
+ 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(#linearGradient24090);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 32.35,336.4 1.25,0"
+ id="path23950"
+ 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
+ id="path23956"
+ d="m 32.35,334.4 1.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <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="rect23959"
+ width="0.25"
+ height="1"
+ x="37"
+ y="336" />
+ <rect
+ y="334"
+ x="36.96875"
+ height="1.099999"
+ width="0.28125"
+ id="rect23961"
+ 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="rect23965"
+ 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="rect23967"
+ width="0.28125"
+ height="1.099999"
+ x="30.90625"
+ y="333.95001" />
+ <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(#linearGradient24092);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23982"
+ 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="path23984"
+ style="opacity:0.6;fill:url(#radialGradient24094);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
+ id="path24054"
+ style="fill:none;stroke:url(#linearGradient24096);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" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient24098);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24056"
+ 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.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="path24060"
+ sodipodi:cx="64"
+ 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"
+ 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
+ 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(#radialGradient24100);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path24064"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.85;fill:#504416;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24066"
+ width="5"
+ height="0.75"
+ x="31.5"
+ y="333" />
+ <path
+ 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="path24068"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:url(#linearGradient24102);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="path24070"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <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="rect24072"
+ width="1"
+ height="1"
+ x="32"
+ y="328" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path24078"
+ style="fill:none;stroke:url(#radialGradient24104);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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path24082"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <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="rect24086"
+ width="2"
+ height="1"
+ x="33"
+ y="329" />
+ <rect
+ y="328"
+ x="35"
+ height="1"
+ width="1"
+ id="rect24088"
+ 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
+ id="g25056"
+ transform="translate(-168,2)">
+ <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" />
+ <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" />
+ <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" />
+ <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" />
+ <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" />
+ <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" />
+ </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"
+ transform="translate(-126,2)"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ id="g41200"
+ style="opacity:0.65;display:inline;enable-background:new">
+ <rect
+ y="71"
+ x="341"
+ height="16"
+ width="16"
+ id="rect41164"
+ 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" />
+ <g
+ id="g41166"
+ transform="translate(252,-337)">
+ <path
+ style="fill:url(#linearGradient42055);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,409.49245 0,10.5 1.5,1.5 10.5,0.008 0,-11 -8,-0.008 0,-1 -4,0 z"
+ id="path41168"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-361,287.99994)"
+ id="g41170"
+ style="display:inline" />
+ <path
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient42057);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.49245 11,0.0151 0,5.5 -1.5,1.49245 -11,0 0,-2 1.5,0 0,-5.00755 0,0 0,0 0,0 z"
+ id="path41172"
+ 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,-9.02344 2,0 0,1 L 100.5,411.5"
+ id="path41174"
+ inkscape:connector-curvature="0" />
+ <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 9.5,0"
+ id="path41176"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41178"
+ d="m 102.5,415.5 -9,-0.008 0,4.00755 -1.5,1.5 -1.5,-1.5"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient42059);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 93,410 0,2 -3,0 0,-2 3,0 z"
+ id="path41180"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path41182"
+ d="m 89.5,409.50755 0,10.4849 1.5,1.5 11,0.008 1.5,-1.49245 0,-5.5 -2,-0.008 0,-3.9849 -8,-0.008 0,-1 -4,0 0,4.5e-4 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" />
+ </g>
+ </g>
+ <g
+ transform="translate(-81,-80.992447)"
+ id="g24185"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccc"
+ id="path41134"
+ d="m 428.75,158.5 3,-0.008 0,6.50755 0,2.50755 0.75,0 0,-1 1,0 0,-1 2,0 0,1 1,0 0,1 0.67818,0 0,-9.50755 -0.67818,0 0,-0.5 -0.25,0 0,-0.75 -1.75,-0.008 -4.75,0.008 0,1 -1,0 0,0.75 0,4.5e-4 z"
+ style="fill:none;stroke:#401406;stroke-width:1.00000012;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
+ id="g41137"
+ transform="translate(-16,37.992447)">
+ <g
+ transform="translate(0,-1)"
+ id="g41139">
+ <rect
+ style="fill:#822b0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24197"
+ width="3"
+ height="0.99999988"
+ x="445"
+ y="121.00755" />
+ <g
+ id="g24199">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41143"
+ d="m 446,120 0,1 6,0 0,-1 -6,0 z"
+ style="fill:#ed7e5c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="fill:#e7541a;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 448,121 0,9.00755 1,0.008 0,-1 1,0 0,-1 1,-0.008 0,1.00755 1,0 0,1 1,-0.008 0,-9.00755 -5,0 0,4.5e-4 0,0 0,0 z"
+ id="path41145"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;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"
+ d="m 448,121 0,9.00755 1,0 0,-9.00755 -1,0 0,0 0,0 0,0 z"
+ id="path41147"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41149"
+ d="m 452,121 0,9.00755 1,0 0,-9.00755 -1,0 0,0 0,0 0,0 z"
+ style="opacity:0.3;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;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"
+ d="m 446,120.00755 0,1 2,-0.008 0,-1 -2,0.008 z"
+ id="path41151"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41153"
+ d="m 445,121.00755 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.45;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"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24216"
+ style="opacity:0.3">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41156"
+ d="m 451,128.00755 0,1 1,0 0,-1 -1,0 z"
+ style="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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="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"
+ d="m 450,127.00755 0,1 1,0 0,-1 -1,0 0,0 0,0 0,0 z"
+ id="path41158"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41160"
+ d="m 449,128.00755 0,1 1,0 0,-1 -1,0 z"
+ style="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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g62487"
+ transform="translate(0,128)">
+ <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"
+ id="rect23556"
+ width="16"
+ height="16"
+ x="281"
+ y="68" />
+ <g
+ transform="matrix(0,-1,1,0,-254.00001,365.00041)"
+ id="g24740">
+ <g
+ style="opacity:0.7"
+ id="g24922">
+ <path
+ d="m 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:#1a1a1a;stroke-width:2.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"
+ id="path24671"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24673"
+ style="fill:none;stroke:#cccccc;stroke-width:1;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 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="323.5"
+ x="80.500122"
+ height="3"
+ width="2.9998772"
+ id="rect24678"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path24681"
+ d="m 83.00041,324.00001 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect24684"
+ width="2.9998772"
+ height="3"
+ x="80.49971"
+ y="334.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 83,335 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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="path24686"
+ 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>
+ </g>
+ <g
+ id="g62412"
+ transform="translate(1,127)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="67"
+ x="303"
+ height="16"
+ width="16"
+ id="rect23554"
+ 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" />
+ <g
+ transform="matrix(0,1,1,0,-255,214)"
+ id="g24695">
+ <g
+ transform="translate(-356.00003,55.00003)"
+ id="g24697">
+ <g
+ transform="translate(296.99995,249.99998)"
+ id="g24699"
+ 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="g24701"
+ transform="translate(187.99958,-21.0368)">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="opacity:0.9;fill:none;stroke:#2b1600;stroke-width:2.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"
+ id="path24703"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path24705"
+ style="fill:none;stroke:#ed993f;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"
+ d="m 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24709" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ d="m 258.50045,291.53677 0,3.28125 0,6.71875 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:url(#linearGradient62436);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"
+ id="path24711"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24713">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24715"
+ width="1"
+ height="1"
+ x="90"
+ y="325"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="325"
+ x="96"
+ height="1"
+ width="1"
+ id="rect24717"
+ style="fill:#ffffff;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:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24719"
+ width="1"
+ height="1"
+ x="102"
+ y="325"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ transform="translate(0,5)"
+ id="g24721">
+ <rect
+ ry="0"
+ rx="0"
+ y="325"
+ x="90"
+ height="1"
+ width="1"
+ id="rect24723"
+ style="fill:#ffffff;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:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24725"
+ width="1"
+ height="1"
+ x="96"
+ y="325"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="325"
+ x="102"
+ height="1"
+ width="1"
+ id="rect24727"
+ style="fill:#ffffff;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="g24729"
+ transform="translate(0,9.96875)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24731"
+ width="1"
+ height="1"
+ x="90"
+ y="325.03125"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="325.03125"
+ x="96"
+ height="1"
+ width="1"
+ id="rect24733"
+ style="fill:#ffffff;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:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24736"
+ width="1"
+ height="1"
+ x="102"
+ y="325.03125"
+ rx="0"
+ ry="0" />
+ <path
+ id="rect24766"
+ d="m 70,304 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.27999998;fill:#2b1600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(21,11.03125)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g62543"
+ transform="translate(1,2)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="340"
+ x="261"
+ height="16"
+ width="16"
+ id="rect23562"
+ 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" />
+ <g
+ id="g24926"
+ transform="matrix(0,1,1,0,18,172)">
+ <g
+ id="g24928"
+ transform="translate(-356.00003,55.00003)">
+ <g
+ style="display:inline"
+ 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="g24930"
+ transform="translate(296.99995,249.99998)" />
+ <g
+ transform="translate(187.99958,-21.0368)"
+ id="g24932">
+ <path
+ id="path24935"
+ style="opacity:0.9;fill:none;stroke:#0b1728;stroke-width:2.29999995;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 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:url(#linearGradient62558);stroke-width:1;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="path24937"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24939" />
+ </g>
+ </g>
+ <g
+ id="g24943">
+ <path
+ id="rect24945"
+ transform="translate(-252,42)"
+ d="m 342,283 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m -12,5 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m -12,5 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.7;fill:url(#linearGradient62560);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" />
+ </g>
+ <g
+ id="g24951"
+ transform="translate(0,5)" />
+ <g
+ transform="translate(0,9.96875)"
+ id="g24959">
+ <path
+ style="opacity:0.27999998;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 70,304 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z"
+ id="path24967"
+ transform="translate(21,11.03125)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24707"
+ transform="translate(-210,128)">
+ <rect
+ y="302"
+ x="299"
+ height="16"
+ width="16"
+ id="rect24543"
+ 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" />
+ <path
+ style="fill:#f0a453;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;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 304.5,308.5 c 1.52069,0 3,-1.25 3,-2.5 0,-2 1.5,-3.5 3.5,-3.5 2,0 3.5,1.568 3.5,3.5 0,1.84581 -1.5,3.5 -3.5,3.5 -1.25,0 -2.5,1.5 -2.5,3 0,2.25 -1.75,4 -4,4 -2.25,0 -4,-1.75 -4,-4 0,-2.25 1.75,-4 4,-4 z"
+ id="path24546"
+ sodipodi:nodetypes="cssssszzs"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 311,303 c -1.75507,0 -3,1.24493 -3,3 0,0.81824 -0.48216,1.55558 -1.125,2.09375 C 306.23216,308.63192 305.39457,309 304.5,309 c -1.996,0 -3.5,1.504 -3.5,3.5 0,1.996 1.504,3.5 3.5,3.5 1.996,0 3.5,-1.504 3.5,-3.5 0,-0.88607 0.36895,-1.73024 0.90625,-2.375 0.5373,-0.64476 1.27281,-1.125 2.09375,-1.125 1.72989,0 3,-1.41958 3,-3 0,-1.67845 -1.25603,-3 -3,-3 z"
+ id="path24792"
+ style="opacity:0.8;fill:url(#linearGradient24797);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86598092;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.48985747"
+ sodipodi:type="inkscape:offset" />
+ <path
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path24550"
+ style="fill:none;stroke:url(#radialGradient24599);stroke-width:1;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:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset" />
+ <path
+ transform="translate(96.999991,232.95)"
+ sodipodi:type="arc"
+ style="opacity:0.75;fill:url(#radialGradient43962);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path43958"
+ sodipodi:cx="207.5"
+ 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" />
+ <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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="79.5"
+ sodipodi:cx="207.5"
+ id="path43960"
+ style="opacity:0.75;fill:url(#radialGradient43964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.14754021;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.8714292,0,0,0.8714292,130.17844,236.77138)" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.96440691"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="fill:none;stroke:url(#radialGradient24632);stroke-width:1;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="path24630"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ transform="matrix(0,-1,-1,0,617,617)" />
+ <path
+ transform="matrix(0,-1,-1,0,617,617)"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path24809"
+ style="fill:none;stroke:url(#linearGradient24820);stroke-width:1;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:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g23140"
+ 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"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="286"
+ x="-6"
+ height="16"
+ width="16"
+ id="rect39828"
+ style="opacity:0;fill:#ffffff;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23145">
+ <g
+ id="g23149">
+ <path
+ id="path39832"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3;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 -4.5,289.5 1.5,0 c 3.5,0 1.9989834,11 6.5,11 2.6782554,0 2.25,-3 5.25,-3 l 0.25,0"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ d="m 9,297.5 -0.25,0 c -3,0 -2.5,3 -5.25,3 -4.5010166,0 -3,-11 -6.5,-11 l -2,0"
+ style="fill:none;stroke:#bde7a2;stroke-width:1.60000002;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="path39834"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path39836"
+ style="opacity:0.35;fill:none;stroke:url(#radialGradient23167);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 3.5,300.5 c -4.5,0 -3,-11 -6.5,-11"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23161">
+ <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="path39839"
+ d="m -4.5,294.5 6,0 c 4,0 2,-7 6,-7 l 1,0"
+ style="fill:none;stroke:#000000;stroke-width:3;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:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;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 -5,294.5 6.5,0 c 4,0 2,-7 6,-7 l 1.5,0"
+ id="path23165"
+ 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>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(54,277.99993)"
+ id="g24129"
+ 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">
+ <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="rect24131"
+ width="16"
+ height="16"
+ x="203"
+ y="257" />
+ <g
+ style="display:inline;enable-background:new"
+ 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="g24133"
+ transform="translate(-39.983882,19.00809)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 244.51612,238.49191 -0.0161,3 7.98388,0 0.0161,-3 -7.98388,0 z"
+ id="path39845"
+ 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
+ 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="path39847"
+ d="m 247.51612,241.49191 -0.0161,3 11,0 0.0161,-3 -11,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;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="ccccc"
+ 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="path39849"
+ d="m 243.5,247.49191 -0.0161,3 12,0 0.0161,-3 -12,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 250.48388,250.49191 -0.0161,3 7.01612,0 0.0161,-3 -7.01612,0 z"
+ id="path39851"
+ 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" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient24202);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 205.51612,259.5 c 0,-0.25 0,-1 0,-1 l 6,0"
+ id="path39853"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path24145"
+ d="m 208.51612,262.5 c 0,-0.25 0,-1 0,-1 l 9,0"
+ style="fill:none;stroke:url(#linearGradient24204);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24206);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 204.5,268.5 c 0,-0.25 0,-1 0,-1 l 10,0"
+ id="path24147"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24208);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 211.5,271.5 c 0,-0.25 0,-1 0,-1 l 5,0"
+ id="path39857"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(2,298)"
+ id="g40315"
+ 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">
+ <g
+ id="g40317"
+ transform="matrix(-1.023377,0,0,1.016727,-99.930251,85.381494)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40319"
+ d="m -114.25921,159.20547 0,-6.88483 5.85921,2.61269 -0.01,7.96045 -5.84921,-3.68831 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.96069634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ 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"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.96069634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -102.53333,159.20547 0,-6.88483 -5.86667,2.61269 -0.0101,7.96045 5.87676,-3.68831 10e-6,0 0,0 0,0 z"
+ id="path40321"
+ 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="path40323"
+ d="m -102.53333,152.32064 -5.8704,-1.47533 -5.85548,1.47533 5.85921,2.85858 5.86667,-2.85858 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.96069634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ 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" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40325"
+ d="m -114.25921,159.20548 0,-6.88484 5.86294,-1.47532 c 0,2.52838 -0.004,11.53297 -0.004,12.08795 l -5.85864,-3.72779 -3e-4,0 z"
+ style="fill:url(#linearGradient40722);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -102.53333,159.20548 0,-6.88484 -5.8704,-1.47533 0.003,12.08796 5.86724,-3.72779 1.6e-4,0 0,0 0,0 z"
+ id="path40327"
+ 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="path40329"
+ d="m -102.53333,152.32064 -5.8704,-1.47533 -5.85548,1.47533 5.85548,1.72121 5.8704,-1.72121 z"
+ style="fill:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path40331"
+ d="m -103.02191,152.32064 1e-5,6.63895 0,0 -5.37437,3.44241 -5.37437,-3.44241 1e-5,-6.63895"
+ style="fill:none;stroke:url(#linearGradient40724);stroke-width:0.98034734px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="237"
+ x="3"
+ height="16"
+ width="16"
+ id="rect40333"
+ style="fill:none;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(12.401337,137.46985)"
+ id="g40381"
+ 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">
+ <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="rect40383"
+ width="16"
+ height="16"
+ x="265.59866"
+ y="397.53015" />
+ <g
+ style="display:inline"
+ id="g40385"
+ transform="translate(2.6147745,148.53014)">
+ <path
+ id="path40387"
+ d="m 270,251 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.29736,-1.49999 -1.5,1.5 1.51611,1.28124 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.51611,1.28126 1.5,1.5 1.29736,-1.50001 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.26514,1.50001 1.5,-1.5 -1.25,-1.25 c 0.29338,-0.44313 0.26916,-0.96592 0.39111,-1.50001 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.0977,-1.05686 -0.39111,-1.49999 l 1.25,-1.25 -1.5,-1.5 -1.25,1.25 C 273.04076,252.70663 272.53409,252.74695 272,252.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ 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="fill:url(#linearGradient40734);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 270,251 0,1.625 c -0.53409,0.12195 -1.07298,0.0816 -1.51611,0.37501 l -1.25,-1.25 -1.5,1.5 1.25,1.25 c -0.29338,0.44313 -0.23694,0.9659 -0.35889,1.49999 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.0655,1.05688 0.35889,1.50001 l -1.25,1.25 1.5,1.5 1.25,-1.25 c 0.44313,0.29338 0.98202,0.25304 1.51611,0.37499 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.04076,-0.0816 1.48389,-0.37499 l 1.25,1.25 1.5,-1.5 -1.25,-1.25 c 0.29338,-0.44313 0.26916,-0.96592 0.39111,-1.50001 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.0977,-1.05686 -0.39111,-1.49999 l 1.25,-1.25 -1.5,-1.5 -1.25,1.25 C 273.04076,252.70663 272.53409,252.74695 272,252.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ id="path40389"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ 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="cccccscccccccc"
+ id="path40391"
+ d="M 274.73389,252.25001 273.5,253.75 m -2,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.01806,0.29269 -1.5172,0.50569 m -1.49,1.50752 c -0.20864,0.49552 -0.41426,1.14284 -0.4928,1.48679 l -1.5,0 0,1 m 1.5,-5 -0.5,0.5 m 1.25,6.5 -1.51611,1.25001"
+ 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"
+ 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:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 273.23389,255.50001 0,3.75 L 269.5,259.25"
+ id="path40393"
+ 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
+ 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 266.43389,253.45001 1,-1"
+ id="path40395"
+ sodipodi:nodetypes="cc"
+ 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" />
+ <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-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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40520"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ y="407"
+ x="216"
+ height="16"
+ width="16"
+ id="rect40522"
+ 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="g40524"
+ transform="translate(12,170.00654)">
+ <path
+ sodipodi:nodetypes="cccssssssccccsssssscccccc"
+ id="path40526"
+ d="m 207.5,239.5 0,3 0,5.03125 c -0.31763,0.0283 -0.63892,0.0942 -0.96875,0.21875 -0.61538,0.23235 -1.12455,0.59487 -1.5,1.03125 -0.37546,0.43635 -0.63146,0.99926 -0.46875,1.625 0.1627,0.62575 0.6413,0.93109 1.15625,1.03125 0.51496,0.10016 1.1346,0.0761 1.75,-0.15625 0.61542,-0.23236 1.12456,-0.62615 1.5,-1.0625 0.33776,-0.39252 0.53125,-0.86133 0.53125,-1.46875 l 0,-6.25 6,0 0,5.03125 c -0.31763,0.0283 -0.63892,0.0942 -0.96875,0.21875 -0.61538,0.23235 -1.12455,0.59487 -1.5,1.03125 -0.37546,0.43635 -0.63146,0.99926 -0.46875,1.625 0.1627,0.62575 0.6413,0.93109 1.15625,1.03125 0.51496,0.10016 1.1346,0.0761 1.75,-0.15625 0.61542,-0.23236 1.12456,-0.62615 1.5,-1.0625 C 217.30651,249.82623 217.5,249.3373 217.5,248.75 l 0,-9.25 -1,0 -1,0 -6,0 -2,0 z"
+ style="fill:url(#linearGradient40758);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.58322862;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g40528">
+ <path
+ id="path40530"
+ d="m 207.44628,248.42245 c -0.25577,0.0323 -0.54038,0.11684 -0.81334,0.24698 -0.36394,0.17354 -0.65949,0.40136 -0.86757,0.65378 -0.20806,0.2524 -0.34395,0.56878 -0.21514,0.8647 0.12879,0.29592 0.44506,0.40032 0.76358,0.40164 0.3185,0.001 0.6909,-0.0762 1.05486,-0.24968 0.36397,-0.17355 0.65786,-0.41845 0.86594,-0.67084 0.20807,-0.25239 0.34394,-0.56879 0.21514,-0.86472 -0.12879,-0.29592 -0.44345,-0.38323 -0.76195,-0.38454 -0.0796,-3.4e-4 -0.15625,-0.008 -0.24152,0.003 l 0,-3.2e-4 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient40760);stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 209.5,241.5 6,0"
+ id="path40532"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40762);stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 215.4463,248.42245 c -0.25577,0.0323 -0.54038,0.11684 -0.81334,0.24698 -0.36394,0.17354 -0.65949,0.40136 -0.86757,0.65378 -0.20806,0.2524 -0.34395,0.56878 -0.21514,0.8647 0.12879,0.29592 0.44506,0.40032 0.76358,0.40164 0.3185,0.001 0.6909,-0.0762 1.05486,-0.24968 0.36397,-0.17355 0.65786,-0.41845 0.86594,-0.67084 0.20807,-0.25239 0.34394,-0.56879 0.21514,-0.86472 -0.12879,-0.29592 -0.44345,-0.38323 -0.76195,-0.38454 -0.0796,-3.4e-4 -0.15625,-0.008 -0.24152,0.003 l 0,-3.2e-4 0,0 0,0 z"
+ id="path40534"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g40602"
+ 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"
+ inkscape:export-ydpi="90">
+ <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="rect40604"
+ width="16"
+ height="16"
+ x="299"
+ y="407" />
+ <g
+ 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(0.927848,0,0,0.916217,147.82022,210.72362)"
+ id="g40606"
+ style="display:inline">
+ <path
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient42519);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.22752953;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path40608"
+ 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" />
+ </g>
+ <g
+ style="fill:none;stroke:url(#linearGradient42523);stroke-width:1.17973554;stroke-opacity:1;display:inline"
+ id="g40610"
+ transform="matrix(0.784039,0,0,0.779055,172.50801,241.28815)"
+ 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\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="path40612"
+ style="fill:none;stroke:url(#linearGradient42521);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 309.5,411.5 -3,3 m 0,1 2,2"
+ style="fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40614"
+ 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:transform-center-x="-1.25"
+ inkscape:transform-center-y="1.25"
+ id="path40616"
+ style="fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 306.5,415.5 2,2"
+ 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" />
+ <rect
+ style="opacity:0.5;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40618"
+ width="1"
+ height="1.5"
+ x="307"
+ y="419" />
+ <rect
+ style="opacity:0.5;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40620"
+ width="1.5"
+ height="1"
+ x="311"
+ y="414" />
+ <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"
+ d="m 309.5,411.5 -3,3"
+ style="fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40622"
+ inkscape:transform-center-y="-0.75"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.0204512"
+ inkscape:transform-center-x="1.4653436"
+ id="path40624"
+ d="m 306.85514,408.97535 c -3.25557,0.003 -5.8936,2.6597 -5.87155,5.95078 0.0105,1.56055 0.63214,2.99542 1.61111,4.05762 2.7831,-7.37691 5.95805,-1.77373 7.49116,-9.06794 -0.92886,-0.60835 -2.04538,-0.9415 -3.23072,-0.94046 l 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient42525);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="415"
+ x="301.51614"
+ height="1"
+ width="1.4999696"
+ id="rect40626"
+ style="opacity:0.3;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="409.5"
+ x="306"
+ height="1.4999921"
+ width="1"
+ id="rect40628"
+ style="opacity:0.3;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:transform-center-y="-0.75"
+ id="path40630"
+ style="opacity:0.6;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 309.5,411.5 -3,3"
+ 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>
+ <g
+ transform="translate(9,297.99992)"
+ id="g40632"
+ 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">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g40634"
+ transform="translate(-1.5986633,-160.53013)">
+ <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="rect40636"
+ width="16"
+ height="16"
+ x="165.59866"
+ y="397.53015" />
+ <g
+ id="g40638"
+ transform="translate(2.6147745,150.03014)"
+ 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">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect40640"
+ width="15.000031"
+ height="16"
+ x="162.99997"
+ y="247.5" />
+ <rect
+ ry="1.9578006"
+ rx="1.9578006"
+ y="250.00002"
+ x="164.48389"
+ height="13.000053"
+ width="11.999973"
+ id="rect40642"
+ style="fill:url(#linearGradient40788);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m 174.48389,251 1,1 0,9 -1,1 -8,0 -1,-1 0,-9 1,-1 8,0 z"
+ style="fill:none;stroke:url(#linearGradient40790);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path40644"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccc"
+ transform="translate(-0.0161112,10.500011)"
+ id="path40646"
+ d="m 165.25,238.25 1,-1 0.5,0 0.75,0.75 0.75,-0.75 0.5,0 0.75,0.75 0.75,-0.75 0.5,0 0.75,0.75 0.75,-0.75 0.5,0 0.75,0.83779 0.75,-0.83779 0.5,0 1,1 0,2.75 -0.75,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.75,-1 0,-2.75 z"
+ style="fill:url(#linearGradient40792);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 166.48389,249.00001 0,2 m 2,-2 0,2 m 2,-2 0,2 m 2,-2 0,2 m 2,-2 0,2"
+ style="fill:none;stroke:url(#linearGradient40794);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path40648"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="248"
+ x="168"
+ height="1"
+ width="7"
+ id="rect40650"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40652"
+ width="7"
+ height="1"
+ x="168"
+ y="246" />
+ <rect
+ y="244"
+ x="168"
+ height="1"
+ width="7"
+ id="rect40654"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40656"
+ width="1"
+ height="1"
+ x="174"
+ y="250" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40518"
+ transform="translate(18.999997,-40.99992)">
+ <g
+ style="display:inline"
+ transform="translate(60.98406,570.00002)"
+ id="g40521">
+ <g
+ 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="translate(0.01612278,22)"
+ id="g40523"
+ style="display:inline">
+ <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="path40525"
+ d="m 296.49991,-1.4999999 -13.00008,0 0,-12.9999991 13.00008,0 0,12.9999991 0,0 0,0 0,0 z"
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40545);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 284.50009,-2.5000021 0,-11.0000069 11.00001,0 -2.7e-4,11.000009 -10.99974,-2.1e-6 z"
+ id="path40527"
+ 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.3;fill:#9dac93;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 345,578 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z"
+ id="path40529"
+ transform="translate(-61.000183,-592.00002)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient40547);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 295.99982,-1.9999789 -11.9999,0 0,-12.0000411 11.9999,0 0,12.0000411 0,0 0,0 0,0 z"
+ id="path40531"
+ 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>
+ <rect
+ y="580"
+ x="347"
+ height="1"
+ width="0.99999863"
+ id="rect40533"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40535"
+ width="0.99999863"
+ height="1"
+ x="348"
+ y="581" />
+ <rect
+ y="582"
+ x="349"
+ height="1"
+ width="0.99999863"
+ id="rect40537"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40539"
+ width="0.99999863"
+ height="1"
+ x="348"
+ y="583" />
+ <rect
+ y="584"
+ x="347"
+ height="1"
+ width="0.99999863"
+ id="rect40541"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40543"
+ width="3"
+ height="1"
+ x="350"
+ y="584" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24081"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ transform="scale(1,-1)"
+ y="-652.00006"
+ x="104"
+ height="16"
+ width="16"
+ id="rect23916"
+ 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="g24071">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ 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="path23922"
+ d="m 118.5,637.6177 -1.25,-1.1177 -10.5,0 -1.25,1.25 0.0161,12.75006 0.9839,0.99994 11,0 1.01611,-0.99994 L 118.5,637.6177 z"
+ style="fill:url(#linearGradient26077);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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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 117,638 -10,0 0,1 10,0 0,-1 z"
+ id="path23926"
+ 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="ccccccccc"
+ style="fill:none;stroke:url(#linearGradient26079);stroke-width:0.99999923px;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 117.5,650.25006 -0.25,0.25 -10.5,0 -0.25,-0.25 0,-12.5 0.25,-0.25 10.5,0 0.25,0.25 0,12.5 z"
+ id="path23928"
+ 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:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23930"
+ width="1"
+ height="1.0000043"
+ x="115"
+ y="-639"
+ 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="scale(1,-1)" />
+ <path
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 108,641 0,4 4,0 0,-4 -4,0 z m 4,4 0,4 4,0 0,-4 -4,0 z"
+ id="rect23964"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24035"
+ d="m 108,649 0,-4 4,0 0,4 -4,0 z m 4,-4 0,-4 4,0 0,4 -4,0 z"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-648.5"
+ x="-115.5"
+ height="7"
+ width="7"
+ id="rect23986"
+ style="opacity:0.55;fill:none;stroke:url(#linearGradient26081);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"
+ transform="scale(-1,-1)" />
+ <rect
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient26083);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="rect23971"
+ width="7"
+ height="7"
+ x="108.5"
+ 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"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ transform="scale(1,-1)"
+ y="-652.00006"
+ x="104"
+ height="16"
+ width="16"
+ id="rect23328"
+ 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="g23330">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ 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="path23333"
+ d="m 118.5,637.6177 -1.25,-1.1177 -10.5,0 -1.25,1.25 0.0161,12.75006 0.9839,0.99994 11,0 1.01611,-0.99994 L 118.5,637.6177 z"
+ style="fill:url(#linearGradient23351);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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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 117,638 -10,0 0,1 10,0 0,-1 z"
+ id="path23335"
+ 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="ccccccccc"
+ style="fill:none;stroke:url(#linearGradient23353);stroke-width:0.99999923px;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 117.5,650.25006 -0.25,0.25 -10.5,0 -0.25,-0.25 0,-12.5 0.25,-0.25 10.5,0 0.25,0.25 0,12.5 z"
+ id="path23337"
+ 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:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23339"
+ width="1"
+ height="1.0000043"
+ x="115"
+ y="-639"
+ 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="scale(1,-1)" />
+ <path
+ style="fill:#b41500;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 108,641 0,4 4,0 0,-4 -4,0 z m 4,4 0,4 4,0 0,-4 -4,0 z"
+ id="path23341"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23345"
+ d="m 108,649 0,-4 4,0 0,4 -4,0 z m 4,-4 0,-4 4,0 0,4 -4,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-648.5"
+ x="-115.5"
+ height="7"
+ width="7"
+ id="rect23347"
+ style="opacity:0.45;fill:none;stroke:url(#linearGradient23355);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"
+ transform="scale(-1,-1)" />
+ <rect
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient23357);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="rect23349"
+ width="7"
+ height="7"
+ x="108.5"
+ y="641.5" />
+ </g>
+ </g>
+ <g
+ 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"
+ transform="translate(-198,-247)"
+ style="display:inline;enable-background:new">
+ <rect
+ y="257"
+ x="203"
+ height="16"
+ width="16"
+ id="rect42665"
+ 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(-39.983882,19.00809)"
+ id="g42667"
+ 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;enable-background:new">
+ <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="path42669"
+ d="m 244.51612,238.49191 -0.0161,3 7.98388,0 0.0161,-3 -7.98388,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;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 247.51612,241.49191 -0.0161,3 11,0 0.0161,-3 -11,0 z"
+ id="path42671"
+ 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="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 243.5,247.49191 -0.0161,3 12,0 0.0161,-3 -12,0 z"
+ id="path42673"
+ 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="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="path42675"
+ d="m 250.48388,250.49191 -0.0161,3 7.01612,0 0.0161,-3 -7.01612,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path42677"
+ d="m 205.51612,259.5 c 0,-0.25 0,-1 0,-1 l 6,0"
+ style="fill:none;stroke:url(#linearGradient42685);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42687);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 208.51612,262.5 c 0,-0.25 0,-1 0,-1 l 9,0"
+ id="path42679"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path42681"
+ d="m 204.5,268.5 c 0,-0.25 0,-1 0,-1 l 10,0"
+ style="fill:none;stroke:url(#linearGradient42689);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path42683"
+ d="m 211.5,271.5 c 0,-0.25 0,-1 0,-1 l 5,0"
+ style="fill:none;stroke:url(#linearGradient42691);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g25594"
+ transform="translate(-306,-275)">
+ <g
+ style="display:inline"
+ transform="translate(363,59)"
+ id="g25596"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="0.80014729"
+ y="289"
+ x="389"
+ height="16"
+ width="16"
+ id="rect25598"
+ style="opacity:0;fill:#ffffff;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="g25600"
+ transform="translate(-177,71)">
+ <g
+ 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="g25602"
+ transform="translate(480,287.5)">
+ <g
+ id="g25604"
+ transform="translate(-118.5,-200.5)"
+ 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
+ id="g25606"
+ transform="translate(1,24)"
+ style="fill:#000000" />
+ </g>
+ </g>
+ <rect
+ rx="0"
+ y="348"
+ x="752"
+ height="16"
+ width="16"
+ id="rect25608"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;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="path25610"
+ d="m 756.16666,348.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient25872);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path25612"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,817.54887,13.43979)"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask23591)"
+ transform="translate(725,-419)"
+ id="g25614"
+ style="display:inline">
+ <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="rect25616"
+ width="9"
+ height="13.999984"
+ x="31"
+ y="768" />
+ <g
+ id="g25618">
+ <rect
+ y="771"
+ x="32"
+ height="1"
+ width="1"
+ id="rect25620"
+ 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="rect25622"
+ width="1"
+ height="1"
+ x="32"
+ y="773" />
+ <rect
+ y="775"
+ x="32"
+ height="1"
+ width="1"
+ id="rect25624"
+ 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="rect25626"
+ width="1"
+ height="1"
+ x="32"
+ y="777" />
+ <rect
+ y="779"
+ x="32"
+ height="1"
+ width="1"
+ id="rect25628"
+ 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="rect25630"
+ width="1"
+ height="1"
+ x="32"
+ y="781" />
+ <rect
+ y="771"
+ x="34"
+ height="3"
+ width="3"
+ id="rect25632"
+ 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="rect25634"
+ width="3"
+ height="3"
+ x="34"
+ y="775" />
+ <rect
+ y="779"
+ x="34"
+ height="3"
+ width="3"
+ id="rect25636"
+ 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="rect25638"
+ width="1"
+ height="1"
+ x="38"
+ y="771" />
+ <rect
+ y="773"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25640"
+ 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="rect25642"
+ width="1"
+ height="1"
+ x="38"
+ y="775" />
+ <rect
+ y="777"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25644"
+ 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="rect25646"
+ width="1"
+ height="1"
+ x="38"
+ y="779" />
+ <rect
+ y="781"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25648"
+ 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="rect25650"
+ width="1"
+ height="1"
+ x="32"
+ y="769.02289" />
+ <rect
+ y="769.02289"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25652"
+ 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="rect25654"
+ width="3"
+ height="2"
+ x="34"
+ y="768" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 754.5,353 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient25874);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25656"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753,352 4,0 0,-4 -4,4 z"
+ id="path25658"
+ 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,351.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="path25660"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g25988"
+ transform="translate(-152,-151)">
+ <g
+ transform="translate(-272,34)"
+ id="g25437"
+ style="display:inline;enable-background:new">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ id="g25439"
+ transform="translate(523,-99)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25442"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g25444">
+ <g
+ transform="translate(480,287.5)"
+ id="g25446"
+ 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
+ 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"
+ transform="translate(-118.5,-200.5)"
+ id="g25448" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g25450" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25452"
+ width="16"
+ height="16"
+ x="912"
+ y="190"
+ rx="0" />
+ <g
+ id="g25454">
+ <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="path25456"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient26011);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter22979)"
+ id="path25458"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient26013);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25460"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ id="path25462"
+ 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 913.5,193.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="path25464"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25582"
+ d="m 650,228 1,0 -10e-6,6.5 -1,0 L 650,228 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 654,227 0,2 -4,0 10e-6,-2 3.99999,0 z"
+ id="path25584"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.8571421,0,0,0.8,601.28577,-208.6)"
+ id="g25586"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:type="arc"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25588"
+ sodipodi:cx="53"
+ 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"
+ 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"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path25590"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25592"
+ d="m 654,227 0,1 -4,0 10e-6,-1 3.99999,0 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25662"
+ d="m 645.5,226.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient26015);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g25963"
+ transform="translate(-86,-139)">
+ <g
+ transform="translate(-262,-147)"
+ id="g25359"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(-34,169)"
+ id="g25361">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ id="g25363"
+ transform="translate(523,-99)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25365"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g25367">
+ <g
+ transform="translate(480,287.5)"
+ id="g25369"
+ 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
+ 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"
+ transform="translate(-118.5,-200.5)"
+ id="g25372" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g25374" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25376"
+ width="16"
+ height="16"
+ x="912"
+ y="190"
+ rx="0" />
+ <g
+ id="g25378">
+ <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="path25380"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient25982);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter22999)"
+ id="path25382"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient25984);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25384"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ id="path25387"
+ 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 913.5,193.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="path25389"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ d="m 889.5,372.5 1,0 m 0,-4 -8,0 m 5,2 -5,0 m 1.25,-8 6.75,0 m 0,4 -8,0 m 8,-2 -8,0"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25391"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient25986);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 621.5,214.5 0,2 -2,0"
+ id="path25668"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g25933"
+ transform="translate(-107,-115)">
+ <g
+ id="g25393"
+ transform="translate(-296,-2.000004)"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ transform="translate(523,-99)"
+ id="g25396"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="0.80014729"
+ y="289"
+ x="389"
+ height="16"
+ width="16"
+ id="rect25398"
+ style="opacity:0;fill:#ffffff;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="g25400"
+ transform="translate(-177,71)">
+ <g
+ 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="g25402"
+ transform="translate(480,287.5)">
+ <g
+ id="g25404"
+ transform="translate(-118.5,-200.5)"
+ 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
+ id="g25406"
+ transform="translate(1,24)"
+ style="fill:#000000" />
+ </g>
+ </g>
+ <rect
+ rx="0"
+ y="190"
+ x="912"
+ height="16"
+ width="16"
+ id="rect25408"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25410">
+ <path
+ style="fill:url(#linearGradient25957);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path25413"
+ 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" />
+ <g
+ transform="translate(15.27209,-110)"
+ style="fill:#0044aa;display:inline"
+ id="g25415">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25417"
+ d="m 902.72791,305 2,0.90909 0,9.09091 -2,0 0,-10 z"
+ style="fill:#214478"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25419"
+ d="m 901.72791,305 1,0 0.25,0.5 -1.25,0 0,-0.5 z"
+ style="fill:#214478"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25421"
+ d="m 902.72791,305 6.75,0 0,1 -5.09127,0 -1.65873,-1 z"
+ style="fill:#214478"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="310"
+ x="904.72791"
+ height="1"
+ width="2.7499952"
+ id="rect25423"
+ style="fill:#214478" />
+ <rect
+ y="309.25"
+ x="907.22791"
+ height="2.5"
+ width="0.5"
+ id="rect25425"
+ style="fill:#214478" />
+ <rect
+ y="305"
+ x="909.22791"
+ height="2"
+ width="0.5"
+ id="rect25427"
+ style="fill:#214478" />
+ </g>
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ sodipodi:nodetypes="ccc"
+ id="path25429"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter23007)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25431"
+ style="fill:none;stroke:url(#linearGradient25959);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path25433"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path25435"
+ 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 913.5,193.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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ id="path25670"
+ d="m 621.5,190.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient25961);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g25672"
+ transform="translate(-348,-155)">
+ <g
+ transform="translate(-126,60.000002)"
+ id="g25674">
+ <g
+ transform="translate(-34,-22.000002)"
+ id="g25676">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ id="g25678"
+ transform="translate(523,-99)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25680"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g25682">
+ <g
+ transform="translate(480,287.5)"
+ id="g25684"
+ 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
+ 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"
+ transform="translate(-118.5,-200.5)"
+ id="g25686" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g25688" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25690"
+ width="16"
+ height="16"
+ x="912"
+ y="190"
+ rx="0" />
+ <g
+ id="g25692">
+ <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="path25694"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient25886);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter23015)"
+ id="path25696"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient25888);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25698"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ id="path25700"
+ 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 913.5,193.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="path25702"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25705"
+ transform="translate(910,-321.00012)"
+ mask="none"
+ clip-path="url(#clipPath22590)">
+ <rect
+ y="491.00012"
+ x="-29"
+ height="16"
+ width="16"
+ id="rect25707"
+ 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="g25709">
+ <g
+ id="g25711">
+ <path
+ id="path25713"
+ 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:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25715"
+ sodipodi:cx="13.5"
+ 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"
+ transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m -25.5,496.5 7.5,0 m -8.5,5.00012 3.5,-3.5"
+ 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:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25717"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient25890);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25719"
+ sodipodi:cx="13.5"
+ 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"
+ transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)" />
+ <path
+ id="path25721"
+ style="fill:none;stroke:url(#linearGradient25892);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.984366,-0.0226 M -26.5,501.50012 -21.5,496.5 m 5.996227,1.44466 L -20.25,493.5"
+ sodipodi:nodetypes="cccccc"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path25723"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path25725"
+ sodipodi:cx="13.5"
+ 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"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path25727"
+ style="fill:none;stroke:url(#linearGradient25894);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path25729"
+ style="fill:none;stroke:url(#linearGradient25897);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -6.734366,7.94478 3.280183,-3.10926 m -2,-2 6.25,0"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient25899);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,230.5 0,2 -2,0"
+ id="path25731"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g25822"
+ transform="translate(273,-334)">
+ <rect
+ y="407"
+ x="89"
+ height="16"
+ width="16"
+ id="rect25824"
+ 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" />
+ <g
+ id="g25826">
+ <path
+ style="fill:url(#linearGradient25927);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,408.5 0,11.49245 1.5,1.5 10.5,0.008 0,-11.99245 -8,-0.008 0,-1 -4,0 z"
+ id="path25828"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-361,287.99994)"
+ id="g25830"
+ style="display:inline" />
+ <path
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient25929);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,413.74245 12,0.008 0,6.25 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.75755 0,-9e-4 z"
+ id="path25832"
+ 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,-10.02344 2,0 0,1 L 100.5,410.5"
+ id="path25834"
+ inkscape:connector-curvature="0" />
+ <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 9.5,0"
+ id="path25836"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25838"
+ d="m 103.5,414.75 -10,-0.008 0,4.75755 -1.5,1.5 -1.5,-1.5"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient25931);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 93,409 0,2 -3,0 0,-2 3,0 z"
+ id="path25840"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path25842"
+ d="m 89.5,408.5 0,11.49245 1.5,1.5 12,0.008 1.5,-1.49245 0,-6.50755 -3,-0.008 0,-3.9849 -8,-0.008 0,-1 -4,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" />
+ </g>
+ </g>
+ <g
+ transform="translate(371,90.000008)"
+ id="g26093">
+ <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"
+ width="16"
+ height="16"
+ x="117"
+ y="529" />
+ <g
+ style="display:inline"
+ id="g26097"
+ transform="translate(28.71596,210.64282)">
+ <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="2.0305908"
+ ry="2.0305908"
+ y="326.84842"
+ x="88.784042"
+ height="6.0000124"
+ width="14"
+ id="rect26099"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new" />
+ <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"
+ style="fill:none;stroke:url(#linearGradient26126);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect26101"
+ width="12"
+ height="4.00875"
+ x="89.784042"
+ y="327.84842"
+ ry="1.029202"
+ rx="1.029202" />
+ <rect
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect26103"
+ width="14"
+ height="4.9999971"
+ x="88.784042"
+ y="319.85718"
+ ry="2.0154257"
+ rx="2.0154257"
+ 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"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient26128);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect26105"
+ width="12.000008"
+ height="2.9999971"
+ x="89.784042"
+ y="320.85718"
+ ry="0.97821051"
+ rx="0.97821051" />
+ <rect
+ ry="0"
+ rx="0"
+ y="320.35718"
+ x="89.284042"
+ height="3.9999919"
+ width="8"
+ id="rect26107"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ rx="0.97821051"
+ ry="0.97821051"
+ y="320.85718"
+ x="89.784042"
+ height="2.9999971"
+ width="12.000008"
+ id="rect26109"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient26130);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ 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"
+ rx="0"
+ y="320.85718"
+ x="96.284042"
+ height="3.0000272"
+ width="0.99999988"
+ id="rect26111"
+ style="opacity:0.6;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g26113"
+ transform="matrix(-1,0,0,1,193.28404,-130.61032)"
+ style="opacity:0.8;display:inline;enable-background:new">
+ <g
+ id="g26115">
+ <rect
+ style="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="rect26117"
+ width="1"
+ height="1"
+ x="91"
+ y="459.9675"
+ rx="0"
+ ry="0"
+ transform="matrix(-1,0,0,1,194,-1.1e-6)" />
+ <rect
+ ry="0"
+ rx="0"
+ y="458.9675"
+ x="92"
+ height="3"
+ width="1"
+ id="rect26119"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(-1,0,0,1,194,-1.1e-6)" />
+ <rect
+ ry="0"
+ rx="0"
+ y="459.9675"
+ x="92"
+ height="1"
+ width="1"
+ id="rect26121"
+ style="fill:#000000;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:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26123"
+ width="1"
+ height="3"
+ x="93"
+ y="458.9675"
+ rx="0"
+ ry="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g28119"
+ transform="translate(0,127.99999)">
+ <rect
+ y="302"
+ x="404"
+ height="16"
+ width="16.000004"
+ id="rect27916"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <g
+ id="g28110">
+ <path
+ id="path27918"
+ d="m 412,306.45213 c -3.54545,0 -5.90909,1.5 -6.49999,3.04787 0.5909,1.45213 2.95581,3.77094 6.49999,3.75 3.54709,-0.021 5.9091,-2.29787 6.50001,-3.75 -0.59091,-1.54787 -2.95455,-3.04787 -6.50001,-3.04787 z"
+ style="fill:url(#linearGradient28107);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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"
+ sodipodi:ry="2.91429"
+ sodipodi:rx="3.9999149"
+ sodipodi:cy="14.5"
+ sodipodi:cx="431"
+ id="path27920"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path27922"
+ style="fill:url(#linearGradient28099);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(2.249956,0,0,2.251405,267.75278,4.81032)" />
+ <path
+ sodipodi:nodetypes="ccscs"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ 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"
+ id="path27924"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="307.91428"
+ x="411"
+ height="2"
+ width="2"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path27928"
+ 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="translate(347,172.91429)" />
+ </g>
+ </g>
+ <g
+ id="g27932"
+ transform="translate(4e-6,127.99999)">
+ <g
+ transform="translate(0.4838899,-6.2084382e-8)"
+ id="g27934">
+ <path
+ sodipodi:nodetypes="ccscz"
+ style="opacity:0.25;fill:url(#radialGradient27973);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 432.51611,305.45213 c -3,0 -7,2.04787 -5.5,4.04787 0.5,1.45213 2.49969,3.02073 5.49861,2.99979 3.00139,-0.021 4.82513,-1.62106 5.50139,-2.99995 2,-2.49984 -2.5,-4.04771 -5.5,-4.04771 z"
+ id="path27936"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path27938"
+ d="m 432.51611,305.45213 c -3,0 -7.75,2.04787 -6.25,4.04787 0.5,1.45213 3.25108,3.52094 6.25,3.5 3.00139,-0.021 5.82374,-2.12111 6.5,-3.5 2,-2.49984 -3.5,-4.04787 -6.5,-4.04787 z"
+ style="opacity:0.18000004;fill:url(#radialGradient27975);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccscz"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:none;stroke:url(#linearGradient27977);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 438.51611,309.5 c -2,4 -10,4 -12,0"
+ id="path27940"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27942"
+ d="m 426.01611,309.5 c 2,5 11,5 13,0"
+ style="opacity:0.3;fill:none;stroke:#000000;stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="opacity:0.25;fill:none;stroke:none"
+ id="rect27944"
+ width="15.983887"
+ height="16"
+ x="425.01611"
+ y="302" />
+ </g>
+ <g
+ id="g27416"
+ transform="translate(105,-82)">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect27418"
+ width="16.000004"
+ height="16"
+ x="404"
+ y="302" />
+ <g
+ id="g27420">
+ <path
+ sodipodi:nodetypes="ccscz"
+ style="fill:url(#linearGradient27448);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 412,306.45213 c -3.54545,0 -5.90909,1.5 -6.49999,3.04787 0.5909,1.45213 2.95581,3.77094 6.49999,3.75 3.54709,-0.021 5.9091,-2.29787 6.50001,-3.75 -0.59091,-1.54787 -2.95455,-3.04787 -6.50001,-3.04787 z"
+ id="path27422"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.7500463,0,0,1.0294111,88.73017,294.07354)"
+ sodipodi:type="arc"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path27424"
+ sodipodi:cx="431"
+ 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" />
+ <path
+ transform="matrix(2.249956,0,0,2.251405,267.75278,4.81032)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient27450);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path27426"
+ sodipodi:cx="64"
+ 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" />
+ <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"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccscs"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect27430"
+ width="2"
+ height="2"
+ x="411"
+ y="307.91428" />
+ <path
+ transform="translate(347,172.91429)"
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path27432"
+ sodipodi:cx="64"
+ 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" />
+ </g>
+ </g>
+ <g
+ transform="translate(62.983887,-82)"
+ id="g27434">
+ <g
+ id="g27436"
+ transform="translate(0.4838899,-6.2084382e-8)">
+ <path
+ id="path27438"
+ d="m 432.51611,305.45213 c -3,0 -7,2.04787 -5.5,4.04787 0.5,1.45213 2.49969,3.02073 5.49861,2.99979 3.00139,-0.021 4.82513,-1.62106 5.50139,-2.99995 2,-2.49984 -2.5,-4.04771 -5.5,-4.04771 z"
+ style="opacity:0.25;fill:url(#radialGradient27452);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccscz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscz"
+ style="opacity:0.18000004;fill:url(#radialGradient27454);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 432.51611,305.45213 c -3,0 -7.75,2.04787 -6.25,4.04787 0.5,1.45213 3.25108,3.52094 6.25,3.5 3.00139,-0.021 5.82374,-2.12111 6.5,-3.5 2,-2.49984 -3.5,-4.04787 -6.5,-4.04787 z"
+ id="path27440"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27442"
+ d="m 438.51611,309.5 c -2,4 -10,4 -12,0"
+ style="opacity:0.25;fill:none;stroke:url(#linearGradient27456);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#000000;stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 426.01611,309.5 c 2,5 11,5 13,0"
+ id="path27444"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="302"
+ x="425.01611"
+ height="16"
+ width="15.983887"
+ id="rect27446"
+ style="opacity:0.25;fill:none;stroke:none" />
+ </g>
+ <g
+ transform="translate(147,170.00001)"
+ id="g27500">
+ <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"
+ width="16"
+ height="16"
+ x="26"
+ y="323"
+ ry="0" />
+ <g
+ id="g27516">
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path27518"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path27520"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path27522"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.765625"
+ rx="0.765625"
+ y="333.25"
+ x="31"
+ height="4.75"
+ width="6"
+ id="rect27524"
+ 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="rect27527"
+ width="4"
+ height="3"
+ x="32"
+ y="334" />
+ <path
+ sodipodi:nodetypes="cssssccccsccsssc"
+ id="path27529"
+ 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(#linearGradient27598);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path27531"
+ 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
+ id="path27533"
+ 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"
+ inkscape:connector-curvature="0" />
+ <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="rect27535"
+ width="0.25"
+ height="1"
+ x="37"
+ y="336" />
+ <rect
+ y="334"
+ x="37"
+ height="1"
+ width="0.25"
+ id="rect27537"
+ 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="rect27539"
+ 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="rect27541"
+ 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(#linearGradient27600);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path27543"
+ 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="path27545"
+ style="opacity:0.6;fill:url(#radialGradient27602);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
+ id="path27547"
+ style="fill:none;stroke:url(#linearGradient27604);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" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient27606);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path27549"
+ 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.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="path27551"
+ sodipodi:cx="64"
+ 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"
+ 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
+ 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(#radialGradient27608);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path27554"
+ inkscape:connector-curvature="0" />
+ <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="rect27557"
+ width="5"
+ height="0.75"
+ x="31.5"
+ y="333" />
+ <path
+ 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="path27564"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:url(#linearGradient27610);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="path27566"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <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="rect27585"
+ width="1"
+ height="1"
+ x="32"
+ y="328" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path27587"
+ style="fill:none;stroke:url(#radialGradient27612);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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path27590"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <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="rect27594"
+ width="2"
+ height="1"
+ x="33"
+ y="329" />
+ <rect
+ y="328"
+ x="35"
+ height="1"
+ width="1"
+ id="rect27596"
+ 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
+ style="display:inline;enable-background:new"
+ id="g28080"
+ transform="translate(-823,-175)">
+ <rect
+ y="416"
+ x="870"
+ height="16"
+ width="16"
+ id="rect28083"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1.2930992,0,0,1.3011246,677.85367,159.07065)"
+ style="opacity:0.96000001;display:inline"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path28087"
+ style="opacity:0.25;fill:url(#radialGradient28099);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
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient28101);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path28089"
+ 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.3568764,-0.3150232,0.3151738,-1.348049,102.81491,906.57916)" />
+ </g>
+ <path
+ style="fill:url(#linearGradient28103);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.89999998;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 883.5,426.5 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-3.5 2.5,-4.5 5,-10 2.5,5.5 5,6.5 5,10 z"
+ id="path28091"
+ sodipodi:nodetypes="csscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path28093"
+ d="m 878.5,418.40909 c 0.4375,0.96023 0.90625,1.78977 1.36328,2.53255 0.45703,0.74278 0.90234,1.3988 1.29297,2.01196 0.78125,1.22633 1.34375,2.28125 1.34375,3.5161 0,2.22473 -1.792,4.0303 -4,4.0303 -2.208,0 -4,-1.80557 -4,-4.0303 0,-2.41818 2.25,-4.2197 4,-8.06061 z"
+ style="fill:none;stroke:url(#linearGradient28105);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ 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="path28095"
+ sodipodi:cx="878.5"
+ 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"
+ transform="matrix(0.6434675,-0.7329672,0.7942866,0.5945179,-26.858149,815.24158)" />
+ <path
+ inkscape:transform-center-y="-7.1785015"
+ inkscape:transform-center-x="-7.136318"
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#radialGradient28107);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69954133;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path28097"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="translate(-94.999994,403.00001)"
+ id="g30296"
+ 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="rect30298"
+ width="16"
+ height="16"
+ x="163"
+ y="195" />
+ <g
+ id="g30300">
+ <g
+ transform="translate(0.01612278,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="g30302"
+ style="display:inline">
+ <g
+ style="fill:#ff943d;fill-opacity:1;stroke:none"
+ id="g30304">
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30306"
+ width="1"
+ height="2"
+ x="-199"
+ y="168.98387" />
+ <rect
+ y="207.98763"
+ x="174.98387"
+ height="2"
+ width="1"
+ id="rect30309"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="164.98387"
+ x="-199"
+ height="2"
+ width="1"
+ id="rect30311"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30313"
+ width="1"
+ height="2"
+ x="174.98387"
+ y="203.98763" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30315"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="207" />
+ <rect
+ y="203"
+ x="162.98387"
+ height="2"
+ width="1"
+ id="rect30318"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="167.97594"
+ x="-211"
+ height="2"
+ width="1"
+ id="rect30326"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ 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"
+ id="rect30328"
+ width="1"
+ height="2"
+ x="-211"
+ y="171.97594" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30330"
+ width="1"
+ height="2"
+ x="-211"
+ y="163.98387" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30332"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="199" />
+ </g>
+ <g
+ style="fill:#532500;fill-opacity:1"
+ id="g30334">
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30336"
+ width="1"
+ height="2"
+ x="-199"
+ y="166.98387" />
+ <rect
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30338"
+ width="1"
+ height="2"
+ x="174.98387"
+ y="205.98763" />
+ <rect
+ y="205"
+ x="162.98387"
+ height="2"
+ width="1"
+ id="rect30340"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30342"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="209" />
+ <rect
+ y="165.97594"
+ x="-211"
+ height="2"
+ width="1"
+ id="rect30344"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30346"
+ width="1"
+ height="2"
+ x="-211"
+ y="169.97594" />
+ <rect
+ y="173.97594"
+ x="-211"
+ height="2"
+ width="1"
+ id="rect30348"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ y="202"
+ x="174.98387"
+ height="2"
+ width="1"
+ id="rect30350"
+ style="fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30353"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="201" />
+ <rect
+ y="162.98387"
+ x="-199"
+ height="2"
+ width="1"
+ id="rect30355"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path30357"
+ d="m 163.99999,199 6.51562,0 1.23438,3.25 3.25,1.20312 0,6.54688 -11,0 0,-11 z"
+ style="opacity:0.25;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"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.781818,0,0,0.781818,38.760709,42.85549)"
+ 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="g30359"
+ style="display:inline">
+ <path
+ inkscape:transform-center-y="-6.3853012"
+ inkscape:transform-center-x="-6.3473305"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.78698397;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path30361"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:none;stroke:#28170b;stroke-width:4.47674513;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 164.66657,209.31279 3.51745,-3.51744"
+ id="path30363"
+ 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
+ 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="path30365"
+ d="m 168.5,205.5 0.96309,-0.98372"
+ style="fill:none;stroke:#000000;stroke-width:2.5581398;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.40697706;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 168.5,205.5 1.28285,-1.30349"
+ id="path30367"
+ 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="g30369"
+ 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.878699,0,0,0.877142,14.70687,20.74499)">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30389);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient30391);stroke-width:1.16848361;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="path30371"
+ 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.2468441,0,0,1.246865,503.16273,106.89331)" />
+ </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="path30373"
+ d="m 164.66657,209.31279 3.51745,-3.51744"
+ style="fill:none;stroke:#a05a2c;stroke-width:2.55814004;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
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.2790699;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 164.02704,208.99303 3.83721,-3.83721"
+ id="path30375"
+ 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
+ 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.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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path30377"
+ style="opacity:0.5;fill:url(#radialGradient30393);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69954133;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ <g
+ id="g30379"
+ style="opacity:0.96000001;display:inline"
+ transform="matrix(0.9729196,0,0,0.9789579,9.7047721,-0.8010785)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient30395);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30381"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path30383"
+ style="opacity:0.25;fill:url(#radialGradient30397);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
+ 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="path30385"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(1.2790738,0,0,1.2790735,89.840744,25.765779)" />
+ </g>
+ <path
+ id="path30387"
+ d="m 163.99999,199 0,11 1,0 0,-10 6,0 0,-1 -7,0 z"
+ style="opacity:0.12999998;fill:#000000;fill-opacity:1;fill-rule:nonzero;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>
+ <g
+ id="g28857">
+ <rect
+ y="241.00877"
+ x="68.001282"
+ height="16"
+ width="16"
+ id="rect27661"
+ 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
+ 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(0.9168751,0,0,0.9161255,-39.818417,44.251476)"
+ id="g27663"
+ style="display:inline"
+ clip-path="url(#clipPath42711)">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient42435);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.45480967;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="path27665"
+ 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"
+ clip-path="none"
+ mask="none" />
+ <path
+ transform="matrix(0.6147126,0,0,0.6147118,47.3579,150.96368)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42437);stroke-width:1.77499008;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path27667"
+ 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" />
+ </g>
+ <g
+ transform="translate(-167.99872,-18.991228)"
+ style="opacity:0.55"
+ id="g27669">
+ <path
+ style="fill:url(#linearGradient42432);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"
+ 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"
+ 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>
+ <g
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-167.74474,113.52244)"
+ style="display:inline;enable-background:new"
+ id="g27675">
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.49999988;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 73.54505,272.57627 1.06066,-2.47487"
+ id="path33728"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27679"
+ d="m 73.545051,272.22272 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
+ sodipodi:nodetypes="cc"
+ id="path33730"
+ d="m 78.494797,266.21231 2.651651,-0.88388"
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.49999988;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"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42359"
+ 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
+ id="g56105">
+ <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"
+ width="16"
+ height="16"
+ x="530"
+ y="52" />
+ <g
+ id="g56091">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path29110"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,2.75 -5.99999,3.24999 L 531,60.75 531,58 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;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\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#9e9e9e;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 531,58 6,-2.5 7.99996,3.49998 0,0.5 -6,3 L 531,58.56558 531,58 z"
+ id="path29112" />
+ <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="path29114"
+ d="M 531.00001,60.75 531,58.5 l 7.99996,3.99998 0.01,2.49885 -8.00991,-4.24883 -4e-5,0 z"
+ style="fill:#848484;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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"
+ style="fill:#383838;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 544.99996,61.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path29116"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient56084);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58.5 0,2 7.49996,3.99998 5.5,-3 0,-2"
+ id="path29118"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58 7.49996,3.74998"
+ id="path29120"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29129);stroke-width:1.08012342;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="path29122"
+ sodipodi:cx="749"
+ sodipodi:cy="420.25"
+ sodipodi:rx="2.5"
+ sodipodi:ry="1.75"
+ 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"
+ id="rect29125"
+ width="1"
+ height="1"
+ x="544"
+ y="61" />
+ </g>
+ </g>
+ <g
+ transform="translate(-0.1658249,128.41502)"
+ id="g27744">
+ <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"
+ width="16"
+ height="16"
+ x="47.165825"
+ y="364.58499" />
+ <g
+ id="g27748"
+ transform="matrix(1.032664,0,0,1.043556,-79.760429,254.38542)"
+ 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">
+ <path
+ sodipodi:type="arc"
+ style="fill:#4169a5;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.22966909;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="path27750"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path27752"
+ style="fill:url(#linearGradient27767);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ 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.666432,0,0,0.659342,42.69924,35.46375)" />
+ <path
+ transform="matrix(0.3631382,0,0,0.3593485,81.755824,69.904768)"
+ 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:type="arc"
+ style="opacity:0.7;fill:url(#linearGradient27769);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path27755"
+ 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" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27757"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter13996)"
+ transform="matrix(0.9688184,0,0,0.9547322,-131.63668,47.640696)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccssscsscccscccccccccccccccsccccc"
+ id="path27761"
+ d="m 130.67404,112.3079 c 0.0244,0.78706 -0.15754,1.63085 0.59269,2.02213 0.71197,-0.0434 1.49133,0.64122 1.35667,1.40517 -0.26776,0.77861 0.14071,1.12325 0.95576,1.36401 0.57868,-0.0716 0.79053,-0.93546 0.87357,-1.36401 0.0948,-1.27121 0.51542,-1.09421 0.82108,-1.98991 -0.45733,-0.91502 -0.003,-1.04443 -0.72629,-1.43739 m -1.00945,-3.89288 c -0.4426,0.34378 -0.24372,1.04314 -0.66162,1.39841 -0.45372,0.13628 -0.78226,-0.0605 -1.16771,0.43164 -0.30841,1.10457 0.35004,1.22306 0.90205,1.10457 0.49538,-0.0502 0.61419,-0.94321 0.97928,-0.37853 0.0831,0.10976 0.71917,-0.0403 0.86266,0.18898 0.0669,0.10682 -0.11785,0.0255 -0.14729,0.18955 -0.0428,0.23847 0.27734,0.37341 0.372,0.3824 0.32089,0.0305 0.60005,0.92548 0.83846,1.05499 0,0.46738 0.0924,-0.6774 0.3515,-0.78703 0.22948,-0.0971 0.47929,0.10731 0.5,0 0.29928,-1.55081 -1.26113,-3.00604 -2.82933,-3.58498 z M 128.96474,107.5 c -0.6111,1.01384 0.85343,1.46103 1.73001,1.21329 0.57897,-0.37879 1.00716,-0.92331 0.55665,-1.21329 -0.20614,-0.1415 -2.07706,0.0431 -2.28666,0 l 0,0 0,0 0,0 z m -1.372,1.37253 c -0.49575,-0.14959 0.44952,-0.11945 0.45733,0.45751 0.1696,0.54756 -0.42801,0.23756 0,0.45752 0.70893,0.1644 0.35328,1.70031 -0.28114,1.56208 -0.56042,0.10119 -0.43915,0.95826 -1.64865,0.88279 -0.0836,0.0755 -1.04512,0.61593 -0.81421,1.21521 1.12968,0.30162 -0.36816,1.26478 -0.43867,0.55236 -0.15441,-0.49797 -0.62853,-1.11348 -0.43994,-1.68674 0.11734,-0.63627 0.5689,-1.12263 0.82646,-1.69865 0.36225,-0.61946 0.89084,-1.17688 1.57758,-1.42595 0.21411,-0.16799 0.46159,-0.41691 0.76124,-0.31613 l 0,0 0,0 0,0 z m -0.91467,5.03262 c -0.55163,-0.27585 -0.72934,0.28829 -0.60377,0.7984 0.15577,0.47138 0.52607,0.97695 0.72628,1.43739 0.40435,0.49619 1.512,1.34081 2.17883,1.67696 0.31768,0.16015 0.48418,0 0.24209,-0.23956 -0.31367,-0.6375 -1.14073,-1.94893 -0.48418,-2.15609 0.59647,-0.60342 0.34203,-1.58773 -0.48419,-1.43739 -0.54779,-0.25818 -0.75551,-0.39899 -1.38855,-0.0752 -0.0558,0.0743 -0.12403,0.006 -0.18651,-0.004 l 0,-5.1e-4 0,0 0,0 z"
+ style="fill:url(#linearGradient27771);fill-opacity:1;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\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="path27763"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient27773);stroke-width:1.45454657;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path27765"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ 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.06052282,0,0,0.05989117,121.21686,103.80334)" />
+ </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"
+ transform="translate(0,2)">
+ <g
+ id="g31771"
+ transform="matrix(0,-1,1,0,249,491)">
+ <g
+ style="opacity:0.7;display:inline"
+ id="g31773"
+ transform="translate(257,86)">
+ <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="rect31775"
+ width="16"
+ height="16"
+ x="63"
+ y="48" />
+ </g>
+ <g
+ id="g31784"
+ transform="matrix(-1,0,0,1,656,0)">
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;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 323.5,137.5 0,9 3,0 3,0 3,0 0,-4 0,-5 -3,0 0,6 -3,0 0,-6 -3,0 z"
+ id="path31786"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31788"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 324.5,145.5 0,-7 1,0 m 6,0 -1,0 0,6 -4,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ transform="translate(0,21)"
+ style="opacity:0.8"
+ id="g31854">
+ <g
+ id="g31823">
+ <g
+ id="g31807">
+ <path
+ id="path31804"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;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 384.5,138.5 0,-3 3,0"
+ id="path31796"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,782,0)"
+ id="g31811">
+ <path
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;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:new"
+ d="m 384.5,138.5 0,-3 3,0"
+ id="path31813"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31819"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g31831"
+ transform="matrix(1,0,0,-1,0,284)">
+ <g
+ id="g31833">
+ <path
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;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:new"
+ d="m 384.5,138.5 0,-3 3,0"
+ id="path31842"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31845"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g31847"
+ transform="matrix(-1,0,0,1,782,0)">
+ <path
+ id="path31849"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;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 384.5,138.5 0,-3 3,0"
+ id="path31852"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </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"
+ transform="translate(63,212.00001)">
+ <rect
+ ry="0"
+ rx="0"
+ y="281"
+ x="47"
+ height="16"
+ width="16"
+ id="rect31979"
+ 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="g31981">
+ <g
+ transform="translate(-290.00001,409.99343)"
+ style="opacity:0.75;display:inline"
+ id="g31985">
+ <path
+ style="fill:none;stroke:#1a1a1a;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"
+ d="m 341.00001,-115.99343 c 4.5365,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path31987"
+ sodipodi:nodetypes="csc"
+ 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"
+ 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\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path31994"
+ d="m 341.00001,-115.99343 c 4.49647,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;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>
+ <g
+ transform="translate(-189.02763,408)"
+ id="g31998"
+ style="display:inline">
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect32000"
+ width="2.9998772"
+ height="3"
+ x="238.52776"
+ y="-115.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;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 241.02763,-115 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path32009"
+ 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
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-125.5"
+ x="241.52776"
+ height="3"
+ width="2.9998772"
+ id="rect32011"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32014"
+ d="m 244.02763,-125 c -0.65334,0 -1.30668,1e-5 -1.96003,1e-5 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-1e-5 1.96003,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#ffffff;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" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g32016"
+ 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"
+ id="rect32018"
+ width="16"
+ height="16"
+ x="563"
+ y="-183" />
+ <g
+ id="g32020">
+ <g
+ style="opacity:0.75"
+ id="g32022"
+ transform="translate(476.04566,-283.51773)">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path32025"
+ d="m 89.95451,104.01774 5,9.5 5,-9.5 -10,0 z"
+ style="fill:none;stroke:#1a1a1a;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;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.95451,103.98095 5,9.5 5,-9.5 -10,0 z"
+ id="path32028"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-181.49998"
+ x="574.50031"
+ height="3"
+ width="2.9998772"
+ id="rect32030"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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:#000000;stroke-width:1.5;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="rect32032"
+ width="2.9998772"
+ height="3"
+ x="564.50043"
+ y="-181.49998"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-171.5"
+ x="569.5"
+ height="3"
+ width="2.9998772"
+ id="rect32034"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 577.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="path32036"
+ 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="path32038"
+ d="m 572.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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path32040"
+ d="m 567.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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g32042"
+ transform="translate(83,212.00001)">
+ <rect
+ y="68"
+ x="281"
+ height="16"
+ width="16"
+ id="rect32044"
+ 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"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ id="g32046"
+ transform="matrix(0,-1,1,0,-254.00001,365.00041)">
+ <g
+ id="g32048"
+ style="opacity:0.7">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path32051"
+ style="fill:none;stroke:#1a1a1a;stroke-width:2.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 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:#cccccc;stroke-width:1;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="path32053"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect32055"
+ width="2.9998772"
+ height="3"
+ x="80.500122"
+ y="323.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 83.00041,324.00001 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="path32061"
+ 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
+ rx="1.4999386"
+ ry="1.4999386"
+ y="334.5"
+ x="80.49971"
+ height="3"
+ width="2.9998772"
+ id="rect32063"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32065"
+ d="m 83,335 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g25012"
+ transform="translate(-83.999998,191)">
+ <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="rect25014"
+ width="16.000032"
+ height="16"
+ x="-231.00003"
+ y="281" />
+ <g
+ transform="translate(235.00016,-1)"
+ id="g25016">
+ <g
+ id="g25018"
+ transform="translate(-376,510)"
+ style="opacity:0.8">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path25020"
+ d="m 358.99997,-216.75 c -0.99997,-6.5 6.00003,-2.75 5,-9.25 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="fill:none;stroke:#1a1a1a;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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#b3b3b3;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 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path25022"
+ 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"
+ style="opacity:0.7;fill:url(#linearGradient25056);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path25024"
+ 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"
+ id="path25026"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="opacity:0.75;fill:url(#radialGradient25058);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ 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="path25028"
+ d="m 364.24984,-225.5 4.25016,1.75 c 1,5.75 -5.50003,2 -5.08381,8.85761 l -4.04561,-2.26888"
+ style="fill:none;stroke:url(#linearGradient25060);stroke-width:1;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"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;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 364.24997,-225.5 4.25003,1.75"
+ id="path25031"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-399.2499,383.75)"
+ id="g25033">
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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="rect25035"
+ width="2.9998772"
+ height="3"
+ x="391.75"
+ y="-99.25"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;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 394.24987,-98.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path25039"
+ 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>
+ <g
+ id="g25041"
+ transform="translate(-406.2499,380.75)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-98.25"
+ x="392.74988"
+ height="3"
+ width="2.9998772"
+ id="rect25043"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path25046"
+ d="m 395.24974,-97.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.666663 0,1.333317 0,1.99999 0.66668,0 1.33333,-1e-5 2,-1e-5 0,-0.666663 0,-1.333327 0,-1.99999 z"
+ style="fill:#ffffff;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" />
+ </g>
+ <path
+ style="opacity:0.3;fill:#ffffff;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 -11.00003,286 c -0.66668,0 -1.33332,0 -2,0 0,-0.33334 0,-0.66666 0,-1 0.66668,0 1.33332,0 2,0 0,0.33334 0,0.66667 0,1 z"
+ id="path25048"
+ 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="path25050"
+ d="m -7.00003,285.53933 c -0.33334,0 -0.66666,10e-6 -1,10e-6 0,0.82281 0,1.64561 0,2.46844 0.33334,0 0.66666,-1e-5 1,-1e-5 0,-0.82282 0,-1.64562 0,-2.46844 l 0,0 0,0 0,0 z"
+ style="opacity:0.3;fill:#ffffff;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
+ 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="path25052"
+ d="m -9.972188,286 c -0.342621,0 -0.685221,0 -1.027842,0 0,-0.66873 0,-1.33742 0,-2.00616 0.342621,0 0.685221,0 1.027842,0 0,0.66874 0,1.33745 0,2.00616 z"
+ style="opacity:0.3;fill:#ffffff;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.3;fill:#ffffff;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 -6.000162,287 c -0.33334,0 -0.66666,0 -1,0 0,0.33428 0,0.66856 0,1.00284 0.33334,0 0.66666,0 1,0 0,-0.33428 0,-0.66856 0,-1.00284 z"
+ id="path25054"
+ 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>
+ </g>
+ <g
+ id="g32145"
+ transform="translate(147,191.00001)">
+ <g
+ transform="translate(-138,212)"
+ style="opacity:0.8;display:inline"
+ id="g32147">
+ <g
+ transform="translate(1.0551033e-6,0)"
+ id="g32149">
+ <g
+ style="display:inline"
+ transform="matrix(0.927273,0,0,1,85.654543,64)"
+ id="g32151"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\Browser icons ver 1\Outliner ICON CODES.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ sodipodi:nodetypes="cccccc"
+ 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="path32153"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.63466382;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ 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:#1a1a1a;stroke-width:1.86925566;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z M 63.999982,17 64,19 l 2.156862,0 -1.8e-5,-2 -2.156862,0 0,0 0,0 0,0 z m 10.78431,0 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path32155"
+ 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"
+ 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"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path32158"
+ style="fill:url(#radialGradient32241);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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"
+ sodipodi:nodetypes="cccc"
+ d="M 70.499967,14.5 75.5,17.5"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ececec;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path32161"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ style="opacity:0.8;fill:none;stroke:url(#radialGradient32243);stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path32165"
+ 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="cccccc"
+ transform="translate(-1.6176466e-5,0)"
+ 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"
+ sodipodi:nodetypes="ccccc"
+ id="path32168"
+ d="m 74.784292,17 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;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"
+ sodipodi:nodetypes="cccc"
+ id="path32172"
+ style="fill:none;stroke:#999999;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 65.5,17.5"
+ 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"
+ sodipodi:nodetypes="cc"
+ id="path32174"
+ style="fill:none;stroke:#cccccc;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 70.470586,14.5 0,-6"
+ 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"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path32177"
+ 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"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 64,17 0,2 2.156844,0 0,-2 L 64,17 z"
+ id="path32179"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="13.25"
+ x="68.583321"
+ height="3.5"
+ width="3.774509"
+ id="rect32186"
+ style="opacity:0.05;fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path32193"
+ d="m 64.539197,18.5 0,-1 1.078431,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.03847623px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ 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:1.03847647px;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 69.931347,8.5 0,-0.9673924 1.078413,0"
+ id="path32197"
+ sodipodi:nodetypes="ccc"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path32199"
+ d="m 75.323509,18.500001 0,-1 1.078431,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="5"
+ x="61.843121"
+ height="16"
+ width="17.254898"
+ id="rect32201"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 155,80.5 -3,-1.870665"
+ id="path32206"
+ transform="matrix(1.0784311,0,0,1,-92.372519,-64)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.01000001;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:1.03847647px;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 74.245078,17.500001 0,-1 1.078431,0"
+ id="path32208"
+ sodipodi:nodetypes="ccc"
+ 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
+ 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="cc"
+ id="path32215"
+ d="m 69.931352,9.5000005 1.078431,0"
+ style="opacity:0.4;fill:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#666666;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path32218"
+ d="m 66.696014,17.499989 0,-1 -1.078431,0"
+ style="opacity:0.4;fill:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#4c4c4c;stroke-width:1.03847575px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path32230"
+ d="m 147,80.5 3,-1.870665"
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 150.5,73.5 0,4"
+ id="path32235"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="78"
+ x="150.06403"
+ height="2"
+ width="2"
+ id="rect32237"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ rx="0"
+ ry="0"
+ y="289.5"
+ x="11.499837"
+ height="3"
+ width="2.9998772"
+ id="rect32239"
+ 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
+ style="display:inline;enable-background:new"
+ id="g52805"
+ 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"
+ id="rect52807"
+ width="16"
+ height="16"
+ x="-75"
+ y="420" />
+ <g
+ transform="translate(-577.98389,452.95862)"
+ style="display:inline;enable-background:new"
+ id="g52809">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52811"
+ 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(#radialGradient53119);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="path52813"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path52815"
+ 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(#linearGradient53121);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.38281,1.847656 2.36719,-2.347656 -1.5,-2 z"
+ id="path52817"
+ 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 518.48389,-29.45862 -4,4.75 2,2.25 2,-2"
+ id="path52819"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52821"
+ d="m 518.98389,-29.70862 -4.75,5.5 1.75,1.75 3,-2.75 0,-4.5 z"
+ style="fill:url(#linearGradient53123);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 5,-6"
+ id="path52823"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53125);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="path52825"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-185,34)"
+ id="g52827">
+ <rect
+ ry="0.019097222"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52829"
+ width="11"
+ height="11"
+ x="110"
+ y="386"
+ rx="0.019097222" />
+ <g
+ id="g52831">
+ <path
+ id="path52833"
+ d="m 116.53125,386.5 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.28156 0.12508,0.53133 0.3125,0.71875 L 113,392 c -0.18742,-0.18742 -0.46844,-0.5 -0.75,-0.5 l -0.75,0 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.56312 0.46813,1.03125 1.03125,1.03125 l 0.9375,0 c 0.0103,0 0.021,3e-4 0.0312,0 -3e-4,0.0102 0,0.021 0,0.0312 l 0,0.9375 c 0,0.56312 0.46813,1.03126 1.03125,1.03125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.28156 -0.10164,-0.53133 -0.28125,-0.71875 l 2.625,-2.625 c 0.18742,0.18742 0.43719,0.3125 0.71875,0.3125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.56312 -0.43688,-1.03125 -1,-1.03125 l -0.96875,0 c -0.0103,0 -0.021,-3e-4 -0.0312,0 3e-4,-0.0102 0,-0.021 0,-0.0312 l 0,-0.9375 c 0,-0.56312 -0.46813,-1.03125 -1.03125,-1.03125 l -0.9375,0 z"
+ style="fill:url(#linearGradient53127);fill-opacity:1;fill-rule:evenodd;stroke:#333333;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="cccccccccccsccccccccccccccscccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52835"
+ d="m 111.5,393.5 0,-0.75 0.25,-0.25 1.75,0 3,-3 0,-1.75 0.25,-0.25 0.75,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 118.75,389.5 0.75,0 m -6,6 0,-0.75"
+ id="path52837"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;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"
+ id="rect52839"
+ width="1"
+ height="1"
+ x="114"
+ y="393" />
+ <rect
+ y="390"
+ x="117"
+ height="1"
+ width="1"
+ id="rect52841"
+ style="opacity:0.2;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>
+ </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">
+ <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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g52873"
+ transform="translate(120,94.000007)">
+ <rect
+ y="420"
+ x="-52"
+ height="16"
+ width="16"
+ id="rect52875"
+ 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
+ transform="translate(-556.98389,452.95862)"
+ style="display:inline;enable-background:new"
+ id="g52877">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52879"
+ 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(#radialGradient53141);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="path52881"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path52883"
+ 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(#linearGradient53143);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="path52885"
+ 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 520.48389,-31.45862 -6,6.75 2,2.25 4,-4"
+ id="path52887"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52889"
+ d="m 520.98389,-31.95862 -6.75,7.75 1.75,1.75 5,-4.5 0,-5 z"
+ style="fill:url(#linearGradient53145);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 7,-8.25"
+ id="path52891"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53147);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="path52893"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ mask="url(#mask57450)"
+ id="g52895"
+ style="display:inline"
+ transform="translate(-378.00003,264.99999)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path52897"
+ d="m 328.50261,168.45815 0.0576,-10.96002 10.94282,-0.0283"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#d2d2d2;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 328.50261,168.45815 0.0576,-10.96002 10.94282,-0.0283"
+ id="path52899"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(1,5.25126e-6,0,1,0,0)"
+ y="155.49829"
+ x="326.50003"
+ height="2.9999838"
+ width="2.9999995"
+ id="rect52901"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265" />
+ </g>
+ </g>
+ <g
+ transform="translate(318,94.000007)"
+ id="g52903"
+ 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"
+ id="rect52905"
+ width="16"
+ height="16"
+ x="-124"
+ y="420" />
+ <g
+ id="g52907"
+ transform="translate(-258,96.99999)"
+ mask="url(#mask32294)">
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 142.5,327.5 c 0,1.2526 -0.5,2 -1.5,3 -1,1 0,3 -1.25,3 l -2.5,0 c -1.25,0 -0.25,-2 -1.25,-3 -1,-1 -1.5,-1.75686 -1.5,-3 0,-2.208 1.792,-4 4,-4 2.208,0 4,1.792 4,4 z"
+ id="path52909"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path52911"
+ d="m 142.5,327.5 c 0,1.2526 -0.5,2 -1.5,3 -1,1 0,3 -1.25,3 l -2.5,0 c -1.25,0 -0.25,-2 -1.25,-3 -1,-1 -1.5,-1.75686 -1.5,-3 0,-2.208 1.792,-4 4,-4 2.208,0 4,1.792 4,4 z"
+ style="fill:none;stroke:#1a1a1a;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 137.5,336.00001 2,0 0,1 -2,-10e-6 0,-0.99999 z"
+ id="path52913"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <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="rect52915"
+ width="5"
+ height="4.7498698"
+ x="136"
+ y="331.25"
+ rx="0.765625"
+ ry="0.765625" />
+ <rect
+ y="332.60001"
+ x="137"
+ height="2.55"
+ width="3"
+ id="rect52917"
+ style="fill:#a89858;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,-128.7,252.00668)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.021577613"
+ inkscape:original="M 249.25 79.96875 C 248.7604 79.96875 248.46875 80.255136 248.46875 80.5 C 248.46875 80.744863 248.76041 81.031252 249.25 81.03125 C 249.73959 81.031248 251.26039 81.03125 251.75 81.03125 C 252.23961 81.03125 252.53125 80.744873 252.53125 80.5 C 252.53125 80.255131 252.23961 79.968752 251.75 79.96875 L 249.25 79.96875 z M 249.25 81.96875 C 248.7604 81.96875 248.46875 82.255138 248.46875 82.5 C 248.46875 82.744863 248.76041 83.031253 249.25 83.03125 L 251.75 83.03125 C 252.23961 83.03125 252.53125 82.744875 252.53125 82.5 C 252.53125 82.255131 252.23961 81.968753 251.75 81.96875 C 251.26039 81.968747 249.7396 81.96875 249.25 81.96875 z "
+ style="fill:url(#linearGradient53149);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path52919"
+ 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 l 2.5,0 c 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 l -2.5,0 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 2.5,0 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 l -2.5,0 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z" />
+ <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="path52921"
+ d="m 137.25,334.25 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 137.25,332.25 1.25,0"
+ id="path52923"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="334"
+ x="141"
+ height="1"
+ width="0.25"
+ id="rect52925"
+ 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="rect52927"
+ width="0.25"
+ height="1"
+ x="141"
+ y="332" />
+ <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="rect52929"
+ width="0.25"
+ height="1"
+ x="135.75"
+ y="334" />
+ <rect
+ y="332"
+ x="135.75"
+ height="1"
+ width="0.25"
+ id="rect52931"
+ 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="translate(-112,254)"
+ 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="path52933"
+ style="fill:url(#linearGradient53151);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(#radialGradient53153);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path52935"
+ 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="translate(-112,254)" />
+ <path
+ d="m 138.5,324.5 c 1.656,0 3,1.34699 3,3.00667 0,0.89477 -0.39063,1.69865 -1.01019,2.24958 C 139.96017,330.22723 139.5,331 139.5,332.25 m -1,-7.75 c -1.656,0 -3,1.34699 -3,3.00667 0,0.89477 0.39063,1.69865 1.01019,2.24958 C 137.03983,330.22723 137.5,331 137.5,332.25"
+ style="fill:none;stroke:url(#linearGradient53155);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path52937"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path52939"
+ style="opacity:0.25;fill:url(#radialGradient53157);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="path52941"
+ 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,74.34506,191)" />
+ <path
+ id="path52943"
+ style="fill:none;stroke:url(#radialGradient53159);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 138.5,324.5 c 1.656,0 3,1.34699 3,3.00667 0,0.89477 -0.39063,1.69865 -1.01019,2.24958 C 139.96017,330.22723 139.5,331 139.5,332.25 m -1,-7.75 c -1.656,0 -3,1.34699 -3,3.00667 0,0.89477 0.39063,1.69865 1.01019,2.24958 C 137.03983,330.22723 137.5,331 137.5,332.25"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="331"
+ x="136.01562"
+ height="0.75"
+ width="4.96875"
+ id="rect52945"
+ style="opacity:0.85;fill:#504416;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="path52947"
+ d="m 137.5,335.01146 2,0 0,1 -2,-10e-6 0,-0.99999 z"
+ style="fill:#6c6753;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52949"
+ d="m 138,329 0,3.75 1,0 0,-3.75 -1,0 z"
+ style="opacity:0.2;fill:url(#linearGradient53161);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="137"
+ height="1"
+ width="3"
+ id="rect52951"
+ style="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.3;fill:#d3bc5f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52953"
+ width="1"
+ height="1"
+ x="138"
+ y="328" />
+ <path
+ d="m 138.5,324.5 c 1.656,0 3,1.34699 3,3.00667 0,0.89477 -0.39063,1.69865 -1.01019,2.24958 C 139.96017,330.22723 139.5,331 139.5,332.25 m -1,-7.75 c -1.656,0 -3,1.34699 -3,3.00667 0,0.89477 0.39063,1.69865 1.01019,2.24958 C 137.03983,330.22723 137.5,331 137.5,332.25"
+ style="fill:none;stroke:url(#radialGradient53163);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path52955"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52957"
+ d="m 137.5,336.00001 0.5,0 0,1 -0.5,-10e-6 0,-0.99999 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-626.98389,452.95862)"
+ style="display:inline;enable-background:new"
+ id="g52959">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52961"
+ 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(#radialGradient53165);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="path52963"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path52965"
+ 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(#linearGradient53167);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.38281,1.847656 2.36719,-2.347656 -1.5,-2 z"
+ id="path52967"
+ 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 518.48389,-29.45862 -4,4.75 2,2.25 2,-2"
+ id="path52969"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52971"
+ d="m 518.98389,-29.70862 -4.75,5.5 1.75,1.75 3,-2.75 0,-4.5 z"
+ style="fill:url(#linearGradient53169);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 5,-6"
+ id="path52973"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53171);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="path52975"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g77742"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-870.9421,-297.02038)" />
+ <g
+ id="g33404"
+ 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"
+ id="rect33341"
+ width="16"
+ height="16"
+ x="257"
+ y="113" />
+ <g
+ style="opacity:0.8;display:inline"
+ id="g33343"
+ transform="matrix(1.1658027,0,0,1.1657997,112.71027,-140.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
+ 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="path33345"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1.33333421;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.643333,0,0,0.643335,44.424162,146.72855)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient33427);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path33347"
+ 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.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)" />
+ <path
+ transform="matrix(0.5361112,0,0,0.5361024,58.577433,159.38208)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33429);stroke-width:1.60001671;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path33349"
+ 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" />
+ </g>
+ <g
+ transform="translate(5,-21)"
+ id="g33351">
+ <g
+ id="g33353"
+ transform="translate(169.04507,38.63228)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path33355"
+ d="m 90.45493,102.86772 -4.5e-4,6.03674 6.00045,-0.0367 4.5e-4,-6.03674 -6.00045,0.0367 z"
+ style="opacity:0.7;fill:none;stroke:#002255;stroke-width:2.5;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:#afc6e9;fill-opacity:0.70588235;fill-rule:evenodd;stroke:#afc6e9;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 90.45493,102.86772 -4.5e-4,6.03674 6,0 4.5e-4,-6.03674 -6,0 z"
+ id="path33357"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="146.5"
+ x="264.50012"
+ height="3"
+ width="2.9998772"
+ id="rect33359"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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="rect33361"
+ width="2.9998772"
+ height="3"
+ x="257.50012"
+ y="139.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="146.49997"
+ x="257.49969"
+ height="3"
+ width="2.9998772"
+ id="rect33363"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 267.00027,146.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="path33365"
+ 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="path33367"
+ d="m 260,147 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path33369"
+ d="m 260.00029,140 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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="rect33371"
+ width="2.9998772"
+ height="3"
+ x="264.50085"
+ y="139.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <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="path33373"
+ d="m 267.00101,139.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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g50822"
+ 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"
+ id="rect50824"
+ width="16"
+ height="16"
+ x="-27"
+ y="446" />
+ <g
+ transform="translate(-49,229)"
+ id="g50826"
+ style="opacity:0.5">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path50828"
+ style="fill:none;stroke:#1a1a1a;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 25.5,220 0,10.5 4,0 m -4,-5 c 0.125,0 4,0 4,0"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m 25.5,220 0,10.5 4,0 m -4,-5 c 0.125,0 4,0 4,0"
+ style="fill:none;stroke:#bcd0f5;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="path50830"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient50870);fill-opacity:1;fill-rule:evenodd;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"
+ id="rect50832"
+ width="7.000001"
+ height="3"
+ x="-26.5"
+ y="446.5" />
+ <g
+ transform="translate(-48,228)"
+ style="opacity:0.45"
+ id="g50834">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50836"
+ width="1"
+ height="1"
+ x="24"
+ y="226" />
+ <rect
+ y="231"
+ x="24"
+ height="1"
+ width="1"
+ id="rect50838"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path50840"
+ d="m -19.5,452.5 0,3 7,0 0,-3 -7,0 z m 0,6 0,3 7,0 0,-3 -7,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.69999999;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
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -25.5,448.5 0,-1 5,0"
+ id="path50842"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path50844"
+ d="m -18.5,454.5 0,-1 5,0"
+ style="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="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -18.5,460.5 0,-1 5,0"
+ id="path50846"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="447.25"
+ x="-25"
+ height="1.75"
+ width="1"
+ id="rect50848"
+ style="opacity:0.4;fill:#000000;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.3;fill:#000000;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50850"
+ width="1"
+ height="2"
+ x="-18"
+ y="453" />
+ <rect
+ y="459"
+ x="-18"
+ height="2"
+ width="1"
+ id="rect50852"
+ style="opacity:0.3;fill:#000000;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path50854"
+ d="m -23.5,448.5 0,-1 3,0"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -16.5,454.5 0,-1 3,0"
+ id="path50856"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path50858"
+ d="m -16.5,460.5 0,-1 3,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="translate(-48,228)"
+ y="225"
+ x="24"
+ height="1"
+ width="1"
+ id="rect50860"
+ 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" />
+ <rect
+ 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"
+ id="rect50862"
+ width="1"
+ height="1"
+ x="-23"
+ y="454" />
+ <rect
+ y="455"
+ x="-24"
+ height="1"
+ width="1"
+ id="rect50864"
+ 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" />
+ <rect
+ 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"
+ id="rect50866"
+ width="1"
+ height="1"
+ x="-24"
+ y="458" />
+ <rect
+ y="459"
+ x="-23"
+ height="1"
+ width="1"
+ id="rect50868"
+ 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"
+ 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"
+ id="rect33464"
+ width="16"
+ height="16"
+ x="173"
+ y="134"
+ ry="0" />
+ <g
+ style="opacity:0.8;display:inline"
+ id="g33466"
+ transform="matrix(1.0761252,0,0,1.0761229,40.809522,-96.59025)"
+ 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\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="path33469"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient33831);stroke-width:1.44444537;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.643333,0,0,0.643335,44.424162,146.72855)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient33833);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path33471"
+ 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.5902213,-0.06639044,0.06727327,-0.5855229,199.31507,300.5352)" />
+ <path
+ transform="matrix(0.5227063,0,0,0.5226977,60.34688,160.96383)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33835);stroke-width:1.77780378;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path33473"
+ 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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g33475"
+ transform="translate(-62.70896,-1.9304201)">
+ <path
+ style="fill:none;stroke:#003380;stroke-width:2.99999976;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 245.20896,142.43042 5,-5"
+ id="path33477"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:none;stroke:#2a7fff;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000233;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 244.54233,144.43041 1.33333,0 1.33332,-1.33332 0,-1.33335 -1.33332,-1.33332 -1.33332,-1e-5 -1.33333,1.33334 0,1.33333 1.33332,1.33333 z"
+ id="path33479"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path33483"
+ d="m 244.45896,144.43042 1.5,0 1.25,-1.25 0,-1.5 -1.3333,-1.25 -1.4167,0 -1.25,1.25 0,1.5 1.25,1.25 z"
+ style="fill:none;stroke:#0044aa;stroke-width:1.20000005;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 244.45896,143.93042 1.5,0 0.75,-0.75 0,-1.5 -0.75,-0.75 -1.5,0 -0.75,0.75 0,1.5 0.75,0.75 z"
+ id="path33481"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path33485"
+ d="m 245.20896,142.43042 5,-5"
+ style="fill:none;stroke:url(#linearGradient33585);stroke-width:1.29999995;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="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="141.93039"
+ x="244.709"
+ height="1"
+ width="1"
+ id="rect33487"
+ style="opacity:0.8;fill:#00112b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.99999976;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </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="rect33589"
+ width="16"
+ height="16"
+ x="215"
+ y="136" />
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(84,-124)"
+ id="g36191"
+ mask="url(#mask25369)">
+ <rect
+ y="281"
+ x="320"
+ height="16"
+ width="16"
+ id="rect36193"
+ style="opacity:0.01000001;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 324.5,295.75 0,-13.5 m 7,13.5 0,-13.5"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36195"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36197"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 321.25001,285.50001 334.75,285.5 M 321.25001,292.50001 334.75,292.5"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36199"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 324.5,296.5 0,-14.99999 m 7,14.99999 0,-14.99999"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 320.5,285.50001 15,0 m -15,6.99999 15,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ 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)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ 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"
+ 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)" />
+ <g
+ id="g36232">
+ <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" />
+ <path
+ 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)" />
+ </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)" />
+ </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"
+ 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"
+ id="rect36248"
+ width="16"
+ height="16"
+ x="71"
+ y="518" />
+ <g
+ id="g36250">
+ <g
+ mask="url(#mask18634)"
+ id="g36252"
+ transform="translate(-136,386)">
+ <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="path36254"
+ d="m 210,134.5 7.5,0 0,13 -10,0 0,-10.5 2.5,-2.5 z"
+ style="fill:url(#linearGradient37472);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ sodipodi:nodetypes="ccc"
+ id="path36256"
+ style="fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ d="m -48.384641,259.86235 2.000031,-0.008 -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36258"
+ d="m 207,138 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ 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 207.5,137 0,10.5 10,0 0,-13 -7.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="path36260"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36262"
+ style="fill:none;stroke:url(#linearGradient37475);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 208.5,138.5 0,8 m 3,-11 5,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.01000001"
+ clip-path="url(#clipPath18524)"
+ transform="translate(-134,387)"
+ id="g36264">
+ <path
+ style="fill:url(#linearGradient37477);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 210,134.5 7.5,0 0,12 -10,0 0,-9.5 2.5,-2.5 z"
+ id="path36266"
+ 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
+ d="m -48.384641,259.86235 2.000031,-0.008 -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path36268"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 207,138 4,0 0,-4 -4,4 z"
+ id="path36270"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path36272"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 207.5,137 0,9.5 10,0 0,-12 -7.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"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 208.5,138.5 0,7 m 3,-10 5,0"
+ style="fill:none;stroke:url(#linearGradient37479);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path36274"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g36276"
+ 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.781818,0,0,0.781818,-53.239298,365.85549)">
+ <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.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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36278"
+ style="fill:#ffffff;fill-opacity:0.1372549;stroke:#000000;stroke-width:0.78698397;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.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ <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="path36280"
+ d="m 164.66657,209.31279 3.51745,-3.51744"
+ style="fill:none;stroke:#28170b;stroke-width:4.47674513;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.5581398;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 168.5,205.5 0.96309,-0.98372"
+ id="path36282"
+ 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
+ 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="path36284"
+ d="m 168.5,205.5 1.28285,-1.30349"
+ style="fill:none;stroke:#cccccc;stroke-width:1.40697706;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" />
+ <g
+ transform="matrix(0.878699,0,0,0.877142,14.70687,20.74499)"
+ 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="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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36288"
+ style="fill:url(#linearGradient37481);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37483);stroke-width:1.16848361;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:type="arc" />
+ </g>
+ <path
+ style="fill:none;stroke:#a05a2c;stroke-width:2.55814004;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 164.66657,209.31279 3.51745,-3.51744"
+ id="path36290"
+ 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
+ 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="path36292"
+ d="m 164.02704,208.99303 3.83721,-3.83721"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.2790699;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-6.3853012"
+ inkscape:transform-center-x="-6.3473305"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient37485);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69954133;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36294"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="matrix(0.9729196,0,0,0.9789579,9.7047721,-0.8010785)"
+ style="opacity:0.96000001;display:inline"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36298"
+ style="opacity:0.25;fill:url(#radialGradient37487);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
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37489);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36300"
+ 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)" />
+ </g>
+ <path
+ transform="matrix(1.2790738,0,0,1.2790735,89.840744,25.765779)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path36302"
+ sodipodi:cx="64"
+ 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" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(42,41)"
+ id="g36304"
+ style="opacity:0.96000001;display:inline;enable-background:new">
+ <path
+ inkscape:transform-center-y="-6.5435007"
+ inkscape:transform-center-x="-6.5092113"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient37491);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ id="path36306"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="translate(42,87)"
+ id="g36308">
+ <rect
+ y="449"
+ x="89"
+ height="16"
+ width="16"
+ id="rect36310"
+ 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="path36312"
+ d="M 93.5,460.5 95,459"
+ style="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:transform-center-y="-6.8594309"
+ inkscape:transform-center-x="-6.8191649"
+ sodipodi:type="arc"
+ style="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;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36314"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ <path
+ style="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 90.863188,463.13807 93.25,460.75"
+ id="path36316"
+ 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:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 93.5,460.5 2,-2"
+ id="path36318"
+ 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="g36320"
+ 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,-86.169279,229.32421)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37493);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37495);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="path36322"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36326"
+ style="opacity:0.25;fill:url(#radialGradient37497);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
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37499);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36328"
+ 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)" />
+ </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="path36330"
+ 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)" />
+ </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="path36332"
+ d="m 90.75,463.25 2.5,-2.5"
+ style="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.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.25,463 93,460.25"
+ id="path36334"
+ 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>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 142,545 1,3e-5 0,-1 0,-1 3.5,0 0,-2 -3.5,0 0,-1 0,-1 -1,-3e-5 -2,2.5 0,1 z"
+ id="path36337"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339"
+ 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"
+ id="rect36341"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343">
+ <g
+ id="g36345"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349"
+ style="fill:#ff6600;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#ad2f94;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353"
+ style="fill:#0060f0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#00d4aa;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357"
+ style="fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#ffbf0e;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361"
+ 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
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ 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="path36363"
+ style="opacity:0.3;fill:url(#radialGradient37501);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <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="path36365"
+ style="fill:none;stroke:url(#linearGradient37503);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ transform="translate(105,41)"
+ id="g36367"
+ style="opacity:0.96000001;display:inline;enable-background:new">
+ <g
+ id="g36369"
+ transform="translate(0,87)">
+ <rect
+ y="449"
+ x="89"
+ height="16"
+ width="16"
+ id="rect36371"
+ 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="path36373"
+ d="M 93.5,460.5 95,459"
+ style="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:transform-center-y="-6.8594309"
+ inkscape:transform-center-x="-6.8191649"
+ sodipodi:type="arc"
+ style="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="path36375"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ <path
+ style="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 90.863188,463.13807 93.25,460.75"
+ id="path36377"
+ 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:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 93.5,460.5 95,459"
+ id="path36379"
+ 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="g36381"
+ 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,-86.169279,229.32421)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37505);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37507);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="path36383"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36387"
+ style="opacity:0.25;fill:url(#radialGradient37509);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
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37511);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36389"
+ 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)" />
+ </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="path36391"
+ 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)" />
+ </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="path36393"
+ d="m 90.75,463.25 2.5,-2.5"
+ style="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.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.25,463 93,460.25"
+ id="path36395"
+ 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>
+ <path
+ inkscape:transform-center-y="-6.547647"
+ inkscape:transform-center-x="-6.5102284"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient37513);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ id="path36397"
+ 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.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"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g36399"
+ style="fill:#000000"
+ transform="translate(0,87)">
+ <g
+ id="g36401"
+ style="fill:#000000">
+ <rect
+ style="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="rect36403"
+ width="2"
+ height="6"
+ x="98"
+ y="452"
+ ry="0.453125" />
+ <rect
+ y="-102"
+ x="454"
+ height="6"
+ width="2"
+ id="rect36405"
+ style="fill:#000000;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)"
+ ry="0.65625" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(105,41)"
+ id="g36407"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36409"
+ style="fill:url(#radialGradient37515);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.5092113"
+ inkscape:transform-center-y="-6.5435007" />
+ <g
+ id="g36411"
+ transform="translate(21,87)">
+ <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="rect36413"
+ width="16"
+ height="16"
+ x="89"
+ y="449" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 93.5,460.5 95,459"
+ id="path36415"
+ 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
+ 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,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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36417"
+ style="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: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="path36419"
+ d="M 90.863188,463.13807 93.25,460.75"
+ style="fill:none;stroke:#28170b;stroke-width:3.70000005;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"
+ sodipodi:nodetypes="cc"
+ id="path36421"
+ d="M 93.5,460.5 95,459"
+ style="fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1.0988734,0,0,1.0981343,-86.169279,229.32421)"
+ 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="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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36425"
+ style="fill:url(#linearGradient37517);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37519);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="g36427">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37521);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36429"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36431"
+ style="opacity:0.25;fill:url(#radialGradient37523);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="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path36433"
+ sodipodi:cx="64"
+ 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"
+ inkscape:transform-center-x="-3.1120555"
+ inkscape:transform-center-y="-5.7593212" />
+ </g>
+ <path
+ style="fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 90.75,463.25 2.5,-2.5"
+ id="path36435"
+ 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
+ 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="path36437"
+ d="M 90.25,463 93,460.25"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="-123"
+ x="541"
+ height="6"
+ width="2"
+ id="rect36439"
+ style="fill:#000000;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)"
+ ry="0.609375" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36441"
+ transform="translate(107,-124)">
+ <g
+ style="opacity:0.85;display:inline;enable-background:new"
+ transform="translate(-273,0)"
+ id="g36443"
+ mask="url(#mask25561)">
+ <rect
+ y="281"
+ x="320"
+ height="16"
+ width="16"
+ id="rect36445"
+ style="opacity:0.01000001;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 325.5,295.75 0,-13.5 m 6,13.5 0,-13.5"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36447"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36449"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 321.25,286.5 13.49999,-10e-6 M 321.25001,292.50001 334.75,292.5"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36451"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 325.5,296.49999 0,-14.99999 m 6,15 0,-14.99999"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 320.5,286.5 15,0 m -15,6 15,0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36453"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-21,0)"
+ id="g36455">
+ <g
+ transform="translate(-277.98388,250)"
+ id="g36457"
+ 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"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path36459"
+ style="fill:url(#linearGradient37525);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.69999641;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="fill:none;stroke:url(#linearGradient37527);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="path36461"
+ 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(0.857099,0,0,0.857147,67.228993,5.071249)" />
+ </g>
+ <g
+ transform="translate(-210,147)"
+ id="g36463">
+ <rect
+ y="137"
+ x="282"
+ height="1"
+ width="1"
+ id="rect36465"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36467"
+ width="1"
+ height="1"
+ x="283"
+ y="138" />
+ <rect
+ y="139"
+ x="282"
+ height="1"
+ width="1"
+ id="rect36469"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36472"
+ width="1"
+ height="1"
+ x="281"
+ y="138" />
+ <rect
+ y="138"
+ x="283"
+ height="1"
+ width="1"
+ id="rect36474"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36476"
+ style="opacity:0.5">
+ <rect
+ y="137"
+ x="281"
+ height="1"
+ width="1"
+ id="rect36478"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="137"
+ x="283"
+ height="1"
+ width="1"
+ id="rect36480"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="139"
+ x="283"
+ height="1"
+ width="1"
+ id="rect36482"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="139"
+ x="281"
+ height="1"
+ width="1"
+ id="rect36484"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36486"
+ transform="translate(-44.309303,267.47333)">
+ <rect
+ y="309.52667"
+ x="49.309303"
+ height="16"
+ width="16"
+ id="rect36488"
+ style="opacity:0;fill:#ececec;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:transform-center-y="-5"
+ inkscape:transform-center-x="5"
+ style="opacity:0.7"
+ id="g36490"
+ transform="translate(-396.6907,133.52667)">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36492"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;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 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36494"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,1,-1,0,241.3093,-136.47333)"
+ id="g36496"
+ style="opacity:0.7"
+ inkscape:transform-center-x="-5"
+ inkscape:transform-center-y="-5">
+ <path
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36498"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36500"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;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>
+ <g
+ inkscape:transform-center-y="5"
+ inkscape:transform-center-x="-5"
+ style="opacity:0.7"
+ id="g36502"
+ transform="matrix(-1,0,0,-1,511.3093,501.52667)">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36504"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;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 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36506"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,-1,1,0,-126.6907,771.52667)"
+ id="g36508"
+ style="opacity:0.7"
+ inkscape:transform-center-x="5"
+ inkscape:transform-center-y="5">
+ <path
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36510"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36512"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;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>
+ <g
+ transform="matrix(1.1870922,0,0,1.1818357,-168.36213,276.1664)"
+ id="g36514"
+ style="display:inline">
+ <g
+ id="g36516">
+ <g
+ style="display:inline;enable-background:new"
+ id="g36518"
+ transform="matrix(0.8423946,0,0,0.8461413,-192.36364,-120.73212)">
+ <path
+ inkscape:transform-center-y="-3"
+ inkscape:transform-center-x="3"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ id="path36520"
+ d="m 450.5,179 -0.83982,0.68197 L 449,180.5 l 0,0.5 1,0 0,1 1,0 0,1 0.25,0 0.66329,-1.10494 L 453,181.25 l 0,-0.25 -1,0 0,-1 -1,0 0,-1 -0.5,0 z"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 459,180.5 458.31803,179.66018 457.5,179 l -0.5,0 0,1 -1,0 0,1 -1,0 0,0.25 1.10494,0.66329 L 456.75,183 l 0.25,0 0,-1 1,0 0,-1 1,0 0,-0.5 z"
+ id="path36522"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:transform-center-x="-3"
+ inkscape:transform-center-y="-3"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="3"
+ inkscape:transform-center-x="-3"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ id="path36524"
+ d="m 457.5,189 0.83982,-0.68197 L 459,187.5 l 0,-0.5 -1,0 0,-1 -1,0 0,-1 -0.25,0 -0.66329,1.10494 L 455,186.75 l 0,0.25 1,0 0,1 1,0 0,1 0.5,0 z"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 449,187.5 0.68197,0.83982 L 450.5,189 l 0.5,0 0,-1 1,0 0,-1 1,0 0,-0.25 -1.10494,-0.66329 L 451.25,185 l -0.25,0 0,1 -1,0 0,1 -1,0 0,0.5 z"
+ id="path36526"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:transform-center-x="3"
+ inkscape:transform-center-y="3"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cssscczzzz"
+ 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="path36528"
+ d="m 190.07108,29.454411 c -3.02619,0 -5.48439,2.463313 -5.48438,5.5 0,3.036688 2.45819,5.500001 5.48438,5.5 3.02619,0 5.48437,-2.46331 5.48437,-5.5 0,-3.036689 -2.45818,-5.500001 -5.48437,-5.5 z m 0.0124,3.388115 c 1.26359,0 2.10599,0.846143 2.10599,2.115354 0,1.269211 -0.8424,2.115353 -2.10599,2.115353 -1.26359,0 -2.10598,-0.846141 -2.10598,-2.115353 0,-1.269212 0.84239,-2.115354 2.10598,-2.115354 l 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient37529);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.75983924;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" />
+ <path
+ transform="matrix(0.5547465,0,0,-0.5552803,116.84153,100.48096)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37531);stroke-width:2.28174472;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path36530"
+ 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\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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path36532"
+ style="fill:none;stroke:url(#linearGradient37533);stroke-width:3.21050167;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.3942416,0,0,-0.3946688,138.04864,81.514802)" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccc"
+ id="path36534"
+ d="m 190.94678,29.919785 -0.8687,-0.147436 -0.81609,0.147436 0,2.538424 0.8347,-0.01215 0.85009,0.01215 0,-2.538424 0,0 0,0 0,0 z m 1.68479,4.230706 0,0.846142 0,0.846141 2.52718,0 0.0755,-0.891284 -0.0755,-0.800999 -2.52718,0 0,0 0,0 0,0 z m -7.58155,0 -0.10953,0.819696 0.10953,0.872587 2.52718,0 0,-0.846141 0,-0.846142 -2.52718,0 z m 5.89676,3.17303 -0.8687,0.152099 -0.81609,-0.152099 0,2.74996 0.8347,0.07585 0.85009,-0.07585 0,-2.74996 z"
+ style="fill:#d40000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ 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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path36536"
+ style="fill:none;stroke:url(#linearGradient37535);stroke-width:2.28174472;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.5547465,0,0,-0.5552803,116.84153,100.48096)" />
+ <path
+ transform="matrix(0.3942416,0,0,-0.3946688,138.04864,81.514802)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37537);stroke-width:3.21050167;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path36538"
+ 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\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g36540"
+ inkscape:label="Layer 1"
+ transform="translate(-211.14286,264.78067)">
+ <g
+ transform="translate(307.14286,-384.78067)"
+ id="g36542"
+ style="display:inline">
+ <rect
+ y="592"
+ x="182"
+ height="16"
+ width="16"
+ id="rect36544"
+ 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="g36546"
+ transform="translate(117.00001,391)">
+ <g
+ transform="translate(-203,-446)"
+ style="display:inline"
+ id="g36548">
+ <g
+ transform="matrix(0.9993234,0,0,1.0050357,164.07104,603.72198)"
+ style="opacity:0.96000001;display:inline"
+ id="g36550">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path36552"
+ d="m 118.00879,52.264848 10e-6,2.238708 -7.00472,3.482446 -6.00407,-2.984969 -1e-5,-2.238708 7.00473,-2.736203 6.00406,2.238726 0,0 0,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79609263;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36554"
+ d="m 105.00001,52.762325 7.00473,-2.736212 6.00406,2.238717 0,2.238716 -7.00473,1.492495 -6.00406,-0.995 0,-2.238716 0,0 0,0 0,0 z"
+ style="fill:#e6e6e6;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"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 105.00998,54.999895 -0.01,-1.988833 6.00407,2.984969 0.01,1.988833 -6.00406,-2.984969 -1e-5,0 z"
+ id="path36556"
+ 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="path36558"
+ d="m 118.0088,54.503556 -0.01,-1.988833 -6.99476,3.481308 c 0,2.570679 0,1.425722 0,1.989979 l 7.00473,-3.482454 3e-5,0 0,0 0,0 z"
+ style="fill:#4d4d4d;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" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient37539);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 269.25,657.25 0,1.5 5.75,3 6.75,-3.5 0,-1.5"
+ id="path36560"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 70,228.5 65,226"
+ id="path36562"
+ transform="translate(2.0099702,-15.001162)"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,1,433.97059,0)"
+ id="g36564">
+ <path
+ sodipodi:nodetypes="cssccssccssc"
+ id="path36566"
+ d="m 245.5,593.5 c 1.25,2.5 0.97056,4.5 0.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 0.0294,-4 -1.97056,-6.5 z m -5,0 c 2.75,1.25 2.97056,4.5 2.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 -0.72056,-5 -3.97056,-6.5 z m -1,4 c 1.97058,0 1.97058,2 1.97058,2.5 0,0.75 0,0.75 0,0 0,-0.5 0,-2.5 -1.97058,-2.5 z"
+ style="fill:none;stroke:url(#linearGradient37541);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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssccssccssc"
+ id="path36568"
+ d="m 245.5,593.5 c 1.25,2.5 0.97056,4.5 0.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 0.0294,-4 -1.97056,-6.5 z m -5,0 c 2.75,1.25 2.97056,4.5 2.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 -0.72056,-5 -3.97056,-6.5 z m -1,4 c 1.97058,0 1.97058,1.5 1.97058,2.5 0,0.5 0,0.5 0,0 0,-1 0,-2.5 -1.97058,-2.5 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37543);stroke-width:1.29999995;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>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36570"
+ transform="translate(21,254)">
+ <rect
+ y="321"
+ x="66"
+ height="20"
+ width="20"
+ id="rect36572"
+ style="opacity:0;fill:#ececec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-235,231)"
+ id="g36574"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(392,-78.06282)"
+ id="g36576"
+ style="display:inline;enable-background:new">
+ <g
+ id="g36578">
+ <g
+ mask="url(#mask13041)"
+ id="g36580"
+ transform="translate(-360,181.06282)">
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 279.46875,-12.53125 c -1.65264,0 -2.96875,1.066109 -2.96875,2.71875 l 0,2.5625 c 0,1.6526411 1.31612,2.71875 2.96875,2.71875 l 0.0625,0 c 1.65264,0 2.96875,-1.0661089 2.96875,-2.71875 l 0,-2.5625 c 0,-1.652641 -1.31612,-2.71875 -2.96875,-2.71875 l -0.0625,0 z M 279.5,-10.5 c 0.554,0 1,0.196 1,0.75 l 0,2.5 c 0,0.554 -0.446,0.75 -1,0.75 -0.554,0 -1,-0.196 -1,-0.75 l 0,-2.5 c 0,-0.554 0.446,-0.75 1,-0.75 z"
+ id="path36582"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-10"
+ x="277"
+ height="2.5"
+ width="1"
+ id="rect36584"
+ style="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"
+ ry="0.5" />
+ <rect
+ style="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"
+ id="rect36586"
+ width="1"
+ height="1"
+ x="277.49176"
+ y="-11.287262"
+ ry="0.5" />
+ </g>
+ <g
+ mask="url(#mask13052)"
+ transform="translate(-360,191.06282)"
+ id="g36588">
+ <path
+ id="path36590"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.003609 -2.96875,2.65625 l 0,2.5625 c 0,1.6526411 1.34737,2.75 3,2.75 l 0.0625,0 c 1.65264,0 2.9375,-1.0973589 2.9375,-2.75 l 0,-2.5625 c 0,-1.652641 -1.31612,-2.65625 -2.96875,-2.65625 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.1335 1,0.6875 l 0,2.5 c 0,0.554 -0.41475,0.78125 -0.96875,0.78125 -0.554,0 -1.03125,-0.22725 -1.03125,-0.78125 l 0,-2.5 c 0,-0.554 0.446,-0.6875 1,-0.6875 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="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"
+ id="rect36592"
+ width="1"
+ height="2.5"
+ x="277"
+ y="-10"
+ ry="0.390625" />
+ <rect
+ y="-11"
+ x="278"
+ height="1"
+ width="1"
+ id="rect36594"
+ style="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"
+ ry="0.5" />
+ </g>
+ </g>
+ <g
+ id="g36596" />
+ </g>
+ <rect
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36608"
+ width="1"
+ height="3"
+ x="311"
+ y="93" />
+ <rect
+ y="104"
+ x="311"
+ height="3"
+ width="1"
+ id="rect36610"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36612"
+ transform="translate(0,275)">
+ <g
+ transform="translate(-226,210)"
+ id="g36614"
+ style="display:inline;enable-background:new">
+ <path
+ id="path36616"
+ d="m 302.5,105.52631 0,-4"
+ style="fill:none;stroke:#2d2d2d;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask24466)"
+ transform="translate(23,116.0625)"
+ id="g36618">
+ <path
+ id="path36620"
+ d="m 279.46875,-12.59375 c -1.65264,0 -2.96875,1.066109 -2.96875,2.71875 l 0,2.5625 c 0,1.6526411 1.31612,2.78125 2.96875,2.78125 l 0.0625,0 c 1.65264,0 2.96875,-1.1286089 2.96875,-2.78125 l 0,-2.5625 c 0,-1.652641 -1.31612,-2.71875 -2.96875,-2.71875 l -0.0625,0 z m 0.0312,2.03125 c 0.554,0 1,0.196 1,0.75 l 0,2.5 c 0,0.554 -0.446,0.8125 -1,0.8125 -0.554,0 -1,-0.2585 -1,-0.8125 l 0,-2.5 c 0,-0.554 0.446,-0.75 1,-0.75 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;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"
+ id="rect36622"
+ width="1"
+ height="3.5"
+ x="277"
+ y="-11.0625"
+ ry="0.5" />
+ <rect
+ y="-12.0625"
+ x="278"
+ height="1"
+ width="1"
+ id="rect36624"
+ style="opacity:0.7;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"
+ ry="0.5" />
+ </g>
+ <g
+ id="g36626"
+ mask="url(#mask24456)"
+ transform="translate(2e-6,-21.02385)">
+ <path
+ id="path36628"
+ d="m 302.5,118.49506 0,-3.99506"
+ style="fill:none;stroke:#2d2d2d;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(22.999998,128.02385)"
+ id="g36630"
+ mask="none">
+ <path
+ id="path36632"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.128609 -2.96875,2.78125 l 0,2.5 c 0,1.6526411 1.34737,2.75 3,2.75 l 0.0625,0 c 1.65264,0 2.9375,-1.0973589 2.9375,-2.75 l 0,-2.5 c 0,-1.652641 -1.31612,-2.78125 -2.96875,-2.78125 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.2585 1,0.8125 l 0,2.4375 c 0,0.554 -0.41475,0.78125 -0.96875,0.78125 -0.554,0 -1.03125,-0.22725 -1.03125,-0.78125 l 0,-2.4375 c 0,-0.554 0.446,-0.8125 1,-0.8125 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;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"
+ id="rect36634"
+ width="1"
+ height="3.5"
+ x="277"
+ y="-10"
+ ry="0.5" />
+ <rect
+ y="-11"
+ x="278"
+ height="1"
+ width="1"
+ id="rect36636"
+ style="opacity:0.7;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" />
+ </g>
+ <g
+ mask="none"
+ id="g36638"
+ transform="translate(22.999998,120)">
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.128609 -2.96875,2.78125 l 0,2.5 c 0,1.6526411 1.34737,2.75 3,2.75 l 0.0625,0 c 1.65264,0 2.9375,-1.0973589 2.9375,-2.75 l 0,-2.5 c 0,-1.652641 -1.31612,-2.78125 -2.96875,-2.78125 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.2585 1,0.8125 l 0,2.4375 c 0,0.554 -0.41475,0.78125 -0.96875,0.78125 -0.554,0 -1.03125,-0.22725 -1.03125,-0.78125 l 0,-2.4375 c 0,-0.554 0.446,-0.8125 1,-0.8125 z"
+ id="path36640"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-10"
+ x="277"
+ height="3.5"
+ width="1"
+ id="rect36642"
+ style="opacity:0.7;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" />
+ <rect
+ style="opacity:0.7;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"
+ id="rect36644"
+ width="1"
+ height="1"
+ x="278"
+ y="-11" />
+ </g>
+ <g
+ id="g36646"
+ mask="none"
+ transform="translate(21.999998,-0.00494)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36648"
+ d="m 280.5,118.5 0,-4"
+ style="opacity:0.55;fill:none;stroke:#1a1a1a;stroke-width:2.79440284;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36650"
+ d="m 280.5,118.5 0,-4"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.55;fill:none;stroke:#1a1a1a;stroke-width:2.79440284;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 302.5,105.52631 0,-4"
+ id="path36652"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 302.5,105.52631 0,-4"
+ id="path36654"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="99"
+ x="302"
+ height="1"
+ width="1"
+ id="rect36664"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ y="297"
+ x="66"
+ height="26"
+ width="20"
+ id="rect36666"
+ style="opacity:0;fill:#ececec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,530,548)"
+ style="opacity:0.9;display:inline;enable-background:new"
+ id="g36668">
+ <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"
+ width="16"
+ height="16"
+ x="488"
+ y="29" />
+ <g
+ id="g36672">
+ <path
+ sodipodi:nodetypes="csccccccccsssc"
+ id="path36674"
+ d="m 500.5,34.5 0,5 c 0,1.666667 0.25,1.75 1,3.25 l -1.25,1.75 -1.75,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -1,0 C 491,43 490.5,42.416667 490.5,40.75 l 0,-6.25 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ style="fill:url(#linearGradient37545);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" />
+ <path
+ d="m 495.5,30.375 c -2.28774,0 -4.125,1.837258 -4.125,4.125 l 0,6.25 c 0,0.74605 0.0978,1.170828 0.28125,1.625 0.13101,0.324408 0.38353,0.789244 0.625,1.25 l 0.0937,0 1.5,-1.5 a 0.87292083,0.87292083 0 0 1 1.25,0 l 1.375,1.375 1.375,-1.375 a 0.87292083,0.87292083 0 0 1 1.1875,-0.03125 l 1.375,1.21875 0.1875,-0.1875 0,-0.4375 C 500.24057,42.152166 499.91254,41.661109 499.78125,41.125 499.62101,40.470677 499.625,39.833334 499.625,39 l 0,-4.5 c 0,-2.287742 -1.83726,-4.125 -4.125,-4.125 z"
+ id="path36676"
+ style="fill:none;stroke:url(#linearGradient37547);stroke-width:1;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:original="M 495.5 29.5 C 492.74 29.5 490.5 31.74 490.5 34.5 L 490.5 40.75 C 490.5 42.416667 491 43 491.75 44.5 L 492.75 44.5 L 494.5 42.75 L 496.25 44.5 L 496.75 44.5 L 498.5 42.75 L 500.5 44.5 L 501.5 43.5 L 501.5 42.5 C 500.5 41.25 500.5 40.666667 500.5 39 L 500.5 34.5 C 500.5 31.74 498.26 29.5 495.5 29.5 z "
+ inkscape:radius="-0.87283355"
+ sodipodi:type="inkscape:offset" />
+ <g
+ style="opacity:0.25;fill:#000000"
+ id="g36678">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ d="m 493,43.75 c 0,-0.212963 0,-5.75 0,-5.75 l 1.5,4.472222 L 493,43.75 z"
+ id="path36681"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36683"
+ d="m 497,44 c 0,-0.203703 -1,-6 -1,-6 l 2,3.428571 0,1.714286 L 497,44 z"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,990,0.25)"
+ id="g36685"
+ style="opacity:0.7;fill:#ffffff">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36687"
+ d="m 493,43.75 c 0,-0.212963 1,-6 1,-6 l 1,5 -1,1 -1,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 497,43.75 c 0,-0.203703 0,-6 0,-6 l 2,5 -1,1 -1,0 z"
+ id="path36689"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 490,43.25 c 0,-0.212963 1.5,-6.25 1.5,-6.25 l 0.5,5.5 -2,0.75 z"
+ id="path36691"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ 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"
+ d="m 500.5,34.5 0,4.5 c 0,1.666667 0,2.25 1,3.5 l 0,1 -1,1 -2,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -0.5,0 C 491,43 490.5,43.166667 490.5,41.5 l 0,-7 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ id="path36693"
+ sodipodi:nodetypes="cscccccccccsssc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36695"
+ d="m 56,139 0,1 -1,0 0,1 2,0 0,-2 -1,0 z"
+ style="opacity:0.8;fill:url(#linearGradient37549);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:url(#linearGradient37551);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 51,139 0,2 2,0 0,-1 -1,0 0,-1 -1,0 z"
+ id="path36697"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(47,571)"
+ id="g36699"
+ 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"
+ d="m 67,7.75 0,7.25 -1,0 -1,-2 -1,0 0,1 2,5 2,2 7,0 2,-3.25 0,-4 L 76.5,13 76,13 76,14 75,14 75,12.75 74.25,12 73,12 l 0,2 -1,0 0,-2 -1,-1 -1,0 0,3 -1,0 L 69,7.75 68.37057,7 67.643297,7 67,7.75 z"
+ id="path36701"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36703"
+ width="16"
+ height="16"
+ x="63"
+ y="6" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ id="path36705"
+ d="m 67,7.75 0,7.25 -1,0 0,-1 -1,-1 -1,0 0,1 2,5 2,2 7,0 2,-3.25 0,-4 L 76.5,13 76,13 76,14 75,14 75,12.75 74.25,12 73,12 l 0,2 -1,0 0,-2 -1,-1 -1,0 0,3 -1,0 L 69,7.75 68.37057,7 67.643297,7 67,7.75 z"
+ style="fill:url(#linearGradient37553);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient37555);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 69,17 0,3 1,0 0,-3 -1,0 z m 2,0 0,3 1,0 0,-3 -1,0 z m 2,0 0,3 1,0 0,-3 -1,0 z"
+ id="path36707"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="15"
+ x="66"
+ height="1"
+ width="1"
+ id="rect36709"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36711"
+ width="1"
+ height="1"
+ x="66"
+ y="16" />
+ <path
+ style="fill:none;stroke:url(#linearGradient37557);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 74.09375,12.25 -0.625,0 0,1.75 c 0.0031,0.12523 -0.04536,0.246239 -0.133933,0.334817 C 73.246239,14.423395 73.12523,14.4718 73,14.46875 L 72.5,14.5 m -1.65625,-3.25 -0.375,0 0,2.75 c 0.0031,0.12523 -0.04536,0.246239 -0.133933,0.334817 C 70.246239,14.423395 70.12523,14.4718 70,14.46875 L 69.5,14.5 M 64.46875,13.46875 64.5,14 l 1.870938,4.629172 1.847812,1.902078 6.53125,0 1.78125,-2.875 0,-4 -0.0625,-0.125 0,0.46875 c 0.0031,0.12523 -0.04536,0.246239 -0.133933,0.334817 C 76.246239,14.423395 76.12523,14.4718 76,14.46875 L 75.5,14.5 m -7.3125,-7.03125 -0.3125,0 L 67.5,8 l 0,7"
+ id="path36713"
+ sodipodi:nodetypes="cccscccccscccccccccccscccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:url(#radialGradient37559);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 66,15 0,-1 -1,-1 -1,0 0,1 2,5 0,-4 z"
+ id="path36715"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36882"
+ transform="translate(-21,254)">
+ <rect
+ ry="0"
+ rx="0"
+ y="323"
+ x="257"
+ height="16"
+ width="16"
+ id="rect36884"
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36886"
+ 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"
+ transform="translate(21,69)">
+ <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="rect36888"
+ width="1"
+ height="2"
+ x="236"
+ y="262" />
+ <rect
+ y="-239.00793"
+ x="260"
+ height="2.0079346"
+ width="1"
+ id="rect36890"
+ 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="matrix(0,1,-1,0,0,0)" />
+ <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="rect36892"
+ width="1"
+ height="2"
+ x="236"
+ y="266" />
+ <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="rect36894"
+ width="2"
+ height="1"
+ x="236.99207"
+ y="269" />
+ <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="rect36896"
+ width="1"
+ height="1.9920638"
+ x="269"
+ y="-242.99207" />
+ <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="rect36898"
+ width="1"
+ height="1.9920638"
+ x="269"
+ y="-246.99207" />
+ <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="rect36900"
+ width="1"
+ height="2"
+ x="246.99207"
+ y="266" />
+ </g>
+ <g
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g36902">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36904"
+ width="1"
+ height="2"
+ x="257"
+ y="-331" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36906"
+ width="1"
+ height="2"
+ x="257"
+ y="-335" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36908"
+ width="1"
+ height="2"
+ x="257"
+ y="-339" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36910"
+ width="1"
+ height="2.0079362"
+ x="338"
+ y="259.99207" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36912"
+ width="1"
+ height="2.0079362"
+ x="338"
+ y="263.99207" />
+ <rect
+ y="-339"
+ x="267.99207"
+ height="2"
+ width="1"
+ id="rect36914"
+ style="fill:#321900;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)" />
+ </g>
+ <rect
+ y="330"
+ x="258"
+ height="8"
+ width="10"
+ id="rect36916"
+ style="opacity:0.2;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
+ id="g36918"
+ transform="translate(-205,313.97063)">
+ <rect
+ style="fill:url(#linearGradient37571);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36920"
+ width="12"
+ height="10"
+ x="465.5"
+ y="10.5"
+ ry="1.5909902"
+ rx="1.5909902" />
+ <path
+ style="fill:url(#linearGradient37573);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 465,13.40909 0,4.59375 c 0,0.56244 0.36784,0.99717 0.84375,0.99716 l 11.3125,0.01065 c 0.47591,0 0.84375,-0.43471 0.84375,-0.99716 l 0,-4.59375 c -0.31371,0.37073 -0.76923,0.59091 -1.25,0.59091 L 466.25,14 c -0.48077,0 -0.93629,-0.22018 -1.25,-0.59091 l 0,0 0,0 0,0 z"
+ id="path36922"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.98531502"
+ y="10.52937"
+ x="465.5"
+ height="1.9999996"
+ width="12"
+ id="rect36924"
+ 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.4762714" />
+ <rect
+ ry="1.3782184"
+ y="10.5"
+ x="465.5"
+ height="10"
+ width="12"
+ id="rect36926"
+ 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"
+ rx="1.3782184" />
+ <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="rect36928"
+ width="9.9998779"
+ height="7.999999"
+ x="466.5"
+ y="11.5"
+ ry="0.44196323"
+ rx="0.39062494" />
+ <g
+ transform="matrix(0.7547901,0,0,1,414.01868,-484.99999)"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36932"
+ style="fill:none;stroke:#999999;stroke-width:2.90780973;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
+ style="fill:none;stroke:#000000;stroke-width:0.92082453;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.531013,495.51105 0,-0.50001 c 0,-0.276 0.890314,-0.5 1.987308,-0.5 1.096993,0 1.987307,0.224 1.987307,0.5 l 0,0.50001"
+ id="path36934"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="495.01105"
+ x="70.193451"
+ height="1"
+ width="2.6497409"
+ id="rect36936"
+ 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
+ id="g36938"
+ transform="matrix(1,0,0,0.6666667,331,-319.00002)">
+ <rect
+ y="496.5"
+ x="143"
+ height="1.5"
+ width="2"
+ id="rect36940"
+ 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(#radialGradient37575);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36942"
+ width="2"
+ height="1.5"
+ x="143"
+ y="496.5" />
+ </g>
+ <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="rect36944"
+ width="1"
+ height="1"
+ x="468"
+ y="13" />
+ <g
+ transform="translate(1.1408497e-7,0.5000446)"
+ id="g36946">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89240623;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="path36948"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36950"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:0.71801031;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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient37578);stroke-width:1.11641002;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="path36952"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36954"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:0.80643582;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(#linearGradient37580);stroke-width:1.69505489;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="path36956"
+ 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.591154,0,0,0.5887513,425.87219,-279.05319)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient37582);stroke-width:0.80110824;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="path36958"
+ 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.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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36960"
+ style="opacity:0.7;fill:url(#radialGradient37584);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
+ sodipodi:type="arc"
+ style="opacity:0.2;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="path36962"
+ 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,456.0926,-84.399595)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#radialGradient37586);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36964"
+ 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.6760501,-0.1575078,0.1570322,-0.6740085,446.07727,367.34791)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36966"
+ d="m 476.49997,11.941967 0,7.174103"
+ style="opacity:0.05;fill:none;stroke:#ffffff;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ 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"
+ d="m 258,330 0,8 1,0 0,-7 1,0 0,-1 -2,0 z"
+ id="path36968"
+ sodipodi:nodetypes="ccccccc"
+ 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" />
+ <g
+ id="g36976"
+ transform="translate(1,84)">
+ <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" />
+ </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:#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"
+ 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"
+ id="rect37070"
+ width="16"
+ height="16"
+ x="173"
+ y="491" />
+ <g
+ id="g37072">
+ <g
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none"
+ id="g37074"
+ transform="translate(-63.000001,168)">
+ <g
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none"
+ id="g37076">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 243.5,336.5 0,-12"
+ id="path37078"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,325.5 3,3 3,-3"
+ id="path37080"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37082"
+ d="m 240.5,335.5 3,-3 3,3"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none"
+ transform="matrix(0,1,-1,0,574,87)"
+ id="g37084">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37086"
+ d="m 243.5,336.5 0,-12"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37088"
+ d="m 240.5,325.5 3,3 3,-3"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,335.5 3,-3 3,3"
+ id="path37090"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g37092"
+ style="stroke:#c8c8c8;stroke-opacity:1">
+ <g
+ id="g37094"
+ style="stroke:#c8c8c8;stroke-opacity:1">
+ <g
+ style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="g37096"
+ transform="translate(-63.000001,168)">
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 243.5,336.5 0,-12"
+ id="path37098"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,325.5 3,3 3,-3"
+ id="path37100"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37102"
+ d="m 240.5,335.5 3,-3 3,3"
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ transform="matrix(0,1,-1,0,511,255)"
+ id="g37104">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37106"
+ d="m 243.5,336.5 0,-12"
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37108"
+ d="m 240.5,325.5 3,3 3,-3"
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,335.5 3,-3 3,3"
+ id="path37110"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ transform="matrix(0.625,0,0,0.625,15.1875,291.9375)"
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:2.4000001;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="path37112"
+ sodipodi:cx="264.5"
+ 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" />
+ </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"
+ d="M 175.75,495.75 175.5,495.5"
+ id="path37114"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37116"
+ d="m 177.5,493.5 0.25,0.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 180.5,492.25 0,2.5"
+ id="path37118"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ 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"
+ d="m 177,500 -1.75,1.75"
+ id="path37120"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37122"
+ d="m 174.25,498.5 2.5,0"
+ 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
+ sodipodi:nodetypes="cc"
+ id="path37124"
+ d="m 179.75,501.25 -2.5,2.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1;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
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1;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 185.75,495.25 -2.5,2.5"
+ id="path37126"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37128"
+ d="M 183.75,493.25 182,495"
+ 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"
+ sodipodi:ry="2"
+ sodipodi:rx="2"
+ sodipodi:cy="330.5"
+ sodipodi:cx="264.5"
+ id="path37130"
+ style="fill:none;stroke:url(#linearGradient37588);stroke-width:2.4000001;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"
+ sodipodi:type="arc"
+ transform="matrix(0.625,0,0,0.625,15.1875,291.9375)" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37132"
+ d="m 182.5,502.5 0,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 184.5,500.5 0,0"
+ id="path37134"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ d="m 185.5,498.5 1.25,0"
+ id="path37136"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37138"
+ transform="translate(147.01612,401.00818)">
+ <rect
+ transform="scale(1,-1)"
+ y="-87"
+ x="256.98419"
+ height="16"
+ width="16"
+ id="rect37140"
+ 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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 266.48388,77.49182 c -1,0 -2,10e-6 -3,2e-5 0,0.99999 0,1.99999 0,2.99998 1,0 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 z"
+ id="path37142"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37144"
+ d="m 266.48388,83.49182 c -1,0 -2,10e-6 -3,10e-6 0,1 0,2 0,2.99999 1,-1e-5 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 261.48419,74.5 c -1,0 -2,1e-5 -3,1e-5 0,1 0,2 0,2.99999 1,-1e-5 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path37146"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 261.48419,80.5 c -1,0 -2,1e-5 -3,1e-5 0,1 0,2 0,2.99999 1,-1e-5 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path37148"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-189.01581,-315)"
+ style="opacity:0.55"
+ id="g37150">
+ <path
+ id="path37152"
+ d="m 460.50726,389.48364 c -1.00252,0 -2.00505,1e-5 -3.00757,1e-5 0,1.00272 0,2.00544 0,3.00817 1.00252,0 2.00505,-1e-5 3.00757,-1e-5 0,-1.00273 0,-2.00545 0,-3.00817 z"
+ style="fill:none;stroke:#000000;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 460.51514,395.48364 c -1.00252,0 -2.00505,1e-5 -3.00757,1e-5 0,1.00272 0,2.00544 0,3.00817 1.00252,0 2.00505,-1e-5 3.00757,-1e-5 0,-1.00273 0,-2.00545 0,-3.00817 z"
+ id="path37154"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 455.5,386.5 c -1.00252,0 -2.00505,10e-6 -3.00757,10e-6 0,1.00272 0,2.00544 0,3.00817 1.00252,0 2.00505,-10e-6 3.00757,-10e-6 0,-1.00273 0,-2.00545 0,-3.00817 z"
+ id="path37156"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-189.01581,-315)"
+ style="opacity:0.55"
+ id="g37158">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 457.99938,389.98364 c 0.6694,0 1.33879,1e-5 2.00819,1e-5 0,0.66939 0,1.33877 0,2.00817 -0.6694,0 -1.33879,-1e-5 -2.00819,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path37160"
+ 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="path37162"
+ d="m 458.00726,395.98364 c 0.6694,0 1.33879,1e-5 2.00819,1e-5 0,0.66939 0,1.33877 0,2.00817 -0.6694,0 -1.33879,-1e-5 -2.00819,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path37164"
+ d="m 452.99212,387 c 0.6694,0 1.33879,10e-6 2.00819,10e-6 0,0.66939 0,1.33877 0,2.00817 -0.6694,0 -1.33879,-10e-6 -2.00819,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(420,44)"
+ id="g37166">
+ <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"
+ width="16.000006"
+ height="16.000002"
+ x="26.016129"
+ y="428" />
+ <rect
+ y="428"
+ x="26"
+ height="16"
+ width="16"
+ id="rect37170"
+ 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(1.0004639,0,0,0.9963165,-237.11238,367.28985)"
+ 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="g37172"
+ style="display:inline">
+ <path
+ transform="matrix(0.81218,0,0,0.815735,163.7897,-27.2907)"
+ 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:type="arc"
+ style="fill:#724c4c;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10749674;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="path37174"
+ 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" />
+ <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="path37176"
+ style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.16363633;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.7480284,0,0,0.7480284,172.26025,-19.267349)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:url(#linearGradient37590);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37178"
+ 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.7478104,0,0,0.7510504,172.29077,-19.598754)" />
+ <path
+ style="fill:url(#linearGradient37592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269.98748,62.965763 c -1.39411,0.455357 -2.67784,0.634788 -4.24803,3.011091 l 2.24896,0 1.99907,-3.011091 0,0 0,0 0,0 z m 0.99954,0 0,3.011091 2.99861,0 -1.99908,-3.011091 -0.99953,0 z m 2.99861,3.011091 0.99953,3.011091 1.99907,0 c 0.006,-0.929403 -0.1914,-1.917894 -0.74965,-3.011091 l -2.24895,0 0,0 0,0 0,0 z m 0.99953,3.011091 -3.99814,0 0,3.011092 2.49884,0 1.4993,-3.011092 z m -3.99814,3.011092 -2.99861,0 1.99907,3.011091 0.99954,0 0,-3.011091 0,0 0,0 0,0 z m -2.99861,0 -0.99954,-3.011092 -1.99907,0 c -0.006,0.929404 0.1914,1.917895 0.74965,3.011092 l 2.24896,0 0,0 0,0 0,0 z m -0.99954,-3.011092 3.99815,0 0,-3.011091 -2.49884,0 -1.49931,3.011091 0,0 0,0 0,0 z m 7.24312,3.011092 -1.85125,3.011091 c 1.3675,-0.485137 2.19971,-0.728674 3.85384,-3.011091 l -2.00259,0 z"
+ id="path37180"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path37182"
+ d="m 274.00069,72.011668 0.005,0.97479 -0.99045,0.01431 -0.0223,1.019377 -0.481,0.837285 c 0.77072,-0.321774 2.72643,-1.067855 3.69499,-2.816464 l -2.20604,-0.0293 -2e-4,2e-6 0,0 0,0 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)"
+ 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="path37185"
+ style="opacity:0.4;fill:url(#linearGradient37594);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.7010701,0,0,0.7040938,178.4346,-14.083074)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37596);stroke-width:1.14049816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path37187"
+ 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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#aaccff;stroke-width:0;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 268.98793,64.973163 0,0.407752 -0.93706,0 0,0.595945 -0.56224,0 0,1.003697 -0.49977,0 0,1.505546 0.99953,0 0,-1.505546 0.4373,0 0,-0.595945 0.56224,0 0,-0.407752 1.53054,0 0,-1.003697 -1.53054,0 z"
+ id="path37189"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-499.98389,503.95862)"
+ style="display:inline;enable-background:new"
+ id="g37229">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37231"
+ 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(#radialGradient37608);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="path37233"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path37235"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ style="fill:none;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient37610);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="path37237"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b0000;stroke-width:1.29999995;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 520.48389,-31.45862 -6,6.75 2,2.25 4,-4"
+ id="path37239"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37241"
+ d="m 520.98389,-31.95862 -6.75,7.75 1.75,1.75 5,-4.5 0,-5 z"
+ style="fill:url(#linearGradient37612);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 7,-8.25"
+ id="path37243"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient37614);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="path37245"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37307"
+ transform="translate(-42,86)">
+ <g
+ id="g37309"
+ transform="translate(209,0)">
+ <rect
+ rx="0.015625"
+ y="393"
+ x="222"
+ height="9"
+ width="9"
+ id="rect37311"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.015625" />
+ <g
+ id="g37313"
+ transform="matrix(0.4224039,0.424791,0.4224039,-0.424791,74.64489,479.288)"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient37636);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.33543694;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 85.554034,278.09107 c 1.182038,0.59351 1.745531,1.60418 1.940766,2.40894 l 0.0052,0.2482 c 0,0.75 -0.75,1.75 -1.5,1.75 -0.75,0 -1.16648,-0.20985 -1.91648,-1.20806 -0.5,0 -0.676716,3.3e-4 -1.176716,3.3e-4 -0.75,0.99821 -1.156804,1.20773 -1.906804,1.20773 -0.75,0 -1.5,-1 -1.5,-1.75 l -0.0052,-0.2482 c 0.217441,-0.78256 0.749208,-1.83372 1.92792,-2.42058 l 0.07208,-4.57942 c -0.335564,-0.0958 -0.633693,-0.23081 -0.890995,-0.39497 -0.637372,-0.40663 -1.024226,-0.99226 -1.109005,-1.60503 l 0.0052,-0.2518 c 0,-0.75 0.68844,-1.71861 1.5,-1.75 0.71584,-0.0277 1.25,0 2,1.00179 l 1,0 c 0.749447,-1.00234 1.174653,-1.09387 2,-1.00179 0.745329,0.0832 1.5,1 1.5,1.75 l -0.0052,0.2518 c -0.122391,0.38782 -0.722942,1.77706 -2,2 l 0.05923,4.59106 4e-6,0 0,0 0,0 z"
+ id="path37315"
+ sodipodi:nodetypes="ccczcczccccsscsccscscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37317"
+ d="m 82.886207,273.9157 -0.02165,3.97041"
+ style="fill:none;stroke:#ffffff;stroke-width:1.66929841px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37319"
+ d="M 82.4948,279.50001 C 80,278.75 79.891731,281.54098 81.141731,281.29098"
+ style="fill:none;stroke:#ffffff;stroke-width:0.83464772;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.83464754;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 82.320782,273.05364 c -2.405243,-1.28815 -1.663086,-3.01898 -0.56905,-2.28347"
+ id="path37321"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(315,0)"
+ id="g37323"
+ style="display:inline;enable-background:new">
+ <rect
+ ry="0.019097222"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37325"
+ width="11"
+ height="11"
+ x="110"
+ y="386"
+ rx="0.019097222" />
+ <g
+ id="g37327">
+ <path
+ id="path37329"
+ d="m 116.53125,386.5 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.28156 0.12508,0.53133 0.3125,0.71875 L 113,392 c -0.18742,-0.18742 -0.46844,-0.5 -0.75,-0.5 l -0.75,0 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.56312 0.46813,1.03125 1.03125,1.03125 l 0.9375,0 c 0.0103,0 0.021,3e-4 0.0312,0 -3e-4,0.0102 0,0.021 0,0.0312 l 0,0.9375 c 0,0.56312 0.46813,1.03126 1.03125,1.03125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.28156 -0.10164,-0.53133 -0.28125,-0.71875 l 2.625,-2.625 c 0.18742,0.18742 0.43719,0.3125 0.71875,0.3125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.56312 -0.43688,-1.03125 -1,-1.03125 l -0.96875,0 c -0.0103,0 -0.021,-3e-4 -0.0312,0 3e-4,-0.0102 0,-0.021 0,-0.0312 l 0,-0.9375 c 0,-0.56312 -0.46813,-1.03125 -1.03125,-1.03125 l -0.9375,0 z"
+ style="fill:url(#linearGradient37638);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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccccccsccccccccccccccscccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37331"
+ d="m 111.5,393.5 0,-0.75 0.25,-0.25 1.75,0 3,-3 0,-1.75 0.25,-0.25 0.75,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 118.75,389.5 0.75,0 m -6,6 0,-0.75"
+ id="path37333"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;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"
+ id="rect37335"
+ width="1"
+ height="1"
+ x="114"
+ y="393" />
+ <rect
+ y="390"
+ x="117"
+ height="1"
+ width="1"
+ id="rect37337"
+ style="opacity:0.2;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>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37339"
+ transform="translate(-84,65)">
+ <rect
+ transform="scale(-1,-1)"
+ y="-423"
+ x="-525"
+ height="16"
+ width="16"
+ id="rect37341"
+ 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="g37343"
+ transform="translate(205.00003,252.00003)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\not used yet.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ transform="matrix(0.767131,0,0,0.788662,393.6565,37.08664)"
+ style="fill:#000000;fill-opacity:1"
+ id="g37345"
+ 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,390.0934,62.34418)"
+ id="g37347"
+ 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="g37350"
+ style="opacity:0.3" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 304.99997,158.99997 c 0.66669,0 1.33337,1e-5 2.00006,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.66669,0 -1.33337,-1e-5 -2.00006,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ id="path37352"
+ 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="g37354"
+ style="fill:none"
+ transform="translate(141,63)"
+ 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="fill:none;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 163.5,95.5 c 1,5e-6 2,1.1e-5 3,1.6e-5 0,0.999995 0,1.99999 0,2.999984 -1,-5e-6 -2,-1.1e-5 -3,-1.6e-5 0,-0.999994 0,-1.999989 0,-2.999984 z"
+ id="path37356"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37358"
+ d="m 163.5,101.5 c 1,1e-5 2,1e-5 3,2e-5 0,0.99999 0,1.99999 0,2.99998 -1,-1e-5 -2,-1e-5 -3,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 z"
+ style="fill:none;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 168.49997,92.49997 c 1,5e-6 2,1.1e-5 3,1.6e-5 0,0.999995 0,1.999995 0,2.999985 -1,-1e-5 -2,-1e-5 -3,-2e-5 0,-0.99999 0,-1.999986 0,-2.999981 l 0,0 0,0 0,0 z"
+ id="path37360"
+ inkscape:connector-curvature="0" />
+ </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"
+ id="path37362"
+ d="m 304.99997,164.99997 c 0.66669,0 1.33337,1e-5 2.00006,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.66669,0 -1.33337,-1e-5 -2.00006,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 309.99994,155.99994 c 0.66669,0 1.33337,1e-5 2.00006,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.66669,0 -1.33337,-1e-5 -2.00006,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ id="path37364"
+ 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>
+ <g
+ id="g37366"
+ transform="matrix(0.7614057,0,0,0.7675903,253.76942,219.40377)">
+ <g
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)"
+ id="g37368">
+ <path
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)"
+ sodipodi:type="arc"
+ style="fill:#ff5a19;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37370"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-2.8145849"
+ inkscape:transform-center-y="-3.2499984" />
+ <path
+ inkscape:transform-center-y="1.6729808e-05"
+ inkscape:transform-center-x="-3.2630798"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37372"
+ style="fill:#ad2f94;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)" />
+ <path
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)"
+ sodipodi:type="arc"
+ style="fill:#0060f0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37374"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-2.8145756"
+ inkscape:transform-center-y="3.2500173" />
+ <path
+ inkscape:transform-center-y="3.249994"
+ inkscape:transform-center-x="2.8145978"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37376"
+ style="fill:#00d4aa;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)" />
+ <path
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)"
+ sodipodi:type="arc"
+ style="fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37378"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="3.2630773" />
+ <path
+ inkscape:transform-center-x="2.8145777"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37380"
+ style="fill:#ffbf0e;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ inkscape:transform-center-y="-3.2500006" />
+ </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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path37382"
+ style="fill:none;stroke:#000000;stroke-width:1.29430985;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)" />
+ <path
+ transform="matrix(0.6594197,0,0,0.6608114,261.96791,180.02435)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37640);stroke-width:1.98156261;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path37384"
+ 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" />
+ </g>
+ </g>
+ <g
+ id="g37816"
+ 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="rect37759"
+ width="16"
+ height="16"
+ x="173"
+ y="617" />
+ <g
+ style="display:inline"
+ id="g37761"
+ transform="translate(-290,397)">
+ <g
+ id="g37779">
+ <g
+ id="g37781"
+ style="opacity:0.85"
+ transform="translate(20.029029,0)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path37783"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ 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="path37785"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g37787"
+ transform="translate(20.029029,0)">
+ <path
+ id="path37789"
+ 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"
+ inkscape:connector-curvature="0" />
+ <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:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path37791"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-58,340)"
+ id="g41151"
+ style="display:inline;enable-background:new">
+ <rect
+ y="48"
+ x="63"
+ height="16"
+ width="16"
+ id="rect41153"
+ 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(1.0003553,0,0,0.9995949,18.983834,-41.953346)"
+ style="display:inline"
+ 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="g41155">
+ <rect
+ y="91.491928"
+ x="45.5"
+ height="13.003749"
+ width="12.995382"
+ id="rect41157"
+ style="fill:url(#linearGradient42322);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;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" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41159"
+ d="m 46.49945,103.49527 0,-11.002747 10.996287,0 0,11.002747 -10.996287,0 z"
+ style="fill:none;stroke:url(#linearGradient42324);stroke-width:1.0000248px;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-15,340)"
+ id="g41161"
+ style="display:inline;enable-background:new">
+ <rect
+ y="48"
+ x="83"
+ height="16"
+ width="16"
+ id="rect41163"
+ 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"
+ 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.1658027,0,0,1.1657997,-59.289717,-204.05607)"
+ id="g41165"
+ style="display:inline">
+ <path
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23686147;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41167"
+ 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
+ transform="matrix(-0.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)"
+ 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="path41169"
+ style="opacity:0.8;fill:url(#linearGradient42326);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ id="path41171"
+ style="fill:none;stroke:url(#linearGradient42328);stroke-width:0.51466751;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ d="m 134.27086,222.67786 c -0.8523,1.03645 -2.40069,1.91195 -5.35869,1.91195 -2.92931,0 -4.50028,-0.8755 -5.35806,-1.88283 m 5.3611,5.72324 c -1.3021,0 -2.35888,-2.40136 -2.35888,-5.36019 0,-2.95882 1.05678,-5.36019 2.35888,-5.36019 1.30211,0 2.35889,2.40137 2.35889,5.36019 0,2.9364 -1.03866,5.32486 -2.33081,5.35981"
+ 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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path41173"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42330);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41175"
+ transform="translate(-21,359)">
+ <rect
+ y="29"
+ x="47"
+ height="16"
+ width="16"
+ id="rect41177"
+ 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="g41179"
+ transform="translate(116,-325)">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -55,358.25 -6,-2.25 -6,2.25 0,7.5 6,3.25 6,-3.25 0,-7.5 z"
+ id="path41181"
+ sodipodi:nodetypes="ccccccc"
+ 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:url(#linearGradient42332);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 -55,365.75 0,-7.5 -6,-2.25 8.34e-4,13.04035 L -55,365.75 z"
+ id="path41183"
+ sodipodi:nodetypes="ccccc"
+ 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="path41185"
+ d="m -67,365.75 0,-7.5 6,-2.25 8.34e-4,13.04035 L -67,365.75 z"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -67,358.25 6,-2.25 6,2.25 -6,2.75 -6,-2.75 z"
+ id="path41187"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41189"
+ d="M -66.499841,365.52276 -66.5,358.5 l 5.5,-2 5.5,2 0,7 -5.5,3 -5.499841,-2.97724 z"
+ style="fill:none;stroke:url(#linearGradient42334);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(3,417)"
+ id="g41191">
+ <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"
+ width="16"
+ height="16"
+ x="128"
+ y="-29" />
+ <g
+ id="g41195">
+ <path
+ id="path41197"
+ style="fill:#999999;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 140,-21 c 1.125,1 3.5,0.25 3.5,-1 0,-1.5 0.47443,-1.637992 -2,-1.5 -0.1033,1.43128 -0.66697,1.819388 -1.5,2.5 z"
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscc"
+ d="m 132,-21 c -1.125,1 -3.5,0.25 -3.5,-1 0,-1.5 -0.47443,-1.637992 2,-1.5 0.1033,1.43128 0.66697,1.819388 1.5,2.5 z"
+ style="fill:#e6e6e6;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path41199"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccsccccccc"
+ d="m 135.75,-25.5 -1.25,-2 -0.75,0 -3.25,2.75 0,1.25 c 0.15379,2.182132 1.3678,1.901463 3,4 l 0,4.5 c 0,1.5 1.5,1.5 2.5,1.5 1,0 2.5,0 2.5,-1.5 l 0,-4.5 c 1.62605,-2.090636 2.83897,-1.844587 3,-4 l 0,-1.25 -3.25,-2.75 -0.75,0 -1.25,2"
+ style="fill:url(#linearGradient42336);fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ id="path41201"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-16"
+ x="135"
+ height="1"
+ width="2"
+ id="rect41203"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="1"
+ style="fill:url(#linearGradient42338);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41205"
+ width="2.75"
+ height="2"
+ x="135"
+ y="-21"
+ rx="1" />
+ <rect
+ y="-21"
+ x="135"
+ height="1"
+ width="2"
+ id="rect41207"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path41209"
+ style="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"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42340);stroke-width:0.93034029;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="path41211"
+ sodipodi:cx="133"
+ 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"
+ transform="matrix(1.2143583,0,0,1.1512108,-28.054112,2.9290602)" />
+ <path
+ sodipodi:type="arc"
+ style="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"
+ id="path41213"
+ sodipodi:cx="133"
+ 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"
+ 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"
+ id="rect41215"
+ width="2"
+ height="1"
+ x="135"
+ y="-15" />
+ <path
+ id="path41217"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 131.88556,-21.103144 c 0.4583,0.371362 1.00745,1.072735 1.61444,1.853144 l 0,3.75 c 0,1.5 1.5,2 2.5,2 1,0 2.5,-0.5 2.5,-2 l 0,-3.75 c 0.64842,-0.833678 1.23114,-1.545786 1.70766,-1.936772 M 130.5,-23.5 l 0,-1.25 3,-2.75 1,0 1.25,1.75 0.5,0 1.25,-1.75 1,0 3,2.75 0,1.25"
+ sodipodi:nodetypes="ccccccccccccccccs"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path41219"
+ style="fill:none;stroke:url(#linearGradient42342);stroke-width:0.94079971;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: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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path41221"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41223"
+ d="M 136.75,-24.75 138,-26.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 129.25,-22.25 0.5,-0.5"
+ id="path41225"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41227"
+ d="m 142.75,-22.5 -0.25,-0.25"
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41229"
+ transform="translate(169,365)">
+ <rect
+ y="23"
+ x="-80"
+ height="16"
+ width="16"
+ id="rect41231"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41233"
+ d="m -72,23.5 -1.5,4 8,0 0,-0.25 -6.5,-3.75 z"
+ style="fill:#ececec;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41235"
+ d="m -73.5,27.5 3,7 5,-7 -8,0 z"
+ style="fill:#c3c3c3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41237"
+ d="m -65.5,27.5 -5,7 5,0 0,-7 z"
+ style="fill:#666666;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41239"
+ d="m -70.5,34.5 -1.5,4 6.5,-3.75 0,-0.25 -5,0"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41241"
+ d="m -78.5,34.5 0,0.25 6.5,3.75 1.5,-4 -8,0 z"
+ style="fill:#b3b3b3;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41243"
+ d="m -78.5,27.5 0,-0.25 6.5,-3.75 -1.5,4 -5,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41245"
+ d="m -73.5,27.5 -5,0 0,7 5,-7 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41247"
+ d="m -78.5,34.5 8,0 -3,-7 -5,7 z"
+ style="fill:#f2f2f2;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="star"
+ style="fill:none;stroke:#000000;stroke-width:0.76889962;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="path41249"
+ sodipodi:sides="6"
+ sodipodi:cx="-72"
+ sodipodi:cy="31"
+ sodipodi:r1="7.2111025"
+ sodipodi:r2="6.244998"
+ sodipodi:arg1="0.52359878"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M -65.755002,34.605551 -72,38.211102 l -6.244998,-3.605551 0,-7.211102 L -72,23.788898 l 6.244998,3.605551 z"
+ transform="matrix(1.040833,0,0,1.0400629,2.9399768,-1.241949)" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path41251"
+ style="fill:none;stroke:url(#linearGradient42344);stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -78.5,27.5 13,0 m -7,-3 -1,3 m -5,7 12.75,0 m -12.75,0 5,-6.75 3,6.75 5,-7 m -5,7 -1,3"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.8807051,0,0,0.9013876,-8.5892309,3.0569843)"
+ d="M -65.755002,34.605551 -72,38.211102 l -6.244998,-3.605551 0,-7.211102 L -72,23.788898 l 6.244998,3.605551 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.0471976"
+ sodipodi:arg1="0.52359878"
+ sodipodi:r2="6.244998"
+ sodipodi:r1="7.2111025"
+ sodipodi:cy="31"
+ sodipodi:cx="-72"
+ sodipodi:sides="6"
+ id="path41253"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42346);stroke-width:1.12235165;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="star" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41255"
+ transform="translate(231,348)">
+ <rect
+ y="40"
+ x="-121"
+ height="16"
+ width="16"
+ id="rect41257"
+ 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(1.0003553,0,0,0.9995949,-165.01617,-49.953346)"
+ style="display:inline"
+ 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="g41259">
+ <rect
+ y="92.490814"
+ x="46.499645"
+ height="12.004883"
+ width="11.995742"
+ id="rect41261"
+ style="fill:url(#linearGradient42348);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;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" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41263"
+ d="m 47.49929,95.49203 0,-2.000811 1.999291,3e-6 0,2.000811 -1.999291,-3e-6 z"
+ style="fill:none;stroke:url(#linearGradient42350);stroke-width:1.00002491px;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"
+ 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:url(#linearGradient42352);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 47.49929,99.493651 0,-1.999102 1.999291,-4e-6 0,1.999102 -1.999291,4e-6 z"
+ id="path41265"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41267"
+ d="m 47.49929,103.49527 0,-1.9991 1.999291,0 0,1.9991 -1.999291,0 z"
+ style="fill:none;stroke:url(#linearGradient42354);stroke-width:1.00002491px;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"
+ 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:url(#linearGradient42356);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 51.497871,103.49527 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ id="path41269"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41271"
+ d="m 51.497869,99.49194 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ style="fill:none;stroke:url(#linearGradient42358);stroke-width:1.00002491px;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"
+ 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:url(#linearGradient42360);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 51.497868,95.49203 1e-6,-2.000811 1.99929,0 -1e-6,2.000811 -1.99929,0 z"
+ id="path41273"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41275"
+ d="m 55.496451,103.49527 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ style="fill:none;stroke:url(#linearGradient42362);stroke-width:1.00002491px;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"
+ 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:url(#linearGradient42364);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 55.496449,99.49194 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ id="path41277"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41279"
+ d="m 55.496448,95.49203 0,-2.000811 1.99929,0 0,2.000811 -1.99929,0 z"
+ style="fill:none;stroke:url(#linearGradient42366);stroke-width:1.00002491px;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path41281"
+ style="fill:none;stroke:url(#linearGradient42368);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -110.5,43 0,11 m -4,-11 0,11 m 7.5,-3.5 -11,0 m 11,-4 -11,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41283"
+ transform="translate(275,332)">
+ <rect
+ y="56"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41285"
+ 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\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="path41287"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23034608;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8124999,0,0,0.813059,-327.25,-31.946343)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42370);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path41289"
+ 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.7451143,0.08386971,-0.08492794,0.7396793,-308.33359,-34.308811)" />
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-310.55192,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42372);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41291"
+ 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="path41293"
+ style="fill:none;stroke:url(#linearGradient42374);stroke-width:1.78040731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5610858,0,0,0.5622541,-294.05201,-2.3458915)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41295"
+ transform="translate(380,233)">
+ <rect
+ y="155"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41297"
+ 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" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path41299"
+ d="m -220,156.5 c -3.036,0 -5.49999,1.12 -5.49999,2.5 l -1e-5,9 c 0,1.38 2.46399,2.5 5.49999,2.5 3.036,0 5.5,-1.12 5.5,-2.5 l 1e-5,-9 c 0,-1.38 -2.464,-2.5 -5.5,-2.5 z"
+ style="fill:url(#linearGradient42376);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient42378);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient42380);stroke-width:1;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 -215.49145,159.5 c 0,1 -1.5,2 -4.50855,2 -3.00854,0 -4.49145,-1 -4.49145,-2 0,-1.5 2.25,-2.25 4.5,-2.25 2.25,0 4.5,0.75 4.5,2.25 z"
+ id="path41301"
+ sodipodi:nodetypes="czszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path41303"
+ d="m -214.99565,159.99149 c 0,1.12926 -1.66739,2.25851 -5.01168,2.25851 -3.34426,0 -4.99267,-1.12925 -4.99267,-2.25851"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient42382);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
+ 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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -220,156.5 c -3.49999,0 -5.49999,1.12 -5.49999,2.5 l -1e-5,8.5 c 0,2 2.46399,3 5.49999,3 3.036,0 5.50001,-1 5.50001,-3 l 0,-8.5 c 0,-1.38 -1.99999,-2.5 -5.5,-2.5 z"
+ id="path41305"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42384);stroke-width:0.99999994;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 -224.5,160.5 0,6.5 c 0,0.9838 0.64285,2.5 4.5,2.5 3.85714,0 4.5,-1.5162 4.5,-2.5 l 0,-6.5"
+ id="path41307"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41309"
+ 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"
+ id="rect41311"
+ width="16"
+ height="16"
+ x="-228"
+ y="176" />
+ <path
+ sodipodi:nodetypes="cssscccscc"
+ id="path41313"
+ d="m -220,178.5 c -4.14,0 -7.40235,2.464 -7.40234,5.5 0,3.036 3.26234,5.5 7.40234,5.5 4.14,0 7.40234,-2.464 7.40234,-5.5 0,-3.036 -3.26233,-5.50001 -7.40234,-5.5 z m 0,4 c 1.2993,0 2.42742,0.39879 3.03125,1 -0.60383,0.60121 -1.73196,1 -3.03125,1 -1.29929,0 -2.42742,-0.39879 -3.03125,-1 0.60383,-0.60121 1.73196,-1 3.03125,-1 z"
+ style="fill:url(#linearGradient42386);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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsscc"
+ id="path41315"
+ d="m -214.625,180.4375 c 1.5822,4.85564 -3.15377,7.27675 -11.84375,6.21875 l 0,0.0312 c 1.25689,1.67541 3.66207,2.8125 6.46875,2.8125 4.14,0 7.40625,-2.464 7.40625,-5.5 0,-1.34213 -0.64966,-2.57614 -1.71875,-3.53125 -0.10326,-0.0119 -0.20204,-0.024 -0.3125,-0.0312 z"
+ style="opacity:0.6;fill:url(#radialGradient42388);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;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"
+ d="m -223.375,183.45313 c 1.90631,-1.46639 4.08905,-1.44306 6.1875,-0.53125 L -217,182.76563 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ id="path41317"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path41319"
+ d="m -223.375,183.65625 0.5,-0.0312 c -0.0509,-0.0426 -0.11109,-0.08 -0.15625,-0.125 0.60383,-0.60121 1.73196,-1 3.03125,-1 0.99575,0 1.89552,0.24495 2.53125,0.625 L -217,182.96875 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ style="opacity:0.6;fill:url(#radialGradient42390);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" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42392);stroke-width:0.5962854;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="path41321"
+ sodipodi:cx="-220"
+ 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"
+ transform="matrix(0.9999986,0,0,1.799999,-2.971883e-4,111.10004)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41323"
+ transform="translate(422,192)">
+ <rect
+ y="196"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41325"
+ 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" />
+ <path
+ sodipodi:nodetypes="ccssscc"
+ id="path41327"
+ d="m -220,196.70312 -6.24219,10.18714 c -0.17094,0.32797 -0.25781,0.44407 -0.25781,0.85974 0,2.25 2.96003,3.75 6.5,3.75 3.53998,0 6.5,-1.5 6.5,-3.75 0,-0.41567 -0.0869,-0.53177 -0.2578,-0.85974 L -220,196.70312 z"
+ style="fill:url(#radialGradient42394);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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42396);stroke-width:1;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,198.75 -5.29067,8.34531 c -0.1388,0.26737 -0.20933,0.56583 -0.20933,0.90469 0,1.3338 2.63213,2.56728 5.50644,2.56728 2.87432,0 5.49356,-1.23348 5.49356,-2.56728 0,-0.33886 -0.0706,-0.63732 -0.20932,-0.90469 L -220,198.75 z"
+ id="path41329"
+ sodipodi:nodetypes="ccssscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.05;fill:none;stroke:#1a1a1a;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 -226.5,208 c 0,-1.63609 2.96003,-3.5 6.5,-3.5 3.53998,0 6.5,1.75 6.5,3.5"
+ id="path41331"
+ sodipodi:nodetypes="css"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41333"
+ 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"
+ id="rect41335"
+ width="16"
+ height="16"
+ x="-278"
+ y="137" />
+ <g
+ transform="translate(-22,0)"
+ id="g41337">
+ <path
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ d="m -243.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ id="path41339"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41341"
+ d="m -255.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g41343"
+ style="opacity:0.7">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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 -252.25,139.5 8.5,0"
+ id="path41345"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41347"
+ d="m -252,139.5 8,0"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.5;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="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -254.5,139.5 0,-1 1,0"
+ id="path41349"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41351"
+ d="m -242.5,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g41353"
+ transform="translate(-327,-164)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="312.5"
+ x="52.5"
+ height="3"
+ width="2.9998772"
+ id="rect41355"
+ style="fill:#1a1a1a;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:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.0999999;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 54,314.25 c 3.75,1.75 8.5,2.36379 8.5,-2 0,-3 -3.5,-6.25 -5.5,-8.25"
+ id="path41357"
+ sodipodi:nodetypes="csc"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;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 54,314.25 c 3.5,1.75 8.5,2.36741 8.5,-2 0,-3 -3.5,-6.25 -5.5,-8.25"
+ id="path41359"
+ sodipodi:nodetypes="csc"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#1a1a1a;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:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41361"
+ width="2.9998772"
+ height="3"
+ x="55.500122"
+ y="302.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path41363"
+ d="m 54,314.25 c 3.5,1.75 8.5,2.33285 8.5,-2 0,-3 -3.5,-6.25 -5.5,-8.25"
+ style="fill:none;stroke:url(#linearGradient42398);stroke-width:1.5;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
+ 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="path41365"
+ d="m 55,313 c -0.67541,0 -1.35081,10e-6 -2.02623,10e-6 0,0.66666 0,1.33332 0,1.99999 0.67542,0 1.35082,-10e-6 2.02623,-10e-6 0,-0.66666 0,-1.33333 0,-1.99999 z"
+ style="fill:#e6e6e6;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="fill:#ececec;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 58,303 c -0.666663,0 -1.333327,10e-6 -2,10e-6 0,0.66667 0,1.33332 0,1.99999 0.666673,0 1.333337,-10e-6 2,-10e-6 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path41367"
+ 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.8;fill:#ececec;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 56.499999,304.5 0,-1 1,0"
+ id="path41369"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41371"
+ d="m 53.5,314.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
+ 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="path41373"
+ d="m 56,315.66293 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.55431 0,-1.1086 0,-1.66292 0.32001,0 0.64002,10e-6 0.96003,10e-6 0,0.55431 0,1.10861 0,1.66292 z"
+ style="opacity:0.15;fill:#4b4b4b;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path41375"
+ d="m 59,306 c -0.333333,0 -0.666667,-10e-6 -1,-10e-6 0,-0.66666 0,-1.33331 0,-1.99999 0.333333,0 0.666667,10e-6 1,10e-6 0,0.66667 0,1.33333 0,1.99999 z"
+ style="opacity:0.15;fill:#4b4b4b;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:#1d1d1d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 56,316 c -0.32001,0 -0.64002,0 -0.96003,0 0,-0.21055 0,-0.42107 0,-0.63162 0.32001,0 0.64002,0 0.96003,0 0,0.21055 0,0.42107 0,0.63162 z"
+ id="path41377"
+ 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>
+ <g
+ transform="translate(-21.421813,3.140625)"
+ id="g41379"
+ style="display:inline;enable-background:new" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41381"
+ transform="matrix(0,1,1,0,99,651)">
+ <rect
+ y="137"
+ x="-284"
+ height="16"
+ width="16"
+ id="rect41383"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ rx="1.4999387"
+ ry="1.4999353"
+ y="149.5"
+ x="-271.5"
+ height="2.9999931"
+ width="2.9998772"
+ id="rect41385"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.99999994;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
+ id="g41387">
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -271.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ id="path41389"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41391"
+ d="m -283.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ 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;display:inline;enable-background:new"
+ d="m -282.50008,139.5 0,-1 1,0"
+ id="path41393"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41395"
+ d="m -270.50008,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g41397"
+ style="opacity:0.7">
+ <path
+ id="path41399"
+ d="m -270.5,140.74992 0,8.5"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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 -280.25008,139.5 8.5,0"
+ id="path41401"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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 -281.49999,140.75 0,8.5"
+ id="path41403"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41405"
+ d="m -280.00008,139.5 8,0"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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 -270.5,140.99992 0,8"
+ id="path41407"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41409"
+ d="m -281.49999,141 0,8"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.99999994;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="rect41411"
+ width="2.9998772"
+ height="2.999995"
+ x="-283.5"
+ y="149.5"
+ ry="1.4999362"
+ rx="1.4999387" />
+ <g
+ id="g41413">
+ <path
+ sodipodi:nodetypes="csc"
+ id="path41415"
+ d="m -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ 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:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;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 -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ id="path41417"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path41419"
+ d="m 36.445698,40.205481 c 0,3.312 -2.660849,4.931507 -5.972849,4.931507 -3.312,0 -5.97285,-1.619507 -5.97285,-4.931507"
+ style="fill:none;stroke:url(#linearGradient42400);stroke-width:1.41714692;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.9208335,0,0,-1.2166667,-304.06042,199.41667)"
+ inkscape:connector-curvature="0" />
+ </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"
+ id="path41421"
+ d="m -269,150 c -0.66667,0 -1.33333,1e-5 -2,1e-5 0,0.66667 0,1.33332 0,1.99999 0.66667,0 1.33333,-1e-5 2,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#cccccc;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="fill:#ffffff;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 -281,150 c -0.66667,0 -1.33333,1e-5 -2,1e-5 0,0.66667 0,1.33332 0,1.99999 0.66667,0 1.33333,-1e-5 2,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path41423"
+ 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.8;fill:#ececec;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -270.5,151.5 0,-1 1,0"
+ id="path41425"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="149"
+ x="-283"
+ height="1"
+ width="2.75"
+ id="rect41427"
+ style="opacity:0.2;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" />
+ <rect
+ style="opacity:0.2;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"
+ id="rect41429"
+ width="2.75"
+ height="1"
+ x="-271.75"
+ y="149"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41431"
+ transform="translate(565.49991,277.875)">
+ <g
+ transform="translate(-23.5,-18.875)"
+ id="g41433"
+ style="opacity:0.8">
+ <rect
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41435"
+ width="16"
+ height="16"
+ x="-284.99991"
+ y="108" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ id="path41437"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41439"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ 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;display:inline;enable-background:new"
+ d="m -283.5,110.5 0,-1 1,0"
+ id="path41441"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41443"
+ d="m -271.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41445"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ id="path41447"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41449"
+ d="m -283.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m -271.49992,122.5 0,-1 1,0"
+ id="path41451"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1.0019678,0,0,1,-97.100449,33.125005)"
+ id="g41453">
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:4.36388111;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41455"
+ 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="path41457"
+ style="fill:none;stroke:url(#linearGradient42402);stroke-width:2.18194032;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41459"
+ transform="translate(311,278)">
+ <g
+ transform="translate(0,-19)"
+ id="g41461"
+ style="opacity:0.8">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41463"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41465"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41467"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41469"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41471"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41473"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41475"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ 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;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41477"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41479"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-57,33)"
+ id="g41481">
+ <rect
+ y="56"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41483"
+ 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\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="path41485"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23039246;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8124999,0,0,0.8129977,-327.25,-31.938622)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42404);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path41487"
+ 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.7451143,0.08386971,-0.08492794,0.7396793,-308.33359,-34.308811)" />
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-310.55192,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42406);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41489"
+ 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="path41491"
+ style="fill:none;stroke:url(#linearGradient42408);stroke-width:1.78040731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5610858,0,0,0.5622541,-294.05201,-2.3458915)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41493"
+ transform="translate(455,122.97748)">
+ <rect
+ y="244.02252"
+ x="-240.00009"
+ height="16"
+ width="16"
+ id="rect41495"
+ 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" />
+ <g
+ id="g41497"
+ transform="translate(15.99992,107.02252)">
+ <path
+ id="path41499"
+ d="m -243.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ d="m -255.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41501"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.5"
+ id="g41503">
+ <path
+ id="path41505"
+ d="m -252.25,138.49219 8.5,0"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.5;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 -252,138.49219 8,0"
+ id="path41507"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path41509"
+ d="m -254.5,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m -242.5,139.5 0,-1 1,0"
+ id="path41511"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#1a1a1a;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:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41513"
+ width="2.9998772"
+ height="3"
+ x="-233.49988"
+ y="245.52252"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <g
+ id="g41515"
+ transform="translate(68.499908,155.89752)">
+ <g
+ transform="matrix(1.0019678,0,0,1,-97.100449,33.125005)"
+ id="g41517">
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:4.36388111;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41519"
+ 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="path41521"
+ style="fill:none;stroke:url(#linearGradient42410);stroke-width:2.18194032;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)" />
+ </g>
+ </g>
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="245.52252"
+ x="-233.49988"
+ height="3"
+ width="2.9998772"
+ id="rect41523"
+ style="opacity:0.25;fill:#1a1a1a;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:7.40000265;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"
+ id="path41525"
+ d="m -230.99988,246.02251 c -0.66667,0 -1.33333,10e-6 -2,10e-6 0,0.66667 0,1.33332 0,1.99999 0.66667,0 1.33333,-1e-5 2,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#ffffff;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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41527"
+ transform="translate(70.968338,302.76882)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41529"
+ width="16"
+ height="16"
+ x="64.231171"
+ y="-65.968338" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999994;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="rect41531"
+ width="2.9998772"
+ height="2.9999931"
+ x="76.731178"
+ y="-53.468342"
+ ry="1.4999353"
+ rx="1.4999387" />
+ <g
+ transform="matrix(0,1,1,0,-202.96833,348.23118)"
+ id="g41533"
+ style="display:inline;enable-background:new">
+ <path
+ id="path41535"
+ d="m -271.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -283.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41537"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41539"
+ d="m -282.50008,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m -270.50008,139.5 0,-1 1,0"
+ id="path41541"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.7"
+ id="g41543">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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 -270.5,140.74992 0,8.5"
+ id="path41545"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41547"
+ d="m -280.25008,139.5 8.5,0"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41549"
+ d="m -281.49999,140.75 0,8.5"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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 -280.00008,139.5 8,0"
+ id="path41551"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41553"
+ d="m -270.5,140.99992 0,8"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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 -281.49999,141 0,8"
+ id="path41555"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ rx="1.4999387"
+ ry="1.4999362"
+ y="-53.468342"
+ x="64.731171"
+ height="2.999995"
+ width="2.9998772"
+ id="rect41557"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999994;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
+ transform="matrix(0,1,1,0,-202.96833,348.23118)"
+ id="g41559"
+ style="display:inline;enable-background:new">
+ <path
+ 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:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ id="path41561"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path41563"
+ d="m -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;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
+ transform="matrix(0.9208335,0,0,-1.2166667,-304.06042,199.41667)"
+ style="fill:none;stroke:url(#linearGradient42412);stroke-width:1.41714692;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 36.445698,40.205481 c 0,3.312 -2.660849,4.931507 -5.972849,4.931507 -3.312,0 -5.97285,-1.619507 -5.97285,-4.931507"
+ id="path41565"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.6;display:inline;enable-background:new"
+ transform="translate(132.03151,-159.76882)"
+ id="g41567">
+ <path
+ transform="matrix(0.8124999,0,0,0.8131203,-292.24999,136.05677)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.98423982;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 133.84616,110 0,15.98779 L 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.416 3.584,-8 8,-8 l 1.84616,0 z"
+ id="path41569"
+ sodipodi:nodetypes="cccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csscccc"
+ id="path41571"
+ d="M 132.92501,125.94702 C 132.6215,125.98201 132.31284,126 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.11109 3.10616,-7.5011 7.09807,-7.94965 l 1.32084,-0.14976 1.81209,15.89838 -1.30599,0.14805 0,0 0,0 0,0 z"
+ style="opacity:0.8;fill:url(#linearGradient42414);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ transform="matrix(0.7451143,0.08449152,-0.08492794,0.7451633,-273.33359,132.91784)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccscc"
+ id="path41573"
+ d="m 132.71228,109.99971 0,16.00029 L 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.416 3.584,-8 8,-8 l 0.71228,-2.9e-4 z"
+ style="fill:none;stroke:url(#linearGradient42416);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ transform="matrix(0.6860851,0,0,0.6874876,-275.55192,150.87656)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="css"
+ id="path41575"
+ d="m 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.416 3.584,-8 8,-8"
+ style="fill:none;stroke:url(#linearGradient42418);stroke-width:1.78040731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ transform="matrix(0.5610858,0,0,0.5622541,-259.05201,165.65411)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#cccccc;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 -52.968334,79.231175 c 0,-0.66667 10e-6,-1.33333 10e-6,-2 0.66667,0 1.33332,0 1.99999,0 0,0.66667 -1e-5,1.33333 -1e-5,2 -0.66666,0 -1.33332,0 -1.99999,0 z"
+ id="path41577"
+ 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="path41579"
+ d="m -52.968334,67.231175 c 0,-0.66667 10e-6,-1.33333 10e-6,-2 0.66667,0 1.33332,0 1.99999,0 0,0.66667 -1e-5,1.33333 -1e-5,2 -0.66666,0 -1.33332,0 -1.99999,0 z"
+ style="fill:#ffffff;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
+ id="path41581"
+ d="m -51.468334,77.731175 -1,0 0,1"
+ style="opacity:0.8;fill:#ececec;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="opacity:0.2;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"
+ id="rect41583"
+ width="2.75"
+ height="1"
+ x="65.231171"
+ y="-53.968342"
+ rx="0"
+ ry="0" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ rx="0"
+ y="-53.968342"
+ x="76.481178"
+ height="1"
+ width="2.75"
+ id="rect41585"
+ style="opacity:0.2;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
+ style="display:inline;enable-background:new"
+ id="g41587"
+ 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"
+ id="rect41589"
+ width="16"
+ height="16"
+ x="-307"
+ y="136" />
+ <g
+ id="g41591"
+ transform="translate(-22.000001,28)"
+ style="opacity:0.8;display:inline;enable-background:new">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41593"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41595"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41597"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41599"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41601"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41603"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41605"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ 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;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41607"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41609"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g41611">
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path41613"
+ d="m -299,137.5 c -3.036,0 -5.49999,1.12 -5.49999,2.5 l -10e-6,8 c 0,1.38 2.46399,2.5 5.49999,2.5 3.036,0 5.5,-1.12 5.5,-2.5 l 10e-6,-8 c 0,-1.38 -2.464,-2.5 -5.5,-2.5 z"
+ style="fill:url(#linearGradient42420);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient42422);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient42424);stroke-width:1;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 -294.49145,140.5 c 0,1 -1.5,2 -4.50855,2 -3.00854,0 -4.49145,-1 -4.49145,-2 0,-1.5 2.25,-2.25 4.5,-2.25 2.25,0 4.5,0.75 4.5,2.25 z"
+ id="path41615"
+ sodipodi:nodetypes="czszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path41617"
+ d="m -293.99565,140.99149 c 0,1.12926 -1.66739,2.25851 -5.01168,2.25851 -3.34426,0 -4.99267,-1.12925 -4.99267,-2.25851"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient42426);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
+ 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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -299,137.5 c -3.49999,0 -5.49999,1.12 -5.49999,2.5 l -10e-6,7.5 c 0,2 2.46399,3 5.49999,3 3.036,0 5.50001,-1 5.50001,-3 l 0,-7.5 c 0,-1.38 -1.99999,-2.5 -5.5,-2.5 z"
+ id="path41619"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42428);stroke-width:0.99999994;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 -303.5,141.5 0,5.5 c 0,0.9838 0.64285,2.5 4.5,2.5 3.85714,0 4.5,-1.5162 4.5,-2.5 l 0,-5.5"
+ id="path41621"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41623"
+ transform="translate(258.99995,102)">
+ <rect
+ transform="scale(-1,1)"
+ style="opacity:0.01000001;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"
+ id="rect41625"
+ width="16.000032"
+ height="16"
+ x="195.99995"
+ y="265" />
+ <g
+ transform="translate(77.000139,146.99992)"
+ id="g41627">
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -287.5,118.5 c 10e-6,1.00003 10e-6,2.00005 2e-5,3.00008 0.99999,0 1.99998,0 2.99998,0 -10e-6,-1.00003 -10e-6,-2.00005 -2e-5,-3.00008 -0.99999,0 -1.99999,0 -2.99998,0 z"
+ id="path41629"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41631"
+ d="m -285.5,119.5 -1,0 0,1"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.5"
+ id="g41633"
+ transform="matrix(0,1,1,0,-425,402.00008)">
+ <path
+ id="path41635"
+ d="m -279.50016,139.5 6.00016,2e-5"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41637"
+ d="m -281.50008,141.5 0,2"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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 -280.00008,139.5 6.50008,2e-5"
+ id="path41639"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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 -281.49999,141 -9e-5,2.5"
+ id="path41641"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g41643"
+ transform="matrix(-1,0,0,-1,-484.99984,399)">
+ <path
+ id="path41645"
+ d="m -287.5,118.5 c 10e-6,1.00003 10e-6,2.00005 2e-5,3.00008 0.99999,0 1.99998,0 2.99998,0 -10e-6,-1.00003 -10e-6,-2.00005 -2e-5,-3.00008 -0.99999,0 -1.99999,0 -2.99998,0 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ 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;display:inline;enable-background:new"
+ d="m -285.5,119.5 -1,0 0,1"
+ id="path41647"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0,1,1,0,-425,402.00008)"
+ id="g41649"
+ style="opacity:0.5">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;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 -279.50016,139.5 7,0"
+ id="path41652"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;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 -281.50008,141.5 0,2"
+ id="path41654"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41656"
+ d="m -280.00008,139.5 7.49992,0"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41658"
+ d="m -281.49999,141 -9e-5,2.5"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-191.99984,-17.000001)"
+ id="g41660"
+ style="display:inline;enable-background:new">
+ <g
+ id="g41662"
+ transform="translate(-376,510)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path41664"
+ d="m 358.99997,-216.75 c -0.99997,-6.5 6.00003,-2.75 5,-9.25 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cdcdcd;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 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path41666"
+ 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"
+ style="opacity:0.7;fill:url(#linearGradient42430);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path41668"
+ 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"
+ id="path41670"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="opacity:0.85;fill:url(#radialGradient42432);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ 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="path41672"
+ d="m 364.24984,-225.5 4.25016,1.75 c 1,5.75 -5.50003,2 -5.08381,8.85761 l -4.04561,-2.26888"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient42434);stroke-width:1;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"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;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 364.24997,-225.5 4.25003,1.75"
+ id="path41674"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-399.2499,383.75)"
+ id="g41676" />
+ <g
+ id="g41678"
+ transform="translate(-406.2499,380.75)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41680"
+ transform="translate(338.00016,191)">
+ <g
+ id="g41682"
+ transform="translate(56.999841,68)"
+ style="opacity:0.8;display:inline;enable-background:new">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41684"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41686"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41688"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41690"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41692"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41694"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41696"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ 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;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41699"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41701"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="176"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41703"
+ 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" />
+ <path
+ style="fill:url(#linearGradient42436);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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -220,178.5 c -4.14,0 -7.40235,2.464 -7.40234,5.5 0,3.036 3.26234,5.5 7.40234,5.5 4.14,0 7.40234,-2.464 7.40234,-5.5 0,-3.036 -3.26233,-5.50001 -7.40234,-5.5 z m 0,4 c 1.2993,0 2.42742,0.39879 3.03125,1 -0.60383,0.60121 -1.73196,1 -3.03125,1 -1.29929,0 -2.42742,-0.39879 -3.03125,-1 0.60383,-0.60121 1.73196,-1 3.03125,-1 z"
+ id="path41705"
+ sodipodi:nodetypes="cssscccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:url(#radialGradient42438);fill-rule:evenodd;stroke:none"
+ d="m -214.625,180.4375 c 1.5822,4.85564 -3.15377,7.27675 -11.84375,6.21875 l 0,0.0312 c 1.25689,1.67541 3.66207,2.8125 6.46875,2.8125 4.14,0 7.40625,-2.464 7.40625,-5.5 0,-1.34213 -0.64966,-2.57614 -1.71875,-3.53125 -0.10326,-0.0119 -0.20204,-0.024 -0.3125,-0.0312 z"
+ id="path41707"
+ sodipodi:nodetypes="cccsscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path41709"
+ d="m -223.375,183.45313 c 1.90631,-1.46639 4.08905,-1.44306 6.1875,-0.53125 L -217,182.76563 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ style="opacity:0.6;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:url(#radialGradient42440);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 -223.375,183.65625 0.5,-0.0312 c -0.0509,-0.0426 -0.11109,-0.08 -0.15625,-0.125 0.60383,-0.60121 1.73196,-1 3.03125,-1 0.99575,0 1.89552,0.24495 2.53125,0.625 L -217,182.96875 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ id="path41711"
+ sodipodi:nodetypes="cccsccc"
+ 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"
+ sodipodi:ry="2.5"
+ sodipodi:rx="6.5"
+ sodipodi:cy="40.5"
+ sodipodi:cx="-220"
+ id="path41713"
+ style="fill:none;stroke:url(#linearGradient42442);stroke-width:0.5962854;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"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41715"
+ 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"
+ id="rect41717"
+ width="16"
+ height="16"
+ x="-211.99985"
+ y="304" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ transform="translate(73.00016,196)"
+ id="g41719">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41721"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41723"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41725"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41727"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41729"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41731"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41733"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;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:new"
+ 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;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41735"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41737"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g41739"
+ transform="matrix(1.1658027,0,0,1.1657997,-354.28956,51.94393)"
+ 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\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="path41741"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23686147;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42444);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path41743"
+ 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.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)" />
+ <path
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42446);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41745"
+ 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" />
+ </g>
+ <path
+ sodipodi:nodetypes="cscc"
+ id="path41747"
+ style="fill:none;stroke:url(#linearGradient42448);stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ d="m -197.75642,311.54171 c -0.99362,1.2083 -2.79874,2.22895 -6.24718,2.22895 -3.415,0 -5.24644,-1.02065 -6.24644,-2.195"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41749"
+ transform="matrix(1,0,0,-1,496,768)">
+ <rect
+ transform="scale(-1,1)"
+ y="385"
+ x="202"
+ height="16"
+ width="16"
+ id="rect41751"
+ 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" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -203.5,396.5 0,3 -3,0"
+ id="path41753"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41755"
+ d="m -213.5,386.5 0,3 -3,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41757"
+ d="m -208.5,391.5 0,3 -3,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g41759"
+ 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,0,0,1,-118.8387,295.00001)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cz"
+ id="path41761"
+ 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:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 85.6613,103.49999 9,-9"
+ inkscape:connector-curvature="0" />
+ <path
+ 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"
+ id="path41763"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 85.6613,103.49999 9,-9"
+ style="fill:none;stroke:#d7e3f4;stroke-width:1.5;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="path41765"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41767"
+ d="m -203,400 0,-4 -1,0 0,3 -3,0 0,1 4,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41769"
+ d="m -213,390 0,-4 -1,0 0,3 -3,0 0,1 4,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -208,395 0,-4 -1,0 0,3 -3,0 0,1 4,0 z"
+ id="path41771"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,-1,-420,786)"
+ style="opacity:0.2"
+ id="g41773">
+ <path
+ style="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"
+ d="m -208,395 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path41775"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41777"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="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"
+ d="m -211,392 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path41779"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41781"
+ d="m -213,390 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42152"
+ transform="translate(272.99917,170)">
+ <g
+ transform="translate(83.990361,105)"
+ id="g42154"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42157"
+ 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="path42159"
+ style="fill:none;stroke:url(#linearGradient42462);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42464);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42161"
+ 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
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42466);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42163"
+ 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" />
+ </g>
+ <g
+ transform="translate(81.056581,171.48366)"
+ id="g42165">
+ <path
+ id="path42168"
+ d="m 101.94425,50.518348 -5.000004,1.875 0,6.3125 5.000004,2.71875 5,-2.71875 0,-6.3125 -5,-1.875 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42170"
+ d="m 106.94413,58.696518 0,-6.29009 -5,-1.89415 c 0,2.16796 0,10.43646 0,10.91232 l 5,-2.72808 z"
+ style="fill:url(#linearGradient42468);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 96.944126,58.696518 0,-6.29009 5.000004,-1.89415 0,10.91232 -5.000004,-2.72808 z"
+ id="path42175"
+ 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="path42177"
+ d="m 96.944126,52.406428 5.000004,-1.89415 5,1.89415 -5,2.07396 -5.000004,-2.07396 z"
+ style="fill:#ffffff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42470);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 106.44413,52.406428 0,6.04208 -4.5,2.48007 -4.500004,-2.48007 0,-6.04208"
+ id="path42179"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42181"
+ transform="translate(335.99917,149.00001)">
+ <g
+ style="opacity:0.5"
+ id="g42183"
+ transform="translate(83.990367,126)">
+ <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="path42185"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)" />
+ <path
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42472);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42187"
+ 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="path42189"
+ style="fill:none;stroke:url(#linearGradient42474);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)" />
+ <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="path42191"
+ style="fill:none;stroke:url(#linearGradient42477);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(321.49473,233.64631)"
+ id="g42193">
+ <g
+ id="g42195"
+ transform="translate(-38.4939,35.353694)">
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path42197"
+ d="m -98.999998,-25.5 c -2.485192,0 -4.499992,0.89481 -4.500002,2 l 0,7 c 0,1.10519 2.0148,2 4.500002,2 2.48519,0 4.499998,-1.1448 4.499998,-2.25 l 2e-6,-6.75 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ style="fill:url(#linearGradient42479);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ id="path42199"
+ d="m -102.5,-22 0,5 c 0,1.25 0.5,1.5 3.5,1.5 3,0 3.5,-0.25 3.5,-1.5 l 0,-5"
+ style="fill:none;stroke:url(#linearGradient42481);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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="css"
+ id="path42201"
+ d="M -94.730509,-23.353486 C -94.748454,-21.92288 -95.5,-21.5 -99,-21.5 c -3.5,0 -4.24845,-0.42288 -4.24845,-1.848345"
+ style="fill:none;stroke:url(#linearGradient42483);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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient42485);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"
+ d="m -95.341215,-23.173655 c 0,0.873491 -0.648671,1.587005 -3.656631,1.582419 -3.011664,-0.0046 -3.656634,-0.708928 -3.656634,-1.582419 0,-0.87349 0.64497,-1.582418 3.656634,-1.582418 3.00796,0 3.656631,0.708928 3.656631,1.582418 z"
+ id="path42203"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ 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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -99,-25.5 c -4,0 -4.49999,0.89481 -4.5,2 l 0,6 c 0,1.10519 0,3.00433 4.50216,3.002164 C -94.5,-14.5 -94.5,-16.3948 -94.5,-17.5 l 0,-6 c 0,-1.10519 -0.5,-2 -4.5,-2 z"
+ id="path42205"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42207"
+ transform="translate(251.99917,191.00001)">
+ <g
+ transform="translate(83.990364,83.999999)"
+ id="g42209"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42211"
+ 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="path42213"
+ style="fill:none;stroke:url(#linearGradient42487);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42489);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42215"
+ 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
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42491);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42217"
+ 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" />
+ </g>
+ <g
+ transform="matrix(1.3088013,0,0,1.3078064,114.94487,78.842325)"
+ style="display:inline"
+ 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="g42219">
+ <rect
+ y="94.553505"
+ x="48.560436"
+ height="7.6462827"
+ width="7.6405811"
+ id="rect42221"
+ style="fill:url(#linearGradient42493);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.61147881;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" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42223"
+ d="m 49.324493,101.43525 0,-6.117109 6.112464,0 9.17e-4,6.117009 -6.113381,1e-4 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient42495);stroke-width:0.76434839px;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42225"
+ transform="translate(293.99917,128.01655)">
+ <g
+ id="g42227">
+ <g
+ transform="translate(83.990364,146.98346)"
+ id="g42229"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42231"
+ 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="path42233"
+ style="fill:none;stroke:url(#linearGradient42497);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42499);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42235"
+ 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
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42501);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42237"
+ 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" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g42239"
+ transform="matrix(0.9864502,0,0,0.9977342,55.832396,47.37231)"
+ 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\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="path42241"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.45345163;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42503);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path42243"
+ 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.6289675,-0.07056955,0.07168957,-0.6223801,203.47957,305.88099)" />
+ <path
+ transform="matrix(0.5718707,0,0,0.5622842,53.438009,156.77386)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42505);stroke-width:1.77757704;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42245"
+ 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" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42247"
+ transform="translate(315,107)">
+ <g
+ transform="translate(83.990364,168)"
+ id="g42249"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42251"
+ 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="path42253"
+ style="fill:none;stroke:url(#linearGradient42507);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42509);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42255"
+ 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
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42511);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42257"
+ 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" />
+ </g>
+ <g
+ transform="translate(67,168)"
+ id="g42259">
+ <rect
+ style="opacity:0;fill:#ffd5d5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42261"
+ width="14"
+ height="14"
+ x="109"
+ y="116" />
+ <g
+ transform="matrix(0,-0.7411719,0.7413284,0,26.310335,194.89046)"
+ id="g42263">
+ <rect
+ y="113"
+ x="89.000832"
+ height="16"
+ width="16"
+ id="rect42265"
+ 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"
+ 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.3039373,-0.2835816,-0.2811062,1.3154136,-8.365286,-135.94413)"
+ id="g42268"
+ style="display:inline">
+ <path
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.52109182;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 139.87786,116.72728 c 0,4.416 -4.87654,8.89303 -9.18264,9.14567 -4.03231,0.23658 -6.86684,-2.60955 -6.61392,-6.64097 0.26963,-4.29785 4.87655,-8.89304 9.18265,-9.14567 4.03232,-0.23656 6.86685,2.60957 6.61391,6.64097 z"
+ id="path42273"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-0.6214741,-0.06030772,0.08065856,-0.6191475,201.43124,304.14414)"
+ style="opacity:0.8;fill:url(#linearGradient42513);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 140.14875,115.73726 c 0,4.416 -4.29905,10.26855 -8.71505,10.26855 -4.416,0 -7.23906,-1.65769 -7.23906,-6.07369 0,-4.416 4.28332,-9.5732 8.27188,-10.31985 3.26409,-0.61103 7.68223,1.70899 7.68223,6.12499 l 0,0 0,0 0,0 z"
+ id="path42275"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.5541229,-0.02016698,-0.02019099,0.5552959,58.152692,160.26124)"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42515);stroke-width:1.90297282;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 139.88903,116.28509 c 0,4.416 -5.24736,9.49944 -9.66336,9.49944 -4.416,0 -6.16482,-1.70296 -6.16482,-6.11896 0,-4.416 5.24736,-9.49945 9.66336,-9.49945 4.416,0 6.16482,1.70297 6.16482,6.11897 l 0,0 0,0 0,0 z"
+ id="path42277"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ inkscape:export-ydpi="90"
+ 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">
+ <rect
+ y="237.5"
+ x="162.99997"
+ height="16"
+ width="16"
+ id="rect42282"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <g
+ id="g42285"
+ style="opacity:0.9">
+ <g
+ transform="translate(75.999999,-319.5)"
+ id="g42287"
+ style="fill:#ffcc00;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline">
+ <path
+ style="fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m -167,235 0,9 1,0 0,-4 3,0 0,-1 -3,0 0,-4 5,0 0,-1 -6,0 0,1 z"
+ transform="translate(262.99997,326)"
+ id="path42289"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:#ffcc00;display:inline"
+ id="g42291"
+ transform="translate(75.999999,-319.5)">
+ <path
+ style="fill:url(#linearGradient42517)"
+ d="m -167,235 0,9 1,0 0,-4 3,0 0,-1 -3,0 0,-4 5,0 0,-1 -6,0 0,1 z"
+ transform="translate(262.99997,326)"
+ id="path42294"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.85;fill:#ffffff;display:inline"
+ d="m 171.99997,240.5 0,10 0.65625,0 0,-10 -0.65625,0 z"
+ id="path42296"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;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"
+ id="g42298">
+ <rect
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;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"
+ id="rect42300"
+ width="1.25"
+ height="1"
+ x="90"
+ y="43"
+ transform="translate(73.999969,208.5)" />
+ <rect
+ y="251.5"
+ x="167.74997"
+ height="1"
+ width="1.2500329"
+ id="rect42302"
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;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" />
+ <rect
+ y="238.5"
+ x="163.99997"
+ height="1"
+ width="1.2499995"
+ id="rect42304"
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;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" />
+ <rect
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;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"
+ id="rect42306"
+ width="1.250011"
+ height="1"
+ x="167.74997"
+ y="238.5" />
+ <rect
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;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"
+ id="rect42308"
+ width="1.0000029"
+ height="12.5"
+ x="165.99997"
+ y="239.25" />
+ </g>
+ <g
+ id="g42310"
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ transform="translate(73.999969,208.5)"
+ y="43"
+ x="90"
+ height="1"
+ width="2"
+ id="rect42312"
+ style="fill:#e9f0fa;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:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42314"
+ width="2"
+ height="1"
+ x="166.99997"
+ y="251.5" />
+ <rect
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42316"
+ width="2"
+ height="1"
+ x="163.99997"
+ y="238.5" />
+ <rect
+ y="238.5"
+ x="166.99997"
+ height="1"
+ width="2"
+ id="rect42318"
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="239.5"
+ x="165.99997"
+ height="12"
+ width="0.99999952"
+ id="rect42320"
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g35366"
+ transform="translate(333.02099,358)">
+ <rect
+ y="135"
+ x="-202"
+ height="16"
+ width="16"
+ id="rect35368"
+ 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" />
+ <g
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)"
+ id="g35370"
+ style="opacity:0.35">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#f8dcdc;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#580000;stroke-width:1.22792602;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="path35372"
+ 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="path35374"
+ style="fill:none;stroke:url(#linearGradient35406);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)" />
+ <path
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35408);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35376"
+ 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" />
+ </g>
+ <g
+ id="g35378"
+ transform="matrix(0.857703,0,0,0.8577018,-4.235469,19.278753)"
+ style="opacity:0.7">
+ <path
+ sodipodi:nodetypes="cssssszzs"
+ id="path35380"
+ d="m -222.5,141.5 c 1.52069,0 2.97702,-1.62476 3,-2.5 0.0525,-1.99931 1.5,-3.5 3.5,-3.5 2,0 3.5,1.568 3.5,3.5 0,1.84581 -1.5,3.50326 -3.5,3.5 -0.8997,-0.001 -2.5,1.5 -2.5,3 0,2.25 -1.75,4 -4,4 -2.25,0 -4,-1.75 -4,-4 0,-2.25 1.75,-4 4,-4 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.93272448;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" />
+ <path
+ transform="translate(-527,-167)"
+ d="m 311,303 c -1.75507,0 -3,1.24493 -3,3 0,0.81824 -0.48216,1.55558 -1.125,2.09375 C 306.23216,308.63192 305.39457,309 304.5,309 c -1.996,0 -3.5,1.504 -3.5,3.5 0,1.996 1.504,3.5 3.5,3.5 1.996,0 3.5,-1.504 3.5,-3.5 0,-0.88607 0.36895,-1.73024 0.90625,-2.375 0.5373,-0.64476 1.27281,-1.125 2.09375,-1.125 1.72989,0 3,-1.41958 3,-3 0,-1.67845 -1.25603,-3 -3,-3 z"
+ id="path35382"
+ style="opacity:0.8;fill:url(#linearGradient35410);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86598092;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.48985747"
+ sodipodi:type="inkscape:offset" />
+ <path
+ transform="translate(-527,-167)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.96440691"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="fill:none;stroke:url(#radialGradient35412);stroke-width:1.16590559;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="path35384"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z" />
+ <path
+ transform="matrix(0,-1,-1,0,90,450)"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path35386"
+ style="fill:none;stroke:url(#radialGradient35414);stroke-width:1.16590559;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:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset" />
+ </g>
+ <g
+ style="opacity:0.12999998"
+ id="g35388"
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)">
+ <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="path35390"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#530505;stroke-width:1.22792602;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)" />
+ <path
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35416);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35392"
+ 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="path35394"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35418);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)" />
+ </g>
+ <g
+ style="opacity:0.9;display:inline;enable-background:new"
+ transform="matrix(0.8749996,0,0,0.8802811,-404.57262,-113.49608)"
+ id="g35396">
+ <path
+ sodipodi:type="arc"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient35420);stroke-width:1.13942409;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="path35398"
+ sodipodi:cx="219.5"
+ 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"
+ transform="translate(20,0)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient35422);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35400"
+ sodipodi:cx="219.5"
+ 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"
+ 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"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35402"
+ style="fill:none;stroke:url(#linearGradient35424);stroke-width:1.6138407;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(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"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35404"
+ style="opacity:0.8;fill:url(#radialGradient35426);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ transform="translate(291,273.9804)"
+ id="g35428"
+ 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"
+ id="rect35430"
+ width="16"
+ height="16"
+ x="-202"
+ y="135" />
+ <g
+ style="opacity:0.35"
+ id="g35432"
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)">
+ <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="path35434"
+ style="fill:#f8dcdc;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#580000;stroke-width:1.22792602;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"
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)" />
+ <path
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35468);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35436"
+ 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="path35438"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35470);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)" />
+ </g>
+ <g
+ style="opacity:0.7"
+ transform="matrix(0.857703,0,0,0.8577018,-4.235469,19.278753)"
+ id="g35440">
+ <path
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.93272448;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 -222.5,141.5 c 1.52069,0 2.97702,-1.62476 3,-2.5 0.0525,-1.99931 1.5,-3.5 3.5,-3.5 2,0 3.5,1.568 3.5,3.5 0,1.84581 -1.5,3.50326 -3.5,3.5 -0.8997,-0.001 -2.5,1.5 -2.5,3 0,2.25 -1.75,4 -4,4 -2.25,0 -4,-1.75 -4,-4 0,-2.25 1.75,-4 4,-4 z"
+ id="path35442"
+ sodipodi:nodetypes="cssssszzs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.48985747"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="opacity:0.8;fill:url(#linearGradient35472);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86598092;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35444"
+ d="m 311,303 c -1.75507,0 -3,1.24493 -3,3 0,0.81824 -0.48216,1.55558 -1.125,2.09375 C 306.23216,308.63192 305.39457,309 304.5,309 c -1.996,0 -3.5,1.504 -3.5,3.5 0,1.996 1.504,3.5 3.5,3.5 1.996,0 3.5,-1.504 3.5,-3.5 0,-0.88607 0.36895,-1.73024 0.90625,-2.375 0.5373,-0.64476 1.27281,-1.125 2.09375,-1.125 1.72989,0 3,-1.41958 3,-3 0,-1.67845 -1.25603,-3 -3,-3 z"
+ transform="translate(-527,-167)" />
+ <path
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path35446"
+ style="fill:none;stroke:url(#radialGradient35474);stroke-width:1.16590559;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:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset"
+ transform="translate(-527,-167)" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.96440691"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="fill:none;stroke:url(#radialGradient35476);stroke-width:1.16590559;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="path35448"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ transform="matrix(0,-1,-1,0,90,450)" />
+ </g>
+ <g
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)"
+ id="g35450"
+ style="opacity:0.12999998">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#530505;stroke-width:1.22792602;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35452"
+ 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="path35454"
+ style="fill:none;stroke:url(#linearGradient35478);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)" />
+ <path
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35480);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35456"
+ 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" />
+ </g>
+ <g
+ id="g35458"
+ transform="matrix(0.8749996,0,0,0.8802811,-404.57262,-113.49608)"
+ 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"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35460"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient35482);stroke-width:1.13942409;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(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"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35462"
+ style="opacity:0.8;fill:url(#linearGradient35484);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35486);stroke-width:1.6138407;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="path35464"
+ sodipodi:cx="219.5"
+ 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"
+ transform="matrix(0.7060003,0,0,0.7060647,84.532933,85.976064)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#radialGradient35488);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35466"
+ sodipodi:cx="219.5"
+ 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"
+ transform="matrix(0.875,0,0,0.875,47.4375,36.5625)" />
+ </g>
+ </g>
+ <g
+ id="g34702"
+ 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">
+ <g
+ id="g35479"
+ transform="translate(30.046349,-38.039825)"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(-340.00002,-121.00001)"
+ id="g35481">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9e9af;stroke-width:0.58333313;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="path35483"
+ sodipodi:cx="464.5"
+ 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"
+ 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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35485"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e1e08e;stroke-width:0.69999987;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:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#adac2f;stroke-width:1.16666663;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="path35487"
+ sodipodi:cx="464.5"
+ 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"
+ transform="matrix(0.8571429,0,0,0.8571429,66.810813,28.039828)" />
+ </g>
+ <rect
+ y="71.039841"
+ x="123.95369"
+ height="2"
+ width="2"
+ id="rect35489"
+ style="fill:#f4eed7;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="opacity:0.6"
+ transform="matrix(-1,0,0,1,194,-21)"
+ id="g35439">
+ <path
+ style="fill:url(#linearGradient35446);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ d="m 31.5,52.5 c -1.656,0 -3,1.343998 -3,3 0,0.02155 -4.53e-4,0.04106 0,0.0625 -1.138867,0.233417 -1.999999,1.229094 -2,2.4375 0,1.381035 1.120001,2.500001 2.5,2.5 l 6.5,0 c 1.656,0 3,-1.344001 3,-3 0,-1.656001 -1.344,-2.999999 -3,-3 -0.40365,0 -0.77337,0.105241 -1.125,0.25 C 34.035268,53.465989 32.89035,52.500001 31.5,52.5 z"
+ id="path34600"
+ 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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path35419"
+ style="fill:url(#linearGradient35450);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0,0.3125,-0.3124999,0,68.374988,14.250001)" />
+ <path
+ transform="matrix(0,0.2187504,-0.2187496,0,54.562456,29.374947)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35448);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path34624"
+ 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
+ transform="matrix(0.08088095,0.3018518,-0.3018517,0.08088093,60.442218,8.1116116)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35452);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path35435"
+ 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="path35429"
+ style="fill:url(#linearGradient35454);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0,0.2812501,-0.2812497,0,64.937461,20.624986)" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.92788464"
+ inkscape:original="M 31.5 52.5 C 29.844 52.5 28.5 53.843998 28.5 55.5 C 28.5 55.521551 28.499547 55.541057 28.5 55.5625 C 27.361133 55.795917 26.500001 56.791594 26.5 58 C 26.5 59.381035 27.620001 60.500001 29 60.5 L 35.5 60.5 C 37.156 60.5 38.5 59.155999 38.5 57.5 C 38.5 55.843999 37.156 54.500001 35.5 54.5 C 35.09635 54.5 34.72663 54.605241 34.375 54.75 C 34.035268 53.465989 32.89035 52.500001 31.5 52.5 z "
+ style="fill:none;stroke:url(#linearGradient35718);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="path35703"
+ d="m 31.5,53.4375 c -1.153957,0 -2.0625,0.908541 -2.0625,2.0625 0,0.03455 7.4e-5,0.03475 0,0.03125 a 0.92797743,0.92797743 0 0 1 -0.75,0.9375 c -0.72055,0.147681 -1.249999,0.763662 -1.25,1.53125 0,0.879367 0.684082,1.562501 1.5625,1.5625 l 6.5,0 c 1.153956,0 2.0625,-0.908545 2.0625,-2.0625 0,-1.153957 -0.908543,-2.062499 -2.0625,-2.0625 -0.242369,0 -0.494949,0.03839 -0.78125,0.15625 A 0.92797743,0.92797743 0 0 1 33.46875,55 C 33.231438,54.103084 32.460566,53.437501 31.5,53.4375 z" />
+ </g>
+ <rect
+ y="31"
+ x="152"
+ height="16"
+ width="16"
+ id="rect34608"
+ 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"
+ 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(0.9059893,0,0,0.9161677,40.690483,-162.91268)"
+ id="g34610"
+ style="display:inline">
+ <path
+ transform="matrix(0.6879625,0,0,0.6812035,38.104167,142.74297)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.6033566;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path34612"
+ 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
+ transform="matrix(-0.6156869,-0.06867104,0.07017585,-0.6056363,201.96224,303.63852)"
+ 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="path34614"
+ style="opacity:0.8;fill:url(#linearGradient34618);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <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="path34616"
+ style="fill:none;stroke:url(#linearGradient34620);stroke-width:2.02934265;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5436035,0,0,0.5381576,57.159565,159.63177)" />
+ </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"
+ transform="translate(-20.999985,0)">
+ <rect
+ y="157"
+ x="89.000015"
+ height="16"
+ width="16"
+ id="rect36400"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36402">
+ <g
+ transform="translate(8.000015,151)"
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="g36404">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#00163c;stroke-width:3.29999995;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 88.999985,8 0,8"
+ id="path36407"
+ 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="path36410"
+ d="m 82.99997,20 6.000015,-4"
+ style="fill:none;stroke:#5d0606;stroke-width:3.29999995;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="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#183c00;stroke-width:3.29999995;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 94.99997,20 88.999985,16"
+ id="path36412"
+ 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
+ style="fill:none;stroke:#5d0606;stroke-width:1.79999995;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="rect36414"
+ width="2.0000153"
+ height="2.0000069"
+ x="89.999985"
+ y="170"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:none;stroke:#001e50;stroke-width:1.79999995;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="rect36416"
+ width="2.0000153"
+ height="2.0000069"
+ x="96"
+ y="158"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4c8ff4;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 97,159 0,8"
+ id="path36418"
+ 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="path36420"
+ d="M 90.999985,171 97,167"
+ style="fill:none;stroke:#ef4e29;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="89.999985"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36422"
+ style="opacity:0.3;fill:none;stroke:#5d0606;stroke-width:1.79999995;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
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.3;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 90.499985,170.75 6,-4 1.5e-5,-7.25"
+ id="path36424"
+ 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
+ ry="0"
+ rx="0"
+ y="170"
+ x="102"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36426"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;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
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#93e420;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 102.99998,171 97,167"
+ id="path36428"
+ 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
+ ry="0"
+ rx="0"
+ y="170"
+ x="90"
+ height="2"
+ width="2"
+ id="rect36430"
+ style="fill:#eb512e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="158"
+ x="96"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36432"
+ style="opacity:0.3;fill:none;stroke:#001e50;stroke-width:1.79999995;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
+ ry="0"
+ rx="0"
+ y="158"
+ x="96.000023"
+ height="2"
+ width="2"
+ id="rect36434"
+ style="fill:#4c8ff4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient36452);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36436"
+ sodipodi:cx="70.5"
+ 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"
+ 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"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.6666679,0,0,0.6666668,49.999915,157.33333)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36438"
+ sodipodi:cx="70.5"
+ 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"
+ 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="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;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="rect36440"
+ width="2.0000153"
+ height="2.0000069"
+ x="102"
+ y="170"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#95e51f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36442"
+ width="2"
+ height="2"
+ x="102.00002"
+ y="170"
+ rx="0"
+ ry="0" />
+ <g
+ id="g36444"
+ style="opacity:0.8">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36446"
+ d="m 96.5,159.5 0,-1 1,0"
+ style="fill:none;stroke:url(#linearGradient36454);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient36456);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.499985,171.5 0,-1 1,0"
+ id="path36448"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36450"
+ d="m 102.49999,171.5 0,-1 1,0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient36458);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(105,337.99999)"
+ id="g35291"
+ 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"
+ id="rect35293"
+ width="16"
+ height="16"
+ x="-210"
+ y="-66"
+ transform="scale(-1,-1)" />
+ <g
+ id="g35295"
+ transform="translate(22.999994,19)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path35297"
+ d="m 178.00001,33.5 -1.5,0 L 174,36 c -1.00699,1.006986 -0.0205,3.604505 2.1875,5.8125 2.208,2.207997 4.80551,3.194485 5.8125,2.1875 l 2.50001,-2.5 0,-1.5 -0.75,-1.75 -4,-4 -1.75,-0.75 z"
+ style="fill:url(#linearGradient36648);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccscccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35299"
+ style="fill:url(#linearGradient36650);fill-rule:evenodd;stroke:none"
+ d="m 186.50001,35.5 -2.75,2.75 -1,-1 -1,-1 -1,-1 -1,-1 2.75,-2.75 1.25,0 1.5,1.25 1.25,1.5 0,1.25 z"
+ sodipodi:nodetypes="ccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35301"
+ d="m 182.50001,31.5 -2.75,2.75 -1.75,-0.75 -1.5,0 L 174,36 c -1.00699,1.006986 -0.0205,3.604505 2.1875,5.8125 2.208,2.207997 4.80551,3.194485 5.8125,2.1875 l 2.50001,-2.5 0,-1.5 -0.75,-1.75 2.75,-2.75 0,-1 -1.25,-1.75 -1.75,-1.25 -1,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccsccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:none;stroke:url(#linearGradient36652);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 174.75001,36.5 2.25,-2.25 1.5,0.25 1.5,0.75 1.5,1.25 1.25,1.5 0.75,1.5 0.25,1.5 -1.5,1.5"
+ id="path35303" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#d3c656;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74147779;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35305"
+ sodipodi:cx="181"
+ 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"
+ 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"
+ sodipodi:ry="5.5293522"
+ sodipodi:rx="1.1763829"
+ sodipodi:cy="35"
+ sodipodi:cx="181"
+ id="path35307"
+ style="fill:#f3eebb;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74147779;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="czs"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient36654);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 182.25,43.75 C 182.25,42 182,41 179.5,38.5 177,36 175.75,35.75 174.25,35.75"
+ id="path35309" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient36656);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 180.50001,34.5 2,-2 1,0 1,1 1,1 0,1 -2,2"
+ id="path35311"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35313"
+ d="m 184.50001,41.5 c 0,-1.75 0,-3 -2.5,-5.5 -2.5,-2.5 -4,-2.5 -5.5,-2.5"
+ style="fill:none;stroke:url(#linearGradient36658);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="czs" />
+ </g>
+ <g
+ id="g35315"
+ style="opacity:0.65">
+ <g
+ id="g35317"
+ transform="translate(21,21)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 174.5,40.5 0,3 3,0"
+ id="path35319" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35321"
+ style="fill:none;stroke:#2b2600;stroke-width:3;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"
+ d="M 175.5,42.5 179,39" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,383,116)"
+ id="g35323">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.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="g35325">
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path35327"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35329"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;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"
+ d="m 85.6613,103.49999 5,-5" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,4 -1,0 0,-3 -3,0 0,-1 4,0 z"
+ id="path35331"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g35333"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b5a731;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path35335"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ </g>
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35337"
+ width="1.25"
+ height="1.25"
+ x="200.75"
+ y="58" />
+ <rect
+ y="58.75"
+ x="199.75"
+ height="1.5"
+ width="1.5"
+ id="rect35339"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35341"
+ width="1.5"
+ height="1.5"
+ x="198.75"
+ y="59.75" />
+ </g>
+ <g
+ id="g35343"
+ transform="translate(0,-7e-6)">
+ <rect
+ transform="scale(-1,-1)"
+ y="-404"
+ x="-273"
+ height="16"
+ width="16"
+ id="rect35345"
+ 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" />
+ <g
+ mask="url(#mask31861)"
+ id="g35347"
+ transform="translate(63,338)"
+ style="opacity:0.65">
+ <g
+ id="g35349"
+ transform="matrix(0,-1,1,0,104.00001,149.1613)"
+ style="stroke:#9e872a;stroke-opacity:1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path35351"
+ d="m 187.5,53.75 0,-2.25 -2,0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(0,1,-1,0,149.1613,-83.00001)" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ style="fill:none;stroke:#2b2600;stroke-width:3;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="path35353"
+ sodipodi:nodetypes="cz"
+ transform="matrix(0,-1,1,0,-6.83869,189.16129)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 187.5,53.5 0,-2 -2,0"
+ id="path35355"
+ transform="matrix(0,-1,1,0,33.1613,278.99999)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35357"
+ style="fill:none;stroke:#2b2600;stroke-width:3;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"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ transform="matrix(0,1,-1,0,189.16129,6.83869)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35359"
+ d="m 187.5,53.5 0,-2 -2,0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ transform="translate(-89.8387,39.99999)" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ style="fill:none;stroke:#2b2600;stroke-width:3;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="path35361"
+ sodipodi:nodetypes="cz"
+ transform="matrix(-1,0,0,-1,182.3226,195.99998)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 187.5,53.5 0,-2 -2,0"
+ id="path35363"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35365"
+ style="fill:none;stroke:#2b2600;stroke-width:3;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"
+ d="m 85.6613,103.49999 5.5,-5.5" />
+ </g>
+ <g
+ id="g35367"
+ transform="translate(21,0)">
+ <g
+ id="g35369"
+ 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,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ id="path35371"
+ sodipodi:nodetypes="cz"
+ d="" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;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="path35373"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path35375"
+ d="m 188,51 0,3 -1,0 0,-2 -2,0 0,-1 3,0 z"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.3"
+ id="g35377">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path35379"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#2b2600;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>
+ <g
+ transform="matrix(-1,0,0,-1,383,116)"
+ id="g35381">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.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="g35383">
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path35385"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35387"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;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"
+ d="m 85.6613,103.49999 5.5,-5.5" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,3 -1,0 0,-2 -2,0 0,-1 3,0 z"
+ id="path35391"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g35393"
+ style="opacity:0.3"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#2b2600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path35395"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ <g
+ id="g35398"
+ inkscape:transform-center-x="3.125"
+ inkscape:transform-center-y="-3.125"
+ transform="matrix(0,-1,1,0,144,239)">
+ <g
+ id="g35400"
+ 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,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ id="path35405"
+ sodipodi:nodetypes="cz"
+ d="" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;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="path35407"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path35409"
+ d="m 188,51 0,3 -1,0 0,-2 -2,0 0,-1 3,0 z"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.3"
+ id="g35411">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path35413"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#2b2600;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>
+ <g
+ id="g35415"
+ transform="translate(-16,0)">
+ <path
+ inkscape:connector-curvature="0"
+ d="M 223.5,63.5 218,58"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;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="path35417"
+ sodipodi:nodetypes="cz" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 225,65 -3,0 0,-1 2,0 0,-2 1,0 0,3 z"
+ id="path35420"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g35422"
+ style="opacity:0.3"
+ transform="matrix(0,-1,-1,0,611,-152)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#2b2600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path35424"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(139.00002,324)"
+ id="g35426">
+ <g
+ id="g35429"
+ 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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35431"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9ddaf;stroke-width:0.49999988;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:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.15;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#fffc28;stroke-width:0.38888648;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="path35433"
+ sodipodi:cx="464.5"
+ 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"
+ 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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35437"
+ style="opacity:0.3;fill:#e1d98e;fill-opacity:1;fill-rule:nonzero;stroke:#f0d700;stroke-width:0.50000638;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: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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35439"
+ style="fill:#fbf7e5;fill-opacity:1;fill-rule:nonzero;stroke:#474213;stroke-width:0.63000238;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:type="arc" />
+ </g>
+ </g>
+ <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="rect35441"
+ width="2"
+ height="2"
+ x="264"
+ y="395" />
+ </g>
+ <g
+ transform="translate(147,337.99999)"
+ id="g35443"
+ 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"
+ id="rect35445"
+ width="16"
+ height="16"
+ x="131"
+ y="50" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccc"
+ id="path35447"
+ d="m 144.5,63.5 -1,0 -2.5,-1 -1.5,3 -1,0 -1.5,-3 -2.5,1 -1,10e-7 0,-1.000001 1,-2.5 -3,-1.5 0,-1 3,-1.5 -1,-2.5 0,-1 1,0 2.5,1 1.5,-3 1,0 1.5,3 2.5,-1 1,0 0,1 -1,2.5 3,1.5 0,1 -3,1.5 1,2.5 0,1 z"
+ style="opacity:0.85;fill:#f5efb2;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#38330e;stroke-width:0.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" />
+ <g
+ id="g35449">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9ddaf;stroke-width:0.49999988;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="path35451"
+ sodipodi:cx="464.5"
+ 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"
+ 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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35453"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#fff6d5;stroke-width:0.38888386;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: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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35455"
+ style="fill:#b5a51f;fill-opacity:1;fill-rule:nonzero;stroke:#463f00;stroke-width:0.39999822;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:type="arc" />
+ <rect
+ style="opacity:0.9;fill:#ffed55;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35457"
+ width="5"
+ height="5"
+ x="136"
+ y="55"
+ rx="2.5"
+ ry="2.5" />
+ <rect
+ ry="1.875"
+ rx="1.875"
+ y="55.25"
+ x="136.25"
+ height="3.75"
+ width="3.75"
+ id="rect35459"
+ style="opacity:0.9;fill:#fbfaef;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="56"
+ x="137"
+ height="2"
+ width="2"
+ id="rect35461"
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ transform="translate(189,295.99999)"
+ id="g35463"
+ style="display:inline;enable-background:new">
+ <rect
+ y="92"
+ x="152"
+ height="16"
+ width="16"
+ id="rect35465"
+ 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="g35467"
+ transform="matrix(1.6519496,0,0,1.6519309,-230.47015,-63.200317)"
+ style="opacity:0.25;display:inline;filter:url(#filter30564);enable-background:new"
+ clip-path="url(#clipPath31849)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#fff6aa;stroke-width:0.26988116;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="path35469"
+ sodipodi:cx="464.5"
+ 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"
+ 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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35471"
+ style="opacity:0.25;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#ffe400;stroke-width:0.31863192;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: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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35473"
+ style="fill:#ffeeaa;fill-opacity:1;fill-rule:nonzero;stroke:#b4b200;stroke-width:0.38825312;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:type="arc" />
+ </g>
+ <g
+ id="g35477"
+ style="opacity:0.6"
+ transform="translate(-55,-1)">
+ <g
+ id="g35480">
+ <path
+ inkscape:connector-curvature="0"
+ id="path35482"
+ d="m 219.5,102 0,4.5"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;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"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35484"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ style="fill:none;stroke:#2b2600;stroke-width:2.79999995;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>
+ <g
+ id="g35486">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1;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"
+ d="m 219.5,101.5 0,5.5"
+ id="path35488"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffd5;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ id="path35490"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.6"
+ id="g35493"
+ transform="matrix(0,1,-1,0,261,-124)">
+ <g
+ id="g35496">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;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"
+ d="m 219.5,102 0,4.5"
+ id="path35498" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.79999995;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"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ id="path35500"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ id="g35502">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path35504"
+ d="m 219.5,101.5 0,5.5"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1;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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35506"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ style="fill:none;stroke:#ffffd5;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <g
+ id="g35508"
+ style="opacity:0.65;display:inline;enable-background:new"
+ transform="translate(-41,41)">
+ <g
+ id="g35510"
+ transform="translate(21,21)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 174.5,40.5 0,3 3,0"
+ id="path35512" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35514"
+ style="fill:none;stroke:#2b2600;stroke-width:3;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"
+ d="m 175.5,42.5 5.75,-5.75" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,383,116)"
+ id="g35516">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.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="g35518">
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path35520"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35522"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;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"
+ d="m 85.6613,103.49999 6.25,-6.25" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,4 -1,0 0,-3 -3,0 0,-1 4,0 z"
+ id="path35524"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g35526"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b5a731;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path35528"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path35530"
+ d="m 161.5,95.5 3,3"
+ style="opacity:0.15;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#ffeeaa;stroke-width:5;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;filter:url(#filter30556);enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.25;fill:#ffdd55;fill-opacity:1;fill-rule:nonzero;stroke:#ffed55;stroke-width:4;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;filter:url(#filter30552);enable-background:accumulate"
+ d="m 161.5,94.5 4,4"
+ id="path35532"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path35534"
+ d="m 161.5,93.5 5,5"
+ style="fill:none;stroke:#5a5310;stroke-width:3.29999995;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:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#fbf7e5;stroke-width:1.60000002;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 161.5,93.5 5,5"
+ id="path35536"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <g
+ transform="translate(168,274.99999)"
+ id="g35538"
+ 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"
+ id="rect35540"
+ width="16"
+ height="16"
+ x="152"
+ y="113.00001" />
+ <g
+ id="g35542"
+ transform="translate(-21,21.000005)">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.12000002;fill:#fff6aa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30544);enable-background:accumulate"
+ d="m 177,94.75 c 0,0 -0.47556,3.774441 2.5,6.75 2.97556,2.97556 7,2.5 7,2.5 3.44436,-0.63991 2.99995,-3.42845 0.0937,-4.5 -1.83387,-3.557342 -2.66053,-4.290113 -5.09375,-5.09375 -0.64623,-3.372957 -3.91818,-2.771894 -4.5,0.34375 l 5e-5,0 z"
+ id="path35544"
+ sodipodi:nodetypes="cscccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.17000002;fill:#ffed55;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30580);enable-background:accumulate"
+ d="m 179.15625,93.71875 c 0,0 -0.3702,1.0264 -0.21875,2.1875 0.15145,1.1611 0.76936,2.613109 2.15625,4 1.38689,1.38689 2.8389,2.0048 4,2.15625 1.1611,0.15145 2.1875,-0.21875 2.1875,-0.21875 1.01828,-0.43147 1.49397,-1.60672 1.0625,-2.625 l -5.65501,-5.846474 c -1.32148,-1.409979 -2.40864,-0.889298 -3.53249,0.346474 z"
+ id="path35546"
+ sodipodi:nodetypes="cssscccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssscccc"
+ id="path35548"
+ d="m 179.15625,93.71875 c 0,0 -0.3702,1.0264 -0.21875,2.1875 0.15145,1.1611 0.76936,2.613109 2.15625,4 1.38689,1.38689 2.8389,2.0048 4,2.15625 1.1611,0.15145 2.1875,-0.21875 2.1875,-0.21875 1.01828,-0.43147 1.49397,-1.60672 1.0625,-2.625 l -5.65501,-5.846474 c -1.32148,-1.409979 -2.40864,-0.889298 -3.53249,0.346474 z"
+ style="opacity:0.18000004;fill:#fff6aa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30580);enable-background:accumulate"
+ transform="matrix(0.5121167,0,0,0.5121167,89.625148,47.477443)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#5a5310;stroke-width:3.0999999;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 176.5,93.5 c 0,0 5.75,-0.25 8.5,2.5 2.75,2.75 2.5,8.5 2.5,8.5"
+ id="path35550"
+ sodipodi:nodetypes="czs" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="czs"
+ id="path35552"
+ d="m 176.5,93.5 c 0,0 5.75,-0.25 8.5,2.5 3,3 2.5,8.5 2.5,8.5"
+ style="fill:none;stroke:#fbf7e5;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" />
+ </g>
+ <g
+ id="g35554"
+ style="opacity:0.65;display:inline;enable-background:new"
+ transform="translate(-42,63.000005)">
+ <g
+ id="g35556"
+ transform="translate(21,21)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 174.5,40.5 0,3 3,0"
+ id="path35558" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35561"
+ style="fill:none;stroke:#2b2600;stroke-width:3;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"
+ d="m 175.5,42.5 6.25,-6.25" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,383,116)"
+ id="g35563">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.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="g35566">
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path35568"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cz"
+ id="path35570"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;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"
+ d="m 85.6613,103.49999 7,-7" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,4 -1,0 0,-3 -3,0 0,-1 4,0 z"
+ id="path35572"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g35574"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b5a731;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path35576"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g36448"
+ transform="translate(41.84997,0.15003049)">
+ <g
+ transform="translate(105,416)"
+ id="g36297">
+ <g
+ id="g36211"
+ transform="translate(194.04507,17.48225)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36215"
+ d="m 90.45451,103.98095 0,7 7.00045,0.0368 0,-7 -7.00045,-0.0368 z"
+ style="opacity:0.8;fill:none;stroke:#333333;stroke-width:2.5;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:#cccccc;fill-opacity:0.15686275;fill-rule:evenodd;stroke:#e6e6e6;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 90.45451,103.98095 4.5e-4,7.03677 7,0 -4.5e-4,-7.03677 -7,0 z"
+ id="path36228"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="127.49997"
+ x="290.50015"
+ height="3"
+ width="2.9998772"
+ id="rect36230"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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="rect36232"
+ width="2.9998772"
+ height="3"
+ x="282.49982"
+ y="119.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="127.49997"
+ x="282.50015"
+ height="3"
+ width="2.9998772"
+ id="rect36234"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 293.0003,127.99997 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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 l 0,0 0,0 0,0 z"
+ id="path36237"
+ 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="path36239"
+ d="m 285.00045,128 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="path36241"
+ d="m 285,120 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;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="rect36243"
+ width="2.9998772"
+ height="3"
+ x="290.49988"
+ y="119.49997"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <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="path36245"
+ d="m 293.00003,119.99997 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 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 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </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="rect36312"
+ width="16"
+ height="16"
+ x="383"
+ y="535" />
+ <g
+ id="g36314"
+ transform="translate(334.99992,111)">
+ <rect
+ y="429.54614"
+ x="48.499996"
+ height="9.9538488"
+ width="10.000013"
+ id="rect36316"
+ style="fill:#ececec;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(#linearGradient36468);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36318"
+ width="9.0000706"
+ height="9.0003176"
+ x="49.000011"
+ y="430" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path36320"
+ d="m 49,430 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 m -6,3 0,-3 -3,0 0,3 3,0 z"
+ style="fill:url(#linearGradient36470);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" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36324"
+ d="m 57.50001,430.49999 -8.000011,10e-6 1.1e-5,7.99999 8,0 -1.1e-5,-7.99999"
+ style="fill:none;stroke:url(#linearGradient36472);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </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" />
+ <g
+ transform="translate(1,0)"
+ id="g35733">
+ <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" />
+ <g
+ transform="translate(179,-179)"
+ id="g35741">
+ <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" />
+ <path
+ 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="path35745"
+ inkscape:connector-curvature="0" />
+ </g>
+ <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" />
+ </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" />
+ <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" />
+ </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" />
+ <g
+ id="g35757"
+ transform="translate(1,0)">
+ <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" />
+ <g
+ id="g35765"
+ transform="translate(179,-179)">
+ <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" />
+ <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:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <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" />
+ </g>
+ <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" />
+ <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" />
+ </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">
+ <g
+ transform="translate(111,-158)"
+ id="g35778"
+ style="opacity:0.55;display:inline">
+ <rect
+ y="336"
+ x="-64"
+ height="16"
+ width="16"
+ id="rect35780"
+ 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="g35782"
+ transform="translate(1,0)">
+ <g
+ id="g35785"
+ transform="translate(-386,446.5)">
+ <path
+ 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="path35787" />
+ <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="path35789"
+ 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="g35791"
+ transform="translate(179,-179)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path35793"
+ 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="path35795"
+ 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"
+ id="path35797"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient36725);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="rect35799"
+ style="fill:url(#linearGradient36727);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35801"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient36729);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0.07999998;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-8"
+ width="3.0000007"
+ height="7.25"
+ x="54"
+ y="185" />
+ <g
+ id="g35818"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-1080.9861,-256)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffb769;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"
+ 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="path35822"
+ d="m 1136.4859,448.5 -6,-3.25 0,-7.5"
+ style="fill:none;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>
+ <g
+ transform="matrix(-1,0,0,1,532,25)"
+ id="g37386"
+ 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="rect37388"
+ width="16"
+ height="16"
+ x="343"
+ y="195" />
+ <g
+ 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(-2.196282,0,0,1.316799,1208.5661,-118.9575)"
+ id="g37390"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path37392"
+ d="m 392.96689,239.5639 -0.56915,0 -4.43932,4.36665 0,1.13912 4.43932,4.36665 0.56911,-1e-5 0,-9.87242 0,0 4e-5,1e-5 0,0 z"
+ style="fill:url(#linearGradient37396);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.58802557px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path37394"
+ d="m 392.51157,247.91748 0,-7.59417 -4.09783,3.98695 0,0.3797"
+ style="fill:none;stroke:url(#linearGradient37398);stroke-width:0.58802563px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ 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"
+ 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"
+ id="rect38783"
+ width="16"
+ height="16"
+ x="-259"
+ y="72" />
+ <path
+ sodipodi:nodetypes="csasc"
+ id="path38785"
+ d="m -257.5,83.5 2,0 c 2,0 2.50929,2 4,2 1.49071,0 2,-2 4,-2 l 2,0"
+ style="fill:none;stroke:#001c46;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" />
+ <path
+ style="fill:none;stroke:#aaccff;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 -257.5,83.5 2,0 c 2,0 2.50929,2 4,2 1.49071,0 2,-2 4,-2 l 2,0"
+ id="path38787"
+ sodipodi:nodetypes="csasc"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline;enable-background:new"
+ transform="matrix(1,0,0,-1,-235,265)"
+ id="g38789">
+ <path
+ transform="translate(-1,2)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;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 -16,180 0,6 -1,0 0,-1.75 -1,1.75 0,1.5 2,2.5 6,0 1,-2 0,-3.25 -0.75,-0.75 -0.25,0 0,1 -1,0 0,-1 -0.75,-0.75 -0.25,0 0,1.75 -1,0 0,-1.5 -0.75,-1 -0.25,0 0,2.5 -1,0 0,-5 -1,0 z"
+ id="path38791"
+ sodipodi:nodetypes="cccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g38794"
+ transform="translate(-1,2)">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccc"
+ id="path38796"
+ d="m -16,179.5 0,6.5 -1,0 0,-2 -0.25,0 -0.75,2 0,1.5 2,2.5 6,0 1,-2 0,-3.25 -0.75,-0.75 -0.25,0 0,1 -1,0 0,-1 -0.75,-0.75 -0.25,0 0,1.75 -1,0 0,-1.5 -0.75,-1 -0.25,0 0,2.5 -1,0 0,-5.5 -1,0 z"
+ style="fill:url(#linearGradient39048);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -15,187 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ id="path38799"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38801"
+ d="m -15,185 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -13,185 0,1 1,0 0,-1 -1,0 z"
+ id="path38803"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38805"
+ d="m -11,185 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient39050);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -18,186 0,1 1,0 0,-3 -0.25,0 -0.75,2 z"
+ id="path38807"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38810"
+ d="m -17.25,187.5 1.5,2 5.25,0 1,-2 0,-0.5"
+ style="fill:none;stroke:url(#linearGradient39052);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" />
+ <path
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -14.00935,182.77669 0,1 1,0 0,-1 -1,0 z"
+ id="path38819"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38821"
+ d="m -11.978216,183.55574 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -11.978216,183.55574 0,1 1,0 0,-1 -1,0 z"
+ id="path38823"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38825"
+ d="m -16,180 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g39803"
+ transform="translate(-66,268)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\sss.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="-27"
+ x="155"
+ height="16"
+ width="15.999955"
+ id="rect39805"
+ 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" />
+ <g
+ style="opacity:0.6;display:inline;enable-background:new"
+ id="g39807">
+ <path
+ style="fill:url(#linearGradient39835-9);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1;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:new"
+ d="m 157.5,-26.5 c -1.10457,0 -2,0.895431 -2,2 0,1.104569 0.89543,2 2,2 0.0211,0 0.0415,6.5e-4 0.0625,0 0.005,0.02296 0.0259,0.03977 0.0312,0.0625 -0.63487,0.174633 -1.09375,0.747145 -1.09375,1.4375 0,0.828426 0.67157,1.5 1.5,1.5 0.69036,0 1.26287,-0.45888 1.4375,-1.09375 0.18381,0.04305 0.36556,0.09375 0.5625,0.09375 1.38071,0 2.5,-1.119289 2.5,-2.5 0,-1.380711 -1.11929,-2.5 -2.5,-2.5 -0.25351,0 -0.48817,0.05484 -0.71875,0.125 -0.32553,-0.663426 -0.9924,-1.125 -1.78125,-1.125 l 5e-5,0 z"
+ id="path39809"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0,0.1250004,0.1250004,0,143.24995,-37.50005)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient39837-4);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path39811"
+ 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="path39813"
+ style="fill:url(#linearGradient39839-3);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0,0.25,0.2500001,0,130.49998,-56)" />
+ </g>
+ <g
+ transform="translate(45,-100)"
+ id="g39815">
+ <path
+ style="fill:#214478;stroke:none"
+ d="m 110.5,85.5 c 0,2.25 2,3 3.5,3 2.25,0 3.1933,-1.514034 4,-2.5 l 4.5,-5.5 3,0 0,-2 -4,0 -5.5,5.5 -1.25,-1.5 -3.25,0 -1,1 0,2 z"
+ id="path39817"
+ sodipodi:nodetypes="cszccccccccz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cszccccccccz"
+ id="path39819"
+ d="m 110.5,85.5 c 0,2.25 2,3 3.5,3 2.25,0 3.46788,-1.244422 4.25,-2.25 L 120,84 l -2,-2 -1.5,1.5 -1,0 0,-1 -1,-1 -3,0 -1,1 0,3 z"
+ style="fill:url(#linearGradient39841-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cszccccccccccccccccz"
+ id="path39821"
+ d="m 110.5,85 c 0,2.25 1.5,3.5 3.75,3.5 2.25,0 3.50071,-1.469729 4.25,-2.5 l 4,-5.5 0.5,0 0.5,0 1,0 1,0 0,-2 -1,0 -1.11272,0 -0.88728,0 -1,0 -5,5 -1,0 0,-1 -1,-1 -3,0 -1,1 0,2.5 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path39823"
+ d="m 118,83 1,0 0,1 1,0 0,-1 -1,0 0,-1 -1,0 0,1 z"
+ style="fill:url(#linearGradient39843-3);stroke-width:1px"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path39825"
+ d="m 111.5,82.5 0.75818,0.763059 1.5,0 0.75,-0.75"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="82"
+ x="112"
+ height="1"
+ width="2"
+ id="rect39827"
+ style="opacity:0.6;fill:#000000;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ y="83.5"
+ x="115"
+ height="1.4999981"
+ width="0.99994147"
+ id="rect39829"
+ style="opacity:0.4;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" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path39831"
+ d="m 124.5,79.5 -3,0 -5,5 -0.5,0"
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccsc"
+ id="path39833"
+ d="m 111.5,83.5 0,1.271428 c -0.0915,0.859266 0.18827,2.299909 2.00056,2.733557 3.70517,0.886581 6.00049,-3.943221 6.00049,-3.943221"
+ style="fill:none;stroke:url(#linearGradient39845-2);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-249,193)"
+ id="g41505"
+ style="display:inline">
+ <g
+ style="opacity:0.85"
+ id="g41507">
+ <rect
+ style="opacity:0.5;fill:url(#linearGradient41540);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41509"
+ width="7.8166504"
+ height="3"
+ x="-433.5"
+ y="82"
+ transform="scale(-1,1)" />
+ <rect
+ style="fill:url(#linearGradient41542);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41511"
+ width="8.9931746"
+ height="1"
+ x="-434"
+ y="83"
+ transform="scale(-1,1)" />
+ <rect
+ style="fill:#333333;fill-opacity:0.81960784;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41514"
+ width="2"
+ height="1"
+ x="-430.5"
+ y="83"
+ transform="scale(-1,1)" />
+ </g>
+ <g
+ id="g41613"
+ style="opacity:0.45">
+ <g
+ style="opacity:0.8"
+ id="g41516">
+ <rect
+ y="69"
+ x="422"
+ height="16"
+ width="16"
+ id="rect41518"
+ style="opacity:0.05;fill:url(#radialGradient41666);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41520">
+ <path
+ sodipodi:nodetypes="csscccc"
+ id="path41522"
+ d="m 422.51387,74.4375 c 2.14278,1.6383 5.29475,5.652 6.25,7.5625 0.5,1 1.05394,1.01957 1.5,0 0.875,-2 3.25,-4.75 4.75,-6 l -3.5,-4 c -1.25,1.83839 -2,3.25 -2.75,4.63304 -1.71617,-1.72583 -4.35859,-3.39262 -6.25,-4.13304"
+ style="fill:url(#linearGradient41668);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient41670);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" />
+ </g>
+ </g>
+ <g
+ id="g41524">
+ <g
+ id="g41526">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path41528"
+ d="m 422.51387,73.5 c 1.93909,0.815624 4.07262,1.664731 6,4 l 0.75,0 c 0.82427,-1.547027 1.51287,-2.596571 2.16161,-3.5"
+ style="fill:none;stroke:url(#linearGradient41672);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient41674);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 422.51387,73.5 c 1.93909,0.815624 5.41183,5.25 7,8 1.5,-3 2.75,-4 4.75,-6.25"
+ id="path41530"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient41676);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 428.5,78.5 c 0.95165,-1.519624 1.88025,-3.040081 2.92548,-4.5"
+ id="path41532"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient41582);fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:2.07584167;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="path32513-1"
+ 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.4336871,0,0,0.4334311,376.83381,21.772579)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient32529-7);stroke-width:3.1984036;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="path32517-6"
+ 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.3127677,0,0,0.3125443,475.3332,36.070149)" />
+ </g>
+ <g
+ transform="translate(-21.1375,-0.42)"
+ id="g42277">
+ <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" />
+ <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" />
+ </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"
+ transform="translate(41.834175,191.41501)">
+ <rect
+ y="364.58499"
+ x="47.165825"
+ height="16"
+ width="16"
+ id="rect38701"
+ 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"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.032664,0,0,1.043556,-79.760429,254.38542)"
+ id="g38703">
+ <path
+ transform="matrix(0.787566,0,0,0.779223,26.709197,21.3179)"
+ 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="path38705"
+ style="fill:#3771c8;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.22966909;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(0.666432,0,0,0.659342,42.69924,35.46375)"
+ 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:type="arc"
+ style="fill:url(#linearGradient38719);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path38707"
+ 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" />
+ <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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38709"
+ style="opacity:0.7;fill:url(#linearGradient38722);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ 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.3631382,0,0,0.3593485,81.755824,69.904768)" />
+ <path
+ transform="matrix(0.9688184,0,0,0.9547322,-131.63668,47.640696)"
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter13996)"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ id="path38711"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient38724);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 130.67404,112.3079 c 0.0244,0.78706 -0.15754,1.63085 0.59269,2.02213 0.71197,-0.0434 1.49133,0.64122 1.35667,1.40517 -0.26776,0.77861 0.14071,1.12325 0.95576,1.36401 0.57868,-0.0716 0.79053,-0.93546 0.87357,-1.36401 0.0948,-1.27121 0.51542,-1.09421 0.82108,-1.98991 -0.45733,-0.91502 -0.003,-1.04443 -0.72629,-1.43739 m -1.00945,-3.89288 c -0.4426,0.34378 -0.24372,1.04314 -0.66162,1.39841 -0.45372,0.13628 -0.78226,-0.0605 -1.16771,0.43164 -0.30841,1.10457 0.35004,1.22306 0.90205,1.10457 0.49538,-0.0502 0.61419,-0.94321 0.97928,-0.37853 0.0831,0.10976 0.71917,-0.0403 0.86266,0.18898 0.0669,0.10682 -0.11785,0.0255 -0.14729,0.18955 -0.0428,0.23847 0.27734,0.37341 0.372,0.3824 0.32089,0.0305 0.60005,0.92548 0.83846,1.05499 0,0.46738 0.0924,-0.6774 0.3515,-0.78703 0.22948,-0.0971 0.47929,0.10731 0.5,0 0.29928,-1.55081 -1.26113,-3.00604 -2.82933,-3.58498 z M 128.96474,107.5 c -0.6111,1.01384 0.85343,1.46103 1.73001,1.21329 0.57897,-0.37879 1.00716,-0.92331 0.55665,-1.21329 -0.20614,-0.1415 -2.07706,0.0431 -2.28666,0 l 0,0 0,0 0,0 z m -1.372,1.37253 c -0.49575,-0.14959 0.44952,-0.11945 0.45733,0.45751 0.1696,0.54756 -0.42801,0.23756 0,0.45752 0.70893,0.1644 0.35328,1.70031 -0.28114,1.56208 -0.56042,0.10119 -0.43915,0.95826 -1.64865,0.88279 -0.0836,0.0755 -1.04512,0.61593 -0.81421,1.21521 1.12968,0.30162 -0.36816,1.26478 -0.43867,0.55236 -0.15441,-0.49797 -0.62853,-1.11348 -0.43994,-1.68674 0.11734,-0.63627 0.5689,-1.12263 0.82646,-1.69865 0.36225,-0.61946 0.89084,-1.17688 1.57758,-1.42595 0.21411,-0.16799 0.46159,-0.41691 0.76124,-0.31613 l 0,0 0,0 0,0 z m -0.91467,5.03262 c -0.55163,-0.27585 -0.72934,0.28829 -0.60377,0.7984 0.15577,0.47138 0.52607,0.97695 0.72628,1.43739 0.40435,0.49619 1.512,1.34081 2.17883,1.67696 0.31768,0.16015 0.48418,0 0.24209,-0.23956 -0.31367,-0.6375 -1.14073,-1.94893 -0.48418,-2.15609 0.59647,-0.60342 0.34203,-1.58773 -0.48419,-1.43739 -0.54779,-0.25818 -0.75551,-0.39899 -1.38855,-0.0752 -0.0558,0.0743 -0.12403,0.006 -0.18651,-0.004 l 0,-5.1e-4 0,0 0,0 z"
+ id="path38713"
+ sodipodi:nodetypes="ccccccccccccssscsscccscccccccccccccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.6657538,0,0,0.6588051,42.794535,35.527157)"
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient38726);stroke-width:1.45454657;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path38715"
+ 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
+ transform="matrix(0.06052282,0,0,0.05989117,121.21686,103.80334)"
+ 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:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path38717"
+ 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" />
+ </g>
+ </g>
+ <g
+ transform="translate(179.00003,444.99999)"
+ id="g37955"
+ style="display:inline">
+ <rect
+ y="90"
+ x="162"
+ height="16"
+ width="16"
+ id="rect37957"
+ 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="96.749977"
+ x="165.74995"
+ height="1.75"
+ width="2.5"
+ id="rect37959"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;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
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,2.75 -5.99999,3.24999 -6.00001,-3.24999 0,-2.75 z"
+ id="path37961"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.96000001;fill:none;stroke:#1a1a1a;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"
+ id="rect37963"
+ width="2"
+ height="7"
+ x="170.98643"
+ y="91.999977" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 0,-0.56558 z"
+ id="path37965"
+ 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="path37967"
+ d="m 164.99997,101.74998 -1e-5,-2.25 6,3 0.01,2.49885 -6.00995,-3.24885 -4e-5,0 0,0 0,0 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ 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:#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 176.99996,101.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path37969"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="97.999977"
+ x="165.99995"
+ height="1"
+ width="2"
+ id="rect37971"
+ style="fill:#aa0000;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:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37973"
+ width="2"
+ height="1"
+ x="165.99995"
+ y="96.999977" />
+ <rect
+ y="96.999977"
+ x="165.99995"
+ height="2"
+ width="1"
+ id="rect37975"
+ style="opacity:0.5;fill:#ffaaaa;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:url(#linearGradient38005);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 165.49996,99.49998 0,0 0,2 5.5,3 5.5,-3 0,-2"
+ id="path37977"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37979"
+ transform="translate(-114.00004,-232.99999)">
+ <rect
+ y="328.03571"
+ x="285"
+ height="3.9642856"
+ width="2"
+ id="rect37981"
+ style="opacity:0.3;fill:none;stroke:#1a1a1a;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" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#550000;stroke-width:0.59999985;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="path37983"
+ sodipodi:cx="286"
+ 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"
+ transform="matrix(1.6666708,0,0,1.6666633,-190.66784,-215.66559)" />
+ <rect
+ y="328.49997"
+ x="285"
+ height="3.5000324"
+ width="2"
+ id="rect37985"
+ style="fill:#b3b3b3;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:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37987"
+ width="1"
+ height="3.5000324"
+ x="285"
+ 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"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="325"
+ sodipodi:cx="286"
+ id="path37989"
+ style="fill:url(#linearGradient38007);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.59999985;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <rect
+ style="opacity:0.5;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="rect37991"
+ width="1"
+ height="1"
+ x="284"
+ y="331" />
+ <rect
+ y="332"
+ x="285"
+ height="1"
+ width="2"
+ id="rect37993"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="331"
+ x="287"
+ height="1"
+ width="1"
+ id="rect37995"
+ style="opacity:0.5;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>
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 165.49996,98.99998 5.5,2.75"
+ id="path37997"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37999"
+ mask="url(#mask20957)">
+ <path
+ style="opacity:0.7;fill:none;stroke:#1a1a1a;stroke-width:2.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 168.25,102.75 -0.75,0.75 c -1,1 -0.75,1 -2,1 l -2.25,0"
+ id="path38001"
+ sodipodi:nodetypes="cccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path38003"
+ d="m 168.25,102.75 -0.75,0.75 c -1.25,1.17188 -0.75,1 -2,1 l -3,0"
+ style="fill:none;stroke:#ececec;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ 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"
+ transform="translate(588,446)">
+ <rect
+ y="26"
+ x="-79"
+ height="16"
+ width="16"
+ id="rect43390-2"
+ style="opacity:0;fill:#999999;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="g43392-4"
+ clip-path="url(#clipPath43368-1)">
+ <rect
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;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"
+ id="rect43394-5"
+ width="6"
+ height="2"
+ x="-72.5"
+ y="31.5"
+ rx="0.79505396"
+ ry="0.79505396" />
+ <rect
+ ry="0.79505396"
+ rx="0.79505396"
+ y="28.5"
+ x="-75.5"
+ height="2"
+ width="6"
+ id="rect43396-5"
+ style="fill:#6996d7;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;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" />
+ <rect
+ style="fill:#6996d7;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;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"
+ id="rect43398-1"
+ width="6"
+ height="2"
+ x="-75.5"
+ y="36.5"
+ rx="0.74381745"
+ ry="0.74381745" />
+ <rect
+ ry="0.71819919"
+ rx="0.71819919"
+ y="39.5"
+ x="-72.5"
+ height="2"
+ width="6"
+ id="rect43400-7"
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;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" />
+ <path
+ id="path43402-1"
+ style="fill:none;stroke:#000000;stroke-width:2.9000001;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43404-1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path43406-5"
+ style="opacity:0.4;fill:none;stroke:url(#radialGradient43410-4);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="opacity:0.4;fill:none;stroke:url(#radialGradient43412-8);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43408-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(273,441)"
+ id="g40240">
+ <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"
+ d="M 52.75,44.25 62.5,34.5 c 0,-1 -0.5,-1.5 -1,-2 -0.498692,-0.498692 -1,-1 -2,-1 l -9.75,9.75 c 1,0 1.501308,0.501308 2,1 0.5,0.5 1,1 1,2 z"
+ sodipodi:nodetypes="ccsccsc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="31"
+ x="47"
+ height="16"
+ width="16"
+ id="rect40244"
+ style="opacity:0.01000001;fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <path
+ sodipodi:nodetypes="ccsccc"
+ d="M 60.75,36.25 62.5,34.5 c 0,-1 -0.5,-1.5 -1,-2 -0.498692,-0.498692 -1,-1 -2,-1 l -1.75,1.75 3,3 z"
+ style="fill:url(#linearGradient40270);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40246"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m 57.5,35.5 -1,-1 -6.75,6.75 1.75,0.25 6,-6 z"
+ style="fill:#bcd35f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40248"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40250"
+ style="fill:#445016;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 59.5,37.25 -1,-0.75 -6,6 0.25,1.5 6.75,-6.75 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path40252"
+ d="m 59.75,37.25 -3,-3"
+ style="fill:none;stroke:url(#linearGradient40272);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40274);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 60.75,36.25 -3,-3"
+ id="path40254"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient40276);fill-opacity:1;stroke-width:1px"
+ d="m 57.75,33.25 2.98375,3.003125 -1.0075,1.0075 -3.0225,-2.98375 L 57.75,33.25 z"
+ id="path40256"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#501616;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 61,36 1.5,-1.5 c 0,-1 -0.5,-1.5 -1,-2 -0.498692,-0.498692 -1,-1 -2,-1 L 58,33"
+ id="path40258"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path40260"
+ d="M 58.25,32.75 50,41 l -2,4 -0.5,0.5 0.25,0.75 0.75,0.25 0.5,-0.5 4,-2 8.25,-8.25"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccsc"
+ id="path40262"
+ d="M 50.25,41 48.5,44.25 49.75,45.5 53,43.75 C 53,43.25 52.5,42.5 52,42 51.501308,41.501308 50.75,41 50.25,41 z"
+ style="fill:url(#linearGradient40278);fill-opacity:1;stroke-width:1px"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#445016;stroke:#22280b;stroke-width:2.4000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 48.25,45.75 0.5,-0.5"
+ id="path40264"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path40266"
+ d="M 48.25,45.75 48.5,45.5"
+ style="fill:none;stroke:#9ab432;stroke-width:1.10000002;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round"
+ d="M 52.527427,43.527587 61.514313,34.48568"
+ id="path40268"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40603-2"
+ transform="translate(238,594)">
+ <rect
+ y="-122"
+ x="-44"
+ height="16"
+ width="16"
+ id="rect40445-4"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40447-5"
+ d="m -43.5,-116.75 12.5,-4.75 0.75,2 -13.25,5 0,-2.25 z"
+ style="fill:#1a1a1a;stroke:#000000;stroke-width:0.89999998;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-114.5"
+ x="-42.5"
+ height="7.9999971"
+ width="12.999988"
+ id="rect40449-5"
+ style="fill:url(#linearGradient39686-1);fill-opacity:1;fill-rule:nonzero;stroke:#000000;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" />
+ <rect
+ style="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"
+ id="rect40451-1"
+ width="1"
+ height="1.5"
+ x="-32"
+ y="-121" />
+ <rect
+ y="-119.41868"
+ x="-36"
+ height="1.5"
+ width="1"
+ id="rect40453-7"
+ style="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" />
+ <rect
+ style="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"
+ id="rect40455-1"
+ width="1"
+ height="1.5"
+ x="-37"
+ y="-119.16868" />
+ <rect
+ y="-117.62802"
+ x="-41"
+ height="1.5"
+ width="1"
+ id="rect40457-1"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;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:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40459-5"
+ width="1"
+ height="1.5"
+ x="-40"
+ y="-117.87802" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#000000;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"
+ id="rect40461-2"
+ width="13.999996"
+ height="2.0000052"
+ x="-43.5"
+ y="-114.5" />
+ <rect
+ y="-113"
+ x="-42"
+ height="1.7500292"
+ width="12.154154"
+ id="rect40490-7"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="rect40463-6"
+ d="m -40,-114 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z"
+ style="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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round"
+ d="m -31.5,-120.5 -9.75,3.75"
+ id="path40474-1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient39688-9);stroke-width:1px;stroke-linejoin:round"
+ d="m -41.5,-107.5 0,-6 11,0 0,6 -11,0 z"
+ id="path40476-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#87aade;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 -43,-116.75 1,0 1,1.75 0,2 -2,0 0,-3.75 z"
+ id="path40478-2"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#002255;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 -41,-115 0,2 -2,0 0,0.75 2.75,0 0,-3 -1.25,-2.25 -1.5,0.25 0,0.5 1,0 1,1.75 z"
+ id="path40480-3"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40558-2"
+ d="m -41.5,-107.38206 0,-4.66445"
+ style="opacity:0.2;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="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"
+ id="rect40553-2"
+ width="1"
+ height="1.5"
+ x="-33"
+ y="-120.75" />
+ <rect
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40556-1"
+ width="1"
+ height="1.25"
+ x="-40"
+ y="-114" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ d="m -42.4975,-113.46527 0,-3.0928"
+ id="path40560-6"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(1,0)"
+ style="opacity:0.35"
+ id="g40590-8">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40586-5"
+ width="5"
+ height="0.9617852"
+ x="-38"
+ y="-110" />
+ <rect
+ y="-111"
+ x="-36"
+ height="3"
+ width="1.0280838"
+ id="rect40588-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ transform="translate(56,-67)"
+ id="g42945"
+ style="display:inline;enable-background:new">
+ <rect
+ y="602"
+ x="327"
+ height="16"
+ width="16"
+ id="rect42947"
+ 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="g42949">
+ <g
+ style="opacity:0.85"
+ id="g42951">
+ <path
+ style="fill:#e6e6e6;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 341.5161,616.38229 340.5,617.5 l -10.73389,-10e-6 -1.25,-1.25 L 328.5,605.5 l 13,0 0.0161,10.88229 z"
+ id="path42953"
+ 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
+ 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="path42955"
+ d="m 340,616 -8.25,0 0,-1 8.25,0 0,1 z"
+ style="fill:#999999;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" />
+ <rect
+ style="opacity:0.2;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="rect38927"
+ width="11.970581"
+ height="8.0306396"
+ x="329.02942"
+ y="605.96936" />
+ <rect
+ y="605.96936"
+ x="329.02942"
+ height="8.0306396"
+ width="11.970581"
+ id="rect45307"
+ style="opacity:0.3;fill:url(#radialGradient45309);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: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="path42957"
+ d="m 340.48389,606.50001 c -3.66204,-3e-5 -7.70403,2e-5 -10.98389,-10e-6 l 0.002,10.00007 10.99778,-7e-5 -0.0161,-9.99999 2.1e-4,0 z"
+ style="fill:none;stroke:url(#linearGradient42965-7);stroke-width:0.99999923px;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="ccccc"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="615"
+ x="330"
+ height="1.0000043"
+ width="1"
+ id="rect42959"
+ 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" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.35;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"
+ d="m 340.5,614 -11,0 0,-1 11,0 0,1 z"
+ id="path38929"
+ 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.25;fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter24186-3-2)"
+ d="m 337.7,606.7 0,2.75 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.75 2,0 z"
+ id="path42961"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path42963"
+ d="m 333.75,602.5 1.75,0 c 0,0 0,2 0,2 l 2,0 0,-2 1.75,0 0.25,0.25 0,2.5 -2,1.5 0,2.5 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.5 -2,-1.5 0,-2.5 0.25,-0.25 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:url(#linearGradient42967-6);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </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" />
+ <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">
+ <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.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-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">
+ <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="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)" />
+ </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"
+ height="16"
+ width="16"
+ id="rect41249"
+ 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="g41251"
+ 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)"
+ style="opacity:0.8;display:inline">
+ <g
+ style="display:inline"
+ id="g41253"
+ 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">
+ <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="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"
+ 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"
+ id="path41257"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <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.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">
+ <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"
+ 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"
+ 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
+ id="path41264"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g40887">
+ <g
+ id="g40668">
+ <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="rect39989"
+ width="16"
+ height="16"
+ x="215"
+ y="472"
+ rx="0"
+ ry="0" />
+ <g
+ id="g40555">
+ <rect
+ ry="1.7356256"
+ y="475.5"
+ x="215.5"
+ height="11.000039"
+ width="14.000015"
+ id="rect39993"
+ style="fill:url(#linearGradient40918);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
+ sodipodi:nodetypes="ccccccccc"
+ id="path39996"
+ d="m 216.00001,479.40741 0,4.59259 c 0,0.56404 0.36784,1.00001 0.84375,1 l 11.3125,0 c 0.47591,0 0.84375,-0.43595 0.84375,-1 l 0,-4.59259 C 228.6863,479.7792 228.23078,480 227.75001,480 l -10.5,0 c -0.48077,0 -0.93629,-0.2208 -1.25,-0.59259 z"
+ style="fill:url(#linearGradient40920);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="rect39999"
+ width="14.000005"
+ height="2.0000522"
+ x="215.5"
+ y="475.5"
+ ry="0.8750208" />
+ <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="rect40001"
+ width="14.000006"
+ height="10.999848"
+ x="215.5"
+ y="475.5"
+ ry="1.503511"
+ rx="1.503511" />
+ <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="path40005"
+ 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.3955004,0,0,1.2452423,115.18334,-141.72474)" />
+ <rect
+ rx="0.5078125"
+ ry="0.4910686"
+ y="476.5"
+ x="216.5"
+ height="9.0000038"
+ width="12.000035"
+ id="rect40008"
+ 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,100.49326,-321.69208)"
+ 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="path40010"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:0.62952662;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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient40922);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="path40012"
+ 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.1794014,0,0,0.8999954,131.50687,28.952303)" />
+ <path
+ transform="matrix(1.1827463,0,0,1.2,131.2458,-119.90002)"
+ 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="path40014"
+ 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(#linearGradient40924);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="path40016"
+ 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.790122,0,0,0.787736,161.87049,87.05649)" />
+ <path
+ transform="matrix(0.5963773,0,0,0.2000006,171.47609,375.5997)"
+ 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="path40020"
+ 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" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1;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 216.48394,475.5 0,-0.50001 c 0,-0.276 0.67629,-0.5 1.50958,-0.5 0.83329,0 1.50958,0.224 1.50958,0.5 l 0,0.50001"
+ id="path40022"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="475"
+ x="217"
+ height="1"
+ width="2"
+ id="rect40024"
+ 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="477"
+ x="226"
+ height="1"
+ width="2"
+ id="rect40026"
+ 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(#radialGradient40926);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40028"
+ width="2"
+ height="1"
+ x="226"
+ y="477" />
+ <rect
+ y="478"
+ x="218"
+ height="1"
+ width="1"
+ id="rect40030"
+ 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" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient40928);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="path40032"
+ 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,131.2458,-119.90002)" />
+ <path
+ transform="matrix(0.8888868,0,0,0.8862026,154.16683,37.626266)"
+ 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="path40034"
+ style="fill:url(#radialGradient40930);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
+ 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="path40036"
+ 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.1975308,0,0,0.1999991,207.09261,381.10045)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#radialGradient40932);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40043"
+ 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.8867575,0.06148883,-0.06130315,-0.8840797,323.44127,921.51187)" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.9986805,0,0,1,-92.569205,199)"
+ id="g25007-8"
+ style="display:inline;enable-background:new">
+ <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-2"
+ 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-4"
+ 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
+ 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-5"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ 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-5"
+ d="m 318.48945,276 1.25165,-0.25 1.50199,0 1.25162,0.25001 0,1.00005 -1.25162,0.24994 -1.50199,0 -1.25165,-0.24995 0,-1.00005 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 319.99139,278.50006 -0.25029,-1.25006 0,-1.5 0.2503,-1.25 1.00137,0 0.25032,1.25 0,1.5 -0.25033,1.25006 -1.00137,0 0,0 0,0 0,0 z"
+ id="path25015-1"
+ 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>
+ </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">
+ <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"
+ width="16"
+ height="16"
+ x="109"
+ y="472" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient36549);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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 110.5,472.5 13.98222,2e-5 0,14.96443 -13.98222,-2e-5 0,-14.96443 z"
+ id="path36516"
+ 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="path36518"
+ d="m 111.49999,485.48369 0,-11.00155 10.99999,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.9999997px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:url(#radialGradient36551);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 112,474 11,0 0,11 -11,0 0,-11 z"
+ id="path36521"
+ 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" />
+ <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="path36523"
+ d="m 112.5,474.5 9.98224,0 0,10 -9.98224,0 0,-10 z"
+ style="fill:url(#linearGradient36553);fill-opacity:1;fill-rule:evenodd;stroke:#808080;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" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#4d4d4d;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 112.5,484.5 0,-10 9.98224,0"
+ id="path36525"
+ 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="ccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g39496">
+ <path
+ transform="matrix(0.2498674,0,0,0.249916,83.518554,451.9933)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient36555);stroke-width:4.00173378;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36527"
+ 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
+ sodipodi:nodetypes="cccsccc"
+ id="path36529"
+ d="m 119,475.50001 c -1.44825,0 -1.50029,0.42731 -1.50029,0.85462 l 2.2e-4,4.27306 c 0,0.85461 0.052,0.85461 1.50029,0.85461 1.44823,0 1.49984,0.0467 1.49984,-0.85461 l 0,-4.27306 c 0,-0.42731 -0.0518,-0.85462 -1.50006,-0.85462 z"
+ style="fill:url(#linearGradient36557);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" />
+ <path
+ style="fill:none;stroke:url(#linearGradient36559);stroke-width:0.80000001;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 118.99995,475.50001 c -1.44821,0 -1.50025,0.42731 -1.50025,0.85461 l 2.2e-4,4.27306 c 0,0.85462 0.052,0.85462 1.50025,0.85462 1.44821,0 1.49982,0.0467 1.49982,-0.85462 l 0,-4.27306 c 0,-0.4273 -0.0518,-0.85461 -1.50004,-0.85461 z"
+ id="path36531"
+ sodipodi:nodetypes="cccsccc"
+ 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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path36533"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.1876323,0,0,0.1876688,91.733582,459.33847)" />
+ <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="path36535"
+ style="fill:#ffffff;stroke:url(#linearGradient36561);stroke-width:12.91347408;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.1154571,0,0,0.1168626,101.25809,467.69987)" />
+ <g
+ style="opacity:0.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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path36539"
+ style="opacity:0.15;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffdd55;stroke-width:0.87499446;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:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:#ffd42a;stroke-width:1.74999654;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="path36541"
+ sodipodi:cx="464.5"
+ 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"
+ transform="matrix(0.5714297,0,0,0.5714297,-150.92912,366.49979)" />
+ <rect
+ y="476"
+ x="113.99994"
+ height="1"
+ width="1"
+ id="rect36543"
+ 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:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36545"
+ width="2"
+ height="1"
+ x="118"
+ y="476" />
+ <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="path36547"
+ style="fill:none;stroke:url(#linearGradient36563);stroke-width:4.00173378;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.2498674,0,0,0.249916,83.518554,451.9933)" />
+ </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"
+ transform="translate(-369,-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"
+ 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);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);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"
+ 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);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path39245"
+ 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"
+ 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"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39251"
+ d="m 757.5,206.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient39260);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-705,268)"
+ id="g36639"
+ 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"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path36641"
+ 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
+ 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="path36643"
+ 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(#radialGradient36659);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" />
+ <path
+ id="path36646"
+ style="fill:none;stroke:url(#linearGradient36661);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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36649"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path36653"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient36663);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path36655"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g37112"
+ transform="translate(-42,0)">
+ <g
+ transform="matrix(-1,0,0,1,887,548.02778)"
+ style="opacity:0.8;display:inline;enable-background:new"
+ id="g36742">
+ <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="rect36744"
+ width="16"
+ height="16"
+ x="488"
+ y="29" />
+ <g
+ id="g36746">
+ <path
+ sodipodi:nodetypes="csccccccccsssc"
+ id="path36748"
+ d="m 500.5,34.5 0,5 c 0,1.666667 0.25,1.75 1,3.25 l -1.25,1.75 -1.75,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -1,0 C 491,43 490.5,42.416667 490.5,40.75 l 0,-6.25 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ style="fill:url(#linearGradient37132);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" />
+ <path
+ d="m 495.5,30.375 c -2.28774,0 -4.125,1.837258 -4.125,4.125 l 0,6.25 c 0,0.74605 0.0978,1.170828 0.28125,1.625 0.13101,0.324408 0.38353,0.789244 0.625,1.25 l 0.0937,0 1.5,-1.5 a 0.87292083,0.87292083 0 0 1 1.25,0 l 1.375,1.375 1.375,-1.375 a 0.87292083,0.87292083 0 0 1 1.1875,-0.03125 l 1.375,1.21875 0.1875,-0.1875 0,-0.4375 C 500.24057,42.152166 499.91254,41.661109 499.78125,41.125 499.62101,40.470677 499.625,39.833334 499.625,39 l 0,-4.5 c 0,-2.287742 -1.83726,-4.125 -4.125,-4.125 z"
+ id="path36750"
+ style="fill:none;stroke:url(#linearGradient37134);stroke-width:1;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:original="M 495.5 29.5 C 492.74 29.5 490.5 31.74 490.5 34.5 L 490.5 40.75 C 490.5 42.416667 491 43 491.75 44.5 L 492.75 44.5 L 494.5 42.75 L 496.25 44.5 L 496.75 44.5 L 498.5 42.75 L 500.5 44.5 L 501.5 43.5 L 501.5 42.5 C 500.5 41.25 500.5 40.666667 500.5 39 L 500.5 34.5 C 500.5 31.74 498.26 29.5 495.5 29.5 z "
+ inkscape:radius="-0.87283355"
+ sodipodi:type="inkscape:offset" />
+ <g
+ style="opacity:0.25;fill:#000000"
+ id="g36752">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ d="m 493,43.75 c 0,-0.212963 0,-5.75 0,-5.75 l 1.5,4.472222 L 493,43.75 z"
+ id="path36754"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36756"
+ d="m 497,44 c 0,-0.203703 -1,-6 -1,-6 l 2,3.428571 0,1.714286 L 497,44 z"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,990,0.25)"
+ id="g36758"
+ style="opacity:0.7;fill:#ffffff">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36760"
+ d="m 493,43.75 c 0,-0.212963 1,-6 1,-6 l 1,5 -1,1 -1,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 497,43.75 c 0,-0.203703 0,-6 0,-6 l 2,5 -1,1 -1,0 z"
+ id="path36762"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 490,43.25 c 0,-0.212963 1.5,-6.25 1.5,-6.25 l 0.5,5.5 -2,0.75 z"
+ id="path36764"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ 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"
+ d="m 500.5,34.5 0,4.5 c 0,1.666667 0,2.25 1,3.5 l 0,1 -1,1 -2,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -0.5,0 C 491,43 490.5,43.166667 490.5,41.5 l 0,-7 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ id="path36766"
+ sodipodi:nodetypes="cscccccccccsssc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36768"
+ d="m 56,139 0,1 -1,0 0,1 2,0 0,-2 -1,0 z"
+ style="opacity:0.8;fill:url(#linearGradient37136);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:url(#linearGradient37138);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 51,139 0,2 2,0 0,-1 -1,0 0,-1 -1,0 z"
+ id="path36770"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.65;fill:#000000;fill-rule:evenodd;stroke:#2b0000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 385.5,578.5 12,12"
+ id="path36738"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36740"
+ d="m 385.5,578.5 12,12"
+ style="fill:none;stroke:#ff5555;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:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(87.000001,33.999969)"
+ id="g37053"
+ 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">
+ <rect
+ y="459.00003"
+ x="-61.000011"
+ height="16"
+ width="16"
+ id="rect37055"
+ 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" />
+ <g
+ transform="matrix(0.9778614,0.2092535,-0.2092535,0.9778614,137.19272,32.846168)"
+ style="display:inline;enable-background:new"
+ id="g37057"
+ inkscape:transform-center-x="6.529123"
+ inkscape:transform-center-y="4.2273311">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;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 -98.435716,459.41623 9.935716,0.0838 0,10.99997 -9.935716,-0.0838 0,-10.99997 z"
+ id="path37059"
+ 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" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.8656081"
+ inkscape:original="M -98.4375 459.40625 L -98.4375 470.40625 L -88.5 470.5 L -88.5 459.5 L -98.4375 459.40625 z "
+ style="fill:url(#linearGradient37089);fill-opacity:1;fill-rule:evenodd;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="path37061"
+ d="m -97.5625,460.28125 0,9.25 8.1875,0.0937 0,-9.25 -8.1875,-0.0937 z" />
+ </g>
+ <g
+ id="g37063"
+ style="display:inline;enable-background:new"
+ transform="translate(38.999989,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="path37065"
+ d="m -99.499989,459.50003 10.999989,-10e-6 0,10.99997 -10.999989,10e-6 0,-10.99997 z"
+ style="fill:#ffffff;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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:url(#linearGradient37091);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0;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 -97.999989,461 7.99998,0 0,8 -7.99998,0 0,-8 z"
+ id="path37067"
+ 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
+ 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"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path37069"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#d4aa00;stroke-width:1.74999654;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: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"
+ id="path37071"
+ d="m -98.49992,460.49999 9.00002,0 0,9.00003 -9.00002,0 0,-9.00003 z"
+ style="fill:none;stroke:url(#linearGradient37093);stroke-width:0.99999952px;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="fill:#ffe680;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37073"
+ width="1"
+ height="1"
+ x="-98"
+ y="461" />
+ <rect
+ y="461.5"
+ x="-94.500008"
+ height="5"
+ width="3"
+ id="rect37075"
+ style="fill:url(#linearGradient37096);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:none;stroke:url(#linearGradient37098);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"
+ id="rect37077"
+ width="3"
+ height="5"
+ x="-94.500008"
+ y="461.5"
+ rx="0.46547449"
+ ry="0.46547449" />
+ <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="rect37079"
+ width="2"
+ height="1"
+ x="-94.000008"
+ y="462" />
+ <path
+ transform="matrix(0.1904433,0,0,0.1904803,-120.13881,444.5233)"
+ sodipodi:type="arc"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#4d4d4d;stroke-width:5.25039816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path37081"
+ 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" />
+ <rect
+ ry="0.46547449"
+ rx="0.46547449"
+ y="461.5"
+ x="-94.500008"
+ height="5"
+ width="3"
+ id="rect37083"
+ style="fill:none;stroke:url(#linearGradient37100);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" />
+ <path
+ transform="matrix(0.07365497,0,0,0.07463961,-104.72475,458.19728)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37102);stroke-width:20.23044777;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path37085"
+ 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="path37087"
+ style="fill:none;stroke:url(#linearGradient37104);stroke-width:5.25039816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.1904433,0,0,0.1904803,-120.13881,444.5233)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37514"
+ transform="translate(-327.01257,-130.96121)">
+ <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="path37516"
+ d="m 757.01257,204.46121 9.48743,0.0388 0,14.99999 -13,0 0.0126,-11.53879 3.5,-3.5 -3e-5,0 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37518"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <g
+ id="g37520">
+ <rect
+ style="fill:#e9afaf;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37522"
+ width="9.9999914"
+ height="12"
+ x="-83"
+ y="94" />
+ <rect
+ y="101"
+ x="-83"
+ height="4.9999976"
+ width="9.9999924"
+ id="rect37524"
+ style="opacity:0.5;fill:#4b7fcd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="94"
+ x="-83"
+ height="6.8499999"
+ width="9.9999914"
+ id="rect37526"
+ style="opacity:0.3;fill:url(#radialGradient37553);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path37528"
+ d="m -83,100.00002 1,0 1,0.74999 1,-0.74999 1,0.99999 2,0 1.5,-0.75 1.5,0.75 0.999991,0 L -73,102 l -9.999991,0 -9e-6,-1.99998 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37530"
+ width="2.0000029"
+ height="2.0000038"
+ x="-77"
+ y="96" />
+ <path
+ style="opacity:0.3;fill:#2b0000;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 -83,102 10,0 0,1 -10,0 0,-1 z"
+ id="path37532"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37534"
+ d="m -77,102 2.000003,0 -0.750003,4 -0.5,0 -0.75,-4 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g37536"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37538"
+ d="m -82.5,105.5 0,-11 9,0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -82.5,105.5 0,-11 9,0 0,11 -9,0 z"
+ id="path37540"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:url(#radialGradient37555);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 757.51257,204.46121 9,1e-5 0,14.99999 -13,0 0,-11 4,-4 z"
+ id="path37542"
+ 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.51257,209.96121 754.5,218.5 M 759.01257,205.46121 765.5,205.5"
+ style="opacity:0.1;fill:none;stroke:url(#linearGradient37558);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path37544"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753.01257,208.96121 5,0 0,-5 -5,5 z"
+ id="path37546"
+ 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.51257,207.96121 753.5,219.5 l 13,0 0,-14.99999 -9.48743,-0.0388 -3.5,3.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="path37549"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37551"
+ d="m 758.51257,206.46121 0,3 -3,0"
+ style="fill:none;stroke:url(#linearGradient37561);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37514-4"
+ transform="translate(-726.01257,268.03879)">
+ <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="path37516-1"
+ d="m 757.01257,204.46121 9.48743,0.0388 0,14.99999 -13,0 0.0126,-11.53879 3.5,-3.5 -3e-5,0 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37518-1"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <g
+ id="g37520-3">
+ <rect
+ style="fill:#ebb5b5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37522-8"
+ width="9.9999914"
+ height="12"
+ x="-83"
+ y="94" />
+ <rect
+ y="101"
+ x="-83"
+ height="4.9999976"
+ width="9.9999924"
+ id="rect37524-7"
+ style="opacity:0.5;fill:#4b80cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="94"
+ x="-83"
+ height="6.8499999"
+ width="9.9999914"
+ id="rect37526-4"
+ style="opacity:0.3;fill:url(#radialGradient37553-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path37528-2"
+ d="m -83,100.00002 1,0 1,0.74999 1,-0.74999 1,0.99999 2,0 1.5,-0.75 1.5,0.75 0.999991,0 L -73,102 l -9.999991,0 -9e-6,-1.99998 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37530-7"
+ width="2.0000029"
+ height="2.0000038"
+ x="-77"
+ y="96" />
+ <path
+ style="opacity:0.3;fill:#280b0b;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 -83,102 10,0 0,1 -10,0 0,-1 z"
+ id="path37532-7"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37534-9"
+ d="m -77,102 2.000003,0 -0.750003,4 -0.5,0 -0.75,-4 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g37536-3"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37538-1"
+ d="m -82.5,105.5 0,-11 9,0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -82.5,105.5 0,-11 9,0 0,11 -9,0 z"
+ id="path37540-9"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:url(#radialGradient37555-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 757.51257,204.46121 9,1e-5 0,14.99999 -13,0 0,-11 4,-4 z"
+ id="path37542-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:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="M 754.51257,209.96121 754.5,218.5 M 759.01257,205.46121 765.5,205.5"
+ style="fill:none;stroke:url(#linearGradient37558-8);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path37544-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753.01257,208.96121 5,0 0,-5 -5,5 z"
+ id="path37546-5"
+ 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.51257,207.96121 753.5,219.5 l 13,0 0,-14.99999 -9.48743,-0.0388 -3.5,3.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="path37549-0"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37551-2"
+ d="m 758.51257,206.46121 0,3 -3,0"
+ style="fill:none;stroke:url(#linearGradient37610-3);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-167.99999,190.99999)"
+ id="g71820">
+ <rect
+ y="365"
+ x="215"
+ height="16"
+ width="16"
+ id="rect71822"
+ 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(167.99999,-62.999991)"
+ id="g71824">
+ <rect
+ ry="0"
+ style="fill:#ececec;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="rect71826"
+ width="13.016124"
+ height="12.953857"
+ x="48.499996"
+ y="429.54614" />
+ <rect
+ y="430"
+ x="50.016117"
+ height="11.046139"
+ width="11.000001"
+ id="rect71828"
+ style="fill:url(#linearGradient71834);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
+ style="fill:url(#linearGradient71836);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 49,430 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,0 0,3 3,0 0,-3 -3,0 z m 0,3 -3,0 0,3 3,0 0,-3 z m 0,3 0,3 3,0 0,-3 -3,0 z m -3,0 -3,0 0,3 3,0 0,-3 z m -3,0 0,-3 -3,0 0,3 3,0 z"
+ id="path71830"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient71838);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 60.517703,430.5 -11.017704,0 0,11 11.017704,0 0,-11"
+ id="path71832"
+ sodipodi:nodetypes="ccc"
+ 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)">
+ <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-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" />
+ <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:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <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" />
+ <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" />
+ <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,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" />
+ <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" />
+ </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"
+ transform="translate(131,-30)">
+ <g
+ transform="translate(-45.97248,412)"
+ id="g38319">
+ <path
+ style="fill:url(#linearGradient38362);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 40.472488,166.25001 -1.250005,1.25 -12.483893,-1e-5 -1.25,-1.25 -5e-6,-11.75001 14.983898,1e-5 5e-6,11.75001 z"
+ id="path38330"
+ 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
+ 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="path38332"
+ d="m 38.972483,166.00001 -10.250003,0 0,-1 10.250003,0 0,1 z"
+ style="fill:#b3b3b3;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" />
+ <g
+ transform="translate(110.97248,58)"
+ style="display:inline;enable-background:new"
+ id="g38334">
+ <g
+ id="g38336">
+ <rect
+ y="97.000008"
+ x="-85"
+ height="8.9999962"
+ width="14.000007"
+ id="rect38338"
+ style="fill:#d89090;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;fill:#3771c8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38340"
+ width="13.999992"
+ height="2.9999936"
+ x="-85"
+ y="103.00001" />
+ <rect
+ style="opacity:0.3;fill:url(#radialGradient38364);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38342"
+ width="14"
+ height="8.8499966"
+ x="-85"
+ y="97.000008" />
+ <path
+ style="fill:#000000;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 -84.999997,101.00001 1.166667,0 1.166666,0.74999 1.166667,-0.74999 1.166666,0.99999 4.666666,1e-5 1.75,-0.75 1.75,0.75 1.166667,0 1e-5,0.99999 -13.999999,-1e-5 -10e-6,-1.99998 0,0 0,0 0,0 z"
+ id="path38344"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="99"
+ x="-77"
+ height="2.0000038"
+ width="2.0000029"
+ id="rect38346"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38350"
+ d="m -85,103.0089 14.061944,0 0,1 -14.061944,0 0,-1 z"
+ style="opacity:0.3;fill:#280b0b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path38360"
+ d="m -71.75,105.5 -12.5,0"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -77,103 2.000003,0 -0.750003,2.75 -0.5,0 L -77,103 z"
+ id="path38352"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </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"
+ id="path38354"
+ d="m 39.472483,155.5 -13,0 0.01611,11 13.01389,-7e-5 -0.03,-10.99993 z"
+ style="fill:none;stroke:url(#linearGradient38367);stroke-width:0.99999923px;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="ccccc"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="165"
+ x="26.972481"
+ height="1.0000043"
+ width="1"
+ id="rect38356"
+ 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
+ transform="translate(63,473)"
+ style="display:inline;enable-background:new"
+ id="g38358" />
+ </g>
+ <g
+ id="g38738"
+ transform="translate(41.000016,-2e-5)">
+ <rect
+ y="472"
+ x="488"
+ height="16"
+ width="16"
+ id="rect43314"
+ style="opacity:0;fill:#999999;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(565,446)"
+ clip-path="url(#clipPath43368-7)"
+ id="g43300">
+ <rect
+ style="fill:#4e83d0;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;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"
+ id="rect43243"
+ width="6"
+ height="2"
+ x="-75.5"
+ y="28.5"
+ rx="0.79505396"
+ ry="0.79505396" />
+ <rect
+ ry="0.74381745"
+ rx="0.74381745"
+ y="36.5"
+ x="-75.5"
+ height="2"
+ width="6"
+ id="rect43245"
+ style="fill:#4e83d0;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;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" />
+ <rect
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;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"
+ id="rect43262"
+ width="6"
+ height="2"
+ x="-72.5"
+ y="39.5"
+ rx="0.71819919"
+ ry="0.71819919" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="fill:none;stroke:#000000;stroke-width:2.9000001;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43241"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41718"
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="opacity:0.35;fill:none;stroke:url(#radialGradient38734);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43266"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path43282"
+ style="opacity:0.35;fill:none;stroke:url(#radialGradient38736);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g39638-8"
+ transform="matrix(0.9986805,0,0,1,179.4308,202.99997)">
+ <rect
+ rx="1.2018067"
+ y="274.00003"
+ x="317.9888"
+ height="4.9999909"
+ width="5.006597"
+ id="rect39640-1"
+ style="opacity:0.25;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.5;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="rect39642-2"
+ width="5.0065966"
+ height="4.9999905"
+ x="317.9888"
+ y="274.00003"
+ rx="1.2018069"
+ ry="1.2018069" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ 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="path43508"
+ d="m 317.98879,278 0,-3 1.00132,-1 3.00396,0 1.00132,1 0,3 -1.00132,1 -3.00396,0 -1.00132,-1 z"
+ style="opacity:0.8;fill:#dcb000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <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="path39644-1"
+ 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 317.98877,276 c 1.66888,0 3.33774,10e-6 5.00662,10e-6 0,0.33335 0,0.6667 0,1.00005 -1.66888,0 -3.33774,-1e-5 -5.00662,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ id="path39646-4"
+ 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="path39648-9"
+ d="m 319.99139,279.00006 c 0,-1.66671 10e-6,-3.33335 10e-6,-5.00006 0.33379,0 0.66758,0 1.00137,0 0,1.66671 -1e-5,3.33335 -1e-5,5.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="g28606">
+ <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="matrix(0,-1,-1,0,0,0)"
+ 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="rect22257"
+ width="16"
+ height="16"
+ x="-551"
+ y="-168" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path22271"
+ d="m 167.49999,535.50001 0,8 -9,0 0,-6 2,-2 7,0 z"
+ style="fill:url(#linearGradient28603);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:30;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect22281"
+ d="m 166.99999,538.00001 -2,0 0,3 2,0 0,-3 z m -3,0 -1.75,0 -1.25,1.25 0,1.75 3,0 0,-3 z"
+ style="fill:url(#linearGradient28600);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.75;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22285"
+ width="1"
+ height="1"
+ x="542"
+ y="162"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ id="rect22287"
+ d="m 166.99999,542.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ style="opacity:0.2;fill:#f2f2f2;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" />
+ <path
+ id="rect22291"
+ d="m 166.99999,536.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ style="opacity:0.8;fill:#f2f2f2;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" />
+ <path
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:30;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 158.74999,537.25001 4.75,4.75 0,1 -4.75,0 0,-5.75 z"
+ id="path22298"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient28593);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:30;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 152.49999,550.50001 0,-8 9,0 1.75,-1.5 0.25,0.5 0,7.75 -1.25,1.25 -9.75,0 z"
+ id="path22300"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 152.49999,550.50001 9.5,0 1.5,-1.5 0,-5.5 4,0 0,-8 -7,0 -2,2 0,5 -6,0 0,8 z"
+ id="path22304"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:url(#linearGradient28589);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 162.99999,544.00001 -1,1 -1,0 0,3 0.75,0 1.25,-1.25 0,-2.75 z m -3,1 -3,0 0,3 3,0 0,-3 z m -4,0 -3,0 0,3 3,0 0,-3 z"
+ id="rect22308"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect22314"
+ d="m 161.99999,549.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ style="opacity:0.8;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:connector-curvature="0" />
+ <path
+ id="rect22322"
+ d="m 161.99999,543.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 160.99999,542.00001 0,-0.5 -2,-2 0,2.5 2,0 z"
+ id="path22348"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22340"
+ style="fill:none;stroke:url(#linearGradient28583);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 158.99999,542.50001 2.5,0 0,-1 -2.25,-2.25 m 4.25,4.25 0,-2 -3,-3 0.5,-0.5"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient28580);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 162.49999,542.50001 -1,1 -8,0 0,6 8.25,0 1,-1"
+ id="path22342"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22345"
+ style="fill:none;stroke:url(#linearGradient28577);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 164.49999,542.50001 2,0 0,-6 -5.5,0 -1.5,1.5 0,0.5 3,3 0,1"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m 160.74999,536.50001 -1.25,1.25 0,0.75 3,3 0,1"
+ style="fill:none;stroke:url(#linearGradient28574);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path22368"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="542"
+ x="162"
+ height="6.25"
+ width="1"
+ id="rect38915"
+ 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)">
+ <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)">
+ <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" />
+ </g>
+ <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" />
+ </g>
+ </g>
+ </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"
+ transform="translate(-21,0)">
+ <g
+ style="display:inline;enable-background:new"
+ id="g38076"
+ transform="translate(173.70204,-41.325069)">
+ <g
+ transform="translate(1,1.0000001)"
+ id="g38078">
+ <g
+ id="g38080"
+ 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="rect38082"
+ 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="rect38084"
+ width="0.99999899"
+ height="1"
+ x="170.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="168.0161"
+ height="1"
+ width="1"
+ id="rect38086"
+ 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="rect38088"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="177.01379" />
+ <rect
+ y="179.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38090"
+ 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="rect38092"
+ 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="rect38094"
+ 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="rect38096"
+ 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="rect38098"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="183.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="rect38173"
+ width="0.99999899"
+ height="1"
+ x="178.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="176.0161"
+ height="1"
+ width="1"
+ id="rect38175"
+ 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="189.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38181"
+ 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="187.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38183"
+ 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
+ transform="translate(-40.70204,21.325054)"
+ id="g38100"
+ style="fill:#000000">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38102"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="178.00002" />
+ <rect
+ y="180.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect38104"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38106"
+ width="1"
+ height="1"
+ x="167.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="169.00002"
+ height="1"
+ width="1"
+ id="rect38108"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38110"
+ width="1"
+ height="1"
+ x="171.00002"
+ y="177.00002" />
+ <rect
+ y="182.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect38112"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38114"
+ width="1"
+ height="1"
+ x="173"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="175"
+ height="1"
+ width="1"
+ id="rect38116"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38118"
+ width="1"
+ height="1"
+ x="166"
+ y="184" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38120"
+ width="1"
+ height="1"
+ x="166"
+ y="186" />
+ <rect
+ y="177.00002"
+ x="177"
+ height="1"
+ width="1"
+ id="rect38169"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="188.00002"
+ x="166"
+ height="1"
+ width="1"
+ id="rect38177"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ <g
+ id="g38190"
+ transform="matrix(-1,0,0,-1,264.59592,410.65014)">
+ <g
+ transform="translate(-40.718137,21.311275)"
+ id="g38192"
+ 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="rect38194"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="181.01379" />
+ <rect
+ y="177.01379"
+ x="170.0161"
+ height="1"
+ width="0.99999899"
+ id="rect38196"
+ 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="rect38198"
+ width="1"
+ height="1"
+ x="168.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38200"
+ 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="rect38203"
+ 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="rect38205"
+ width="0.99999899"
+ height="1"
+ x="174.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="172.0161"
+ height="1"
+ width="1"
+ id="rect38207"
+ 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="rect38209"
+ 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="rect38211"
+ 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="rect38215"
+ width="1"
+ height="1"
+ x="176.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="rect38219"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="187.01379" />
+ </g>
+ <g
+ style="fill:#000000"
+ id="g38225"
+ transform="translate(-40.70204,21.325054)">
+ <rect
+ y="178.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect38227"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38229"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="180.00002" />
+ <rect
+ y="177.00002"
+ x="167.00002"
+ height="1"
+ width="1"
+ id="rect38231"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38233"
+ width="1"
+ height="1"
+ x="169.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="171.00002"
+ height="1"
+ width="1"
+ id="rect38235"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38237"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="182.00002" />
+ <rect
+ y="177.00002"
+ x="173"
+ height="1"
+ width="1"
+ id="rect38239"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38241"
+ width="1"
+ height="1"
+ x="175"
+ y="177.00002" />
+ <rect
+ y="184"
+ x="166"
+ height="1"
+ width="1"
+ id="rect38243"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="186"
+ x="166"
+ height="1"
+ width="1"
+ id="rect38245"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38247"
+ width="1"
+ height="1"
+ x="177"
+ y="177.00002" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38251"
+ width="1"
+ height="1"
+ x="166"
+ y="188.00002" />
+ </g>
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 301.5,168.92817 5e-5,-9.44187 11.99995,0 0,12.00195 -12,0.0118 0,-2.57183 0,-5e-5 z"
+ id="path37737-4"
+ inkscape:connector-curvature="0" />
+ <rect
+ 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="rect37061-2"
+ width="2.9998772"
+ height="3"
+ x="305.5"
+ y="161.5"
+ ry="0"
+ rx="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="164.5"
+ x="303.50012"
+ height="3"
+ width="2.9998772"
+ id="rect38072"
+ 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" />
+ <rect
+ 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="rect38074"
+ width="2.9998772"
+ height="3"
+ x="306.50012"
+ y="165.5"
+ ry="0"
+ rx="0" />
+ </g>
+ <g
+ id="g38397"
+ transform="translate(20.999878,0)">
+ <rect
+ rx="0"
+ ry="0"
+ y="158.5"
+ x="283.50012"
+ height="3"
+ width="2.9998772"
+ id="rect38277"
+ 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" />
+ <rect
+ 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="rect38279"
+ width="2.9998772"
+ height="3"
+ x="280.50012"
+ y="167.5"
+ ry="0"
+ rx="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="164.5"
+ x="288.50024"
+ height="3"
+ width="2.9998772"
+ id="rect38281"
+ 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"
+ transform="translate(436,-380)">
+ <rect
+ y="516"
+ x="-95"
+ height="16"
+ width="16"
+ id="rect36540"
+ 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="g36458"
+ transform="translate(-122,1.3e-4)">
+ <g
+ id="g36460"
+ style="opacity:0.75"
+ transform="translate(-116,424.99975)">
+ <g
+ transform="translate(-179,199.50012)"
+ id="g36462">
+ <path
+ id="path36464"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.25,-2 0,-6.75 -4.25,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000167;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="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g36468">
+ <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 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ id="path36470"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#cccccc;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 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ id="path36466"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient38049);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ id="path36474"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;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 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ id="path36472"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient38051);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ id="path36476"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.35;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36479"
+ width="1"
+ height="6.7500019"
+ x="149"
+ y="96.000122" />
+ <rect
+ y="96.000122"
+ x="150"
+ height="6.7500019"
+ width="1"
+ id="rect36481"
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ rx="0"
+ ry="0"
+ y="517.49976"
+ x="27.500006"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect36486"
+ style="fill:none;stroke:#8c4800;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:none;stroke:#8c4800;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="rect36489"
+ width="2.9999485"
+ height="3.0001416"
+ x="27.500006"
+ y="524.49951"
+ ry="0"
+ rx="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36496"
+ d="m 28.000006,520.49983 -0.5,0 0,-3.00014 2.99995,0"
+ style="fill:none;stroke:#5a2f00;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#5a2f00;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"
+ d="m 28.000006,524.49978 -0.5,0 0,3.00014 2.99995,0"
+ id="path36499"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36503"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000051"
+ y="517.99988"
+ ry="0"
+ rx="0" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36507"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000051"
+ y="524.99982"
+ ry="0"
+ rx="0" />
+ </g>
+ <g
+ transform="translate(-309,277)"
+ id="g36761-1"
+ style="display:inline;enable-background:new">
+ <path
+ style="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"
+ d="m 223,243 0,10 1,0 0,-1 1,0 1,0 0,2 1,0 0,1 1,0 0,-1 1,0 0,-2 -1,0 0,-2 1,0 1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 z"
+ id="path36763-5"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g36765-2"
+ style="fill:#1a1a1a;display:inline;enable-background:new"
+ transform="translate(5,-6.0000002e-7)">
+ <rect
+ y="243"
+ x="218"
+ height="10"
+ width="1"
+ id="rect36767-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="244"
+ x="219"
+ height="1"
+ width="1"
+ id="rect36769-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="245"
+ x="220"
+ height="1"
+ width="1"
+ id="rect36771-1"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="246"
+ x="221"
+ height="1"
+ width="1"
+ id="rect36773-4"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="247"
+ x="222"
+ height="1"
+ width="1"
+ id="rect36775-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="248"
+ x="223"
+ height="1"
+ width="1"
+ id="rect36777-3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="249"
+ x="224"
+ height="1"
+ width="1.0000017"
+ id="rect36779-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="219"
+ height="1"
+ width="1"
+ id="rect36781-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="251"
+ x="220"
+ height="1"
+ width="1"
+ id="rect36783-1"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="221"
+ height="2"
+ width="1"
+ id="rect36785-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="250"
+ x="222.25"
+ height="2"
+ width="0.75"
+ id="rect36787-8"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="223"
+ height="1.9999931"
+ width="1"
+ id="rect36789-5"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="254"
+ x="222"
+ height="1.0000006"
+ width="1.5"
+ id="rect36791-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36793-6"
+ width="1.5"
+ height="1"
+ x="223.5"
+ y="250" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g37508"
+ transform="translate(525,27.999998)">
+ <g
+ style="opacity:0.7"
+ id="g37302"
+ transform="translate(-244,373.99988)">
+ <g
+ transform="translate(-179,199.50012)"
+ id="g37304">
+ <path
+ id="path37306"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;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"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g37308">
+ <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 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ id="path37311"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#cccccc;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 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ id="path37313"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient37530);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ id="path37316"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;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 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ id="path37318"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient37534);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ id="path37320"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37322"
+ width="1"
+ height="6.7500019"
+ x="149"
+ y="96.000122" />
+ <rect
+ y="96.000122"
+ x="150"
+ height="6.7500019"
+ width="1"
+ id="rect37324"
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g37284"
+ transform="translate(-524.98389,247.00001)">
+ <rect
+ y="218"
+ x="425"
+ height="16"
+ width="16"
+ id="rect37286"
+ 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(46.000035,99.00001)"
+ id="g37288"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g37290"
+ transform="translate(-3.542969e-5,0)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path37292"
+ style="fill:none;stroke:#000000;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.23389,129.74998 4.25,-4.24999 m 0.98389,1.99999 -1.48389,-1.49999 m 0.48389,2.49999 -1.4142,-1.41422"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 387.98389,129.99999 c 0.78065,0.78065 0.78065,2.21936 0,3 -0.78064,0.78065 -2.21935,0.78065 -3,0 -0.78064,-0.78064 -0.78064,-2.21935 0,-3 0.78065,-0.78064 2.21936,-0.78064 3,0 z"
+ style="fill:none;stroke:#000000;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path37504"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 388.23389,129.74998 4.25,-4.24999 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path37294"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37500"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 387.98389,129.99999 c 0.78064,0.78065 0.78064,2.21935 0,3 -0.78065,0.78065 -2.21936,0.78065 -3,0 -0.78065,-0.78065 -0.78065,-2.21935 0,-3 0.78064,-0.78065 2.21935,-0.78065 3,0 z"
+ sodipodi:nodetypes="czzzz"
+ inkscape:connector-curvature="0" />
+ </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"
+ sodipodi:ry="0.5"
+ sodipodi:rx="0.5"
+ sodipodi:cy="477.5"
+ sodipodi:cx="-92.5"
+ id="path37506"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g37565">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.7668704,0,0,0.7668711,19.45715,14.604317)"
+ id="g10270-1"
+ style="opacity:0.3;display:inline;enable-background:new">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.39093411;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10272-2"
+ 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
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)"
+ 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="path10275-3"
+ style="opacity:0.4;fill:url(#linearGradient38254);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <rect
+ y="178"
+ x="110"
+ height="16"
+ width="16"
+ id="rect37989"
+ 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"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="g38006"
+ transform="translate(-255.99996,227.9746)"
+ style="display:inline">
+ <rect
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="-43.49577"
+ x="372.49994"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect37525"
+ style="opacity:0.15;fill:none;stroke:#d5e5ff;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="0"
+ ry="0" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="40.991806"
+ x="372.99994"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect38010"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ ry="0"
+ rx="0"
+ style="fill:#ebf3ff;fill-opacity:1;fill-rule:nonzero;stroke:#004cbe;stroke-width:0.99999875;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="rect38012"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.49577"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.4000001;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:new"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ id="path37498"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="rect38140"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ style="fill:none;stroke:url(#linearGradient37509);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ 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" />
+ <g
+ transform="translate(-290,397)"
+ id="g37579"
+ style="display:inline">
+ <g
+ id="g37582">
+ <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" />
+ </g>
+ <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" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g37577"
+ transform="translate(-105,-63)">
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ id="g37580"
+ transform="matrix(0.7668704,0,0,0.7668711,19.45715,14.604317)"
+ 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">
+ <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="path37582"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.39093411;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37613);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path37584"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38120-7"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:2.28571391;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:new"
+ 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" />
+ </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="rect37586"
+ width="16"
+ height="16"
+ x="110"
+ y="178" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path37608"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ style="fill:none;stroke:#000000;stroke-width:2.4000001;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:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient37615);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ id="path37610"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14409"
+ 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"
+ id="rect15296"
+ width="16"
+ height="16"
+ x="47"
+ y="92" />
+ <g
+ style="display:inline"
+ id="g15298"
+ transform="matrix(1.0756796,0,0,1.076923,-83.216744,-140.6923)"
+ 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\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="path15301"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.11492968;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:url(#linearGradient14439-9);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path15303"
+ 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.6926913,-0.07795333,0.0789528,-0.6875008,210.6113,314.95068)" />
+ <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="path15305"
+ style="fill:none;stroke:url(#linearGradient14441-4);stroke-width:1.454548;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6391304,0,0,0.6383922,44.127271,148.16974)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14396"
+ transform="translate(4.7892764e-7,23)">
+ <rect
+ y="92"
+ x="68"
+ height="16"
+ width="16"
+ id="rect15309"
+ 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="g15311"
+ 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.0829765,0,0,1.0830206,-86.990103,-142.06175)"
+ style="display:inline">
+ <g
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path15315"
+ style="fill:#7c7c7c;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10805392;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ 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.8076551,0,0,0.8055247,44.427594,128.39229)" />
+ <path
+ transform="matrix(0.745771,0,0,0.7384254,52.598397,136.33161)"
+ 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="path15317"
+ style="opacity:0.7;fill:url(#linearGradient14433-1);fill-opacity:1;fill-rule:nonzero"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient14435-7);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path15319"
+ 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.624995,0,0,0.625,68.0007,149.25)" />
+ <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="path15321"
+ style="fill:none;stroke:url(#linearGradient14437-6);stroke-width:1.4544518;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6837125,0,0,0.6818205,60.789416,142.9887)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path15323"
+ d="m 147.27014,223.27443 c 0.22029,-2.14702 1.65545,-2.83866 3,-3"
+ style="fill:none;stroke:#ffffff;stroke-width:0.92336226px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:0.9233622px;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;filter:url(#filter15421-1);enable-background:accumulate"
+ d="m 153.73381,225.66118 c 0,1 -1,2 -2,2"
+ id="path15325"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37996"
+ 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"
+ id="rect37994"
+ width="16.000006"
+ height="16.000002"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37953"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10749674;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"
+ 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.8125568,0,0,0.8127302,-123.25796,26.09414)" />
+ <path
+ id="path37970"
+ d="m -18,116.34375 c -1.706032,0.60248 -3.053766,1.95022 -3.65625,3.65625 l 3.65625,0 0,-3.65625 z m 0,3.65625 0,4 4,0 0,-4 -4,0 z m 4,0 3.65625,0 C -10.94623,118.29397 -12.29397,116.94623 -14,116.34375 L -14,120 z m 0,4 0,3.65625 c 1.70603,-0.60248 3.05377,-1.95022 3.65625,-3.65625 L -14,124 z m -4,0 -3.65625,0 c 0.602484,1.70603 1.950218,3.05377 3.65625,3.65625 L -18,124 z"
+ style="fill:url(#linearGradient38073-8);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.749378,0,0,0.7495379,-114.92287,33.554528)"
+ 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:type="arc"
+ style="opacity:0.25;fill:url(#linearGradient38075-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23055196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path37963"
+ 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" />
+ <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="path37955"
+ style="fill:none;stroke:url(#linearGradient38077-1);stroke-width:1.45488834;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6874075,0,0,0.6872685,-106.73771,40.90046)" />
+ <path
+ style="opacity:0.7;fill:url(#linearGradient38079-2);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 -18,116.34375 c -1.706032,0.60248 -3.053766,1.95022 -3.65625,3.65625 l 3.65625,0 0,-3.65625 z"
+ id="path37972"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(4.7892764e-7,23)"
+ id="g38272"
+ style="display:inline;enable-background:new">
+ <g
+ id="g37676">
+ <rect
+ y="92"
+ x="26"
+ height="16"
+ width="16"
+ id="rect38274"
+ 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
+ transform="matrix(-0.7606373,-0.08449162,0.08669728,-0.7451645,124.04885,199.0823)"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38284"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="fill:none;stroke:#000000;stroke-width:1.23076892;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path38294"
+ 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"
+ transform="matrix(0.8125001,0,0,0.8125002,-73.250026,4.1249738)" />
+ <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.1;fill:none;stroke:url(#radialGradient38306-3);stroke-width:2.44404984;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path38296"
+ sodipodi:cx="132"
+ 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"
+ sodipodi:start="0"
+ sodipodi:end="3.12636"
+ transform="matrix(0.8077059,0,0,-0.2072667,-72.578821,124.6156)"
+ sodipodi:open="true" />
+ <path
+ transform="matrix(-0.7451139,-0.08394973,0.08492792,-0.7403854,122.33348,198.48526)"
+ 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="path15303-4"
+ style="opacity:0.15;fill:url(#linearGradient37646-4);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.780896,0,0,0.2786183,-69.081831,66.644097)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:1.50070953;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path38300"
+ 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.37076,0 -7.9325,-3.50789 -7.99907,-7.87814"
+ sodipodi:start="0"
+ sodipodi:end="3.12636"
+ 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
+ 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(#linearGradient37677);stroke-width:1.45454454;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:new"
+ id="path38298"
+ 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"
+ transform="matrix(0.6875009,0,0,0.687501,-56.75013,18.874887)" />
+ <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:#000000;stroke-width:1.35088885;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path38302"
+ 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.38113,0 7.94728,3.52395 7.99943,7.90477"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38304"
+ style="opacity:0.18000004;fill:none;stroke:url(#linearGradient38313-7);stroke-width:1.0666672;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:new"
+ 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" />
+ </g>
+ </g>
+ <g
+ id="g39510"
+ transform="translate(-570,274)">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path44921"
+ d="m 653.5,356.5 -4,4 -7,0 -4,-4 0,-7 4,-4 7,0 4,4 0,7 z"
+ style="fill:url(#linearGradient39518);fill-opacity:1;fill-rule:nonzero;stroke:#550000;stroke-width:1;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" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path44926"
+ d="m 652.5,356 -3.5,3.5 -6,0 -3.5,-3.5 0,-6 3.5,-3.5 6,0 3.5,3.5 0,6 z"
+ style="fill:none;stroke:url(#linearGradient39520);stroke-width:1.20000005;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39523);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 651.5,355.5 -2.75,3 -5.25,0 -3,-3 0,-5 3,-3 5,0 3,3 0,5 z"
+ id="path44954"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.6567169,0.6567169,-0.6567304,0.6567304,736.47216,94.047762)"
+ style="display:inline;enable-background:new"
+ id="g51749-0-4">
+ <path
+ id="path51751-1-8"
+ style="fill:none;stroke:#aa0000;stroke-width:2.69179726;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 132.08133,266.03337 -7.61363,0 m 3.80681,3.80673 0,-7.61347"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path51753-2-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.29206276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 128.27451,269.8401 0,-7.61347 m 3.80682,3.80674 -7.61363,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g40247"
+ 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"
+ id="rect40250"
+ width="16"
+ height="15.99988"
+ x="5"
+ y="514.00012" />
+ <g
+ transform="translate(70,178)"
+ id="g40252">
+ <g
+ transform="translate(-386,446.5)"
+ id="g40254">
+ <path
+ id="path40257"
+ 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:#422200;fill-opacity:1;fill-rule:evenodd;stroke:#281500;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:#efa351;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ id="path40259"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g40261">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#915515;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path40263"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#f5ca9b;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="path40270"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient40280);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="path40272"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient40282);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40275"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40284);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="path40278"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(508.99432,90)"
+ id="g38556">
+ <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"
+ id="rect38558"
+ width="16"
+ height="16"
+ x="46"
+ y="-209.99432" />
+ <g
+ transform="translate(-113.99432,-362)"
+ id="g38560"
+ style="opacity:0.5">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path38563"
+ style="fill:none;stroke:#000000;stroke-width:2.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 -93.5,422.5 12,0 0,-12 -12,0 0,12 z m 0,-6 12,0 m -6.00001,-5.99959 0,12"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;fill:url(#linearGradient38689);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38570"
+ width="13"
+ height="13"
+ x="-94.000008"
+ y="410"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m -93.5,422.5 12,0 -1e-5,-11.99959 -12,0 1e-5,11.99959 z m 0,-6 12,0 m -6.00001,-5.99959 1e-5,11.99959"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;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="path38572"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38574"
+ d="M -92.46875,415.53125 -92.5,411.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38693);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38695);stroke-width:1px;stroke-linecap:round"
+ d="M -86.46875,415.53125 -86.5,411.5 l 4,0"
+ id="path38577"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38697);stroke-width:1px;stroke-linecap:round"
+ d="M -92.46875,421.53125 -92.5,417.5 l 4,0"
+ id="path38579"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38581"
+ d="M -86.46875,421.53125 -86.5,417.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38701);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="48"
+ x="-207.99432"
+ height="9"
+ width="9.0000038"
+ id="rect37920-7"
+ style="opacity:0.07999998;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="g38583"
+ transform="translate(-137.99432,-356)">
+ <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="path38585"
+ d="m -70.5,411.5 0,-8 8,0 0,8 -8,0 z"
+ style="fill:#ffb769;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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;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"
+ d="m -70.5,411.5 0,-8 8,0"
+ id="path38588"
+ 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.4;fill:none;stroke:url(#linearGradient38703);stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ d="M -68.46875,409.53125 -68.5,405.5 l 4,0"
+ id="path38590"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38592"
+ d="m -64.53125,405.5 0.03125,4.03125 -4,0"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient38706);stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(505.99432,90)"
+ id="g38644">
+ <rect
+ y="-185.99432"
+ x="46"
+ height="16"
+ width="16"
+ id="rect38650"
+ 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"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ style="opacity:0.5"
+ id="g38652"
+ transform="translate(-98.99432,-362)">
+ <path
+ d="m -85.5,422.5 4,0 0,-12 -4,0 0,12 z m 0,-6 4,0"
+ style="fill:none;stroke:#000000;stroke-width:2.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"
+ id="path38654"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="410"
+ x="-86"
+ height="13"
+ width="4.9999924"
+ id="rect38657"
+ style="opacity:0.7;fill:url(#linearGradient38720);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path38659"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;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 -85.49999,422.49959 -81.5,422.5 -81.50001,410.50041 -85.5,410.5 l 1e-5,11.99959 z m 0,-6 L -81.5,416.5"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38723);stroke-width:1px;stroke-linecap:round"
+ d="M -84.46875,415.53125 -84.5,411.5 l 2,0"
+ id="path38661"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38663"
+ d="M -84.46875,421.53125 -84.5,417.5 l 2,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38725);stroke-width:1px;stroke-linecap:round"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,1.7057638,-106.49432,-641.33135)"
+ id="g38665">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffb769;fill-opacity:1;fill-rule:nonzero;stroke:#462400;stroke-width:0.76566803;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 -71,412.03125 0,-8.2055 7,0 0,8.2055 -7,0 z"
+ id="path38668"
+ 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="path38670"
+ d="m -69,407.19668 0,-2.19843 2.75,0"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38727);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38729);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -66,405.14481 0,2.19843 -2.75,0"
+ id="path38672"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38731);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -69,410.71416 0,-2.19843 2.75,0"
+ id="path38674"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path38676"
+ d="m -66,408.6623 0,2.19843 -2.75,-10e-6"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38736);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39152"
+ transform="translate(507.99432,90)">
+ <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"
+ id="rect39154"
+ width="16"
+ height="16"
+ x="46"
+ y="-229.99432" />
+ <g
+ transform="translate(-133.99432,-362)"
+ id="g39157"
+ style="opacity:0.55">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path39159"
+ style="fill:none;stroke:#000000;stroke-width:2.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 -93.5,422.5 12,0 0,-12 -12,0 0,12 z m 0,-6 12,0 m -6.00001,-5.99959 0,12"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;fill:url(#linearGradient39199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39161"
+ width="13"
+ height="13"
+ x="-94.000008"
+ y="410"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m -93.5,422.5 12,0 -1e-5,-11.99959 -12,0 1e-5,11.99959 z m 0,-6 12,0 m -6.00001,-5.99959 1e-5,11.99959"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;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="path39163"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39165"
+ d="M -92.46875,415.53125 -92.5,411.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39201);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39203);stroke-width:1px;stroke-linecap:round"
+ d="M -86.46875,415.53125 -86.5,411.5 l 4,0"
+ id="path39167"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39205);stroke-width:1px;stroke-linecap:round"
+ d="M -92.46875,421.53125 -92.5,417.5 l 4,0"
+ id="path39169"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39171"
+ d="M -86.46875,421.53125 -86.5,417.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39207);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="opacity:0.07999998;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="rect37922"
+ width="1.9785498"
+ height="10"
+ x="-215.97287"
+ y="48" />
+ <rect
+ style="opacity:0.07999998;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="rect37896-1"
+ width="2.9785526"
+ height="10"
+ x="-227.99432"
+ y="48" />
+ <g
+ id="g39173"
+ transform="translate(-190.01023,-189.50001)">
+ <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="rect39175"
+ width="1.9999995"
+ height="9.999959"
+ x="-38.484093"
+ y="236.00082"
+ transform="matrix(1,2.1226448e-5,0,1,0,0)" />
+ <rect
+ transform="matrix(1,3.6759233e-5,0,1,0,0)"
+ y="236.5014"
+ x="-37.984093"
+ height="8.9999657"
+ width="0.9999997"
+ id="rect39178"
+ style="fill:#ffcb91;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="path39180"
+ d="m -37.484093,246.00001 -0.9549,0.0112 -0.0271,-10.01124 1.982,4e-5 0,1"
+ 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>
+ <rect
+ y="48"
+ x="-221.97287"
+ height="10"
+ width="2.9785526"
+ id="rect37920"
+ style="opacity:0.07999998;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
+ transform="translate(-184.01023,-189.50001)"
+ id="g39182">
+ <rect
+ transform="matrix(1,2.6522988e-5,0,1,0,0)"
+ y="236.00104"
+ x="-38.484093"
+ height="9.9999399"
+ width="1.9999998"
+ id="rect39184"
+ 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:#ffcb91;fill-opacity:1;fill-rule:nonzero;display:inline"
+ id="rect39186"
+ width="0.99999994"
+ height="9.0000439"
+ x="-37.984093"
+ y="236.50175"
+ transform="matrix(1,4.7261927e-5,0,1,0,0)" />
+ <path
+ 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 -38.484093,237.00001 0.018,-1.00004 1.982,4e-5 0,1"
+ id="path39189"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,-252.97841,-189.50001)"
+ id="g39191">
+ <rect
+ transform="matrix(1,2.1226448e-5,0,1,0,0)"
+ y="236.00082"
+ x="-38.484093"
+ height="9.999959"
+ width="1.9999995"
+ id="rect39193"
+ 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:#ffcb91;fill-opacity:1;fill-rule:nonzero;display:inline"
+ id="rect39195"
+ width="0.9999997"
+ height="8.9999657"
+ x="-37.984093"
+ y="236.5014"
+ transform="matrix(1,3.6759233e-5,0,1,0,0)" />
+ <path
+ 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.484093,246.00001 -0.9549,0.0112 -0.0271,-10.01124 1.982,4e-5 0,1"
+ id="path39197"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39209"
+ transform="translate(508.99432,90)">
+ <rect
+ y="-251.99432"
+ x="46"
+ height="16"
+ width="16"
+ id="rect39211"
+ 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"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ transform="translate(-155.99432,-362)"
+ style="opacity:0.55"
+ id="g39213">
+ <path
+ d="m -93.5,422.5 12,0 0,-12 -12,0 0,12 z m 0,-6 12,0 m -6.00001,-5.99959 0,12"
+ style="fill:none;stroke:#000000;stroke-width:2.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"
+ id="path39215"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="410"
+ x="-94.000008"
+ height="13"
+ width="13"
+ id="rect39217"
+ style="opacity:0.7;fill:url(#linearGradient39246);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path39219"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;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 -93.5,422.5 12,0 -1e-5,-11.99959 -12,0 1e-5,11.99959 z m 0,-6 12,0 m -6.00001,-5.99959 1e-5,11.99959"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39248);stroke-width:1px;stroke-linecap:round"
+ d="M -92.46875,415.53125 -92.5,411.5 l 4,0"
+ id="path39221"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39223"
+ d="M -86.46875,415.53125 -86.5,411.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39252);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39225"
+ d="M -92.46875,421.53125 -92.5,417.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39255);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39259);stroke-width:1px;stroke-linecap:round"
+ d="M -86.46875,421.53125 -86.5,417.5 l 4,0"
+ id="path39227"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ rx="0"
+ ry="0"
+ y="-251.49432"
+ x="-49.500275"
+ height="3"
+ width="2.9998772"
+ id="rect39229"
+ style="fill:none;stroke:#402100;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="opacity:0.07999998;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="rect37866"
+ width="3.9785564"
+ height="4"
+ x="-250.99432"
+ y="47" />
+ <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="path39231"
+ d="m -250.99432,47 c 0,0.6694 10e-6,1.3388 10e-6,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -1e-5,-1.3388 -1e-5,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="47"
+ x="-243.97287"
+ height="4"
+ width="3.9785564"
+ id="rect37868"
+ style="opacity:0.07999998;fill:#000000;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:none;stroke:#402100;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="rect39233"
+ width="2.9998772"
+ height="3"
+ x="-49.500305"
+ y="-244.5025"
+ ry="0"
+ rx="0" />
+ <rect
+ y="54"
+ x="-250.97287"
+ height="4"
+ width="3.9785564"
+ id="rect37870"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.07999998;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="rect37896"
+ width="3.9785564"
+ height="4"
+ x="-243.97287"
+ y="54" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -244.00249,47 c 0,0.6694 1e-5,1.3388 1e-5,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -10e-6,-1.3388 -10e-6,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ id="path39235"
+ 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
+ rx="0"
+ ry="0"
+ y="-251.5025"
+ x="-56.492096"
+ height="3"
+ width="2.9998772"
+ id="rect39237"
+ style="fill:none;stroke:#402100;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="matrix(0,-1,1,0,0,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="path39239"
+ d="m -251.0025,53.9918 c 0,0.6694 1e-5,1.3388 1e-5,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -1e-5,-1.3388 -1e-5,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:none;stroke:#402100;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="rect39241"
+ width="2.9998772"
+ height="3"
+ x="-56.492096"
+ y="-244.49432"
+ ry="0"
+ rx="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -243.99432,53.9918 c 0,0.6694 10e-6,1.3388 10e-6,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -1e-5,-1.3388 -1e-5,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ id="path39244"
+ 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>
+ <g
+ id="g39098"
+ transform="translate(42,63)">
+ <rect
+ ry="0"
+ rx="0"
+ y="535"
+ x="488"
+ height="16"
+ width="16"
+ id="rect39095"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39082">
+ <g
+ mask="url(#mask38956)"
+ id="g38942"
+ transform="translate(0,-21)">
+ <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="path38944"
+ d="m 489.5,570.5 7.5,0 c 7.75,0 6.25,-9 2.5,-9 l -1,0"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;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:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssc"
+ style="fill:none;stroke:url(#linearGradient39115);stroke-width:1.39999998;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 489,570.5 8,0 c 7.75,0 6.25,-9 2.5,-9 l -1,0"
+ id="path38946"
+ 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
+ sodipodi:nodetypes="cccsccccccc"
+ id="path38948"
+ d="m 493.5,535.5 c -0.554,0 -1,0.446 -1,1 l 0,8 c 0,0.554 0.446,1 1,1 0.554,0 1,-0.446 1,-1 l 1.5,0 c 1.939,0 3.5,-1.561 3.5,-3.5 l 0,-1 c 0,-1.939 -1.561,-3.5 -3.5,-3.5 l -1.5,0 c 0,-0.554 -0.446,-1 -1,-1 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffeeaa;fill-opacity:1;fill-rule:evenodd;stroke:#28220b;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 492.5,539.5 -3,0 c -0.54593,0 -0.98543,-0.4395 -0.98543,-0.98544 0,-0.54593 0.4395,-0.98543 0.98543,-0.98543 l 3,0"
+ id="rect38938"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39117);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 494.5,543.59375 1.5,0 c 1.45545,0 2.59375,-1.1383 2.59375,-2.59375 l 0,-1 c 0,-1.45545 -1.1383,-2.59375 -2.59375,-2.59375 l -1.5,0"
+ id="path39045"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.5"
+ rx="0.49151421"
+ y="536"
+ x="493"
+ height="9"
+ width="1"
+ id="rect38950"
+ style="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" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39119);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 494.5,542.5 1.5,0 c 0.94305,0 1.5,-0.55695 1.5,-1.5 l 0,-1 c 0,-0.94305 -0.55695,-1.5 -1.5,-1.5 l -1.5,0"
+ id="path39068"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39052"
+ width="1"
+ height="7"
+ x="494"
+ y="537"
+ rx="0.49151421"
+ ry="0.5" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path39076"
+ d="m 494.5,542.5 1.5,0 c 0.94305,0 1.5,-0.55695 1.5,-1.5 l 0,-1 c 0,-0.94305 -0.55695,-1.5 -1.5,-1.5 l -1.5,0"
+ style="fill:none;stroke:url(#linearGradient39122);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ id="path39534"
+ d="m 492.5,543.47087 -3,0 c -0.54593,0 -0.98543,-0.4395 -0.98543,-0.98544 0,-0.54593 0.4395,-0.98543 0.98543,-0.98543 l 3,0"
+ style="fill:#ffeeaa;fill-opacity:1;fill-rule:evenodd;stroke:#28220b;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-105,212.00008)"
+ id="g39237"
+ style="display:inline;enable-background:new">
+ <g
+ 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"
+ id="g39240"
+ transform="translate(5.4013367,9.4697686)"
+ 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="rect39242"
+ width="16"
+ height="16"
+ x="125.59866"
+ y="397.53015" />
+ <g
+ style="display:inline"
+ transform="translate(2.6147745,160.52205)"
+ 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="g39244">
+ <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.927848,0,0,0.916217,-28.19594,40.73172)"
+ id="g39246"
+ style="display:inline">
+ <path
+ transform="matrix(1.0155084,0,0,1.0286863,37.51084,101.58226)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient39261);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.8489247;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path39248"
+ 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" />
+ </g>
+ <g
+ style="fill:none;stroke:url(#linearGradient39265);stroke-width:1.17973554;stroke-opacity:1;display:inline"
+ id="g39250"
+ 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">
+ <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="path39252"
+ style="fill:none;stroke:url(#linearGradient39263);stroke-width:1.22986293;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(1.0337319,0,0,1.0470635,35.105336,99.413761)" />
+ </g>
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccc"
+ id="path39309"
+ transform="translate(105,-235.00008)"
+ d="m 32,645 0,1 -1,0 0,2 2,0 0,-1 2,0 0,2 -1,0 0,1.25 -1,0 0,1.75 2,0 0,-1.5 1,0 0,-1 1,0 0,-3.5 -1,0 0,-1 -4,0 z m 1,8 0,2 2,0 0,-2 -2,0 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 32,645 0,1 -1,0 0,2 2,0 0,-1 2,0 -0.02802,1.97638 -1,0 L 34,650.25 l -1,0 0,1.75 2,0 0,-1.5 1,0 0,-1 1,0 0,-3.5 -1,0 0,-1 -4,0 z m 1,8 0,2 2,0 0,-2 -2,0 z"
+ transform="translate(105,-235.00008)"
+ id="path11803-1"
+ sodipodi:nodetypes="cccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-3.0078133e-8,128.00008)"
+ id="g39694"
+ style="display:inline;enable-background:new">
+ <g
+ 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"
+ id="g39696"
+ transform="translate(5.4013367,9.4697686)"
+ 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="rect39698"
+ width="16"
+ height="16"
+ x="125.59866"
+ y="397.53015" />
+ <g
+ style="display:inline"
+ transform="translate(2.6147745,160.52205)"
+ 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="g39700">
+ <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.927848,0,0,0.916217,-28.19594,40.73172)"
+ id="g39702"
+ style="display:inline">
+ <path
+ transform="matrix(0.8835182,0,0,0.8949854,54.933548,117.35897)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient39261-4-5);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97574574;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="path39704"
+ 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" />
+ </g>
+ <g
+ style="fill:none;stroke:url(#linearGradient39718);stroke-width:1.17973554;stroke-opacity:1;display:inline"
+ id="g39706"
+ 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">
+ <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="path39708"
+ style="fill:none;stroke:url(#linearGradient39716);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g39802"
+ style="opacity:0.7;stroke:#000000">
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000"
+ d="m 138,413.99992 c 0.25,0 2,0 2,0 l 0,4 0.75,0 0,1 -3.5,0 0,-1 0.75,0 0,-3 c -0.66667,0 4.15703,0 -1.25,0 l 0.5,-1 0.75,0 z"
+ id="path39804"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39806"
+ width="2"
+ height="2"
+ x="138"
+ y="410.99991"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g39798">
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path39710"
+ d="m 138,413.99992 c 0.25,0 2,0 2,0 l 0,4 0.75,0 0,1 -3.5,0 0,-1 0.75,0 0,-3 c -0.66667,0 4.15703,0 -1.25,0 l 0.5,-1 0.75,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="410.99991"
+ x="138"
+ height="2"
+ width="2"
+ id="rect39712"
+ style="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" />
+ </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" />
+ <g
+ id="g40270"
+ transform="translate(146.99999,-417.99999)">
+ <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" />
+ <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" />
+ <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" />
+ </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" />
+ </g>
+ <g
+ id="g39333"
+ 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"
+ id="rect38951"
+ width="16"
+ height="16"
+ x="26"
+ y="198" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g39096-7"
+ transform="translate(26.00079,19.1)">
+ <rect
+ rx="1.3125"
+ ry="1.3125001"
+ y="180.53122"
+ x="5.4992032"
+ height="9.9687805"
+ width="10.000007"
+ id="rect39098-7"
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39100-7"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ style="fill:none;stroke:url(#linearGradient40733-0);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-1.00079,-19)"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ id="g39118-3">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="path39183-3"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect39114-5"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 9.49921,181.5 2,0"
+ id="path39106-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,-1,-1,0,212.75,247.25)"
+ id="g38966">
+ <g
+ id="g38968"
+ transform="matrix(-1,0,0,-1,215.25,222.75)">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 174.5,38.5 0,5 5,0"
+ id="path38970"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path38972"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;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"
+ d="m 175.5,42.5 5,-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-146.75,127.75)"
+ id="g38975">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.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="g38977">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path38984"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path38987"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;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"
+ d=""
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ id="path38994"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g38996"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path38998"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,118.4113,290.74999)"
+ 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="g39000">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path39015"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path39017"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;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"
+ d="m 78.1613,110.99999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,-175.75,-207.25)"
+ style="opacity:0.2"
+ id="g39020">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path39022"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g39306"
+ transform="translate(-1,-62)">
+ <rect
+ y="198"
+ x="6"
+ height="16"
+ width="16"
+ id="rect38948"
+ 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" />
+ <g
+ id="g39096"
+ transform="translate(1.00079,19)">
+ <rect
+ rx="1.3125"
+ ry="1.3125001"
+ y="180.53122"
+ x="5.4992032"
+ height="9.9687805"
+ width="10.000007"
+ id="rect39098"
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39100"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ style="fill:none;stroke:url(#linearGradient40733);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-1.00079,-19)"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ id="g39118">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="path39183"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect39114"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 9.49921,181.5 2,0"
+ id="path39106"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39052"
+ transform="matrix(0,1,-1,0,199.75,171.75)">
+ <g
+ transform="matrix(-1,0,0,-1,215.25,222.75)"
+ id="g39054">
+ <path
+ id="path39056"
+ d="m 174.5,38.5 0,5 5,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 175.5,42.5 5,-5"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;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="path39058"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39060"
+ transform="translate(-146.75,127.75)">
+ <g
+ id="g39062"
+ 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,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ 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"
+ id="path39064"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d=""
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;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="path39066"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path39069"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g39071">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path39073"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39076"
+ 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,0,0,-1,118.4113,290.74999)"
+ style="display:inline">
+ <path
+ 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"
+ id="path39078"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 78.1613,110.99999 5.5,-5.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;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="path39080"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39083"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-175.75,-207.25)">
+ <path
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path39085"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40848"
+ 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"
+ id="rect40824"
+ width="16"
+ height="16"
+ x="-17"
+ y="94" />
+ <g
+ id="g39622"
+ transform="translate(-3.2236328e-6,0.9999981)">
+ <g
+ transform="translate(-83.999951,1.9073486e-6)"
+ style="opacity:0.6"
+ id="g40663">
+ <rect
+ style="fill:url(#linearGradient40875-3-9-8);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40665"
+ width="7.9999967"
+ height="9.9999981"
+ x="69.499954"
+ y="94.5"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient40877-5-5-9);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40667"
+ width="5.9999967"
+ height="7.9999981"
+ x="70.499954"
+ y="95.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g40669"
+ transform="translate(-85,-1)">
+ <rect
+ 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:0"
+ id="rect40671"
+ width="8.0000029"
+ height="9.0000019"
+ x="73.5"
+ y="98.5"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="99"
+ x="74"
+ height="9"
+ width="7"
+ id="rect40673"
+ style="fill:url(#linearGradient40879-9-8-1);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ style="fill:none;stroke:#333333;stroke-width:0.7499997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 73.5,103.75 0,-5.25 4,0"
+ id="path40675"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient40881-8-0-8);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40677"
+ width="6.0000033"
+ height="7.0000019"
+ x="74.5"
+ y="99.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <rect
+ style="opacity:0.4;fill:url(#radialGradient40883-4-0-3);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="rect40679"
+ width="7.0000033"
+ height="8.0000019"
+ x="-11"
+ y="98"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ transform="translate(-122.97615,-9.9999881)"
+ id="g40681">
+ <path
+ id="path40683"
+ d="m 116.47121,117.5 -3.99506,0"
+ style="fill:none;stroke:#2d2d2d;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 114.4449,117.46875 c 0,-1.65264 1.12861,-2.96875 2.78125,-2.96875 l 1.5,0 c 1.65264,0 2.71875,1.31617 2.71875,2.9688 l 0,0.0625 c 0,1.65264 -1.06611,2.9687 -2.71875,2.9687 l -1.5,0 c -1.65264,0 -2.78125,-1.31612 -2.78125,-2.96875 l 0,-0.0625 z m 2.03125,0.0312 c 0,0.554 0.2585,0.99995 0.8125,0.99995 l 1.40625,-0.0312 c 0.554,0 0.78125,-0.41475 0.78125,-0.96875 0,-0.554 -0.22725,-1.03125 -0.78125,-1.03125 l -1.40625,0.0312 c -0.554,0 -0.8125,0.44605 -0.8125,1.00005 z"
+ id="path40685"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="116"
+ x="115"
+ height="2.47615"
+ width="1"
+ id="rect40687"
+ style="opacity:0.7;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"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="opacity:0.7;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"
+ id="rect40689"
+ width="1"
+ height="1"
+ x="116"
+ y="115"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ id="path40691"
+ d="m 106.4449,117.4688 c 0,-1.65264 1.12861,-2.96875 2.78125,-2.96875 l 1.5,-5e-5 c 1.65264,0 2.71875,1.31617 2.71875,2.9688 l 0,0.0625 c 0,1.65264 -1.06611,2.9687 -2.71875,2.9687 l -1.5,5e-5 c -1.65264,0 -2.78125,-1.31612 -2.78125,-2.96875 l 0,-0.0625 z m 2.03125,0.0312 c 0,0.554 0.2585,1 0.8125,1 l 1.4375,-5e-5 c 0.554,0 0.75,-0.44595 0.75,-0.99995 0,-0.554 -0.196,-1.00005 -0.75,-1.00005 l -1.4375,5e-5 c -0.554,0 -0.8125,0.446 -0.8125,1 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;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"
+ id="rect40693"
+ width="0.99998814"
+ height="2.5000362"
+ x="115"
+ y="107.97615"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="106.97615"
+ x="116"
+ height="1"
+ width="1"
+ id="rect40695"
+ style="opacity:0.7;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"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ style="opacity:0.55;fill:none;stroke:#1a1a1a;stroke-width:2.79440284;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 116.47121,117.5 -4.99506,-1e-5"
+ id="path40697"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 116.47121,117.5 -4.99506,-1e-5"
+ id="path40699"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="118.97615"
+ x="119"
+ height="1"
+ width="1"
+ id="rect40701"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40703"
+ width="1"
+ height="1"
+ x="115"
+ y="118.97615"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40705"
+ width="1"
+ height="1"
+ x="119"
+ y="111"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="111"
+ x="115"
+ height="1"
+ width="1"
+ id="rect40707"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40709"
+ width="1"
+ height="0.97614998"
+ x="117"
+ y="118"
+ transform="matrix(0,1,1,0,0,0)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40697"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ y="29"
+ x="-31"
+ height="16"
+ width="16"
+ id="rect40643"
+ 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="g40513"
+ style="opacity:0.8">
+ <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="path40465"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ style="fill:url(#linearGradient40511-7-9-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m -29.5,34 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient40507-4-8-1);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path40469"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:url(#radialGradient40649-2-6-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ id="path40645"
+ 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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m -31,33 4,0 0,-4 -4,4 z"
+ id="path40471"
+ 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 -30.5,32.00001 0,10.49999 11,-1e-5 0,-12.99999 -8.5,10e-6 -2.5,2.5 0,0 0,0 0,0 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="path40473"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40475"
+ d="m -26.5,31.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient40502-7-8-3);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40263"
+ transform="matrix(0.8738816,0,0,0.8823479,-135.18828,-60.939841)"
+ 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">
+ <path
+ sodipodi:type="arc"
+ style="fill:#3771c8;fill-opacity:1;fill-rule:nonzero;stroke:#040910;stroke-width:1.45371544;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="path40265"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path40267"
+ style="fill:url(#linearGradient40635-7-2-2);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ 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.666432,0,0,0.659342,42.69924,35.46375)" />
+ <path
+ transform="matrix(0.3631382,0,0,0.3593485,81.755824,69.904768)"
+ 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:type="arc"
+ style="opacity:0.7;fill:url(#linearGradient40637-9-5-8);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path40269"
+ 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" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path40271"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:1.18410921px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter13996-9-7-7)"
+ transform="matrix(0.9688184,0,0,0.9547322,-131.63668,47.640696)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccssscsscccscccccccccccccccsccccc"
+ id="path40273"
+ d="m 130.67404,112.3079 c 0.0244,0.78706 -0.15754,1.63085 0.59269,2.02213 0.71197,-0.0434 1.49133,0.64122 1.35667,1.40517 -0.26776,0.77861 0.14071,1.12325 0.95576,1.36401 0.57868,-0.0716 0.79053,-0.93546 0.87357,-1.36401 0.0948,-1.27121 0.51542,-1.09421 0.82108,-1.98991 -0.45733,-0.91502 -0.003,-1.04443 -0.72629,-1.43739 m -1.00945,-3.89288 c -0.4426,0.34378 -0.24372,1.04314 -0.66162,1.39841 -0.45372,0.13628 -0.78226,-0.0605 -1.16771,0.43164 -0.30841,1.10457 0.35004,1.22306 0.90205,1.10457 0.49538,-0.0502 0.61419,-0.94321 0.97928,-0.37853 0.0831,0.10976 0.71917,-0.0403 0.86266,0.18898 0.0669,0.10682 -0.11785,0.0255 -0.14729,0.18955 -0.0428,0.23847 0.27734,0.37341 0.372,0.3824 0.32089,0.0305 0.60005,0.92548 0.83846,1.05499 0,0.46738 0.0924,-0.6774 0.3515,-0.78703 0.22948,-0.0971 0.47929,0.10731 0.5,0 0.29928,-1.55081 -1.26113,-3.00604 -2.82933,-3.58498 z M 128.96474,107.5 c -0.6111,1.01384 0.85343,1.46103 1.73001,1.21329 0.57897,-0.37879 1.00716,-0.92331 0.55665,-1.21329 -0.20614,-0.1415 -2.07706,0.0431 -2.28666,0 l 0,0 0,0 0,0 z m -1.372,1.37253 c -0.49575,-0.14959 0.44952,-0.11945 0.45733,0.45751 0.1696,0.54756 -0.42801,0.23756 0,0.45752 0.70893,0.1644 0.35328,1.70031 -0.28114,1.56208 -0.56042,0.10119 -0.43915,0.95826 -1.64865,0.88279 -0.0836,0.0755 -1.04512,0.61593 -0.81421,1.21521 1.12968,0.30162 -0.36816,1.26478 -0.43867,0.55236 -0.15441,-0.49797 -0.62853,-1.11348 -0.43994,-1.68674 0.11734,-0.63627 0.5689,-1.12263 0.82646,-1.69865 0.36225,-0.61946 0.89084,-1.17688 1.57758,-1.42595 0.21411,-0.16799 0.46159,-0.41691 0.76124,-0.31613 l 0,0 0,0 0,0 z m -0.91467,5.03262 c -0.55163,-0.27585 -0.72934,0.28829 -0.60377,0.7984 0.15577,0.47138 0.52607,0.97695 0.72628,1.43739 0.40435,0.49619 1.512,1.34081 2.17883,1.67696 0.31768,0.16015 0.48418,0 0.24209,-0.23956 -0.31367,-0.6375 -1.14073,-1.94893 -0.48418,-2.15609 0.59647,-0.60342 0.34203,-1.58773 -0.48419,-1.43739 -0.54779,-0.25818 -0.75551,-0.39899 -1.38855,-0.0752 -0.0558,0.0743 -0.12403,0.006 -0.18651,-0.004 l 0,-5.1e-4 0,0 0,0 z"
+ style="fill:url(#linearGradient40639-1-2-1);fill-opacity:1;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\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="path40275"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient40641-9-2-7);stroke-width:1.78065979;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path40277"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ 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.06052282,0,0,0.05989117,121.21686,103.80334)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41840"
+ transform="translate(497,652)">
+ <rect
+ y="-75"
+ x="-135"
+ height="16"
+ width="16"
+ id="rect41622"
+ 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="g41624"
+ style="display:inline;enable-background:new"
+ transform="matrix(1,0,0,0.9999542,-104,-101.99865)">
+ <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="path41626"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ style="fill:url(#linearGradient41638-8-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m -29.5,34 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient41640-2-0);stroke-width:1.00002289px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path41628"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:url(#radialGradient41642-5-0);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ id="path41630"
+ 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
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m -31,33 4,0 0,-4 -4,4 z"
+ id="path41632"
+ 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 -30.5,32.00001 0,10.49999 11,-1e-5 0,-12.99999 -8.5,10e-6 -2.5,2.5 0,0 0,0 0,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80001831;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path41634"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41636"
+ d="m -26.5,31.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient41644-5-4);stroke-width:1.00002289px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g43546-0"
+ transform="matrix(0.9986805,0,0,1,-443.5692,-347.00003)">
+ <rect
+ rx="1.2018067"
+ y="274.00003"
+ x="317.9888"
+ height="4.9999909"
+ width="5.006597"
+ id="rect43548-7"
+ style="opacity:0.2;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.4;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="rect43550-6"
+ width="5.0065966"
+ height="4.9999905"
+ x="317.9888"
+ y="274.00003"
+ rx="1.2018069"
+ ry="1.2018069" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ 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="path43552-3"
+ d="m 317.98879,278 0,-3 1.00132,-1 3.00396,0 1.00132,1 0,3 -1.00132,1 -3.00396,0 -1.00132,-1 z"
+ style="opacity:0.8;fill:#dcb000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#967800;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 318.9901,278.50003 c 0,-1.33336 3e-5,-2.66664 3e-5,-4 1.00132,0 2.00263,0 3.00395,0 0,1.33336 -3e-5,2.66664 -3e-5,4 -1.00132,0 -2.00263,0 -3.00395,0 z"
+ id="path43554-6"
+ 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="path43583-1"
+ d="m 318.48944,278.00003 c 0,-1.00002 4e-5,-1.99998 4e-5,-3 1.33509,0 2.67017,0 4.00526,0 0,1.00002 -4e-5,1.99998 -4e-5,3 -1.33509,0 -2.67017,0 -4.00526,0 z"
+ style="fill:#967800;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 317.98877,276 c 1.66888,0 3.33774,10e-6 5.00662,10e-6 0,0.33335 0,0.6667 0,1.00005 -1.66888,0 -3.33774,-1e-5 -5.00662,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ id="path43556-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"
+ 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="path43558-4"
+ d="m 319.99139,279.00006 c 0,-1.66671 10e-6,-3.33335 10e-6,-5.00006 0.33379,0 0.66758,0 1.00137,0 0,1.66671 -1e-5,3.33335 -1e-5,5.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
+ transform="translate(378,684)"
+ style="display:inline;enable-background:new"
+ id="g39156">
+ <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"
+ width="16"
+ height="16"
+ x="-205"
+ y="-87" />
+ <g
+ transform="translate(-272,-181)"
+ style="opacity:0.6"
+ id="g40789">
+ <rect
+ style="fill:url(#linearGradient39136-2-0);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40791"
+ width="9.0000124"
+ height="10.000001"
+ x="68.5"
+ y="95.5"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient39138-8-6);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40793"
+ width="7.0000038"
+ height="8.0000086"
+ x="69.5"
+ y="96.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g40795"
+ transform="translate(-273.00002,-181)">
+ <rect
+ 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:0"
+ id="rect40797"
+ width="8.9999342"
+ height="10.000006"
+ x="73.500023"
+ y="99.5"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="100"
+ x="74.000023"
+ height="9"
+ width="8.0000086"
+ id="rect40799"
+ style="fill:url(#linearGradient39140-6-8);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ style="fill:none;stroke:#333333;stroke-width:0.7499997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 73.5,103.75 2e-5,-4.25 4,0"
+ id="path40801"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient39143-0-6);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40803"
+ width="7.0000048"
+ height="8.0000267"
+ x="74.500023"
+ y="100.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ style="fill:#800000"
+ id="g37993">
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37978"
+ width="2.00001"
+ height="1.0000038"
+ x="-198"
+ y="-77" />
+ <rect
+ y="-76"
+ x="-197.00002"
+ height="2"
+ width="1.0000153"
+ id="rect37980"
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37982"
+ width="1.0000153"
+ height="1"
+ x="-197.00002"
+ y="-79" />
+ <rect
+ y="-75"
+ x="-194.5"
+ height="1.0000088"
+ width="1.4999988"
+ id="rect37984"
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-76"
+ x="-195.00002"
+ height="1"
+ width="1.0000153"
+ id="rect37986"
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37988"
+ width="1.5000049"
+ height="1.0000198"
+ x="-194.5"
+ y="-77" />
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37990"
+ width="1.0000153"
+ height="5"
+ x="-193.00002"
+ y="-79" />
+ </g>
+ </g>
+ <g
+ id="g39528">
+ <g
+ clip-path="url(#clipPath40902)"
+ id="g40560"
+ transform="matrix(-1,0,0,1,90,-62)">
+ <rect
+ y="198"
+ x="6"
+ height="16"
+ width="16"
+ id="rect40562"
+ 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" />
+ <g
+ style="opacity:0.4"
+ id="g40565"
+ transform="matrix(-1,0,0,1,21.999203,19)">
+ <rect
+ rx="1.3125"
+ ry="1.3125001"
+ y="180.53122"
+ x="5.4992032"
+ height="9.9687805"
+ width="10.000007"
+ id="rect40567"
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40569"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ style="fill:none;stroke:url(#linearGradient40679);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-1.00079,-19)"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ id="g40571">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="path40573"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40575"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 9.49921,181.5 2,0"
+ id="path40577"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40581"
+ transform="matrix(0,1,-1,0,199.75,171.75)">
+ <g
+ transform="matrix(-1,0,0,-1,215.25,222.75)"
+ id="g40583">
+ <path
+ id="path40585"
+ d="m 174.5,38.5 0,5 5,0"
+ style="fill:none;stroke:#00112b;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 175.5,42.5 5,-5"
+ style="fill:none;stroke:#00112b;stroke-width:3.20000005;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="path40587"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40589"
+ transform="translate(-146.75,127.75)">
+ <g
+ id="g40591"
+ 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,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ 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"
+ id="path40593"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d=""
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;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="path40595"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40597"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g40599">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40602"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g40604"
+ 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,0,0,-1,118.4113,290.74999)"
+ style="display:inline">
+ <path
+ 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"
+ id="path40606"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 78.1613,110.99999 5.5,-5.5"
+ style="fill:#abcdff;fill-opacity:1;stroke:#c3dbff;stroke-width:1.5;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="path40609"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40611"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-175.75,-207.25)">
+ <path
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path40613"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-160.74474,8.5136728)"
+ style="display:inline;enable-background:new"
+ id="g27675-3">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27679-1"
+ d="m 73.191498,271.86917 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.95;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-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42359-1"
+ 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
+ id="g39560">
+ <g
+ clip-path="url(#clipPath40897)"
+ id="g40506"
+ transform="matrix(-1,0,0,1,89,-62)">
+ <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"
+ id="rect40508"
+ width="16"
+ height="16"
+ x="26"
+ y="198" />
+ <g
+ transform="matrix(-1,0,0,1,46.99921,19)"
+ id="g39096-2"
+ style="opacity:0.4;display:inline;enable-background:new">
+ <rect
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39098-5"
+ width="10.000007"
+ height="9.9687805"
+ x="5.4992032"
+ y="180.53122"
+ ry="1.3125001"
+ rx="1.3125" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40733-03);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ id="path39100-0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g39118-9"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ transform="translate(-1.00079,-19)">
+ <path
+ id="path39183-4"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="rect39114-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path39106-8"
+ d="m 9.49921,181.5 2,0"
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,-1,-1,0,212.75,247.25)"
+ id="g40522">
+ <g
+ id="g40526"
+ transform="matrix(-1,0,0,-1,215.25,222.75)">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#00112b;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 174.5,38.5 0,5 5,0"
+ id="path40528"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path40533"
+ style="fill:none;stroke:#00112b;stroke-width:3.20000005;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"
+ d="m 175.5,42.5 5,-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-146.75,127.75)"
+ id="g40535">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.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="g40537">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path40539"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path40541"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;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"
+ d=""
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ id="path40543"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g40545"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path40547"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,118.4113,290.74999)"
+ 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="g40549">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path40551"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path40553"
+ style="fill:#abcdff;fill-opacity:1;stroke:#c3dbff;stroke-width:1.5;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"
+ d="m 78.1613,110.99999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,-175.75,-207.25)"
+ style="opacity:0.2"
+ id="g40556">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40558"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g40888"
+ style="display:inline;enable-background:new"
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-194.74474,8.5136728)">
+ <path
+ 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 73.191498,271.86917 7.071067,-7.07107"
+ id="path40890"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40892"
+ style="opacity:0.95;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"
+ 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="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="path40894"
+ inkscape:connector-curvature="0" />
+ </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">
+ <g
+ id="g44266"
+ style="opacity:0.8;display:inline"
+ transform="translate(-138,212)">
+ <g
+ id="g44268"
+ transform="translate(1.0551033e-6,0)">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\Browser icons ver 1\Outliner ICON CODES.png"
+ id="g44270"
+ transform="matrix(0.927273,0,0,1,85.654543,64)"
+ style="display:inline">
+ <path
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.63466382;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path44272"
+ 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="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44274"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z M 63.999982,17 64,19 l 2.156862,0 -1.8e-5,-2 -2.156862,0 0,0 0,0 0,0 z m 10.78431,0 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:none;stroke:#1a1a1a;stroke-width:1.86925566;stroke-linecap:square;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"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient44318);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path44276"
+ sodipodi:cx="70.5"
+ 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"
+ 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"
+ inkscape:export-ydpi="90" />
+ <path
+ id="path44278"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ececec;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 75.5,17.5"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-1.6176466e-5,0)"
+ sodipodi:nodetypes="cccccc"
+ 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="path44280"
+ style="opacity:0.8;fill:none;stroke:url(#radialGradient44320);stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 74.784292,17 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path44282"
+ sodipodi:nodetypes="ccccc"
+ 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
+ d="M 70.499967,14.5 65.5,17.5"
+ style="fill:none;stroke:#999999;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path44284"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 70.470586,14.5 0,-6"
+ style="fill:none;stroke:#cccccc;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path44286"
+ sodipodi:nodetypes="cc"
+ 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
+ id="path44288"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ 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
+ id="path44290"
+ d="m 64,17 0,2 2.156844,0 0,-2 L 64,17 z"
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ 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" />
+ <rect
+ style="opacity:0.05;fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44292"
+ width="3.774509"
+ height="3.5"
+ x="68.583321"
+ y="13.25" />
+ <path
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.03847623px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 64.539197,18.5 0,-1 1.078431,0"
+ id="path44294"
+ sodipodi:nodetypes="ccc"
+ 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"
+ id="path44296"
+ d="m 69.931347,8.5 0,-0.9673924 1.078413,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.03847647px;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\BLENDER ICONSET\Kopia 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:evenodd;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 75.323509,18.500001 0,-1 1.078431,0"
+ id="path44298"
+ sodipodi:nodetypes="ccc"
+ 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" />
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44300"
+ width="17.254898"
+ height="16"
+ x="61.843121"
+ y="5" />
+ <path
+ transform="matrix(1.0784311,0,0,1,-92.372519,-64)"
+ id="path44302"
+ d="m 155,80.5 -3,-1.870665"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path44304"
+ d="m 74.245078,17.500001 0,-1 1.078431,0"
+ style="opacity:0.01000001;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:1.03847647px;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.4;fill:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#666666;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 69.931352,9.5000005 1.078431,0"
+ id="path44306"
+ sodipodi:nodetypes="cc"
+ 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:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#4c4c4c;stroke-width:1.03847575px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 66.696014,17.499989 0,-1 -1.078431,0"
+ id="path44308"
+ sodipodi:nodetypes="ccc"
+ 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>
+ <path
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 147,80.5 3,-1.870665"
+ id="path44310"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44312"
+ d="m 150.5,73.5 0,4"
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44314"
+ width="2"
+ height="2"
+ x="150.06403"
+ y="78" />
+ </g>
+ <rect
+ 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="rect44316"
+ width="2.9998772"
+ height="3"
+ x="11.499837"
+ y="289.5"
+ ry="0"
+ rx="0" />
+ </g>
+ <g
+ id="g43843">
+ <g
+ transform="translate(20,-30.990313)"
+ id="g39499">
+ <g
+ style="opacity:0.5"
+ transform="translate(-20,8)"
+ id="g39466">
+ <rect
+ style="opacity:0;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39468"
+ width="16"
+ height="16"
+ x="47"
+ y="642" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path39470"
+ d="m 34.8125,650.5 c -0.469932,0.0628 -0.901978,0.36287 -1.125,0.78125 l -6,11 c -0.495227,0.9075 0.278677,2.21576 1.3125,2.21875 l 12,0 c 1.033823,-0.003 1.807727,-1.31125 1.3125,-2.21875 l -6,-11 c -0.282798,-0.52794 -0.905299,-0.85216 -1.5,-0.78125 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#ffdd55;fill-opacity:1;stroke:#2b0000;stroke-width:0.89999998;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="655"
+ x="34"
+ height="5"
+ width="2.0152419"
+ id="rect39472"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39474"
+ width="2.0152419"
+ height="1"
+ x="33.984756"
+ y="661" />
+ <path
+ id="path39476"
+ d="m 34.936406,651.39468 c -0.144491,0.0192 -0.31295,0.15614 -0.381583,0.28384 l -6.105329,11.1013 c -0.0509,0.0926 -0.05511,0.27404 0.0636,0.47307 0.118705,0.19902 0.275323,0.31508 0.381582,0.31538 l 12.210658,0 c 0.106265,-3e-4 0.262877,-0.11636 0.381583,-0.31538 0.118706,-0.19903 0.114499,-0.38055 0.06359,-0.47307 l -6.105329,-11.1013 c -0.08049,-0.14902 -0.33952,-0.30385 -0.508777,-0.28384 l 5e-6,0 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.5;fill:none;stroke:#ff0000;stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ inkscape:connector-curvature="0" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:none;stroke:url(#linearGradient39508);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ d="m 34.936406,651.39468 c -0.144491,0.0192 -0.31295,0.15614 -0.381583,0.28384 l -6.105329,11.1013 c -0.0509,0.0926 -0.05511,0.27404 0.0636,0.47307 0.118705,0.19902 0.275323,0.31508 0.381582,0.31538 l 12.210658,0 c 0.106265,-3e-4 0.262877,-0.11636 0.381583,-0.31538 0.118706,-0.19903 0.114499,-0.38055 0.06359,-0.47307 l -6.105329,-11.1013 c -0.08049,-0.14902 -0.33952,-0.30385 -0.508777,-0.28384 l 5e-6,0 z"
+ id="path39478"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path43799"
+ d="M 54.75,622.5 50,631.25"
+ style="opacity:0.25;fill:none;stroke:#2b2200;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path43801"
+ d="m 29.5,631.5 9.5,0"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44081"
+ 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"
+ id="rect44079"
+ width="16"
+ height="16"
+ x="320"
+ y="73" />
+ <g
+ transform="translate(0,-22.005631)"
+ id="g43931">
+ <g
+ id="g43459">
+ <g
+ transform="translate(0,21)"
+ id="g43446">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path43448"
+ d="m 333.25,86.005631 -5.25,0 -1,-1 L 327,76"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43450"
+ d="M 331.25,80.244369 327,76 l -4.25,4.244369"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g43442">
+ <path
+ style="fill:none;stroke:#dcdcdc;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 333.25,86.005631 -5.25,0 -1,-1 L 327,76"
+ id="path42664"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;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 331.25,80.25 327,76.005631 322.75,80.25"
+ id="path42666"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 328.5,106.50563 5,0 m -7,-7.00563 0,6.50563"
+ id="path43773"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44954);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 322.25,101.00563 4.5,-4.499999 0.5,0 4.5,4.499999"
+ id="path44952"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g44124">
+ <rect
+ y="73"
+ x="341"
+ height="16"
+ width="16"
+ id="rect44077"
+ 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
+ id="g44913"
+ transform="translate(0,1)">
+ <g
+ transform="matrix(-1,0,0,-1,698,183)"
+ id="g43652">
+ <path
+ sodipodi:nodetypes="csc"
+ id="path43654"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2 8,0.5"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;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
+ sodipodi:nodetypes="ccc"
+ id="path43660"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,698,183)"
+ id="g43662">
+ <path
+ style="fill:none;stroke:#dcdcdc;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 343.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2.25 8,0.5"
+ id="path43668"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;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 343,108.25 0,-4.25 4.25,0"
+ id="path43666"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path43671"
+ d="m 354,78 0,-1 0,-1.5 -1,0 0,1.5 -1.5,0 0,1 1.5,0 1,0 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43747"
+ d="M 353.09375,76.40625 C 350.56802,73.88797 346.75,74 344.25,76"
+ style="fill:none;stroke:url(#linearGradient44944);stroke-width:1.10000002;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: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 350.5,78.5 4,0 0,-4"
+ id="path43750"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44931"
+ transform="translate(0,-1)">
+ <g
+ transform="translate(0,-21)"
+ id="g43636">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;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.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2.25 8,0.5"
+ id="path43623"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;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,108.25 0,-4.25 4.25,0"
+ id="path43506"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,-21)"
+ id="g43632">
+ <path
+ sodipodi:nodetypes="csc"
+ id="path43584"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2.25 8,0.5"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43502"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#e6e6e6;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344,84 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ id="rect43547"
+ inkscape:connector-curvature="0" />
+ <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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 347.5,82.5 -4.5,0 c -0.25,0 -0.5,0.25 -0.5,0.5 l 0,4.5"
+ id="path43761"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44942);stroke-width:1.10000002;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 345.59375,84.90625 c 2.07803,2.0719 5.36384,2.10325 7.53125,0.1875"
+ id="path43765"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g44097">
+ <rect
+ y="52"
+ x="320"
+ height="16"
+ width="16"
+ id="rect44095"
+ 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(42.999999,-42)"
+ id="g43952">
+ <g
+ transform="matrix(0,-1,1,0,183.99437,429)"
+ id="g43483">
+ <g
+ transform="translate(0,21)"
+ id="g43488">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43490"
+ d="M 327,86.255631 327,76"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;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"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g43494">
+ <path
+ style="fill:none;stroke:#dcdcdc;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 327,86.255631 327,76"
+ id="path43496"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;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 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43498"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43776"
+ 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"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44485);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 284,97.25 -4.5,4.5 0,0.5 4.5,4.5"
+ id="path43780"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43860"
+ d="m 291.5,101.5 -8.99437,0"
+ 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-1,0)"
+ id="g44111">
+ <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"
+ width="16"
+ height="16"
+ x="341"
+ y="52" />
+ <g
+ transform="translate(41.97875,-42)"
+ id="g43941">
+ <g
+ id="g43467"
+ transform="matrix(0,-1,-1,0,409.02125,429)">
+ <g
+ id="g43469"
+ transform="translate(0,21)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 327,86.25 327,76"
+ id="path43471"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43473"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43475"
+ transform="translate(0,21)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43478"
+ d="M 327,86.25 327,76"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43481"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="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 308.5,106 2.75,-2.75"
+ id="path43778"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path43785"
+ d="m 308.75,97.25 c -0.25,0 -0.5,0.25 -0.5,0.5 m 2.26562,3.75 -8.99437,0"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44950);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 309.02125,97.249998 4.5,4.500002 0,0.5 -4.5,4.5"
+ id="path44948"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g32752"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\v. 2.5.06\prvicons 2.5.06.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="180"
+ x="872"
+ height="192"
+ width="192"
+ id="rect30285"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.39191818;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ transform="translate(856,-203)"
+ id="g21955"
+ style="opacity:0.3;display:inline;enable-background:new">
+ <rect
+ 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"
+ id="rect21957"
+ width="48"
+ height="48"
+ x="108"
+ y="430"
+ rx="2.4004419"
+ ry="0" />
+ <g
+ id="g21959">
+ <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="path21961"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient21977);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21963"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21965"
+ 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)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21967"
+ style="fill:none;stroke:url(#linearGradient21979);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 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" />
+ <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 115.5,442.75 0,31.75 33,0 0,-41 -23.75,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="path21969"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21971"
+ 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)" />
+ <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="path21973"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21975"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g30335">
+ <g
+ id="g21367"
+ transform="translate(760,-202)">
+ <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="path21369"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30321);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21371"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21373"
+ 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)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21375"
+ style="fill:none;stroke:url(#linearGradient30323);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 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" />
+ <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 115.5,442.75 0,31.75 33,0 0,-41 -23.75,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="path21377"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21569"
+ 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)" />
+ <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="path21379"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21381"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="font-size:33.49144363px;font-style:normal;font-weight:normal;fill:#214478;fill-opacity:1;stroke:none;display:inline;font-family:Bitstream Vera Sans"
+ d="m 891.07148,245 -0.0715,9 2.39012,0 C 896,254 896,253 896.5,251 l 0.5,0 0,7 -0.5,0 c -0.5,-2 -0.5,-3 -3.10988,-3 L 891,255 l 0,7 c 0,2.5 1,3.25 3.14146,3.39973 l -0.004,0.60029 L 885,266 l 0.004,-0.60029 C 887,265.25 888,264.5 888.00001,262 L 888,248 c 0,-2.5 -1,-3.25 -3,-3.5 l 0,-0.5 16,0 0,5 -0.5,0 c -0.50001,-1.99999 -1.5,-4 -4.5,-4 l -4.92852,0 z"
+ id="text13209"
+ sodipodi:nodetypes="ccccccccccccccccccccccc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21625"
+ transform="translate(904,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21627"
+ 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" />
+ <g
+ id="g21629">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21647);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21631"
+ 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" />
+ <g
+ style="opacity:0.5;fill:#000000;display:inline"
+ id="g16261"
+ transform="matrix(1.2499985,0,0,1,-87.6203,-147.85351)">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35099"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="598.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35101"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="600.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15690"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="602.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15692"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="604.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15694"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="606.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15696"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="608.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15698"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="610.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15700"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="612.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15732"
+ width="14.400002"
+ height="1"
+ x="167.69646"
+ y="614.85352"
+ rx="0.09920612"
+ ry="0.065390877" />
+ <g
+ transform="translate(150.89645,557.85352)"
+ id="g4849"
+ style="fill:#000000;display:inline">
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="29"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15736"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="31"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15738"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="33"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15740"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="35"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15742"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.055114571"
+ y="37"
+ x="16.799992"
+ height="1"
+ width="8.0000095"
+ id="rect15744"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ ry="0.065390304"
+ rx="0.0057410933"
+ y="617.85352"
+ x="184.49646"
+ height="0.99999124"
+ width="0.83333319"
+ id="rect16334"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21633"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21635"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21649);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21637"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21639"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21641"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21643"
+ 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" />
+ <g
+ id="g35119"
+ transform="translate(2,-160.99999)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ transform="translate(105.39645,589.71201)"
+ id="g16097">
+ <g
+ id="g16099"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)">
+ <radialGradient
+ id="radialGradient16101"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16103" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16105" />
+ </radialGradient>
+ <radialGradient
+ id="radialGradient16109"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16111" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16113" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ id="path16107" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#radialGradient21565);fill-rule:nonzero;stroke:none"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ id="path16117" />
+ </g>
+ <g
+ id="g16131"
+ transform="translate(105.39645,579.71201)"
+ style="display:inline">
+ <g
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ id="g16133">
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="114.5684"
+ fx="20.892099"
+ r="5.256"
+ cy="114.5684"
+ cx="20.892099"
+ id="radialGradient16135">
+ <stop
+ id="stop16137"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16140"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="64.567902"
+ fx="20.892099"
+ r="5.257"
+ cy="64.567902"
+ cx="20.892099"
+ id="radialGradient16142">
+ <stop
+ id="stop16144"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16146"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path35139"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35141"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ style="fill:url(#radialGradient21567);fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21645"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21572"
+ transform="translate(808,-203)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21574"
+ 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" />
+ <g
+ id="g21576">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21594);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21578"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21580"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21582"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21596);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21584"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21586"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21588"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21590"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path21592"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ id="g30382">
+ <g
+ id="g23655"
+ transform="translate(760,-154)">
+ <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="path23657"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30368);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path23659"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path23661"
+ 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)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path23663"
+ style="fill:none;stroke:url(#linearGradient30370);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 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" />
+ <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 115.5,442.75 0,31.75 33,0 0,-41 -23.75,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="path23665"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path23667"
+ 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)" />
+ <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="path23669"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23671"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 888,295 1,0 0,14 -1,0 0,-14 z"
+ id="path23675"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23677"
+ d="m 900,294 1.00002,-1 0,14 -1.00002,0 0,-13 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path23679"
+ d="m 901.00003,292 0,2.25 -13.00002,2 0,-2.25 13.00002,-2 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23681"
+ transform="matrix(1.1428564,0,0,1.2000001,822.71436,-355.40005)">
+ <path
+ transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)"
+ 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"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23683"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ id="path23685"
+ sodipodi:cx="53"
+ 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"
+ transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
+ inkscape:transform-center-y="0.3813435"
+ clip-path="url(#clipPath20586)" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.38999999;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 901.00003,292 -1e-5,1 -13.00002,2 10e-6,-1 13.00002,-2 z"
+ id="path23694"
+ sodipodi:nodetypes="ccccc" />
+ <g
+ transform="matrix(1.1428564,0,0,1.2000001,834.71436,-357.40005)"
+ id="g23717">
+ <path
+ sodipodi:type="arc"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23724"
+ sodipodi:cx="53"
+ 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"
+ 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"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23726"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g23922"
+ transform="translate(-16,-220)"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g23924"
+ transform="translate(824,66)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect23926"
+ 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" />
+ <g
+ id="g23928">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient23978);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path23930"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23932"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path23934"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient23980);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23936"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path23938"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path23940"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path23942"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path23944"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccc"
+ id="path23946"
+ d="m 952,530 0,10 1,0 1,0 11,0 1,0 1,0 0,-10 -15,0 z m 1,2 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient23982);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23948"
+ width="13"
+ height="5.5"
+ x="953"
+ y="-524" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23952"
+ transform="translate(76,0)"
+ d="m 876,514 0,17 15,0 0,-17 -1,0 0,1 -1,0 0,-1 -11,0 0,1 -1,0 0,-1 -1,0 z m 1,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
+ style="fill:url(#linearGradient23986);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 952,507 3,0 0,3 9,0 0,-3 3,0 0,7 -15,0 0,-7 z m 1,0 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z m 12,-4 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z"
+ id="path23954" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="507"
+ height="9"
+ width="3"
+ id="rect23956"
+ style="fill:url(#linearGradient23988);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23958"
+ width="9"
+ height="9"
+ x="512"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="523"
+ height="9"
+ width="9"
+ id="rect23960"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ transform="matrix(0,-0.5624971,0.5624971,0,893.12531,590.74965)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path23962"
+ 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="path23964"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,601.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path23966"
+ d="m 961.00001,519.00005 -3,0 0,-0.99992 0.99994,0 6e-5,-2.00008 -1,0 0,-1 1,0 0,-1 1.00006,0 0,4.00008 0.99994,0 0,0.99992 z" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,525 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -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"
+ id="path23968" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23970"
+ width="6"
+ height="9"
+ x="534"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ clip-path="url(#clipPath23877)"
+ id="g23972">
+ <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="path23974"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,612.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,536 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,1 -2,0 0,1 2,0 0,-1 z"
+ id="path23976" />
+ </g>
+ </g>
+ <g
+ transform="translate(208,88)"
+ id="g45475"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g22242"
+ transform="translate(696,-194)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect22244"
+ 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" />
+ <g
+ id="g22246">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient22274);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path22249"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path22251"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path22253"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient22276);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path22264"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path22266"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path22268"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path22270"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path22272"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ id="g21517"
+ inkscape:label="Layer 1"
+ transform="matrix(0.5406242,0,0,0.5829534,814.13667,247.65542)">
+ <path
+ transform="matrix(1.274286,0,0,1.377124,-7.569123,-16.70193)"
+ 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"
+ sodipodi:ry="5.3033009"
+ sodipodi:rx="15.467961"
+ sodipodi:cy="38.98439"
+ sodipodi:cx="28.019106"
+ id="path35486"
+ style="opacity:0.54857142;fill:url(#radialGradient21442);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssssssssscccsscccscccssccc"
+ 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"
+ id="path2482"
+ style="fill:#f57900;fill-rule:evenodd;stroke:#aa4400;stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ transform="matrix(0.8018194,0,0,0.8471126,6.257567,4.5089892)"
+ 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"
+ sodipodi:ry="10.125"
+ sodipodi:rx="11.5625"
+ sodipodi:cy="25.75"
+ sodipodi:cx="31.1875"
+ id="path39153"
+ style="fill:url(#linearGradient21444);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.4857143;fill:none;stroke:url(#linearGradient21446);stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
+ 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"
+ id="path21414"
+ sodipodi:nodetypes="csssssscssscsssccssscscccsccssssccscsscccssssc" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ id="path2478"
+ style="fill:#3465a4;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssscsccsscsccssssscsscccsssc"
+ id="path39166"
+ 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"
+ style="opacity:0.51999996;fill:url(#radialGradient21448);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.5"
+ id="g24847"
+ transform="translate(162,248)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24867);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24849"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24851"
+ style="opacity:0.07999998;fill:url(#linearGradient24869);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24853"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24871);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:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24855"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,4.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24857" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24859"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24861" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24863"
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24873);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24865"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.5"
+ transform="translate(114,248)"
+ id="g24784">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z"
+ id="path24789"
+ style="fill:url(#linearGradient24809);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ style="opacity:0.07999998;fill:url(#linearGradient24811);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24791" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient24813);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 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ id="path24793"
+ sodipodi:nodetypes="csccsczc"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-ydpi="74.800003" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccssccc"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path24796"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24799"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 840.5,89 0,4.5"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24801" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24803"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ sodipodi:nodetypes="cccccccsc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsscccssssccc"
+ style="fill:none;stroke:#000000;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="path24805"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscc"
+ id="path24807"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ style="fill:none;stroke:url(#linearGradient24815);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ <g
+ transform="translate(0,-2)"
+ style="opacity:0.4;stroke:#3d361a;filter:url(#filter44473)"
+ id="g44424">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44406"
+ d="m 950.25,362 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44408"
+ d="M 948.25,354.25 944,350.00563 939.75,354.25"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ </g>
+ <g
+ transform="translate(617,273)"
+ id="g44334"
+ style="display:inline;enable-background:new">
+ <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="rect44336"
+ width="16"
+ height="16"
+ x="320"
+ y="73" />
+ <g
+ transform="translate(0,-21)"
+ id="g44338">
+ <g
+ id="g44340">
+ <g
+ transform="translate(0,21)"
+ id="g44342">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44344"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44346"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g44348">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ id="path44350"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path44352"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 328.5,107.5 5,0 m -7,-9 0,8.5 m -4.25,-7 4.5,-4.5"
+ id="path44354"
+ sodipodi:nodetypes="cccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(66,248)"
+ id="g24818"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24839);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24821"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24823"
+ style="opacity:0.07999998;fill:url(#linearGradient24841);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24825"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-16 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,17 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24843);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:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24827"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,7.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24829" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24831"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,98.75 0,14.75 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-16 34,0 m -29,-10 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24833" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-16 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-8 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24835"
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24845);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,96.500004 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,15.999996 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24837"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.4;filter:url(#filter44477)"
+ id="g44455">
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44446"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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,108.25 0,-4.25 4.25,0"
+ id="path44449"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="cs"
+ id="path44451"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="ccc"
+ id="path44453"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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
+ transform="translate(645,273.05)"
+ id="g44356"
+ style="display:inline;enable-background:new">
+ <rect
+ y="73"
+ x="341"
+ height="16"
+ width="16"
+ id="rect44358"
+ 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(0,-21)"
+ id="g44360">
+ <g
+ id="g44362">
+ <g
+ id="g44364">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44366"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#000000;stroke-width:3.5;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="path44368"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;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" />
+ </g>
+ <g
+ id="g44370">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;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 343,108.25 0,-4.25 4.25,0"
+ id="path44372"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;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 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44374"
+ sodipodi:nodetypes="cs" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path44376"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g44378"
+ transform="matrix(-1,0,0,-1,698,204)">
+ <g
+ id="g44380">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.5;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.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44382"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;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,108.25 0,-4.25 4.25,0"
+ id="path44384"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ id="g44386">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44388"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#e6e6e6;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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44390"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#e6e6e6;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" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ id="path44392" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44402);stroke-width:1.10000002;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 344.90625,106.59375 c 2.52573,2.51828 6.66805,2.52691 9.1875,0 l 0.5,-0.5"
+ id="path44394"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 350.5,99.5 4,0 0,-4"
+ id="path44396"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 347.5,103.5 -4.5,0 c -0.25,0 -0.5,0.25 -0.5,0.5 l 0,4.5"
+ id="path44398"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44404);stroke-width:1.10000002;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 345.59375,105.90625 c 2.07803,2.0719 5.36384,2.10325 7.53125,0.1875 L 354,105.25"
+ id="path44400"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g34977"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g21853-3"
+ transform="translate(856,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21855-8"
+ 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" />
+ <g
+ id="g21857-6">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21875-7-1-0-1);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21859-9"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21861-8"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ 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="cccc"
+ id="path21863-6"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21877-3-2-7-2);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21865-6"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21867-2"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ 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="cccc"
+ id="path21869-3"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21871-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:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21873-2"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ id="g34938"
+ transform="translate(63,-47)">
+ <path
+ id="path61236"
+ style="color:#000000;fill:url(#linearGradient34959-9-2-1);fill-opacity:1;fill-rule:nonzero;stroke:#ff0000;stroke-width:0.17893334;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 919.5,356.5067 0,-3 c 0,-1.73575 1.26424,-3 3,-3 l 5,0 c 1.73576,0 3,-1.26425 3,-3 l 0,-3.0064 2.5,0.006 c 2,0 3.5,2.5 3.5,6 0,3.5 -1.25,6 -3.5,6 -4.98134,0 -12.77318,0 -2.5,0 l 0,2.75 c 0,2.5 -2,3.24997 -5.5,3.24998 l 0,2e-5 c -3.5,0.0104 -5.5,-0.75 -5.5,-3.25 l 0,-2.7628"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssccsscsccsc" />
+ <path
+ sodipodi:nodetypes="cssssccsscsccsc"
+ inkscape:connector-curvature="0"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3.0064 -2.5,-0.006 c -2,0 -3.5,-2.5 -3.5,-6 0,-3.5 1.25,-6 3.5,-6 4.98134,0 12.77318,0 2.5,0 l 0,-2.75 c 0,-2.5 2,-3.24997 5.5,-3.24998 l 0,-2e-5 c 3.5,-0.0104 5.5,0.75 5.5,3.25 l 0,2.7628"
+ style="color:#000000;fill:url(#linearGradient34961-3-6-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.17893334;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61233" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccscccsccccsccccc"
+ id="path61167"
+ d="m 925,338.50002 c -3.5,10e-6 -5.5,0.74998 -5.5,3.24998 l 0,2.75 5.5,0 -8,0 c -2.25,0 -3.5,2.5 -3.5,6 0,3.5 1.5,6 3.5,6 l 2.5,0.0128 0,2.9872 c 0,2 2,3.01281 5.5,3.0128 3.5,-1e-5 5.5,-1.0128 5.5,-3.0128 l 0,-3 -5.5,0 8,0 c 2,0 3.5,-2.5 3.5,-6 0,-3.5 -1.5,-6 -3.5,-6 l -2.5,0.0128 0,-2.7628 c 0,-2.5 -2,-3.26045 -5.5,-3.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path61169"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.78431373;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 923,342 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path61220"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ d="m 929,359 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="359"
+ sodipodi:cx="928"
+ id="path61222"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <g
+ style="opacity:0.4"
+ id="g61345">
+ <path
+ style="fill:none;stroke:url(#linearGradient34963-5-9-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ id="path61333"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cszsc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient34965-1-5-2);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5 0,3 1.28917,5 2.5,5 l 1.5,0"
+ id="path61335"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccszsc" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ id="path61337"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 918.5,355.25 0,-1.75 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ id="path61339"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssc" />
+ <path
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)"
+ sodipodi:type="arc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34967-4-1-8);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61355"
+ sodipodi:cx="922"
+ sodipodi:cy="342"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 923,342 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" />
+ </g>
+ <g
+ style="opacity:0.8;stroke:#ff0000"
+ transform="matrix(-1,0,0,-1,1850,701)"
+ id="g34104">
+ <path
+ sodipodi:nodetypes="cszsc"
+ inkscape:connector-curvature="0"
+ id="path34106"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ style="fill:none;stroke:none" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path34108"
+ d="m 914.5,350.5 c 0,3 1.28917,5 2.5,5 l 1.5,0"
+ style="fill:none;stroke:url(#linearGradient34969-4-4-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path34110"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ style="fill:none;stroke:url(#linearGradient34971-5-0-9);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0"
+ id="path34113"
+ d="m 918.5,355.5 0,-2 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ style="fill:none;stroke:url(#radialGradient34973-2-5-7);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ d="m 923,342 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path34115"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34975-9-4-9);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5"
+ id="path34901"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccsc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g44575"
+ 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"
+ transform="translate(168,-42)">
+ <g
+ id="g43593"
+ transform="matrix(-1,0,0,1,677,525)">
+ <path
+ style="fill:none;stroke:#000000;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="path43595"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;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="path43597"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,-21,729)"
+ id="g44539">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44541"
+ d="m 347.25,100.25 -4,-4"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path44543"
+ d="m 343,100.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43599"
+ transform="matrix(-1,0,0,1,677,517)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43601"
+ d="M 347.25,108.25 343,104"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43603"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 333.5,622.5 0,3 m -4,-5 4.5,0"
+ id="path44489"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 329.25,625 2,-2"
+ id="path44491"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333,622 0,1 0,1.5 -1,0 0,-1.5 -1.5,0 0,-1 1.5,0 1,0 z"
+ id="path43605"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1,0,0,-1,-21,737)"
+ id="g44545">
+ <path
+ style="fill:none;stroke:#dcdcdc;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 347.25,108.25 343,104"
+ id="path44547"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;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 343,108.25 0,-4.25 4.25,0"
+ id="path44549"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path44551"
+ d="m 323.5,632.5 3,0 m -5,-4 0,4.5"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44553"
+ d="m 326,628.25 -2,2"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44555"
+ d="m 323,632 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44633"
+ 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"
+ inkscape:export-ydpi="90">
+ <g
+ id="g44671"
+ transform="matrix(-1,0,0,-1,662.9375,1247)">
+ <g
+ id="g44635"
+ transform="matrix(-1,0,0,1,677,525)">
+ <path
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44647"
+ transform="matrix(-1,0,0,1,677,517)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44649"
+ d="M 347.25,108.25 343,104"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path44651"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 332.5,621.5 -3,0 m 5,4 0,-4.5"
+ id="path44653"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 330,625.75 2,-2"
+ id="path44655"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333,622 0,1 0,1.5 -1,0 0,-1.5 -1.5,0 0,-1 1.5,0 1,0 z"
+ id="path44657"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44682"
+ transform="matrix(-1,0,0,-1,648.9375,1261)">
+ <g
+ transform="matrix(1,0,0,-1,-21,729)"
+ id="g44641">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44643"
+ d="m 347.25,100.25 -4,-4"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path44645"
+ d="m 343,100.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,-21,737)"
+ id="g44659">
+ <path
+ style="fill:none;stroke:#dcdcdc;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 347.25,108.25 343,104"
+ id="path44661"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;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 343,108.25 0,-4.25 4.25,0"
+ id="path44663"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path44665"
+ d="m 322.5,631.5 0,-3 m 4,5 -4.5,0"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44667"
+ d="m 326.75,629 -2,2"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44669"
+ d="m 323,632 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ clip-path="url(#clipPath45147)"
+ id="g45199">
+ <g
+ id="g45201"
+ clip-path="none"
+ transform="translate(1,1)">
+ <rect
+ y="261"
+ x="4"
+ height="16"
+ width="16"
+ id="rect45203"
+ 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(-96.98388,244)"
+ 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="g45205"
+ style="display:inline">
+ <path
+ id="path45207"
+ style="fill:url(#linearGradient45220);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 105.48388,31.25 6.25,-6 c 0.49692,0.284098 0.2225,0.232267 0.76612,0.25 2.20206,0.07183 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -4,1.792 -4,4 0,0.58349 0.009,0.250006 0.23388,0.75 l -6.25,6 0,2 1,1 2,0 z"
+ sodipodi:nodetypes="ccsccccccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ d="m 115.5,21.5 -2.25,2.25 m -1,-5.5 c -1.75,0 -4,2.25 -2.5,5 l -1.26612,0.25 -5,5 0,1.75"
+ 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"
+ id="path45209"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsccccccccsccccccc"
+ d="m 105.48388,31.5 5.5,-5.5 0.25,-0.5 1.26612,0 c 2.73388,0 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -3.96454,1.25 -4,4 l -0.0161,1.25 -0.5,0.25 -5.5,5.5 0,2 1,1 2,0 -2e-5,0 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;stroke-dashoffset:0"
+ id="path45211"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ d="m 109.98388,25 -5,5"
+ style="fill:none;stroke:#afc6e9;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path45214"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path45216"
+ style="fill:none;stroke:#336abd;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 109.48388,24.5 -4,4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45218"
+ width="1"
+ height="1"
+ x="103.98388"
+ y="29" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g45262">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect45264"
+ width="16"
+ height="16"
+ x="-420"
+ y="577"
+ transform="scale(-1,1)" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 412,585 0,-6"
+ id="path45266"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path45268"
+ d="m 412,585 0,-6"
+ style="fill:none;stroke:#b3b3b3;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ style="fill:none;stroke:#ffffff;stroke-width:2.56570244;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="g45270"
+ transform="matrix(0.5478212,-0.56064,0.5419177,0.5545983,197.19518,557.21673)"
+ 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
+ sodipodi:open="true"
+ transform="matrix(0.9615911,0.00541935,0.00537191,0.9740527,43.776178,107.51876)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:4.37432003;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="path45272"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="0.063198177"
+ sodipodi:end="4.6607369" />
+ <path
+ sodipodi:end="4.6607369"
+ sodipodi:start="0.063198177"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path45274"
+ style="fill:none;stroke:#b3b3b3;stroke-width:2.65110302;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:type="arc"
+ transform="matrix(0.9615911,0.00541935,0.00537191,0.9740527,43.776178,107.51876)"
+ sodipodi:open="true" />
+ <path
+ sodipodi:open="true"
+ transform="matrix(1.0558925,0.00528428,0.00523802,1.0695762,31.432317,96.175729)"
+ sodipodi:type="arc"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient45283);stroke-width:1.20716298;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="path45276"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="0.063198177"
+ sodipodi:end="4.6607369" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.6607369"
+ sodipodi:start="0.063198177"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path45278"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient45285);stroke-width:1.44679213;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:type="arc"
+ transform="matrix(0.8810135,0.00553476,0.00548631,0.8924309,54.323627,117.21103)" />
+ </g>
+ <path
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 411.5,585 0,-6"
+ id="path45280"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(517.99163,649)"
+ id="g45287">
+ <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"
+ style="opacity:0.25;fill:none;stroke:#000000;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"
+ id="path45290"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#0b1e00;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"
+ id="path45302"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path45294"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g42952"
+ style="display:inline;enable-background:new"
+ transform="translate(433,-61)">
+ <rect
+ y="554"
+ x="-113"
+ height="16"
+ width="16"
+ id="rect42954"
+ 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(-252,462.99988)"
+ id="g42956">
+ <g
+ id="g42958"
+ transform="translate(-179,199.50012)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;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"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ id="path42960"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g42962"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42964"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ style="fill:#808080;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" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path42966"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#cccccc;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="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42968"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient42988);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42970"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#f2f2f2;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="path42972"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient42990);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect42974"
+ style="opacity:0.18000004;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42976"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <g
+ 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(0.7882544,0,0,0.7883038,-210.45268,388.9974)"
+ id="g42978"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.6425292,0,0,0.642531,44.523834,146.81699)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.97436094;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42980"
+ 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
+ transform="matrix(-0.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)"
+ 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="path42982"
+ style="opacity:0.8;fill:url(#linearGradient42992);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <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="path42984"
+ style="fill:none;stroke:url(#linearGradient42994);stroke-width:2.54167628;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4991181,0,0,0.4991107,63.460522,163.7471)" />
+ </g>
+ <path
+ id="path42986"
+ d="m -102.5625,554.75 c -0.0429,0.005 -0.0849,0.0154 -0.125,0.0312 l -4.5,1.75 c -0.1919,0.0756 -0.31653,0.26258 -0.3125,0.4688 l 0,6.5 c 0.003,0.18741 0.11203,0.35691 0.28125,0.4375 l 4.5,2.25 c 0.13787,0.0682 0.29963,0.0682 0.4375,0 l 4.499997,-2.25 c 0.169224,-0.0806 0.278188,-0.25009 0.28125,-0.4375 l 0,-6.5 c 0.004,-0.2062 -0.120622,-0.39315 -0.3125,-0.46875 l -4.499997,-1.75 c -0.0792,-0.0318 -0.16537,-0.0426 -0.25,-0.0312 l 0,-5e-5 z"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient42996);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" />
+ </g>
+ <g
+ id="g43828">
+ <g
+ transform="translate(0,128)"
+ id="g24024">
+ <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="rect22150"
+ width="16"
+ height="16"
+ x="299"
+ y="365" />
+ <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="path12337"
+ d="m 304.20488,366.47791 8.33334,0 0,13 -11,0 -1e-5,-10 2.66667,-3 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient14204);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,365.56499,31.43979)"
+ sodipodi:nodetypes="ccc"
+ id="path12339"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12341"
+ d="m 301.01612,370 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12343"
+ style="fill:none;stroke:url(#linearGradient14198);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 302.51612,371.00001 0,7.5 m 3.5,-11 5.5,0"
+ 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 301.53822,368.97791 0,10.5 11,0 0,-13 -8.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="path12345"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="translate(-454.0088,290)"
+ mask="url(#mask43822)"
+ sodipodi:nodetypes="cccccccc"
+ id="path43815"
+ d="m 765.0088,212.5 -3.9824,3.5 -0.0176,-2 -6.9736,0 -0.0132,-3 6.9868,0 0.004,-2 z"
+ style="opacity:0.93999993;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:transform-center-x="-2"
+ inkscape:transform-center-y="1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43838"
+ transform="translate(0,-21)"
+ style="opacity:0.4">
+ <g
+ id="g43840"
+ transform="translate(0,128)">
+ <rect
+ y="365"
+ x="299"
+ height="16"
+ width="16"
+ id="rect43842"
+ 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
+ style="fill:url(#linearGradient43856);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 304.20488,366.47791 8.33334,0 0,13 -11,0 -1e-5,-10 2.66667,-3 0,0 0,0 0,0 z"
+ id="path43844"
+ 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
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path43846"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,365.56499,31.43979)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 301.01612,370 4,0 0,-4 -4,4 z"
+ id="path43848"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 302.51612,371.00001 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient43858);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path43850"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path43852"
+ 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 301.53822,368.97791 0,10.5 11,0 0,-13 -8.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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:transform-center-y="1"
+ inkscape:transform-center-x="-2"
+ style="opacity:0.93999993;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 765.0088,212.5 -3.9824,3.5 -0.0176,-2 -6.9736,0 -0.0132,-3 6.9868,0 0.004,-2 z"
+ id="path43854"
+ sodipodi:nodetypes="cccccccc"
+ mask="url(#mask43822)"
+ transform="translate(-454.0088,290)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g46790"
+ transform="translate(0,12)" />
+ <g
+ id="g46890" />
+ <g
+ id="g46912"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ y="107"
+ x="23"
+ height="16"
+ width="16"
+ id="rect46788"
+ style="opacity:0.01000001;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"
+ transform="matrix(-1,0,0,1,0,12)" />
+ <g
+ style="opacity:0.55;display:inline;enable-background:new"
+ transform="translate(-22,30)"
+ id="g46766">
+ <g
+ id="g46768"
+ transform="translate(23.01472,-88)">
+ <path
+ id="path46770"
+ style="fill:none;stroke:url(#linearGradient46780);stroke-width:3.29999995;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 -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ 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
+ 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"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46782);stroke-width:1.70000005;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="path46772"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(24.03125,-88)"
+ id="g46774">
+ <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"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ style="fill:none;stroke:url(#linearGradient46784);stroke-width:3.29999995;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="path46776"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46778"
+ style="fill:none;stroke:url(#linearGradient46786);stroke-width:1.70000005;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 -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ 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>
+ </g>
+ <g
+ id="g46860"
+ transform="translate(18.998123,-58.00355)"
+ style="display:inline;enable-background:new">
+ <path
+ id="path46862"
+ d="m -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ style="fill:none;stroke:#462300;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"
+ 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="path46864"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-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;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(26.01365,-55.00527)"
+ id="g46866">
+ <path
+ style="fill:none;stroke:#462300;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 -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ id="path46868"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path46870"
+ 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>
+ </g>
+ <g
+ id="g46928"
+ 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"
+ inkscape:export-ydpi="90">
+ <g
+ transform="translate(-20,0)"
+ id="g46800">
+ <rect
+ transform="scale(-1,1)"
+ style="opacity:0.01000001;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"
+ id="rect46802"
+ width="16"
+ height="16"
+ x="24"
+ y="119" />
+ <g
+ id="g46804"
+ transform="translate(-22,18)"
+ style="opacity:0.55;display:inline;enable-background:new">
+ <g
+ transform="translate(23.01472,-76)"
+ id="g46806">
+ <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"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46818);stroke-width:3.29999995;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="path46808"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46810"
+ style="fill:none;stroke:url(#linearGradient46820);stroke-width:1.70000005;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 -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ 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>
+ <g
+ id="g46812"
+ transform="translate(24,-76)">
+ <path
+ id="path46814"
+ style="fill:none;stroke:url(#linearGradient46822);stroke-width:3.29999995;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 -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ 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
+ 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"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ style="fill:none;stroke:url(#linearGradient46824);stroke-width:1.70000005;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="path46816"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-4.98635,-46.00527)"
+ id="g46872">
+ <path
+ style="fill:none;stroke:#462300;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 -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ id="path46874"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path46876"
+ 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>
+ <g
+ id="g46878"
+ transform="translate(-0.98635,-58.00527)"
+ style="display:inline;enable-background:new">
+ <path
+ id="path46880"
+ d="m -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ style="fill:none;stroke:#462300;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"
+ 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="path46882"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-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;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-4.023135,-51.99484)"
+ id="g46884">
+ <path
+ style="fill:none;stroke:#462300;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 -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ id="path46886"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path46888"
+ 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>
+ </g>
+ <g
+ id="g46958"
+ 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"
+ inkscape:export-ydpi="90">
+ <g
+ id="g46960"
+ transform="translate(22,12)">
+ <rect
+ y="107"
+ x="24"
+ height="16"
+ width="16"
+ id="rect46962"
+ style="opacity:0.01000001;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"
+ transform="scale(-1,1)" />
+ <g
+ style="opacity:0.55;display:inline;enable-background:new"
+ transform="translate(-22,18)"
+ id="g46964">
+ <g
+ id="g46966"
+ transform="translate(23.01472,-88)">
+ <path
+ id="path46968"
+ style="fill:none;stroke:url(#linearGradient46990);stroke-width:3.29999995;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 -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ 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
+ 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"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46992);stroke-width:1.70000005;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="path46970"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(24.140625,-88)"
+ id="g46972">
+ <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"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ style="fill:none;stroke:url(#linearGradient46994);stroke-width:3.29999995;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="path46974"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46976"
+ style="fill:none;stroke:url(#linearGradient46996);stroke-width:1.70000005;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 -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ 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>
+ <g
+ transform="translate(23.01472,-88)"
+ id="g46978">
+ <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"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46998);stroke-width:3.29999995;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="path46980"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46982"
+ style="fill:none;stroke:url(#linearGradient47000);stroke-width:1.70000005;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 -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ 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>
+ </g>
+ </g>
+ <g
+ transform="translate(24,-58)"
+ id="g46984"
+ style="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"
+ sodipodi:nodetypes="cc"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ style="fill:none;stroke:#462300;stroke-width:3.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"
+ id="path46986"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46988"
+ style="fill:none;stroke:#ffc17d;stroke-width:1.70000005;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 -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ 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>
+ </g>
+ <g
+ transform="translate(-1,0)"
+ id="g24914">
+ <g
+ id="g25430"
+ transform="translate(0,-21)">
+ <rect
+ ry="0"
+ rx="0"
+ transform="translate(1,0)"
+ y="514"
+ x="446"
+ height="16"
+ width="16"
+ id="rect25424"
+ style="opacity:0;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" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ id="g24916"
+ transform="translate(337,128)">
+ <rect
+ rx="0.019097222"
+ y="386"
+ x="110"
+ height="11"
+ width="11"
+ id="rect24918"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.019097222" />
+ <g
+ id="g24920">
+ <path
+ sodipodi:nodetypes="cccccccccccsccccccccccccccscccc"
+ style="fill:url(#linearGradient25449);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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 116.53125,386.5 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.28156 0.12508,0.53133 0.3125,0.71875 L 113,392 c -0.18742,-0.18742 -0.46844,-0.5 -0.75,-0.5 l -0.75,0 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.56312 0.46813,1.03125 1.03125,1.03125 l 0.9375,0 c 0.0103,0 0.021,3e-4 0.0312,0 -3e-4,0.0102 0,0.021 0,0.0312 l 0,0.9375 c 0,0.56312 0.46813,1.03126 1.03125,1.03125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.28156 -0.10164,-0.53133 -0.28125,-0.71875 l 2.625,-2.625 c 0.18742,0.18742 0.43719,0.3125 0.71875,0.3125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.56312 -0.43688,-1.03125 -1,-1.03125 l -0.96875,0 c -0.0103,0 -0.021,-3e-4 -0.0312,0 3e-4,-0.0102 0,-0.021 0,-0.0312 l 0,-0.9375 c 0,-0.56312 -0.46813,-1.03125 -1.03125,-1.03125 l -0.9375,0 z"
+ id="path24923"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 111.5,393.5 0,-0.75 0.25,-0.25 1.75,0 3,-3 0,-1.75 0.25,-0.25 0.75,0"
+ id="path24925"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path24927"
+ d="m 118.75,389.5 0.75,0 m -6,6 0,-0.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="393"
+ x="114"
+ height="1"
+ width="1"
+ id="rect24929"
+ style="opacity:0.2;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" />
+ <rect
+ style="opacity:0.2;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"
+ id="rect24931"
+ width="1"
+ height="1"
+ x="117"
+ y="390" />
+ </g>
+ </g>
+ <g
+ transform="translate(22.915112,0.02875225)"
+ id="g24933">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 430.5,525.5329 0,2 1,1 2,0 2,-2.0329 0,-2 -1,-1 -2,0 -2,2.0329 z"
+ id="path24939"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path24941"
+ d="m 433.5,522.4671 0,1.75 1,1.25 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:none;stroke:url(#linearGradient25451);stroke-width:1.29999995;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 433.5,522.4671 0,2.0329 1,0.9671 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ id="path24945"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24954"
+ d="m 434.5,523.5 -2,0"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path24956"
+ d="m 430.5,525.5 0,2 1,1 2,0 2,-2 0,-2 -1,-1 -2,0 -2,2 z"
+ style="fill:none;stroke:url(#linearGradient25453);stroke-width:1.29999995;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:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 434.08489,525.47125 2.25,0"
+ id="path24958"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24960"
+ d="M 434.33489,525.47125 436.5,525.4671"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25426"
+ width="0"
+ height="0.25"
+ x="462.25"
+ y="515"
+ transform="translate(1,0)"
+ rx="1.3125"
+ ry="0.25" />
+ </g>
+ <g
+ transform="translate(0.00572791,126.98898)"
+ id="g25026">
+ <rect
+ y="403.99695"
+ x="-382.01102"
+ height="16"
+ width="16"
+ id="rect25028"
+ 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="matrix(0,-1,1,0,0,0)" />
+ <g
+ id="g25030">
+ <rect
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ rx="2.1489482"
+ ry="2.143424"
+ y="-559.32709"
+ x="-33.931175"
+ height="5.651536"
+ width="8.4518671"
+ id="rect25032"
+ 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:0.5" />
+ <rect
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ 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:0.5"
+ id="rect25034"
+ width="8.5198517"
+ height="5.5904222"
+ x="-28.308893"
+ y="-557.84644"
+ ry="2.1434233"
+ rx="2.1489475" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ id="path25036"
+ d="m 411.49427,375.51102 -0.5,-0.5 c -0.69131,-0.69131 -0.84611,-2.14587 0.0258,-3.01533 l 2.98873,-2.98076 c 0.87178,-0.86946 2.29697,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ style="fill:none;stroke:url(#linearGradient25117);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m -26.159946,-552.25601 c -1.190517,0 -2.148947,-0.95597 -2.148947,-2.14343"
+ id="rect25114"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#radialGradient25457);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 411.49427,375.51102 -0.5,-0.5 c -0.69131,-0.69131 -0.84611,-2.14587 0.0258,-3.01533 l 2.98873,-2.98076 c 0.87178,-0.86946 2.29697,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ id="path25455"
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccczz"
+ d="m 407.51079,379.37902 c 0.56229,0.50812 1.81497,0.33519 2.49825,-0.3481 l 2.96969,-3.09463 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.96969,3.09462 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 10e-6,-9e-5 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient25106);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25038"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25040"
+ style="opacity:0.7;fill:none;stroke:url(#radialGradient25048);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m 407.4987,379.35912 c 0.56229,0.50812 1.81497,0.33519 2.49825,-0.3481 l 2.98178,-3.07473 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.98178,3.07472 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 10e-6,-9e-5 0,0 0,0 z"
+ sodipodi:nodetypes="ccccccczz"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m -27.628256,-559.32709 c 1.190517,0 2.148948,0.95597 2.148948,2.14343"
+ id="rect25127"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient25117);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 417.50245,369.52434 0.49841,0.4984 c 0.68807,0.68805 0.86319,2.11415 -0.004,2.98828 l -2.96882,2.99286 c -0.68052,0.68603 -1.74799,0.71589 -2.49825,0.34809 -0.18628,-0.0913 -0.39866,-0.20409 -0.53552,-0.34095 l -1,-1"
+ id="path25042"
+ sodipodi:nodetypes="csssssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23496"
+ transform="matrix(-1,0,0,1,614,0)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="299"
+ x="52"
+ height="16"
+ width="16"
+ id="rect23456"
+ 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
+ id="g23458"
+ transform="matrix(0,1,1,0,203.99437,-269)">
+ <g
+ id="g23460">
+ <g
+ id="g23462"
+ transform="translate(0,21)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 327,76 0,10.00563 2,2 3,0 2,-2 0,-3.25"
+ id="path23464"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 330.25,79.25563 327,76 l -3.25,3.25563"
+ id="path23466"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23468"
+ transform="translate(0,21)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path23470"
+ d="m 327,76 0,10.00563 2,2 3,0 2,-2 0,-3"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path23473"
+ d="M 330.25,79.25563 327,76.005631 323.75,79.25563"
+ style="fill:none;stroke:#dcdcdc;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"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23475"
+ d="m 333.5,106.50563 0,-2.75"
+ 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"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(0,1,1,0,269,-203.99437)"
+ y="56"
+ x="303"
+ height="1"
+ width="1.5"
+ id="rect23492"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23547"
+ d="m 330,100.50563 -1.25,-1.25"
+ style="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"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23494"
+ width="1.5"
+ height="1"
+ x="99.00563"
+ y="328"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23559);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 323.25,100.25563 c 0,0.25 0.25,0.5 0.5,0.5 m 2.75,-1.24437 0,7.74437 2.25,2.25 3.5,0 2,-2"
+ id="path23550"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path23552"
+ d="m 323.25,100.00563 3.5,-3.5 0.5,0 3.5,3.5"
+ style="fill:none;stroke:url(#linearGradient23557);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>
+ </g>
+ <g
+ id="g23511"
+ 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"
+ id="rect23513"
+ width="16"
+ height="16"
+ x="52"
+ y="299"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ transform="matrix(0,1,1,0,203.99437,-269)"
+ id="g23515">
+ <g
+ id="g23518">
+ <g
+ transform="translate(0,21)"
+ id="g23520">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path23523"
+ d="m 327,76 0,10.00563 2,2 3,0 2,-2 0,-3.25"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path23525"
+ d="M 330.25,79.25563 327,76 l -3.25,3.25563"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g23527">
+ <path
+ style="fill:none;stroke:#dcdcdc;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 327,76 0,10.00563 2,2 3,0 2,-2 0,-3"
+ id="path23530"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;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 330.25,79.25563 327,76.005631 323.75,79.25563"
+ id="path23532"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 326.5,99.5 0,6.50563 m 3,2.5 2,0 2,-2 0,-2.75"
+ id="path23534"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23543);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 323.25,100.00563 3.5,-3.499999 0.5,0 3.5,3.499999"
+ id="path23536"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23539"
+ width="1.5"
+ height="1"
+ x="303"
+ y="56"
+ transform="matrix(0,1,1,0,269,-203.99437)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="328"
+ x="99.00563"
+ height="1"
+ width="1.5"
+ id="rect23541"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </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"
+ style="display:inline">
+ <rect
+ y="69"
+ x="62"
+ height="16"
+ width="16"
+ id="rect27864"
+ 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"
+ 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,0,0,1,461.01011,-167)"
+ id="g27866"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path27868"
+ d="m 392.5,239.5 -4.98989,4.75 0,0.5 4.98989,4.75 1.01011,-1e-5 0.0368,-9.96874 L 392.5,239.5 z"
+ style="fill:url(#linearGradient27872);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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path27870"
+ d="m 392.51011,248.24999 0,-7.49999 -4,3.75"
+ style="fill:none;stroke:url(#linearGradient27874);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,70,704.00001)"
+ id="g27876"
+ style="display:inline">
+ <rect
+ y="69"
+ x="82"
+ height="16"
+ width="16"
+ id="rect27878"
+ 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"
+ 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="g27880"
+ transform="matrix(0,-1,1,0,-153.98989,467.9919)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="color:#000000;fill:url(#linearGradient27886);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;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 392.49192,239.48989 -5.00001,4.75 0,0.5 5.00001,4.75 1,0 0,-10 -1,0 z"
+ id="path27882"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient27902);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.49191,248.23989 -4.00002,-3.75 4.00002,-3.75"
+ id="path27884"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-231,-21)"
+ id="g29960"
+ 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">
+ <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="rect29962"
+ width="16"
+ height="16"
+ x="-336"
+ y="283"
+ transform="scale(-1,1)" />
+ <g
+ transform="translate(362,20.75)"
+ id="g29964"
+ mask="none"
+ clip-path="none">
+ <path
+ id="path29966"
+ d="m -35,273.5 0,-10.5 8,3.75 0,10.75 -8,-4 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ 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" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient29988);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -35,273.5 0,-10.5 8,3.75 0,10.75 -8,-4 z"
+ id="path29968"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path29970"
+ d="m 334.5,287.75 -7,-3.25 0,9"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient29990);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.6827482,0,0,0.68258425,246.77037,137.93793)"
+ id="g29972"
+ style="opacity:0.75;display:inline;enable-background:new"
+ mask="url(#mask29419)"
+ clip-path="url(#clipPath28964)">
+ <path
+ transform="matrix(0.75,0,0,0.75,28.052144,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#162d50;stroke-width:1.75781369;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path29974"
+ 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
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,208.02475,314.325)"
+ 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="path29976"
+ style="color:#000000;fill:url(#linearGradient29773-5);fill-opacity:1;fill-rule:nonzero;stroke:none;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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.65;fill:none;stroke:#ffffff;stroke-width:2.56764865;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:new"
+ id="path29978"
+ 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"
+ transform="matrix(0.5705005,0,0,0.5705012,51.746079,156.18087)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g29980"
+ transform="matrix(0.6827482,0,0,0.68258425,236.77037,141.93793)"
+ 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">
+ <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="path29982"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.56250119;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient29994);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path29984"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29986"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:2.56764865;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:new"
+ 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" />
+ </g>
+ </g>
+ <g
+ id="g29313"
+ transform="translate(-21,2)"
+ style="opacity:0.5">
+ <rect
+ y="176"
+ x="425"
+ height="16"
+ width="16"
+ id="rect29315"
+ 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="g29317"
+ transform="translate(263,148.99995)">
+ <g
+ transform="matrix(0.786268,0,0,0.7877987,82.392071,-41.848894)"
+ 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="g29320">
+ <path
+ transform="matrix(0.874026,0,0,0.873701,-3.948211,-5.552958)"
+ 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="path29323"
+ style="fill:url(#linearGradient29334);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.16319752;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(0.398744,0,0,-0.395524,58.82401,144.1804)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29336);stroke-width:3.20095801;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path29326"
+ 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" />
+ </g>
+ <path
+ transform="matrix(0.186538,0,0,-0.189699,145.3693,57.36304)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29338);stroke-width:5.31599474;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path29328"
+ 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\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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path29330"
+ style="fill:none;stroke:url(#linearGradient29340);stroke-width:1.77120221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.566689,0,0,-0.562497,95.23056,101.3747)" />
+ <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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path29332"
+ style="fill:none;stroke:url(#linearGradient29342);stroke-width:2.35577321;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ 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">
+ <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>
+ </g>
+ <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>
+ </g>
+ <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>
+ </g>
+ </g>
+ <g
+ transform="translate(315,-441)"
+ id="g31816">
+ <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"
+ width="16"
+ height="16"
+ x="-247"
+ y="514" />
+ <g
+ transform="translate(0,-21)"
+ id="g31820">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 -245.25,538 12.5,0"
+ id="path31822"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31824"
+ d="m -245.25,538 12.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -245.5,538.5 -0.25,-0.5 0.25,-0.5 13,0"
+ id="path31826"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31828"
+ d="m -242.5,543.5 0,-1 7,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 0,-1 1,0"
+ id="path31830"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31832"
+ d="m -242.25,543 6.5,0"
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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="color:#000000;fill:none;stroke:#d2d2d2;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 -242.25,543 6.5,0"
+ id="path31834"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31836"
+ d="m -242.5,543.5 -0.25,-0.5 0.25,-0.5 7,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 -239.25,548 0.5,0"
+ id="path31838"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840"
+ d="m -239.25,548 0.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g31846"
+ 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"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31848"
+ width="16"
+ height="16"
+ x="-186"
+ y="493" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 -177.25,499 5.25,0 0,0.5 -5.03256,7.02015 0,0.5 L -171.75,507"
+ id="path31857"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path31859"
+ d="m -177.25,499 5.25,0 0,0.5 -5.03256,7.02015 0,0.5 L -171.75,507"
+ style="color:#000000;fill:none;stroke:url(#linearGradient31946);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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -175.25,506.5 3.75,0 m -6.5,-8 6.25,0 m -1.75,2 -4,5.75 0,1"
+ id="path31861"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter50168-9);enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ d="m -183.4375,493.25 a 1.7525094,1.7525094 0 0 0 0.1875,3.5 l 1.875,0 0.125,0 c 0.30188,0 0.5,0.19814 0.5,0.5 l -2.25,0 a 1.750175,1.750175 0 0 0 -1.25,0.5 l -1,1 a 1.750175,1.750175 0 0 0 -0.5,1.25 l 0,2 a 1.750175,1.750175 0 0 0 0.5,1.25 l 1,1 a 1.750175,1.750175 0 0 0 1.25,0.5 l 2.5,0 a 1.750175,1.750175 0 0 0 1.25,-0.5 l 0.25,0.25 a 1.767767,1.767767 0 1 0 2.5,-2.5 l -0.75,-0.75 0,-1.9375 a 1.750175,1.750175 0 0 0 0,-0.5 1.750175,1.750175 0 0 0 0,-0.1875 l 0,-1.09375 a 1.750175,1.750175 0 0 0 0,-0.28125 1.750175,1.750175 0 0 0 -0.125,-0.6875 c -0.004,-0.0221 -0.0268,-0.0405 -0.0312,-0.0625 a 1.750175,1.750175 0 0 0 -0.0312,-0.0937 c -0.35614,-1.57819 -1.57955,-2.76466 -3.1875,-3.03125 a 1.750175,1.750175 0 0 0 -0.625,-0.125 l -0.1875,0 -1.8125,0 a 1.750175,1.750175 0 0 0 -0.1875,0 z m 1.1875,7.5 1.5,0 0,0.5 -1.5,0 0,-0.5 z"
+ id="path31869"
+ clip-path="url(#clipPath50172-0)"
+ mask="none"
+ transform="translate(-0.05279266,-2.0457936e-6)"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31871"
+ transform="translate(-0.25906372,0.25457764)"
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 -180.99094,494.73636 c 1.24765,0 2.25907,1.01142 2.25907,2.25906 m -0.009,0 0,4.75 1.25,1.25 m -2.75,-0.25 -2.5,0 -1,-1 0,-2 1,-1 4,0 m -4.25,-4 2,0"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -180.99094,494.73636 c 1.24765,0 2.25907,1.01142 2.25907,2.25906 m -0.009,0 0,4.75 1.25,1.25 m -2.75,-0.25 -2.5,0 -1,-1 0,-2 1,-1 4,0 m -4.25,-4 2,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient31948);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"
+ transform="translate(-0.25906372,0.25457764)"
+ id="path31873"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path31875"
+ d="m -179.5,495.25 -1.25,-0.75 -2.75,0 -0.25,0.5 0.24997,0.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31879"
+ d="m -184.5,502 0,-2.25 1.25,-1.25 3.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31881"
+ d="m -182.25,502.5 2,0 0.75,-0.75 0,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g31883"
+ transform="translate(189,-315)">
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g31885"
+ transform="translate(-307.59866,-9.53021)">
+ <g
+ id="g31887"
+ transform="translate(2.6147747,150.03012)"
+ 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="g31889">
+ <rect
+ transform="translate(-2.6147747,-150.03012)"
+ y="397.53015"
+ x="165.59866"
+ height="16"
+ width="16"
+ id="rect31891"
+ 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="247.5"
+ x="162.99997"
+ height="16"
+ width="15.000031"
+ id="rect31893"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="m 167.48389,249.00007 0,2 m 6,-2 0,2"
+ style="fill:none;stroke:#162d50;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path31896"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:url(#linearGradient31950);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect31898"
+ width="11.999973"
+ height="13.000053"
+ x="164.48389"
+ y="250.00002"
+ rx="1.0000547"
+ ry="1.0000547" />
+ <path
+ sodipodi:nodetypes="cc"
+ d="m 165.48389,262.00007 0,-11"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path31900"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31902"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient31952);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 175.48389,251.00007 0,11 -10,0 0,-11 10,0 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(346.98389,-98.49991)"
+ style="color:#000000;fill:url(#linearGradient31954);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 -181.5,348.96875 c -0.0977,0 -0.2593,0.0405 -0.375,0.15625 -0.1157,0.1157 -0.15625,0.27731 -0.15625,0.375 l 0,7 2.53125,2.53125 10.53125,0 0,-1.15625 c -1.11643,-0.22954 -2,-1.19538 -2,-2.375 l 0,-6 c 0,-0.0977 -0.0405,-0.2593 -0.15625,-0.375 -0.1157,-0.1157 -0.27731,-0.15625 -0.375,-0.15625 l -10,0 z"
+ id="path31905"
+ sodipodi:nodetypes="cscccccccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(346.98389,-98.49991)"
+ style="color:#000000;fill:none;stroke:url(#linearGradient31956);stroke-width:1px;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 -181.5,349.5 0,6.75 2.25,2.25 9.7813,0.0312 -0.0313,-0.2812 c -1.11143,-0.43566 -2,-1.49177 -2,-2.75 l 0.0313,-6.00005 -10.0313,5e-5 z"
+ id="path31907"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="color:#000000;fill:url(#linearGradient31958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.4000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31909"
+ width="11.000002"
+ height="4.0000105"
+ x="164.98389"
+ y="250.50008"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 165.48389,254.50007 0,-3.5 10,0 0,3.5"
+ style="opacity:0.45;fill:none;stroke:url(#linearGradient31960);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path31912"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31914"
+ style="opacity:0.8;fill:none;stroke:#162d50;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 167.48389,249.00007 0,2 m 6,-2 0,2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -181.5,348.5 c -0.13851,0 -0.25527,0.0433 -0.375,0.0937 -0.23945,0.10094 -0.43031,0.2918 -0.53125,0.53125 -0.0505,0.11973 -0.0937,0.23649 -0.0937,0.375 l 0,7 0,4 c 0,0.55403 0.44597,1 1,1 l 10,0 c 0.55403,0 1,-0.44597 1,-1 l 0,-1 2,0 0,-2 c -1.09489,0 -2,-0.90511 -2,-2 l 0,-6 c 0,-0.125 -0.0391,-0.25781 -0.0937,-0.375 -0.10094,-0.23945 -0.2918,-0.43031 -0.53125,-0.53125 -0.11973,-0.0505 -0.23649,-0.0937 -0.375,-0.0937 l -10,0 z"
+ transform="translate(346.98389,-98.49991)"
+ id="path31917"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31919"
+ style="fill:none;stroke:url(#linearGradient31962);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 167.48389,249.00007 0,2 m 6,-2 0,2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -200.5,372.5 0.75,0 1.25,-1.25 0,-0.75"
+ id="path31921"
+ transform="translate(367.98389,-119.49993)"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31923"
+ d="m 173.48389,253.00007 0.75,0 1.25,-1.25 0,-0.75"
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31925"
+ d="m 167.48389,252.00007 0.5,0 0.5,-0.5 0,-0.5"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.48389,252.00007 0.5,0 0.5,-0.5 0,-0.5"
+ id="path31927"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 165.48389,254.00007 10,0"
+ id="path31929"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path31931"
+ d="m -170.5,359.5 c -3.30603,0.005 -5.7501,0 -9,0 l -1.75,-1.75"
+ style="opacity:0.5;color:#000000;fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(346.98389,-98.49991)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ style="color:#000000;fill:none;stroke:#000000;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 170.48389,259.00009 c -0.25,0 -0.64081,-0.31307 -0.82432,-0.78241 -0.17644,-0.45125 -0.17568,-0.96756 -0.17568,-2.21759"
+ id="path31933"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31935"
+ d="m 173.48389,259.00009 c -0.25,0 -0.64081,-0.31307 -0.82432,-0.78241 -0.17644,-0.45125 -0.17568,-0.96756 -0.17568,-2.21759"
+ style="color:#000000;fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <rect
+ ry="0"
+ rx="0"
+ y="396"
+ x="-136"
+ height="1"
+ width="1"
+ id="rect31937"
+ style="color:#000000;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" />
+ <rect
+ style="color:#000000;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"
+ id="rect31939"
+ width="1"
+ height="1"
+ x="-133"
+ y="396"
+ rx="0"
+ ry="0" />
+ <rect
+ y="398.25"
+ x="-136"
+ height="0.7500025"
+ width="0.50001091"
+ id="rect31941"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31943"
+ width="0.50001091"
+ height="0.7500025"
+ x="-133.00002"
+ y="398.25" />
+ </g>
+ <g
+ 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\screw modifier.png"
+ transform="translate(-105,-42)"
+ id="g31976">
+ <rect
+ y="283"
+ x="236"
+ height="16"
+ width="16"
+ id="rect31978"
+ 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" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path31980"
+ d="m 244,283.5 c -3.49999,0 -5.5,1 -5.49999,2.5 l -1e-5,1.75 3,3 0,6.5 1.25,1.25 2.5,0 1.25,-1.25 0,-6.5 3,-3 0,-1.75 c 0,-1.5 -1.99999,-2.5 -5.5,-2.5 z"
+ style="color:#000000;fill:url(#linearGradient32236);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:url(#linearGradient32238);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 244,287.5 c -3.49999,0 -5.5,-1 -5.49999,-2.5 l -1e-5,2.75 3,3 5,0 3,-3 0,-2.75 c 0,1.5 -1.99999,2.5 -5.5,2.5 z"
+ id="path31982"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path31985"
+ d="m 248.99999,286.24149 c 0,1.12925 -1.66739,2.25851 -5.01168,2.25851 -3.34426,0 -4.99267,-1.12926 -4.99267,-2.25851"
+ style="fill:none;stroke:url(#linearGradient32240);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
+ 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:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 246.5,290.75 3,-3 0,-1.75 c 0,-1.5 -1.99999,-2.5 -5.5,-2.5 -3.49999,0 -5.5,1 -5.49999,2.5 l -1e-5,1.75 3,3"
+ id="path31989"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#89a9d9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.29137695;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 249,285.86765 c 0,0.99654 -1.81092,1.88235 -5,1.88235 -3.18906,0 -5,-0.88581 -5,-1.88235 0,-1.36765 2.61499,-2.11765 5,-2.11765 2.38501,0 5,0.75 5,2.11765 z"
+ id="path31991"
+ sodipodi:nodetypes="czszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31993"
+ d="m 239.5,287.5 3,3"
+ style="opacity:0.7;color:#000000;fill:none;stroke:url(#linearGradient32242);stroke-width:0.99999994;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path31996"
+ d="m 241.5,290.75 0,6.5 1.25,1.25 2.5,0 1.25,-1.25 0,-6.5"
+ 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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:url(#linearGradient32244);stroke-width:0.99999994;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 242.5,291 0,5.75 0.75,0.75 1.5,0 0.75,-0.75 0,-6.25 3,-3"
+ id="path31998"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:url(#linearGradient32246);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 242.5,291 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -3,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -3,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -3,0 z m 0.75,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 1.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1.5,0 z"
+ id="path32000"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:url(#linearGradient32248);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 242.5,292 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.75,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -2.75,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.75,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -2.75,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.75,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -2.75,0 z"
+ id="path32002"
+ sodipodi:nodetypes="csccscccsccscccsccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 242.47368,287.53915 246,284"
+ id="path32004"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path32006"
+ d="m 243.5,287.5 3,-3"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ 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"
+ transform="translate(147,0)">
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-240,-247)"
+ id="g32262"
+ 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"
+ mask="url(#mask29801)">
+ <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="rect32264"
+ width="16"
+ height="16"
+ x="203"
+ y="257" />
+ <g
+ style="display:inline;enable-background:new"
+ 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="g32266"
+ transform="translate(-39.983882,19.00809)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 244.51612,238.49191 -0.0161,3 7.98388,0 0.0161,-3 -7.98388,0 z"
+ id="path32269"
+ 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
+ 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="path32276"
+ d="m 247.51612,241.49191 -0.0161,3 11,0 0.0161,-3 -11,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;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="ccccc"
+ 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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path32278"
+ d="m 249.48388,247.49191 -0.0161,3 7.01612,0 0.0161,-3 -7.01612,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient32296);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 205.51612,259.5 c 0,-0.25 0,-1 0,-1 l 6,0"
+ id="path32280"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32282"
+ d="m 208.51612,262.5 c 0,-0.25 0,-1 0,-1 l 9,0"
+ style="fill:none;stroke:url(#linearGradient32299);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32284"
+ d="m 210.5,268.5 c 0,-0.25 0,-1 0,-1 l 5,0"
+ style="fill:none;stroke:url(#linearGradient32301);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g32286"
+ transform="translate(-85,-411)">
+ <rect
+ y="427.5"
+ x="48.5"
+ height="9"
+ width="9"
+ id="rect32288"
+ style="fill:#ececec;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(#linearGradient32303);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32290"
+ width="5.9999886"
+ height="6"
+ x="50.000011"
+ y="429" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path32292"
+ d="m 50,429 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,2 -2,0 0,2 2,0 0,-2 z m -4,2 0,-2 -2,0 0,2 2,0 z"
+ style="fill:url(#linearGradient32305);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" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path32294"
+ d="m 56.50001,428.49999 -7.000011,10e-6 1.1e-5,6.99999 7,0 -1.1e-5,-6.99999"
+ style="fill:none;stroke:url(#linearGradient32307);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ 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\mysterious PR.png"
+ transform="translate(-118,-465)"
+ id="g32309">
+ <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"
+ width="16"
+ height="16"
+ x="312"
+ y="685" />
+ <g
+ id="g32313">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g32315"
+ transform="matrix(0.927848,0,0,0.916217,160.82022,488.72362)"
+ 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\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="path32317"
+ style="fill:url(#linearGradient32353);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.22752953;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path32319"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient32355);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.68828432,0,0,0.69278557,229.1626,611.24321)" />
+ <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="path32321"
+ style="opacity:0.96000001;fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 322.5,689.5 -3,3 m 0,1 2,2"
+ 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"
+ sodipodi:nodetypes="cc"
+ d="m 319.5,693.5 2,2"
+ style="opacity:0.96000001;fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32323"
+ inkscape:transform-center-y="1.25"
+ inkscape:transform-center-x="-1.25"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="697"
+ x="320"
+ height="1.5"
+ width="1"
+ id="rect32325"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="692"
+ x="324"
+ height="1"
+ width="1.5"
+ id="rect32327"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.96000001;fill:url(#linearGradient32357);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 319.85514,686.97535 c -3.25557,0.003 -5.8936,2.6597 -5.87155,5.95078 0.0105,1.56055 0.63214,2.99542 1.61111,4.05762 2.7831,-7.37691 5.95805,-1.77373 7.49116,-9.06794 -0.92886,-0.60835 -2.04538,-0.9415 -3.23072,-0.94046 l 0,0 0,0 0,0 z"
+ id="path32329"
+ inkscape:transform-center-x="1.4653436"
+ inkscape:transform-center-y="-1.0204512"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-2.5000099"
+ inkscape:transform-center-x="-3.00001"
+ id="path32331"
+ d="m 319.93245,687.49998 c -0.13655,0 -0.28922,0.0368 -0.43244,0.0521 l 0,4.94792 6,0 c -0.22415,-2.79556 -2.6077,-5 -5.56756,-5 z"
+ style="color:#000000;fill:#ff9e05;fill-opacity:1;fill-rule:evenodd;stroke:#d68c1a;stroke-width:1;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32333"
+ width="1.4999696"
+ height="1"
+ x="314.51614"
+ y="693" />
+ <rect
+ style="opacity:0.15;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32335"
+ width="1"
+ height="1.4999921"
+ x="319"
+ y="687.5" />
+ <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"
+ d="m 324.5,692.5 -5,0"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32349"
+ inkscape:transform-center-y="-0.75"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.68828432,0,0,0.69278557,229.1626,611.24321)"
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient32359);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path32351"
+ 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" />
+ </g>
+ </g>
+ <g
+ 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\recently used.png"
+ transform="translate(32,-86.95)"
+ id="g32361">
+ <rect
+ y="664"
+ x="414"
+ height="16"
+ width="16"
+ id="rect32363"
+ 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="g32365">
+ <g
+ style="opacity:0.8"
+ id="g32367"
+ transform="translate(23,1)">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g32369"
+ transform="matrix(0.927848,0,0,0.916217,240.82022,467.72362)"
+ 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\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="path32371"
+ style="fill:url(#linearGradient32426);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.19779229;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.80941061,0,0,0.82049866,65.263425,126.69853)" />
+ </g>
+ <g
+ 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(0.784039,0,0,0.779055,265.50801,498.28815)"
+ id="g32373"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient32430);stroke-width:1.17973554;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.79894049,0,0,0.80499668,66.729242,128.65178)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient32428);stroke-width:1.59548569;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path32375"
+ 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" />
+ </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"
+ id="path32377"
+ style="opacity:0.96000001;fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 400.5,668.5 0,4 m 0,0 2,2"
+ 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"
+ sodipodi:nodetypes="cc"
+ d="m 400.5,672.5 2,2"
+ style="opacity:0.96000001;fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32380"
+ inkscape:transform-center-y="1.25"
+ inkscape:transform-center-x="-1.25"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="676"
+ x="400"
+ height="2.5"
+ width="1"
+ id="rect32382"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="672"
+ x="404"
+ height="1"
+ width="2.5"
+ id="rect32384"
+ style="opacity:0.15;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:transform-center-y="-0.75"
+ id="path32387"
+ style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 400.5,668.5 0,4"
+ 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:url(#linearGradient32432);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 400.30467,667.25 c -2.80257,0.003 -5.07354,2.32096 -5.05455,5.19291 0.009,1.36179 0.54419,2.61392 1.38693,3.54084 2.39585,-6.4374 5.12903,-1.54783 6.44881,-7.91306 -0.79962,-0.53087 -1.76077,-0.82159 -2.78119,-0.82069 l 0,0 0,0 0,0 z"
+ id="path32389"
+ inkscape:transform-center-x="1.2614492"
+ inkscape:transform-center-y="-0.89049022"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32391"
+ width="2.4838562"
+ height="1"
+ x="394.51614"
+ y="672" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32393"
+ width="1"
+ height="1.4999921"
+ x="400"
+ y="666.5" />
+ <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"
+ d="m 400.5,668.5 0,4"
+ style="opacity:0.57600002;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32396"
+ inkscape:transform-center-y="-0.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g32398">
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32400">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32403"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#0b1e00;stroke-width:3.5999999;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>
+ <path
+ style="color:#000000;fill:none;stroke:#0b1e00;stroke-width:3.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 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ id="path32411"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32413">
+ <path
+ style="fill:none;stroke:#8af01e;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 343,108.25 0,-4.25 4.25,0"
+ id="path32416"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path32418"
+ d="m 417,669 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path32420"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ style="color:#000000;fill:none;stroke:#8af01e;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;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 415.5,670 0,-4.5 m 5,4 -2,0"
+ id="path32422"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ id="path32424"
+ d="m 428.5,671.21875 c -0.0591,-1.37274 -0.59591,-2.66246 -1.5,-3.6875 -1.09228,-1.23842 -2.62571,-1.96363 -4.1875,-2.09375 -1.55879,-0.12987 -3.16135,0.33951 -4.40625,1.4375 -3.3e-4,0.0104 -3.3e-4,0.0208 0,0.0312 L 417.5,667.75"
+ style="opacity:0.4;color:#000000;fill:none;stroke:url(#linearGradient32434);stroke-width:1.10000002;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>
+ </g>
+ </g>
+ <g
+ transform="translate(0,2)"
+ id="g31005">
+ <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"
+ width="16"
+ height="16"
+ x="425"
+ y="218" />
+ <g
+ style="display:inline"
+ id="g31009"
+ transform="translate(43.016148,98.00001)">
+ <g
+ transform="translate(-3.542969e-5,0)"
+ id="g31011"
+ style="display:inline">
+ <path
+ d="M 388.23389,129.74999 394.5,123.5 m 0.98389,1.99999 L 394,124 m 0.48389,2.49999 -1.4142,-1.41422"
+ style="fill:none;stroke:#000000;stroke-width:3.00000095;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31013"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path31021"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.04706,129.93681 c 0.81353,0.81353 0.81353,2.31284 0,3.12634 -0.81352,0.81354 -2.31283,0.81354 -3.12635,0 -0.81353,-0.8135 -0.81353,-2.31281 0,-3.12634 0.81352,-0.81352 2.31283,-0.81352 3.12635,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31015"
+ style="fill:none;stroke:url(#linearGradient31019);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="M 388.73389,129.24999 394.5,123.5 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czzzz"
+ d="m 388.01764,129.96629 c 0.79818,0.79819 0.79818,2.26923 0,3.06743 -0.7982,0.79819 -2.26925,0.79819 -3.06743,0 -0.79821,-0.7982 -0.79821,-2.26924 0,-3.06743 0.79818,-0.7982 2.26923,-0.7982 3.06743,0 z"
+ style="fill:none;stroke:url(#linearGradient31025);stroke-width:1.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31023"
+ inkscape:connector-curvature="0" />
+ </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"
+ sodipodi:ry="0.71093756"
+ sodipodi:rx="0.70312506"
+ sodipodi:cy="122.5078"
+ sodipodi:cx="387.50003"
+ id="path31017"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g31159">
+ <g
+ style="opacity:0.8"
+ transform="translate(-21,2)"
+ id="g31037">
+ <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="rect31039"
+ width="16"
+ height="16"
+ x="425"
+ y="218" />
+ <g
+ style="display:inline"
+ id="g31041"
+ transform="translate(43.016148,98.00001)">
+ <g
+ transform="translate(-3.542969e-5,0)"
+ id="g31043"
+ style="display:inline">
+ <path
+ d="M 388.23389,129.74999 394.5,123.5 m 0.98389,1.99999 L 394,124 m 0.48389,2.49999 -1.4142,-1.41422"
+ style="fill:none;stroke:#000000;stroke-width:3.00000095;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31045"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path31047"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.04706,129.93681 c 0.81353,0.81353 0.81353,2.31284 0,3.12634 -0.81352,0.81354 -2.31283,0.81354 -3.12635,0 -0.81353,-0.8135 -0.81353,-2.31281 0,-3.12634 0.81352,-0.81352 2.31283,-0.81352 3.12635,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31049"
+ style="fill:none;stroke:url(#linearGradient31055);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="M 388.73389,129.24999 394.5,123.5 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czzzz"
+ d="m 388.01764,129.96629 c 0.79818,0.79819 0.79818,2.26923 0,3.06743 -0.7982,0.79819 -2.26925,0.79819 -3.06743,0 -0.79821,-0.7982 -0.79821,-2.26924 0,-3.06743 0.79818,-0.7982 2.26923,-0.7982 3.06743,0 z"
+ style="fill:none;stroke:url(#linearGradient31057);stroke-width:1.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31051"
+ inkscape:connector-curvature="0" />
+ </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"
+ sodipodi:ry="0.71093756"
+ sodipodi:rx="0.70312506"
+ sodipodi:cy="122.5078"
+ sodipodi:cx="387.50003"
+ id="path31053"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g31031"
+ transform="matrix(0,1,-1,0,636.39781,-199.65488)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31033"
+ d="m 422.15488,229.89781 11,-11"
+ style="opacity:0.5;fill:#000000;fill-rule:evenodd;stroke:#2b0000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ff5555;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 422.15488,229.89781 11,-11"
+ id="path31035"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g31133"
+ transform="translate(0,-21)">
+ <rect
+ y="241"
+ x="383"
+ height="16"
+ width="16"
+ id="rect31089"
+ 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(3.016145,122.00001)"
+ id="g31091"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g31093"
+ transform="translate(-3.542969e-5,0)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path31095"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.23389,129.74999 5.25,-5.25 m 0.98389,1.99999 -1.48389,-1.49999 m 0.48389,2.49999 -1.4142,-1.41422"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 388.04706,129.93681 c 0.81353,0.81353 0.81353,2.31284 0,3.12634 -0.81352,0.81354 -2.31283,0.81354 -3.12635,0 -0.81353,-0.8135 -0.81353,-2.31281 0,-3.12634 0.81352,-0.81352 2.31283,-0.81352 3.12635,0 z"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31097"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 388.73389,129.24999 4.75,-4.75 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ style="fill:none;stroke:url(#linearGradient31151);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path31099"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31101"
+ style="fill:none;stroke:url(#linearGradient31153);stroke-width:1.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.01764,129.96629 c 0.79818,0.79819 0.79818,2.26923 0,3.06743 -0.7982,0.79819 -2.26925,0.79819 -3.06743,0 -0.79821,-0.7982 -0.79821,-2.26924 0,-3.06743 0.79818,-0.7982 2.26923,-0.7982 3.06743,0 z"
+ sodipodi:nodetypes="czzzz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path31103"
+ sodipodi:cx="387.50003"
+ 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"
+ transform="matrix(1.4399775,0,0,1.4399775,-171.50748,-44.947546)" />
+ </g>
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.3;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.4000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ d="m 389.5,229.65625 c -0.73878,0 -1.48012,0.26136 -2.03125,0.8125 -1.10229,1.10226 -1.10228,2.96023 0,4.0625 0.41335,0.41335 0.92256,0.67791 1.46875,0.78125 0.008,-0.004 0.0231,0.004 0.0312,0 0.76739,-0.40457 1.35785,-1.08414 1.65625,-1.90625 -0.0307,0.0416 -0.0579,0.0891 -0.0937,0.125 -0.49413,0.49412 -1.5684,0.49411 -2.0625,0 -0.49414,-0.49413 -0.49413,-1.56838 0,-2.0625 0.24705,-0.24706 0.63541,-0.375 1.03125,-0.375 0.39584,0 0.78419,0.12794 1.03125,0.375 0.12353,0.12353 0.21949,0.29083 0.28125,0.46875 -0.0858,-0.9079 -0.52654,-1.71591 -1.1875,-2.28125 -0.0405,-0.002 -0.0845,0 -0.125,0 z m -2.125,1.9375 c 0.37998,0 0.65625,0.27629 0.65625,0.65625 0,0.37998 -0.27627,0.6875 -0.65625,0.6875 -0.37092,0 -0.64331,-0.29002 -0.65625,-0.65625 0,-0.009 -3.2e-4,-0.0223 0,-0.0312 0.0129,-0.3662 0.28534,-0.65625 0.65625,-0.65625 z"
+ transform="translate(0,21)"
+ id="path31190"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g31059"
+ transform="translate(-42,23)">
+ <g
+ style="display:inline"
+ id="g31073"
+ transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,60.12783,410.54412)">
+ <g
+ id="g31075"
+ transform="translate(2.016112,1.00001)">
+ <path
+ d="m 388.60119,129.3396 4.94975,-4.94974 m 1.41421,1.41421 -1.23743,-1.23743 m 0.53033,1.94454 -1.23742,-1.23744"
+ style="fill:none;stroke:#100d04;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31077"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path31113"
+ style="fill:none;stroke:#100d04;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 387.93695,130.00385 c 0.8043,0.80431 0.8043,2.10984 0,2.91414 -0.8043,0.80431 -2.10984,0.80431 -2.91414,0 -0.8043,-0.8043 -0.8043,-2.10983 0,-2.91414 0.8043,-0.80428 2.10984,-0.80428 2.91414,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31079"
+ style="fill:none;stroke:url(#linearGradient31155);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.60119,129.3396 4.94975,-4.94974 m 1.41421,1.41421 -0.25,-0.25 m -0.4571,0.95711 -0.25,-0.25"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.05;fill:#181406;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path31081"
+ sodipodi:cx="387.50003"
+ 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"
+ transform="matrix(1.7719122,0,0,1.7719122,-300.13217,-85.612134)" />
+ <path
+ sodipodi:nodetypes="czzzz"
+ d="m 387.96588,129.97488 c 0.82029,0.8203 0.82029,2.15177 0,2.97206 -0.8203,0.82029 -2.15179,0.82029 -2.97206,0 -0.8203,-0.82029 -0.8203,-2.15176 0,-2.97206 0.82027,-0.82029 2.15176,-0.82029 2.97206,0 z"
+ style="fill:none;stroke:url(#linearGradient31157);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31109"
+ inkscape:connector-curvature="0" />
+ </g>
+ </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"
+ transform="translate(448,657)">
+ <rect
+ y="-122"
+ x="-44"
+ height="16"
+ width="16"
+ id="rect40445-4-2"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40447-5-3"
+ d="m -43.5,-116.75 12.5,-4.75 0.75,2 -13.25,5 0,-2.25 z"
+ style="fill:#1a1a1a;stroke:#000000;stroke-width:0.89999998;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-114.5"
+ x="-42.5"
+ height="7.9999971"
+ width="12.999988"
+ id="rect40449-5-9"
+ style="fill:url(#linearGradient16887);fill-opacity:1;fill-rule:nonzero;stroke:#000000;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" />
+ <rect
+ style="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"
+ id="rect40451-1-1"
+ width="1"
+ height="1.5"
+ x="-32"
+ y="-121" />
+ <rect
+ y="-119.41868"
+ x="-36"
+ height="1.5"
+ width="1"
+ id="rect40453-7-7"
+ style="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" />
+ <rect
+ style="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"
+ id="rect40455-1-9"
+ width="1"
+ height="1.5"
+ x="-37"
+ y="-119.16868" />
+ <rect
+ y="-117.62802"
+ x="-41"
+ height="1.5"
+ width="1"
+ id="rect40457-1-4"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;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:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40459-5-8"
+ width="1"
+ height="1.5"
+ x="-40"
+ y="-117.87802" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#000000;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"
+ id="rect40461-2-3"
+ width="13.999996"
+ height="2.0000052"
+ x="-43.5"
+ y="-114.5" />
+ <rect
+ y="-113"
+ x="-42"
+ height="1.7500292"
+ width="12.154154"
+ id="rect40490-7-9"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="rect40463-6-4"
+ d="m -40,-114 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z"
+ style="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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round"
+ d="m -31.5,-120.5 -9.75,3.75"
+ id="path40474-1-2"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient16889);stroke-width:1px;stroke-linejoin:round"
+ d="m -41.5,-107.5 0,-6 11,0 0,6 -11,0 z"
+ id="path40476-4-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#87aade;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 -43,-116.75 1,0 1,1.75 0,2 -2,0 0,-3.75 z"
+ id="path40478-2-5"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#002255;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 -41,-115 0,2 -2,0 0,0.75 2.75,0 0,-3 -1.25,-2.25 -1.5,0.25 0,0.5 1,0 1,1.75 z"
+ id="path40480-3-8"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40558-2-3"
+ d="m -41.5,-107.38206 0,-4.66445"
+ style="opacity:0.2;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="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"
+ id="rect40553-2-9"
+ width="1"
+ height="1.5"
+ x="-33"
+ y="-120.75" />
+ <rect
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40556-1-3"
+ width="1"
+ height="1.25"
+ x="-40"
+ y="-114" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ d="m -42.4975,-113.46527 0,-3.0928"
+ id="path40560-6-1"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(1,0)"
+ style="opacity:0.35"
+ id="g40590-8-8">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40586-5-0"
+ width="5"
+ height="0.9617852"
+ x="-38"
+ y="-110" />
+ <rect
+ y="-111"
+ x="-36"
+ height="3"
+ width="1.0280838"
+ id="rect40588-7-3"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55801">
+ <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"
+ width="16"
+ height="16"
+ x="47"
+ y="52" />
+ <g
+ transform="translate(74.95064,-440.02091)"
+ id="g26260-3">
+ <g
+ id="g26262-9">
+ <path
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26264-6"
+ 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"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26266-7"
+ style="fill:none;stroke:#28170b;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path26268-5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -9.5,6 6,-6"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26270-5"
+ style="fill:none;stroke:url(#linearGradient26282-0);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -27.5,502.5 l 6,-6 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient26284-9);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26272-4"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path26274-0"
+ sodipodi:cx="13.5"
+ 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"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26276-1"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient26286-4);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26278-1"
+ sodipodi:cx="13.5"
+ 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"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -7.704183,9.08552 4.25,-4.25 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient26288-9);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path26280-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g24933-4"
+ transform="translate(-375.85,-461.8829)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path24939-9"
+ d="m 430.5,525.5329 0,2 1,1 2,0 2,-2.0329 0,-2 -1,-1 -2,0 -2,2.0329 z"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 433.5,522.4671 0,1.75 1,1.25 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ id="path24941-0"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24945-6"
+ d="m 433.5,522.4671 0,2.0329 1,0.9671 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ style="fill:none;stroke:url(#linearGradient55785);stroke-width:1.29999995;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="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 434.5,523.5 -2,0"
+ id="path24954-1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient55787);stroke-width:1.29999995;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 430.5,525.5 0,2 1,1 2,0 2,-2 0,-2 -1,-1 -2,0 -2,2 z"
+ id="path24956-1"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path24958-1"
+ d="m 434.08489,525.47125 2.25,0"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 434.33489,525.47125 436.5,525.4671"
+ id="path24960-1" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55835">
+ <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"
+ width="16"
+ height="16"
+ x="68"
+ y="52" />
+ <g
+ transform="translate(95.95064,-440.02091)"
+ id="g26260-3-6">
+ <g
+ id="g26262-9-1">
+ <path
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26264-6-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"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26266-7-7"
+ style="fill:none;stroke:#28170b;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path26268-5-3"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -9.5,6 6,-6"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26270-5-9"
+ style="fill:none;stroke:url(#linearGradient26282-0-8);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -27.5,502.5 l 6,-6 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient26284-9-6);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26272-4-9"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path26274-0-6"
+ sodipodi:cx="13.5"
+ 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"
+ 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26276-1-7"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient26286-4-5);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26278-1-5"
+ sodipodi:cx="13.5"
+ 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"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -7.704183,9.08552 4.25,-4.25 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient26288-9-5);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path26280-5-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,110.9,273.1)"
+ id="g39333-1"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(26.00079,19.1)"
+ id="g39096-7-1"
+ style="display:inline;enable-background:new">
+ <g
+ id="g39118-3-3"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ transform="translate(-1.00079,-19)" />
+ </g>
+ <g
+ id="g38966-7"
+ transform="matrix(0,-1,-1,0,212.75,247.25)">
+ <g
+ transform="matrix(-1,0,0,-1,215.25,222.75)"
+ id="g38968-4">
+ <path
+ inkscape:connector-curvature="0"
+ id="path38970-5"
+ d="m 174.5,38.5 0,5 5,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 175.5,42.5 5,-5"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;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="path38972-1"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <g
+ id="g38975-0"
+ transform="translate(-146.75,127.75)">
+ <g
+ id="g38977-1"
+ 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,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ id="path38984-8"
+ sodipodi:nodetypes="cz"
+ d="" />
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;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="path38987-2"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path38994-9"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g38996-7">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path38998-6"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#333333;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>
+ <g
+ id="g39000-4"
+ 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,0,0,-1,118.4113,290.74999)"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ id="path39015-9"
+ sodipodi:nodetypes="cz"
+ d="" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 78.1613,110.99999 5.5,-5.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;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="path39017-0"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <g
+ id="g39020-8"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-175.75,-207.25)">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path39022-9"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55731">
+ <rect
+ y="51.97921"
+ x="25.950649"
+ height="16"
+ width="16"
+ id="rect42947-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
+ transform="translate(-301.04935,-550.02079)"
+ id="g42949-4">
+ <g
+ style="opacity:0.85"
+ id="g42951-6">
+ <path
+ style="fill:#e6e6e6;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 341.5161,616.38229 340.5,617.5 l -10.73389,-10e-6 -1.25,-1.25 L 328.5,605.5 l 13,0 0.0161,10.88229 z"
+ id="path42953-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"
+ sodipodi:nodetypes="ccccccc"
+ 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="path42955-8"
+ d="m 340,616 -8.25,0 0,-1 8.25,0 0,1 z"
+ style="fill:#999999;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" />
+ <rect
+ style="opacity:0.2;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="rect38927-6"
+ width="11.970581"
+ height="8.0306396"
+ x="329.02942"
+ y="605.96936" />
+ <rect
+ y="605.96936"
+ x="329.02942"
+ height="8.0306396"
+ width="11.970581"
+ id="rect45307-5"
+ style="opacity:0.3;fill:url(#radialGradient45309-0);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: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="path42957-3"
+ d="m 340.48389,606.50001 c -3.66204,-3e-5 -7.70403,2e-5 -10.98389,-10e-6 l 0.002,10.00007 10.99778,-7e-5 -0.0161,-9.99999 2.1e-4,0 z"
+ style="fill:none;stroke:url(#linearGradient42965-7-9);stroke-width:0.99999923px;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="ccccc"
+ inkscape:connector-curvature="0" />
+ <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"
+ y="615"
+ x="330"
+ height="1.0000043"
+ width="1"
+ id="rect42959-9"
+ 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" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.35;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"
+ d="m 340.5,614 -11,0 0,-1 11,0 0,1 z"
+ id="path38929-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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.25;fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter24186-3-2-5)"
+ d="m 337.7,606.7 0,2.75 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.75 2,0 z"
+ id="path42961-6"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path42963-7"
+ d="m 333.75,602.5 1.75,0 c 0,0 0,2 0,2 l 2,0 0,-2 1.75,0 0.25,0.25 0,2.5 -2,1.5 0,2.5 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.5 -2,-1.5 0,-2.5 0.25,-0.25 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:url(#linearGradient42967-6-4);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g45287-4"
+ transform="translate(160.94228,123.97921)"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path45290-5"
+ style="opacity:0.25;fill:none;stroke:#000000;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"
+ 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"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45302-1"
+ style="fill:none;stroke:#0b1e00;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"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path45294-9" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55696">
+ <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="rect45203-3"
+ width="16"
+ height="16"
+ x="-20.95064"
+ y="-67.97921" />
+ <g
+ style="display:inline"
+ id="g45205-1"
+ 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,0,0,-1,123.0839,85.1)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccccccccsccccc"
+ d="m 105.48388,31.25 6.25,-6 c 0.49692,0.284098 0.2225,0.232267 0.76612,0.25 2.20206,0.07183 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -4,1.792 -4,4 0,0.58349 0.009,0.250006 0.23388,0.75 l -6.25,6 0,2 1,1 2,0 z"
+ style="fill:url(#linearGradient55656);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path45207-7" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45209-9"
+ 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 115.5,21.5 -2.25,2.25 m -1,-5.5 c -1.75,0 -4,2.25 -2.5,5 l -1.26612,0.25 -5,5 0,1.75"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45211-9"
+ 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:0"
+ d="m 105.48388,31.5 5.5,-5.5 0.25,-0.5 1.26612,0 c 2.73388,0 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -3.96454,1.25 -4,4 l -0.0161,1.25 -0.5,0.25 -5.5,5.5 0,2 1,1 2,0 -2e-5,0 z"
+ sodipodi:nodetypes="cccsccccccccsccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45214-0"
+ style="fill:none;stroke:#d7d7d7;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 109.98388,25 -5,5"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 109.48388,24.5 -4,4"
+ style="fill:none;stroke:#646464;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path45216-1" />
+ <rect
+ y="29"
+ x="103.98388"
+ height="1"
+ width="1"
+ id="rect45218-5"
+ style="fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(-409.04935,-611.97079)"
+ id="g32398-1">
+ <g
+ id="g32400-8"
+ transform="matrix(1,0,0,-1,73,774)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#0b1e00;stroke-width:3.5999999;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,108.25 0,-4.25 4.25,0"
+ id="path32403-1"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ id="path32411-7"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ style="color:#000000;fill:none;stroke:#0b1e00;stroke-width:3.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" />
+ <g
+ id="g32413-8"
+ transform="matrix(1,0,0,-1,73,774)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path32416-5"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#8af01e;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" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 417,669 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ id="path32418-2" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:none;stroke:#8af01e;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 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ id="path32420-2"
+ sodipodi:nodetypes="csc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path32422-4"
+ d="m 415.5,670 0,-4.5 m 5,4 -2,0"
+ style="opacity:0.4;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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.4;color:#000000;fill:none;stroke:url(#linearGradient55624);stroke-width:1.10000002;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 428.5,671.21875 c -0.0591,-1.37274 -0.59591,-2.66246 -1.5,-3.6875 -1.09228,-1.23842 -2.62571,-1.96363 -4.1875,-2.09375 -1.55879,-0.12987 -3.16135,0.33951 -4.40625,1.4375 -3.3e-4,0.0104 -3.3e-4,0.0208 0,0.0312 L 417.5,667.75"
+ id="path32424-5"
+ sodipodi:nodetypes="cscccc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g17770">
+ <rect
+ y="51.979202"
+ x="88.95063"
+ height="16"
+ width="16"
+ id="rect42954-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
+ transform="translate(-49.94936,-39.370919)"
+ id="g42956-6">
+ <g
+ id="g42958-1"
+ transform="translate(-179,199.50012)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path14490"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#281500;stroke-width:1.79999995;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"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g42962-0"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42964-9"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ style="fill:#915515;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" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path42966-1"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#efa351;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="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42968-5"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient55950);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42970-1"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#f5ca9b;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="path42972-5"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient55952);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect42974-8"
+ style="fill:url(#linearGradient55954);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42976-8"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <g
+ 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(0.7882544,0,0,0.7883038,-8.4020402,-113.3734)"
+ id="g42978-1"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.6425292,0,0,0.642531,44.523834,146.81699)"
+ sodipodi:type="arc"
+ style="fill:#f2b676;fill-opacity:1;fill-rule:nonzero;stroke:#281500;stroke-width:1.97436094;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42980-5"
+ 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="path42984-5"
+ style="fill:none;stroke:url(#linearGradient55956);stroke-width:2.54167628;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4991181,0,0,0.4991107,63.460522,163.7471)" />
+ <path
+ transform="matrix(-0.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)"
+ 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="path42982-9"
+ style="opacity:0.8;fill:url(#linearGradient55958);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ transform="matrix(0.875,0,0,0.875,-151.54375,-26.76875)"
+ id="g43952-8">
+ <g
+ transform="matrix(0,-1,1,0,183.99437,429)"
+ id="g43483-9">
+ <g
+ transform="translate(0,21)"
+ id="g43488-2">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43490-2"
+ d="M 327,86.255631 327,76"
+ style="fill:none;stroke:#000000;stroke-width:3.88571429;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"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:4.11428547;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g43494-2">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;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,86.255631 327,76"
+ id="path43496-7"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;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 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43498-9"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43776-0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.14285719;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=""
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient55988);stroke-width:1.14285719;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 284,97.25 -4.5,4.5 0,0.5 4.5,4.5"
+ id="path43780-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43860-6"
+ d="m 291.5,101.5 -8.99437,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.14285719;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>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56020">
+ <g
+ transform="translate(-28.94936,-39.370919)"
+ id="g42956-6-7">
+ <g
+ id="g42958-1-8"
+ transform="translate(-179,199.50012)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path14490-2"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#281500;stroke-width:1.79999995;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"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g42962-0-2"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42964-9-7"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ style="fill:#915515;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" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path42966-1-0"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#efa351;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="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42968-5-4"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient14559-8);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42970-1-3"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#f5ca9b;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="path42972-5-8"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient14561-9);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect42974-8-0"
+ style="fill:url(#linearGradient14563-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42976-8-4"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <g
+ 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(0.7882544,0,0,0.7883038,12.59796,-113.3734)"
+ id="g42978-1-6"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.6425292,0,0,0.642531,44.523834,146.81699)"
+ sodipodi:type="arc"
+ style="fill:#f2b676;fill-opacity:1;fill-rule:nonzero;stroke:#281500;stroke-width:1.97436094;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42980-5-8"
+ 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="path42984-5-2"
+ style="fill:none;stroke:url(#linearGradient14565-5);stroke-width:2.54167628;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4991181,0,0,0.4991107,63.460522,163.7471)" />
+ <path
+ transform="matrix(-0.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)"
+ 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="path42982-9-0"
+ style="opacity:0.8;fill:url(#linearGradient14567-8);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ transform="matrix(0.875,0,0,0.875,-149.68867,-26.76875)"
+ id="g43941-0">
+ <g
+ id="g43467-5"
+ transform="matrix(0,-1,-1,0,409.02125,429)">
+ <g
+ id="g43469-6"
+ transform="translate(0,21)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.88571429;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 327,86.25 327,76"
+ id="path43471-7"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:4.11428547;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43473-1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43475-6"
+ transform="translate(0,21)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43478-9"
+ d="M 327,86.25 327,76"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;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
+ sodipodi:nodetypes="ccc"
+ id="path43481-3"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;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>
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.37142861;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 308.5,106 2.75,-2.75"
+ id="path43778-6"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path43785-2"
+ d="m 308.75,97.25 c -0.25,0 -0.5,0.25 -0.5,0.5 m 2.26562,3.75 -8.99437,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.14285719;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:none;stroke:url(#linearGradient55990);stroke-width:1.14285719;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.02125,97.249998 4.5,4.500002 0,0.5 -4.5,4.5"
+ id="path44948-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56270">
+ <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"
+ width="16"
+ height="16"
+ x="131"
+ y="52" />
+ <g
+ transform="translate(-399,2)"
+ id="g56091-7">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path29110-17"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,2.75 -5.99999,3.24999 L 531,60.75 531,58 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;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\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#9e9e9e;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 531,58 6,-2.5 7.99996,3.49998 0,0.5 -6,3 L 531,58.56558 531,58 z"
+ id="path29112-53" />
+ <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="path29114-1"
+ d="M 531.00001,60.75 531,58.5 l 7.99996,3.99998 0.01,2.49885 -8.00991,-4.24883 -4e-5,0 z"
+ style="fill:#848484;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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"
+ style="fill:#383838;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 544.99996,61.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path29116-3"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient56084-9);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58.5 0,2 7.49996,3.99998 5.5,-3 0,-2"
+ id="path29118-7"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58 7.49996,3.74998"
+ id="path29120-1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29129-4);stroke-width:1.08012342;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="path29122-40"
+ sodipodi:cx="749"
+ 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"
+ 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"
+ id="rect29125-3"
+ width="1"
+ height="1"
+ x="544"
+ y="61" />
+ </g>
+ <g
+ transform="matrix(0.53305487,0,0,0.53305487,-263.95264,-56.614058)"
+ id="g15021"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient15123);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="path15023"
+ 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
+ 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="path15025"
+ 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(#radialGradient15125);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" />
+ <path
+ id="path15027"
+ style="fill:none;stroke:url(#linearGradient15127);stroke-width:1.03178871;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path15029"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path15031"
+ style="fill:none;stroke:#000000;stroke-width:1.50078368;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15129);stroke-width:0.93798971;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path15033"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g15009"
+ transform="matrix(0.53305487,0,0,0.53305487,86.97987,-126.1707)">
+ <rect
+ y="344"
+ x="89"
+ height="16"
+ width="16"
+ id="rect15011"
+ 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="g15013">
+ <rect
+ y="344.7504"
+ x="91.249611"
+ height="12.998481"
+ width="13"
+ id="rect15015"
+ style="fill:url(#linearGradient15131);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.50078368;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" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15017"
+ d="m 92.28796,356.69549 0,-10.90453 10.90641,0 0,10.90453 -10.90641,0 z"
+ style="fill:none;stroke:url(#linearGradient15133);stroke-width:0.56279385;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\Kopia 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"
+ sodipodi:nodetypes="cszzcc"
+ id="path15019"
+ d="m 103.5,353.27516 c -0.37083,-1.1875 -1.21031,-1.72293 -1.9,-1.72929 -1.39235,-0.0134 -1.47709,3.98814 -2.999997,4 -1.491657,0.0119 -2.001315,-7 -3.5,-7 -1.52993,-10e-4 -1.18608,5.00645 -3.5,4.97929 l -1,0"
+ style="fill:none;stroke:url(#linearGradient15135);stroke-width:1.1255877;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g15035"
+ transform="matrix(0.53305487,0,0,0.53305487,-270.25684,-53.589044)">
+ <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="path15037"
+ d="m 757.01257,204.46121 9.48743,0.0388 0,14.99999 -13,0 0.0126,-11.53879 3.5,-3.5 -3e-5,0 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g15039"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <g
+ id="g15041">
+ <rect
+ style="fill:#ebb5b5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15043"
+ width="9.9999914"
+ height="12"
+ x="-83"
+ y="94" />
+ <rect
+ y="101"
+ x="-83"
+ height="4.9999976"
+ width="9.9999924"
+ id="rect15045"
+ style="opacity:0.5;fill:#4b80cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="94"
+ x="-83"
+ height="6.8499999"
+ width="9.9999914"
+ id="rect15047"
+ style="opacity:0.3;fill:url(#radialGradient15137-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path15050"
+ d="m -83,100.00002 1,0 1,0.74999 1,-0.74999 1,0.99999 2,0 1.5,-0.75 1.5,0.75 0.999991,0 L -73,102 l -9.999991,0 -9e-6,-1.99998 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15052"
+ width="2.0000029"
+ height="2.0000038"
+ x="-77"
+ y="96" />
+ <path
+ style="opacity:0.3;fill:#280b0b;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 -83,102 10,0 0,1 -10,0 0,-1 z"
+ id="path15054"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path15056"
+ d="m -77,102 2.000003,0 -0.750003,4 -0.5,0 -0.75,-4 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g15058"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15060"
+ d="m -82.5,105.5 0,-11 9,0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1.87597954px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.87597954px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -82.5,105.5 0,-11 9,0 0,11 -9,0 z"
+ id="path15062"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:url(#radialGradient15139-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 757.51257,204.46121 9,1e-5 0,14.99999 -13,0 0,-11 4,-4 z"
+ id="path15064"
+ 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.51257,209.96121 754.5,218.5 M 759.01257,205.46121 765.5,205.5"
+ style="fill:none;stroke:url(#linearGradient15141-6);stroke-width:1.03178871;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path15066"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753.01257,208.96121 5,0 0,-5 -5,5 z"
+ id="path15068"
+ 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.51257,207.96121 753.5,219.5 l 13,0 0,-14.99999 -9.48743,-0.0388 -3.5,3.5 z"
+ style="fill:none;stroke:#000000;stroke-width:1.50078368;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path15070"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15072"
+ d="m 758.51257,206.46121 0,3 -3,0"
+ style="fill:none;stroke:url(#linearGradient15143-1);stroke-width:0.93798971;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56314">
+ <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"
+ width="16"
+ height="16"
+ x="152"
+ y="52" />
+ <g
+ transform="translate(-378,2)"
+ id="g56091-71">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path29110-7"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,2.75 -5.99999,3.24999 L 531,60.75 531,58 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;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\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#9e9e9e;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 531,58 6,-2.5 7.99996,3.49998 0,0.5 -6,3 L 531,58.56558 531,58 z"
+ id="path29112-1" />
+ <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="path29114-0"
+ d="M 531.00001,60.75 531,58.5 l 7.99996,3.99998 0.01,2.49885 -8.00991,-4.24883 -4e-5,0 z"
+ style="fill:#848484;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ 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"
+ style="fill:#383838;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 544.99996,61.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path29116-7"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient56084-0);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58.5 0,2 7.49996,3.99998 5.5,-3 0,-2"
+ id="path29118-8"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58 7.49996,3.74998"
+ id="path29120-7"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29129-1);stroke-width:1.08012342;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="path29122-0"
+ sodipodi:cx="749"
+ 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"
+ 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"
+ id="rect29125-72"
+ width="1"
+ height="1"
+ x="544"
+ y="61" />
+ </g>
+ <g
+ transform="translate(-262.04935,-611.97079)"
+ id="g32365-0-5">
+ <g
+ style="opacity:0.8"
+ id="g32367-2-1"
+ transform="translate(23,1)">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g32369-7-1"
+ transform="matrix(0.927848,0,0,0.916217,240.82022,467.72362)"
+ 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
+ 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(0.784039,0,0,0.779055,265.50801,498.28815)"
+ id="g32373-2-0"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient32430-7-9-7);stroke-width:1.17973554;stroke-opacity:1;display:inline" />
+ </g>
+ <g
+ id="g32398-1-7">
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32400-8-4">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32403-1-2"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#0b1e00;stroke-width:3.5999999;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>
+ <path
+ style="color:#000000;fill:none;stroke:#0b1e00;stroke-width:3.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 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ id="path32411-7-3"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32413-8-5">
+ <path
+ style="fill:none;stroke:#8af01e;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 343,108.25 0,-4.25 4.25,0"
+ id="path32416-5-1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path32418-2-3"
+ d="m 417,669 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path32420-2-7"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ style="color:#000000;fill:none;stroke:#8af01e;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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;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 415.5,670 0,-4.5 m 5,4 -2,0"
+ id="path32422-4-0"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ id="path32424-5-0"
+ d="m 428.5,671.21875 c -0.0591,-1.37274 -0.59591,-2.66246 -1.5,-3.6875 -1.09228,-1.23842 -2.62571,-1.96363 -4.1875,-2.09375 -1.55879,-0.12987 -3.16135,0.33951 -4.40625,1.4375 -3.3e-4,0.0104 -3.3e-4,0.0208 0,0.0312 L 417.5,667.75"
+ style="opacity:0.4;color:#000000;fill:none;stroke:url(#linearGradient32434-5-8-9);stroke-width:1.10000002;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>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56410">
+ <g
+ transform="translate(190.95065,3.97921)"
+ id="g18875-2"
+ 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="rect18877-3"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g18879-4"
+ transform="translate(0.01612278,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="path18881-0"
+ d="M 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17222-4-4);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"
+ 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="path18883-5"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17224-0-9);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ id="path18885-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"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18887-7"
+ width="1"
+ height="1"
+ x="6.9838772"
+ y="81"
+ 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
+ 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 197.45064,77.47921 9,0 m -9,2 9,0 m -9,2 9,0"
+ style="fill:none;stroke:url(#linearGradient56401);stroke-width:0.9999994px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ id="path19108-4"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g45287-4-9"
+ transform="translate(328.94228,144.9792)"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path45290-5-8"
+ style="opacity:0.25;fill:none;stroke:#000000;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"
+ 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"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45302-1-2"
+ style="fill:none;stroke:#0b1e00;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"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path45294-9-3" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56383">
+ <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"
+ width="16"
+ height="16"
+ x="173"
+ y="73" />
+ <g
+ id="g45287-4-6"
+ transform="translate(307.94228,144.9792)"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path45290-5-0"
+ style="opacity:0.25;fill:none;stroke:#000000;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"
+ 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"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45302-1-7"
+ style="fill:none;stroke:#0b1e00;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"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path45294-9-7" />
+ </g>
+ <g
+ transform="translate(421.95065,-463.02079)"
+ id="g31820-9">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 0,-1 1,0"
+ id="path31830-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 -239.25,548 0.5,0"
+ id="path31838-1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4"
+ d="m -239.25,548 0.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(425.95065,-463.02079)"
+ id="g31820-9-7">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 0,-1 1,0"
+ id="path31830-7-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 -239.25,548 0.5,0"
+ id="path31838-1-6"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3"
+ d="m -239.25,548 0.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56477">
+ <rect
+ y="73"
+ x="299"
+ height="16"
+ width="16"
+ id="rect25824-7"
+ 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" />
+ <g
+ transform="translate(209.95065,-333.02079)"
+ id="g25826-2">
+ <path
+ style="fill:url(#linearGradient25927-1-2);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,408.5 0,11.49245 1.5,1.5 10.5,0.008 0,-11.99245 -8,-0.008 0,-1 -4,0 z"
+ id="path25828-2"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-361,287.99994)"
+ id="g25830-3"
+ style="display:inline" />
+ <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,-10.02344 2,0 0,1 L 100.5,410.5"
+ id="path25834-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 93,409 0,2 -3,0 0,-2 3,0 z"
+ id="path25840-3"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path25842-4"
+ d="m 89.5,408.5 0,11.49245 1.5,1.5 12,0.008 1.5,-1.49245 0,-6.50755 -3,-0.008 0,-3.9849 -8,-0.008 0,-1 -4,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" />
+ </g>
+ <g
+ id="g56440">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g40606-5"
+ transform="matrix(0.927848,0,0,0.916217,148.77086,-125.29717)"
+ 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\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="path40608-1"
+ style="fill:url(#linearGradient42519-8-7);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.22752953;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </g>
+ <g
+ 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(0.784039,0,0,0.779055,173.45865,-94.73264)"
+ id="g40610-3"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient42523-5-8);stroke-width:1.17973554;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42521-3-0);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path40612-7"
+ 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" />
+ </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="path40614-9"
+ style="opacity:0.96000001;fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 310.45064,75.47921 -3,3 m 0,1 2,2"
+ 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"
+ d="m 307.45064,79.47921 2,2"
+ style="opacity:0.96000001;fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40616-6"
+ inkscape:transform-center-y="1.25"
+ inkscape:transform-center-x="-1.25" />
+ <rect
+ y="82.97921"
+ x="307.95065"
+ height="1.5"
+ width="1"
+ id="rect40618-1"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="77.97921"
+ x="311.95065"
+ height="1"
+ width="1.5"
+ id="rect40620-6"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-0.75"
+ id="path40622-6"
+ style="opacity:0.96000001;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 310.45064,75.47921 -3,3"
+ 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"
+ style="opacity:0.96000001;fill:url(#linearGradient56428);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 307.80578,72.95456 c -3.25557,0.003 -5.8936,2.6597 -5.87155,5.95078 0.0105,1.56055 0.63214,2.99542 1.61111,4.05762 2.7831,-7.37691 5.95805,-1.77373 7.49116,-9.06794 -0.92886,-0.60835 -2.04538,-0.9415 -3.23072,-0.94046 l 0,0 0,0 0,0 z"
+ id="path40624-9"
+ inkscape:transform-center-x="1.4653436"
+ inkscape:transform-center-y="-1.0204512" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40626-3"
+ width="1.4999696"
+ height="1"
+ x="302.4668"
+ y="78.97921" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40628-5"
+ width="1"
+ height="1.4999921"
+ x="306.95065"
+ y="73.47921" />
+ <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"
+ d="m 310.45064,75.47921 -3,3"
+ style="opacity:0.57600002;fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40630-7"
+ inkscape:transform-center-y="-0.75" />
+ </g>
+ <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="rect15838"
+ width="16"
+ height="16"
+ x="298.95065"
+ y="73.97921" />
+ <g
+ transform="translate(209.95065,-333.02079)"
+ id="g15840">
+ <g
+ style="display:inline"
+ id="g15844"
+ transform="translate(-361,287.99994)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path15846"
+ d="m 92.5,413.74245 12,0.008 0,6.25 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.75755 0,-9e-4 z"
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient25929-7-8);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="path15850"
+ d="m 93,420.5 9.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(#linearGradient15963-3);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 103.5,414.75 -10,-0.008 0,4.75755 -1.5,1.5 -1.5,-1.5"
+ id="path15852" />
+ <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,419.99245 1.5,1.5 12,0.008 1.5,-1.49245 0,-6.50755 -3,-0.008"
+ id="path15856"
+ sodipodi:nodetypes="cccccc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339-2"
+ 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"
+ id="rect36341-7"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343-6">
+ <path
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ 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="path36363-9"
+ style="opacity:0.3;fill:url(#radialGradient37501-4-64);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <g
+ id="g36345-6"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349-3"
+ style="fill:#fa2929;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#ba0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351-4"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353-6"
+ style="fill:#8c0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#bb1010;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355-4"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357-2"
+ style="fill:#fa2929;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#ff7777;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359-5"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361-7"
+ 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="path36365-0"
+ style="fill:none;stroke:url(#linearGradient37503-1-7);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339-2-8"
+ 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"
+ id="rect36341-7-6"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343-6-8">
+ <path
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ 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="path36363-9-4"
+ style="opacity:0.3;fill:url(#radialGradient37501-4-9-0);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <g
+ id="g36345-6-9"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349-3-1"
+ style="fill:#1fdf05;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#16ba00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351-4-7"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353-6-7"
+ style="fill:#109400;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#24bb10;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355-4-6"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357-2-5"
+ style="fill:#60f44c;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#87ff77;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359-5-2"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361-7-9"
+ 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="path36365-0-7"
+ style="fill:none;stroke:url(#linearGradient37503-1-9-9);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339-2-9"
+ 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"
+ id="rect36341-7-4"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343-6-2">
+ <path
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ 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="path36363-9-0"
+ style="opacity:0.3;fill:url(#radialGradient37501-4-6-8);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <g
+ id="g36345-6-4"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349-3-5"
+ style="fill:#5050fb;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#0000ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351-4-3"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353-6-4"
+ style="fill:#00008c;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#1010bb;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355-4-4"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ 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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357-2-9"
+ style="fill:#5050fb;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#9a9afd;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359-5-4"
+ sodipodi:cx="132"
+ 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"
+ 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"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361-7-0"
+ 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="path36365-0-0"
+ style="fill:none;stroke:url(#linearGradient37503-1-1-1);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42207-2"
+ transform="translate(230.94982,190.97922)">
+ <g
+ transform="translate(83.990364,83.999999)"
+ id="g42209-9"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42211-6"
+ 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="path42213-0"
+ style="fill:none;stroke:url(#linearGradient42487-4-5);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42489-5-9);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42215-8"
+ 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
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42491-0-9);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42217-3"
+ 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="path17230"
+ style="fill:none;stroke:url(#linearGradient17232-8);stroke-width:3.2130022;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.31076006,0,0,0.31171146,55.992715,84.224347)" />
+ </g>
+ <g
+ transform="matrix(1.3088013,0,0,1.3078064,114.94487,78.842325)"
+ style="display:inline"
+ 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="g42219-5" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16164">
+ <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"
+ width="16"
+ height="16"
+ x="173"
+ y="241" />
+ <g
+ id="g16145">
+ <g
+ transform="translate(-150.04936,350.7292)"
+ id="g18697-4">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path18699-1"
+ 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"
+ style="fill:none;stroke:url(#linearGradient28405-0);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient18721-1-6);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 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"
+ id="path18719-9" />
+ <g
+ transform="translate(179,-179)"
+ id="g18703-1">
+ <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:url(#linearGradient18728-6-0);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 146.0019,73.295281 5,-1.894157 5,1.894157 -5,2.073959 -5,-2.073959 z"
+ id="path18707-3" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient18765-0-9);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 334.98437,-105.6875 -5,2.04687 0.0156,6.89063 5,-2.75 z"
+ id="path18763-6" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient18712-0-7);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ 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"
+ id="path18709-9"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ style="opacity:0.7"
+ id="g18737-7" />
+ </g>
+ <g
+ id="g52877-0"
+ style="display:inline;enable-background:new"
+ transform="translate(-332.03324,273.93783)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#2968c3;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;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="path52879-3"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path52881-6"
+ 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(#radialGradient53141-5-8);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="path52883-5"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path52885-6"
+ 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(#linearGradient53143-6-3);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path52887-1"
+ d="m 520.48389,-31.45862 -6,6.75 2,2.25 4,-4"
+ style="fill:none;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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient53145-1-0);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 520.98389,-31.95862 -6.75,7.75 1.75,1.75 5,-4.5 0,-5 z"
+ id="path52889-3"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path52891-3"
+ d="m 513.48389,-22.45862 7,-8.25"
+ 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="path52893-4"
+ 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(#linearGradient53147-9-4);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16082">
+ <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"
+ width="16"
+ height="16"
+ x="152"
+ y="241" />
+ <g
+ id="g16049">
+ <g
+ id="g16027">
+ <g
+ transform="translate(-20.81186,-5.9082992)"
+ id="g27791"
+ style="display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#181dff;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#2f4cff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-13.91186,-7.9082992)"
+ id="g27791-5"
+ style="fill:none;display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-5"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-0"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#00cc19;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#34ff24;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-10.27839,-7.4632172)"
+ id="g27791-9"
+ style="display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-7"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-5"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#ffff0a;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#fcff7b;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-6.9118602,-5.9082992)"
+ id="g27791-0"
+ style="display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-54"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-1"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#ff0606;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ff3131;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-17.39403,-7.3654702)"
+ id="g27791-5-2"
+ style="fill:none;display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;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 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-5-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-0-6"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#00bc86;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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#24ffea;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-7-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g16016">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path18699-7"
+ d="m 159.95712,247.8542 -3.25648,1.32353 -1.7128,5.25087 5,2.71875 4.99999,-2.71875 -1.77423,-5.25087 z"
+ style="fill:none;stroke:#0b1728;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient16010);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 159.98133,247.9448 -3.25648,1.2408 -1.73704,5.243 5,2.71875 4.99999,-2.71875 -1.75,-5.243 z"
+ id="path18719-4" />
+ <g
+ transform="translate(8.95064,173.9792)"
+ id="g18703-0">
+ <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:url(#linearGradient15994);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 147.75124,75.228495 3.25648,-1.253486 3.25648,1.253486 -3.25648,1.372473 z"
+ id="path18707-0" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient16005);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 163.2136,249.34317 -3.25648,1.32353 -0.006,6.4375 5,-2.75 z"
+ id="path18763-7" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient16002);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 162.79956,249.6191 1.65308,4.57246 -4.5,2.48007 -4.5,-2.48007 1.75043,-4.61666 2.79824,-1.11389 z"
+ id="path18709-5"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0"
+ id="path14332-7-5"
+ d="m 161.04227,247.90828 c 0.24495,-0.26634 0.39423,-0.62011 0.39423,-1.00834 0,-0.8284 -0.67974,-1.49994 -1.51825,-1.49994 -0.83851,0 -1.51825,0.67154 -1.51825,1.49994 0,0.43979 0.0353,0.57241 0.34052,0.84677"
+ style="fill:#e6e6e6;fill-opacity:1;stroke:#0b1728;stroke-width:2.80000019;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ transform="matrix(0.8540253,0,0,-1.199954,81.751209,396.89409)"
+ 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"
+ sodipodi:cx="91.5"
+ id="path14336-5-6"
+ style="fill:#000000;fill-opacity:1;stroke:url(#linearGradient15989);stroke-width:1.28417933;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:type="arc" />
+ <rect
+ style="opacity:0.75;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="rect14340-2-4"
+ width="2.0011597"
+ height="2"
+ x="158.93533"
+ y="245.8999" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16224">
+ <rect
+ y="241"
+ x="194"
+ height="16"
+ width="16"
+ id="rect18695-5-8"
+ 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="g16203">
+ <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-6"
+ width="16"
+ height="16"
+ x="193.95064"
+ y="240.9792" />
+ <g
+ clip-path="url(#clipPath42711-8-1)"
+ style="display:inline;enable-background:new"
+ id="g27663-9"
+ transform="matrix(0.9168751,0,0,0.9161255,86.13094,44.221905)"
+ 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="ccccccccc"
+ inkscape:connector-curvature="0"
+ id="path27665-7"
+ d="m 140.02478,121.67739 -4.38034,-0.0133 0.0328,4.36819 -6.18368,-0.0323 -0.0643,-16 6.1827,-0.0158 -0.0143,4.42449 4.42553,-0.0164 z"
+ clip-path="none"
+ mask="none"
+ style="fill:url(#linearGradient15368-7);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.45480967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ style="fill:url(#linearGradient15326-8);fill-opacity:1;stroke:#183e75;stroke-width:1.45480967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none"
+ clip-path="none"
+ d="m 135.64444,121.66409 -6.15088,-0.006 -0.0643,-7.28458 6.1684,0.0349 z"
+ id="path15284"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ style="fill:none;stroke:#0b1728;stroke-width:1.45480967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none"
+ clip-path="none"
+ d="m 140.02478,121.67739 -4.38034,-0.0133 0.0328,4.36819 -6.18368,-0.0323 -0.0643,-16 6.1827,-0.0158 -0.0143,4.42449 4.42553,-0.0164 z"
+ id="path15318"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ </g>
+ <g
+ id="g27669-3"
+ style="opacity:0.55;display:inline;enable-background:new"
+ transform="translate(-42.04936,-19.020799)">
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ sodipodi:nodetypes="cccc"
+ id="path27671-9"
+ d="M 243.50439,274.05251 237.04285,268 l 0.43058,-0.40461 6.03096,-5.66723"
+ style="fill:url(#linearGradient42432-3-3);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
+ style="fill:url(#linearGradient15281-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.87159598;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 243.55198,273.44361 237.66157,268 l 5.84282,0.0171"
+ id="path15273"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path27673-0-1"
+ d="m 200.70018,253.41671 -4.93656,-4.42903 4.93656,-4.57097"
+ style="fill:none;stroke:url(#linearGradient15620-8);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
+ id="g27675-38"
+ style="display:inline;enable-background:new"
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-41.79538,113.49288)">
+ <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 73.545051,272.22272 7.071067,-7.07107"
+ id="path27679-2"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path42388-6"
+ 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-8" />
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.6507937;display:inline;enable-background:new"
+ d="m 207.43504,247.49483 1.06248,0"
+ id="path15333"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.6507937;display:inline;enable-background:new"
+ d="m 203.9116,244.49483 1.51561,0"
+ id="path15333-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.6507937;display:inline;enable-background:new"
+ d="m 203.9116,247.51045 1.54686,0"
+ id="path15333-3"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1b4685;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 207.38817,249.47921 0.0703,0.004"
+ id="path15333-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#185e98;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 203.38817,249.47921 1.07811,0.0118"
+ id="path15333-2-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#143564;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 204.37254,253.47921 1.07811,0.0118"
+ id="path15333-2-7-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16281">
+ <rect
+ y="241"
+ x="236"
+ height="16"
+ width="16"
+ id="rect18695-5-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" />
+ <g
+ id="g38510"
+ style="display:inline;enable-background:new"
+ transform="translate(-0.04936017,-0.02079917)">
+ <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="rect41297-5"
+ width="10"
+ height="16"
+ x="239"
+ y="241" />
+ <path
+ style="fill:url(#linearGradient15474-9);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 244,242.5 c -1.8975,0 -3.4375,1.12 -3.4375,2.5 l 0,2.6875 c -0.79985,0.58688 -1.28125,1.40301 -1.28125,2.4375 0,1.01219 0.48237,1.85277 1.28125,2.4375 l 0,1.4375 c 0,1.38 1.54,2.5 3.4375,2.5 1.8975,0 3.4375,-1.12 3.4375,-2.5 l 0,-1.375 c 0.82151,-0.58809 1.3125,-1.44988 1.3125,-2.5 0,-1.02039 -0.50216,-1.82067 -1.3125,-2.40625 l 0,-2.71875 c 0,-1.38 -1.54,-2.5 -3.4375,-2.5 z"
+ id="path41299-1"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.44561403;fill:none;stroke:url(#linearGradient15467-9);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 246.78175,244.56297 c -0.49244,0.67079 -1.66895,1.05852 -2.78633,1.05852 -1.11738,0 -2.54413,-0.3096 -2.81106,-1.12463"
+ id="path41303-1"
+ sodipodi:nodetypes="czs" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ id="path41307-7"
+ d="m 241.4192,253.61696 c 0.11987,0.88868 0.64962,2.00518 2.61584,2.01183 1.81407,0.006 2.49621,-1.01999 2.49621,-2.00379"
+ style="fill:none;stroke:#1b4685;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.64285715;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="czcsssc"
+ id="path15557"
+ d="m 247.22147,247.96875 c -0.5625,0.53865 -1.82275,0.90274 -3.1948,0.90274 -1.37205,0 -2.25345,-0.3128 -3.15167,-0.80899 -0.625,0.59375 -1.17803,1.9131 -0.72606,2.94175 0.61274,1.39456 1.58368,2.00791 3.99437,2.02034 2.38609,0.0123 3.13442,-0.85323 3.75195,-2.02459 0.57357,-1.08798 0.16996,-2.1875 -0.67379,-3.03125 z"
+ style="fill:none;stroke:url(#linearGradient15601-9);stroke-width:1;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
+ inkscape:connector-curvature="0"
+ id="path41305-9"
+ d="m 244,242.5 c -2.18749,0 -3.4375,1.12 -3.4375,2.5 l 0,2.3125 c -0.8822,0.72794 -1.4375,1.73295 -1.4375,2.84375 0,1.1108 0.5553,2.11581 1.4375,2.84375 l 0,0.5 c 0,2 1.54,3 3.4375,3 1.8975,0 3.4375,-1 3.4375,-3 l 0,-0.5 c 0.8822,-0.72794 1.4375,-1.73295 1.4375,-2.84375 0,-1.1108 -0.5553,-2.11581 -1.4375,-2.84375 l 0,-2.3125 c 0,-1.38 -1.24999,-2.5 -3.4375,-2.5 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000007;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
+ style="display:inline;enable-background:new"
+ id="g41715-3"
+ transform="matrix(0.75,0,0,0.625,396.9999,55.104854)">
+ <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="rect41717-2"
+ width="16"
+ height="16"
+ x="-211.99985"
+ y="304" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ transform="translate(73.00016,196)"
+ id="g41719-6" />
+ <g
+ style="display:inline"
+ id="g41739-4"
+ transform="matrix(1.1658027,0,0,1.1657997,-354.28956,51.94393)"
+ 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
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient15576-5);stroke-width:1;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 247.03531,249.33728 c -0.5,0.22615 -1.69837,0.52774 -2.8823,0.52774 -1.18393,0 -1.75974,-0.0315 -3.02667,-0.49649"
+ id="path41303-1-0"
+ sodipodi:nodetypes="czs" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000007;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 250.25295,253 c 0.73683,-0.72794 1.01313,-1.73295 1.01313,-2.84375 0,-1.1108 -0.2763,-2.11581 -1.01313,-2.84375"
+ id="path15603"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path15609"
+ d="m 249.80713,252.38128 c 0.53336,-0.70678 0.65533,-1.36527 0.65533,-2.22503 0,-0.80144 -0.27822,-1.5779 -0.65533,-2.18084"
+ style="fill:none;stroke:#aacee7;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.80392157;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000007;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 237.81491,253 c -0.73683,-0.72794 -1.01313,-1.73295 -1.01313,-2.84375 0,-1.1108 0.2763,-2.11581 1.01313,-2.84375"
+ id="path15603-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path15609-7"
+ d="m 238.26073,252.38128 c -0.53336,-0.70678 -0.65533,-1.36527 -0.65533,-2.22503 0,-0.80144 0.27822,-1.5779 0.65533,-2.18084"
+ style="fill:none;stroke:#aacee7;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.80392157;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g81264">
+ <rect
+ y="241"
+ x="278"
+ height="16"
+ width="16"
+ id="rect41153-9"
+ 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.96226475,0.05341077)"
+ id="g16521">
+ <rect
+ y="242.48071"
+ x="280.45062"
+ height="12.983693"
+ width="12.031255"
+ id="rect41157-7"
+ style="fill:url(#linearGradient81258);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.90000004;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" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41159-4"
+ d="m 281.45064,253.1653 0.0312,-9.6861 3.81301,0.0312"
+ style="fill:none;stroke:url(#linearGradient81260);stroke-width:0.99999994;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\Kopia 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:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.53174594;display:inline;enable-background:new"
+ d="m 291.50046,246.74298 -3.08218,7.80871"
+ id="path15817-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.48809521"
+ d="m 285.63278,246.41513 -3.2942,8.11179"
+ id="path15817"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#555555;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 286.48189,242.32295 0.0625,12.09375"
+ id="path15730"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59"
+ width="2.0172396"
+ height="2.0000157"
+ x="279.45065"
+ y="241.47917" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41159-4-9"
+ d="m 287.42759,252.9156 -0.0313,-9.49861 3.85989,0.0312"
+ style="fill:none;stroke:url(#linearGradient81262);stroke-width:0.99999982px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ 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="fill:none;stroke:#1b4685;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 292.04439,242.6042 -5.18214,13.04504"
+ id="path15722"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1b4685;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 286.07564,242.5417 -5.19822,12.90441"
+ id="path15726"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-1"
+ width="2.0172396"
+ height="2.0000157"
+ x="285.47092"
+ y="241.53545" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-50"
+ width="2.0172396"
+ height="2.0000157"
+ x="285.47092"
+ y="254.48941" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-6"
+ width="2.0172396"
+ height="2.0000157"
+ x="291.48386"
+ y="254.48941" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-16"
+ width="2.0172396"
+ height="2.0000157"
+ x="291.45065"
+ y="241.47917" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-15"
+ width="2.0172396"
+ height="2.0000157"
+ x="279.48859"
+ y="254.48941" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16263">
+ <rect
+ y="241"
+ x="215"
+ height="16"
+ width="16"
+ id="rect18695-5-85"
+ 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="g16254">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccscsscccscscccsccc"
+ inkscape:connector-curvature="0"
+ id="path15496"
+ d="m 220.26315,246.13546 c -0.0862,0.1378 -0.24068,0.22975 -0.40625,0.28125 -1.65981,0.47731 -3.15715,1.19818 -4.5,2.59375 -0.0159,0.0174 -0.0268,0.0393 -0.0312,0.0625 -0.001,0.0103 -0.001,0.0208 0,0.0312 -0.001,0.0103 -0.001,0.0208 0,0.0312 -0.001,0.0104 -0.001,0.0208 0,0.0312 0.0905,0.15733 0.21244,0.52956 0.25,0.8125 0.0551,0.41528 -0.0701,0.57924 -0.21875,0.8125 -0.0121,0.008 -0.0227,0.0191 -0.0312,0.0312 -0.001,0.0104 -0.001,0.0208 0,0.0312 -0.001,0.0103 -0.001,0.0208 0,0.0312 -0.001,0.0104 -0.001,0.0208 0,0.0312 0.008,0.0121 0.0191,0.0227 0.0312,0.0312 1.14704,1.20048 2.82583,2.11181 4.34375,2.15625 0.23229,0.01 0.47603,0.12502 0.59375,0.3125 0.16075,0.25148 0.43475,0.47431 0.75,0.65625 0.36481,0.21054 0.91885,0.30403 1.0936,0.3126 -0.22349,-0.50587 -0.17899,-0.77088 -0.0469,-0.99985 0.0995,-0.17241 0.27563,-0.29702 0.54688,-0.34375 1.23062,-0.212 2.86055,-0.63055 4.03125,-1.34375 0.29545,-0.18247 0.80307,-0.0462 1,0.25 0.55094,0.7385 1.45946,1.2674 2.03896,1.31646 -0.36853,-0.9196 -0.50376,-2.31287 -0.46489,-3.25371 0.0492,-1.1901 0.4842,-2.52395 1.04302,-3.51538 -0.16982,0.006 -0.65061,0.17808 -0.71074,0.20318 -0.7366,0.30737 -1.4716,0.94031 -1.90625,1.5625 -0.21933,0.29875 -0.71618,0.4032 -1,0.1875 -1.35724,-1.03154 -2.55364,-1.6969 -4.09375,-2.1875 -0.26943,-0.0858 -0.50165,-0.42209 -0.5,-0.71875 0.002,-0.30009 0.0702,-0.84684 0.12109,-1.07402 -0.58853,0.18102 -1.36128,0.81203 -1.93359,1.66737 z"
+ style="fill:none;stroke:url(#linearGradient38716-8);stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;display:inline;enable-background:new" />
+ <path
+ style="fill:url(#radialGradient15517-8);fill-opacity:1;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 219.6786,253.82631 c -1.96642,-0.0576 -4.05614,-1.31113 -5.29929,-2.86623 0.0654,-0.19861 0.53326,-0.60538 0.48122,-0.99782 -0.0595,-0.44857 -0.37333,-0.70398 -0.47362,-0.96241 1.5443,-1.81083 3.32964,-2.734 5.24944,-3.28607 0.78991,-1.17883 1.845,-2.02236 3.60073,-2.29898 -0.23142,0.67492 -0.40517,1.48328 -0.41544,2.14499 1.60855,0.52209 2.84544,1.19775 4.24601,2.26976 1.05365,-1.50823 3.37131,-2.56597 4.4316,-1.95202 -0.84375,1.27451 -1.45665,2.90118 -1.50672,4.17975 -0.0491,1.25211 0.0947,2.42706 0.75517,3.90477 -1.30024,0.35961 -2.91498,-0.40691 -3.71178,-1.61649 -1.31489,0.80105 -3.03198,1.22409 -4.31307,1.42108 0.13331,0.35326 0.31382,0.79794 0.42375,1.41797 -1.5092,0.0506 -2.82758,-0.35645 -3.468,-1.3583 z"
+ id="path26202"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccccccsccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path38361"
+ d="m 218.00011,250.69439 c -0.39287,0 -0.71132,-0.31189 -0.71132,-0.69657 0,-0.38468 0.31845,-0.69659 0.71132,-0.69659 0.39025,0 0.70763,0.30797 0.71128,0.69334 0,0.38793 -0.31844,0.69982 -0.71128,0.69982 z"
+ style="fill:none;stroke:url(#linearGradient15553-4);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.72222218;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ style="fill:none;stroke:#183e75;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 217.62649,250.02159 c -0.17675,0 -0.32002,-0.1385 -0.32002,-0.30932 0,-0.17083 0.14327,-0.30933 0.32002,-0.30933 0.17557,0 0.31836,0.13676 0.32,0.30789 0,0.17226 -0.14327,0.31076 -0.32,0.31076 z"
+ id="path26221"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15545-5);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.58823529;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 219.95124,248.20112 c 0.63267,0.99518 0.82685,2.28773 0.0962,3.39254"
+ id="path26223-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ transform="translate(-0.04936017,-0.02079917)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.21185222"
+ inkscape:original="M 222.25 244.5 C 221.66147 244.68102 220.88481 245.30091 220.3125 246.15625 C 220.2263 246.29405 220.07182 246.386 219.90625 246.4375 C 218.24644 246.91481 216.7491 247.63568 215.40625 249.03125 C 215.39035 249.04865 215.3794 249.07055 215.375 249.09375 C 215.374 249.10405 215.374 249.1146 215.375 249.125 C 215.374 249.1353 215.374 249.14585 215.375 249.15625 C 215.374 249.16665 215.374 249.1771 215.375 249.1875 C 215.4655 249.34483 215.58744 249.71706 215.625 250 C 215.6801 250.41528 215.5549 250.57924 215.40625 250.8125 C 215.39415 250.8205 215.3835 250.83165 215.375 250.84375 C 215.374 250.85415 215.374 250.8646 215.375 250.875 C 215.374 250.8853 215.374 250.89585 215.375 250.90625 C 215.374 250.91665 215.374 250.9271 215.375 250.9375 C 215.383 250.9496 215.39415 250.96025 215.40625 250.96875 C 216.55329 252.16923 218.23208 253.08056 219.75 253.125 C 219.98229 253.135 220.22603 253.25002 220.34375 253.4375 C 220.5045 253.68898 220.7785 253.91181 221.09375 254.09375 C 221.45856 254.30429 222.01275 254.39768 222.1875 254.40625 C 221.96401 253.90038 221.99291 253.63522 222.125 253.40625 C 222.2245 253.23384 222.41625 253.10923 222.6875 253.0625 C 223.91812 252.8505 225.54805 252.43195 226.71875 251.71875 C 227.0142 251.53628 227.52182 251.67255 227.71875 251.96875 C 228.26969 252.70725 229.1705 253.23219 229.75 253.28125 C 229.38147 252.36165 229.24238 250.97209 229.28125 250.03125 C 229.33045 248.84115 229.78493 247.52268 230.34375 246.53125 C 230.17393 246.53725 229.68513 246.69365 229.625 246.71875 C 228.8884 247.02612 228.1534 247.65906 227.71875 248.28125 C 227.49942 248.58 227.00257 248.68445 226.71875 248.46875 C 225.36151 247.43721 224.16511 246.77185 222.625 246.28125 C 222.35557 246.19545 222.12335 245.85916 222.125 245.5625 C 222.127 245.26241 222.19911 244.72718 222.25 244.5 z "
+ style="fill:none;stroke:url(#linearGradient15502-8);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path15500"
+ d="m 221.96875,244.90625 c -0.47698,0.2556 -1.02431,0.71077 -1.46875,1.375 -0.12408,0.19836 -0.33308,0.28211 -0.53125,0.34375 a 0.21187341,0.21187341 0 0 1 0,0.0312 c -1.62449,0.46715 -3.06989,1.15677 -4.375,2.5 -0.005,0.005 0.005,0.026 0,0.0312 0.1061,0.21524 0.2123,0.49726 0.25,0.78125 0.0568,0.42776 -0.0841,0.69165 -0.21875,0.90625 1.11129,1.13328 2.71326,1.98992 4.125,2.03125 0.29567,0.0127 0.61425,0.14029 0.78125,0.40625 0.1325,0.20728 0.35983,0.42268 0.65625,0.59375 0.20197,0.11656 0.49212,0.2047 0.71875,0.25 -0.0302,-0.11277 -0.0911,-0.24526 -0.0937,-0.34375 -0.005,-0.19698 0.0446,-0.36065 0.125,-0.5 0.13631,-0.23619 0.40186,-0.41416 0.71875,-0.46875 1.21549,-0.20939 2.80996,-0.62559 3.9375,-1.3125 0.21394,-0.13213 0.48738,-0.12178 0.71875,-0.0625 0.22418,0.0574 0.42522,0.18054 0.5625,0.375 0.41333,0.55404 1.07488,0.98799 1.5625,1.15625 -0.29258,-0.93531 -0.41043,-2.11125 -0.375,-2.96875 0.0456,-1.10343 0.44992,-2.25295 0.9375,-3.21875 -0.14571,0.0415 -0.29515,0.0995 -0.28125,0.0937 -0.68743,0.28685 -1.40343,0.91443 -1.8125,1.5 a 0.21187341,0.21187341 0 0 1 -0.0312,0 c -0.14786,0.2014 -0.35962,0.32934 -0.59375,0.375 -0.23413,0.0457 -0.48506,-0.002 -0.6875,-0.15625 -1.34443,-1.0218 -2.51369,-1.67283 -4.03125,-2.15625 -0.1942,-0.0618 -0.35572,-0.18089 -0.46875,-0.34375 -0.11303,-0.16286 -0.18863,-0.35845 -0.1875,-0.5625 0.001,-0.19898 0.0297,-0.41985 0.0625,-0.65625 z" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15537-5);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 220.40065,247.42921 c 1.3319,1.37892 1.29257,3.57882 0.34306,4.70903"
+ id="path26223-2-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16592">
+ <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"
+ width="16"
+ height="16"
+ x="488"
+ y="262" />
+ <g
+ id="g16579">
+ <rect
+ y="268.95908"
+ x="495.95065"
+ height="1"
+ width="2"
+ id="rect23532-1-0"
+ style="opacity:0.8;fill:#1e56ab;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;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 501.95064,269.22921 0,0.75008 0,2.99996 -3,1.5 c -3,1.5 -6.25,1.5 -10,1.49996 l -0.0183,-2.52715 c 0,0 3.366,-6.98108 4.33827,-8.04174 0.97227,-1.06066 4.00392,-2.08028 4.61579,-2.33915 3.72167,-0.006 4.09599,4.72641 4.06425,6.15804 z m -8,0.25 4.90625,-1.875 c 0.0715,-1.36645 -0.67378,-2.97927 -2.03429,-3.23624"
+ id="path23522-5"
+ sodipodi:nodetypes="scccccsccsccc" />
+ <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 493.95064,269.47921 4,-1.5 0.9375,-0.40625 3.0625,1.65625 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-5" />
+ <path
+ 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"
+ 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"
+ 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"
+ 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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.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\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"
+ 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" />
+ <path
+ 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"
+ 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"
+ d="m 497.15108,270.57068 c -0.87852,0.21783 -1.75,-0.0997 -1.75,-0.67783 0,-0.57817 0.44856,-1.11322 1.32701,-1.33132 0.77415,-0.19217 1.49604,0.10015 1.66916,0.65891 0.16722,0.53968 -0.3266,1.12224 -1.24617,1.35024 z"
+ id="path27309-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.37383178"
+ d="m 492.06936,275.51839 0.98651,-0.0593"
+ id="path27317-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14953">
+ <rect
+ y="198.9792"
+ x="4.9506397"
+ height="16"
+ width="16"
+ id="rect23018-5-4"
+ 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.94058502,0,0,0.94058502,0.9128606,12.74924)"
+ id="g56716">
+ <path
+ sodipodi:type="star"
+ style="fill:url(#linearGradient14951);fill-opacity:1;stroke:#000000;stroke-width:0.96882826;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path15855"
+ sodipodi:sides="5"
+ sodipodi:cx="13.700194"
+ sodipodi:cy="207.20645"
+ sodipodi:r1="7.1873641"
+ sodipodi:r2="3.3158474"
+ sodipodi:arg1="0.94697287"
+ sodipodi:arg2="1.5618338"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 17.898641,213.04008 -4.168729,-2.51791 -4.280439,2.47993 1.106473,-4.74277 -3.6812884,-3.3046 4.8525664,-0.41328 2.005278,-4.52229 1.892578,4.48735 4.920618,0.50967 -3.682889,3.18662 z"
+ inkscape:transform-center-x="-0.010954063"
+ inkscape:transform-center-y="-0.74285516"
+ transform="matrix(1.0972098,0,0,1.0975406,-2.0923019,-19.740595)" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.06316817;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 12.931855,202.51514 -1.201334,2.70994 c -0.137665,0.32193 -0.454082,0.55986 -0.800889,0.60222 l -2.9032248,0.26765 2.2358168,1.97391 c 0.261321,0.2395 0.380487,0.62447 0.300333,0.97022 l -0.667408,2.81032"
+ id="path15869"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(-0.04936017,-0.02079917)"
+ style="display:inline;enable-background:new"
+ id="g16432">
+ <rect
+ y="199"
+ x="68"
+ height="16"
+ width="16"
+ id="rect23008-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" />
+ <g
+ style="display:inline"
+ transform="translate(-129.04638,24.90625)"
+ 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="g11015-1">
+ <path
+ style="fill:url(#linearGradient15744-9-8);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 205.54638,177.59375 -1,0 0,9 1,0 5,-3.75 0,-1.5 z"
+ id="path11017-5"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path11019-7"
+ d="m 205.54638,185.34375 0,-6.5 4.03125,3.01562"
+ style="fill:none;stroke:url(#linearGradient10982-8-5);stroke-width:1.10000002;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:url(#linearGradient16268-9);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect10822-0-7"
+ width="9.2000065"
+ height="2.1999984"
+ x="202.39999"
+ y="71.400002"
+ rx="0"
+ ry="1.4168683"
+ 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="cc"
+ style="fill:none;stroke:url(#linearGradient16302-5);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 72.27078,203.33478 0.475194,-7e-5"
+ id="path10824-4-2"
+ 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="translate(-0.04936017,-0.02079917)"
+ style="display:inline;enable-background:new"
+ id="g16424">
+ <rect
+ transform="scale(-1,1)"
+ y="198.89999"
+ x="-62.900002"
+ height="16"
+ width="16"
+ id="rect23008-0-8"
+ 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;enable-background:new"
+ transform="matrix(-1,0,0,1,259.94638,24.80625)"
+ 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="g11015-1-2">
+ <path
+ style="fill:url(#linearGradient15744-9-0-9);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 205.54638,177.59375 -1,0 0,9 1,0 5,-3.75 0,-1.5 z"
+ id="path11017-5-5"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11019-7-9"
+ d="m 205.54638,178.84375 4.03125,3.01562"
+ style="fill:none;stroke:url(#linearGradient10982-8-9-5);stroke-width:1.10000002;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:url(#linearGradient16268-5-0);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect10822-0-7-7"
+ width="9.2000065"
+ height="2.1999984"
+ x="202.29999"
+ y="-59.5"
+ rx="0"
+ ry="1.4168683"
+ 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="cc"
+ style="fill:none;stroke:url(#linearGradient16302-3-4);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 58.62922,203.23478 -0.475194,-7e-5"
+ id="path10824-4-2-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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56653">
+ <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"
+ style="opacity:0.3;color:#000000;fill:#0027b4;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18242" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path38437-9"
+ 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"
+ style="color:#000000;fill:#000000;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="path18240"
+ d="m 289.95065,120.97921 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"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g27975"
+ style="display:inline;enable-background:new"
+ transform="translate(-0.04936017,-0.02079917)">
+ <rect
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36400-0-73"
+ width="16"
+ height="16"
+ x="278"
+ y="115" />
+ <g
+ id="g36402-8-9"
+ transform="translate(186.99836,-42.1)">
+ <rect
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;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="rect36426-6-8"
+ width="2.0000153"
+ height="2.0000069"
+ x="102"
+ y="170"
+ rx="0"
+ ry="0" />
+ <g
+ id="g36404-0-04"
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(8.000015,151)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient27963-5);stroke-width:3.29999995;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 85.65162,18.243282 88.999985,16"
+ id="path36410-3-3"
+ 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="path36407-9-8"
+ d="m 88.999985,8 0,8"
+ style="fill:none;stroke:#00163c;stroke-width:3.29999995;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="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"
+ id="path36412-3-7"
+ d="M 94.99997,20 88.999985,16"
+ style="fill:none;stroke:#5d0606;stroke-width:3.29999995;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="cc" />
+ </g>
+ <rect
+ ry="0"
+ rx="0"
+ y="158"
+ x="96"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36416-1-8"
+ style="fill:none;stroke:#001e50;stroke-width:1.79999995;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"
+ 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="path36418-7-2"
+ d="m 97,159 0,8"
+ style="fill:none;stroke:#4c8ff4;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"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient27965-1);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 93.15039,169.65379 3.794367,-2.66484"
+ id="path36420-1-8"
+ 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="path36424-2-5"
+ d="M 92.728285,169.42532 96.499985,166.75 96.5,159.5"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient27967-9);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"
+ 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"
+ id="path36428-6-8"
+ d="M 102.99998,171 97,167"
+ style="fill:none;stroke:#ef4e29;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"
+ sodipodi:nodetypes="cc" />
+ <rect
+ style="opacity:0.3;fill:none;stroke:#001e50;stroke-width:1.79999995;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="rect36432-1-2"
+ width="2.0000153"
+ height="2.0000069"
+ x="96"
+ y="158"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#4c8ff4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36434-5-5"
+ width="2"
+ height="2"
+ x="96.000023"
+ y="158"
+ rx="0"
+ ry="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"
+ 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"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path36436-4-6"
+ style="opacity:0.5;fill:url(#radialGradient27969-8);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ 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 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"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path36438-7-62"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0.6666679,0,0,0.6666668,49.999915,157.33333)" />
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="102"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36440-7-5"
+ style="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;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
+ ry="0"
+ rx="0"
+ y="170"
+ x="102.00002"
+ height="2"
+ width="2"
+ id="rect36442-2-0"
+ style="fill:#eb512e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="opacity:0.8"
+ id="g36444-2-2">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient27971-9);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 96.5,159.5 0,-1 1,0"
+ id="path36446-6-0"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient27973-6);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 102.49999,171.5 0,-1 1,0"
+ id="path36450-1-8"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56628">
+ <g
+ transform="translate(-0.04936017,-1.0207992)"
+ id="g18315"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path18244-7"
+ style="opacity:0.3;color:#000000;fill:#45eb0a;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269,122 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z m 0,-6 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" />
+ <path
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269,116 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"
+ id="path38437-9-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269,122 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path38435-3-8-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="114.97919"
+ x="256.95062"
+ height="16"
+ width="16"
+ id="rect36400-0"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-2.0730802,-0.12079917)"
+ id="g17954"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient17973-0);stroke-width:3.29999995;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 261.67372,127.26538 3.34836,-2.24328"
+ id="path36410-3-3-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" />
+ <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="path36407-9"
+ d="m 264.99997,117 0,8"
+ style="fill:none;stroke:#00163c;stroke-width:3.29999995;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="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"
+ id="path36412-3"
+ d="m 270.99996,129 -5.99999,-4"
+ style="fill:none;stroke:#183c00;stroke-width:3.29999995;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="cc" />
+ <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="path36420-1-8-8"
+ d="m 261.17248,127.67589 3.79437,-2.66484"
+ style="fill:none;stroke:url(#linearGradient17975-1);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"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:#001e50;stroke-width:1.79999995;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="rect36416-1"
+ width="2.0000153"
+ height="2.0000069"
+ x="263.99997"
+ y="116"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4c8ff4;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 264.99998,117 0,8"
+ id="path36418-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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient17977-8);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 260.75037,127.44742 3.7717,-2.67532 2e-5,-7.25"
+ id="path36424-2-5-6"
+ 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
+ ry="0"
+ rx="0"
+ y="128"
+ x="269.99997"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36426-6"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;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
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4ee420;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 270.99996,129 -5.99998,-4"
+ id="path36428-6"
+ 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
+ ry="0"
+ rx="0"
+ y="116"
+ x="263.99997"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36432-1"
+ style="opacity:0.3;fill:none;stroke:#001e50;stroke-width:1.79999995;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
+ ry="0"
+ rx="0"
+ y="116"
+ x="264"
+ height="2"
+ width="2"
+ id="rect36434-5"
+ style="fill:#4c8ff4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient17979-7);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36436-4"
+ sodipodi:cx="70.5"
+ 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"
+ 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"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.6666679,0,0,0.6666668,217.99989,115.33333)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36438-7"
+ sodipodi:cx="70.5"
+ 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"
+ 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="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;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="rect36440-7"
+ width="2.0000153"
+ height="2.0000069"
+ x="269.99997"
+ y="128"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#4ee51f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36442-2"
+ width="2"
+ height="2"
+ x="270"
+ y="128"
+ rx="0"
+ ry="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient17981-0);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 264.49998,117.5 0,-1 1,0"
+ id="path36446-6"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.72000002;fill:none;stroke:url(#linearGradient17983-9);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.49997,129.5 0,-1 1,0"
+ id="path36450-1"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56680">
+ <g
+ transform="translate(-0.04936017,-1.0207992)"
+ id="g18312"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path11174-1-9"
+ style="opacity:0.3;color:#000000;fill:#f82516;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 311,122 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 m -1,-9 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z" />
+ </g>
+ <rect
+ y="114.97919"
+ x="298.95062"
+ height="16"
+ width="16"
+ id="rect36400-0-73-7"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path38435-3-8"
+ d="m 310.95065,114.97921 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#000000;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="path18240-3"
+ d="m 310.95065,120.97921 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"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.95063983,-0.12079917)"
+ id="g27760"
+ style="display:inline;enable-background:new">
+ <rect
+ style="fill:none;stroke:#183c00;stroke-width:1.79999995;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="rect36416-1-8-5"
+ width="2.0000153"
+ height="2.0000069"
+ x="302.98999"
+ y="116"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="128"
+ x="308.98999"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36426-6-8-0"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;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: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="path36410-3-3-7-4"
+ d="m 300.65,127.2387 3.34836,-2.24328"
+ style="fill:none;stroke:url(#linearGradient27998-5);stroke-width:3.29999995;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="cc"
+ inkscape:connector-curvature="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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36407-9-8-3"
+ d="m 303.98998,117 0,8"
+ style="fill:none;stroke:#183c00;stroke-width:3.29999995;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="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient28000-5);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 300.14876,127.64921 3.79437,-2.66484"
+ id="path36420-1-8-8-6"
+ 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="path36412-3-7-3"
+ d="m 309.98997,129 -5.99999,-4"
+ style="fill:none;stroke:#5d0606;stroke-width:3.29999995;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="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4ee420;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 303.98999,117 0,8"
+ id="path36418-7-2-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"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36424-2-5-6-9"
+ d="m 299.72665,127.42074 3.7717,-2.67532 2e-5,-7.25"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient28002-1);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"
+ sodipodi:nodetypes="ccc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ef4e29;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 309.98997,129 -5.99998,-4"
+ id="path36428-6-8-8"
+ 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
+ ry="0"
+ rx="0"
+ y="116"
+ x="302.98999"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36432-1-2-2"
+ style="opacity:0.3;fill:none;stroke:#183c00;stroke-width:1.79999995;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
+ ry="0"
+ rx="0"
+ y="116"
+ x="302.99002"
+ height="2"
+ width="2"
+ id="rect36434-5-5-9"
+ style="fill:#4ee51f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient28004-7);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36436-4-6-0"
+ sodipodi:cx="70.5"
+ 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"
+ 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"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.6666679,0,0,0.6666668,256.9899,115.33333)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36438-7-62-3"
+ sodipodi:cx="70.5"
+ 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"
+ 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="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;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="rect36440-7-5-9"
+ width="2.0000153"
+ height="2.0000069"
+ x="308.98999"
+ y="128"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#eb512e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36442-2-0-6"
+ width="2"
+ height="2"
+ x="308.99002"
+ y="128"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36446-6-0-8"
+ d="m 303.5,117.51562 0,-1 1,0"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient28006-8);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36450-1-8-0"
+ d="m 309.47793,129.48277 0,-1 1,0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient28008-2);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ 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">
+ <rect
+ y="198.9792"
+ x="4.9506397"
+ height="16"
+ width="16"
+ id="rect23018-5-4-4"
+ 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.94058502,0,0,0.94058502,0.9128606,12.74924)"
+ id="g56716-9">
+ <path
+ sodipodi:type="star"
+ style="fill:url(#linearGradient14951-4);fill-opacity:1;stroke:#341b00;stroke-width:0.96882826;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path15855-2"
+ sodipodi:sides="5"
+ sodipodi:cx="13.700194"
+ sodipodi:cy="207.20645"
+ sodipodi:r1="7.1873641"
+ sodipodi:r2="3.3158474"
+ sodipodi:arg1="0.94697287"
+ sodipodi:arg2="1.5618338"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 17.898641,213.04008 -4.168729,-2.51791 -4.280439,2.47993 1.106473,-4.74277 -3.6812884,-3.3046 4.8525664,-0.41328 2.005278,-4.52229 1.892578,4.48735 4.920618,0.50967 -3.682889,3.18662 z"
+ inkscape:transform-center-x="-0.010954063"
+ inkscape:transform-center-y="-0.74285516"
+ transform="matrix(1.0972098,0,0,1.0975406,-2.0923019,-19.740595)" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.06316817;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 12.931855,202.51514 -1.201334,2.70994 c -0.137665,0.32193 -0.454082,0.55986 -0.800889,0.60222 l -2.9032248,0.26765 2.2358168,1.97391 c 0.261321,0.2395 0.380487,0.62447 0.300333,0.97022 l -0.667408,2.81032"
+ id="path15869-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(189,-229)"
+ id="g22900-8"
+ 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="rect22902-0"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904-5"
+ style="opacity:0.6;stroke:#162d50">
+ <path
+ style="opacity:0.9;fill:none;stroke:#2d3239;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906-2"
+ sodipodi:nodetypes="cc"
+ 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.9;fill:none;stroke:#2d3239;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908-5"
+ sodipodi:nodetypes="cc"
+ 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>
+ <path
+ style="opacity:0.9;fill:none;stroke:#e4e9f0;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22910-1"
+ sodipodi:nodetypes="cc"
+ 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="ccccccccccccc"
+ style="fill:url(#linearGradient22933-6);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935-6);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914-3"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916-2"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937-4);stroke-width:1;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918-7"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920-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
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922-0"
+ 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="path22924-2"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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"
+ sodipodi:nodetypes="cc"
+ id="path22926-3"
+ d="m 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#e4e9f0;stroke-width:1.29999995;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:none;stroke:url(#linearGradient22939-8);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931-5"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient17039);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(210,-229)"
+ id="g22900-8-5"
+ 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="rect22902-0-6"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904-5-2"
+ style="opacity:0.6;stroke:#162d50" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="fill:url(#linearGradient22933-6-8);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912-6-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935-6-2);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914-3-7"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916-2-2"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937-4-1);stroke-width:1;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918-7-7"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920-0-4"
+ 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
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922-0-2"
+ 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="path22924-2-7"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22939-8-6);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928-8-6"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931-5-7"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient17172);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-42,-40)"
+ id="g22900-8-3"
+ 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="rect22902-0-4"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904-5-8"
+ style="opacity:0.6;stroke:#162d50">
+ <path
+ style="opacity:0.9;fill:none;stroke:#333333;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906-2-2"
+ sodipodi:nodetypes="cc"
+ 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.9;fill:none;stroke:#333333;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908-5-8"
+ sodipodi:nodetypes="cc"
+ 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>
+ <path
+ style="opacity:0.9;fill:none;stroke:#eaeaea;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22910-1-6"
+ sodipodi:nodetypes="cc"
+ 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="ccccccccccccc"
+ style="opacity:0.8;fill:url(#linearGradient22933-6-87);fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912-6-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935-6-22);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914-3-3"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916-2-6"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937-4-8);stroke-width:1;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918-7-5"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920-0-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
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922-0-0"
+ 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="path22924-2-2"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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"
+ sodipodi:nodetypes="cc"
+ id="path22926-3-1"
+ d="m 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#eaeaea;stroke-width:1.29999995;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:none;stroke:url(#linearGradient22939-8-3);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928-8-5"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931-5-2"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient17172-9);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g17563">
+ <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"
+ width="16"
+ height="16"
+ x="215"
+ y="430" />
+ <g
+ id="g17546">
+ <path
+ style="opacity:0.6;fill:none;stroke:#643200;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 227.5,433.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908-5-0-4"
+ sodipodi:nodetypes="cc"
+ 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.6;fill:none;stroke:#633300;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 225.5,435.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906-2-9-6"
+ sodipodi:nodetypes="cc"
+ 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
+ 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="cc"
+ id="path22910-1-4"
+ d="m 225.5,435.5 c 1.5,1.5 1.5,3.5 0,5"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient17582);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22912-6-7"
+ d="m 222.58167,432.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ style="fill:url(#linearGradient17584);fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.84313725;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path22914-3-6"
+ d="m 216.5,440.5 1,0 1,-1 3.25,3"
+ style="fill:none;stroke:url(#linearGradient17586);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray: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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.65263157;fill:none;stroke:url(#linearGradient17588);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 218.5,435.5 0,4.9091"
+ id="path22916-2-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"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 216.5,436.5 1,0"
+ id="path22918-7-2" />
+ <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="path22920-0-2"
+ d="m 220.59506,434.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22922-0-22"
+ d="m 216.5,435.63598 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ 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="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 220.59506,435.5 1,-1"
+ id="path22924-2-9"
+ 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="opacity:0.9;fill:none;stroke:url(#linearGradient17590);stroke-width:1.29999995;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 227.5,433.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22926-3-9"
+ sodipodi:nodetypes="cc"
+ 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="path22928-8-7"
+ d="m 221.5,433.5 0,9"
+ style="fill:none;stroke:url(#linearGradient17592);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient17594);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 216.5,435.3 0,5.4"
+ id="path22931-5-72" />
+ <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="cc"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 225.37642,435.40307 0.60225,0.61872"
+ id="path22922-0-22-4"
+ 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"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 227.40936,433.37013 0.51386,0.59663"
+ id="path22922-0-22-2"
+ 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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g17941">
+ <rect
+ transform="scale(-1,1)"
+ y="220.00047"
+ x="-546"
+ height="16"
+ width="16"
+ id="rect14357-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="g17935">
+ <rect
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;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"
+ id="rect43394-5-7"
+ width="6"
+ height="2"
+ x="540.12811"
+ y="231.61429"
+ rx="0.79505396"
+ ry="0.79505396" />
+ <path
+ sodipodi:nodetypes="czszcccc"
+ id="path14368-1"
+ 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:7.40000034;display:inline"
+ d="m 542.6613,230.54031 -4.34213,0.008 c -5.18824,0.0101 -5.3353,-2.04831 -3.33529,-4.04831 0.96487,-0.96488 3.61611,-2.89515 -1.50001,-5 m 6.83689,6.08925 2.34054,2.95106 m -2.32899,2.96017 2.32899,-2.96017"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 542.6613,230.54031 -4.34213,0.008 c -5.18824,0.0106 -5.3353,-2.04783 -3.33529,-4.04783 0.96487,-0.96488 3.83708,-2.76256 -1.50001,-5 m 6.83689,6.08877 2.34054,2.95106 m -2.32899,2.96017 2.32899,-2.96017"
+ style="fill:none;stroke:url(#linearGradient17932);stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path14375-4"
+ sodipodi:nodetypes="czszcccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.79505396"
+ rx="0.79505396"
+ y="220.375"
+ x="530.3125"
+ height="2"
+ width="6"
+ id="rect43396-5-4"
+ style="fill:#6996d7;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;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" />
+ </g>
+ </g>
+ <g
+ id="g20086">
+ <rect
+ y="598"
+ x="299"
+ height="16"
+ width="16"
+ id="rect25569-8"
+ 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(1.1,-0.09992002)"
+ id="g20068">
+ <rect
+ y="605.5"
+ x="-312.5"
+ height="7.0000267"
+ width="10"
+ id="rect15044-4"
+ style="fill:url(#linearGradient20080);fill-opacity:1;fill-rule:nonzero;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: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="scale(-1,1)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path15046-4"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 304.49848,605.5625 0,-2 c 0,-2 -0.62933,-3 -2.51731,-3.00008 -1.2779,5e-5 -2.17039,0.23501 -2.53494,1.78073"
+ 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="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient20199);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 304.49848,605.5625 0,-2.25 c 0,-1.75 -0.62933,-2.75 -2.51734,-2.75008 -1.27677,5e-5 -2.05659,0.20629 -2.29807,1.20103"
+ id="path15049-9"
+ sodipodi:nodetypes="cscc"
+ 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
+ ry="0"
+ rx="0"
+ y="606.5"
+ x="303.5"
+ height="5"
+ width="8"
+ id="rect15051-2"
+ style="fill:none;stroke:url(#linearGradient20084);stroke-width:1.00000024;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="path19016-6"
+ d="m 304,607.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 304,609.5 7.5,0"
+ id="path19018-0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19020-2"
+ d="m 304,611.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36041-6"
+ width="1"
+ height="2.0000124"
+ x="307"
+ y="608" />
+ <rect
+ y="608"
+ x="307"
+ height="0.99994379"
+ width="0.99998754"
+ id="rect36043-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 308,608 0,2 -1,0 0,1 1,0 1,0 0,-1 0,-2 -1,0 z"
+ id="path36045-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(21,0)"
+ style="display:inline;enable-background:new"
+ id="g20086-7">
+ <rect
+ y="598"
+ x="299"
+ height="16"
+ width="16"
+ id="rect25569-8-3"
+ 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(1.1,-0.09992002)"
+ id="g20068-2">
+ <rect
+ y="605.5"
+ x="-312.5"
+ height="7.0000267"
+ width="10"
+ id="rect15044-4-1"
+ style="fill:url(#linearGradient20080-5);fill-opacity:1;fill-rule:nonzero;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: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="scale(-1,1)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path15046-4-9"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 310.5,605.5 0,-2 c 0,-2 -0.75,-3 -3,-3.00008 -2.25,8e-5 -3,1.00008 -3,3.00008 l 0,2"
+ 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"
+ style="fill:none;stroke:url(#linearGradient20082-4);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 310.5,605.5 c 0,0 0,-2.25 0,-2.25 0,-1.75 -0.75,-2.75 -3.00003,-2.75008 C 305.25,600.5 304.5,601.5 304.5,603.25 l 0,2.25005"
+ id="path15049-9-8"
+ sodipodi:nodetypes="csccc"
+ 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
+ ry="0"
+ rx="0"
+ y="606.5"
+ x="303.5"
+ height="5"
+ width="8"
+ id="rect15051-2-5"
+ style="fill:none;stroke:url(#linearGradient20084-9);stroke-width:1.00000024;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="path19016-6-0"
+ d="m 304,607.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 304,609.5 7.5,0"
+ id="path19018-0-2" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19020-2-9"
+ d="m 304,611.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36041-6-4"
+ width="1"
+ height="2.0000124"
+ x="307"
+ y="608" />
+ <rect
+ y="608"
+ x="307"
+ height="0.99994379"
+ width="0.99998754"
+ id="rect36043-2-8"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 308,608 0,2 -1,0 0,1 1,0 1,0 0,-1 0,-2 -1,0 z"
+ id="path36045-7-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-105.02687,272.93951)"
+ style="display:inline;enable-background:new"
+ id="g17107">
+ <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"
+ width="16"
+ height="16"
+ x="299"
+ y="325" />
+ <g
+ id="g17099">
+ <path
+ style="fill:url(#linearGradient16783-1-6-0-2);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="M 309.7702,332.24765 304.5,337.5 l -1,0 -1,1 -1,0 0,-1 1,-1 0,-1 5.2702,-5.25235 z"
+ id="path18700-1-3-9"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccc"
+ id="path17007-7"
+ d="M 309.7702,332.24765 304.5,337.5 l -1,0 -1,1 -1,0 0,-1 1,-1 0,-1 5.2702,-5.25235 z"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="ccszsccc"
+ id="path18711-5-8-1"
+ d="m 310.5,333.5 0,-2.75 c 1.1224,0 1.75,0 2.5,-0.75 0.75,-0.75 0.75,-2.25 0,-3 -0.75,-0.75 -2.25,-0.75 -3,0 -0.75,0.75 -0.75,1.49506 -0.75,2.5 l -2.75,0 4,4 z"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-x="-1.4435745"
+ inkscape:transform-center-y="-1.4192649"
+ style="fill:url(#linearGradient16778-3-5-3-2);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 309.22323,329.79745 c -0.11594,-0.12547 0.0486,-1.2642 0.81343,-2.11918 1.04731,-1.1688 1.89745,-0.8692 1.99021,-0.61778 1.02063,2.76644 -1.73024,3.89859 -2.80364,2.73696 z"
+ id="path18713-4-2-0"
+ sodipodi:nodetypes="csss"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path18715-9-8-1"
+ d="m 308.26612,330.5 c 0,0 0.25,0 0.25,0 l 0,-1"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient16775-4-9-5-6);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ 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;display:inline;enable-background:new"
+ d="m 303.25,335.75 4.17237,-4.0625"
+ id="path18705-8-4-0"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-42,231)"
+ style="display:inline;enable-background:new"
+ id="g17942-1">
+ <rect
+ y="304"
+ x="278"
+ height="16"
+ width="16"
+ id="rect22048-0-1-2"
+ style="opacity:0.01000001;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17930-6">
+ <rect
+ y="305.5"
+ x="281.5"
+ height="6.0211244"
+ width="9.0000076"
+ id="rect22050-0-1-6"
+ style="opacity:0.6;fill:#ffd6aa;fill-opacity:1;fill-rule:evenodd;stroke:#2b1600;stroke-width:0.40000001;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
+ sodipodi:nodetypes="ccccc"
+ id="path22056-3-7-1"
+ d="m 282.5,316.5 3,3 3,-3 -3,-3 -3,3 z"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="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"
+ d="m 282.75,316.5 2.75,2.75 2.75,-2.75 -2.75,-2.75 -2.75,2.75 z"
+ id="path22058-8-8-7"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22060-3-9-9"
+ d="m 283.5,316.5 2,-2 2,2 -2,2 -2,-2 z"
+ style="fill:none;stroke:url(#linearGradient18148);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path22157-2-9-1"
+ d="m 287.75,308.25 0,0.5 2.5,2.5 0.5,0 2.5,-2.5 0,-0.5 -2.5,-2.5 -0.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#552c00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e98316;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 288,308.5 2.5,2.5 2.5,-2.5 -2.5,-2.5 -2.5,2.5 z"
+ id="path22159-1-9-5"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22161-4-8-9"
+ d="M 288.64504,308.5 290.5,306.66161 292.35496,308.5 290.5,310.36049 z"
+ style="fill:none;stroke:url(#linearGradient17904-1);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 278.75,308.25 0,0.5 2.5,2.5 0.5,0 2.5,-2.5 0,-0.5 -2.5,-2.5 -0.5,0 -2.5,2.5 z"
+ id="path22208-0-8-1"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22212-5-4-4"
+ d="m 279,308.5 2.5,2.5 2.5,-2.5 -2.5,-2.5 z"
+ style="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"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient17893-5);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 279.64062,308.5 281.5,306.66406 283.35547,308.5 281.5,310.375 z"
+ id="path22214-3-8-8"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g16806">
+ <rect
+ y="472"
+ x="257"
+ height="16"
+ width="16"
+ id="rect35680"
+ 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:transform-center-y="2.2787562"
+ inkscape:transform-center-x="-0.78726"
+ id="g35844"
+ transform="translate(-186,256.02369)"
+ style="opacity:0.9;display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35846"
+ d="m 454.5,218.5 c -1.25,-1.5 -2.5,-1.5 -4,1 -1.5,-2.5 -2.75,-2.5 -4,-1"
+ style="opacity:0.85;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 454.5,218.5 c -1.25,-1.5 -2.5,-1.5 -4,1 -1.5,-2.5 -2.75,-2.5 -4,-1"
+ id="path35848"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path35862"
+ d="m 264.5,485.5 -1,-1 -2,2 -2,-2 -1,1.02369"
+ style="opacity:0.76499999;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 264.5,485.5 -1,-1 -2,2 -2,-2 -1,1.02369"
+ id="path35864"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-21,21)"
+ id="g38276">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.85;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 292.5,459.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ id="path35702"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35704"
+ d="m 292.5,459.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ style="fill:none;stroke:#ececec;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ d="m 266.53125,480.65625 -0.0312,0.9375 m -0.85937,-1.07813 c 0.49634,0.0684 0.8328,0.24341 1.79687,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path16745" />
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ d="m 264.46875,474.79687 -0.0312,0.9375 m -0.85937,-1.07813 c 0.49634,0.0684 0.8328,0.24341 1.79687,0"
+ style="fill:none;stroke:#f0f0f0;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ 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">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path45378-1-5-0"
+ d="m 367.75,440.75 1.75,-1.5 2.5,5.25 1.75,-1 -2.25,-5 2.5,0 -6.25,-6.25 z"
+ style="fill:url(#linearGradient17833-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="430"
+ x="362"
+ height="16"
+ width="16"
+ id="rect45374-0-5-0"
+ 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" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ id="path17835-6"
+ d="m 367.5,431.5 7,7.25 -3,0 2.5,4.75 -1.75,1 -2.5,-5 -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" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path17845-4"
+ d="m 368.34375,433.75 0,5.75"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ transform="translate(84,0)"
+ style="display:inline;enable-background:new"
+ id="g17847-9">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path45378-1-5-6"
+ d="m 367.75,440.75 1.75,-1.5 2.5,5.25 1.75,-1 -2.25,-5 2.5,0 -6.25,-6.25 z"
+ style="fill:url(#linearGradient17833-8);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="430"
+ x="362"
+ height="16"
+ width="16"
+ id="rect45374-0-5-6"
+ 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" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ id="path17835-7"
+ d="m 367.5,431.5 7,7.25 -3,0 2.5,4.75 -1.75,1 -2.5,-5 -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" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path17845-9"
+ d="m 368.34375,433.75 0,5.75"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10534-1"
+ transform="translate(189.0161,-397)">
+ <rect
+ y="428"
+ x="193.9839"
+ height="16"
+ width="16"
+ id="rect20642-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
+ transform="translate(-29.016109,339.00751)"
+ id="g20606-2">
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10953-7">
+ <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="cccccccccccccccccccccccccccccccccccccc"
+ style="fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.25,-1.53125 -1,-1 -1.53125,1.25 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ id="path10955-5"
+ 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"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ id="path10957-4"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.5,-1.78125 -1,-1 -1.78125,1.5 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ style="fill:url(#linearGradient20796-9);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 434.9998,198.49249 -1.5,1.25 m -2,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.01806,0.29269 -1.5172,0.50569 m -1.49,1.50752 c -0.20864,0.49552 -0.41426,1.14284 -0.4928,1.48679 l -1.5,0 0,1 m 1.5,-5 -0.5,0.5 m 1.25,6.5 -1.25,1.5 m 6.5,-5.5 0,3.5 -3.5,0 m -3,-6 0.5,-0.5 1.5,1.25"
+ style="fill:none;stroke:#f9f9f9;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ id="path10959-0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10961-1">
+ <rect
+ ry="0"
+ rx="0"
+ y="202.46629"
+ x="430.49979"
+ height="8.1236582"
+ width="7.0000763"
+ id="rect10963-2"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;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" />
+ <path
+ d="m 432.53795,204.5065 2.96201,0 m -2.96201,1.993 2.96201,0 m -2.96201,1.993 2.96201,0"
+ style="fill:none;stroke:#000000;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path10965-7"
+ 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" />
+ <rect
+ ry="0"
+ rx="0"
+ y="202.48912"
+ x="430.49661"
+ height="8.0067444"
+ width="7.0067482"
+ id="rect10967-1"
+ style="fill:none;stroke:url(#linearGradient20798-1);stroke-width:0.99325603;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\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </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">
+ <rect
+ y="325"
+ x="299"
+ height="16"
+ width="16.000002"
+ id="rect44300-0-5-3-4"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g81149-2">
+ <path
+ sodipodi:nodetypes="cssssssssssssssscssc"
+ inkscape:connector-curvature="0"
+ id="path41299-1-2-7-4-0"
+ d="m 306.46211,325.45009 c -1.82601,0 -3.30699,1.48105 -3.30699,3.30711 0,0.25952 0.0379,0.51035 0.087,0.75425 0.18833,0.93505 0.24637,1.73179 -0.11603,2.43677 -0.32404,0.63034 -0.67881,0.97731 -1.45039,1.27638 -1.27734,0.49511 -2.17564,1.6304 -2.17564,3.04602 0,0.7411 0.24647,1.42826 0.6672,1.97265 0.21236,0.27479 0.1962,0.24789 0.29008,0.34806 0.60044,0.64074 1.56724,0.98341 2.29168,0.95729 0.74932,-0.027 1.28404,-0.28854 1.8855,-0.60911 0.58287,-0.31066 0.97831,-0.70633 1.82755,-0.69624 0.70498,0.008 1.33214,0.39548 1.88546,0.75426 0.55206,0.35795 1.29426,0.55886 1.8275,0.55114 1.8258,-0.0264 3.30697,-1.48104 3.30697,-3.30711 0,-1.23932 -0.68675,-2.33495 -1.71151,-2.87196 -0.78932,-0.41364 -1.71989,-0.83441 -2.11757,-1.47945 -0.44817,-0.72695 0.029,-2.46582 0.029,-2.46582 0.0441,-0.21523 0.087,-0.43896 0.087,-0.66722 0,-1.82606 -1.48098,-3.30711 -3.30698,-3.30711 z"
+ style="fill:url(#linearGradient80406-8);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.89999998;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cscsscc"
+ inkscape:connector-curvature="0"
+ id="path15475-1-1-9"
+ d="m 306.46211,326.3494 c -1.34707,0 -2.40772,1.06069 -2.40772,2.4078 0,0.17324 0.0147,0.36498 0.058,0.5802 0.2006,0.99599 0.30102,2.03645 -0.20306,3.017 -0.3838,0.74661 -1.01301,1.33313 -1.91455,1.68257 -0.98238,0.38077 -1.59548,1.19286 -1.59548,2.23374 0.0793,1.22982 0.59501,1.65939 1.12899,2.05552"
+ style="fill:none;stroke:url(#linearGradient80403-6);stroke-width:0.99999988;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 306.5,333.5 -4,3 m 4,-3 4,3 m -4,-8 0,5"
+ style="fill:none;stroke:#acc1f5;stroke-width:2.29999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path16558"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path15730-0-3-9-7"
+ style="fill:none;stroke:#474747;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 306.5,333.5 -4,3 m 4,-3 4,3 m -4,-8 0,5" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-8-3"
+ width="2.0172396"
+ height="2.0000157"
+ x="305.48901"
+ y="327.52499" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-82-7"
+ width="2.0172396"
+ height="2.0000157"
+ x="301.52026"
+ y="335.49374" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-9-2"
+ width="2.0172396"
+ height="2.0000157"
+ x="309.49374"
+ y="335.49374" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-1-6"
+ width="2.0172396"
+ height="2.0000157"
+ x="305.52499"
+ 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
+ style="display:inline;enable-background:new"
+ id="g16724-8-3">
+ <rect
+ y="598"
+ x="152"
+ height="16"
+ width="16"
+ id="rect38813-3-2"
+ 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" />
+ <g
+ transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,76.587007,362.72598)"
+ id="g10876-8-5-8-64-4"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient16663-3-0-8);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 226.05286,111.6246 3.53553,0 1e-5,-3.53553 2.82843,0 0,3.53553 3.53553,0 -1e-5,2.82843 -3.53553,0 0,3.53553 -2.82843,0 0,-3.53553 -3.53553,0 z"
+ id="path10878-4-0-1-4-6"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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="cc"
+ inkscape:connector-curvature="0"
+ id="path16661-5-1-6"
+ d="m 235.06847,113.56915 0,-1.06066"
+ style="fill:none;stroke:#d4d4d4;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16659-5-9-6"
+ d="m 230.47227,114.62981 0,2.47487"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16657-8-5-2"
+ d="m 230.47227,108.97295 0,2.47488"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path10880-7-5-7-5-9"
+ d="m 226.93674,112.50849 0,1.06066"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <g
+ transform="translate(252,21)"
+ style="display:inline;enable-background:new"
+ id="g16724-8-1">
+ <rect
+ y="598"
+ x="152"
+ height="16"
+ width="16"
+ id="rect38813-3-1"
+ 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" />
+ <g
+ transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,76.587007,362.72598)"
+ id="g10876-8-5-8-64-9"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient16663-3-0-0);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 224.63864,111.6246 4.94975,0 0,-4.94974 2.82843,0 1e-5,4.94974 4.94973,0 -1e-5,2.82843 -4.94973,0 0,4.94975 -2.82843,0 0,-4.94975 -4.94975,0 z"
+ id="path10878-4-0-1-4-9"
+ sodipodi:nodetypes="ccccccccccccc"
+ 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="cc"
+ inkscape:connector-curvature="0"
+ id="path16661-5-1-5"
+ d="m 236.48268,113.56915 0,-1.06066"
+ style="fill:none;stroke:#d4d4d4;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16659-5-9-5"
+ d="m 230.47227,114.62981 0,3.88908"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16657-8-5-5"
+ d="m 230.47227,107.55874 0,3.88909"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path10880-7-5-7-5-6"
+ d="m 225.52253,112.50849 0,1.06066"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <g
+ id="g27438">
+ <g
+ transform="translate(0,-21)"
+ id="g23604">
+ <g
+ style="fill:#321900"
+ id="g23590">
+ <rect
+ transform="scale(-1,-1)"
+ y="-602"
+ x="-258"
+ height="2"
+ width="1"
+ id="rect23464"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23466"
+ width="1"
+ height="2"
+ x="-258"
+ y="-606" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23548"
+ width="1"
+ height="2"
+ x="-273"
+ y="-602"
+ transform="scale(-1,-1)" />
+ <rect
+ y="-606"
+ x="-273"
+ height="2"
+ width="1"
+ id="rect23550"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,-1)" />
+ <rect
+ y="-268"
+ x="598"
+ height="2"
+ width="1"
+ id="rect23472"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;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
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23474"
+ width="1"
+ height="2"
+ x="598"
+ y="-264" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23476"
+ width="1"
+ height="2"
+ x="598"
+ y="-271.99207" />
+ <rect
+ y="-259.99207"
+ x="598"
+ height="2"
+ width="1"
+ id="rect23480"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;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
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23540"
+ width="1"
+ height="2"
+ x="607"
+ y="-268" />
+ <rect
+ y="-264"
+ x="607"
+ height="2"
+ width="1"
+ id="rect23542"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;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="-271.99207"
+ x="607"
+ height="2"
+ width="1"
+ id="rect23544"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;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
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23546"
+ width="1"
+ height="2"
+ x="607"
+ y="-259.99207" />
+ </g>
+ <g
+ id="g23572">
+ <rect
+ transform="matrix(0,-1,-1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23461"
+ width="1"
+ height="2"
+ x="-608"
+ y="-270" />
+ <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="rect23468"
+ width="1"
+ height="2"
+ x="-273"
+ y="-600" />
+ <rect
+ transform="scale(-1,-1)"
+ y="-604"
+ x="-273"
+ height="2"
+ width="1"
+ id="rect23470"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="-266"
+ x="-608"
+ height="2"
+ width="1"
+ id="rect23478"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ 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"
+ id="rect23482"
+ width="1"
+ height="2"
+ x="-608"
+ y="-262" />
+ <rect
+ y="-262"
+ x="598"
+ height="2"
+ width="1"
+ id="rect23529"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ 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"
+ id="rect23531"
+ width="1"
+ height="2"
+ x="598"
+ y="-266" />
+ <rect
+ y="-270"
+ x="598"
+ height="2"
+ width="1"
+ id="rect23533"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <rect
+ y="-273"
+ x="-608"
+ height="1"
+ width="2"
+ id="rect23535"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <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="rect23525"
+ width="1"
+ height="2"
+ x="-258"
+ y="-600"
+ transform="scale(-1,-1)" />
+ <rect
+ y="-604"
+ x="-258"
+ height="2"
+ width="1"
+ id="rect23527"
+ 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
+ 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="rect23537"
+ width="1"
+ height="2"
+ x="-258"
+ y="-608" />
+ </g>
+ <rect
+ y="599"
+ x="258"
+ height="8"
+ width="14"
+ id="rect23637"
+ 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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="opacity:0.12999998;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 259,600 13,0 0,-1 -14,0 0,8 1,0 0,-7 z"
+ id="path23639" />
+ <g
+ transform="translate(40,359)"
+ id="g23641"
+ style="display:inline;enable-background:new">
+ <g
+ id="g23646"
+ style="fill:#1a1a1a;display:inline;enable-background:new"
+ transform="translate(5,-6.0000002e-7)" />
+ </g>
+ </g>
+ <g
+ transform="translate(0.1767767,0.13258252)"
+ id="g106636">
+ <path
+ style="fill:url(#linearGradient106641);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 263.5625,590.375 1.75,-1.5 1.99177,3.7253 1.75,-1 -1.74177,-3.4753 2.5,0 -6.25,-6.25 z"
+ id="path45378-1-5-6-2-9"
+ 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 263.3125,581.125 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-5"
+ 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 264.15625,583.375 0,5.75"
+ id="path17845-9-1-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ transform="translate(0.02855492,0)"
+ style="display:inline;enable-background:new"
+ id="g15868-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"
+ id="rect18695-6-9-6"
+ width="15.971445"
+ height="16.000002"
+ x="110"
+ y="241" />
+ <g
+ id="g15853-0">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path15095-5"
+ d="m 117.9106,247.99675 0.007,7.98875 -5.98631,-3.26708 -0.0121,-7.34356 z"
+ style="opacity:0.63859648;fill:url(#radialGradient15836-5);fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path18719-6-9-0"
+ d="m 117.94049,242.95683 -5.85545,2.34692 6.10637,2.4934 -0.17358,8.22275 6.00064,-3.2989 0.0442,-7.36753 z"
+ style="fill:url(#linearGradient15851-6);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-4-7-7"
+ transform="matrix(1.2133883,0,0,1.2133883,-65.271004,156.45833)">
+ <path
+ id="path18707-3-8-5"
+ d="m 146.0019,73.295281 5,-2.007976 5,2.007976 -5,2.073959 z"
+ style="fill:url(#linearGradient15818-5);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-2-5-8"
+ d="m 124.01757,245.38766 -6.11113,2.33515 0.39771,8.10095 5.71891,-3.11585 z"
+ style="fill:url(#linearGradient15846-4);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path18709-1-1-0"
+ d="m 114.36329,244.98044 3.58667,-1.46751 5.56035,2.22692 0.0356,6.65202 -4.34973,2.45342"
+ style="fill:none;stroke:url(#linearGradient15843-2);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g18737-4-8-8"
+ style="opacity:0.7"
+ transform="matrix(1.2133883,0,0,1.2133883,-282.46751,373.65484)" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path15957-6"
+ d="m 118.29703,256.35166 5.94799,-3.23942 c 0.0419,-0.0185 0.0806,-0.0443 0.11369,-0.0758 0.0689,-0.0703 0.11042,-0.16699 0.1137,-0.26543 l -0.0379,-7.432 c 10e-4,-0.16462 -0.1103,-0.32426 -0.26543,-0.37919 l -6.06694,-2.42677 c -0.0474,-0.0224 -0.0992,-0.0354 -0.15167,-0.0379 l 1.2e-4,0 c -0.0524,0.002 -0.10423,0.0154 -0.15167,0.0379 l -5.53168,2.30782"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.4429636"
+ inkscape:original="M 111.90625 245.375 L 111.9375 252.71875 L 117.90625 256 L 117.90625 248 L 111.90625 245.375 z "
+ style="fill:none;stroke:url(#linearGradient16730);stroke-width:0.89999998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path16571-2"
+ d="m 111.78125,244.9375 a 0.4430079,0.4430079 0 0 0 -0.3125,0.4375 l 0.0312,7.34375 a 0.4430079,0.4430079 0 0 0 0.21875,0.375 l 5.96875,3.28125 A 0.4430079,0.4430079 0 0 0 118.34375,256 l 0,-8 a 0.4430079,0.4430079 0 0 0 -0.25,-0.40625 l -6,-2.625 a 0.4430079,0.4430079 0 0 0 -0.3125,-0.0312 z" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient16562-7);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.31869,255.08504 -4.89325,-2.67466 -0.0154,-6.1798"
+ id="path16560-5"
+ sodipodi:nodetypes="ccc" />
+ <path
+ style="opacity:0.75333408;fill:none;stroke:url(#linearGradient15773-7);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.38888891"
+ d="m 112.44393,252.43208 3.76322,-1.57568"
+ id="path15671-3"
+ inkscape:connector-curvature="0"
+ 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">
+ <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"
+ width="16"
+ height="16"
+ x="131"
+ y="556" />
+ <g
+ transform="translate(104,40.00013)"
+ id="g39545">
+ <g
+ transform="translate(-116,424.99975)"
+ style="opacity:0.75"
+ id="g39547">
+ <g
+ id="g39549"
+ transform="translate(-179,199.50012)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000167;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 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.25,-2 0,-6.75 -4.25,-1.75 z"
+ id="path39551"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g39553"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39556"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 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"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path39558"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#cccccc;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="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39560"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient27496);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39562"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#ffffff;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="path39564"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient27498);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect39567"
+ style="opacity:0.35;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39569"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <rect
+ style="fill:none;stroke:#8c4800;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="rect39571"
+ width="2.9999485"
+ height="3.0001416"
+ x="27.500006"
+ y="517.49976"
+ ry="0"
+ rx="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="524.49951"
+ x="27.500006"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect39574"
+ style="fill:none;stroke:#8c4800;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
+ y="517.99988"
+ x="28.021444"
+ height="4"
+ width="3.9785564"
+ id="rect37868-0-5"
+ 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" />
+ <path
+ style="fill:none;stroke:#5a2f00;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"
+ d="m 28.000006,520.49983 -0.5,0 0,-3.00014 2.99995,0"
+ id="path39576"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path39583"
+ d="m 28.000006,524.49978 -0.5,0 0,3.00014 2.99995,0"
+ style="fill:none;stroke:#5a2f00;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"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="517.99988"
+ x="28.000051"
+ height="2.0000772"
+ width="1.9999485"
+ id="rect39585"
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="524.99988"
+ x="28"
+ height="1.999992"
+ width="3.9785564"
+ id="rect37868-0-1"
+ 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" />
+ <rect
+ rx="0"
+ ry="0"
+ y="524.99982"
+ x="28.000051"
+ height="2.0000772"
+ width="1.9999485"
+ id="rect39587"
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(-122.79197,-20.867417)"
+ id="g106636-9"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient106641-3);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 263.5625,590.375 1.75,-1.5 1.99177,3.7253 1.75,-1 -1.74177,-3.4753 2.5,0 -6.25,-6.25 z"
+ id="path45378-1-5-6-2-9-3"
+ 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 263.3125,581.125 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-5-1"
+ 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 264.15625,583.375 0,5.75"
+ id="path17845-9-1-1-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g52905"
+ transform="translate(398.95001,-42)">
+ <rect
+ y="367"
+ x="-372.95001"
+ height="16"
+ width="16"
+ id="rect52907"
+ 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" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52910"
+ d="m -368.95,374 5,-5"
+ style="fill:none;stroke:#000000;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask52637-8-8)"
+ id="g52912"
+ transform="translate(-18.95,-84)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m -352.5,465.5 2,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ style="color:#000000;fill:none;stroke:#3c0800;stroke-width:2.70000005;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="path52914"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52916"
+ style="color:#000000;fill:none;stroke:#ed7432;stroke-width:1.5;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 -353.25,465.5 2.75,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccc"
+ d="m -353.25,465.5 2.75,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ style="color:#000000;fill:none;stroke:url(#linearGradient52998-5-5);stroke-width:1.5;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="path52918"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ ry="1.5"
+ rx="1.5"
+ style="fill:none;stroke:#000000;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52920"
+ width="3"
+ height="3"
+ x="-371.45001"
+ y="-376.5"
+ transform="scale(1,-1)" />
+ <g
+ transform="matrix(-1,0,0,1,-711.95,-84)"
+ id="g52922"
+ mask="url(#mask52879-0-5)">
+ <path
+ id="path52924"
+ style="color:#000000;fill:none;stroke:#0b1728;stroke-width:2.70000005;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 -353.5,465.5 3,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m -354.2,465.5 3.7,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ style="color:#000000;fill:none;stroke:#7be10f;stroke-width:1.5;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="path52926"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52928"
+ style="color:#000000;fill:none;stroke:url(#linearGradient53000-3-9);stroke-width:1.5;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 -354.2,465.5 3.75,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ sodipodi:nodetypes="ccccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="scale(1,-1)"
+ y="-376.5"
+ x="-361.45001"
+ height="3"
+ width="3"
+ id="rect52930"
+ style="fill:none;stroke:#000000;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5"
+ ry="1.5" />
+ <path
+ style="fill:none;stroke:#b3b3b3;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -367.7,372.75 3.75,-3.75"
+ id="path52932"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="scale(1,-1)"
+ y="-376.5"
+ x="-371.45001"
+ height="3"
+ width="3"
+ id="rect52934"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5"
+ ry="1.5" />
+ <rect
+ ry="1.5"
+ rx="1.5"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52936"
+ width="3"
+ height="3"
+ x="-361.45001"
+ y="-376.5"
+ transform="scale(1,-1)" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52938"
+ d="m -368.45,372.5 4,-4 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="1.5"
+ rx="1.5"
+ style="fill:none;stroke:url(#linearGradient53002-6-2);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52940"
+ width="3"
+ height="3"
+ x="-371.45001"
+ y="-376.5"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-376.5"
+ x="-361.45001"
+ height="3"
+ width="3"
+ id="rect52942"
+ style="fill:none;stroke:url(#linearGradient58927);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5"
+ ry="1.5" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(252,-210)"
+ id="g52978">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:1.29999995;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 -198,536 -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 -204,542 l 0,1 0,1 1.90625,0.15625 c 0.14227,0.6231 0.25145,1.07677 0.59375,1.59375 l -1.75,1.75 1.75,1.75 1.75,-1.75 c 0.51699,0.34229 0.97065,0.45148 1.59375,0.59375 L -198,550 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 -190,544 l 0,-1 0,-1 -1.90625,-0.15625 c -0.14227,-0.6231 -0.25145,-1.07677 -0.59375,-1.59375 l 1.75,-1.75 -1.75,-1.75 -1.75,1.75 c -0.51699,-0.34229 -0.97065,-0.45148 -1.59375,-0.59375 L -196,536 l -1,0 -1,0 z m 1,4.125 c 1.58782,0 2.875,1.28718 2.875,2.875 0,1.58782 -1.28718,2.875 -2.875,2.875 -1.58782,0 -2.875,-1.28718 -2.875,-2.875 0,-1.58782 1.28718,-2.875 2.875,-2.875 z"
+ id="path52980"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52982"
+ d="m -196,550 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 -190,544 l 0,-1 0,-1 -1.90625,-0.15625 c -0.14227,-0.6231 -0.25145,-1.07677 -0.59375,-1.59375 l 1.5,-1.75 -1.5,-1.5 -1.75,1.5 c -0.51699,-0.34229 -0.97065,-0.45148 -1.59375,-0.59375 L -196,536 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.5 -1.5,1.5 1.5,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L -204,542 l 0,1 0,1 1.90625,0.15625 c 0.14227,0.6231 0.25145,1.07677 0.59375,1.59375 l -1.5,1.75 1.5,1.5 1.75,-1.5 c 0.51699,0.34229 0.97065,0.45148 1.59375,0.59375 L -198,550 l 1,0 1,0 z m -1,-4 c -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 0,1.65685 -1.34315,3 -3,3 z"
+ style="color:#000000;fill:url(#linearGradient32854-6-2);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="535"
+ x="-205"
+ height="16"
+ width="16"
+ id="rect52984"
+ 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
+ ry="6.4999995"
+ rx="6.4999995"
+ y="539.5"
+ x="-200.5"
+ height="6.981843"
+ width="6.981843"
+ id="rect52986"
+ style="fill:none;stroke:url(#linearGradient32856-3-2);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"
+ 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 -192.5,537.5 -1.25,1.25 m -2.75,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.50086,0.537 -2,0.75 m -1.75,1.75 c -0.20864,0.49552 -0.67146,1.65605 -0.75,2 l -1.5,0 0,1 m 1.75,-5.75 -0.5,0.5 m 1,8 -1.25,1.25"
+ id="path52988"
+ sodipodi:nodetypes="cccccscccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52990"
+ d="m -202.5,538.75 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" />
+ <rect
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient32858-7-2);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"
+ id="rect52992"
+ width="6.981843"
+ height="6.981843"
+ x="193.51816"
+ y="-546.48187"
+ rx="6.4999995"
+ ry="6.4999995"
+ transform="scale(-1,-1)" />
+ <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="opacity:0.35;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 -197.5,548.25 0,1.25 m 7,-7 -1.25,0"
+ id="path52994"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52996"
+ d="m -191.75,547.25 -1,1"
+ style="opacity:0.3;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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g32860"
+ transform="translate(231,-294)">
+ <rect
+ style="opacity:0;color:#000000;fill:#ffff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32862"
+ width="16"
+ height="16"
+ x="-226"
+ y="619" />
+ <path
+ sodipodi:nodetypes="cccsssscccc"
+ style="opacity:0.5;fill:url(#linearGradient32896-0-4);fill-opacity:1;stroke:none"
+ d="m -212.5,619.5 -2,0 -6.0625,6.0625 C -220.70928,625.548 -220.84942,625.5 -221,625.5 c -2.48528,0 -4.5,2.01473 -4.5,4.5 0,2.48527 2.01472,4.5 4.5,4.5 2.48528,0 4.5,-2.01473 4.5,-4.5 0,-0.14948 -0.017,-0.29176 -0.0312,-0.4375 l 6.0312,-6.0625 0,-2 -2,-2 z"
+ id="path32864"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -177.09897,651.49231 c 0,1.37646 -1.09713,2.49231 -2.45051,2.49231 -1.35339,0 -2.45052,-1.11585 -2.45052,-2.49231 0,-1.37646 1.09713,-2.49231 2.45052,-2.49231 1.35338,0 2.45051,1.11585 2.45051,2.49231 z"
+ sodipodi:ry="2.4923096"
+ sodipodi:rx="2.4505157"
+ sodipodi:cy="651.49231"
+ sodipodi:cx="-179.54948"
+ id="path32866"
+ style="color:#000000;fill:url(#linearGradient32899-8-3);fill-opacity:1;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.224232,0,0,1.2036922,-1.189782,-154.19619)" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path32868"
+ d="m -219.5,626.5 5.5,-5.5 0.5,-0.5 0.5,0.5 0.5,0.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-21,0)"
+ d="M -193.09375,620.46875 -198.875,626.25 a 0.95626367,0.95626367 0 0 1 -0.78125,0.25 c -0.29297,-0.0289 -0.39637,-0.0312 -0.34375,-0.0312 -1.96853,0 -3.53125,1.56273 -3.53125,3.53125 0,1.96852 1.56272,3.53125 3.53125,3.53125 1.96853,0 3.53125,-1.56273 3.53125,-3.53125 0,-0.0768 0.0155,-0.18427 0,-0.34375 a 0.95626367,0.95626367 0 0 1 0.25,-0.78125 l 5.75,-5.78125 0,-1.1875 -1.4375,-1.4375 -1.1875,0 z"
+ id="path32870"
+ style="fill:none;stroke:url(#radialGradient32901-4-9);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:original="M -193.5 619.5 L -199.5625 625.5625 C -199.70928 625.548 -199.84942 625.5 -200 625.5 C -202.48528 625.5 -204.5 627.51473 -204.5 630 C -204.5 632.48527 -202.48528 634.5 -200 634.5 C -197.51472 634.5 -195.5 632.48527 -195.5 630 C -195.5 629.85052 -195.51705 629.70824 -195.53125 629.5625 L -189.5 623.5 L -189.5 621.5 L -191.5 619.5 L -193.5 619.5 z "
+ inkscape:radius="-0.95616806"
+ sodipodi:type="inkscape:offset" />
+ <path
+ id="path32872"
+ d="m -217,624 0,1 -1,0 0,0.0312 -0.0312,0 0,0.96875 -0.96875,0 0,0.0312 -0.0312,0 0,1 -1,0 0,1 0,1 1,0 1,0 0,-1 1,0 0,-0.0312 0.0312,0 0,-0.96875 0.96875,0 0,-0.0312 0.0312,0 0,-1 1,0 0,-1 -1,0 0,-1 -1,0 z"
+ style="color:#000000;fill:url(#linearGradient32903-6-4);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2638889,0,0,1.2222222,32.853009,-140.1836)"
+ d="m -201.22313,628.93835 c 0,0.44702 -0.36237,0.80939 -0.80939,0.80939 -0.44701,0 -0.80939,-0.36237 -0.80939,-0.80939 0,-0.44701 0.36238,-0.80938 0.80939,-0.80938 0.44702,0 0.80939,0.36237 0.80939,0.80938 z"
+ sodipodi:ry="0.80938911"
+ sodipodi:rx="0.80938911"
+ sodipodi:cy="628.93835"
+ sodipodi:cx="-202.03252"
+ id="path32874"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32877"
+ sodipodi:cx="-202.03252"
+ sodipodi:cy="628.93835"
+ sodipodi:rx="0.80938911"
+ sodipodi:ry="0.80938911"
+ d="m -201.22313,628.93835 c 0,0.44702 -0.36237,0.80939 -0.80939,0.80939 -0.44701,0 -0.80939,-0.36237 -0.80939,-0.80939 0,-0.44701 0.36238,-0.80938 0.80939,-0.80938 0.44702,0 0.80939,0.36237 0.80939,0.80938 z"
+ transform="matrix(0.77047663,0,0,0.74507628,-63.8586,161.95861)" />
+ <path
+ transform="matrix(0.77047663,0,0,0.74507628,-64.708233,162.88548)"
+ d="m -201.22313,628.93835 c 0,0.44702 -0.36237,0.80939 -0.80939,0.80939 -0.44701,0 -0.80939,-0.36237 -0.80939,-0.80939 0,-0.44701 0.36238,-0.80938 0.80939,-0.80938 0.44702,0 0.80939,0.36237 0.80939,0.80938 z"
+ sodipodi:ry="0.80938911"
+ sodipodi:rx="0.80938911"
+ sodipodi:cy="628.93835"
+ sodipodi:cx="-202.03252"
+ id="path32879"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -213.5,621.5 -6,6"
+ id="path32881"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path32883"
+ d="m -212.5,619.5 -2,0 -6.0625,6.0625 C -220.70928,625.548 -220.84942,625.5 -221,625.5 c -2.48528,0 -4.5,2.01473 -4.5,4.5 0,2.48527 2.01472,4.5 4.5,4.5 2.48528,0 4.5,-2.01473 4.5,-4.5 0,-0.14948 -0.017,-0.29176 -0.0312,-0.4375 l 6.0312,-6.0625 0,-2 -2,-2 z"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccsssscccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-21,0)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.95616806"
+ inkscape:original="M -193.5 619.5 L -199.5625 625.5625 C -199.70928 625.548 -199.84942 625.5 -200 625.5 C -202.48528 625.5 -204.5 627.51473 -204.5 630 C -204.5 632.48527 -202.48528 634.5 -200 634.5 C -197.51472 634.5 -195.5 632.48527 -195.5 630 C -195.5 629.85052 -195.51705 629.70824 -195.53125 629.5625 L -189.5 623.5 L -189.5 621.5 L -191.5 619.5 L -193.5 619.5 z "
+ style="fill:none;stroke:url(#radialGradient32905-9-5);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32886"
+ d="M -193.09375,620.46875 -198.875,626.25 a 0.95626367,0.95626367 0 0 1 -0.78125,0.25 c -0.29297,-0.0289 -0.39637,-0.0312 -0.34375,-0.0312 -1.96853,0 -3.53125,1.56273 -3.53125,3.53125 0,1.96852 1.56272,3.53125 3.53125,3.53125 1.96853,0 3.53125,-1.56273 3.53125,-3.53125 0,-0.0768 0.0155,-0.18427 0,-0.34375 a 0.95626367,0.95626367 0 0 1 0.25,-0.78125 l 5.75,-5.78125 0,-1.1875 -1.4375,-1.4375 -1.1875,0 z" />
+ <g
+ style="opacity:0.3;fill:#ffffff"
+ id="g32888">
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32890"
+ width="1"
+ height="0.98873287"
+ x="-217"
+ y="622.98871" />
+ <rect
+ y="624"
+ x="-216"
+ height="0.98873287"
+ width="1"
+ id="rect32892"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32894"
+ width="1"
+ height="0.98873287"
+ x="-215"
+ 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"
+ transform="translate(72,509.96991)">
+ <rect
+ y="148"
+ x="-46"
+ height="16"
+ width="16"
+ id="rect45977-0"
+ style="opacity:0;fill:#666666;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ id="path43354-7"
+ d="m -42,-162.5 c -1.383118,0 -2.5,2.0178 -2.5,4.5 0,2.4822 1.116881,4.5 2.5,4.5 l 9.5,-2 c 1.25,-0.25 1.25,-4.75 0,-5 -3.164485,-0.63789 -6.364604,-1.31719 -9.5,-2 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path43211-1"
+ d="m -42.46462,-153.21991 0,4"
+ style="fill:none;stroke:#000000;stroke-width:2.0999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -42,-163.5 c -1.175382,0 -2.068672,0.84122 -2.625,1.84375 -0.556328,1.00253 -0.875,2.26593 -0.875,3.65625 0,1.39032 0.318672,2.65372 0.875,3.65625 0.556328,1.00253 1.449618,1.84375 2.625,1.84375 a 0.9950207,0.9950207 0 0 0 0.21875,-0.0312 l 9.46875,-2 c 0.01655,-0.003 0.01506,-0.0275 0.03125,-0.0312 0.840076,-0.19179 1.234143,-0.86885 1.4375,-1.46875 0.207276,-0.61147 0.28125,-1.28773 0.28125,-1.96875 0,-0.68102 -0.07397,-1.35728 -0.28125,-1.96875 -0.207276,-0.61147 -0.593404,-1.32493 -1.46875,-1.5 -3.157727,-0.63653 -6.336828,-1.31795 -9.46875,-2 A 0.9950207,0.9950207 0 0 0 -42,-163.5 z"
+ id="path43480-7"
+ style="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"
+ inkscape:original="M -42 -162.5 C -43.383118 -162.5 -44.5 -160.4822 -44.5 -158 C -44.5 -155.5178 -43.383119 -153.5 -42 -153.5 L -32.5 -155.5 C -31.25 -155.75 -31.25 -160.25 -32.5 -160.5 C -35.664485 -161.13789 -38.864604 -161.81719 -42 -162.5 z "
+ inkscape:radius="0.99492121"
+ sodipodi:type="inkscape:offset" />
+ <g
+ id="g43531-7"
+ style="fill:#bc2b00;stroke:none">
+ <g
+ id="g43521-7"
+ style="fill:#bc2b00;stroke:none">
+ <path
+ style="fill:#bc2b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.57082754;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -94.9375,-169.09375 c -0.02445,0.0114 -0.07282,0.0179 -0.09375,0.0312 -0.07655,0.0171 -0.129072,0.0618 -0.1875,0.0937 -0.06733,0.0426 -0.102853,0.0701 -0.125,0.125 -0.04225,0.0882 -0.02336,0.20307 0.0625,0.28125 0.425481,0.37342 0.870923,1.31835 1.09375,2.46875 0.222825,1.15041 0.26055,2.52729 0.0625,3.8125 -0.229814,1.49133 -0.739166,2.50981 -1.21875,2.875 -0.06733,0.0426 -0.134102,0.10133 -0.15625,0.15625 -0.02264,0.0932 0.04665,0.17736 0.15625,0.25 0.116379,0.0913 0.296118,0.15625 0.5,0.15625 0.203886,0 0.383626,-0.065 0.5,-0.15625 0.05375,-0.0409 0.10617,-0.08 0.15625,-0.125 0.100788,-0.012 0.199646,-0.0299 0.28125,-0.0625 0.05623,-0.0197 0.114869,-0.067 0.15625,-0.0937 0.879891,-0.58512 1.33731,-1.57799 1.59375,-3.03125 0.221887,-1.25745 0.188175,-2.58853 -0.0625,-3.71875 -0.250672,-1.13023 -0.67717,-2.06619 -1.40625,-2.625 -0.07644,-0.0471 -0.164946,-0.10325 -0.28125,-0.125 -0.08767,-0.0266 -0.180589,-0.0253 -0.28125,-0.0312 -0.03116,-0.0302 -0.0613,-0.0653 -0.09375,-0.0937 -0.05975,-0.064 -0.132554,-0.12368 -0.25,-0.15625 -0.124538,-0.0375 -0.266141,-0.0447 -0.40625,-0.0312 l 0,-1e-4 0,0 z"
+ transform="translate(56,6)"
+ id="path43515-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43525-3"
+ transform="matrix(1,0,0,0.8248704,3.9999996,-27.664792)"
+ style="fill:#bc2b00;stroke:none">
+ <path
+ id="path43527-3"
+ style="fill:#bc2b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.62850982;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -38.766635,-163.1299 c -0.1926,0.0198 -0.359499,0.088 -0.454803,0.18574 -0.141826,0.12415 -0.141826,0.2845 0,0.40865 0.393723,0.36252 0.827594,1.30384 1.03955,2.45188 0.211957,1.14804 0.253401,2.50645 0.06497,3.78928 -0.218694,1.48887 -0.72826,2.54519 -1.169495,2.89767 -0.09595,0.0836 -0.129342,0.18561 -0.09271,0.28335 0.03663,0.0977 0.140225,0.18301 0.287629,0.23675 0.146132,0.0549 0.324618,0.074 0.495554,0.053 0.170936,-0.0209 0.320068,-0.0802 0.414052,-0.16446 0.787677,-0.62926 1.137868,-1.68972 1.364411,-3.23203 0.196047,-1.33468 0.156543,-2.73807 -0.06497,-3.93787 -0.221514,-1.1998 -0.582737,-2.18614 -1.234468,-2.78623 -0.130885,-0.13138 -0.387364,-0.2047 -0.649719,-0.18574 l 0,0 -10e-7,1e-5 0,0 z m 0.338475,0.29257 c -0.244486,0.0286 -0.443513,0.11281 -0.531926,0.22492 -0.08841,0.11212 -0.05483,0.23776 0.08976,0.33579 0.442252,0.33867 0.938861,1.23068 1.179113,2.31292 0.24025,1.08225 0.287292,2.36512 0.07369,3.57452 -0.247925,1.40376 -0.831847,2.40481 -1.326503,2.73346 -0.229933,0.15651 -0.165504,0.37098 0.14739,0.49062 0.163456,0.0637 0.375184,0.0924 0.584711,0.0791 0.209527,-0.0133 0.398079,-0.0673 0.520708,-0.14918 0.899238,-0.59746 1.290496,-1.62825 1.547585,-3.0839 0.222494,-1.25976 0.177718,-2.58217 -0.0737,-3.71469 -0.251412,-1.13252 -0.582944,-2.05893 -1.326502,-2.62833 -0.04216,-0.0265 -0.09175,-0.05 -0.147388,-0.0701 -0.187804,-0.0957 -0.469403,-0.13585 -0.736946,-0.10513 l 8e-6,0 0,0 z"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.99492121"
+ inkscape:original="M -42 -162.5 C -43.383118 -162.5 -44.5 -160.4822 -44.5 -158 C -44.5 -155.5178 -43.383119 -153.5 -42 -153.5 L -32.5 -155.5 C -31.25 -155.75 -31.25 -160.25 -32.5 -160.5 C -35.664485 -161.13789 -38.864604 -161.81719 -42 -162.5 z "
+ style="fill:url(#linearGradient24022-6);fill-opacity:1;fill-rule:evenodd;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"
+ id="path43484-5"
+ d="m -42,-163.5 c -1.175382,0 -2.068672,0.84122 -2.625,1.84375 -0.556328,1.00253 -0.875,2.26593 -0.875,3.65625 0,1.39032 0.318672,2.65372 0.875,3.65625 0.556328,1.00253 1.449618,1.84375 2.625,1.84375 a 0.9950207,0.9950207 0 0 0 0.21875,-0.0312 l 9.46875,-2 c 0.01655,-0.003 0.01506,-0.0275 0.03125,-0.0312 0.840076,-0.19179 1.234143,-0.86885 1.4375,-1.46875 0.207276,-0.61147 0.28125,-1.28773 0.28125,-1.96875 0,-0.68102 -0.07397,-1.35728 -0.28125,-1.96875 -0.207276,-0.61147 -0.593404,-1.32493 -1.46875,-1.5 -3.157727,-0.63653 -6.336828,-1.31795 -9.46875,-2 A 0.9950207,0.9950207 0 0 0 -42,-163.5 z" />
+ <path
+ style="fill:none;stroke:#999999;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -42.46462,-152.96991 0,4.5"
+ id="path43213-9"
+ sodipodi:nodetypes="cc"
+ 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"
+ sodipodi:ry="4.25"
+ sodipodi:rx="0.9705897"
+ sodipodi:cy="-158"
+ sodipodi:cx="-41.5"
+ id="path43356-9"
+ style="fill:url(#linearGradient24024-4);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.48405313;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"
+ sodipodi:type="arc" />
+ <rect
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43215-8"
+ width="1"
+ height="1"
+ x="-42.964619"
+ y="-152.96989" />
+ <path
+ d="m -42,-162.59375 c -0.74028,0 -1.381145,0.54136 -1.84375,1.375 -0.462605,0.83364 -0.75,1.96262 -0.75,3.21875 0,1.25613 0.287395,2.38511 0.75,3.21875 0.462605,0.83364 1.10347,1.375 1.84375,1.375 a 0.10019871,0.10019871 0 0 0 0.03125,0 l 9.5,-2 c 0.369179,-0.0738 0.619862,-0.43015 0.78125,-0.90625 0.161388,-0.4761 0.21875,-1.08496 0.21875,-1.6875 0,-0.60254 -0.05736,-1.2114 -0.21875,-1.6875 -0.161388,-0.4761 -0.412071,-0.83241 -0.78125,-0.90625 -3.163804,-0.63775 -6.364954,-1.31727 -9.5,-2 a 0.10019871,0.10019871 0 0 0 -0.03125,0 z"
+ id="path43218-1"
+ style="fill:none;stroke:url(#linearGradient14482-7);stroke-width:1;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:original="M -42 -162.5 C -43.383118 -162.5 -44.5 -160.4822 -44.5 -158 C -44.5 -155.5178 -43.383119 -153.5 -42 -153.5 L -32.5 -155.5 C -31.25 -155.75 -31.25 -160.25 -32.5 -160.5 C -35.664485 -161.13789 -38.864604 -161.81719 -42 -162.5 z "
+ inkscape:radius="0.10018869"
+ sodipodi:type="inkscape:offset" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24573-8"
+ transform="translate(189,104.96991)">
+ <g
+ id="g24558-2">
+ <rect
+ y="241"
+ x="47"
+ height="16"
+ width="16"
+ id="rect24365-6"
+ style="opacity:0;fill:#ffff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.10000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccsss"
+ id="path24370-6"
+ d="m 60.5,253 -1,0.5 -0.998035,-1 -7e-6,-2 -0.999999,-1 -2.251959,0 -0.75,-0.75 0.002,-2.25 -1.000001,-1 -1.999993,0 -1.001965,-0.75 0.498035,-1 c 1.618614,-3.25 6.964866,-2.7871 9.501965,-0.25 2.5371,2.53709 3,8 0,9.5 L 60.5,253 z"
+ style="fill:url(#linearGradient24044-1);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;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccsccsccccc"
+ id="path24406-0"
+ d="m 55.40625,241.84375 c -1.752306,-0.0251 -3.360906,0.59103 -4.09375,2.0625 l -0.15625,0.3125 c -0.122559,0.2366 -0.05653,0.52711 0.15625,0.6875 l 0.15625,0.125 c 0.100886,0.0688 0.221909,0.1018 0.34375,0.0937 l 1.6875,0 c 0.01042,3e-4 0.02083,3e-4 0.03125,0 0.09863,-0.003 0.17826,0.0573 0.25,0.125 l 1,0.96875 c 0.06775,0.0718 0.09659,0.15137 0.09375,0.25 -2.98e-4,0.0104 -2.98e-4,0.0208 0,0.0312 l 0,2.09375 0.375,0.15625 4.96875,-4.96875 c -1.186918,-1.18692 -3.03835,-1.91206 -4.8125,-1.9375 l 0,1e-4 0,0 z"
+ style="fill:url(#linearGradient24046-9);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.82999998"
+ id="g24372-3"
+ transform="translate(21,0)"
+ mask="url(#mask25021-4)">
+ <path
+ id="path24374-8"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 30,246.5 -2,7 1.5,1.5 7,-2 m -3.5,-3 -4.5,4.5"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24380-0"
+ style="fill:none;stroke:url(#radialGradient24048-2);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:new"
+ d="M 34.25,248.75 28.5,254.5"
+ mask="none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ mask="none"
+ d="m 30.5,244.75 -2.5,8.75 1.5,1.5 8.75,-2.5"
+ style="fill:none;stroke:url(#radialGradient24050-4);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path24448-1"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccssc"
+ id="path24408-2"
+ d="m 55.40625,242.375 c -1.622878,-0.0233 -2.972755,0.53436 -3.59375,1.78125 l -0.15625,0.3125 0.15625,0.125 1.6875,0 c 0.243249,-0.007 0.479315,0.0829 0.65625,0.25 l 1,1 c 0.167073,0.17694 0.257003,0.413 0.25,0.65625 L 55.5,248 l 0.5,0.5 1.5,0.0937 c 0.243249,-0.007 0.479315,0.0829 0.65625,0.25 l 1,1 c 0.167073,0.17694 0.257003,0.413 0.25,0.65625 l 0,1.59375 0.28125,0.28125 0.40625,-0.1875 c 1.084704,-0.54235 1.613412,-1.88556 1.5625,-3.53125 -0.05091,-1.64569 -0.757004,-3.44451 -1.8125,-4.5 -1.05838,-1.05838 -2.814635,-1.75798 -4.4375,-1.78125 l 0,5e-5 z"
+ style="fill:none;stroke:url(#linearGradient24053-5);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24450-5"
+ width="2"
+ height="1"
+ x="50"
+ y="245" />
+ <rect
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24452-0"
+ width="1"
+ height="1"
+ x="54"
+ y="248" />
+ <rect
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24454-9"
+ width="1"
+ height="1"
+ x="55"
+ y="249" />
+ <rect
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24456-4"
+ width="1"
+ height="2"
+ x="58"
+ y="252" />
+ <rect
+ y="249"
+ x="54"
+ height="1"
+ width="1"
+ id="rect24659-7"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24384-8"
+ transform="matrix(0.3350147,0,0,0.3350147,6.410699,179.66413)"
+ 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">
+ <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="path24396-3"
+ style="fill:#ff541f;fill-opacity:1;fill-rule:nonzero;stroke:#320b00;stroke-width:3.58193231;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"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:url(#linearGradient24055-1);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path24398-5"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path24400-1"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient24057-7);stroke-width:6.6867547;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:new"
+ 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" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g43234-2"
+ transform="matrix(-1,0,0,1,185,310)">
+ <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"
+ id="rect44017-0"
+ width="16"
+ height="16"
+ x="-46"
+ y="-52" />
+ <g
+ style="opacity:0.8"
+ id="g43226-1">
+ <g
+ id="g43115-6"
+ clip-path="url(#clipPath43135-6)"
+ mask="url(#mask43188-4)">
+ <path
+ d="m -45.5,42.5 1,1 3,-1 0.75,1 1.25,0 1,1 0,2 2,2 -2,2 0,1"
+ 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:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path43103-4"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path43099-0"
+ style="fill:none;stroke:#ffffff;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 -45.5,42.5 1,1 3,-1 0.75,1 1.25,0 1,1 0,2 2,2 -2,2 0,1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ mask="url(#mask43182-5)"
+ clip-path="url(#clipPath43178-6)"
+ id="g43206-6">
+ <path
+ d="m -45.5,42.5 1,1 3,-1 0.75,1 1.25,0 1,1 0,3 2,2 -1,1 -1,1"
+ 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:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path43208-1"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path43210-8"
+ style="fill:none;stroke:#ffffff;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 -45.5,42.5 1,1 3,-1 0.75,1 1.25,0 1,1 0,3 2,2 -1,1 -1,1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g43218-9">
+ <g
+ id="g43129-8"
+ clip-path="url(#clipPath43178-6)"
+ mask="url(#mask43182-5)">
+ <path
+ sodipodi:nodetypes="cccccccccccccccc"
+ id="path43131-4"
+ 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:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -45.5,37.5 3,0 0,1 3,0 1,-1 2,2 0,1 1,1 2,0 1,1 0,1 -1,1 0,2 2,2 0,2 -1,1"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -45.5,37.5 3,0 0,1 3,0 1,-1 2,2 0,1 1,1 2,0 1,1 0,1 -1,1 0,2 2,2 0,2 -1,1"
+ style="fill:none;stroke:#ffffff;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"
+ id="path43133-1"
+ sodipodi:nodetypes="cccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ mask="url(#mask43188-4)"
+ clip-path="url(#clipPath43135-6)"
+ id="g43212-4">
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ id="path43214-3"
+ 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:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -45.5,37.5 3,0 0,1 3,0 1,-1 2,2 0,1 1,1 2,0 1,1 -1,1 0,3 2,2 0,2 -1,1"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -45.5,37.5 3,0 0,1 3,0 1,-1 2,2 0,1 1,1 2,0 1,1 -1,1 0,3 2,2 0,2 -1,1"
+ style="fill:none;stroke:#ffffff;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"
+ id="path43216-9"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g29725-8"
+ transform="matrix(-0.3350147,0,0,0.3350147,-0.450611,-25.365697)"
+ 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">
+ <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="path29727-8"
+ style="fill:#ff541f;fill-opacity:1;fill-rule:nonzero;stroke:#320b00;stroke-width:3.58193231;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"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:url(#linearGradient24210-1);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path29729-0"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29731-8"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient24212-8);stroke-width:6.6867547;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:new"
+ 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" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,336)"
+ style="display:inline;enable-background:new"
+ id="g21835-7">
+ <g
+ transform="translate(51,10)"
+ style="opacity:0.8"
+ id="g44612-7">
+ <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"
+ id="rect44610-8"
+ width="16"
+ height="16"
+ x="-46"
+ y="-16" />
+ <g
+ id="g44566-3"
+ transform="translate(0,22)">
+ <g
+ transform="translate(0,0.02014865)"
+ inkscape:transform-center-x="6.4341195"
+ id="g44395-8">
+ <g
+ id="g44383-3"
+ inkscape:transform-center-x="6.4130439"
+ style="fill:none;stroke:#000000;stroke-width:2.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" />
+ <g
+ inkscape:transform-center-x="6.4130439"
+ id="g44315-7" />
+ </g>
+ <g
+ id="g44401-1"
+ inkscape:transform-center-x="-6.4341194"
+ transform="matrix(-1,0,0,-1,-76,-27.947857)">
+ <g
+ style="fill:none;stroke:#000000;stroke-width:2.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:transform-center-x="6.4130439"
+ id="g44403-0" />
+ <g
+ id="g44407-7"
+ inkscape:transform-center-x="6.4130439" />
+ </g>
+ <g
+ inkscape:transform-center-y="-6.3979735"
+ id="g44425-3"
+ transform="matrix(0,1,-1,0,-51.984003,24.036146)">
+ <g
+ style="fill:none;stroke:#000000;stroke-width:2.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:transform-center-x="6.4130439"
+ id="g44427-4" />
+ <g
+ id="g44431-9"
+ inkscape:transform-center-x="6.4130439" />
+ </g>
+ <g
+ inkscape:transform-center-y="6.4702655"
+ transform="matrix(0,-1,1,0,-24.015997,-51.963854)"
+ id="g44435-6">
+ <g
+ id="g44437-5"
+ inkscape:transform-center-x="6.4130439"
+ style="fill:none;stroke:#000000;stroke-width:2.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" />
+ <g
+ inkscape:transform-center-x="6.4130439"
+ id="g44441-1" />
+ </g>
+ <g
+ inkscape:transform-center-y="-4.4797485"
+ id="g44532-0">
+ <g
+ inkscape:transform-center-y="-4.4797485"
+ id="g44511-9"
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,-74.7838,3.0074334)"
+ inkscape:transform-center-x="-4.4797485">
+ <g
+ style="fill:none;stroke:#000000;stroke-width:2.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:transform-center-x="6.4130439"
+ id="g44514-9" />
+ <g
+ id="g44518-6"
+ inkscape:transform-center-x="6.4130439" />
+ </g>
+ <g
+ inkscape:transform-center-x="4.4797488"
+ transform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-20.992567,22.7838)"
+ id="g44522-8"
+ inkscape:transform-center-y="-4.4797486">
+ <g
+ id="g44524-3"
+ inkscape:transform-center-x="6.4130439"
+ style="fill:none;stroke:#000000;stroke-width:2.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" />
+ <g
+ inkscape:transform-center-x="6.4130439"
+ id="g44528-4" />
+ </g>
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,-75.995432,-28)"
+ id="g44544-8"
+ inkscape:transform-center-y="4.4797485">
+ <g
+ inkscape:transform-center-x="-4.4797485"
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,-74.7838,3.0074334)"
+ id="g44546-4"
+ inkscape:transform-center-y="-4.4797485">
+ <g
+ id="g44548-9"
+ inkscape:transform-center-x="6.4130439"
+ style="fill:none;stroke:#000000;stroke-width:2.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" />
+ <g
+ inkscape:transform-center-x="6.4130439"
+ id="g44552-9" />
+ </g>
+ <g
+ inkscape:transform-center-y="-4.4797486"
+ id="g44556-2"
+ transform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-20.992567,22.7838)"
+ inkscape:transform-center-x="4.4797488">
+ <g
+ style="fill:none;stroke:#000000;stroke-width:2.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:transform-center-x="6.4130439"
+ id="g44558-5">
+ <path
+ d="m 139.82809,116.3993 c 0.21326,1.04297 0.21596,2.11803 0.008,3.16206 m -6.21068,6.20286 c -1.04294,0.21326 -2.11797,0.21596 -3.16197,0.008 m -6.20664,-6.20689 c -0.21326,-1.04297 -0.21596,-2.11803 -0.008,-3.16206 m 6.21068,-6.20286 c 1.04294,-0.21326 2.11797,-0.21596 3.16196,-0.008 m 5.10366,12.24081 c -0.58667,0.88829 -1.34493,1.65039 -2.23019,2.24157 m -11.07625,-11.07658 c 0.58667,-0.88829 1.34492,-1.65038 2.23019,-2.24157 m 8.8404,0.006 c 0.88827,0.58669 1.65034,1.34497 2.24151,2.23026 m -11.07626,11.07657 c -0.88826,-0.58669 -1.65033,-1.34496 -2.2415,-2.23025"
+ style="stroke:#000000;stroke-width:3.44192362;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(-0.8135104,0,0,-0.8134867,69.383376,81.991427)"
+ id="path44560-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44562-3"
+ inkscape:transform-center-x="6.4130439">
+ <path
+ d="m 139.86607,116.59777 c 0.16588,0.93061 0.16532,1.88326 -0.002,2.81367 m -6.43712,6.39076 c -0.93059,0.16588 -1.88321,0.16532 -2.81359,-0.002 m -6.39454,-6.43334 c -0.16588,-0.93061 -0.16532,-1.88326 0.002,-2.81367 m 6.43712,-6.39076 c 0.93058,-0.16588 1.88321,-0.16532 2.81359,0.002 m 5.25357,12.26879 c -0.58667,0.88829 -1.34493,1.65039 -2.23019,2.24157 m -11.07625,-11.07658 c 0.58667,-0.88829 1.34492,-1.65038 2.23019,-2.24157 m 8.8404,0.006 c 0.88827,0.58669 1.65034,1.34497 2.24151,2.23026 m -11.07626,11.07657 c -0.88826,-0.58669 -1.65033,-1.34496 -2.2415,-2.23025"
+ style="fill:none;stroke:#ffffff;stroke-width:1.72096181;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.8135104,0,0,-0.8134867,69.383376,81.991427)"
+ id="path44564-3"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.4200287,0,0,0.4200289,-40.97369,-75.87647)"
+ id="g45379-3"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ff541f;fill-opacity:1;fill-rule:nonzero;stroke:#2b0000;stroke-width:2.5395081;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path45381-7"
+ 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
+ transform="matrix(-0.6011908,-0.06817113,0.06852359,-0.6012277,199.77148,303.44348)"
+ 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="path45383-4"
+ style="fill:url(#linearGradient24214-1);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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.6;fill:none;stroke:url(#linearGradient24216-4);stroke-width:5.33335066;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:new"
+ id="path45385-3"
+ 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"
+ transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g45967-8"
+ transform="translate(198,390)">
+ <g
+ mask="url(#mask45447-7)"
+ transform="translate(-261,-409)"
+ id="g15201-1-0"
+ style="opacity:0.8;display:inline;enable-background:new">
+ <rect
+ y="365"
+ x="215"
+ height="16"
+ width="16"
+ id="rect15183-3-8"
+ 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(167.99999,-62.999991)"
+ id="g15185-8-8">
+ <rect
+ ry="0"
+ style="fill:#ececec;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="rect15187-7-0"
+ width="13.016124"
+ height="12.953857"
+ x="48.499996"
+ y="429.54614" />
+ <rect
+ y="430"
+ x="50.016117"
+ height="11.046139"
+ width="11.000001"
+ id="rect15189-4-6"
+ style="fill:url(#linearGradient24218-1);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
+ style="fill:url(#linearGradient24220-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 49,430 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,0 0,3 3,0 0,-3 -3,0 z m 0,3 -3,0 0,3 3,0 0,-3 z m 0,3 0,3 3,0 0,-3 -3,0 z m -3,0 -3,0 0,3 3,0 0,-3 z m -3,0 0,-3 -3,0 0,3 3,0 z"
+ id="path15191-2-8"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24222-6);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 60.517703,430.5 -11.017704,0 0,11 11.017704,0 0,-11"
+ id="path15193-7-1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="429.54614"
+ x="48.499996"
+ height="12.953857"
+ width="13.016124"
+ id="rect45403-9"
+ style="fill:url(#radialGradient24224-0);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.4200287,0,0,0.4200289,-86.973687,-124.87647)"
+ id="g45391-8"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ff541f;fill-opacity:1;fill-rule:nonzero;stroke:#2b0000;stroke-width:2.5395081;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="path45393-9"
+ 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
+ transform="matrix(-0.6011908,-0.06817113,0.06852359,-0.6012277,199.77148,303.44348)"
+ 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="path45395-7"
+ style="fill:url(#linearGradient24226-2);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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.75;fill:none;stroke:url(#linearGradient24228-5);stroke-width:5.33335066;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:new"
+ id="path45397-2"
+ 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"
+ transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g43252-2"
+ transform="matrix(-1,0,0,1,16.999998,490)">
+ <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"
+ id="rect45977-5-8"
+ width="16"
+ height="16"
+ x="-46"
+ y="128" />
+ <g
+ mask="url(#mask45865-7)"
+ style="opacity:0.95"
+ id="g45749-2">
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path45716-8"
+ d="m -37.991001,-135.06482 c -0.756259,0.48145 -1.648418,-0.21174 -1.880274,-0.94014 -0.414735,-1.30293 0.637877,-2.55676 1.880274,-2.82041 1.823267,-0.38691 3.481311,1.06592 3.760547,2.82041 0.372178,2.33846 -1.494127,4.41212 -3.760547,4.70069 -2.852058,0.36313 -5.346025,-1.9223 -5.640821,-4.70069 -0.357038,-3.365 2.346435,-6.33509 5.640821,-6.58096 3.825581,-0.28552 7.055689,2.67913 7.813138,6.13556"
+ style="fill:none;stroke:#000000;stroke-width:2.77754736;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ transform="matrix(0.6590823,0.8571222,-0.8500307,0.6645808,-129.57187,-12.997286)"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.6590823,0.8571222,-0.8500307,0.6645808,-129.57187,-12.997286)"
+ style="fill:none;stroke:#ffffff;stroke-width:1.1110189;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -37.991001,-135.06482 c -0.756259,0.48145 -1.648418,-0.21174 -1.880274,-0.94014 -0.414735,-1.30293 0.637877,-2.55676 1.880274,-2.82041 1.823267,-0.38691 3.481311,1.06592 3.760547,2.82041 0.372178,2.33846 -1.494127,4.41212 -3.760547,4.70069 -2.852058,0.36313 -5.346025,-1.9223 -5.640821,-4.70069 -0.357038,-3.365 2.346435,-6.33509 5.640821,-6.58096 3.825581,-0.28552 7.055689,2.67913 7.813138,6.13556"
+ id="path45712-9"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g29693-0"
+ transform="matrix(-1,0,0,1,-78.286205,4.2655334)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-141.76553"
+ x="-39.799313"
+ height="3"
+ width="2.9998772"
+ id="rect29695-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#5a0d00;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"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path29697-8"
+ d="m -37.299433,-141.26553 -1.999997,1e-5 0,1.99999 1.999997,-10e-6 0,-1.99999 z"
+ style="fill:#ff541f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path29699-1"
+ d="m -38.799427,-139.76553 0,-1 0.999994,0"
+ style="opacity:0.45;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.4;fill:#ffffff;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 -38.29943,-141.26553 -1,1e-5 0,0.99999 1,0 0,-1 z"
+ id="path29701-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"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g45137-8"
+ transform="translate(156,308)">
+ <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"
+ id="rect46015-6"
+ width="16"
+ height="16"
+ x="-46"
+ y="-54" />
+ <g
+ id="g45118-1">
+ <g
+ id="g45099-2"
+ transform="translate(0,6.9866005)">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.6645615,0,0,0.6645596,-126.90026,-106.03317)"
+ id="g37580-2-4"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ff541f;fill-opacity:1;fill-rule:nonzero;stroke:#2b0000;stroke-width:1.60507059;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="path37582-3-2"
+ 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
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)"
+ 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="path37584-3-5"
+ style="opacity:0.6;fill:url(#linearGradient24230-5);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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.7;fill:none;stroke:url(#linearGradient24232-9);stroke-width:2.66303396;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:new"
+ id="path38120-7-4-8"
+ 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"
+ transform="matrix(0.5650525,0,0,0.5650532,53.91307,156.82373)" />
+ </g>
+ <g
+ style="opacity:0.5;fill:#ffd5d5"
+ id="g45083-6">
+ <rect
+ ry="0.88169974"
+ rx="0.88169974"
+ y="42.25"
+ x="-44"
+ height="1.7633995"
+ width="5.5"
+ id="rect45079-2"
+ style="fill:#ffd5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000083;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ ry="0.875"
+ rx="0.97123623"
+ style="fill:#ffd5d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000083;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect45081-6"
+ width="5.5"
+ height="1.75"
+ x="40"
+ y="40"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
+ <rect
+ y="41.986599"
+ x="-44.006248"
+ height="1.0133995"
+ width="5.0062485"
+ id="rect45067-5"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000083;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000083;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect45069-3"
+ width="4.9865952"
+ height="1.0133995"
+ x="-44.986595"
+ y="-42.009823" />
+ </g>
+ <g
+ id="g45110-9"
+ transform="translate(0,-6.986599)">
+ <g
+ style="display:inline;enable-background:new"
+ id="g44887-2"
+ transform="matrix(0.6610822,0,0,0.6610806,-119.47405,-98.276513)"
+ 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">
+ <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="path44889-4"
+ style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.61351788;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient24234-7);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path44891-6"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path44893-1"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:2.64463997;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:new"
+ 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" />
+ </g>
+ <rect
+ ry="1.0066998"
+ rx="1.0066998"
+ y="49"
+ x="-37"
+ height="2.0133996"
+ width="5.5"
+ id="rect45087-8"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000083;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000083;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect45077-2"
+ width="5.0062485"
+ height="1.0133995"
+ x="-37.006248"
+ y="48.986599" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24618-1"
+ transform="translate(168,176)">
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="5"
+ height="16"
+ width="16"
+ id="rect42080-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
+ mask="url(#mask43040-7)"
+ transform="translate(51.040182,194)"
+ id="g42934-9">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path42084-7"
+ d="m -43,-12 c 4.5365,0 10.5,-1.75 10.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:#3c0800;stroke-width:3.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"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#3c0800;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="rect42088-6"
+ width="2.9998772"
+ height="3"
+ x="-39.499878"
+ y="-23.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-13.5"
+ x="-44.499878"
+ height="3"
+ width="2.9998772"
+ id="rect42092-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#5a0d00;stroke-width:0.5;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
+ style="fill:none;stroke:#ed5e32;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 -43,-12 c 4.5365,0 10.5,-1.75 10.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path42142-9"
+ sodipodi:nodetypes="csc"
+ 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"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24236-2);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 -43,-12 c 4.5365,0 10.5,-1.75 10.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path42140-5"
+ sodipodi:nodetypes="csc"
+ 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"
+ 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="path42094-2"
+ d="m -42,-13 c -0.67541,0 -1.35081,10e-6 -2.02623,10e-6 0,0.66939 0,1.33877 0,2.00817 0.67542,0 1.35082,-10e-6 2.02623,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ff541f;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="fill:#ff8d69;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 -37,-23 c -0.65334,0 -1.30668,10e-6 -1.96003,10e-6 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-10e-6 1.96003,-10e-6 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path42096-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"
+ 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;display:inline"
+ d="m -38.5,-21.5 0,-1 1,0"
+ id="path42098-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42100-3"
+ d="m -43.52623,-11.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ 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="path42102-9"
+ d="m -36,-20.48792 c -0.32001,0 -0.64002,-10e-6 -0.96003,-10e-6 0,-0.63982 0,-1.27964 0,-1.91948 0.32001,0 0.64002,10e-6 0.96003,10e-6 0,0.63983 0,1.27966 0,1.91948 z"
+ style="opacity:0.15;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#ff541f;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 -40.999878,-11 c -0.32001,0 -0.64002,0 -0.96003,0 0,-0.21055 0,-0.42107 0,-0.63162 0.32001,0 0.64002,0 0.96003,0 0,0.21055 0,0.42107 0,0.63162 z"
+ id="path42104-1"
+ 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="path42106-8"
+ d="m -40.999878,-11.33707 c -0.32001,0 -0.64002,-10e-6 -0.96003,-10e-6 0,-0.55431 0,-1.1086 0,-1.66292 0.32001,0 0.64002,10e-6 0.96003,10e-6 0,0.55431 0,1.10861 0,1.66292 z"
+ style="opacity:0.25;fill:#ff541f;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" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g44965-1"
+ transform="matrix(0.5000262,0,0,0.5000067,-54.73874,70.74849)"
+ 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">
+ <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="path44967-9"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.13326335;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient24239-1);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path44969-5"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path44971-3"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:4.0295496;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:new"
+ 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" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g43314-2"
+ transform="translate(177,410)">
+ <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"
+ id="rect43157-5"
+ width="16"
+ height="16"
+ x="-46"
+ y="48" />
+ <g
+ id="g43221-2"
+ transform="matrix(1.1891377,0,0,1.189137,-45.334548,102.47504)"
+ style="display:inline;enable-background:new">
+ <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="path43224-5"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.86864018;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.3150215,0,0,0.3150217,-36.662669,-174.25239)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.79000005;fill:url(#linearGradient24241-6);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path43226-8"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path43228-6"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient24243-1);stroke-width:4.00001144;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:new"
+ 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" />
+ </g>
+ <g
+ transform="matrix(0.9963903,0,0,1,-2.1155075,0)"
+ id="g43169-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"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.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="path43170-7"
+ style="fill:#ff5b29;fill-opacity:1;fill-rule:nonzero;stroke:#2b0000;stroke-width:1.6028651;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5625217,0,0,0.5624997,-110.25304,-122.37496)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient24245-3);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path43172-2"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path43174-2"
+ style="opacity:0.65;fill:none;stroke:url(#linearGradient24247-8);stroke-width:2.29000854;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:new"
+ 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" />
+ </g>
+ <g
+ transform="matrix(0,-1,-1,0,-93.999999,-92)"
+ id="g42385-9">
+ <path
+ sodipodi:nodetypes="csscc"
+ id="path42387-4"
+ d="m -36.5,-51.499999 c -0.5,1 -1.34258,1.996832 -2.996831,1.996832 -1.654251,0 -3,-1.345743 -3,-2.999994 0,-1.308742 0.996831,-2.496838 1.996831,-2.996838 l 4,4 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient24249-9);stroke-width:0.89999998;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient24251-6);fill-opacity:1;fill-rule:nonzero"
+ d="m -36.5,-51.499999 c -0.5,1 -1.34258,1.996832 -2.996831,1.996832 -1.654251,0 -2.996872,-1.345746 -3,-2.999994 C -42.5,-54.175184 -41.5,-54.999999 -40.5,-55.499999 l 4,4 z"
+ id="path43279-1"
+ sodipodi:nodetypes="csscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccsss"
+ id="path42392-9"
+ d="m -40.75,-54.249999 3,3 c -0.25,0.25 -0.659057,0.708509 -1.758414,0.708509 -1.099355,0 -1.991586,-0.877412 -1.991586,-1.958509 0,-1.081096 0.5,-1.5 0.75,-1.75 z"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient24253-0);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1.1891377,0,0,1.189137,-39.353927,107.5067)"
+ id="g43258-6"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.3150215,0,0,0.3150217,-36.662669,-174.25239)"
+ sodipodi:type="arc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient24255-6);stroke-width:2.40253735;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path43260-9"
+ 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
+ transform="matrix(-0.2610878,-0.02960567,0.02975872,-0.2611039,35.872259,-102.36161)"
+ 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="path43262-8"
+ style="fill:url(#linearGradient24257-6);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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.7;fill:none;stroke:url(#linearGradient24259-1);stroke-width:4.00001144;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:new"
+ id="path43264-2"
+ 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"
+ 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">
+ <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"
+ id="rect49020-5"
+ width="16"
+ height="16"
+ x="-46"
+ y="69" />
+ <g
+ id="g49022-4"
+ style="opacity:0.5">
+ <g
+ id="g49024-9"
+ mask="url(#mask48816-8)"
+ style="opacity:0.4;display:inline;enable-background:new">
+ <path
+ id="path49027-1"
+ d="M -42.5,-79.5 -32,-83"
+ style="fill:none;stroke:#2b0800;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ff8d73;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M -42.5,-79.5 -32,-83"
+ id="path49031-2"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g49034-5">
+ <g
+ style="display:inline;enable-background:new"
+ id="g49036-0"
+ transform="matrix(1.1891377,0,0,1.189137,-48.353927,83.503529)">
+ <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="path49039-8"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.13558888;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.3150215,0,0,0.3150217,-36.662669,-174.25239)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient24279-6);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path49043-3"
+ 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.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"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path49045-9"
+ style="fill:none;stroke:url(#linearGradient24281-3);stroke-width:4.00001144;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:new"
+ 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" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g49048-3"
+ style="opacity:0.8">
+ <g
+ style="opacity:0.5"
+ mask="url(#mask48816-8)"
+ id="g49050-9">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#2b0800;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M -39.5,-75.5 -32,-83"
+ id="path49055-6"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path49057-7"
+ d="M -39.5,-75.5 -32,-83"
+ style="fill:none;stroke:#ff8d73;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g49059-9">
+ <g
+ transform="matrix(1.1891377,0,0,1.189137,-45.367039,87.538326)"
+ id="g49061-9"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.3150215,0,0,0.3150217,-36.662669,-174.25239)"
+ sodipodi:type="arc"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.13558888;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path49065-7"
+ 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
+ transform="matrix(-0.2610878,-0.02960567,0.02975872,-0.2611039,35.872259,-102.36161)"
+ 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="path49067-6"
+ style="fill:url(#linearGradient24283-7);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="fill:none;stroke:url(#linearGradient24285-8);stroke-width:4.00001144;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:new"
+ id="path49069-9"
+ 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"
+ transform="matrix(0.2102357,0,0,0.2102362,-22.830954,-161.8877)" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g49071-3">
+ <g
+ id="g49073-5"
+ mask="url(#mask28585-8)">
+ <path
+ id="path49075-7"
+ d="M -34.5,-72.5 -32,-83"
+ style="fill:none;stroke:#2b0800;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ff8d73;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M -34.5,-72.5 -32,-83"
+ id="path49077-6"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1.1891377,0,0,1.189137,-40.353927,90.509865)"
+ id="g49079-6"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.3150215,0,0,0.3150217,-36.662669,-174.25239)"
+ sodipodi:type="arc"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.13558888;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path49082-5"
+ 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
+ transform="matrix(-0.2610878,-0.02960567,0.02975872,-0.2611039,35.872259,-102.36161)"
+ 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="path49084-8"
+ style="fill:url(#linearGradient24287-1);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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="fill:none;stroke:url(#linearGradient24289-3);stroke-width:4.00001144;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:new"
+ id="path49086-2"
+ 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"
+ transform="matrix(0.2102357,0,0,0.2102362,-22.830954,-161.8877)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(6.299313,57.265533)"
+ id="g49088-5">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#5a0d00;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="rect49090-4"
+ width="2.9998772"
+ height="3"
+ x="-39.799313"
+ y="-141.76553"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ff541f;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 -37.299433,-141.26553 c -0.65334,0 -1.30668,1e-5 -1.96003,1e-5 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-10e-6 1.96003,-10e-6 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path49092-4"
+ 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.45;fill:none;stroke:#ffffff;stroke-width:1px;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 -38.799433,-139.76553 0,-1 1,0"
+ id="path49094-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g33096-6"
+ transform="translate(189,147)">
+ <g
+ transform="translate(51,203)"
+ id="g45912-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="rect35680-9-6"
+ width="16"
+ height="16"
+ x="-46"
+ y="-4" />
+ <g
+ style="opacity:0.95;display:inline;enable-background:new"
+ transform="translate(-491,-214.9763)"
+ id="g35844-1-3"
+ inkscape:transform-center-x="-0.78726"
+ inkscape:transform-center-y="2.2787562">
+ <path
+ style="opacity:0.95;fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 454.5,218.5 c -1.25,-1.5 -2.5,-1.5 -4,1 -1.5,-2.5 -2.75,-2.5 -4,-1"
+ id="path35846-9-3"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path35848-8-5"
+ d="m 454.5,218.5 c -1.25,-1.5 -2.5,-1.5 -4,1 -1.5,-2.5 -2.75,-2.5 -4,-1"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35914-6-5"
+ width="1"
+ height="2"
+ x="450"
+ y="217.9763" />
+ <rect
+ y="217.9763"
+ x="449.25"
+ height="1"
+ width="0.75"
+ id="rect35916-5-3"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;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:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35919-0-2"
+ width="0.75"
+ height="1"
+ x="451"
+ y="217.9763" />
+ </g>
+ <g
+ id="g38276-9-8"
+ transform="translate(-324,-461)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path35702-0-2"
+ d="m 292.5,459.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ style="opacity:0.95;fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ececec;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 292.5,459.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ id="path35704-0-5"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="459"
+ x="287"
+ height="2"
+ width="1"
+ id="rect35908-6-3"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;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:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35910-1-6"
+ width="0.75"
+ height="1"
+ x="286.25"
+ y="459" />
+ <rect
+ y="459"
+ x="288"
+ height="1"
+ width="0.75"
+ id="rect35912-3-1"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="opacity:0.9;display:inline;enable-background:new"
+ transform="translate(-484,-209.97631)"
+ id="g45582-8"
+ inkscape:transform-center-x="-0.78726"
+ inkscape:transform-center-y="2.2787562">
+ <path
+ style="opacity:0.95;fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 452.5,218.47631 -1,-1 -2,2 -2,-2 -1,1.02369"
+ id="path45584-6"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path45586-2"
+ d="m 452.5,218.47631 -1,-1 -2,2 -2,-2 -1,1.02369"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45588-1"
+ width="1"
+ height="1.4999862"
+ x="449"
+ y="218.4763" />
+ <rect
+ y="217.9763"
+ x="448"
+ height="0.99998617"
+ width="1"
+ id="rect45590-4"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;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:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45592-6"
+ width="1"
+ height="0.99998617"
+ x="447"
+ y="216.9763" />
+ <rect
+ y="217.9763"
+ x="446"
+ height="0.99998617"
+ width="1"
+ id="rect45594-2"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;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:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45596-9"
+ width="1"
+ height="0.99998617"
+ x="452"
+ y="217.9763" />
+ <rect
+ y="216.9763"
+ x="451"
+ height="0.99998617"
+ width="1"
+ id="rect45598-1"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;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:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45600-5"
+ width="1"
+ height="0.99998617"
+ x="450"
+ y="217.9763" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.3350147,0,0,0.3350147,-35.55948,137.66413)"
+ id="g29713-0"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ff541f;fill-opacity:1;fill-rule:nonzero;stroke:#320b00;stroke-width:3.58193231;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="path29715-3"
+ 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
+ transform="matrix(-0.6011908,-0.06817113,0.06852359,-0.6012277,199.77148,303.44348)"
+ 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="path29717-6"
+ style="opacity:0.6;fill:url(#linearGradient33126-9);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ 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.7;fill:none;stroke:url(#linearGradient33128-2);stroke-width:6.6867547;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:new"
+ id="path29719-4"
+ 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"
+ transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24982-9"
+ transform="translate(21,273)">
+ <rect
+ y="73"
+ x="47"
+ height="16"
+ width="16"
+ id="rect24980-2"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ clip-path="none"
+ mask="none"
+ id="g24568-9"
+ transform="translate(93,198.04787)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;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 -44.5,-117.48534 c 0,1 1,3 5.5,3 5.25,0 7.5,-3.26466 7.5,-6.01466 0,-1.5 -0.5,-2.25 -1,-3"
+ id="path24570-3"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24572-4"
+ mask="url(#mask43050-6)"
+ transform="translate(-22,0)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -11.5,-110.54787 c 2.25,-1.5 2,-3.45213 2,-4.20213 0,-1.6875 -2.25,-5.75 -7.5,-5.75 -4.5,0 -5.5,2 -5.5,3"
+ id="path24574-4"
+ sodipodi:nodetypes="cssz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssz"
+ id="path24576-0"
+ d="m -11.5,-110.54787 c 2.25,-1.5 2,-3.45213 2,-4.20213 0,-1.6875 -2.25,-5.75 -7.5,-5.75 -4.5,0 -5.5,2 -5.5,3"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.65;fill:none;stroke:url(#radialGradient24295-1);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -11.5,-110.54787 c 2.25,-1.5 2,-3.45213 2,-4.20213 0,-1.6875 -2.25,-5.75 -7.5,-5.75 -4.5,0 -5.5,2 -5.5,3"
+ id="path24578-5"
+ sodipodi:nodetypes="cssz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssz"
+ id="path24580-9"
+ d="m -11.5,-110.54787 c 2.5,-1.5 2,-3.45213 2,-4.20213 0,-1.6875 -2.25,-5.75 -7.5,-5.75 -4.5,0 -5.5,2 -5.5,3"
+ style="opacity:0.65;fill:none;stroke:url(#radialGradient24297-0);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24582-6"
+ sodipodi:cx="-10.5"
+ 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"
+ transform="matrix(1,0,0,1.4166681,-22,49.0835)" />
+ <g
+ id="g24584-3">
+ <rect
+ y="-124.50001"
+ x="-39.75"
+ height="14.999989"
+ width="2.5"
+ id="rect24586-4"
+ style="fill:#821b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ff9d7d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24588-2"
+ width="1"
+ height="14.999989"
+ x="-39"
+ y="-124.50001" />
+ <rect
+ style="fill:url(#radialGradient24299-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24590-8"
+ width="2"
+ height="14.999989"
+ x="-39.5"
+ y="-124.50001" />
+ </g>
+ <path
+ sodipodi:nodetypes="cssc"
+ id="path24592-8"
+ d="m -44.5,-117.48534 c 0,1 1,3 5.5,3 5.25,0 7.5,-3.26466 7.5,-6.01466 0,-1.5 -0.5,-2.25 -1,-3"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer6"
+ inkscape:label="Python icons"
+ style="display:none">
+ <g
+ style="display:inline;enable-background:new"
+ id="g30250-6"
+ transform="matrix(-1,0,0,1,788.49395,-2.4863553)" />
+ <g
+ id="g59188"
+ transform="translate(441,-963.36218)"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect59190"
+ width="16"
+ height="16"
+ x="26"
+ y="1036.3622" />
+ <g
+ transform="translate(-727,832.3622)"
+ id="g59192"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient106804);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 756.16666,204.50001 8.33334,-1e-5 0,13.99999 -11,1e-5 -10e-6,-10.99999 2.66667,-3 z"
+ id="path59194"
+ 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="path59196"
+ d="m 756.16666,204.50001 8.33334,-1e-5 0,13.99999 -11,1e-5 -10e-6,-10.99999 2.66667,-3 z"
+ style="opacity:0.3;fill:url(#radialGradient106806);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="path59198"
+ style="fill:none;stroke:url(#linearGradient106808);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 5.5,0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path59200"
+ 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="path59202"
+ 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,11.49999 11,-1e-5 0,-13.99999 -8.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(#linearGradient106810);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path59204" />
+ </g>
+ <g
+ id="g59206"
+ transform="translate(26,2.12e-5)">
+ <g
+ transform="translate(42,3.0002)"
+ id="g59208">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#4381b3;fill-opacity:1;stroke:none"
+ d="m -32.5,1036.8622 c -3,0 -3,1.5128 -3,2.0128 l 0,0.9872 -0.5,0 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.9988 2.25,3 2.5,3 l 0.5,0 0,-1 c 0,-1.1046 0.89543,-2 2,-2 l 2,-0.013 c 1.10457,0 2,-0.8954 2,-2 l 0,-1.9872 c 0,-0.5 0,-2 -3,-2 l 0,0 0,2e-4 z"
+ id="path59210"
+ sodipodi:nodetypes="ccccsccccccccc" />
+ <rect
+ style="opacity:0.01000001;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="rect59212"
+ width="0.99999928"
+ height="1.0468764"
+ x="-34"
+ y="1038.3153" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsccccccccc"
+ id="path59214"
+ d="m -32.5,1048.8622 c 3,0 3,-1.5128 3,-2.0128 l 0,-0.9872 0.5,0 c 0.25,0 2.5,-10e-4 2.5,-3 0,-2.9988 -2.25,-3 -2.5,-3 l -0.5,0 0,1 c 0,1.1046 -0.89543,2 -2,2 l -2,0.013 c -1.10457,0 -2,0.8954 -2,2 l 0,1.9872 c 0,0.5 0,2 3,2 l 0,0 0,-2e-4 z"
+ style="fill:#ffd43b;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="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m -32.5,1036.8622 c -3,0 -3,1 -3,2.0128 l 0,0.9872 3.5,0 -4,0.013 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.9988 2.25,3 2.5,3 l 0.5,0 0,1 c 0,0.9872 0,1.9872 3,1.9872 3,0 3,-1.0128 3,-2 l 0,-1 -2.5,0 3,0 c 0.25,0 2.5,-10e-4 2.5,-3 0,-2.9988 -2.25,-3 -2.5,-3 l -0.5,0 0,-1 c 0,-1.0128 0,-2 -3,-2 l 0,-2e-4 z"
+ id="path59216"
+ sodipodi:nodetypes="cccccscccsccccscccz" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;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 -29.5,1039.8622 0,1 c 0,1.1046 -0.89543,2 -2,2 l -2,0 c -1.10457,0 -2,0.8954 -2,2 l 0,1"
+ id="path59218"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cszs"
+ id="path59220"
+ d="m -30.5,1041.3622 0,-2.5 c 0,-0.5128 0.25,-1 -2,-1 -2.15993,0 -1.99997,0.4872 -2,1"
+ style="fill:none;stroke:url(#linearGradient106812);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient106814);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m -32.5,1040.8494 -3.49995,0.013 c -1.00005,0 -1.50005,0.7372 -1.5,2 5e-5,1.285 0.49995,2 1.5,2"
+ id="path59222"
+ sodipodi:nodetypes="cszs" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -34.5,1044.8494 c 0,-0.5 0.5,-1 1,-1 l 2,0.013 c 1.64438,0 3,-1.3428 3,-2.9872 m -6,3.9744 0,3.5"
+ style="fill:none;stroke:url(#linearGradient106816);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path59224" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path59226"
+ style="fill:none;stroke:url(#linearGradient106818);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -31.5,1046.8494 1,0.013" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(172,-563.36218)"
+ id="g3978-5">
+ <rect
+ style="opacity:0;fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect3980-2"
+ width="16"
+ height="15.999996"
+ x="211"
+ y="594.36218"
+ rx="0" />
+ <path
+ style="fill:#5590bf;fill-opacity:1;stroke:none"
+ d="m 219,594.875 c -3.5,10e-6 -3.5,1.5 -3.5,2 l 0,2 -0.5,0 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.99883 2.25,2.99999 2.5,3 l 0.5,0 0,-1 c 0,-1.10457 0.89543,-2 2,-2 l 3,0 c 1.10457,0 2,-0.89543 2,-2 l 0,-3 c 0,-0.5 0,-2.00001 -3.5,-2 z"
+ id="path3982-7"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.01000001;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="rect3984-6"
+ width="0.99999928"
+ height="1.0468764"
+ x="217"
+ y="596.31531" />
+ <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="rect3986-1"
+ width="0.99999928"
+ height="1.0000014"
+ x="217"
+ y="596.36218" />
+ <path
+ id="path3988-4"
+ d="m 219,608.86218 c 3.5,-10e-6 3.5,-1.5 3.5,-2 l 0,-2 0.5,0 c 0.25,0 2.5,-10e-4 2.5,-3 0,-2.99883 -2.25,-2.99999 -2.5,-3 l -0.5,0 0,1 c 0,1.10457 -0.89543,2 -2,2 l -3,0 c -1.10457,0 -2,0.89543 -2,2 l 0,3 c 0,0.5 0,2.00001 3.5,2 z"
+ style="fill:#ffd43b;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
+ y="606.36218"
+ x="220"
+ height="1.0000014"
+ width="0.99999928"
+ id="rect3990-2"
+ 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" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 219,594.875 c -3.5,10e-6 -3.5,0.98718 -3.5,2 l 0,1.98718 3.5,0 -4,0.0128 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.99883 2.25,2.99999 2.5,3 l 0.5,0 0,2 c 0,0.9872 0,2.00001 3.5,2 3.5,-1e-5 3.5,-1.0128 3.5,-2 l 0,-2.0128 -3.5,0 4,0.0128 c 0.25,0 2.5,-0.001 2.5,-3 0,-2.99883 -2.25,-2.99999 -2.5,-3 l -0.5,0 0,-2 c 0,-1.0128 0,-2.00001 -3.5,-2 l 0,2e-5 0,0 z"
+ id="path3992-3"
+ sodipodi:nodetypes="cccccscccsccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;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 222.5,598.86218 0,1 c 0,1.10457 -0.89543,2 -2,2 l -3,0 c -1.10457,0 -2,0.89543 -2,2 l 0,1"
+ id="path3994-2"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cszsc"
+ id="path3996-2"
+ d="m 221.5,600.86218 -5e-5,-3.98718 c -1e-5,-0.51282 0.23494,-0.98725 -2.49995,-1 -2.75,-0.0128 -2.49992,0.48718 -2.49995,1 l -5e-5,0.98718"
+ style="fill:none;stroke:url(#linearGradient106820);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient106822);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 218.5,599.86218 -3.49995,0.0128 c -1.00005,0.004 -1.50005,0.73718 -1.5,2 5e-5,1.285 0.49995,2 1.5,2"
+ id="path3998-16"
+ sodipodi:nodetypes="cszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 216.5,603.86218 c 0,-0.5 0.5,-1 1,-1 l 3,0 c 1.64438,0 3,-1.3428 3,-2.98718 m -7,3.98718 0,3.5"
+ style="fill:none;stroke:url(#linearGradient106824);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path4000-8"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path4002-5"
+ style="fill:none;stroke:url(#linearGradient106826);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.5,605.86218 2.00005,0.0128"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/release/datafiles/blender_icons16.png b/release/datafiles/blender_icons16.png
new file mode 100644
index 00000000000..a185192042e
--- /dev/null
+++ b/release/datafiles/blender_icons16.png
Binary files differ
diff --git a/release/datafiles/blender_icons32.png b/release/datafiles/blender_icons32.png
new file mode 100644
index 00000000000..050743ea094
--- /dev/null
+++ b/release/datafiles/blender_icons32.png
Binary files differ
diff --git a/release/datafiles/fonts/droidsans.ttf.gz b/release/datafiles/fonts/droidsans.ttf.gz
index 439515e5bb4..a0e7502cc1f 100644
--- a/release/datafiles/fonts/droidsans.ttf.gz
+++ b/release/datafiles/fonts/droidsans.ttf.gz
Binary files differ
diff --git a/release/datafiles/matcaps/license.txt b/release/datafiles/matcaps/license.txt
new file mode 100644
index 00000000000..358c8dcd832
--- /dev/null
+++ b/release/datafiles/matcaps/license.txt
@@ -0,0 +1,3 @@
+These matcap images are licensed as GNU GPL 2 or later, like the rest of Blender's code.
+
+Thanks to Kent Trammell, Aidy Burrows, John Herreno , Terry Wallwork and David Silverman for making the pictures.
diff --git a/release/datafiles/matcaps/mc01.jpg b/release/datafiles/matcaps/mc01.jpg
new file mode 100644
index 00000000000..8c7aef287ee
--- /dev/null
+++ b/release/datafiles/matcaps/mc01.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc02.jpg b/release/datafiles/matcaps/mc02.jpg
new file mode 100644
index 00000000000..11deddfeaed
--- /dev/null
+++ b/release/datafiles/matcaps/mc02.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc03.jpg b/release/datafiles/matcaps/mc03.jpg
new file mode 100644
index 00000000000..64d992fb61a
--- /dev/null
+++ b/release/datafiles/matcaps/mc03.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc04.jpg b/release/datafiles/matcaps/mc04.jpg
new file mode 100644
index 00000000000..42be580ee93
--- /dev/null
+++ b/release/datafiles/matcaps/mc04.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc05.jpg b/release/datafiles/matcaps/mc05.jpg
new file mode 100644
index 00000000000..586d233ef31
--- /dev/null
+++ b/release/datafiles/matcaps/mc05.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc06.jpg b/release/datafiles/matcaps/mc06.jpg
new file mode 100644
index 00000000000..657883d0866
--- /dev/null
+++ b/release/datafiles/matcaps/mc06.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc07.jpg b/release/datafiles/matcaps/mc07.jpg
new file mode 100644
index 00000000000..372caf7e87c
--- /dev/null
+++ b/release/datafiles/matcaps/mc07.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc08.jpg b/release/datafiles/matcaps/mc08.jpg
new file mode 100644
index 00000000000..50eec402812
--- /dev/null
+++ b/release/datafiles/matcaps/mc08.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc09.jpg b/release/datafiles/matcaps/mc09.jpg
new file mode 100644
index 00000000000..e05d441aaf9
--- /dev/null
+++ b/release/datafiles/matcaps/mc09.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc10.jpg b/release/datafiles/matcaps/mc10.jpg
new file mode 100644
index 00000000000..ab82f17bb93
--- /dev/null
+++ b/release/datafiles/matcaps/mc10.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc11.jpg b/release/datafiles/matcaps/mc11.jpg
new file mode 100644
index 00000000000..053550f082c
--- /dev/null
+++ b/release/datafiles/matcaps/mc11.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc12.jpg b/release/datafiles/matcaps/mc12.jpg
new file mode 100644
index 00000000000..beb16f3742e
--- /dev/null
+++ b/release/datafiles/matcaps/mc12.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc13.jpg b/release/datafiles/matcaps/mc13.jpg
new file mode 100644
index 00000000000..7fb8fa58e8f
--- /dev/null
+++ b/release/datafiles/matcaps/mc13.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc14.jpg b/release/datafiles/matcaps/mc14.jpg
new file mode 100644
index 00000000000..ba868d2f95a
--- /dev/null
+++ b/release/datafiles/matcaps/mc14.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc15.jpg b/release/datafiles/matcaps/mc15.jpg
new file mode 100644
index 00000000000..b10ea326a42
--- /dev/null
+++ b/release/datafiles/matcaps/mc15.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc16.jpg b/release/datafiles/matcaps/mc16.jpg
new file mode 100644
index 00000000000..c6ce02d59df
--- /dev/null
+++ b/release/datafiles/matcaps/mc16.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc17.jpg b/release/datafiles/matcaps/mc17.jpg
new file mode 100644
index 00000000000..14f15f70460
--- /dev/null
+++ b/release/datafiles/matcaps/mc17.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc18.jpg b/release/datafiles/matcaps/mc18.jpg
new file mode 100644
index 00000000000..db572856b07
--- /dev/null
+++ b/release/datafiles/matcaps/mc18.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc19.jpg b/release/datafiles/matcaps/mc19.jpg
new file mode 100644
index 00000000000..56d2efb1734
--- /dev/null
+++ b/release/datafiles/matcaps/mc19.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc20.jpg b/release/datafiles/matcaps/mc20.jpg
new file mode 100644
index 00000000000..002a0910dd9
--- /dev/null
+++ b/release/datafiles/matcaps/mc20.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc21.jpg b/release/datafiles/matcaps/mc21.jpg
new file mode 100644
index 00000000000..cb2fea573b8
--- /dev/null
+++ b/release/datafiles/matcaps/mc21.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc22.jpg b/release/datafiles/matcaps/mc22.jpg
new file mode 100644
index 00000000000..2fc71b98c5a
--- /dev/null
+++ b/release/datafiles/matcaps/mc22.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc23.jpg b/release/datafiles/matcaps/mc23.jpg
new file mode 100644
index 00000000000..3793c0fcaa5
--- /dev/null
+++ b/release/datafiles/matcaps/mc23.jpg
Binary files differ
diff --git a/release/datafiles/matcaps/mc24.jpg b/release/datafiles/matcaps/mc24.jpg
new file mode 100644
index 00000000000..2a9618d8fe1
--- /dev/null
+++ b/release/datafiles/matcaps/mc24.jpg
Binary files differ
diff --git a/release/datafiles/preview_cycles.blend b/release/datafiles/preview_cycles.blend
new file mode 100644
index 00000000000..11bf8bbb7b8
--- /dev/null
+++ b/release/datafiles/preview_cycles.blend
Binary files differ
diff --git a/release/datafiles/prvicons.sh b/release/datafiles/prvicons.sh
new file mode 100755
index 00000000000..144dd9da362
--- /dev/null
+++ b/release/datafiles/prvicons.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# This script updates icons from the SVG file
+
+inkscape prvicons.svg --without-gui --export-png=prvicons.png
diff --git a/release/datafiles/prvicons.svg b/release/datafiles/prvicons.svg
new file mode 100644
index 00000000000..d373410db73
--- /dev/null
+++ b/release/datafiles/prvicons.svg
@@ -0,0 +1,19741 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="192"
+ height="192"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.3.1 r9886"
+ version="1.0"
+ sodipodi:docname="prvicons.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ style="display:inline;enable-background:new"
+ inkscape:export-filename="blender_icons.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <title
+ id="title49470">Blender icons v. 2.5.06</title>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient30958">
+ <stop
+ id="stop30960"
+ offset="0"
+ style="stop-color:#fff9cf;stop-opacity:1;" />
+ <stop
+ id="stop30962"
+ offset="1"
+ style="stop-color:#c7bc52;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29312">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29314" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29316" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29304">
+ <stop
+ style="stop-color:#11233f;stop-opacity:1;"
+ offset="0"
+ id="stop29306" />
+ <stop
+ style="stop-color:#162d50;stop-opacity:0;"
+ offset="1"
+ id="stop29308" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27896">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27898" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27900" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27854">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27856" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27858" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24343">
+ <stop
+ id="stop24345"
+ offset="0"
+ style="stop-color:#184990;stop-opacity:1;" />
+ <stop
+ id="stop24347"
+ offset="1"
+ style="stop-color:#c1d5f3;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25417">
+ <stop
+ id="stop25419"
+ offset="0"
+ style="stop-color:#60553b;stop-opacity:1;" />
+ <stop
+ id="stop25421"
+ offset="1"
+ style="stop-color:#b0a17f;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25108">
+ <stop
+ id="stop25110"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop25112"
+ offset="1"
+ style="stop-color:#c6c6c6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient43807">
+ <stop
+ style="stop-color:#e31b1b;stop-opacity:1;"
+ offset="0"
+ id="stop43809" />
+ <stop
+ style="stop-color:#930000;stop-opacity:1;"
+ offset="1"
+ id="stop43811" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient38845">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38847" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38849" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38831">
+ <stop
+ style="stop-color:#182b42;stop-opacity:1;"
+ offset="0"
+ id="stop38833" />
+ <stop
+ id="stop38836"
+ offset="0.38971797"
+ style="stop-color:#598ac7;stop-opacity:1;" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1;"
+ offset="1"
+ id="stop38838" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38256">
+ <stop
+ id="stop38258"
+ offset="0"
+ style="stop-color:#e7e0c7;stop-opacity:1;" />
+ <stop
+ id="stop38260"
+ offset="1"
+ style="stop-color:#f1eddf;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient71814">
+ <stop
+ style="stop-color:#6e0d00;stop-opacity:1;"
+ offset="0"
+ id="stop71816" />
+ <stop
+ style="stop-color:#6f2913;stop-opacity:0;"
+ offset="1"
+ id="stop71818" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37667">
+ <stop
+ id="stop37669"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop37671"
+ offset="1"
+ style="stop-color:black;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39080">
+ <stop
+ style="stop-color:#1a2a3d;stop-opacity:1;"
+ offset="0"
+ id="stop39082" />
+ <stop
+ id="stop39084"
+ offset="0.5"
+ style="stop-color:#95b0d1;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop39086" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40703">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37925">
+ <stop
+ id="stop37927"
+ offset="0"
+ style="stop-color:#e7cbab;stop-opacity:1;" />
+ <stop
+ id="stop37929"
+ offset="1"
+ style="stop-color:#af7333;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient36273">
+ <stop
+ id="stop36275"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35411">
+ <stop
+ id="stop35414"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31356">
+ <stop
+ id="stop31358"
+ offset="0"
+ style="stop-color:#1a1a1a;stop-opacity:1" />
+ <stop
+ id="stop31360"
+ offset="1"
+ style="stop-color:#1a1a1a;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient28107"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7228842,8.5733105e-8,-9.4831885e-8,0.7995973,71.917045,14.582004)"
+ cx="256.49512"
+ cy="81.396774"
+ fx="256.49512"
+ fy="81.396774"
+ r="3.779551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28105"
+ gradientUnits="userSpaceOnUse"
+ x1="875.73486"
+ y1="422.77902"
+ x2="885.04938"
+ y2="427.01648" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28887"
+ id="linearGradient28103"
+ gradientUnits="userSpaceOnUse"
+ x1="873.09998"
+ y1="422.09964"
+ x2="881.01172"
+ y2="429.23453" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28101"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.6572588,1.2500456,-1.6473175,2.2058465,774.83033,-697.31982)"
+ cx="76.180473"
+ cy="500.20651"
+ fx="76.180473"
+ fy="500.20651"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28099"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient28887">
+ <stop
+ style="stop-color:#2158a7;stop-opacity:1;"
+ offset="0"
+ id="stop28889" />
+ <stop
+ style="stop-color:#2f73d5;stop-opacity:0.19607843;"
+ offset="1"
+ id="stop28891" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient44421"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient44557"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ id="linearGradient24168">
+ <stop
+ id="stop24170"
+ offset="0"
+ style="stop-color:#182437;stop-opacity:1;" />
+ <stop
+ id="stop24172"
+ offset="1"
+ style="stop-color:#2b4163;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24144">
+ <stop
+ id="stop24146"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.17958513"
+ id="stop24148" />
+ <stop
+ id="stop24150"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24101">
+ <stop
+ style="stop-color:#643400;stop-opacity:1;"
+ offset="0"
+ id="stop24103" />
+ <stop
+ id="stop24105"
+ offset="0.22606115"
+ style="stop-color:#ed983d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#fff0d5;stop-opacity:1;"
+ offset="1"
+ id="stop24107" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24081">
+ <stop
+ id="stop24083"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.3167825"
+ id="stop24085" />
+ <stop
+ id="stop24087"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23302">
+ <stop
+ id="stop23304"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.39332664"
+ id="stop23306" />
+ <stop
+ id="stop23308"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24735">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop24737" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop24739" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24727">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24729" />
+ <stop
+ id="stop24731"
+ offset="0.77520341"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24733" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24711">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24713" />
+ <stop
+ id="stop24715"
+ offset="0.21609697"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24717" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24695">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24697" />
+ <stop
+ id="stop24699"
+ offset="0.60401857"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24701" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24687">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24689" />
+ <stop
+ id="stop24691"
+ offset="0.59630167"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24693" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681" />
+ <stop
+ id="stop24683"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24671">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24673" />
+ <stop
+ id="stop24675"
+ offset="0.29527253"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24677" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23705">
+ <stop
+ id="stop23707"
+ offset="0"
+ style="stop-color:#d4d2bf;stop-opacity:1;" />
+ <stop
+ id="stop23709"
+ offset="1"
+ style="stop-color:#857f5d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23906">
+ <stop
+ id="stop23908"
+ offset="0"
+ style="stop-color:#ff921d;stop-opacity:1;" />
+ <stop
+ id="stop23910"
+ offset="1"
+ style="stop-color:#ffa751;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42459">
+ <stop
+ style="stop-color:#e7dfab;stop-opacity:1;"
+ offset="0"
+ id="stop42461" />
+ <stop
+ style="stop-color:#af9d33;stop-opacity:1;"
+ offset="1"
+ id="stop42463" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287"
+ y1="-276.1875"
+ x2="-281.4375"
+ y2="-271.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="171.42436"
+ y1="259.71194"
+ x2="170.20523"
+ y2="244.96393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24246"
+ gradientUnits="userSpaceOnUse"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(186,-105)"
+ x1="246.12868"
+ y1="283.63254"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287.56247"
+ y1="-276.71042"
+ x2="-282.59851"
+ y2="-271.35284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient24276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="190.33647"
+ y1="266.7905"
+ x2="170.9689"
+ y2="247.58694" />
+ <linearGradient
+ id="linearGradient24143">
+ <stop
+ id="stop24145"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669" />
+ <stop
+ id="stop24147"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24687"
+ id="linearGradient24238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,304.84783,-86.57833)"
+ x1="120.2969"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ id="linearGradient24642">
+ <stop
+ style="stop-color:#d0dbe8;stop-opacity:1;"
+ offset="0"
+ id="stop24644" />
+ <stop
+ style="stop-color:#6ca3e9;stop-opacity:0;"
+ offset="1"
+ id="stop24646" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24632">
+ <stop
+ style="stop-color:#28394f;stop-opacity:1;"
+ offset="0"
+ id="stop24634" />
+ <stop
+ id="stop24636"
+ offset="0.17637014"
+ style="stop-color:#0d386a;stop-opacity:0.78431374;" />
+ <stop
+ id="stop24638"
+ offset="0.35274029"
+ style="stop-color:#18437d;stop-opacity:0.47058824;" />
+ <stop
+ style="stop-color:#154e94;stop-opacity:0;"
+ offset="1"
+ id="stop24640" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="radialGradient23167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9934369,-0.1143813,0.1033636,0.8977446,-30.451879,30.134649)"
+ cx="-0.10810681"
+ cy="294.60239"
+ fx="-0.10810681"
+ fy="294.60239"
+ r="6.6750002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23201"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-61,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.25"
+ y2="245" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.5"
+ y2="245" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23189">
+ <g
+ transform="translate(-28,49)"
+ id="g23193">
+ <rect
+ y="237"
+ x="22"
+ height="16"
+ width="9"
+ id="rect23195"
+ style="fill:url(#linearGradient23199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ style="fill:url(#linearGradient23201);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23197"
+ width="9"
+ height="16"
+ x="-38"
+ y="237" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24208"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24206"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23379"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient23377"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient23375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="52.06274"
+ y1="96.767769"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient23373"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ id="linearGradient23974">
+ <stop
+ id="stop23976"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40983">
+ <stop
+ style="stop-color:#6a9ae0;stop-opacity:1;"
+ offset="0"
+ id="stop40985" />
+ <stop
+ style="stop-color:#5189db;stop-opacity:0;"
+ offset="1"
+ id="stop40987" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23280"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23278"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient23276"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient23274"
+ gradientUnits="userSpaceOnUse"
+ x1="144.8255"
+ y1="132.15414"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ id="linearGradient30777"
+ inkscape:collect="always">
+ <stop
+ id="stop30779"
+ offset="0"
+ style="stop-color:#acacac;stop-opacity:1" />
+ <stop
+ id="stop30781"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29485">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop29487" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop29489" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.55821538"
+ width="2.1164308"
+ y="-1.0219563"
+ height="3.0439126"
+ id="filter20578"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="2.0410255"
+ id="feGaussianBlur20580" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath20586">
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34889"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ 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(1.870472,0.1894819,-0.6587894,2.4281336,319.59052,-798.11661)" />
+ </clipPath>
+ <radialGradient
+ id="aigrd2"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop15566" />
+ <stop
+ offset="1.0000000"
+ style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
+ id="stop15568" />
+ </radialGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106">
+ <path
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850"
+ 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" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient58334">
+ <stop
+ id="stop58336"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8864">
+ <stop
+ id="stop8866"
+ offset="0"
+ style="stop-color:#b43214;stop-opacity:1;" />
+ <stop
+ id="stop8868"
+ offset="1"
+ style="stop-color:#e86830;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20324">
+ <stop
+ id="stop20326"
+ offset="0"
+ style="stop-color:#35241b;stop-opacity:1;" />
+ <stop
+ style="stop-color:#69390e;stop-opacity:0.8392157;"
+ offset="0.17637014"
+ id="stop20328" />
+ <stop
+ style="stop-color:#6c5b15;stop-opacity:0.67843139;"
+ offset="0.35274029"
+ id="stop20330" />
+ <stop
+ id="stop20332"
+ offset="1"
+ style="stop-color:#947b15;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37623">
+ <stop
+ id="stop37625"
+ offset="0"
+ style="stop-color:#e5e1ca;stop-opacity:1;" />
+ <stop
+ id="stop37627"
+ offset="1"
+ style="stop-color:#d6ca22;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient36116">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop36118" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop36120" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22852"
+ gradientUnits="userSpaceOnUse"
+ x1="133.94305"
+ y1="116.00471"
+ x2="117.29694"
+ y2="133.14267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22850"
+ gradientUnits="userSpaceOnUse"
+ x1="136.55727"
+ y1="125.87247"
+ x2="129.70895"
+ y2="118.00132" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22844"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ id="linearGradient22562">
+ <stop
+ style="stop-color:#001e50;stop-opacity:1;"
+ offset="0"
+ id="stop22564" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop22566" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient22842"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ id="linearGradient22556">
+ <stop
+ id="stop22558"
+ offset="0"
+ style="stop-color:#6a9bef;stop-opacity:1" />
+ <stop
+ style="stop-color:#bccee8;stop-opacity:0.58450705;"
+ offset="0.77941167"
+ id="stop22568" />
+ <stop
+ id="stop22560"
+ offset="1"
+ style="stop-color:#ccdaed;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22556"
+ id="linearGradient22840"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient22838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient22882">
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="0"
+ id="stop22884" />
+ <stop
+ id="stop22886"
+ offset="0.21233012"
+ style="stop-color:#323232;stop-opacity:0.49803922;" />
+ <stop
+ id="stop22888"
+ offset="0.54086536"
+ style="stop-color:#323232;stop-opacity:1;" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0.49803922;"
+ offset="0.83381736"
+ id="stop22890" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop22892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22880"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ id="linearGradient35407">
+ <stop
+ id="stop35409"
+ offset="0"
+ style="stop-color:#a17306;stop-opacity:1;" />
+ <stop
+ style="stop-color:#cca649;stop-opacity:1;"
+ offset="0.43277758"
+ id="stop35411" />
+ <stop
+ id="stop35413"
+ offset="1"
+ style="stop-color:#f9f5e9;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35391">
+ <stop
+ id="stop35393"
+ offset="0"
+ style="stop-color:#322800;stop-opacity:1;" />
+ <stop
+ id="stop35395"
+ offset="1"
+ style="stop-color:#6e4800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient34157">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop34159" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop34161" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient22457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-25.5"
+ y1="36.828632"
+ x2="-25.5"
+ y2="26.027344" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22455"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-354,-314.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22453"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-27.299919"
+ y1="37"
+ x2="-25.5"
+ y2="23.414351" />
+ <linearGradient
+ id="linearGradient21609">
+ <stop
+ id="stop21611"
+ offset="0"
+ style="stop-color:black;stop-opacity:1" />
+ <stop
+ id="stop21613"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21609"
+ id="linearGradient20961"
+ gradientUnits="userSpaceOnUse"
+ x1="162"
+ y1="103.71875"
+ x2="165"
+ y2="103.75" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask20957">
+ <rect
+ y="101"
+ x="162"
+ height="5"
+ width="8"
+ id="rect20959"
+ style="fill:url(#linearGradient20961);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32335"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient19900">
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:1;"
+ offset="0"
+ id="stop19902" />
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:0;"
+ offset="1"
+ id="stop19904" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18105">
+ <stop
+ id="stop18107"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18056">
+ <stop
+ id="stop18058"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18060"
+ offset="1"
+ style="stop-color:#295498;stop-opacity:0.34057972;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19625">
+ <stop
+ id="stop19627"
+ offset="0"
+ style="stop-color:#2258a6;stop-opacity:1;" />
+ <stop
+ id="stop19629"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient20217"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient18821">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient29149">
+ <stop
+ id="stop29151"
+ offset="0"
+ style="stop-color:#76adff;stop-opacity:1;" />
+ <stop
+ id="stop29153"
+ offset="1"
+ style="stop-color:#a5c9ff;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient21820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient21818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21816"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21814"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient21741"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient21773"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9281768,0,0,0.9971589,401.42265,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22166"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22164"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22162"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22160"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22158"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient22156"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22154"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15809">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15811" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop15813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15437">
+ <stop
+ id="stop15439"
+ offset="0"
+ style="stop-color:#20529e;stop-opacity:1;" />
+ <stop
+ id="stop15441"
+ offset="1"
+ style="stop-color:#1d3f71;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15425">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15427" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14262">
+ <stop
+ id="stop14264"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath17188">
+ <path
+ style="fill:#d3d7cf;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 240.5,-19.90625 c -1.87005,0 -3.40625,1.536202 -3.40625,3.40625 l 0,2 c 0,1.87005 1.53621,3.40625 3.40625,3.40625 l 0,-2.8125 c -0.33932,0 -0.59375,-0.254431 -0.59375,-0.59375 l 0,-2 c 0,-0.339319 0.25443,-0.59375 0.59375,-0.59375 l 0,-2.8125 z"
+ id="path17190"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient18344">
+ <stop
+ style="stop-color:#6c6c6c;stop-opacity:1;"
+ offset="0"
+ id="stop18346" />
+ <stop
+ style="stop-color:#f0f0f0;stop-opacity:1;"
+ offset="1"
+ id="stop18348" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060">
+ <stop
+ id="stop5062"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient27957">
+ <stop
+ id="stop27959"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0.59290552"
+ id="stop27963" />
+ <stop
+ id="stop27961"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23647">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop23649" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop23651" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23390">
+ <stop
+ style="stop-color:#000000;stop-opacity:1.0000000"
+ offset="0.0000000"
+ id="stop23392" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000"
+ offset="1.0000000"
+ id="stop23400" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16359">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16361" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16363" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.26,-38.98429)"
+ x1="386.09836"
+ y1="230.09529"
+ x2="388.35962"
+ y2="248.10277" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15744"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="390.61163"
+ y1="229.34804"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15683"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.203777,0,0,0.903901,837.9645,-18.01568)"
+ x1="383.67041"
+ y1="225.94354"
+ x2="385.60632"
+ y2="248.55901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15681"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,839.2424,-18.01568)"
+ x1="391.80222"
+ y1="230.5647"
+ x2="387.94211"
+ y2="247.83209" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13545"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="137.11284"
+ y2="126.19643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15878"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient20756">
+ <stop
+ style="stop-color:#932200;stop-opacity:1;"
+ offset="0"
+ id="stop20758" />
+ <stop
+ style="stop-color:#f8420a;stop-opacity:1;"
+ offset="1"
+ id="stop20760" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient13543"
+ gradientUnits="userSpaceOnUse"
+ x1="126.45676"
+ y1="110.59049"
+ x2="134.94949"
+ y2="122.08995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15693"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="215.07817"
+ y1="109.00085"
+ x2="235.90916"
+ y2="121.88217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="217.22589"
+ y1="107.25085"
+ x2="235.90916"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15854"
+ gradientUnits="userSpaceOnUse"
+ x1="381.56296"
+ y1="234.59885"
+ x2="393"
+ y2="247.99632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient13639"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.987"
+ y1="259.26602"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52023"
+ gradientUnits="userSpaceOnUse"
+ x1="390.75"
+ y1="244.5312"
+ x2="395.9375"
+ y2="250.9062" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient14661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="400.88739"
+ y1="257.4874"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52025"
+ gradientUnits="userSpaceOnUse"
+ x1="391.01859"
+ y1="241.86644"
+ x2="396.79285"
+ y2="247.83134" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient15995"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.08661"
+ y1="257.41327"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15993"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15997"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ id="linearGradient47130">
+ <stop
+ style="stop-color:#ed7b00;stop-opacity:1;"
+ offset="0"
+ id="stop47132" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop47134" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52027"
+ gradientUnits="userSpaceOnUse"
+ x1="329.28757"
+ y1="244.97151"
+ x2="339.84518"
+ y2="254.18553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15436"
+ gradientUnits="userSpaceOnUse"
+ x1="319.75095"
+ y1="234.63918"
+ x2="333.94208"
+ y2="248.68198" />
+ <linearGradient
+ id="linearGradient32842">
+ <stop
+ style="stop-color:#183e75;stop-opacity:1;"
+ offset="0"
+ id="stop32844" />
+ <stop
+ style="stop-color:#1d3f71;stop-opacity:0;"
+ offset="1"
+ id="stop32846" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient13900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2541045,-1.3755453,0.900369,1.4754358,-3699.4512,2858.7)"
+ cx="2357.1072"
+ cy="826.77924"
+ fx="2357.1072"
+ fy="826.77924"
+ r="6.1896501" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40983"
+ id="linearGradient38692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2226.9963,823)"
+ x1="130.70599"
+ y1="18.44199"
+ x2="130.70599"
+ y2="21.94199" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15717"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15715"
+ gradientUnits="userSpaceOnUse"
+ x1="320.2735"
+ y1="25.109356"
+ x2="332.41409"
+ y2="37.468754" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15713"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15709"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="323.37836"
+ y1="30.3883"
+ x2="343.5636"
+ y2="53.758793" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15646"
+ gradientUnits="userSpaceOnUse"
+ x1="279.00009"
+ y1="-16.62501"
+ x2="291.93054"
+ y2="-6.3206272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15644"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-253)"
+ x1="25.437477"
+ y1="238.54002"
+ x2="51.01355"
+ y2="263.79816" />
+ <linearGradient
+ id="linearGradient20973">
+ <stop
+ id="stop20975"
+ offset="0"
+ style="stop-color:#15ff00;stop-opacity:1;" />
+ <stop
+ id="stop20977"
+ offset="1"
+ style="stop-color:#15ff00;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20962">
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:1;"
+ offset="0"
+ id="stop20965" />
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:0;"
+ offset="1"
+ id="stop20967" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20036">
+ <stop
+ style="stop-color:#ffb55e;stop-opacity:1;"
+ offset="0"
+ id="stop20038" />
+ <stop
+ style="stop-color:#ff8400;stop-opacity:0;"
+ offset="1"
+ id="stop20040" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15574"
+ gradientUnits="userSpaceOnUse"
+ x1="197.63152"
+ y1="169.14206"
+ x2="190.41687"
+ y2="160.02296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15358"
+ gradientUnits="userSpaceOnUse"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15362"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15360"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,39.669142,20)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14517"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3959732"
+ y1="216.62332"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16069"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="17.011419"
+ y2="82.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient16067"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,-440.36032,-147)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16063"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="6.9917974"
+ y1="219.61856"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16154"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16150"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.8504581"
+ y1="217.4549"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16174"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="2.911078"
+ y1="217.3624"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ id="linearGradient13998">
+ <stop
+ id="stop14000"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4343">
+ <stop
+ id="stop4345"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop4347"
+ offset="1"
+ style="stop-color:#fff9f9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,747.50001,337.33345)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15053"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.166667,-441,-81.66662)"
+ x1="43.647511"
+ y1="164.125"
+ x2="75.731438"
+ y2="164.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15705"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15703"
+ gradientUnits="userSpaceOnUse"
+ x1="146.80022"
+ y1="158.34668"
+ x2="150.08357"
+ y2="162.03282" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15701"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15699"
+ gradientUnits="userSpaceOnUse"
+ x1="122.84515"
+ y1="126.83902"
+ x2="149.88129"
+ y2="164.94562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15742"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="227.57907"
+ y1="118.47696"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="222.4996"
+ y1="110.37873"
+ x2="233.08319"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="230.95012"
+ y1="100.89436"
+ x2="230.74091"
+ y2="124.09359" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15778"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="135.54141"
+ y2="122.0597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15780"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10.767079)"
+ x1="132.35471"
+ y1="246.32236"
+ x2="129.81586"
+ y2="243.70523" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15774"
+ gradientUnits="userSpaceOnUse"
+ x1="103.53399"
+ y1="88.301094"
+ x2="136.3542"
+ y2="123.17216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15450"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15452"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15448"
+ gradientUnits="userSpaceOnUse"
+ x1="132.12782"
+ y1="246.32236"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15446"
+ gradientUnits="userSpaceOnUse"
+ x1="87.969383"
+ y1="69.87941"
+ x2="135.40274"
+ y2="121.19196" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15582"
+ gradientUnits="userSpaceOnUse"
+ x1="9.062501"
+ y1="117.46875"
+ x2="24.625006"
+ y2="131.65625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15584"
+ gradientUnits="userSpaceOnUse"
+ x1="28.607456"
+ y1="116.80592"
+ x2="43.766914"
+ y2="131.5226" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15124"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient15122"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16025"
+ gradientUnits="userSpaceOnUse"
+ x1="192.11751"
+ y1="122.12527"
+ x2="184.43379"
+ y2="112.34031" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.395521,0,0,-0.3955,275.223,171.0515)"
+ x1="213.51967"
+ y1="121.417"
+ x2="204.05295"
+ y2="111.7235" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.607961,0,0,0.607967,64.49194,51.63899)"
+ x1="213.53587"
+ y1="122.66508"
+ x2="203.33264"
+ y2="112.67535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15748"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="349.04059"
+ y1="143.70836"
+ x2="336.72485"
+ y2="117.00745" />
+ <linearGradient
+ id="linearGradient10585">
+ <stop
+ id="stop10587"
+ offset="0.0000000"
+ style="stop-color:#d7d7d7;stop-opacity:1.0000000;" />
+ <stop
+ id="stop10595"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4138">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop4140" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop4142" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31320">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12678">
+ <stop
+ id="stop12680"
+ offset="0"
+ style="stop-color:#d40000;stop-opacity:1" />
+ <stop
+ id="stop12682"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13991"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13520"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.401389,-3.2412)"
+ x1="130.59862"
+ y1="121.2412"
+ x2="142.29109"
+ y2="133.53448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23215"
+ x1="147.07098"
+ y1="134.18185"
+ x2="129.67148"
+ y2="115.54105"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient23178">
+ <stop
+ style="stop-color:#ff992b;stop-opacity:1;"
+ offset="0"
+ id="stop23180" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop23182" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13973">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13938">
+ <stop
+ id="stop13940"
+ offset="0"
+ style="stop-color:#6e0c00;stop-opacity:1;" />
+ <stop
+ id="stop13942"
+ offset="1"
+ style="stop-color:#ee3800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14232">
+ <stop
+ style="stop-color:#fff32a;stop-opacity:1;"
+ offset="0"
+ id="stop14234" />
+ <stop
+ style="stop-color:#fff551;stop-opacity:0;"
+ offset="1"
+ id="stop14236" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14418">
+ <stop
+ id="stop14420"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14935"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-26,2.9206276e-6)"
+ x1="474"
+ y1="73.999992"
+ x2="477.25"
+ y2="77.499992" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,1.4603138e-6)"
+ x1="474.84375"
+ y1="75"
+ x2="477.5"
+ y2="77.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18852"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18850"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18901"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(279.04534,461.00001)"
+ x1="151"
+ y1="-234"
+ x2="149.95467"
+ y2="-239.14549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.04419,461)"
+ x1="151"
+ y1="-234"
+ x2="150.25"
+ y2="-236.85815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.99885,461)"
+ x1="150.11926"
+ y1="-235.21587"
+ x2="145.20955"
+ y2="-241.85452" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,459)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17535"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17533"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17527"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18207">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18209" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop18211" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient18213"
+ x1="481.46063"
+ y1="219"
+ x2="519.44189"
+ y2="218.48816"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17506"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17504"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17502"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17500"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17498"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2078427,0,0,1.0516432,-357.40769,69.427229)"
+ x1="362.28571"
+ y1="-45.098213"
+ x2="352.46426"
+ y2="-54.124699" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18666">
+ <rect
+ y="6"
+ x="62.921577"
+ height="14.000001"
+ width="15.098035"
+ id="rect18668"
+ style="fill:url(#linearGradient18670);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15592"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15590"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="135.54628"
+ y2="120.58403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15596"
+ gradientUnits="userSpaceOnUse"
+ x1="124.52369"
+ y1="112.22441"
+ x2="131.10667"
+ y2="118.10129" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15594"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="134.62978"
+ y2="120.14633" />
+ <linearGradient
+ id="linearGradient14219">
+ <stop
+ id="stop14221"
+ offset="0"
+ style="stop-color:#ff8605;stop-opacity:1;" />
+ <stop
+ id="stop14223"
+ offset="1"
+ style="stop-color:#9c6700;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31456">
+ <stop
+ style="stop-color:#2b1600;stop-opacity:1;"
+ offset="0"
+ id="stop31458" />
+ <stop
+ style="stop-color:#6e3900;stop-opacity:0;"
+ offset="1"
+ id="stop31460" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19425">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop19427" />
+ <stop
+ id="stop19431"
+ offset="0.63109845"
+ style="stop-color:#fffffe;stop-opacity:0.65789473;" />
+ <stop
+ style="stop-color:#fffffe;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop19429" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30208">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop30210" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop30212" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15782"
+ gradientUnits="userSpaceOnUse"
+ x1="125.19086"
+ y1="125.66204"
+ x2="132.98256"
+ y2="118" />
+ <linearGradient
+ id="linearGradient9030">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542">
+ <stop
+ id="stop37544"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30124">
+ <stop
+ style="stop-color:#1d4a8c;stop-opacity:1;"
+ offset="0"
+ id="stop30126" />
+ <stop
+ style="stop-color:#c1d4f2;stop-opacity:1;"
+ offset="1"
+ id="stop30128" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15893">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop15895" />
+ <stop
+ id="stop15897"
+ offset="0.37679368"
+ style="stop-color:#b5ccf0;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b5ccf0;stop-opacity:1;"
+ offset="0.59786767"
+ id="stop15899" />
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="1"
+ id="stop15901" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24000">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop24002" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop24004" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient32998">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop33000" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop33002" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21372"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="radialGradient21517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.891843,0,0,0.909224,-173.99085,171.21624)"
+ cx="350.5"
+ cy="14.5"
+ fx="350.5"
+ fy="14.5"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21641"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="133.62564"
+ y2="120.24665" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21643"
+ gradientUnits="userSpaceOnUse"
+ x1="126.15096"
+ y1="113.21745"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20796"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(159.9998,-41.00751)"
+ x1="261.44702"
+ y1="234.6606"
+ x2="274.30609"
+ y2="247.73561" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20798"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(199.9999,105.99249)"
+ x1="235.46884"
+ y1="103"
+ x2="228.71886"
+ y2="94.53125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.2344713"
+ y1="215.76874"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21864"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="19.011419"
+ y2="86" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3268692"
+ y1="215.35608"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21904"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-237)"
+ x1="24.374985"
+ y1="238.33629"
+ x2="55.384842"
+ y2="269.1373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,16)"
+ x1="278.55817"
+ y1="-16.978563"
+ x2="291.577"
+ y2="-5.8786855" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient31650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.816279,0,-3.646264e-6,0.779872,56.32029,28.34496)"
+ cx="306.55292"
+ cy="11.818644"
+ fx="306.55292"
+ fy="11.818644"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="radialGradient31652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.580596,1.138426,-0.692447,0.961382,-175.3891,-329.6844)"
+ cx="312.80765"
+ cy="10.620173"
+ fx="312.80765"
+ fy="10.620173"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20962"
+ id="radialGradient31654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.48445,-0.00657397,0.00734631,1.660903,-154.1629,19.305572)"
+ cx="313.74268"
+ cy="15.619254"
+ fx="313.74268"
+ fy="15.619254"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20973"
+ id="radialGradient31656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.756245,0,-3.378096e-6,0.722516,72.63115,31.07857)"
+ cx="309.0571"
+ cy="15.518281"
+ fx="309.0571"
+ fy="15.518281"
+ r="4.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31664"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8579582,0,0,0.9285714,7.397998,-211.96428)"
+ x1="-6.3249049"
+ y1="205.0083"
+ x2="32.351238"
+ y2="248.75177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9569715,-1,0,259,351.18743)"
+ x1="347.6467"
+ y1="216.75188"
+ x2="345.98633"
+ y2="243.92201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166667,0,0,0.9166667,24.364541,-55.041665)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9297203,-1.2117965,0,305.73028,342.22894)"
+ x1="346.15555"
+ y1="218.2382"
+ x2="346.58698"
+ y2="238.44429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31694"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient31696"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="64.998215"
+ y1="90.951675"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,105.5221,92.482413)"
+ x1="257.0376"
+ y1="10.838325"
+ x2="277.61203"
+ y2="31.019331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31934"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7827973,0,0,0.9989462,77.082208,42.08484)"
+ x1="332.03717"
+ y1="68.624634"
+ x2="346.08932"
+ y2="83.002625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31936"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(262,-125)"
+ x1="79.329903"
+ y1="236"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient33666"
+ gradientUnits="userSpaceOnUse"
+ x1="124.14184"
+ y1="126.23546"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33668"
+ gradientUnits="userSpaceOnUse"
+ x1="125.45158"
+ y1="125.94608"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33670"
+ gradientUnits="userSpaceOnUse"
+ x1="142.97318"
+ y1="107.64013"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33681"
+ gradientUnits="userSpaceOnUse"
+ x1="139.93341"
+ y1="110.56118"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient33700"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55772"
+ y1="98.630066"
+ x2="123.9021"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10540"
+ gradientUnits="userSpaceOnUse"
+ x1="130.95198"
+ y1="117.09563"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient11333"
+ gradientUnits="userSpaceOnUse"
+ x1="119.1647"
+ y1="106.08605"
+ x2="133.01006"
+ y2="119.79803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-425,393.99999)"
+ x1="225.6198"
+ y1="5.7625732"
+ x2="236.47855"
+ y2="14.103563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient28077"
+ x1="306.26187"
+ y1="272"
+ x2="307"
+ y2="263.55374"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="431.05026"
+ y1="121.42467"
+ x2="446.26407"
+ y2="110.49417" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28528"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="442.69827"
+ y1="107.56771"
+ x2="450.27414"
+ y2="122.95798" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-474,158.25)"
+ x1="437.57828"
+ y1="104.34499"
+ x2="447.96875"
+ y2="117.90625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28532"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10982"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10984"
+ x1="212.04637"
+ y1="182.09375"
+ x2="222.35799"
+ y2="182.77524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11762"
+ x1="371.98389"
+ y1="203"
+ x2="376.48389"
+ y2="203"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11764"
+ x1="366.98389"
+ y1="203"
+ x2="370.98389"
+ y2="202.75"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11766"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient12427"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14219"
+ id="radialGradient12429"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5007214,0.3131662,-0.3623683,0.5793905,300.02235,-93.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16359"
+ id="linearGradient12602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,456.04574,-116.51416)"
+ x1="88.079262"
+ y1="66.110847"
+ x2="95.954262"
+ y2="58.272621" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient12114"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1438.0001,-418)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1830.2675,-33.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1397.7474,-388.72044)"
+ x1="1984.5453"
+ y1="828.21777"
+ x2="1978.11"
+ y2="829.35315" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12215"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12217"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient12305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="257.24991"
+ y1="147.38998"
+ x2="262.24991"
+ y2="152.46707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient12307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="258.08322"
+ y1="147.87068"
+ x2="264.16571"
+ y2="153.8233" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13046"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-161.99999)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13041">
+ <rect
+ style="fill:url(#linearGradient13046);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect13043"
+ width="7"
+ height="8"
+ x="276"
+ y="-12" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-145.93749)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13052">
+ <rect
+ y="4.0625"
+ x="276"
+ height="8"
+ width="7"
+ id="rect13054"
+ style="fill:url(#linearGradient13056);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="443.86667"
+ y1="133.98936"
+ x2="451.98389"
+ y2="143.58749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="453.61005"
+ y2="133.00301" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="449.14645"
+ y1="136.18045"
+ x2="453.24457"
+ y2="138.7879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14173"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="454.31345"
+ y2="133.62801" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient13112"
+ gradientUnits="userSpaceOnUse"
+ x1="133.42287"
+ y1="120.62622"
+ x2="126.67323"
+ y2="113.20281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13114"
+ gradientUnits="userSpaceOnUse"
+ x1="120.77391"
+ y1="106.19939"
+ x2="144.64095"
+ y2="129.62753" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16027"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8289081,0,0,2.1560411,236.27148,-864.45588)"
+ x1="212"
+ y1="435.59741"
+ x2="211.99998"
+ y2="435.32159" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16031"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1035181,0,0,1,158.18497,-359.77344)"
+ x1="229.6875"
+ y1="440.51562"
+ x2="238.53125"
+ y2="440.57812" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23390"
+ id="radialGradient16034"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.8126517,-0.04317018,0.04642643,1.9485655,-18.817545,-774.28453)"
+ cx="224.32494"
+ cy="441.84744"
+ fx="224.32494"
+ fy="441.84744"
+ r="6.7191267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient16036"
+ gradientUnits="userSpaceOnUse"
+ x1="211.99998"
+ y1="435.7319"
+ x2="211.99998"
+ y2="436.07974"
+ gradientTransform="matrix(0.9803611,0,0,2.1560411,204.16345,-864.45588)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16039"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(182,-359.75)"
+ x1="221.96414"
+ y1="439.75"
+ x2="238.87605"
+ y2="448.88205" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17337"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0008786,0,0,1.081555,-21.021535,-187.45087)"
+ x1="-12.839478"
+ y1="201"
+ x2="44.522621"
+ y2="256.70349" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.099576,0,0,1.0999923,190.46996,204.85062)"
+ x1="9.6310225"
+ y1="76"
+ x2="15"
+ y2="81" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,370.43125,-83.863716)"
+ x1="-5.6700387"
+ y1="250.87607"
+ x2="-46.452946"
+ y2="251.42462" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17714"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,280.08766,104.72255)"
+ x1="102.61966"
+ y1="50.742527"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient12655"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12658"
+ gradientUnits="userSpaceOnUse"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13527"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13529"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(68.016116,127.00002)"
+ x1="97.983887"
+ y1="127.99998"
+ x2="88.983887"
+ y2="115.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14570"
+ gradientUnits="userSpaceOnUse"
+ x1="94.485573"
+ y1="122.13319"
+ x2="89.207298"
+ y2="125.83332" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14572"
+ gradientUnits="userSpaceOnUse"
+ x1="88.560204"
+ y1="127.88263"
+ x2="94.011101"
+ y2="123.83599" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient47130"
+ id="linearGradient13699"
+ x1="-162.89217"
+ y1="245"
+ x2="-174.18907"
+ y2="224.99274"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26282"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26284"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26286"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26288"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14198"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15195"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient15209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15211"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15363"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9999519,0,0,0.9998051,-33.993941,254.01926)"
+ x1="101.21339"
+ y1="68.783279"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15365"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,40.331334,244.81698)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10585"
+ id="linearGradient15367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.032977,0,0,1,128.82015,107.77516)"
+ x1="12.330792"
+ y1="246.97107"
+ x2="41.654194"
+ y2="247.3784" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient15383"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14377"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient16640"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="85.874489"
+ y1="501.74075"
+ x2="26.561054"
+ y2="498.48148" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16642"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16644"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,300.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient16648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient32447"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30231"
+ gradientUnits="userSpaceOnUse"
+ x1="441.48248"
+ y1="105.03784"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient30233"
+ gradientUnits="userSpaceOnUse"
+ x1="445.37457"
+ y1="112.86145"
+ x2="425.92511"
+ y2="84.928581" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30235"
+ gradientUnits="userSpaceOnUse"
+ x1="440.68439"
+ y1="106.0996"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30237"
+ gradientUnits="userSpaceOnUse"
+ x1="440.34833"
+ y1="105.74502"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30239"
+ gradientUnits="userSpaceOnUse"
+ x1="440.7211"
+ y1="104.97093"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23302"
+ id="linearGradient30241"
+ gradientUnits="userSpaceOnUse"
+ x1="414.99771"
+ y1="-35"
+ x2="414.99771"
+ y2="-36.625011" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24081"
+ id="linearGradient30243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.00461"
+ y1="-34"
+ x2="415.94211"
+ y2="-37.718761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient30247"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.41162"
+ y1="-34.342831"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30249"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30326"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30328"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30330"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30332"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30334"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30336"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30338"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30340"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30342"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30344"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30346"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30348"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30394"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30396"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30398"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30400"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30402"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30404"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30406"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30408"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30414"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30416"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ 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">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m -44,358 0,14 14,-14 -14,0 z"
+ id="path17572"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18682"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.9230835,365.8517,-147.63686)"
+ x1="27.405855"
+ y1="189.20862"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18690"
+ gradientUnits="userSpaceOnUse"
+ x1="29.972469"
+ y1="164"
+ x2="29.972469"
+ y2="168"
+ gradientTransform="translate(359.05264,-81.98142)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="30.435225"
+ y1="202.99998"
+ x2="30.435225"
+ y2="251.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18756"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18779"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6923077,0,0,-0.6923079,29.049874,351.11545)"
+ x1="7.9951181"
+ y1="264.90152"
+ x2="32.267426"
+ y2="237.9342" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-122.98388,276)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5384613,0,0,0.538461,-189.69233,224.07704)"
+ x1="29.142912"
+ y1="161.42842"
+ x2="29.142912"
+ y2="252.42851" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.538461,-193.81309,224.07705)"
+ x1="29.871567"
+ y1="153.99983"
+ x2="29.871567"
+ y2="252.4285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.461541,-193.81309,236.42243)"
+ x1="29.871567"
+ y1="174.58366"
+ x2="29.871567"
+ y2="259.08319" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18854"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2500001,0,0,2.2000001,-102.35484,177)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.8000001,-122.98388,285.5)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.0000001,0,0,1.6000003,163.54205,53.499972)"
+ x1="-60.266121"
+ y1="74.0625"
+ x2="-54.766121"
+ y2="84.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32725"
+ gradientUnits="userSpaceOnUse"
+ x1="-88.0625"
+ y1="364"
+ x2="-44.983891"
+ y2="411.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-117.02574,313.78567)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient32729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6666675,0,0,0.6666633,-101.32265,336.66698)"
+ x1="61.983898"
+ y1="88.999977"
+ x2="89.770271"
+ y2="121.709" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-122.97299,306.4115)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient32749"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.081988,0,0,1.0833333,-123.05997,-52.467545)"
+ x1="326.72092"
+ y1="33.927608"
+ x2="352.03485"
+ y2="60.463093" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32751"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="-46.417774"
+ y1="1.9796312"
+ x2="-21.988398"
+ y2="27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32753"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0983862,0,0,1.0999999,-128.47957,-53.059225)"
+ x1="324.13901"
+ y1="28.882492"
+ x2="333.96365"
+ y2="39.250004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(18,0)"
+ x1="-51.6875"
+ y1="442.6875"
+ x2="-42.377892"
+ y2="452.20007" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17177"
+ gradientUnits="userSpaceOnUse"
+ x1="28.322077"
+ y1="160.10768"
+ x2="32.679554"
+ y2="164.34546" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient17179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-6.8461644e-7,-1.8,1.1087755,0.00352366,-193.46828,187.54551)"
+ cx="4.351675"
+ cy="81.592964"
+ fx="4.351675"
+ fy="81.592964"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18344"
+ id="radialGradient17181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5123107,0.9569981,-0.5028837,0.7946898,-131.57281,-236.33663)"
+ cx="244.14325"
+ cy="-14.13948"
+ fx="244.14325"
+ fy="-14.13948"
+ r="3.4000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17214"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17216"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17218"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2859748,0,0,1,-272.87621,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4289612,0,0,1,-326.93899,144.5)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17222"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17224"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17226"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2868892,0,0,1,-644.69395,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="36.247395"
+ y2="249.62102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18712"
+ 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
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient18721"
+ 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"
+ id="linearGradient18728"
+ 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"
+ id="linearGradient18765"
+ 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="#linearGradient34157"
+ id="linearGradient35488"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35490"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient35492"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient35494"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35967"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.656002,0,0,0.656002,88.923481,27.003843)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath18524">
+ <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.1435655,0,0,1.1436475,512.11415,45.72091)"
+ 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="path18526"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69954133;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.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18634">
+ <path
+ sodipodi:nodetypes="ccccscc"
+ style="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"
+ d="m 207,134 0,14 11,0 0,-7.5625 c -1.97252,-0.24738 -3.5,-1.89814 -3.5,-3.9375 0,-0.94675 0.35614,-1.81444 0.90625,-2.5 L 207,134 z"
+ id="path18636"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient18478"
+ gradientUnits="userSpaceOnUse"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18480"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-97.983877,565.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18739"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,43.55464,-148.13985)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="16.173666"
+ y2="173.23431" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4343"
+ id="linearGradient18741"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5990464,-0.03583042,0.03242597,0.6546824,59.652868,-253.61658)"
+ x1="-12.264804"
+ y1="333.22653"
+ x2="-10.869003"
+ y2="334.86029" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18743"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(250.01612,148)"
+ x1="-190.37566"
+ y1="-180.13821"
+ x2="-189.34792"
+ y2="-182" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient19045"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,-461,-82.584001)"
+ x1="42.033173"
+ y1="164.51399"
+ x2="75.32457"
+ y2="164.51399" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient19047"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(298,-53.749881)"
+ x1="118.1319"
+ y1="157.11609"
+ x2="85.577972"
+ y2="157.54283" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient19049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,767.51613,327.08335)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35583"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="4.952816"
+ y2="-27.882322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35585"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="3.1666665"
+ y2="-29.550003" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35587"
+ gradientUnits="userSpaceOnUse"
+ x1="-3.5"
+ y1="-35.5"
+ x2="2.6932251"
+ y2="-29.488832" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35589"
+ gradientUnits="userSpaceOnUse"
+ x1="4.9341426"
+ y1="-29.678047"
+ x2="4.8398785e-16"
+ y2="-32.351803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35591"
+ gradientUnits="userSpaceOnUse"
+ x1="0.5079475"
+ y1="-32.317398"
+ x2="4.2000003"
+ y2="-28.597046" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient35593"
+ gradientUnits="userSpaceOnUse"
+ x1="2.8144052"
+ y1="-28.1"
+ x2="-4.375"
+ y2="-36.441402" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35595"
+ gradientUnits="userSpaceOnUse"
+ x1="-2.7708333"
+ y1="-35.5"
+ x2="1.1666667"
+ y2="-32" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient35740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,-206.46148,-296.13985)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="10.490564"
+ y2="176.41806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient35742"
+ gradientUnits="userSpaceOnUse"
+ x1="58.060974"
+ y1="-23.721956"
+ x2="40"
+ y2="-35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35744"
+ gradientUnits="userSpaceOnUse"
+ x1="46.1875"
+ y1="-28.59375"
+ x2="41.099998"
+ y2="-33.59375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36116"
+ id="linearGradient35746"
+ gradientUnits="userSpaceOnUse"
+ x1="46"
+ y1="-32"
+ x2="43.883884"
+ y2="-33.939339" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35748"
+ gradientUnits="userSpaceOnUse"
+ x1="41"
+ y1="-29"
+ x2="43"
+ y2="-27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35750"
+ gradientUnits="userSpaceOnUse"
+ x1="48.662914"
+ y1="-27.071922"
+ x2="43.47097"
+ y2="-32.337086" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6.3,-4.7)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.200001"
+ y2="-28.640625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(5.315625,-3.75)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.325001"
+ y2="-28.765625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35756"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(3.3,0.3)"
+ x1="38.700001"
+ y1="-31.299999"
+ x2="40.012501"
+ y2="-29.799999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35772"
+ gradientUnits="userSpaceOnUse"
+ x1="51.912914"
+ y1="-24.696922"
+ x2="40.75"
+ y2="-35.75"
+ gradientTransform="translate(-0.75,4.75)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51774"
+ gradientUnits="userSpaceOnUse"
+ x1="135.32962"
+ y1="120.04005"
+ x2="130.7244"
+ y2="116.31882" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51776"
+ gradientUnits="userSpaceOnUse"
+ x1="130.9015"
+ y1="115.23484"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient51804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.43697,300.37199)"
+ x1="107.78085"
+ y1="50.778313"
+ x2="111.53449"
+ y2="46.679707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.55698,300.497)"
+ x1="115.37703"
+ y1="51.021076"
+ x2="112.87534"
+ y2="51.021076" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.35699,300.55457)"
+ x1="110.57378"
+ y1="50.963791"
+ x2="108.07208"
+ y2="50.963791" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.36783,218.31526)"
+ x1="-13.691219"
+ y1="241.78653"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.13133,218.33837)"
+ x1="-9.0782614"
+ y1="249.96617"
+ x2="-2.9318311"
+ y2="240.68927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.5254431"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68939"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.091064"
+ y2="242.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68941"
+ gradientUnits="userSpaceOnUse"
+ x1="-41.065678"
+ y1="240.10526"
+ x2="-15.758821"
+ y2="244.11874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68943"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(440.2082,-188.0039)"
+ x1="-10.991813"
+ y1="237.9574"
+ x2="-7.0786314"
+ y2="246.7774" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.9582,-188.0039)"
+ x1="-5.1338587"
+ y1="244.08765"
+ x2="-14.193665"
+ y2="251.35759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient68947"
+ gradientUnits="userSpaceOnUse"
+ x1="-15.6"
+ y1="247.38559"
+ x2="-3.321322"
+ y2="245.68124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68949"
+ gradientUnits="userSpaceOnUse"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.7065439"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68951"
+ gradientUnits="userSpaceOnUse"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.125"
+ y2="242.81946" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68953"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.25,0.2058042)"
+ x1="-12.538609"
+ y1="240.79787"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68955"
+ gradientUnits="userSpaceOnUse"
+ x1="-7.20822"
+ y1="247.4906"
+ x2="-1.7751017"
+ y2="239.86711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient69009"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5466301,0,0,1.6489946,-293.01107,-16.485383)"
+ x1="582"
+ y1="49.294117"
+ x2="582"
+ y2="47.176472" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask69005">
+ <rect
+ style="fill:url(#linearGradient69009);fill-opacity:1;display:inline"
+ id="rect69007"
+ width="24.746082"
+ height="26.383913"
+ x="596.30127"
+ y="39.580433" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20269"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20275"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20283"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20303"
+ gradientUnits="userSpaceOnUse"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20309"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21567"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21594"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21596"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21647"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21649"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21979"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath22590">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22592"
+ width="12"
+ height="14"
+ x="-30"
+ y="490.00012" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23595"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.1666667,-737,357.33333)"
+ x1="771.0965"
+ y1="354.28479"
+ x2="772"
+ y2="358.85715" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23591">
+ <rect
+ mask="none"
+ style="fill:url(#linearGradient23595);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23593"
+ width="11"
+ height="14"
+ x="30"
+ y="768" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath23877">
+ <rect
+ transform="scale(1,-1)"
+ y="-540"
+ x="952"
+ height="6"
+ width="15"
+ id="rect23879"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23978"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23980"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320"
+ id="linearGradient23982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.733333,808.99997,-697.8)"
+ x1="150.5"
+ y1="239.9987"
+ x2="150.5"
+ y2="237" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29485"
+ id="linearGradient23986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,715,364)"
+ x1="147.0625"
+ y1="243.76387"
+ x2="142.9375"
+ y2="243.69914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30777"
+ id="linearGradient23988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2857143,364,645.14283)"
+ x1="148"
+ y1="244.11113"
+ x2="144"
+ y2="244.11113" />
+ <linearGradient
+ id="linearGradient3564"
+ inkscape:collect="always">
+ <stop
+ id="stop3566"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop3568"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39155">
+ <stop
+ id="stop39157"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39159"
+ offset="1"
+ style="stop-color:#dadada;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39171"
+ inkscape:collect="always">
+ <stop
+ id="stop39173"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39175"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient21442"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39155"
+ id="linearGradient21444"
+ gradientUnits="userSpaceOnUse"
+ x1="31.1875"
+ y1="18.875"
+ x2="29.875"
+ y2="34.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3564"
+ id="linearGradient21446"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.06818845,0,0,0.06818845,22.51112,27.02885)"
+ x1="185.9903"
+ y1="193.33229"
+ x2="190.46461"
+ y2="-458.05771" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39171"
+ id="radialGradient21448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.647222,0,0,1.26792,-15.47413,-5.79794)"
+ cx="26.109201"
+ cy="19.668886"
+ fx="26.109201"
+ fy="19.668886"
+ r="20.278975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39281"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="71"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39283"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1944456,0,0,1.2000039,-34.222431,-14.950295)"
+ x1="175.17659"
+ y1="74.972061"
+ x2="176.40117"
+ y2="76.182281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39285"
+ gradientUnits="userSpaceOnUse"
+ x1="165.19363"
+ y1="64.53186"
+ x2="176.15442"
+ y2="76.210785" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39287"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="172.30418"
+ y1="69.838829"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39289"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39291"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39293"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39008"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39010"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39012"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39014"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39016"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39018"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39022"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39024"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39026"
+ x1="1127.7983"
+ y1="448.375"
+ x2="1153.0486"
+ y2="430.25"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient57417"
+ gradientUnits="userSpaceOnUse"
+ x1="146.82516"
+ y1="134.65511"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient57419"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57421"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57423"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient57454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(258.00306,-231.00101)"
+ x1="75.25"
+ y1="393.25"
+ x2="73.5"
+ y2="391.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask57450">
+ <rect
+ y="154.99899"
+ x="326.00305"
+ height="15"
+ width="15"
+ id="rect57452"
+ style="fill:url(#linearGradient57454);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22891"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="174.99828"
+ y1="12.918247"
+ x2="167.59578"
+ y2="12.551482" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22893"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="169.47711"
+ y1="10.424105"
+ x2="169.47711"
+ y2="8.1183796" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22895"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.728189,0,0,1.727271,237.88848,243.63713)"
+ x1="169.41847"
+ y1="10.306772"
+ x2="169.4877"
+ y2="7.9604731" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="145.00008"
+ y1="11.99999"
+ x2="160.31258"
+ y2="19.34374" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="149.00008"
+ y1="10.924165"
+ x2="171.37508"
+ y2="19.12499" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient22901"
+ gradientUnits="userSpaceOnUse"
+ x1="-68.25"
+ y1="263"
+ x2="-56"
+ y2="265.53439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22903"
+ gradientUnits="userSpaceOnUse"
+ x1="-66"
+ y1="264"
+ x2="-57"
+ y2="264.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32998"
+ id="linearGradient22905"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="176.42079"
+ y1="12.946938"
+ x2="169.47711"
+ y2="12.36799" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient22933"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22935"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient22937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22939"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22941"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22970"
+ x1="-197.84375"
+ y1="399.90625"
+ x2="-191"
+ y2="409"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19625"
+ id="linearGradient23241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="476.76578"
+ y2="162.94037" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12678"
+ id="radialGradient23245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0982561,0,0,1.2662999,-45.858153,-42.45126)"
+ cx="470.15939"
+ cy="164.46814"
+ fx="470.15939"
+ fy="164.46814"
+ r="3.500145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23247"
+ gradientUnits="userSpaceOnUse"
+ x1="128.7561"
+ y1="115.77483"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23250"
+ gradientUnits="userSpaceOnUse"
+ x1="127.30917"
+ y1="111.48133"
+ x2="138.30522"
+ y2="124.69373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23445"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="475.50031"
+ y2="162.92206" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23447"
+ 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="#linearGradient23974"
+ id="linearGradient23531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.37032"
+ y1="12.147777"
+ x2="175.38158"
+ y2="15.699567" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23533"
+ gradientUnits="userSpaceOnUse"
+ x1="155.82454"
+ y1="16.845156"
+ x2="158.41653"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.727201,9.075096e-6,0,1.728246,-147.7149,-10.37485)"
+ x1="171.03941"
+ y1="11.121979"
+ x2="175.33569"
+ y2="16.202652" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.18394"
+ y1="11.912162"
+ x2="176.46956"
+ y2="16.427906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40847"
+ gradientUnits="userSpaceOnUse"
+ x1="156.00008"
+ y1="16.99999"
+ x2="159.00008"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40965"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,14)"
+ x1="62.107086"
+ y1="223.54628"
+ x2="96.812675"
+ y2="258.38593" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient40967"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-21,0)"
+ x1="79.04213"
+ y1="253.5"
+ x2="60.155113"
+ y2="234.7775" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24098"
+ x1="208.25"
+ y1="-133.89581"
+ x2="204.01923"
+ y2="-111.15749"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23510"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3008215,-8.6726798)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23512"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="110.16959"
+ y1="57.061836"
+ x2="117.55341"
+ y2="64.995972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23514"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3010161,-8.6726854)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="54.252415"
+ y2="100.44998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23550"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,0.01738631)"
+ x1="468.07968"
+ y1="275.27036"
+ x2="510"
+ y2="266.99997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient23555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,3.959006e-5)"
+ x1="492.95264"
+ y1="267.42996"
+ x2="496.73859"
+ y2="270.36874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23581"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,404.07104,216.722)"
+ x1="116.75796"
+ y1="52.264809"
+ x2="103.18628"
+ y2="55.747272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient23585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-1.0000037)"
+ x1="500.71924"
+ y1="270.24997"
+ x2="477"
+ y2="274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="radialGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="radialGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0009003,-1.5278593,1.1592123,0.7594114,-59.938837,957.7287)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23562"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,461.68129,182.37748)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="56.524509"
+ y2="101.25028" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,323.39462,186.24644)"
+ x1="115.45872"
+ y1="58.869785"
+ x2="106.20376"
+ y2="58.354706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,347.39462,166.24644)"
+ x1="110.54202"
+ y1="56.645538"
+ x2="115.53827"
+ y2="63.567348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2445337,0,0,1.5876961,523.20711,115.4619)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,503.28129,157.47747)"
+ x1="29.506693"
+ y1="100.66651"
+ x2="34.276955"
+ y2="105.98901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24054"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24066"
+ x1="202.5"
+ y1="143.84116"
+ x2="202.5"
+ y2="132.60213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-259,202)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient23738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23750"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,59.49999,53.45766)"
+ x1="445.5"
+ y1="148.90862"
+ x2="433.5"
+ y2="148.69533" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6499984,0,0,0.5439483,434.02514,137.87435)"
+ x1="113.71248"
+ y1="158.24995"
+ x2="91.499992"
+ y2="158.24994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0052083,0,0,0.5057472,778.49218,365.83334)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23914"
+ gradientUnits="userSpaceOnUse"
+ x1="29.200638"
+ y1="160.18758"
+ x2="32.928555"
+ y2="164.13913" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23916"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.02887268,-1.2550276,0.795821,0.01830762,8.763469,168.20647)"
+ cx="11.708446"
+ cy="81.275032"
+ fx="11.708446"
+ fy="81.275032"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.01269957,-0.9297674,1.1086869,0.01514236,-16.51473,165.70609)"
+ cx="4.7455525"
+ cy="82.433929"
+ fx="4.7455525"
+ fy="82.433929"
+ r="5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24460"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(383,-37.999994)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24456">
+ <rect
+ y="108"
+ x="299"
+ height="17"
+ width="7"
+ id="rect24458"
+ style="fill:url(#linearGradient24460);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-142.95536)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24466">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient24470);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24468"
+ width="7"
+ height="9"
+ x="276"
+ y="4.0625" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23971"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23973"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23975"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24099"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24539"
+ 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"
+ id="linearGradient24541"
+ 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"
+ id="linearGradient24543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="483.00034"
+ y1="163"
+ x2="476.68781"
+ y2="162.85956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24545"
+ 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"
+ id="linearGradient24547"
+ gradientUnits="userSpaceOnUse"
+ x1="475.00034"
+ y1="155"
+ x2="469.75034"
+ y2="155" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,-6e-5)"
+ x1="442.81525"
+ y1="290.49384"
+ x2="436.5"
+ y2="290.5249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient24551"
+ gradientUnits="userSpaceOnUse"
+ x1="445.99902"
+ y1="288.5"
+ x2="407.3793"
+ y2="288.5" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath24168">
+ <path
+ style="fill:#808080;fill-rule:evenodd;stroke:none"
+ d="m 134.27489,222.11125 c -3.9249,-6.46418 -7.61892,6.46419 -11.54381,0 l 0,0 -1.61614,0 0,8.77283 14.77608,0 0,-8.77283 -1.61613,0 z"
+ id="path24170"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient24112"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24114"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="302.84085"
+ y1="243.23151"
+ x2="308.82889"
+ y2="244.70323" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6879084,0,0,0.6879446,216.19282,166.82605)"
+ x1="121.7408"
+ y1="115.90587"
+ x2="130.01318"
+ y2="116.60553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24121"
+ gradientUnits="userSpaceOnUse"
+ x1="135.698"
+ y1="122.92034"
+ x2="129.70906"
+ y2="117.15551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24123"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="162.61801"
+ y1="4.5569806"
+ x2="180.11391"
+ y2="23.410421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24192"
+ gradientUnits="userSpaceOnUse"
+ x1="167.43744"
+ y1="23.749996"
+ x2="175.06059"
+ y2="32.144764"
+ gradientTransform="translate(-94.937441,240)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="166.86487"
+ y1="12.306217"
+ x2="173.93744"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24268"
+ gradientUnits="userSpaceOnUse"
+ x1="186.74992"
+ y1="10.795519"
+ x2="189.24992"
+ y2="9.0189686"
+ gradientTransform="matrix(1,0,0,-0.985055,75.000075,275.63418)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24277"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient24395"
+ x1="-27.5"
+ y1="268.76776"
+ x2="-39.875"
+ y2="277.4375"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15893"
+ id="linearGradient41127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,594,-42.40625)"
+ x1="409.45645"
+ y1="52.77837"
+ x2="402.30673"
+ y2="55.86327" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27957"
+ id="linearGradient41129"
+ gradientUnits="userSpaceOnUse"
+ x1="180.20316"
+ y1="8.0551176"
+ x2="192.75177"
+ y2="12.942369" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41172"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="268.21783"
+ y1="200.66605"
+ x2="284.9375"
+ y2="224.1875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient41174"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41963"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(274,-63.999901)"
+ x1="113.71248"
+ y1="158.24995"
+ x2="87.522514"
+ y2="157.99994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42069"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="276.39999"
+ y1="215.3125"
+ x2="265.70886"
+ y2="196.576" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42115"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(60,-342)"
+ x1="206"
+ y1="535"
+ x2="212"
+ y2="549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="263"
+ y1="193.93752"
+ x2="296.25"
+ y2="239.89455" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="265.98389"
+ y1="195"
+ x2="290.98389"
+ y2="232" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40722"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9819031,0,0,0.9481466,-88.271503,-83.584533)"
+ x1="1.6577729"
+ y1="253.01927"
+ x2="-57.772419"
+ y2="253.62515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.977157,0,0,0.9835482,0.06815071,100.43848)"
+ x1="107.84375"
+ y1="57.374996"
+ x2="116.99999"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="241.17908"
+ y1="214.40446"
+ x2="279.89563"
+ y2="254.94975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6025789,0,0,0.668336,263.48819,85.675422)"
+ x1="49.543404"
+ y1="230.81766"
+ x2="73.932747"
+ y2="247.27646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9120445,0,0,1,25.749745,8.9261515)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="308.97327"
+ y2="242" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.584271,0,0,0.661005,267.80323,78.438648)"
+ x1="51.682816"
+ y1="229.19724"
+ x2="73.932762"
+ y2="247.35141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40742"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9103441,0,0,0.989031,29.299938,2.5312404)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="307.25021"
+ y2="241.62509" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40758"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.997359,-17.993456)"
+ x1="199.4335"
+ y1="294.81082"
+ x2="196.00264"
+ y2="259.99347" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40760"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,51.339144,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40762"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,59.339161,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40788"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="146.51619"
+ y1="217.52046"
+ x2="174.56255"
+ y2="252.52081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient40790"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18056"
+ id="linearGradient40792"
+ gradientUnits="userSpaceOnUse"
+ x1="170.42908"
+ y1="237.25"
+ x2="170.71698"
+ y2="249.15927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40794"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.5625"
+ y1="249.55817"
+ x2="168.5"
+ y2="240.10249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40545"
+ gradientUnits="userSpaceOnUse"
+ x1="279.38629"
+ y1="-16.946415"
+ x2="293.80472"
+ y2="-2.5475447" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40547"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9230687,0,0,0.9230801,261.38476,-234.15464)"
+ x1="43.921535"
+ y1="261.52924"
+ x2="29.429007"
+ y2="243.98439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22249"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="387"
+ y1="410"
+ x2="388.78125"
+ y2="411.78125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="386.88852"
+ y1="409.84152"
+ x2="389.14081"
+ y2="412.45016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="387"
+ y1="409.86362"
+ x2="388.86676"
+ y2="411.88974" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23775"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9230769,0,0,-0.9258123,59.615385,471.81593)"
+ x1="-0.71355486"
+ y1="209.97131"
+ x2="37.5"
+ y2="252.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23777"
+ gradientUnits="userSpaceOnUse"
+ x1="72.698921"
+ y1="599.20789"
+ x2="77.111115"
+ y2="604.11108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23351"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23353"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23355"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23357"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23599"
+ x1="191"
+ y1="158.72728"
+ x2="196.59441"
+ y2="167.67831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.89375,0,0,0.89375,20.29375,17.10625)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22704"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23132"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23134"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23147"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23177"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23183"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23185"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23231"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23235"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23239"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23257"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23563"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23566"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23576"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23587"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23589"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23591"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23597"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23616"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23618"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23620"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23626"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23635"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23637"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23799"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23801"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23807"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23811"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23821"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23827"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23829"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23833"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23835"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23837"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23853"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23860"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42685"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient22892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22917"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22922"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="262.67139"
+ cy="74.072273"
+ fx="262.67139"
+ fy="74.072273"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient22954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37925"
+ id="linearGradient23890"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient23892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23906"
+ id="radialGradient23894"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0553103,1.0606182,-1.2516598,1.280294,67.321819,-297.60493)"
+ cx="262.07156"
+ cy="74.306007"
+ fx="262.07156"
+ fy="74.306007"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="radialGradient23898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient24090"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient24092"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24094"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="263.21707"
+ cy="74.441246"
+ fx="263.21707"
+ fy="74.441246"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient24102"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24104"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="66.954422"
+ y1="240.03282"
+ x2="68.458534"
+ y2="246.96069" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="244.37868"
+ y1="285.00754"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24695"
+ id="linearGradient24374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.97597"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-150.99992,596.00357)"
+ x1="199.87271"
+ y1="272.29477"
+ x2="212.22493"
+ y2="287.50357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24811"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.539974"
+ y1="421.80756"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24841"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24144"
+ id="linearGradient24843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="64.019142"
+ y1="419.06366"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24867"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24869"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24871"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.659767"
+ y1="422.46088"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24873"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25073"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25075"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient42055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.94298"
+ y1="281.27435"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient42057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42059"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient24132"
+ gradientUnits="userSpaceOnUse"
+ x1="445.77841"
+ y1="113.24564"
+ x2="426.11459"
+ y2="84.777061" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24599"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1489145,-0.69297,0.4772363,0.7912359,-113.08929,303.20064)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7236207,-0.7167103,1.004637,1.0143218,-131.254,253.93955)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient24797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.3967"
+ y1="310.77368"
+ x2="309.02371"
+ y2="308.51169" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24820"
+ x1="311.37668"
+ y1="311.88205"
+ x2="307.5"
+ y2="308.21875"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4011721,0.3766097,-0.7099042,0.7562044,179.21454,-58.566632)"
+ cx="207.04807"
+ cy="78.473343"
+ fx="207.04807"
+ fy="78.473343"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4543499,0.4687811,-0.6244606,0.6052369,161.562,-65.729731)"
+ cx="206.39249"
+ cy="78.443413"
+ fx="206.39249"
+ fy="78.443413"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="248.69196"
+ y1="279.72827"
+ x2="269.3085"
+ y2="303.10999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient62558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,-33.03632,32.03632)"
+ x1="289.61554"
+ y1="320.55179"
+ x2="250.22783"
+ y2="282.28745" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62560"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,59,638)"
+ x1="354.50601"
+ y1="283.61511"
+ x2="327.92044"
+ y2="300.96124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25381"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25383"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25385"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25387"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25369">
+ <g
+ id="g25371"
+ transform="translate(-21,-21)">
+ <path
+ style="fill:url(#linearGradient25381);fill-rule:evenodd;stroke:none"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ id="path25373"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="4"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25375"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ style="fill:url(#linearGradient25383);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-x="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25377"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ style="fill:url(#linearGradient25385);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="4"
+ sodipodi:nodetypes="cccc"
+ id="path25379"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ style="fill:url(#linearGradient25387);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.01321"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25579"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25561">
+ <g
+ transform="translate(-21,-21)"
+ id="g25563">
+ <path
+ inkscape:transform-center-x="4"
+ sodipodi:nodetypes="cccc"
+ id="path25565"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ style="fill:url(#linearGradient25573);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient25575);fill-rule:evenodd;stroke:none"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ id="path25567"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient25577);fill-rule:evenodd;stroke:none"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ id="path25569"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient25579);fill-rule:evenodd;stroke:none"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ id="path25571"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="4"
+ inkscape:connector-curvature="0" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25872"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,328.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25874"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,111)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="243.92192"
+ y1="-2.6686089"
+ x2="275.10107"
+ y2="26.600887" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25888"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25890"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25892"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25894"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-72.000001)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25927"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25929"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25931"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25957"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25961"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-112)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25984"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-88.000005)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient26011"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient26013"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26015"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,-76.000004)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient26077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26083"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26126"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26128"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26130"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="68.383354"
+ y1="239.95235"
+ x2="69.285805"
+ y2="247.29691" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27973"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27975"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28099"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient28107"
+ gradientUnits="userSpaceOnUse"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845"
+ gradientTransform="translate(-19,294.91429)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient27448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-19,294.91429)"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27450"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27540"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27544"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient27598"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient27600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27604"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient27606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient27610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient30389"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30391"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient30393"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient30395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient30397"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(422.99996,88.99998)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29129"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27767"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27769"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient27771"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="112.18942"
+ y1="114.71685"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27773"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient31865"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.986122,0,0,0.986122,2.8033684,0.804927)"
+ cx="202"
+ cy="58"
+ fx="202"
+ fy="58"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask31861">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient31865);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path31863"
+ sodipodi:cx="202"
+ sodipodi:cy="58"
+ sodipodi:rx="11"
+ sodipodi:ry="11"
+ d="m 213,58 a 11,11 0 1 1 -22,0 11,11 0 1 1 22,0 z" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath31849">
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 232.13187,93.950853 4.84276,0 4.23742,4.237465 0,4.842822 -9.08018,0 0,-9.080287 0,0 z"
+ id="path31851"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32298"
+ gradientUnits="userSpaceOnUse"
+ x1="-117.5"
+ y1="431.5"
+ x2="-119.5"
+ y2="429.5"
+ gradientTransform="translate(258,-96.99999)" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask32294">
+ <rect
+ y="323"
+ x="134"
+ height="16"
+ width="9"
+ id="rect32296"
+ style="fill:url(#linearGradient32298);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53119"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53123"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53125"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient53127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient53129"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="362.79037"
+ y1="-159.88834"
+ x2="373.83752"
+ y2="-150.41035" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53131"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9900316,0,0,1,2.450297,0.00704954)"
+ x1="343.51892"
+ y1="175.19124"
+ x2="350.97491"
+ y2="183.3365" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53133"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53139"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53141"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53143"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53145"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53147"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient53149"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient53151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,115.625,254.97076)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient53157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53159"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient53161"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,237.00668)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53163"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53165"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53171"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient50870"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2e-6,0)"
+ x1="-22.902081"
+ y1="448"
+ x2="-14.000002"
+ y2="448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33427"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="136.04924"
+ y2="121.25749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33429"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient33585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7071068,-0.7071068,0.7071067,0.7071067,-140.04288,401.30258)"
+ x1="458.99997"
+ y1="89.363937"
+ x2="452.63602"
+ y2="90.071045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31356"
+ id="linearGradient33831"
+ gradientUnits="userSpaceOnUse"
+ x1="134.00002"
+ y1="116"
+ x2="142.00002"
+ y2="108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33833"
+ gradientUnits="userSpaceOnUse"
+ x1="124.75568"
+ y1="112.24533"
+ x2="132.97911"
+ y2="120.16792" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33835"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="254.19829"
+ y1="2.1803131"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37475"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37477"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="275.62497"
+ y2="26.679274" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37479"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37481"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37483"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37485"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37487"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37489"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37491"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.5793179,0,-1.0159927e-7,-1.6412688,666.67947,207.37331)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37493"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37495"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37497"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37499"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37501"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37503"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37505"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37507"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37509"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3336259,0,-8.5793649e-8,-1.3859393,603.17514,187.32668)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3648614,0,-8.7803051e-8,-1.4184,611.24862,189.87526)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37517"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37519"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37521"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient37525"
+ gradientUnits="userSpaceOnUse"
+ x1="337.34329"
+ y1="43.328976"
+ x2="330.27045"
+ y2="35.276588" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37527"
+ gradientUnits="userSpaceOnUse"
+ x1="329.9158"
+ y1="35.5"
+ x2="335.27429"
+ y2="41.570362" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="166.89752"
+ y1="9.0567484"
+ x2="193.26451"
+ y2="38.642647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37531"
+ gradientUnits="userSpaceOnUse"
+ x1="127.93343"
+ y1="122.8346"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37533"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37535"
+ gradientUnits="userSpaceOnUse"
+ x1="122.86111"
+ y1="127.14286"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37537"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37539"
+ gradientUnits="userSpaceOnUse"
+ x1="266"
+ y1="659"
+ x2="285"
+ y2="659" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient37541"
+ gradientUnits="userSpaceOnUse"
+ x1="244.21062"
+ y1="600.74884"
+ x2="244.21062"
+ y2="602.96759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35407"
+ id="linearGradient37543"
+ gradientUnits="userSpaceOnUse"
+ x1="235.29379"
+ y1="588.43396"
+ x2="245.93307"
+ y2="604.52502" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37545"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37547"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37553"
+ gradientUnits="userSpaceOnUse"
+ x1="86.248604"
+ y1="32"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="81"
+ y1="27"
+ x2="64.5"
+ y2="9.0000019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient37557"
+ gradientUnits="userSpaceOnUse"
+ x1="70.78582"
+ y1="15.659542"
+ x2="79.465332"
+ y2="24.480759" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient37559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5997527,0.4726093,-0.6665451,0.8458611,35.480681,-28.765852)"
+ cx="63.013588"
+ cy="14.60904"
+ fx="63.013588"
+ fy="14.60904"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37571"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient37573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="83.261826"
+ y1="502.54196"
+ x2="41.311054"
+ y2="501.10059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient37575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37578"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37580"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2665671,0.04035316,-0.03648524,1.99062,-82.893589,-502.25433)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37584"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37586"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37588"
+ gradientUnits="userSpaceOnUse"
+ x1="264.10001"
+ y1="330.10001"
+ x2="264.89999"
+ y2="330.89999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient37590"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37592"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="51.37524"
+ y1="96.955269"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient37594"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37596"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient37612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37614"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37636"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="387.30396"
+ y1="126.23978"
+ x2="332.88193"
+ y2="123.61623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37640"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42322"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42324"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42326"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42328"
+ gradientUnits="userSpaceOnUse"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42330"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42332"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42334"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42336"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42338"
+ gradientUnits="userSpaceOnUse"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42340"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42342"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42344"
+ gradientUnits="userSpaceOnUse"
+ x1="-69.457596"
+ y1="31.914484"
+ x2="-76.564636"
+ y2="28.695114" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42346"
+ gradientUnits="userSpaceOnUse"
+ x1="-57.780041"
+ y1="48.005856"
+ x2="-78.812721"
+ y2="31" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42348"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42350"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.2998291,32.548709,64.760571)"
+ x1="51.497997"
+ y1="97.491707"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42352"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,79.011866)"
+ x1="51.497997"
+ y1="94.987144"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,83.013491)"
+ x1="51.497997"
+ y1="94.987129"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197983,83.013493)"
+ x1="48.998543"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42358"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197981,79.010163)"
+ x1="48.99855"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,42.19798,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196563,83.013493)"
+ x1="48.998539"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196561,79.010163)"
+ x1="48.998547"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,46.19656,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42368"
+ gradientUnits="userSpaceOnUse"
+ x1="-109.125"
+ y1="52.625"
+ x2="-121.73741"
+ y2="38.387074" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42370"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42372"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42374"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42376"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-41,98)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42378"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42380"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42382"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-57.134785,102.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42384"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-92.714287,177.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42386"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42388"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42390"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42392"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient42394"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1226244,0.04761823,-0.1611956,3.8002759,59.188894,-553.59611)"
+ cx="-215.0979"
+ cy="201.01204"
+ fx="-215.0979"
+ fy="201.01204"
+ r="5.8999949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42396"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,4)"
+ x1="-224"
+ y1="201"
+ x2="-214.39445"
+ y2="195.27762" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="209.05762"
+ y1="290.00357"
+ x2="215.34009"
+ y2="277.00357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42400"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42402"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42404"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42408"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42410"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42414"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="133.62697"
+ y2="120.49951" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42418"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42420"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-120,79)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42422"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-136.13478,83.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-171.71429,158.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient42430"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1664.4413"
+ y1="720.01788"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient42432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1977.4047"
+ y2="829.72656" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42436"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42438"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42440"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42442"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42444"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42446"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1658027,0,0,1.1657997,-354.28972,51.94393)"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42462"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42464"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42466"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8370074,0,0,0.8129865,84.784966,-149.92038)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,11.285548,8.325368)"
+ x1="111.03847"
+ y1="57.034107"
+ x2="117.16058"
+ y2="60.591385" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42472"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42474"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42477"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42479"
+ gradientUnits="userSpaceOnUse"
+ x1="-92.587807"
+ y1="-18.005362"
+ x2="-100.62162"
+ y2="-17.998919" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42481"
+ gradientUnits="userSpaceOnUse"
+ x1="-101"
+ y1="-16"
+ x2="-93"
+ y2="-17" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42483"
+ gradientUnits="userSpaceOnUse"
+ x1="-87.491188"
+ y1="-22.830606"
+ x2="-102.96513"
+ y2="-22.166544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42485"
+ gradientUnits="userSpaceOnUse"
+ x1="-98.997849"
+ y1="-23.173643"
+ x2="-98.997849"
+ y2="-25.872688" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42487"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42489"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42491"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42493"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5290924,0,0,0.5294132,-17.313533,46.110999)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42495"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5350034,0,0,0.5349052,24.446207,45.843517)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42497"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42499"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42501"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42503"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42505"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42507"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42509"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42511"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4749148,1.0023386,-1.2226848,-0.4749148,213.62384,41.735193)"
+ x1="118.95689"
+ y1="106.42961"
+ x2="135.14919"
+ y2="119.05286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5333554,1.1220467,-1.1447545,-0.5333554,196.63818,32.816067)"
+ x1="130.39502"
+ y1="116.31751"
+ x2="147.95374"
+ y2="134.687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient42517"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42519"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42521"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42523"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42525"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,26.488451,35.562258)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35408"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35414"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35418"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35420"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35422"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35424"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35468"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35470"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35476"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35478"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35480"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35482"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35484"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35486"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35488"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient34618"
+ gradientUnits="userSpaceOnUse"
+ x1="125.59209"
+ y1="112.6446"
+ x2="133.11621"
+ y2="119.21729" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient34620"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="141.83322"
+ y2="132.30261" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35446"
+ gradientUnits="userSpaceOnUse"
+ x1="31"
+ y1="60.000004"
+ x2="34"
+ y2="54.000004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35448"
+ gradientUnits="userSpaceOnUse"
+ x1="135.46967"
+ y1="118"
+ x2="121.4286"
+ y2="101.14284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35450"
+ gradientUnits="userSpaceOnUse"
+ x1="133.60002"
+ y1="118"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35452"
+ gradientUnits="userSpaceOnUse"
+ x1="132.30316"
+ y1="123.05057"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35454"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35718"
+ x1="28.130203"
+ y1="65.791054"
+ x2="32.5"
+ y2="55.066181"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient36452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,137.60085,-8.4035259)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,131.60084,3.5964741)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36458"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,143.60084,3.5964739)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37095"
+ gradientUnits="userSpaceOnUse"
+ x1="125.75312"
+ y1="111.40558"
+ x2="143.16118"
+ y2="129.27902" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="185.89514"
+ y1="30.343155"
+ x2="197.03207"
+ y2="42.717522" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="188"
+ y1="40.25"
+ x2="180.8125"
+ y2="32.46875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="187.8125"
+ y1="33.9375"
+ x2="184.25"
+ y2="30.15625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3.0999952,2.9000005)"
+ x1="177.85001"
+ y1="33.537502"
+ x2="186.00626"
+ y2="43.381248" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,6.188671,1.0072576)"
+ x1="182.20605"
+ y1="39.645184"
+ x2="172.36885"
+ y2="31.368597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36656"
+ gradientUnits="userSpaceOnUse"
+ x1="181.14906"
+ y1="32.701904"
+ x2="186.00002"
+ y2="37.415516" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,9.438677,-2.4927424)"
+ x1="181.9404"
+ y1="40.924297"
+ x2="175.82253"
+ y2="34.272892" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient36470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36713"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36715"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36721"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36727"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37396"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37398"
+ gradientUnits="userSpaceOnUse"
+ x1="389.51059"
+ y1="241.72565"
+ x2="388.20074"
+ y2="242.55887"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,0)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,-582)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38561">
+ <g
+ id="g38563">
+ <rect
+ y="278"
+ x="-23"
+ height="13"
+ width="16"
+ id="rect38565"
+ style="fill:url(#linearGradient38570);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:url(#linearGradient38572);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38567"
+ width="16"
+ height="13"
+ x="-23"
+ y="-304" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-1" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-7-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-4-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-4-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-8-3" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7-6"
+ id="linearGradient39048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="96"
+ y1="42"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-4-2"
+ id="linearGradient39050"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="65"
+ y1="20"
+ x2="66"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-4"
+ id="linearGradient39052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="67.25"
+ y1="18"
+ x2="68"
+ y2="16" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-4-27"
+ id="linearGradient39835-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8422958,0,0,0.8364537,82.535678,2.9394266)"
+ x1="89.975014"
+ y1="-32.339718"
+ x2="88.492455"
+ y2="-33.303608" />
+ <linearGradient
+ id="linearGradient35411-4-27">
+ <stop
+ id="stop35414-0-9"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-9-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39837-4"
+ gradientUnits="userSpaceOnUse"
+ x1="131.02808"
+ y1="123.49161"
+ x2="128.7139"
+ y2="115.97001" />
+ <linearGradient
+ id="linearGradient35411-8-1-3">
+ <stop
+ id="stop35414-2-7-1"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-4-1-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39839-3"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-5-4"
+ id="linearGradient39841-3"
+ gradientUnits="userSpaceOnUse"
+ x1="115.15884"
+ y1="88.476723"
+ x2="109.18613"
+ y2="82.308861" />
+ <linearGradient
+ id="linearGradient23974-5-4">
+ <stop
+ id="stop23976-27-1"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-6-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-8"
+ id="linearGradient39843-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="101"
+ y1="84.25"
+ x2="97.75"
+ y2="81.5" />
+ <linearGradient
+ id="linearGradient1610-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-77"
+ id="linearGradient39845-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="87.44548"
+ y1="81.439644"
+ x2="96.592278"
+ y2="89.708977" />
+ <linearGradient
+ id="linearGradient319-77">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-31" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41540"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient23974-4">
+ <stop
+ id="stop23976-20"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-9"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-37"
+ id="linearGradient32529-7"
+ gradientUnits="userSpaceOnUse"
+ x1="139.2112"
+ y1="111.35809"
+ x2="125.18381"
+ y2="128" />
+ <linearGradient
+ id="linearGradient319-37">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-60" />
+ </linearGradient>
+ <linearGradient
+ y2="125.77761"
+ x2="139.07738"
+ y1="115.76797"
+ x1="129.62384"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient41582"
+ xlink:href="#linearGradient23974-4"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient41666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient41670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41674"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41676"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42432"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42435"
+ gradientUnits="userSpaceOnUse"
+ x1="135.45557"
+ y1="122.90726"
+ x2="130.54761"
+ y2="116.54932" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42437"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath42711">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42713"
+ width="8.7252884"
+ height="17.464855"
+ x="127.4093"
+ y="214.76154" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient38796-7-9">
+ <stop
+ style="stop-color:#fc9694;stop-opacity:1;"
+ offset="0"
+ id="stop38798-6-8" />
+ <stop
+ style="stop-color:#e71609;stop-opacity:1;"
+ offset="1"
+ id="stop38800-1-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-87">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-78" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679-1">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681-0" />
+ <stop
+ id="stop24683-7"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38719"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38722"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient38724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.46314"
+ y1="113.45913"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38726"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39142"
+ gradientUnits="userSpaceOnUse"
+ x1="400.90442"
+ y1="68.853401"
+ x2="410.47467"
+ y2="77.877228" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38007"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-1">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-7"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43410-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-0">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-4" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43412-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38796-7-9"
+ id="linearGradient40270"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="59.622501"
+ y1="54.1525"
+ x2="60.981617"
+ y2="55.566177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="57.789688"
+ y2="54.130001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="56"
+ y2="52.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.54625,-1)"
+ x1="63.666252"
+ y1="37.960625"
+ x2="60.676094"
+ y2="34.685287" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679-1"
+ id="linearGradient40278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="52.17437"
+ y1="65.644958"
+ x2="50.371208"
+ y2="62.960247" />
+ <linearGradient
+ id="linearGradient24143-0">
+ <stop
+ id="stop24145-0"
+ offset="0"
+ style="stop-color:#2c2c2c;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669-1" />
+ <stop
+ id="stop24147-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-3-7"
+ id="linearGradient39686-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-70.605209"
+ y1="-121.58411"
+ x2="-28.177105"
+ y2="-89.026711" />
+ <linearGradient
+ id="linearGradient1610-3-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-9-4"
+ id="linearGradient39688-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-74"
+ y1="-124"
+ x2="-55.5975"
+ y2="-103.2075" />
+ <linearGradient
+ id="linearGradient319-5-9-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-24-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-6">
+ <stop
+ id="stop37544-18"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-92"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-3" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-41" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-1">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-9" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient59371">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop59373" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop59375" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-9-1"
+ id="linearGradient42965-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(301.02752,449.99999)"
+ x1="25.963812"
+ y1="155.66899"
+ x2="29.972469"
+ y2="168" />
+ <linearGradient
+ id="linearGradient319-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-92-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-55-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-06-1"
+ id="linearGradient42967-6"
+ gradientUnits="userSpaceOnUse"
+ x1="335.96875"
+ y1="607.09375"
+ x2="337.04251"
+ y2="628.20752" />
+ <linearGradient
+ id="linearGradient1610-06-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-1-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41266"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41268"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41270"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient41272"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient40920"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40922"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40924"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40926"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,404.60763,237.35923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient40928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9435203,-2.1990242,1.1704696,1.0049395,-665.14472,173.40654)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40930"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient40932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-6"
+ id="linearGradient36549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1511102,0,0,-1.1511102,152.68442,762.00423)"
+ x1="-16.608393"
+ y1="199.5118"
+ x2="30.713354"
+ y2="245.13458" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="radialGradient36551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6959954,0.116912,-0.04402498,0.2620878,107.60035,414.99606)"
+ cx="32.193073"
+ cy="243.37001"
+ fx="32.193073"
+ fy="243.37001"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143-0"
+ id="linearGradient36553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,147.99998,720.60935)"
+ x1="32.204613"
+ y1="233.6039"
+ x2="35.615856"
+ y2="251.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36555"
+ gradientUnits="userSpaceOnUse"
+ x1="148.76726"
+ y1="134.53409"
+ x2="114.11786"
+ y2="101.28939" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809"
+ id="linearGradient36557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="481.60803"
+ y1="163.09677"
+ x2="477.10818"
+ y2="163.00024" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient59371"
+ id="linearGradient36559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500181,0,0,0.8546123,-235.38338,339.18935)"
+ x1="473.79471"
+ y1="164.64572"
+ x2="463.90472"
+ y2="160.80888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-1"
+ id="linearGradient36561"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36563"
+ gradientUnits="userSpaceOnUse"
+ x1="138.46678"
+ y1="124.90586"
+ x2="126.18426"
+ y2="116.14438" />
+ <linearGradient
+ id="linearGradient9030-7-8-6">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-4-9-2" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-0-2-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809-2-2">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811-1-6" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813-4-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-7-5-5">
+ <stop
+ id="stop20057-1-7-7"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-1-6-8"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-4-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-8-5-8" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-8-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37829">
+ <stop
+ id="stop37831"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop37833" />
+ <stop
+ id="stop37835"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39254"
+ 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="#linearGradient40578-4-8"
+ id="radialGradient39256"
+ 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="#linearGradient58334"
+ id="linearGradient39258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ id="linearGradient40455-7">
+ <stop
+ id="stop40457-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36657"
+ 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="#linearGradient40578-4-8"
+ id="radialGradient36659"
+ 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="#linearGradient58334"
+ id="linearGradient36661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient36663"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37829"
+ id="linearGradient37089"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,165.4,716.20935)"
+ x1="261.17639"
+ y1="247.85646"
+ x2="253.86414"
+ y2="288.70752" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39080"
+ id="linearGradient37091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.888884,0,0,-0.8730569,136.66557,688.20759)"
+ x1="261.60016"
+ y1="247.008"
+ x2="263.60016"
+ y2="262.27994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-124.99991,219.9903)"
+ x1="19.923029"
+ y1="232.59058"
+ x2="50.485012"
+ y2="265.9697" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809-2-2"
+ id="linearGradient37096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="199.26254"
+ y1="144.5041"
+ x2="193.7029"
+ y2="144.5041" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-7-5-5"
+ id="linearGradient37098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="579.625"
+ y1="54.299286"
+ x2="576.4375"
+ y2="49.84375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="582.79974"
+ y1="56.363762"
+ x2="575.70361"
+ y2="49.87711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37102"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37104"
+ gradientUnits="userSpaceOnUse"
+ x1="140.78264"
+ y1="123.96156"
+ x2="132.25548"
+ y2="116.40535" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7"
+ id="radialGradient37553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.135666"
+ cy="95.970413"
+ fx="-73.135666"
+ fy="95.970413"
+ r="4.9999957" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37667"
+ id="radialGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4604901,-0.4901463,0.6187826,0.5813434,279.52277,457.42224)"
+ cx="756.98285"
+ cy="206.8443"
+ fx="756.98285"
+ fy="206.8443"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient37558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37561"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-94.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758.62622"
+ y2="305.53677" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1"
+ id="radialGradient37553-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.227486"
+ cy="95.949913"
+ fx="-73.227486"
+ fy="95.949913"
+ r="4.9999957" />
+ <linearGradient
+ id="linearGradient40455-7-1">
+ <stop
+ id="stop40457-6-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-7"
+ id="radialGradient37555-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4769848,-0.5257394,0.6056598,0.5494938,269.68012,490.96577)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-9"
+ id="linearGradient37558-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-9">
+ <stop
+ id="stop58336-27"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="300.83292"
+ x1="754.28558"
+ gradientTransform="translate(1,-94.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37610-3"
+ xlink:href="#linearGradient16500-4"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71834"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient71836"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient37188"
+ gradientUnits="userSpaceOnUse"
+ x1="-22"
+ y1="36.47311"
+ x2="-18.85"
+ y2="22.485678"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.00015,169.99998)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37201"
+ gradientUnits="userSpaceOnUse"
+ x1="-26"
+ y1="38"
+ x2="-27"
+ y2="30.200407"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ id="linearGradient1610-7409">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-488" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-5" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-17" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-1">
+ <stop
+ id="stop58336-5"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-27"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-14">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-23" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-22" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7409"
+ id="linearGradient37317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="272.92456"
+ y2="26.239208" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-5"
+ id="radialGradient37319"
+ 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="#linearGradient58334-1"
+ id="linearGradient37321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-14"
+ id="linearGradient37323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.1275"
+ y1="301.01553"
+ x2="758.77625"
+ y2="305.51749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37338"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(461.00015,453)"
+ x1="37"
+ y1="53"
+ x2="36.74033"
+ y2="44.322407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37132"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37134"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ id="linearGradient40455-7-1-7">
+ <stop
+ id="stop40457-6-6-4"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-0"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient38362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,2.85168,-84)"
+ x1="-9.3937483"
+ y1="203.3882"
+ x2="28.275171"
+ y2="249.73875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1-7"
+ id="radialGradient38364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1033468,0.01995877,-0.02366572,0.9281732,7.8124646,13.285893)"
+ cx="-73.972397"
+ cy="94.935921"
+ fx="-73.972397"
+ fy="94.935921"
+ r="4.9999957" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38367"
+ gradientUnits="userSpaceOnUse"
+ x1="19.210167"
+ y1="143.17894"
+ x2="38.580528"
+ y2="167.11429"
+ gradientTransform="matrix(1,0,0,0.8461542,0,25.615323)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-7">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-1"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-6">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-49" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36718"
+ gradientUnits="userSpaceOnUse"
+ x1="400.90442"
+ y1="68.853401"
+ x2="410.47467"
+ y2="77.877228" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38051"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37534"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ id="linearGradient1610-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-18" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-92" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient38254"
+ gradientUnits="userSpaceOnUse"
+ x1="124.19057"
+ y1="111.30384"
+ x2="134.62978"
+ y2="120.14633" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37509"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient37613"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37615"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38073-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-14.752135"
+ y1="101.82622"
+ x2="-45.074585"
+ y2="68.279541" />
+ <linearGradient
+ id="linearGradient15425-4-9-8">
+ <stop
+ style="stop-color:#960000;stop-opacity:1;"
+ offset="0"
+ id="stop15427-5-8-24" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429-8-2-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-1"
+ id="linearGradient38075-5"
+ gradientUnits="userSpaceOnUse"
+ x1="137.33838"
+ y1="124.67571"
+ x2="131.35606"
+ y2="118.00494" />
+ <linearGradient
+ id="linearGradient5060-1">
+ <stop
+ id="stop5062-7"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-1"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient38077-1"
+ gradientUnits="userSpaceOnUse"
+ x1="127.15736"
+ y1="111.48302"
+ x2="146.01884"
+ y2="136.15825" />
+ <linearGradient
+ id="linearGradient319-52">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-7614" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-232" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38079-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-15"
+ y1="101"
+ x2="-22"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418-6"
+ id="linearGradient14433-1"
+ gradientUnits="userSpaceOnUse"
+ x1="139.29807"
+ y1="127.35454"
+ x2="130.33557"
+ y2="115.81818" />
+ <linearGradient
+ id="linearGradient14418-6">
+ <stop
+ id="stop14420-8"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422-5"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14435-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.36379"
+ y1="110.81054"
+ x2="135.22182"
+ y2="120.76331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14437-6"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="141.43347"
+ y2="127.52184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-2"
+ id="linearGradient14439-9"
+ gradientUnits="userSpaceOnUse"
+ x1="125.20553"
+ y1="111.38132"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ id="linearGradient10069-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-79" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14441-4"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient48327-1"
+ id="radialGradient38306-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4461753,0.01083717,0.0036163,6.752143,-191.34795,-740.3814)"
+ cx="131.99811"
+ cy="126.63337"
+ fx="131.99811"
+ fy="126.63337"
+ r="9.1978254" />
+ <linearGradient
+ id="linearGradient48327-1">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop48329-23" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop48331-3" />
+ </linearGradient>
+ <linearGradient
+ y2="118.69846"
+ x2="132.35237"
+ y1="111.38132"
+ x1="125.20553"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37646-4"
+ xlink:href="#linearGradient10069-74-1"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient10069-74-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-0-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-9-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-7409-3-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-48-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-82-6-27" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient38313-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient37677"
+ gradientUnits="userSpaceOnUse"
+ x1="130.60338"
+ y1="115.87343"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ id="linearGradient319-19">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-8-3-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-95-2-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-43-7-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327-6">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-8-4">
+ <stop
+ id="stop20057-8-0"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-2-0"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39088">
+ <stop
+ id="stop39090"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop39092"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-83">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-24" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-11" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-95">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-10" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-64" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-87" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-42" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40173"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40175"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40282"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40284"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38693"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38703"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38706"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-157,821.03125)"
+ x1="-90.5"
+ y1="413.51562"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38720"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3846148,0,0,1,-211.38442,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,821.03125)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-2.4825165)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,824.54874)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39201"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39203"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39205"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39207"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39246"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39248"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39255"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39259"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient38961"
+ gradientUnits="userSpaceOnUse"
+ x1="488.5"
+ y1="568"
+ x2="495"
+ y2="568" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38956">
+ <rect
+ style="fill:url(#linearGradient38961);stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38958"
+ width="16"
+ height="12"
+ x="488"
+ y="560"
+ rx="0"
+ ry="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient39115"
+ gradientUnits="userSpaceOnUse"
+ x1="487.2518"
+ y1="531.95105"
+ x2="490.65796"
+ y2="580.63715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39117"
+ gradientUnits="userSpaceOnUse"
+ x1="496.49335"
+ y1="537.78113"
+ x2="498.40021"
+ y2="540.13623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39119"
+ gradientUnits="userSpaceOnUse"
+ x1="495.85294"
+ y1="541.69116"
+ x2="495.25"
+ y2="539.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-3"
+ id="linearGradient39122"
+ gradientUnits="userSpaceOnUse"
+ x1="494.38467"
+ y1="532.42651"
+ x2="496.21078"
+ y2="541.02698" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703"
+ id="linearGradient39261"
+ gradientUnits="userSpaceOnUse"
+ x1="122.25188"
+ y1="106.08706"
+ x2="147.08464"
+ y2="134.12131" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39263"
+ gradientUnits="userSpaceOnUse"
+ x1="116.75861"
+ y1="97.375854"
+ x2="145.729"
+ y2="137.52937" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39265"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient319-46">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-03" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-62" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-46"
+ id="linearGradient39508"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,0)"
+ x1="39.102718"
+ y1="641.73358"
+ x2="58.680996"
+ y2="661.93829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43807"
+ id="linearGradient39518"
+ gradientUnits="userSpaceOnUse"
+ x1="648.09674"
+ y1="355.85541"
+ x2="634.09503"
+ y2="341.23715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39088"
+ id="linearGradient39520"
+ gradientUnits="userSpaceOnUse"
+ x1="696.63055"
+ y1="403.93069"
+ x2="643.71313"
+ y2="349.93216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-95"
+ id="linearGradient39523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.8461523,99.385524,54.308237)"
+ x1="633.10468"
+ y1="338.95337"
+ x2="649.69073"
+ y2="354.92981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39716"
+ gradientUnits="userSpaceOnUse"
+ x1="121.80637"
+ y1="106.4641"
+ x2="142.1468"
+ y2="132.44617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39718"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40297"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask40306">
+ <path
+ id="path40308"
+ d="m 195,11.00001 0,14 0.5,0 13.5,-13.5 0,-0.5 -14,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703-5-5"
+ id="linearGradient39261-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="128.09367"
+ y1="112.43961"
+ x2="145.20987"
+ y2="133.4879" />
+ <linearGradient
+ id="linearGradient40703-5-5">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705-8-2" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707-8-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38252-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38254-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38256-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient40511-7-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ id="linearGradient1610-74-9-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-0-8-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-9-3-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient40507-4-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-8-6-5">
+ <stop
+ id="stop58336-8-9-2"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-24-8-7"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient40649-2-6-6"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-5-6-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-17-2-4" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-11-3-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient40502-7-8-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40635-7-2-2"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ id="linearGradient319-5-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-2-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-7-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40637-9-5-8"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973-3-7-8"
+ id="linearGradient40639-1-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.2239"
+ y1="112.62726"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ id="linearGradient13973-3-7-8">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975-1-8-9" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977-2-0-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40641-9-2-7"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient41638-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient41640-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient41642-5-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient41644-5-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40875-3-9-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ id="linearGradient37542-3-0-7-6">
+ <stop
+ id="stop37544-1-6-6-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-2-1-7-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40877-5-5-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ id="linearGradient319-34-8-7-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-11-9-8-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-38-3-1-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40879-9-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="171.50414"
+ y2="248.54021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40881-8-0-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-7-6-7-4"
+ id="radialGradient40883-4-0-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.06118084,-0.8594818,2.4629674,-0.1753088,-259.40057,190.15309)"
+ cx="77.721619"
+ cy="104.09358"
+ fx="77.721619"
+ fy="104.09358"
+ r="3.9999998" />
+ <linearGradient
+ id="linearGradient10069-7-6-7-4">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-81-3-2-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-6-7-5-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39136-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39138-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39140-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="174.35753"
+ y2="250.6842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39143-0-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <linearGradient
+ id="linearGradient319-17-1-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40679"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25417"
+ id="linearGradient40731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.997161,-259.00079,67.35344)"
+ x1="280.0918"
+ y1="129.28557"
+ x2="267.20212"
+ y2="116.41341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40733"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-7"
+ id="linearGradient40733-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-8"
+ id="linearGradient40733-03"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40897">
+ <rect
+ y="198"
+ x="-41"
+ height="16"
+ width="15"
+ id="rect40899"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40902">
+ <rect
+ y="197"
+ x="-22"
+ height="17"
+ width="15"
+ id="rect40904"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38478"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(254.01612,-211.00101)"
+ x1="96.824379"
+ y1="393.90298"
+ x2="94.246101"
+ y2="391.21976" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38474">
+ <rect
+ style="fill:url(#linearGradient38478);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38476"
+ width="15"
+ height="15"
+ x="343.01611"
+ y="174.99901" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44318"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44320"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42992"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7"
+ id="linearGradient42994"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(4.9999967,20)"
+ x1="-114.75"
+ y1="546.5"
+ x2="-110.5"
+ y2="542.5" />
+ <linearGradient
+ id="linearGradient44627">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop44629" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop44631" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9-7-4-74">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44402"
+ gradientUnits="userSpaceOnUse"
+ x1="351.15625"
+ y1="108.35222"
+ x2="345.40625"
+ y2="108.00847" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44404"
+ gradientUnits="userSpaceOnUse"
+ x1="351.71875"
+ y1="106.93575"
+ x2="347.1875"
+ y2="106.7795" />
+ <filter
+ inkscape:collect="always"
+ id="filter44473"
+ x="-0.12578467"
+ width="1.2515693"
+ y="-0.11472401"
+ height="1.229448"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.81235925"
+ id="feGaussianBlur44475" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter44477"
+ x="-0.12176471"
+ width="1.2435294"
+ y="-0.11828571"
+ height="1.2365714"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.8625"
+ id="feGaussianBlur44479" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44485"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="284.5"
+ y2="106.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44942"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="351.71875"
+ y1="106.93575"
+ x2="339.125"
+ y2="105.092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44944"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,698,183)"
+ x1="351.15625"
+ y1="108.35222"
+ x2="336.40625"
+ y2="106.19597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44950"
+ gradientUnits="userSpaceOnUse"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102"
+ gradientTransform="matrix(-1,0,0,1,593.02125,-1.8e-6)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44954"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath45147">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccc"
+ id="path45149"
+ d="m 5,261 13,0 0,1 -1,0 0,1 1,0 0,1 -1,0 0,1 -1,0 0,2 2,0 0,-1 1,0 0,-1 1,0 0,1 1,0 0,-1 1,0 0,13 -17,0 0,-17 z"
+ style="opacity:0.2;fill:#3771c8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient45220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,221,10)"
+ x1="115.84575"
+ y1="10.8125"
+ x2="106.125"
+ y2="19.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45283"
+ gradientUnits="userSpaceOnUse"
+ x1="125.86876"
+ y1="111.85698"
+ x2="130.88379"
+ y2="121.70699" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45285"
+ gradientUnits="userSpaceOnUse"
+ x1="134.78751"
+ y1="122.29202"
+ x2="132.60205"
+ y2="117.96092" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74"
+ id="radialGradient45309"
+ cx="336.42892"
+ cy="611.10455"
+ fx="336.42892"
+ fy="611.10455"
+ r="5.9852905"
+ gradientTransform="matrix(1.0070601,0.03386866,-0.03770425,1.1211085,20.665977,-85.772965)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627"
+ id="linearGradient43826"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,1444.9824,-215)"
+ x1="689.47357"
+ y1="427"
+ x2="685.47357"
+ y2="427" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43822">
+ <rect
+ y="208"
+ x="754"
+ height="9"
+ width="12"
+ id="rect43824"
+ style="opacity:0.93999993;fill:url(#linearGradient43826);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient43856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient43858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46780"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46782"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46784"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46786"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46822"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46824"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46992"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46994"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46998"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient47000"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25106"
+ gradientUnits="userSpaceOnUse"
+ x1="408.91928"
+ y1="373.01221"
+ x2="410.55432"
+ y2="375.5058" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25117"
+ gradientUnits="userSpaceOnUse"
+ x1="411.05389"
+ y1="375.39175"
+ x2="407.62576"
+ y2="370.21317" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient25449"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25451"
+ gradientUnits="userSpaceOnUse"
+ x1="436.54755"
+ y1="524.30481"
+ x2="434.49387"
+ y2="519.46057" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25453"
+ gradientUnits="userSpaceOnUse"
+ x1="432.0849"
+ y1="524.97125"
+ x2="433"
+ y2="526" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="410.73904"
+ cy="370.11554"
+ fx="410.73904"
+ fy="370.11554"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="292.25"
+ y1="106.5"
+ x2="289.5"
+ y2="109.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24341"
+ x1="413.9498"
+ y1="386.45807"
+ x2="406.7699"
+ y2="374.42419"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24349"
+ gradientUnits="userSpaceOnUse"
+ x1="403.9577"
+ y1="367.62839"
+ x2="413.98795"
+ y2="374.07153" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6"
+ id="radialGradient24354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6402148,-1.1088846,0.8413297,0.4857498,104.42892,800.46622)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient24511"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24513"
+ gradientUnits="userSpaceOnUse"
+ x1="256.90005"
+ y1="80.100891"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient24515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24519"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6691529,0,4.3047361e-8,0.6954014,84.50351,24.951375)"
+ cx="259.02887"
+ cy="77.962585"
+ fx="259.02887"
+ fy="77.962585"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3879142,0,8.9286134e-8,1.4423572,-101.87942,-32.970267)"
+ cx="259.55096"
+ cy="77.188034"
+ fx="259.55096"
+ fy="77.188034"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="240.70209"
+ y1="-9.4293213"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient25056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient25058"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25060"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient29407"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29409"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29411"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient29413"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient44939-8-7-1-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient37396-1"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ id="linearGradient37542-7">
+ <stop
+ id="stop37544-40"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-94"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient15742-5"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998"
+ gradientTransform="matrix(0,1,-1,0,634.98585,-146.00607)" />
+ <linearGradient
+ id="linearGradient37542-5">
+ <stop
+ id="stop37544-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-71"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27860"
+ x1="392.02036"
+ y1="241.13428"
+ x2="386.30408"
+ y2="241.31801"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient27872"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27874"
+ gradientUnits="userSpaceOnUse"
+ x1="390.87131"
+ y1="241.13428"
+ x2="386.74603"
+ y2="242.46706"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient27886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,146.99795,-188.00607)"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27896"
+ id="linearGradient27902"
+ x1="388.70071"
+ y1="244.85669"
+ x2="391.17557"
+ y2="249.54126"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient10069-9-71">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-2">
+ <stop
+ id="stop23976-2"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath28964">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient28968);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 117.50984,228.63415 0,-15.01646 11.71735,5.49383 0,15.38271 -11.71735,-5.86008 z"
+ id="path28966"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-2"
+ id="linearGradient28968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ id="linearGradient319-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-26.511335"
+ y1="257.99881"
+ x2="-30.075666"
+ y2="259.87677" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29419">
+ <path
+ id="path29422"
+ d="m 117.50984,229.00041 0,-15.38272 11.71735,5.49383 0,15.74897 -11.71735,-5.86008 z"
+ style="opacity:0.5;fill:url(#linearGradient29424);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ 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" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient29988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-35.153767"
+ y1="271.58572"
+ x2="-23.636715"
+ y2="252.03563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5"
+ id="linearGradient29990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-113.93222,176.71918)"
+ x1="446.93222"
+ y1="105.28082"
+ x2="441.93222"
+ y2="120.28082" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-71"
+ id="linearGradient29994"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="131.72171"
+ y2="118.18078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6-8"
+ id="linearGradient29773-5"
+ gradientUnits="userSpaceOnUse"
+ x1="124.78239"
+ y1="111.13178"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ id="linearGradient21327-6-8">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3-4" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient28526">
+ <stop
+ id="stop28528"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop28530"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-52-2">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-32-8" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-46-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient29334"
+ gradientUnits="userSpaceOnUse"
+ x1="121.74819"
+ y1="104.14172"
+ x2="140.18503"
+ y2="126.89457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient29336"
+ gradientUnits="userSpaceOnUse"
+ x1="155.10138"
+ y1="91.071259"
+ x2="122.40444"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient29338"
+ gradientUnits="userSpaceOnUse"
+ x1="124.66362"
+ y1="126.19594"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29340"
+ gradientUnits="userSpaceOnUse"
+ x1="124.28249"
+ y1="126.88889"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29342"
+ gradientUnits="userSpaceOnUse"
+ x1="147.25899"
+ y1="101.45953"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1138.1963"
+ y1="287.70486"
+ x2="1146.6705"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1286)"
+ x1="757.2467"
+ y1="367.52411"
+ x2="740.30865"
+ y2="405.3895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="745.48267"
+ y1="396.45972"
+ x2="737.62225"
+ y2="401.90442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient28583"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-239.00001,1286)"
+ x1="743"
+ y1="402"
+ x2="752"
+ y2="400" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38845"
+ id="linearGradient28589"
+ gradientUnits="userSpaceOnUse"
+ x1="162.41054"
+ y1="413.87982"
+ x2="161.83331"
+ y2="406.47784"
+ gradientTransform="matrix(0,1,-1,0,574.99991,384.00001)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="743.87036"
+ y1="396.04428"
+ x2="744.1059"
+ y2="423.54419" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,719.99999,383.00001)"
+ x1="148.56801"
+ y1="544.21143"
+ x2="163.11441"
+ y2="569.18829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28603"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1141.2856"
+ y1="288.19919"
+ x2="1146.2682"
+ y2="291.35333" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-52-2"
+ id="radialGradient29805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.94105289,0.01178942,-0.01073736,0.8570756,238.4669,249.70522)"
+ cx="-30.028414"
+ cy="19.425121"
+ fx="-30.028414"
+ fy="19.425121"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29801">
+ <rect
+ style="opacity:0.35;color:#000000;fill:url(#radialGradient29805);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.71217775;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect29803"
+ width="15"
+ height="16"
+ x="204"
+ y="257" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29884"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29886"
+ gradientUnits="userSpaceOnUse"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath50172-0">
+ <path
+ id="path50174-8"
+ d="m -177.34375,498 a 1.001098,1.001098 0 1 0 0.0937,2 l 3.65625,0 -4.25,5.9375 a 1.0001,1.0001 0 0 0 -0.1875,0.59375 l 0,0.5 a 1.0001,1.0001 0 0 0 1,1 L -171.75,508 a 1.0001,1.0001 0 1 0 0,-2 l -3.6875,0.0312 4.25,-5.9375 A 1.0001,1.0001 0 0 0 -171,499.5 l 0,-0.5 a 1.0001,1.0001 0 0 0 -1,-1 l -5.25,0 a 1.0001,1.0001 0 0 0 -0.0937,0 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <radialGradient
+ id="radialGradient16142-7"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16144-4" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16146-0" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient37542-78">
+ <stop
+ id="stop37544-2"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-78"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-0" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-89" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-04-82">
+ <stop
+ id="stop37544-9-0"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-4-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-38-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-6-7" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-9-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30766-8"
+ inkscape:collect="always">
+ <stop
+ id="stop30768-7"
+ offset="0"
+ style="stop-color:#be0000;stop-opacity:1" />
+ <stop
+ id="stop30770-8"
+ offset="1"
+ style="stop-color:#ff5108;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30752-0">
+ <stop
+ style="stop-color:#0c1b63;stop-opacity:1;"
+ offset="0"
+ id="stop30754-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop30756-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-64,-10)"
+ x1="18.773417"
+ y1="6.2494373"
+ x2="6.9718256"
+ y2="17.82831" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.701513,0.712657,0.712657,0.701513,50.5916,-449.6745)"
+ x1="385.62408"
+ y1="244.3396"
+ x2="401.63013"
+ y2="244.38875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-65.00001,-10.749995)"
+ x1="61.032951"
+ y1="5.9830923"
+ x2="46.491322"
+ y2="20.147326" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32146"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.199998,0,0,1.199999,-74.19988,-12.499988)"
+ x1="59.02124"
+ y1="6.0129876"
+ x2="44.509518"
+ y2="20.110929" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32148"
+ gradientUnits="userSpaceOnUse"
+ x1="47.348152"
+ y1="-25.553123"
+ x2="53.567928"
+ y2="-31.095215" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142-7"
+ id="linearGradient31946"
+ gradientUnits="userSpaceOnUse"
+ x1="-176.1799"
+ y1="508.33572"
+ x2="-193.07495"
+ y2="482.27924" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142"
+ id="linearGradient31948"
+ gradientUnits="userSpaceOnUse"
+ x1="-178.00789"
+ y1="505.36523"
+ x2="-194.90294"
+ y2="479.30875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-78"
+ id="linearGradient31950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="155.37498"
+ y1="230.51552"
+ x2="181.25543"
+ y2="269.24564" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-04-82"
+ id="linearGradient31954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-354.13606,119.42158)"
+ x1="148.47061"
+ y1="217.28368"
+ x2="171.77303"
+ y2="250.87756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-38-2"
+ id="linearGradient31956"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="-259.99872"
+ y1="340.81195"
+ x2="-253.90541"
+ y2="345.10736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30766-8"
+ id="linearGradient31958"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0017964,0,0,0.99629977,-0.31613165,0.94171311)"
+ x1="167.51979"
+ y1="252.44223"
+ x2="170.78137"
+ y2="261.69635" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31960"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.473038"
+ y1="238.21507"
+ x2="89.889603"
+ y2="243.80345" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30752-0"
+ id="linearGradient31962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.53265"
+ y1="244.52007"
+ x2="168.53265"
+ y2="239.5473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-237.5,45.5045)"
+ x1="263.35254"
+ y1="19.495501"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31966"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-238,44.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-243.5,51.5045)"
+ x1="260.25369"
+ y1="11.017987"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31970"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-244,50.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31972"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-57.00003,-165.99191)"
+ x1="85.853188"
+ y1="239.5473"
+ x2="90.563423"
+ y2="242.99191" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31974"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-51,-172)"
+ x1="88"
+ y1="240.90625"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28526"
+ id="linearGradient32236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-175.72238"
+ y1="66.323799"
+ x2="-183.03308"
+ y2="66.235535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-8-4"
+ id="linearGradient32238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-174.51762"
+ y1="66.654762"
+ x2="-183.58472"
+ y2="65.917358" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62"
+ id="linearGradient32240"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,406.86085,228.58514)"
+ x1="-180.7581"
+ y1="63.445515"
+ x2="-169.07387"
+ y2="62.182106" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.861107"
+ y2="-15.138513" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.705353"
+ y2="-15.562586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29312"
+ id="linearGradient32246"
+ gradientUnits="userSpaceOnUse"
+ x1="242.99834"
+ y1="291.5047"
+ x2="244.75"
+ y2="291.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29304"
+ id="linearGradient32248"
+ gradientUnits="userSpaceOnUse"
+ x1="245.20622"
+ y1="294.49902"
+ x2="243.5"
+ y2="294.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32299"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32301"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.000005,-120)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32303"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-9.025729,344.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient32305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-14.983875,337)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32353"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32355"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32357"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,39.488451,313.56226)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32359"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32426"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32428"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32430"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.77915445,-6.9426235e-4,0.00527501,0.79821029,158.94945,341.39422)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7"
+ id="linearGradient32434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31019"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31025"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="84.95932"
+ y2="122.23821" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.14826,118.6716)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.74301467,-0.74301467,0.74301467,0.74301467,250.58064,118.02214)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-19-1"
+ id="linearGradient32854-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1666676,0,0,-1.1666676,119.15081,827.66691)"
+ x1="262.04343"
+ y1="233.0448"
+ x2="273.85818"
+ y2="247.32738" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-19-1">
+ <stop
+ id="stop37544-48-6-1-8-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-6-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-7-8-3-0-3"
+ id="linearGradient32856-3-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,-249.10439,522.04547)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient44939-8-4-7-8-3-0-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-40-2-4-2-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-9-4-9-8-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-5-4-6-5-0-3"
+ id="linearGradient32858-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,144.9138,-563.9364)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient10069-9-7-5-4-6-5-0-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-58-5-9-1-2-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-4-0-8-0-4-9" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52637-8-8">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52641-2-8);fill-opacity:1;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52639-8-9"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52641-2-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-361.27885,-161.73915)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-0-9-9">
+ <stop
+ id="stop37544-48-6-1-4-1-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-9-3-3"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient52998-5-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-307"
+ y1="475"
+ x2="-303.00003"
+ y2="463.92236" />
+ <linearGradient
+ id="linearGradient319-31-8-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-23-2-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-34-4-4-2" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52879-0-5">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52883-6-8);fill-opacity:1;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52881-7-3"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354.95001"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52883-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-362.22886,-161.73912)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient53000-3-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-308.7684"
+ y1="476.0105"
+ x2="-304.76843"
+ y2="464.93286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34488-1-8"
+ id="linearGradient53002-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-839.95,-273.25)"
+ x1="469.49295"
+ y1="-101.22778"
+ x2="470.7515"
+ y2="-102.52942" />
+ <linearGradient
+ id="linearGradient34488-1-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop34490-0-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop34492-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32877-9-6-8"
+ id="linearGradient32896-0-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-217.1391"
+ y1="626.39844"
+ x2="-213.69197"
+ y2="623.21643" />
+ <linearGradient
+ id="linearGradient32877-9-6-8">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0"
+ id="stop32879-8-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop32881-4-3-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-4-9-5"
+ id="linearGradient32899-8-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-180.37465"
+ y1="650.94128"
+ x2="-177.70576"
+ y2="653.27765" />
+ <linearGradient
+ id="linearGradient33058-4-9-5">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-3-3-9" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-9-4-7" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32901-4-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1748275,-1.7208853,0.51495275,0.35155123,-289.20197,69.961171)"
+ cx="-197.66467"
+ cy="630.61389"
+ fx="-197.66467"
+ fy="630.61389"
+ r="7.03125" />
+ <linearGradient
+ id="linearGradient44939-8-4-8-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-0-0-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-8-6-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-2-7-1-7"
+ id="linearGradient32903-6-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-218.31921"
+ y1="624.84143"
+ x2="-215.31401"
+ y2="628.46533" />
+ <linearGradient
+ id="linearGradient33058-2-7-1-7">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-1-8-8-5" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-4-3-4-5" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32905-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.62164476,0.39733376,-0.55111069,0.86222272,269.0477,166.72227)"
+ cx="-202.18748"
+ cy="627"
+ fx="-202.18748"
+ fy="627"
+ r="7.03125" />
+ <linearGradient
+ y2="-102.52942"
+ x2="470.73633"
+ y1="-101.3037"
+ x1="469.52335"
+ gradientTransform="translate(-829.95,-273.25)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient58927"
+ xlink:href="#linearGradient34488-1-8"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-71-6-9-7"
+ id="linearGradient21875-7-1-0-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="278.34866"
+ y2="32.902874" />
+ <linearGradient
+ id="linearGradient1610-71-6-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-26-8-5-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-04-8-8-0" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106-9-2-9-9">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850-4-7-0-4"
+ 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" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011-6-7-0-8"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013-0-1-0-8" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-6-6-2-4"
+ id="linearGradient21877-3-2-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ id="linearGradient5060-6-6-2-4">
+ <stop
+ id="stop5062-2-0-5-5"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-4-4-5-5"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4671-6-4-1-7"
+ id="linearGradient34959-9-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1666.1765"
+ y1="639.65356"
+ x2="1659.0875"
+ y2="629.23273" />
+ <linearGradient
+ id="linearGradient4671-6-4-1-7">
+ <stop
+ id="stop4673-7-6-4-1"
+ offset="0"
+ style="stop-color:#ffd43b;stop-opacity:1;" />
+ <stop
+ id="stop4675-8-0-8-1"
+ offset="1"
+ style="stop-color:#ffe873;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4689-1-6-4-2"
+ id="linearGradient34961-3-6-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1641.4773"
+ y1="607.50525"
+ x2="1663.2872"
+ y2="626.40344" />
+ <linearGradient
+ id="linearGradient4689-1-6-4-2">
+ <stop
+ id="stop4691-6-2-6-7"
+ offset="0"
+ style="stop-color:#5a9fd4;stop-opacity:1;" />
+ <stop
+ id="stop4693-0-4-8-6"
+ offset="1"
+ style="stop-color:#306998;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34963-5-9-1"
+ gradientUnits="userSpaceOnUse"
+ x1="922.89703"
+ y1="339.66599"
+ x2="924.10608"
+ y2="344.10001" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-88-8-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-2-5-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34965-1-5-2"
+ gradientUnits="userSpaceOnUse"
+ x1="919.09998"
+ y1="345.42163"
+ x2="922.104"
+ y2="355.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-8-9-5-5"
+ id="linearGradient34967-4-1-8"
+ gradientUnits="userSpaceOnUse"
+ x1="922.64624"
+ y1="342.71866"
+ x2="921.82654"
+ y2="341.98108" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-8-9-5-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-9-8-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-0-2-8-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34969-4-4-1"
+ gradientUnits="userSpaceOnUse"
+ x1="917.75"
+ y1="355.5"
+ x2="917.25"
+ y2="353" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34971-5-0-9"
+ gradientUnits="userSpaceOnUse"
+ x1="923"
+ y1="343.75"
+ x2="923"
+ y2="344.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="radialGradient34973-2-5-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4166677,-7.678944e-6,1.853542e-6,0.58333478,-1309.0016,145.80659)"
+ cx="924"
+ cy="349.20001"
+ fx="924"
+ fy="349.20001"
+ r="6" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34975-9-4-9"
+ gradientUnits="userSpaceOnUse"
+ x1="921.34045"
+ y1="341.34042"
+ x2="922.16492"
+ y2="342.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-4-6-7-7"
+ id="linearGradient47921-1-7-1-1"
+ gradientUnits="userSpaceOnUse"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-4-6-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-2-4-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-3-5-0-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-2-6-4-4"
+ id="linearGradient47923-2-8-9-9"
+ gradientUnits="userSpaceOnUse"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-2-6-4-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-1-1-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-6-5-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ id="linearGradient47925-8-5-2-2"
+ gradientUnits="userSpaceOnUse"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-45-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-5-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-1-5" />
+ </linearGradient>
+ <linearGradient
+ y2="609.36218"
+ x2="221"
+ y1="604.31494"
+ x1="219"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient49198-1-1"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-1-1-9-4-7-1"
+ id="linearGradient59244-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.40161"
+ y2="29.679312" />
+ <linearGradient
+ id="linearGradient1610-1-1-9-4-7-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-74-7-2-2-2-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-09-4-7-5-1-5" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-4-0-5-2-4-7"
+ id="radialGradient59246-2"
+ 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
+ id="linearGradient40578-4-8-4-0-5-2-4-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-8-9-4-6-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-8-4-3-8-9-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-24-8-2-6-0-2"
+ id="linearGradient59248-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-24-8-2-6-0-2">
+ <stop
+ id="stop58336-55-8-3-6-3-3"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-17-2-3-3-0-2"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-11-1-4-3-1"
+ id="linearGradient59250-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-11-1-4-3-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-5-1-5-5-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-27-3-6-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-1-7-5-7-7"
+ id="linearGradient59252-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-1-7-5-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-7-4-3-6-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-1-2-5-7-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-5-7-6-8-9"
+ id="linearGradient59254-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-5-7-6-8-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-2-9-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-7-3-4-6-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient59256-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-8-9-6-4-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-2-8-2-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-4-6-6-1-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient59258-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="219"
+ y1="604.31494"
+ x2="221"
+ y2="609.36218" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10000"
+ objecttolerance="10000"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="147.30844"
+ inkscape:cy="114.24342"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1912"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:snap-nodes="true"
+ inkscape:snap-bbox="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:object-nodes="false"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-intersection-grid-guide="false"
+ inkscape:window-maximized="1"
+ inkscape:bbox-paths="false"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-grids="true"
+ inkscape:snap-to-guides="false"
+ inkscape:snap-page="false"
+ units="px"
+ inkscape:snap-center="false"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid17394"
+ visible="true"
+ enabled="true"
+ spacingx="0.25px"
+ spacingy="0.25px"
+ empspacing="4"
+ color="#808080"
+ opacity="0.09803922"
+ dotted="false"
+ empcolor="#7f7f7f"
+ empopacity="0.25098039"
+ snapvisiblegridlinesonly="true"
+ originx="0px"
+ originy="0px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Blender icons v. 2.5.06</dc:title>
+ <dc:date>21.05.2012</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:coverage />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-nc-sa/3.0/" />
+ <dc:description>This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed.</dc:description>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-nc-sa/3.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:prohibits
+ rdf:resource="http://creativecommons.org/ns#CommercialUse" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer3"
+ inkscape:label="bckgrnd"
+ style="display:none"
+ sodipodi:insensitive="true"
+ transform="translate(-872,-180)">
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect20607"
+ width="1083.874"
+ height="650"
+ x="-4"
+ y="-4" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;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"
+ id="path23417"
+ sodipodi:nodetypes="cc"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23347"
+ sodipodi:nodetypes="cc"
+ d=""
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:label="ICONS"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline"
+ transform="translate(-872,-180)">
+ <g
+ id="g10203"
+ transform="translate(-211.20006,170)" />
+ <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
+ id="g14009"
+ transform="translate(1,-0.01245054)" />
+ <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">
+ <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>
+ <g
+ id="g16279"
+ transform="translate(318,7.00009)" />
+ <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="g12156"
+ transform="translate(-130.97687,-108)" />
+ <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="g11534"
+ transform="translate(21,-1)" />
+ <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
+ 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
+ transform="translate(-174.00091,22.99815)"
+ id="g15532" />
+ <g
+ transform="translate(-111.96756,-108)"
+ id="g15923">
+ <g
+ id="g15925" />
+ </g>
+ <g
+ transform="translate(189.19394,55.494451)"
+ id="g15616" />
+ <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)" />
+ <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="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(47,-247.0151)"
+ id="g51988" />
+ <g
+ style="display:inline"
+ id="g57337"
+ transform="translate(10,254)" />
+ <g
+ id="g23613" />
+ <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="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
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(-65,-169.00755)"
+ id="g24176" />
+ <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
+ 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="g77742"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-870.9421,-297.02038)" />
+ <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="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(250,-41.00755)"
+ id="g36511" />
+ <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
+ transform="translate(259,168)"
+ mask="url(#mask38561)"
+ id="g40090" />
+ <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
+ 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
+ id="g32752"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\v. 2.5.06\prvicons v.2.5.06.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="180"
+ x="872"
+ height="192"
+ width="192"
+ id="rect30285"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.39191818;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ transform="translate(856,-203)"
+ id="g21955"
+ style="opacity:0.3;display:inline;enable-background:new">
+ <rect
+ 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"
+ id="rect21957"
+ width="48"
+ height="48"
+ x="108"
+ y="430"
+ rx="2.4004419"
+ ry="0" />
+ <g
+ id="g21959">
+ <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="path21961"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient21977);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21963"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21965"
+ 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)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21967"
+ style="fill:none;stroke:url(#linearGradient21979);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 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" />
+ <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 115.5,442.75 0,31.75 33,0 0,-41 -23.75,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="path21969"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21971"
+ 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)" />
+ <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="path21973"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21975"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g30335">
+ <g
+ id="g21367"
+ transform="translate(760,-202)">
+ <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="path21369"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30321);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21371"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21373"
+ 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)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21375"
+ style="fill:none;stroke:url(#linearGradient30323);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 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" />
+ <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 115.5,442.75 0,31.75 33,0 0,-41 -23.75,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="path21377"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21569"
+ 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)" />
+ <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="path21379"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21381"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="font-size:33.49144363px;font-style:normal;font-weight:normal;fill:#214478;fill-opacity:1;stroke:none;display:inline;font-family:Bitstream Vera Sans"
+ d="m 891.07148,245 -0.0715,9 2.39012,0 C 896,254 896,253 896.5,251 l 0.5,0 0,7 -0.5,0 c -0.5,-2 -0.5,-3 -3.10988,-3 L 891,255 l 0,7 c 0,2.5 1,3.25 3.14146,3.39973 l -0.004,0.60029 L 885,266 l 0.004,-0.60029 C 887,265.25 888,264.5 888.00001,262 L 888,248 c 0,-2.5 -1,-3.25 -3,-3.5 l 0,-0.5 16,0 0,5 -0.5,0 c -0.50001,-1.99999 -1.5,-4 -4.5,-4 l -4.92852,0 z"
+ id="text13209"
+ sodipodi:nodetypes="ccccccccccccccccccccccc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21625"
+ transform="translate(904,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21627"
+ 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" />
+ <g
+ id="g21629">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21647);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21631"
+ 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" />
+ <g
+ style="opacity:0.5;fill:#000000;display:inline"
+ id="g16261"
+ transform="matrix(1.2499985,0,0,1,-87.6203,-147.85351)">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35099"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="598.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35101"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="600.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15690"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="602.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15692"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="604.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15694"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="606.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15696"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="608.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15698"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="610.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15700"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="612.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15732"
+ width="14.400002"
+ height="1"
+ x="167.69646"
+ y="614.85352"
+ rx="0.09920612"
+ ry="0.065390877" />
+ <g
+ transform="translate(150.89645,557.85352)"
+ id="g4849"
+ style="fill:#000000;display:inline">
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="29"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15736"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="31"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15738"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="33"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15740"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="35"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15742"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.055114571"
+ y="37"
+ x="16.799992"
+ height="1"
+ width="8.0000095"
+ id="rect15744"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ ry="0.065390304"
+ rx="0.0057410933"
+ y="617.85352"
+ x="184.49646"
+ height="0.99999124"
+ width="0.83333319"
+ id="rect16334"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21633"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21635"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21649);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21637"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21639"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21641"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21643"
+ 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" />
+ <g
+ id="g35119"
+ transform="translate(2,-160.99999)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ transform="translate(105.39645,589.71201)"
+ id="g16097">
+ <g
+ id="g16099"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)">
+ <radialGradient
+ id="radialGradient16101"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16103" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16105" />
+ </radialGradient>
+ <radialGradient
+ id="radialGradient16109"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16111" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16113" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ id="path16107" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#radialGradient21565);fill-rule:nonzero;stroke:none"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ id="path16117" />
+ </g>
+ <g
+ id="g16131"
+ transform="translate(105.39645,579.71201)"
+ style="display:inline">
+ <g
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ id="g16133">
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="114.5684"
+ fx="20.892099"
+ r="5.256"
+ cy="114.5684"
+ cx="20.892099"
+ id="radialGradient16135">
+ <stop
+ id="stop16137"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16140"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="64.567902"
+ fx="20.892099"
+ r="5.257"
+ cy="64.567902"
+ cx="20.892099"
+ id="radialGradient16142">
+ <stop
+ id="stop16144"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16146"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path35139"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35141"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ style="fill:url(#radialGradient21567);fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21645"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21572"
+ transform="translate(808,-203)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21574"
+ 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" />
+ <g
+ id="g21576">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21594);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21578"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21580"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21582"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21596);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21584"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21586"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path21588"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21590"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path21592"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ id="g30382">
+ <g
+ id="g23655"
+ transform="translate(760,-154)">
+ <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="path23657"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30368);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path23659"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path23661"
+ 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)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path23663"
+ style="fill:none;stroke:url(#linearGradient30370);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 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" />
+ <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 115.5,442.75 0,31.75 33,0 0,-41 -23.75,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="path23665"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path23667"
+ 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)" />
+ <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="path23669"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;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\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23671"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 888,295 1,0 0,14 -1,0 0,-14 z"
+ id="path23675"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23677"
+ d="m 900,294 1.00002,-1 0,14 -1.00002,0 0,-13 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path23679"
+ d="m 901.00003,292 0,2.25 -13.00002,2 0,-2.25 13.00002,-2 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23681"
+ transform="matrix(1.1428564,0,0,1.2000001,822.71436,-355.40005)">
+ <path
+ transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)"
+ 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"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23683"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ id="path23685"
+ sodipodi:cx="53"
+ 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"
+ transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
+ inkscape:transform-center-y="0.3813435"
+ clip-path="url(#clipPath20586)" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.38999999;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 901.00003,292 -1e-5,1 -13.00002,2 10e-6,-1 13.00002,-2 z"
+ id="path23694"
+ sodipodi:nodetypes="ccccc" />
+ <g
+ transform="matrix(1.1428564,0,0,1.2000001,834.71436,-357.40005)"
+ id="g23717">
+ <path
+ sodipodi:type="arc"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23724"
+ sodipodi:cx="53"
+ 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"
+ 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"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23726"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g23922"
+ transform="translate(-16,-220)"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g23924"
+ transform="translate(824,66)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect23926"
+ 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" />
+ <g
+ id="g23928">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient23978);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path23930"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23932"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path23934"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient23980);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23936"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path23938"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path23940"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path23942"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path23944"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccc"
+ id="path23946"
+ d="m 952,530 0,10 1,0 1,0 11,0 1,0 1,0 0,-10 -15,0 z m 1,2 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient23982);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23948"
+ width="13"
+ height="5.5"
+ x="953"
+ y="-524" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23952"
+ transform="translate(76,0)"
+ d="m 876,514 0,17 15,0 0,-17 -1,0 0,1 -1,0 0,-1 -11,0 0,1 -1,0 0,-1 -1,0 z m 1,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
+ style="fill:url(#linearGradient23986);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 952,507 3,0 0,3 9,0 0,-3 3,0 0,7 -15,0 0,-7 z m 1,0 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z m 12,-4 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z"
+ id="path23954" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="507"
+ height="9"
+ width="3"
+ id="rect23956"
+ style="fill:url(#linearGradient23988);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23958"
+ width="9"
+ height="9"
+ x="512"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="523"
+ height="9"
+ width="9"
+ id="rect23960"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ transform="matrix(0,-0.5624971,0.5624971,0,893.12531,590.74965)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path23962"
+ 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="path23964"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,601.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path23966"
+ d="m 961.00001,519.00005 -3,0 0,-0.99992 0.99994,0 6e-5,-2.00008 -1,0 0,-1 1,0 0,-1 1.00006,0 0,4.00008 0.99994,0 0,0.99992 z" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,525 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -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"
+ id="path23968" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23970"
+ width="6"
+ height="9"
+ x="534"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ clip-path="url(#clipPath23877)"
+ id="g23972">
+ <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="path23974"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,612.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,536 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,1 -2,0 0,1 2,0 0,-1 z"
+ id="path23976" />
+ </g>
+ </g>
+ <g
+ transform="translate(208,88)"
+ id="g45475"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g22242"
+ transform="translate(696,-194)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect22244"
+ 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" />
+ <g
+ id="g22246">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient22274);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path22249"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path22251"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path22253"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient22276);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path22264"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path22266"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106)"
+ 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="cccc"
+ id="path22268"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path22270"
+ 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"
+ sodipodi:nodetypes="ccc"
+ id="path22272"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ id="g21517"
+ inkscape:label="Layer 1"
+ transform="matrix(0.5406242,0,0,0.5829534,814.13667,247.65542)">
+ <path
+ transform="matrix(1.274286,0,0,1.377124,-7.569123,-16.70193)"
+ 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"
+ sodipodi:ry="5.3033009"
+ sodipodi:rx="15.467961"
+ sodipodi:cy="38.98439"
+ sodipodi:cx="28.019106"
+ id="path35486"
+ style="opacity:0.54857142;fill:url(#radialGradient21442);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssssssssscccsscccscccssccc"
+ 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"
+ id="path2482"
+ style="fill:#f57900;fill-rule:evenodd;stroke:#aa4400;stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ transform="matrix(0.8018194,0,0,0.8471126,6.257567,4.5089892)"
+ 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"
+ sodipodi:ry="10.125"
+ sodipodi:rx="11.5625"
+ sodipodi:cy="25.75"
+ sodipodi:cx="31.1875"
+ id="path39153"
+ style="fill:url(#linearGradient21444);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.4857143;fill:none;stroke:url(#linearGradient21446);stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
+ 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"
+ id="path21414"
+ sodipodi:nodetypes="csssssscssscsssccssscscccsccssssccscsscccssssc" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ id="path2478"
+ style="fill:#3465a4;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssscsccsscsccssssscsscccsssc"
+ id="path39166"
+ 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"
+ style="opacity:0.51999996;fill:url(#radialGradient21448);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.5"
+ id="g24847"
+ transform="translate(162,248)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24867);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24849"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24851"
+ style="opacity:0.07999998;fill:url(#linearGradient24869);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24853"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24871);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:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24855"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,4.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24857" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24859"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24861" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24863"
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24873);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24865"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.5"
+ transform="translate(114,248)"
+ id="g24784">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z"
+ id="path24789"
+ style="fill:url(#linearGradient24809);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ style="opacity:0.07999998;fill:url(#linearGradient24811);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24791" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient24813);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 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ id="path24793"
+ sodipodi:nodetypes="csccsczc"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-ydpi="74.800003" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccssccc"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path24796"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24799"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 840.5,89 0,4.5"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24801" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24803"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ sodipodi:nodetypes="cccccccsc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsscccssssccc"
+ style="fill:none;stroke:#000000;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="path24805"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscc"
+ id="path24807"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ style="fill:none;stroke:url(#linearGradient24815);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ <g
+ transform="translate(0,-2)"
+ style="opacity:0.4;stroke:#3d361a;filter:url(#filter44473)"
+ id="g44424">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44406"
+ d="m 950.25,362 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44408"
+ d="M 948.25,354.25 944,350.00563 939.75,354.25"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ </g>
+ <g
+ transform="translate(617,273)"
+ id="g44334"
+ style="display:inline;enable-background:new">
+ <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="rect44336"
+ width="16"
+ height="16"
+ x="320"
+ y="73" />
+ <g
+ transform="translate(0,-21)"
+ id="g44338">
+ <g
+ id="g44340">
+ <g
+ transform="translate(0,21)"
+ id="g44342">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44344"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44346"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g44348">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ id="path44350"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path44352"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 328.5,107.5 5,0 m -7,-9 0,8.5 m -4.25,-7 4.5,-4.5"
+ id="path44354"
+ sodipodi:nodetypes="cccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(66,248)"
+ id="g24818"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24839);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24821"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24823"
+ style="opacity:0.07999998;fill:url(#linearGradient24841);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24825"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-16 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,17 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24843);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:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24827"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,7.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24829" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24831"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,98.75 0,14.75 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-16 34,0 m -29,-10 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24833" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-16 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-8 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24835"
+ style="fill:none;stroke:#000000;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"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24845);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,96.500004 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,15.999996 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24837"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.4;filter:url(#filter44477)"
+ id="g44455">
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44446"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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,108.25 0,-4.25 4.25,0"
+ id="path44449"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="cs"
+ id="path44451"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="ccc"
+ id="path44453"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#3d361a;stroke-width:5;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
+ transform="translate(645,273.05)"
+ id="g44356"
+ style="display:inline;enable-background:new">
+ <rect
+ y="73"
+ x="341"
+ height="16"
+ width="16"
+ id="rect44358"
+ 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(0,-21)"
+ id="g44360">
+ <g
+ id="g44362">
+ <g
+ id="g44364">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44366"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#000000;stroke-width:3.5;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="path44368"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;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" />
+ </g>
+ <g
+ id="g44370">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;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 343,108.25 0,-4.25 4.25,0"
+ id="path44372"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;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 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44374"
+ sodipodi:nodetypes="cs" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path44376"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g44378"
+ transform="matrix(-1,0,0,-1,698,204)">
+ <g
+ id="g44380">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.5;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.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44382"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;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,108.25 0,-4.25 4.25,0"
+ id="path44384"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ id="g44386">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44388"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#e6e6e6;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" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44390"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#e6e6e6;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" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ id="path44392" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44402);stroke-width:1.10000002;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 344.90625,106.59375 c 2.52573,2.51828 6.66805,2.52691 9.1875,0 l 0.5,-0.5"
+ id="path44394"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 350.5,99.5 4,0 0,-4"
+ id="path44396"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ 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"
+ d="m 347.5,103.5 -4.5,0 c -0.25,0 -0.5,0.25 -0.5,0.5 l 0,4.5"
+ id="path44398"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44404);stroke-width:1.10000002;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 345.59375,105.90625 c 2.07803,2.0719 5.36384,2.10325 7.53125,0.1875 L 354,105.25"
+ id="path44400"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g34977"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g21853-3"
+ transform="translate(856,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21855-8"
+ 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" />
+ <g
+ id="g21857-6">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21875-7-1-0-1);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21859-9"
+ 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"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21861-8"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ 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="cccc"
+ id="path21863-6"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ 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 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21877-3-2-7-2);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21865-6"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21867-2"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 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"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ 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="cccc"
+ id="path21869-3"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21871-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:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21873-2"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,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" />
+ </g>
+ </g>
+ <g
+ id="g34938"
+ transform="translate(63,-47)">
+ <path
+ id="path61236"
+ style="color:#000000;fill:url(#linearGradient34959-9-2-1);fill-opacity:1;fill-rule:nonzero;stroke:#ff0000;stroke-width:0.17893334;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 919.5,356.5067 0,-3 c 0,-1.73575 1.26424,-3 3,-3 l 5,0 c 1.73576,0 3,-1.26425 3,-3 l 0,-3.0064 2.5,0.006 c 2,0 3.5,2.5 3.5,6 0,3.5 -1.25,6 -3.5,6 -4.98134,0 -12.77318,0 -2.5,0 l 0,2.75 c 0,2.5 -2,3.24997 -5.5,3.24998 l 0,2e-5 c -3.5,0.0104 -5.5,-0.75 -5.5,-3.25 l 0,-2.7628"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssccsscsccsc" />
+ <path
+ sodipodi:nodetypes="cssssccsscsccsc"
+ inkscape:connector-curvature="0"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3.0064 -2.5,-0.006 c -2,0 -3.5,-2.5 -3.5,-6 0,-3.5 1.25,-6 3.5,-6 4.98134,0 12.77318,0 2.5,0 l 0,-2.75 c 0,-2.5 2,-3.24997 5.5,-3.24998 l 0,-2e-5 c 3.5,-0.0104 5.5,0.75 5.5,3.25 l 0,2.7628"
+ style="color:#000000;fill:url(#linearGradient34961-3-6-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.17893334;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61233" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccscccsccccsccccc"
+ id="path61167"
+ d="m 925,338.50002 c -3.5,10e-6 -5.5,0.74998 -5.5,3.24998 l 0,2.75 5.5,0 -8,0 c -2.25,0 -3.5,2.5 -3.5,6 0,3.5 1.5,6 3.5,6 l 2.5,0.0128 0,2.9872 c 0,2 2,3.01281 5.5,3.0128 3.5,-1e-5 5.5,-1.0128 5.5,-3.0128 l 0,-3 -5.5,0 8,0 c 2,0 3.5,-2.5 3.5,-6 0,-3.5 -1.5,-6 -3.5,-6 l -2.5,0.0128 0,-2.7628 c 0,-2.5 -2,-3.26045 -5.5,-3.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path61169"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.78431373;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 923,342 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path61220"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ d="m 929,359 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="359"
+ sodipodi:cx="928"
+ id="path61222"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <g
+ style="opacity:0.4"
+ id="g61345">
+ <path
+ style="fill:none;stroke:url(#linearGradient34963-5-9-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ id="path61333"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cszsc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient34965-1-5-2);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5 0,3 1.28917,5 2.5,5 l 1.5,0"
+ id="path61335"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccszsc" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ id="path61337"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 918.5,355.25 0,-1.75 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ id="path61339"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssc" />
+ <path
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)"
+ sodipodi:type="arc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34967-4-1-8);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61355"
+ sodipodi:cx="922"
+ sodipodi:cy="342"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 923,342 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" />
+ </g>
+ <g
+ style="opacity:0.8;stroke:#ff0000"
+ transform="matrix(-1,0,0,-1,1850,701)"
+ id="g34104">
+ <path
+ sodipodi:nodetypes="cszsc"
+ inkscape:connector-curvature="0"
+ id="path34106"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ style="fill:none;stroke:none" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path34108"
+ d="m 914.5,350.5 c 0,3 1.28917,5 2.5,5 l 1.5,0"
+ style="fill:none;stroke:url(#linearGradient34969-4-4-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path34110"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ style="fill:none;stroke:url(#linearGradient34971-5-0-9);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0"
+ id="path34113"
+ d="m 918.5,355.5 0,-2 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ style="fill:none;stroke:url(#radialGradient34973-2-5-7);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ d="m 923,342 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"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path34115"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34975-9-4-9);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5"
+ id="path34901"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccsc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g46790"
+ transform="translate(0,12)" />
+ <g
+ id="g46890" />
+ <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>
+</svg>
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 41284eff9c1..7affcab8a82 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/datafiles/splash_template.xcf b/release/datafiles/splash_template.xcf
new file mode 100644
index 00000000000..6d7e7d42c9f
--- /dev/null
+++ b/release/datafiles/splash_template.xcf
Binary files differ
diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend
index cdd43c74f3b..d19cd414eb4 100644
--- a/release/datafiles/startup.blend
+++ b/release/datafiles/startup.blend
Binary files differ
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index 6bf81d73f8b..02115054396 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -29,7 +29,7 @@ __all__ = (
)
import bpy as _bpy
-
+_user_preferences = _bpy.context.user_preferences
error_duplicates = False
error_encoding = False
@@ -201,16 +201,16 @@ def check(module_name):
:rtype: tuple of booleans
"""
import sys
- loaded_default = module_name in _bpy.context.user_preferences.addons
+ loaded_default = module_name in _user_preferences.addons
mod = sys.modules.get(module_name)
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
if loaded_state is Ellipsis:
print("Warning: addon-module %r found module "
- "but without __addon_enabled__ field, "
- "possible name collision from file: %r" %
- (module_name, getattr(mod, "__file__", "<unknown>")))
+ "but without __addon_enabled__ field, "
+ "possible name collision from file: %r" %
+ (module_name, getattr(mod, "__file__", "<unknown>")))
loaded_state = False
@@ -232,6 +232,7 @@ def enable(module_name, default_set=True, persistent=False):
import os
import sys
+ from bpy_restrict_state import RestrictBlend
def handle_error():
import traceback
@@ -259,34 +260,38 @@ def enable(module_name, default_set=True, persistent=False):
# Split registering up into 3 steps so we can undo
# if it fails par way through.
- # 1) try import
- try:
- mod = __import__(module_name)
- mod.__time__ = os.path.getmtime(mod.__file__)
- mod.__addon_enabled__ = False
- except:
- handle_error()
- return None
-
- # 2) try register collected modules
- # removed, addons need to handle own registration now.
-
- # 3) try run the modules register function
- try:
- mod.register()
- except:
- print("Exception in module register(): %r" %
- getattr(mod, "__file__", module_name))
- handle_error()
- del sys.modules[module_name]
- return None
+ # disable the context, using the context at all is
+ # really bad while loading an addon, don't do it!
+ with RestrictBlend():
+
+ # 1) try import
+ try:
+ mod = __import__(module_name)
+ mod.__time__ = os.path.getmtime(mod.__file__)
+ mod.__addon_enabled__ = False
+ except:
+ handle_error()
+ return None
+
+ # 2) try register collected modules
+ # removed, addons need to handle own registration now.
+
+ # 3) try run the modules register function
+ try:
+ mod.register()
+ except:
+ print("Exception in module register(): %r" %
+ getattr(mod, "__file__", module_name))
+ handle_error()
+ del sys.modules[module_name]
+ return None
# * OK loaded successfully! *
if default_set:
# just in case its enabled already
- ext = _bpy.context.user_preferences.addons.get(module_name)
+ ext = _user_preferences.addons.get(module_name)
if not ext:
- ext = _bpy.context.user_preferences.addons.new()
+ ext = _user_preferences.addons.new()
ext.module = module_name
mod.__addon_enabled__ = True
@@ -327,7 +332,7 @@ def disable(module_name, default_set=True):
(module_name, "disabled" if mod is None else "loaded"))
# could be in more then once, unlikely but better do this just in case.
- addons = _bpy.context.user_preferences.addons
+ addons = _user_preferences.addons
if default_set:
while module_name in addons:
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
new file mode 100644
index 00000000000..18c7b736ea5
--- /dev/null
+++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
@@ -0,0 +1,899 @@
+# ***** 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 *****
+
+# <pep8 compliant>
+
+# Populate a template file (POT format currently) from Blender RNA/py/C data.
+# XXX: This script is meant to be used from inside Blender!
+# You should not directly use this script, rather use update_msg.py!
+
+import collections
+import copy
+import datetime
+import os
+import re
+import sys
+
+# XXX Relative import does not work here when used from Blender...
+from bl_i18n_utils import settings as i18n_settings, utils
+
+import bpy
+
+##### Utils #####
+
+# check for strings like "+%f°"
+ignore_reg = re.compile(r"^(?:[-*.()/\\+%°0-9]|%d|%f|%s|%r|\s)*$")
+filter_message = ignore_reg.match
+
+
+def init_spell_check(settings, lang="en_US"):
+ try:
+ from bl_i18n_utils import spell_check_utils
+ return spell_check_utils.SpellChecker(settings, lang)
+ except Exception as e:
+ print("Failed to import spell_check_utils ({})".format(str(e)))
+ return None
+
+
+def _gen_check_ctxt(settings):
+ return {
+ "multi_rnatip": set(),
+ "multi_lines": set(),
+ "py_in_rna": set(),
+ "not_capitalized": set(),
+ "end_point": set(),
+ "undoc_ops": set(),
+ "spell_checker": init_spell_check(settings),
+ "spell_errors": {},
+ }
+
+
+def _gen_reports(check_ctxt):
+ return {
+ "check_ctxt": check_ctxt,
+ "rna_structs": [],
+ "rna_structs_skipped": [],
+ "rna_props": [],
+ "rna_props_skipped": [],
+ "py_messages": [],
+ "py_messages_skipped": [],
+ "src_messages": [],
+ "src_messages_skipped": [],
+ "messages_skipped": set(),
+ }
+
+
+def check(check_ctxt, msgs, key, msgsrc, settings):
+ """
+ Performs a set of checks over the given key (context, message)...
+ """
+ if check_ctxt is None:
+ return
+ multi_rnatip = check_ctxt.get("multi_rnatip")
+ multi_lines = check_ctxt.get("multi_lines")
+ py_in_rna = check_ctxt.get("py_in_rna")
+ not_capitalized = check_ctxt.get("not_capitalized")
+ end_point = check_ctxt.get("end_point")
+ undoc_ops = check_ctxt.get("undoc_ops")
+ spell_checker = check_ctxt.get("spell_checker")
+ spell_errors = check_ctxt.get("spell_errors")
+
+ if multi_rnatip is not None:
+ if key in msgs and key not in multi_rnatip:
+ multi_rnatip.add(key)
+ if multi_lines is not None:
+ if '\n' in key[1]:
+ multi_lines.add(key)
+ if py_in_rna is not None:
+ if key in py_in_rna[1]:
+ py_in_rna[0].add(key)
+ if not_capitalized is not None:
+ if(key[1] not in settings.WARN_MSGID_NOT_CAPITALIZED_ALLOWED and
+ key[1][0].isalpha() and not key[1][0].isupper()):
+ not_capitalized.add(key)
+ if end_point is not None:
+ if (key[1].strip().endswith('.') and not key[1].strip().endswith('...') and
+ key[1] not in settings.WARN_MSGID_END_POINT_ALLOWED):
+ end_point.add(key)
+ if undoc_ops is not None:
+ if key[1] == settings.UNDOC_OPS_STR:
+ undoc_ops.add(key)
+ if spell_checker is not None and spell_errors is not None:
+ err = spell_checker.check(key[1])
+ if err:
+ spell_errors[key] = err
+
+
+def print_info(reports, pot):
+ def _print(*args, **kwargs):
+ kwargs["file"] = sys.stderr
+ print(*args, **kwargs)
+
+ pot.update_info()
+
+ _print("{} RNA structs were processed (among which {} were skipped), containing {} RNA properties "
+ "(among which {} were skipped).".format(len(reports["rna_structs"]), len(reports["rna_structs_skipped"]),
+ len(reports["rna_props"]), len(reports["rna_props_skipped"])))
+ _print("{} messages were extracted from Python UI code (among which {} were skipped), and {} from C source code "
+ "(among which {} were skipped).".format(len(reports["py_messages"]), len(reports["py_messages_skipped"]),
+ len(reports["src_messages"]), len(reports["src_messages_skipped"])))
+ _print("{} messages were rejected.".format(len(reports["messages_skipped"])))
+ _print("\n")
+ _print("Current POT stats:")
+ pot.print_stats(prefix="\t", output=_print)
+ _print("\n")
+
+ check_ctxt = reports["check_ctxt"]
+ if check_ctxt is None:
+ return
+ multi_rnatip = check_ctxt.get("multi_rnatip")
+ multi_lines = check_ctxt.get("multi_lines")
+ py_in_rna = check_ctxt.get("py_in_rna")
+ not_capitalized = check_ctxt.get("not_capitalized")
+ end_point = check_ctxt.get("end_point")
+ undoc_ops = check_ctxt.get("undoc_ops")
+ spell_errors = check_ctxt.get("spell_errors")
+
+ # XXX Temp, no multi_rnatip nor py_in_rna, see below.
+ keys = multi_lines | not_capitalized | end_point | undoc_ops | spell_errors.keys()
+ if keys:
+ _print("WARNINGS:")
+ for key in keys:
+ if undoc_ops and key in undoc_ops:
+ _print("\tThe following operators are undocumented!")
+ else:
+ _print("\t“{}â€|“{}â€:".format(*key))
+ if multi_lines and key in multi_lines:
+ _print("\t\t-> newline in this message!")
+ if not_capitalized and key in not_capitalized:
+ _print("\t\t-> message not capitalized!")
+ if end_point and key in end_point:
+ _print("\t\t-> message with endpoint!")
+ # XXX Hide this one for now, too much false positives.
+# if multi_rnatip and key in multi_rnatip:
+# _print("\t\t-> tip used in several RNA items")
+# if py_in_rna and key in py_in_rna:
+# _print("\t\t-> RNA message also used in py UI code!")
+ if spell_errors and spell_errors.get(key):
+ lines = ["\t\t-> {}: misspelled, suggestions are ({})".format(w, "'" + "', '".join(errs) + "'")
+ for w, errs in spell_errors[key]]
+ _print("\n".join(lines))
+ _print("\t\t{}".format("\n\t\t".join(pot.msgs[key].sources)))
+
+
+def enable_addons(addons={}, support={}, disable=False):
+ """
+ Enable (or disable) addons based either on a set of names, or a set of 'support' types.
+ Returns the list of all affected addons (as fake modules)!
+ """
+ import addon_utils
+
+ userpref = bpy.context.user_preferences
+ used_ext = {ext.module for ext in userpref.addons}
+
+ ret = [mod for mod in addon_utils.modules(addon_utils.addons_fake_modules)
+ if ((addons and mod.__name__ in addons) or
+ (not addons and addon_utils.module_bl_info(mod)["support"] in support))]
+
+ for mod in ret:
+ module_name = mod.__name__
+ if disable:
+ if module_name not in used_ext:
+ continue
+ print(" Disabling module ", module_name)
+ bpy.ops.wm.addon_disable(module=module_name)
+ else:
+ if module_name in used_ext:
+ continue
+ print(" Enabling module ", module_name)
+ bpy.ops.wm.addon_enable(module=module_name)
+
+ # XXX There are currently some problems with bpy/rna...
+ # *Very* tricky to solve!
+ # So this is a hack to make all newly added operator visible by
+ # bpy.types.OperatorProperties.__subclasses__()
+ for cat in dir(bpy.ops):
+ cat = getattr(bpy.ops, cat)
+ for op in dir(cat):
+ getattr(cat, op).get_rna()
+
+ return ret
+
+
+def process_msg(msgs, msgctxt, msgid, msgsrc, reports, check_ctxt, settings):
+ if filter_message(msgid):
+ reports["messages_skipped"].add((msgid, msgsrc))
+ return
+ if not msgctxt:
+ # We do *not* want any "" context!
+ msgctxt = settings.DEFAULT_CONTEXT
+ # Always unescape keys!
+ msgctxt = utils.I18nMessage.do_unescape(msgctxt)
+ msgid = utils.I18nMessage.do_unescape(msgid)
+ key = (msgctxt, msgid)
+ check(check_ctxt, msgs, key, msgsrc, settings)
+ msgsrc = settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM + msgsrc
+ if key not in msgs:
+ msgs[key] = utils.I18nMessage([msgctxt], [msgid], [], [msgsrc], settings=settings)
+ else:
+ msgs[key].comment_lines.append(msgsrc)
+
+
+##### RNA #####
+def dump_messages_rna(msgs, reports, settings):
+ """
+ Dump into messages dict all RNA-defined UI messages (labels en tooltips).
+ """
+ def class_blacklist():
+ blacklist_rna_class = [
+ # core classes
+ "Context", "Event", "Function", "UILayout", "BlendData", "UnknownType",
+ # registerable classes
+ "Panel", "Menu", "Header", "RenderEngine", "Operator", "OperatorMacro", "Macro", "KeyingSetInfo",
+ # window classes
+ "Window",
+ ]
+
+ # Collect internal operators
+ # extend with all internal operators
+ # note that this uses internal api introspection functions
+ # 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__())
+
+ get_instance = __import__("_bpy").ops.get_instance
+# path_resolve = type(bpy.context).__base__.path_resolve
+ for idname in op_ids:
+ op = get_instance(idname)
+ # XXX Do not skip INTERNAL's anymore, some of those ops show up in UI now!
+# if 'INTERNAL' in path_resolve(op, "bl_options"):
+# blacklist_rna_class.append(idname)
+
+ # Collect builtin classes we don't need to doc
+ blacklist_rna_class.append("Property")
+ blacklist_rna_class.extend([cls.__name__ for cls in bpy.types.Property.__subclasses__()])
+
+ # Collect classes which are attached to collections, these are api access only.
+ collection_props = set()
+ for cls_id in dir(bpy.types):
+ cls = getattr(bpy.types, cls_id)
+ for prop in cls.bl_rna.properties:
+ if prop.type == 'COLLECTION':
+ prop_cls = prop.srna
+ if prop_cls is not None:
+ collection_props.add(prop_cls.identifier)
+ blacklist_rna_class.extend(sorted(collection_props))
+
+ return blacklist_rna_class
+
+ check_ctxt_rna = check_ctxt_rna_tip = None
+ check_ctxt = reports["check_ctxt"]
+ if check_ctxt:
+ check_ctxt_rna = {
+ "multi_lines": check_ctxt.get("multi_lines"),
+ "not_capitalized": check_ctxt.get("not_capitalized"),
+ "end_point": check_ctxt.get("end_point"),
+ "undoc_ops": check_ctxt.get("undoc_ops"),
+ "spell_checker": check_ctxt.get("spell_checker"),
+ "spell_errors": check_ctxt.get("spell_errors"),
+ }
+ check_ctxt_rna_tip = check_ctxt_rna
+ check_ctxt_rna_tip["multi_rnatip"] = check_ctxt.get("multi_rnatip")
+
+ default_context = settings.DEFAULT_CONTEXT
+
+ # Function definitions
+ def walk_properties(cls):
+ bl_rna = cls.bl_rna
+ # Get our parents' properties, to not export them multiple times.
+ bl_rna_base = bl_rna.base
+ if bl_rna_base:
+ bl_rna_base_props = set(bl_rna_base.properties.values())
+ else:
+ bl_rna_base_props = set()
+
+ for prop in bl_rna.properties:
+ # Only write this property if our parent hasn't got it.
+ if prop in bl_rna_base_props:
+ continue
+ if prop.identifier == "rna_type":
+ continue
+ reports["rna_props"].append((cls, prop))
+
+ msgsrc = "bpy.types.{}.{}".format(bl_rna.identifier, prop.identifier)
+ msgctxt = prop.translation_context or default_context
+
+ if prop.name and (prop.name != prop.identifier or msgctxt != default_context):
+ process_msg(msgs, msgctxt, prop.name, msgsrc, reports, check_ctxt_rna, settings)
+ if prop.description:
+ process_msg(msgs, default_context, prop.description, msgsrc, reports, check_ctxt_rna_tip, settings)
+
+ if isinstance(prop, bpy.types.EnumProperty):
+ for item in prop.enum_items:
+ msgsrc = "bpy.types.{}.{}:'{}'".format(bl_rna.identifier, prop.identifier, item.identifier)
+ if item.name and item.name != item.identifier:
+ process_msg(msgs, msgctxt, item.name, msgsrc, reports, check_ctxt_rna, settings)
+ if item.description:
+ process_msg(msgs, default_context, item.description, msgsrc, reports, check_ctxt_rna_tip,
+ settings)
+
+ blacklist_rna_class = class_blacklist()
+
+ def walk_class(cls):
+ bl_rna = cls.bl_rna
+ reports["rna_structs"].append(cls)
+ if bl_rna.identifier in blacklist_rna_class:
+ reports["rna_structs_skipped"].append(cls)
+ return
+
+ # XXX translation_context of Operator sub-classes are not "good"!
+ # So ignore those Operator sub-classes (anyway, will get the same from OperatorProperties sub-classes!)...
+ if issubclass(cls, bpy.types.Operator):
+ reports["rna_structs_skipped"].append(cls)
+ return
+
+ msgsrc = "bpy.types." + bl_rna.identifier
+ msgctxt = bl_rna.translation_context or default_context
+
+ if bl_rna.name and (bl_rna.name != bl_rna.identifier or msgctxt != default_context):
+ process_msg(msgs, msgctxt, bl_rna.name, msgsrc, reports, check_ctxt_rna, settings)
+
+ if bl_rna.description:
+ process_msg(msgs, default_context, bl_rna.description, msgsrc, reports, check_ctxt_rna_tip, settings)
+
+ if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label:
+ process_msg(msgs, msgctxt, bl_rna.bl_label, msgsrc, reports, check_ctxt_rna, settings)
+
+ walk_properties(cls)
+
+ def walk_keymap_hierarchy(hier, msgsrc_prev):
+ for lvl in hier:
+ msgsrc = msgsrc_prev + "." + lvl[1]
+ process_msg(msgs, default_context, lvl[0], msgsrc, reports, None, settings)
+ if lvl[3]:
+ walk_keymap_hierarchy(lvl[3], msgsrc)
+
+ # Dump Messages
+ def process_cls_list(cls_list):
+ if not cls_list:
+ return
+
+ def full_class_id(cls):
+ """ gives us 'ID.Lamp.AreaLamp' which is best for sorting."""
+ cls_id = ""
+ bl_rna = cls.bl_rna
+ while bl_rna:
+ cls_id = bl_rna.identifier + "." + cls_id
+ bl_rna = bl_rna.base
+ return cls_id
+
+ cls_list.sort(key=full_class_id)
+ for cls in cls_list:
+ walk_class(cls)
+ # Recursively process subclasses.
+ process_cls_list(cls.__subclasses__())
+
+ # Parse everything (recursively parsing from bpy_struct "class"...).
+ process_cls_list(bpy.types.ID.__base__.__subclasses__())
+
+ # And parse keymaps!
+ from bpy_extras.keyconfig_utils import KM_HIERARCHY
+
+ walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY")
+
+
+##### Python source code #####
+def dump_py_messages_from_files(msgs, reports, files, settings):
+ """
+ Dump text inlined in the python files given, e.g. 'My Name' in:
+ layout.prop("someprop", text="My Name")
+ """
+ import ast
+
+ bpy_struct = bpy.types.ID.__base__
+
+ # Helper function
+ def extract_strings_ex(node, is_split=False):
+ """
+ Recursively get strings, needed in case we have "Blah" + "Blah", passed as an argument in that case it won't
+ evaluate to a string. However, break on some kind of stopper nodes, like e.g. Subscript.
+ """
+ if type(node) == ast.Str:
+ eval_str = ast.literal_eval(node)
+ if eval_str:
+ yield (is_split, eval_str, (node,))
+ else:
+ is_split = (type(node) in separate_nodes)
+ for nd in ast.iter_child_nodes(node):
+ if type(nd) not in stopper_nodes:
+ yield from extract_strings_ex(nd, is_split=is_split)
+
+ def _extract_string_merge(estr_ls, nds_ls):
+ return "".join(s for s in estr_ls if s is not None), tuple(n for n in nds_ls if n is not None)
+
+ def extract_strings(node):
+ estr_ls = []
+ nds_ls = []
+ for is_split, estr, nds in extract_strings_ex(node):
+ estr_ls.append(estr)
+ nds_ls.extend(nds)
+ ret = _extract_string_merge(estr_ls, nds_ls)
+ return ret
+
+ def extract_strings_split(node):
+ """
+ Returns a list args as returned by 'extract_strings()', But split into groups based on separate_nodes, this way
+ expressions like ("A" if test else "B") wont be merged but "A" + "B" will.
+ """
+ estr_ls = []
+ nds_ls = []
+ bag = []
+ for is_split, estr, nds in extract_strings_ex(node):
+ if is_split:
+ bag.append((estr_ls, nds_ls))
+ estr_ls = []
+ nds_ls = []
+
+ estr_ls.append(estr)
+ nds_ls.extend(nds)
+
+ bag.append((estr_ls, nds_ls))
+
+ return [_extract_string_merge(estr_ls, nds_ls) for estr_ls, nds_ls in bag]
+
+
+ def _ctxt_to_ctxt(node):
+ return extract_strings(node)[0]
+
+ def _op_to_ctxt(node):
+ opname, _ = extract_strings(node)
+ if not opname:
+ return settings.DEFAULT_CONTEXT
+ op = bpy.ops
+ for n in opname.split('.'):
+ op = getattr(op, n)
+ try:
+ return op.get_rna().bl_rna.translation_context
+ except Exception as e:
+ default_op_context = bpy.app.translations.contexts.operator_default
+ print("ERROR: ", str(e))
+ print(" Assuming default operator context '{}'".format(default_op_context))
+ return default_op_context
+
+ # Gather function names.
+ # In addition of UI func, also parse pgettext ones...
+ # Tuples of (module name, (short names, ...)).
+ pgettext_variants = (
+ ("pgettext", ("_",)),
+ ("pgettext_iface", ("iface_",)),
+ ("pgettext_tip", ("tip_",))
+ )
+ pgettext_variants_args = {"msgid": (0, {"msgctxt": 1})}
+
+ # key: msgid keywords.
+ # val: tuples of ((keywords,), context_getter_func) to get a context for that msgid.
+ # Note: order is important, first one wins!
+ translate_kw = {
+ "text": ((("text_ctxt",), _ctxt_to_ctxt),
+ (("operator",), _op_to_ctxt),
+ ),
+ "msgid": ((("msgctxt",), _ctxt_to_ctxt),
+ ),
+ }
+
+ context_kw_set = {}
+ for k, ctxts in translate_kw.items():
+ s = set()
+ for c, _ in ctxts:
+ s |= set(c)
+ context_kw_set[k] = s
+
+ # {func_id: {msgid: (arg_pos,
+ # {msgctxt: arg_pos,
+ # ...
+ # }
+ # ),
+ # ...
+ # },
+ # ...
+ # }
+ func_translate_args = {}
+
+ # First, functions from UILayout
+ # First loop is for msgid args, second one is for msgctxt args.
+ for func_id, func in bpy.types.UILayout.bl_rna.functions.items():
+ # check it has one or more arguments as defined in translate_kw
+ for arg_pos, (arg_kw, arg) in enumerate(func.parameters.items()):
+ if ((arg_kw in translate_kw) and (not arg.is_output) and (arg.type == 'STRING')):
+ func_translate_args.setdefault(func_id, {})[arg_kw] = (arg_pos, {})
+ for func_id, func in bpy.types.UILayout.bl_rna.functions.items():
+ if func_id not in func_translate_args:
+ continue
+ for arg_pos, (arg_kw, arg) in enumerate(func.parameters.items()):
+ if (not arg.is_output) and (arg.type == 'STRING'):
+ for msgid, msgctxts in context_kw_set.items():
+ if arg_kw in msgctxts:
+ func_translate_args[func_id][msgid][1][arg_kw] = arg_pos
+ # We manually add funcs from bpy.app.translations
+ for func_id, func_ids in pgettext_variants:
+ func_translate_args[func_id] = pgettext_variants_args
+ for func_id in func_ids:
+ func_translate_args[func_id] = pgettext_variants_args
+ #print(func_translate_args)
+
+ # Break recursive nodes look up on some kind of nodes.
+ # E.g. we don’t want to get strings inside subscripts (blah["foo"])!
+ stopper_nodes = {ast.Subscript}
+ # Consider strings separate: ("a" if test else "b")
+ separate_nodes = {ast.IfExp}
+
+ check_ctxt_py = None
+ if reports["check_ctxt"]:
+ check_ctxt = reports["check_ctxt"]
+ check_ctxt_py = {
+ "py_in_rna": (check_ctxt.get("py_in_rna"), set(msgs.keys())),
+ "multi_lines": check_ctxt.get("multi_lines"),
+ "not_capitalized": check_ctxt.get("not_capitalized"),
+ "end_point": check_ctxt.get("end_point"),
+ "spell_checker": check_ctxt.get("spell_checker"),
+ "spell_errors": check_ctxt.get("spell_errors"),
+ }
+
+ for fp in files:
+ with open(fp, 'r', encoding="utf8") as filedata:
+ root_node = ast.parse(filedata.read(), fp, 'exec')
+
+ fp_rel = os.path.relpath(fp, settings.SOURCE_DIR)
+
+ for node in ast.walk(root_node):
+ if type(node) == ast.Call:
+ # print("found function at")
+ # print("%s:%d" % (fp, node.lineno))
+
+ # We can't skip such situations! from blah import foo\nfoo("bar") would also be an ast.Name func!
+ if type(node.func) == ast.Name:
+ func_id = node.func.id
+ elif hasattr(node.func, "attr"):
+ func_id = node.func.attr
+ # Ugly things like getattr(self, con.type)(context, box, con)
+ else:
+ continue
+
+ func_args = func_translate_args.get(func_id, {})
+
+ # First try to get i18n contexts, for every possible msgid id.
+ msgctxts = dict.fromkeys(func_args.keys(), "")
+ for msgid, (_, context_args) in func_args.items():
+ context_elements = {}
+ for arg_kw, arg_pos in context_args.items():
+ if arg_pos < len(node.args):
+ context_elements[arg_kw] = node.args[arg_pos]
+ else:
+ for kw in node.keywords:
+ if kw.arg == arg_kw:
+ context_elements[arg_kw] = kw.value
+ break
+ #print(context_elements)
+ for kws, proc in translate_kw[msgid]:
+ if set(kws) <= context_elements.keys():
+ args = tuple(context_elements[k] for k in kws)
+ #print("running ", proc, " with ", args)
+ ctxt = proc(*args)
+ if ctxt:
+ msgctxts[msgid] = ctxt
+ break
+
+ #print(translate_args)
+ # do nothing if not found
+ for arg_kw, (arg_pos, _) in func_args.items():
+ msgctxt = msgctxts[arg_kw]
+ estr_lst = [(None, ())]
+ if arg_pos < len(node.args):
+ estr_lst = extract_strings_split(node.args[arg_pos])
+ #print(estr, nds)
+ else:
+ for kw in node.keywords:
+ if kw.arg == arg_kw:
+ estr_lst = extract_strings_split(kw.value)
+ break
+ #print(estr, nds)
+ for estr, nds in estr_lst:
+ if estr:
+ if nds:
+ msgsrc = "{}:{}".format(fp_rel, sorted({nd.lineno for nd in nds})[0])
+ else:
+ msgsrc = "{}:???".format(fp_rel)
+ process_msg(msgs, msgctxt, estr, msgsrc, reports, check_ctxt_py, settings)
+ reports["py_messages"].append((msgctxt, estr, msgsrc))
+
+
+def dump_py_messages(msgs, reports, addons, settings):
+ def _get_files(path):
+ if os.path.isdir(path):
+ # XXX use walk instead of listdir?
+ return [os.path.join(path, fn) for fn in sorted(os.listdir(path))
+ if not fn.startswith("_") and fn.endswith(".py")]
+ return [path]
+
+ files = []
+ for path in settings.CUSTOM_PY_UI_FILES:
+ files += _get_files(path)
+
+ # Add all addons we support in main translation file!
+ for mod in addons:
+ fn = mod.__file__
+ if os.path.basename(fn) == "__init__.py":
+ files += _get_files(os.path.dirname(fn))
+ else:
+ files.append(fn)
+
+ dump_py_messages_from_files(msgs, reports, files, settings)
+
+
+##### C source code #####
+def dump_src_messages(msgs, reports, settings):
+ def get_contexts():
+ """Return a mapping {C_CTXT_NAME: ctxt_value}."""
+ return {k: getattr(bpy.app.translations.contexts, n) for k, n in bpy.app.translations.contexts_C_to_py.items()}
+
+ contexts = get_contexts()
+
+ # Build regexes to extract messages (with optional contexts) from C source.
+ pygettexts = tuple(re.compile(r).search for r in settings.PYGETTEXT_KEYWORDS)
+
+ _clean_str = re.compile(settings.str_clean_re).finditer
+ clean_str = lambda s: "".join(m.group("clean") for m in _clean_str(s))
+
+ def dump_src_file(path, rel_path, msgs, reports, settings):
+ def process_entry(_msgctxt, _msgid):
+ # Context.
+ msgctxt = settings.DEFAULT_CONTEXT
+ if _msgctxt:
+ if _msgctxt in contexts:
+ msgctxt = contexts[_msgctxt]
+ elif '"' in _msgctxt or "'" in _msgctxt:
+ msgctxt = clean_str(_msgctxt)
+ else:
+ print("WARNING: raw context “{}†couldn’t be resolved!".format(_msgctxt))
+ # Message.
+ msgid = ""
+ if _msgid:
+ if '"' in _msgid or "'" in _msgid:
+ msgid = clean_str(_msgid)
+ else:
+ print("WARNING: raw message “{}†couldn’t be resolved!".format(_msgid))
+ return msgctxt, msgid
+
+ check_ctxt_src = None
+ if reports["check_ctxt"]:
+ check_ctxt = reports["check_ctxt"]
+ check_ctxt_src = {
+ "multi_lines": check_ctxt.get("multi_lines"),
+ "not_capitalized": check_ctxt.get("not_capitalized"),
+ "end_point": check_ctxt.get("end_point"),
+ "spell_checker": check_ctxt.get("spell_checker"),
+ "spell_errors": check_ctxt.get("spell_errors"),
+ }
+
+ data = ""
+ with open(path) as f:
+ data = f.read()
+ for srch in pygettexts:
+ m = srch(data)
+ line = pos = 0
+ while m:
+ d = m.groupdict()
+ # Line.
+ line += data[pos:m.start()].count('\n')
+ msgsrc = rel_path + ":" + str(line)
+ _msgid = d.get("msg_raw")
+ # First, try the "multi-contexts" stuff!
+ _msgctxts = tuple(d.get("ctxt_raw{}".format(i)) for i in range(settings.PYGETTEXT_MAX_MULTI_CTXT))
+ if _msgctxts[0]:
+ for _msgctxt in _msgctxts:
+ if not _msgctxt:
+ break
+ msgctxt, msgid = process_entry(_msgctxt, _msgid)
+ process_msg(msgs, msgctxt, msgid, msgsrc, reports, check_ctxt_src, settings)
+ reports["src_messages"].append((msgctxt, msgid, msgsrc))
+ else:
+ _msgctxt = d.get("ctxt_raw")
+ msgctxt, msgid = process_entry(_msgctxt, _msgid)
+ process_msg(msgs, msgctxt, msgid, msgsrc, reports, check_ctxt_src, settings)
+ reports["src_messages"].append((msgctxt, msgid, msgsrc))
+
+ pos = m.end()
+ line += data[m.start():pos].count('\n')
+ m = srch(data, pos)
+
+ forbidden = set()
+ forced = set()
+ if os.path.isfile(settings.SRC_POTFILES):
+ with open(settings.SRC_POTFILES) as src:
+ for l in src:
+ if l[0] == '-':
+ forbidden.add(l[1:].rstrip('\n'))
+ elif l[0] != '#':
+ forced.add(l.rstrip('\n'))
+ for root, dirs, files in os.walk(settings.POTFILES_SOURCE_DIR):
+ if "/.svn" in root:
+ continue
+ for fname in files:
+ if os.path.splitext(fname)[1] not in settings.PYGETTEXT_ALLOWED_EXTS:
+ continue
+ path = os.path.join(root, fname)
+ rel_path = os.path.relpath(path, settings.SOURCE_DIR)
+ if rel_path in forbidden:
+ continue
+ elif rel_path not in forced:
+ forced.add(rel_path)
+ for rel_path in sorted(forced):
+ path = os.path.join(settings.SOURCE_DIR, rel_path)
+ if os.path.exists(path):
+ dump_src_file(path, rel_path, msgs, reports, settings)
+
+
+##### Main functions! #####
+def dump_messages(do_messages, do_checks, settings):
+ bl_ver = "Blender " + bpy.app.version_string
+ bl_rev = bpy.app.build_revision
+ bl_date = datetime.datetime.strptime(bpy.app.build_date.decode() + "T" + bpy.app.build_time.decode(),
+ "%Y-%m-%dT%H:%M:%S")
+ pot = utils.I18nMessages.gen_empty_messages(settings.PARSER_TEMPLATE_ID, bl_ver, bl_rev, bl_date, bl_date.year,
+ settings=settings)
+ msgs = pot.msgs
+
+ # Enable all wanted addons.
+ # For now, enable all official addons, before extracting msgids.
+ addons = enable_addons(support={"OFFICIAL"})
+ # Note this is not needed if we have been started with factory settings, but just in case...
+ enable_addons(support={"COMMUNITY", "TESTING"}, disable=True)
+
+ reports = _gen_reports(_gen_check_ctxt(settings) if do_checks else None)
+
+ # Get strings from RNA.
+ dump_messages_rna(msgs, reports, settings)
+
+ # Get strings from UI layout definitions text="..." args.
+ dump_py_messages(msgs, reports, addons, settings)
+
+ # Get strings from C source code.
+ dump_src_messages(msgs, reports, settings)
+
+ # Get strings from addons' categories.
+ print("foo, bar", bpy.types.WindowManager.addon_filter[1]['items'](bpy.context.window_manager, bpy.context))
+ for uid, label, tip in bpy.types.WindowManager.addon_filter[1]['items'](bpy.context.window_manager, bpy.context):
+ print(uid, label, tip)
+ process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Addons' categories", reports, None, settings)
+ if tip:
+ process_msg(msgs, settings.DEFAULT_CONTEXT, tip, "Addons' categories", reports, None, settings)
+
+ # Get strings specific to translations' menu.
+ for lng in settings.LANGUAGES:
+ process_msg(msgs, settings.DEFAULT_CONTEXT, lng[1], "Languages’ labels from bl_i18n_utils/settings.py",
+ reports, None, settings)
+ for cat in settings.LANGUAGES_CATEGORIES:
+ process_msg(msgs, settings.DEFAULT_CONTEXT, cat[1],
+ "Language categories’ labels from bl_i18n_utils/settings.py", reports, None, settings)
+
+ #pot.check()
+ pot.unescape() # Strings gathered in py/C source code may contain escaped chars...
+ print_info(reports, pot)
+ #pot.check()
+
+ if do_messages:
+ print("Writing messages…")
+ pot.write('PO', settings.FILE_NAME_POT)
+
+ print("Finished extracting UI messages!")
+
+
+def dump_addon_messages(module_name, messages_formats, do_checks, settings):
+ # Enable our addon and get strings from RNA.
+ addon = enable_addons(addons={module_name})[0]
+
+ addon_info = addon_utils.module_bl_info(addon)
+ ver = addon_info.name + " " + ".".join(addon_info.version)
+ rev = "???"
+ date = datetime.datetime()
+ pot = utils.I18nMessages.gen_empty_messages(settings.PARSER_TEMPLATE_ID, ver, rev, date, date.year,
+ settings=settings)
+ msgs = pot.msgs
+
+ minus_msgs = copy.deepcopy(msgs)
+
+ check_ctxt = _gen_check_ctxt(settings) if do_checks else None
+ minus_check_ctxt = _gen_check_ctxt(settings) if do_checks else None
+
+ # Get current addon state (loaded or not):
+ was_loaded = addon_utils.check(module_name)[1]
+
+ # Enable our addon and get strings from RNA.
+ addons = enable_addons(addons={module_name})
+ reports = _gen_reports(check_ctxt)
+ dump_messages_rna(msgs, reports, settings)
+
+ # Now disable our addon, and rescan RNA.
+ enable_addons(addons={module_name}, disable=True)
+ reports["check_ctxt"] = minus_check_ctxt
+ dump_messages_rna(minus_msgs, reports, settings)
+
+ # Restore previous state if needed!
+ if was_loaded:
+ enable_addons(addons={module_name})
+
+ # and make the diff!
+ for key in minus_msgs:
+ if key == settings.PO_HEADER_KEY:
+ continue
+ del msgs[key]
+
+ if check_ctxt:
+ for key in check_ctxt:
+ for warning in minus_check_ctxt[key]:
+ check_ctxt[key].remove(warning)
+
+ # and we are done with those!
+ del minus_msgs
+ del minus_check_ctxt
+
+ # get strings from UI layout definitions text="..." args
+ reports["check_ctxt"] = check_ctxt
+ dump_messages_pytext(msgs, reports, addons, settings)
+
+ print_info(reports, pot)
+
+ return pot
+
+
+def main():
+ try:
+ import bpy
+ except ImportError:
+ print("This script must run from inside blender")
+ return
+
+ import sys
+ back_argv = sys.argv
+ # Get rid of Blender args!
+ sys.argv = sys.argv[sys.argv.index("--") + 1:]
+
+ import argparse
+ parser = argparse.ArgumentParser(description="Process UI messages from inside Blender.")
+ parser.add_argument('-c', '--no_checks', default=True, action="store_false", help="No checks over UI messages.")
+ parser.add_argument('-m', '--no_messages', default=True, action="store_false", help="No export of UI messages.")
+ parser.add_argument('-o', '--output', default=None, help="Output POT file path.")
+ parser.add_argument('-s', '--settings', default=None,
+ help="Override (some) default settings. Either a JSon file name, or a JSon string.")
+ args = parser.parse_args()
+
+ settings = i18n_settings.I18nSettings()
+ settings.from_json(args.settings)
+
+ if args.output:
+ settings.FILE_NAME_POT = args.output
+
+ dump_messages(do_messages=args.no_messages, do_checks=args.no_checks, settings=settings)
+
+ sys.argv = back_argv
+
+
+if __name__ == "__main__":
+ print("\n\n *** Running {} *** \n".format(__file__))
+ main()
diff --git a/release/scripts/modules/bl_i18n_utils/bl_process_msg.py b/release/scripts/modules/bl_i18n_utils/bl_process_msg.py
deleted file mode 100644
index 7e9266d0530..00000000000
--- a/release/scripts/modules/bl_i18n_utils/bl_process_msg.py
+++ /dev/null
@@ -1,524 +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 *****
-
-# <pep8 compliant>
-
-# Write out messages.txt from Blender.
-# XXX: This script is meant to be used from inside Blender!
-# You should not directly use this script, rather use update_msg.py!
-
-import os
-
-# XXX Relative import does not work here when used from Blender...
-from bl_i18n_utils import settings
-
-
-#classes = set()
-
-
-SOURCE_DIR = settings.SOURCE_DIR
-
-CUSTOM_PY_UI_FILES = [os.path.abspath(os.path.join(SOURCE_DIR, p)) for p in settings.CUSTOM_PY_UI_FILES]
-FILE_NAME_MESSAGES = settings.FILE_NAME_MESSAGES
-COMMENT_PREFIX = settings.COMMENT_PREFIX
-CONTEXT_PREFIX = settings.CONTEXT_PREFIX
-CONTEXT_DEFAULT = settings.CONTEXT_DEFAULT
-UNDOC_OPS_STR = settings.UNDOC_OPS_STR
-
-NC_ALLOWED = settings.WARN_MSGID_NOT_CAPITALIZED_ALLOWED
-
-
-def check(check_ctxt, messages, key, msgsrc):
- if check_ctxt is None:
- return
- multi_rnatip = check_ctxt.get("multi_rnatip")
- multi_lines = check_ctxt.get("multi_lines")
- py_in_rna = check_ctxt.get("py_in_rna")
- not_capitalized = check_ctxt.get("not_capitalized")
- end_point = check_ctxt.get("end_point")
- undoc_ops = check_ctxt.get("undoc_ops")
-
- if multi_rnatip is not None:
- if key in messages and key not in multi_rnatip:
- multi_rnatip.add(key)
- if multi_lines is not None:
- if '\n' in key[1]:
- multi_lines.add(key)
- if py_in_rna is not None:
- if key in py_in_rna[1]:
- py_in_rna[0].add(key)
- if not_capitalized is not None:
- if(key[1] not in NC_ALLOWED and key[1][0].isalpha() and not key[1][0].isupper()):
- not_capitalized.add(key)
- if end_point is not None:
- if key[1].strip().endswith('.'):
- end_point.add(key)
- if undoc_ops is not None:
- if key[1] == UNDOC_OPS_STR:
- undoc_ops.add(key)
-
-
-def dump_messages_rna(messages, check_ctxt):
- import bpy
-
- def classBlackList():
- blacklist_rna_class = [
- # core classes
- "Context", "Event", "Function", "UILayout", "BlendData",
- # registerable classes
- "Panel", "Menu", "Header", "RenderEngine", "Operator", "OperatorMacro", "Macro",
- "KeyingSetInfo", "UnknownType",
- # window classes
- "Window",
- ]
-
- # ---------------------------------------------------------------------
- # Collect internal operators
-
- # extend with all internal operators
- # note that this uses internal api introspection functions
- # 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__())
-
- get_instance = __import__("_bpy").ops.get_instance
- path_resolve = type(bpy.context).__base__.path_resolve
- for idname in op_ids:
- op = get_instance(idname)
- # XXX Do not skip INTERNAL's anymore, some of those ops show up in UI now!
-# if 'INTERNAL' in path_resolve(op, "bl_options"):
-# blacklist_rna_class.append(idname)
-
- # ---------------------------------------------------------------------
- # Collect builtin classes we don't need to doc
- blacklist_rna_class.append("Property")
- blacklist_rna_class.extend([cls.__name__ for cls in bpy.types.Property.__subclasses__()])
-
- # ---------------------------------------------------------------------
- # Collect classes which are attached to collections, these are api
- # access only.
- collection_props = set()
- for cls_id in dir(bpy.types):
- cls = getattr(bpy.types, cls_id)
- for prop in cls.bl_rna.properties:
- if prop.type == 'COLLECTION':
- prop_cls = prop.srna
- if prop_cls is not None:
- collection_props.add(prop_cls.identifier)
- blacklist_rna_class.extend(sorted(collection_props))
-
- return blacklist_rna_class
-
- blacklist_rna_class = classBlackList()
-
- def filterRNA(bl_rna):
- rid = bl_rna.identifier
- if rid in blacklist_rna_class:
- print(" skipping", rid)
- return True
- return False
-
- check_ctxt_rna = check_ctxt_rna_tip = None
- if check_ctxt:
- check_ctxt_rna = {"multi_lines": check_ctxt.get("multi_lines"),
- "not_capitalized": check_ctxt.get("not_capitalized"),
- "end_point": check_ctxt.get("end_point"),
- "undoc_ops": check_ctxt.get("undoc_ops")}
- check_ctxt_rna_tip = check_ctxt_rna
- check_ctxt_rna_tip["multi_rnatip"] = check_ctxt.get("multi_rnatip")
-
- # -------------------------------------------------------------------------
- # Function definitions
-
- def walkProperties(bl_rna):
- import bpy
-
- # Get our parents' properties, to not export them multiple times.
- bl_rna_base = bl_rna.base
- if bl_rna_base:
- bl_rna_base_props = bl_rna_base.properties.values()
- else:
- bl_rna_base_props = ()
-
- for prop in bl_rna.properties:
- # Only write this property if our parent hasn't got it.
- if prop in bl_rna_base_props:
- continue
- if prop.identifier == "rna_type":
- continue
-
- msgsrc = "bpy.types.{}.{}".format(bl_rna.identifier, prop.identifier)
- context = getattr(prop, "translation_context", CONTEXT_DEFAULT)
- if prop.name and (prop.name != prop.identifier or context):
- key = (context, prop.name)
- check(check_ctxt_rna, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
- if prop.description:
- key = (CONTEXT_DEFAULT, prop.description)
- check(check_ctxt_rna_tip, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
- if isinstance(prop, bpy.types.EnumProperty):
- for item in prop.enum_items:
- msgsrc = "bpy.types.{}.{}:'{}'".format(bl_rna.identifier,
- prop.identifier,
- item.identifier)
- if item.name and item.name != item.identifier:
- key = (CONTEXT_DEFAULT, item.name)
- check(check_ctxt_rna, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
- if item.description:
- key = (CONTEXT_DEFAULT, item.description)
- check(check_ctxt_rna_tip, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
-
- def walkRNA(bl_rna):
- if filterRNA(bl_rna):
- return
-
- msgsrc = ".".join(("bpy.types", bl_rna.identifier))
- context = getattr(bl_rna, "translation_context", CONTEXT_DEFAULT)
-
- if bl_rna.name and (bl_rna.name != bl_rna.identifier or context):
- key = (context, bl_rna.name)
- check(check_ctxt_rna, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
-
- if bl_rna.description:
- key = (CONTEXT_DEFAULT, bl_rna.description)
- check(check_ctxt_rna_tip, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
-
- if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label:
- key = (context, bl_rna.bl_label)
- check(check_ctxt_rna, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
-
- walkProperties(bl_rna)
-
- def walkClass(cls):
- walkRNA(cls.bl_rna)
-
- def walk_keymap_hierarchy(hier, msgsrc_prev):
- for lvl in hier:
- msgsrc = "{}.{}".format(msgsrc_prev, lvl[1])
- messages.setdefault((CONTEXT_DEFAULT, lvl[0]), []).append(msgsrc)
-
- if lvl[3]:
- walk_keymap_hierarchy(lvl[3], msgsrc)
-
- # -------------------------------------------------------------------------
- # Dump Messages
-
- def process_cls_list(cls_list):
- if not cls_list:
- return 0
-
- def full_class_id(cls):
- """ gives us 'ID.Lamp.AreaLamp' which is best for sorting.
- """
- cls_id = ""
- bl_rna = cls.bl_rna
- while bl_rna:
- cls_id = "{}.{}".format(bl_rna.identifier, cls_id)
- bl_rna = bl_rna.base
- return cls_id
-
- cls_list.sort(key=full_class_id)
- processed = 0
- for cls in cls_list:
- # XXX translation_context of Operator sub-classes are not "good"!
- # So ignore those Operator sub-classes (anyway, will get the same from OperatorProperties
- # sub-classes!)...
- if issubclass(cls, bpy.types.Operator):
- continue
-
- walkClass(cls)
-# classes.add(cls)
- # Recursively process subclasses.
- processed += process_cls_list(cls.__subclasses__()) + 1
- return processed
-
- # Parse everything (recursively parsing from bpy_struct "class"...).
- processed = process_cls_list(type(bpy.context).__base__.__subclasses__())
- print("{} classes processed!".format(processed))
-# import pickle
-# global classes
-# classes = {str(c) for c in classes}
-# with open("/home/i7deb64/Bureau/tpck_2", "wb") as f:
-# pickle.dump(classes, f, protocol=0)
-
- from bpy_extras.keyconfig_utils import KM_HIERARCHY
-
- walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY")
-
-
-def dump_messages_pytext(messages, check_ctxt):
- """ dumps text inlined in the python user interface: eg.
-
- layout.prop("someprop", text="My Name")
- """
- import ast
-
- # -------------------------------------------------------------------------
- # Gather function names
-
- import bpy
- # key: func_id
- # val: [(arg_kw, arg_pos), (arg_kw, arg_pos), ...]
- func_translate_args = {}
-
- # so far only 'text' keywords, but we may want others translated later
- translate_kw = ("text", )
-
- # Break recursive nodes look up on some kind of nodes.
- # E.g. we don’t want to get strings inside subscripts (blah["foo"])!
- stopper_nodes = {ast.Subscript, }
-
- for func_id, func in bpy.types.UILayout.bl_rna.functions.items():
- # check it has a 'text' argument
- for (arg_pos, (arg_kw, arg)) in enumerate(func.parameters.items()):
- if ((arg_kw in translate_kw) and
- (arg.is_output is False) and
- (arg.type == 'STRING')):
-
- func_translate_args.setdefault(func_id, []).append((arg_kw,
- arg_pos))
- # print(func_translate_args)
-
- check_ctxt_py = None
- if check_ctxt:
- check_ctxt_py = {"py_in_rna": (check_ctxt["py_in_rna"], messages.copy()),
- "multi_lines": check_ctxt["multi_lines"],
- "not_capitalized": check_ctxt["not_capitalized"],
- "end_point": check_ctxt["end_point"]}
-
- # -------------------------------------------------------------------------
- # Function definitions
-
- def extract_strings(fp_rel, node):
- """ Recursively get strings, needed in case we have "Blah" + "Blah",
- passed as an argument in that case it wont evaluate to a string.
- However, break on some kind of stopper nodes, like e.g. Subscript.
- """
-
- if type(node) == ast.Str:
- eval_str = ast.literal_eval(node)
- if eval_str:
- key = (CONTEXT_DEFAULT, eval_str)
- msgsrc = "{}:{}".format(fp_rel, node.lineno)
- check(check_ctxt_py, messages, key, msgsrc)
- messages.setdefault(key, []).append(msgsrc)
- return
-
- for nd in ast.iter_child_nodes(node):
- if type(nd) not in stopper_nodes:
- extract_strings(fp_rel, nd)
-
- def extract_strings_from_file(fp):
- filedata = open(fp, 'r', encoding="utf8")
- root_node = ast.parse(filedata.read(), fp, 'exec')
- filedata.close()
-
- fp_rel = os.path.relpath(fp, SOURCE_DIR)
-
- for node in ast.walk(root_node):
- if type(node) == ast.Call:
- # print("found function at")
- # print("%s:%d" % (fp, node.lineno))
-
- # lambda's
- if type(node.func) == ast.Name:
- continue
-
- # getattr(self, con.type)(context, box, con)
- if not hasattr(node.func, "attr"):
- continue
-
- translate_args = func_translate_args.get(node.func.attr, ())
-
- # do nothing if not found
- for arg_kw, arg_pos in translate_args:
- if arg_pos < len(node.args):
- extract_strings(fp_rel, node.args[arg_pos])
- else:
- for kw in node.keywords:
- if kw.arg == arg_kw:
- extract_strings(fp_rel, kw.value)
-
- # -------------------------------------------------------------------------
- # Dump Messages
-
- mod_dir = os.path.join(SOURCE_DIR,
- "release",
- "scripts",
- "startup",
- "bl_ui")
-
- files = [os.path.join(mod_dir, fn)
- for fn in sorted(os.listdir(mod_dir))
- if not fn.startswith("_")
- if fn.endswith("py")
- ]
-
- # Dummy Cycles has its py addon in its own dir!
- files += CUSTOM_PY_UI_FILES
-
- for fp in files:
- extract_strings_from_file(fp)
-
-
-def dump_messages(do_messages, do_checks):
- import collections
- import re
-
- def enable_addons():
- """For now, enable all official addons, before extracting msgids."""
- import addon_utils
- import bpy
-
- userpref = bpy.context.user_preferences
- used_ext = {ext.module for ext in userpref.addons}
- support = {"OFFICIAL"}
- # collect the categories that can be filtered on
- addons = [(mod, addon_utils.module_bl_info(mod)) for mod in
- addon_utils.modules(addon_utils.addons_fake_modules)]
-
- for mod, info in addons:
- module_name = mod.__name__
- if module_name in used_ext or info["support"] not in support:
- continue
- print(" Enabling module ", module_name)
- bpy.ops.wm.addon_enable(module=module_name)
-
- # XXX There are currently some problems with bpy/rna...
- # *Very* tricky to solve!
- # So this is a hack to make all newly added operator visible by
- # bpy.types.OperatorProperties.__subclasses__()
- for cat in dir(bpy.ops):
- cat = getattr(bpy.ops, cat)
- for op in dir(cat):
- getattr(cat, op).get_rna()
-
- # check for strings like ": %d"
- ignore_reg = re.compile(r"^(?:[-*.()/\\+:%xWXYZ0-9]|%d|%f|%s|%r|\s)*$")
- filter_message = ignore_reg.match
-
- messages = getattr(collections, 'OrderedDict', dict)()
-
- messages[(CONTEXT_DEFAULT, "")] = []
-
- # Enable all wanted addons.
- enable_addons()
-
- check_ctxt = None
- if do_checks:
- check_ctxt = {"multi_rnatip": set(),
- "multi_lines": set(),
- "py_in_rna": set(),
- "not_capitalized": set(),
- "end_point": set(),
- "undoc_ops": set()}
-
- # get strings from RNA
- dump_messages_rna(messages, check_ctxt)
-
- # get strings from UI layout definitions text="..." args
- dump_messages_pytext(messages, check_ctxt)
-
- del messages[(CONTEXT_DEFAULT, "")]
-
- if do_checks:
- print("WARNINGS:")
- keys = set()
- for c in check_ctxt.values():
- keys |= c
- # XXX Temp, see below
- keys -= check_ctxt["multi_rnatip"]
- for key in keys:
- if key in check_ctxt["undoc_ops"]:
- print("\tThe following operators are undocumented:")
- else:
- print("\t“{}â€|“{}â€:".format(*key))
- if key in check_ctxt["multi_lines"]:
- print("\t\t-> newline in this message!")
- if key in check_ctxt["not_capitalized"]:
- print("\t\t-> message not capitalized!")
- if key in check_ctxt["end_point"]:
- print("\t\t-> message with endpoint!")
- # XXX Hide this one for now, too much false positives.
-# if key in check_ctxt["multi_rnatip"]:
-# print("\t\t-> tip used in several RNA items")
- if key in check_ctxt["py_in_rna"]:
- print("\t\t-> RNA message also used in py UI code:")
- print("\t\t{}".format("\n\t\t".join(messages[key])))
-
- if do_messages:
- print("Writing messages…")
- num_written = 0
- num_filtered = 0
- with open(FILE_NAME_MESSAGES, 'w', encoding="utf8") as message_file:
- for (ctx, key), value in messages.items():
- # filter out junk values
- if filter_message(key):
- num_filtered += 1
- continue
-
- # Remove newlines in key and values!
- message_file.write("\n".join(COMMENT_PREFIX + msgsrc.replace("\n", "") for msgsrc in value))
- message_file.write("\n")
- if ctx:
- message_file.write(CONTEXT_PREFIX + ctx.replace("\n", "") + "\n")
- message_file.write(key.replace("\n", "") + "\n")
- num_written += 1
-
- print("Written {} messages to: {} ({} were filtered out)."
- "".format(num_written, FILE_NAME_MESSAGES, num_filtered))
-
-
-def main():
- try:
- import bpy
- except ImportError:
- print("This script must run from inside blender")
- return
-
- import sys
- back_argv = sys.argv
- # Get rid of Blender args!
- sys.argv = sys.argv[sys.argv.index("--") + 1:]
-
- import argparse
- parser = argparse.ArgumentParser(description="Process UI messages from inside Blender.")
- parser.add_argument('-c', '--no_checks', default=True, action="store_false", help="No checks over UI messages.")
- parser.add_argument('-m', '--no_messages', default=True, action="store_false", help="No export of UI messages.")
- parser.add_argument('-o', '--output', help="Output messages file path.")
- args = parser.parse_args()
-
- if args.output:
- global FILE_NAME_MESSAGES
- FILE_NAME_MESSAGES = args.output
-
- dump_messages(do_messages=args.no_messages, do_checks=args.no_checks)
-
- sys.argv = back_argv
-
-
-if __name__ == "__main__":
- print("\n\n *** Running {} *** \n".format(__file__))
- main()
diff --git a/release/scripts/modules/bl_i18n_utils/check_po.py b/release/scripts/modules/bl_i18n_utils/check_po.py
index 2e82047bb95..96f91ee0914 100755
--- a/release/scripts/modules/bl_i18n_utils/check_po.py
+++ b/release/scripts/modules/bl_i18n_utils/check_po.py
@@ -38,45 +38,47 @@ BRANCHES_DIR = settings.BRANCHES_DIR
FILE_NAME_POT = settings.FILE_NAME_POT
-def print_diff(ref_messages, messages, states):
+def print_diff(ref_msgs, msgs):
# Remove comments from messages list!
- messages = set(messages.keys()) - states["comm_msg"]
- unneeded = (messages - ref_messages)
- for msgid in unneeded:
- print('\tUnneeded message id "{}"'.format(msgid))
+ messages = set(msgs.msgs.keys()) - msgs.comm_msgs
+ unneeded = (messages - ref_msgs.msgs.keys())
+ for msgkey in unneeded:
+ print('\tUnneeded message context/id "{}"'.format(msgkey))
- missing = (ref_messages - messages)
- for msgid in missing:
- print('\tMissing message id "{}"'.format(msgid))
+ missing = (ref_msgs.msgs.keys() - messages)
+ for msgkey in missing:
+ print('\tMissing message context/id "{}"'.format(msgkey))
- for msgid in states["comm_msg"]:
- print('\tCommented message id "{}"'.format(msgid))
+ for msgid in msgs.comm_msgs:
+ print('\tCommented message context/id "{}"'.format(msgkey))
- print("\t{} unneeded messages, {} missing messages, {} commented messages." \
- "".format(len(unneeded), len(missing), len(states["comm_msg"])))
+ print("\t{} unneeded messages, {} missing messages, {} commented messages."
+ "".format(len(unneeded), len(missing), len(msgs.comm_msgs)))
return 0
-def process_po(ref_messages, po, glob_stats, do_stats, do_messages):
+#def process_po(ref_messages, po, glob_stats, do_stats, do_messages):
+def process_po(ref_messages, po, do_stats, do_messages):
print("Checking {}...".format(po))
ret = 0
- messages, states, stats = utils.parse_messages(po)
+ messages = utils.I18nMessages(kind='PO', src=po)
if do_messages:
- t = print_diff(ref_messages, messages, states)
+ t = print_diff(ref_messages, messages)
if t:
ret = t
if do_stats:
print("\tStats:")
- t = utils.print_stats(stats, glob_stats, prefix=" ")
+ t = messages.print_stats(prefix=" ")
if t:
ret = t
- if states["is_broken"]:
+ if messages.parsing_errors:
print("\tERROR! This .po is broken!")
ret = 1
return ret
+# XXX Quick update for new I18Nfoo objects, need rework!
def main():
import argparse
parser = argparse.ArgumentParser(description="Check po’s in branches " \
@@ -97,22 +99,21 @@ def main():
if args.pot:
global FILE_NAME_POT
FILE_NAME_POT = args.pot
- glob_stats = {"nbr" : 0.0,
- "lvl" : 0.0,
- "lvl_ttips" : 0.0,
- "lvl_trans_ttips" : 0.0,
- "lvl_ttips_in_trans": 0.0,
- "lvl_comm" : 0.0,
- "nbr_signs" : 0,
- "nbr_trans_signs" : 0,
- "contexts" : set()}
+ #glob_stats = {"nbr" : 0.0,
+ #"lvl" : 0.0,
+ #"lvl_ttips" : 0.0,
+ #"lvl_trans_ttips" : 0.0,
+ #"lvl_ttips_in_trans": 0.0,
+ #"lvl_comm" : 0.0,
+ #"nbr_signs" : 0,
+ #"nbr_trans_signs" : 0,
+ #"contexts" : set()}
ret = 0
pot_messages = None
if args.messages:
- pot_messages, u1, pot_stats = utils.parse_messages(FILE_NAME_POT)
- pot_messages = set(pot_messages.keys())
- glob_stats["nbr_signs"] = pot_stats["nbr_signs"]
+ pot_messages = utils.I18nMessages(kind='PO', src=FILE_NAME_POT)
+ #glob_stats["nbr_signs"] = pot_stats["nbr_signs"]
if args.langs:
for lang in args.langs:
@@ -121,16 +122,16 @@ def main():
else:
po = os.path.join(BRANCHES_DIR, lang, ".".join((lang, "po")))
if os.path.exists(po):
- t = process_po(pot_messages, po, glob_stats,
- args.stats, args.messages)
+ #t = process_po(pot_messages, po, glob_stats, args.stats, args.messages)
+ t = process_po(pot_messages, po, args.stats, args.messages)
if t:
ret = t
elif args.trunk:
for po in os.listdir(TRUNK_PO_DIR):
if po.endswith(".po"):
po = os.path.join(TRUNK_PO_DIR, po)
- t = process_po(pot_messages, po, glob_stats,
- args.stats, args.messages)
+ #t = process_po(pot_messages, po, glob_stats, args.stats, args.messages)
+ t = process_po(pot_messages, po, args.stats, args.messages)
if t:
ret = t
else:
@@ -138,35 +139,35 @@ def main():
for po in os.listdir(os.path.join(BRANCHES_DIR, lang)):
if po.endswith(".po"):
po = os.path.join(BRANCHES_DIR, lang, po)
- t = process_po(pot_messages, po, glob_stats,
- args.stats, args.messages)
+ #t = process_po(pot_messages, po, glob_stats, args.stats, args.messages)
+ t = process_po(pot_messages, po, args.stats, args.messages)
if t:
ret = t
- if args.stats and glob_stats["nbr"] != 0.0:
- nbr_contexts = len(glob_stats["contexts"] - {""})
- if nbr_contexts != 1:
- if nbr_contexts == 0:
- nbr_contexts = "No"
- _ctx_txt = "s are"
- else:
- _ctx_txt = " is"
- print("\nAverage stats for all {:.0f} processed files:\n"
- " {:>6.1%} done!\n"
- " {:>6.1%} of messages are tooltips.\n"
- " {:>6.1%} of tooltips are translated.\n"
- " {:>6.1%} of translated messages are tooltips.\n"
- " {:>6.1%} of messages are commented.\n"
- " The org msgids are currently made of {} signs.\n"
- " All processed translations are currently made of {} signs.\n"
- " {} specific context{} present:\n {}\n"
- "".format(glob_stats["nbr"], glob_stats["lvl"] / glob_stats["nbr"],
- glob_stats["lvl_ttips"] / glob_stats["nbr"],
- glob_stats["lvl_trans_ttips"] / glob_stats["nbr"],
- glob_stats["lvl_ttips_in_trans"] / glob_stats["nbr"],
- glob_stats["lvl_comm"] / glob_stats["nbr"], glob_stats["nbr_signs"],
- glob_stats["nbr_trans_signs"], nbr_contexts, _ctx_txt,
- "\n ".join(glob_stats["contexts"]-{""})))
+ #if args.stats and glob_stats["nbr"] != 0.0:
+ #nbr_contexts = len(glob_stats["contexts"] - {""})
+ #if nbr_contexts != 1:
+ #if nbr_contexts == 0:
+ #nbr_contexts = "No"
+ #_ctx_txt = "s are"
+ #else:
+ #_ctx_txt = " is"
+ #print("\nAverage stats for all {:.0f} processed files:\n"
+ #" {:>6.1%} done!\n"
+ #" {:>6.1%} of messages are tooltips.\n"
+ #" {:>6.1%} of tooltips are translated.\n"
+ #" {:>6.1%} of translated messages are tooltips.\n"
+ #" {:>6.1%} of messages are commented.\n"
+ #" The org msgids are currently made of {} signs.\n"
+ #" All processed translations are currently made of {} signs.\n"
+ #" {} specific context{} present:\n {}\n"
+ #"".format(glob_stats["nbr"], glob_stats["lvl"] / glob_stats["nbr"],
+ #glob_stats["lvl_ttips"] / glob_stats["nbr"],
+ #glob_stats["lvl_trans_ttips"] / glob_stats["nbr"],
+ #glob_stats["lvl_ttips_in_trans"] / glob_stats["nbr"],
+ #glob_stats["lvl_comm"] / glob_stats["nbr"], glob_stats["nbr_signs"],
+ #glob_stats["nbr_trans_signs"], nbr_contexts, _ctx_txt,
+ #"\n ".join(glob_stats["contexts"]-{""})))
return ret
diff --git a/release/scripts/modules/bl_i18n_utils/clean_po.py b/release/scripts/modules/bl_i18n_utils/clean_po.py
index 2924ad9fb74..da8d25cb9f4 100755
--- a/release/scripts/modules/bl_i18n_utils/clean_po.py
+++ b/release/scripts/modules/bl_i18n_utils/clean_po.py
@@ -39,30 +39,27 @@ BRANCHES_DIR = settings.BRANCHES_DIR
def do_clean(po, strict):
print("Cleaning {}...".format(po))
- messages, states, u1 = utils.parse_messages(po)
+ msgs = utils.I18nMessages(kind='PO', src=po)
- if strict and states["is_broken"]:
+ if strict and msgs.parsing_errors:
print("ERROR! This .po file is broken!")
return 1
- for msgkey in states["comm_msg"]:
- del messages[msgkey]
- utils.write_messages(po, messages, states["comm_msg"], states["fuzzy_msg"])
- print("Removed {} commented messages.".format(len(states["comm_msg"])))
+ nbr_rem = len(msgs.comm_msgs)
+ for msgkey in msgs.comm_msgs:
+ del msgs.msgs[msgkey]
+ msgs.write(kind='PO', dest=po)
+ print("Removed {} commented messages.".format(nbr_rem))
return 0
def main():
import argparse
- parser = argparse.ArgumentParser(description="Clean po’s in branches " \
- "or trunk (i.e. remove " \
- "all commented messages).")
- parser.add_argument('-t', '--trunk', action="store_true",
- help="Clean po’s in trunk rather than branches.")
- parser.add_argument('-s', '--strict', action="store_true",
- help="Raise an error if a po is broken.")
- parser.add_argument('langs', metavar='ISO_code', nargs='*',
- help="Restrict processed languages to those.")
+ parser = argparse.ArgumentParser(description="Clean po’s in branches or trunk (i.e. remove all commented "
+ "messages).")
+ parser.add_argument('-t', '--trunk', action="store_true", help="Clean po’s in trunk rather than branches.")
+ parser.add_argument('-s', '--strict', action="store_true", help="Raise an error if a po is broken.")
+ parser.add_argument('langs', metavar='ISO_code', nargs='*', help="Restrict processed languages to those.")
args = parser.parse_args()
ret = 0
diff --git a/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py b/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py
index 533dded3c57..956d2e96154 100755
--- a/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py
+++ b/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py
@@ -26,7 +26,6 @@ import os
import shutil
import sys
import subprocess
-from codecs import open
try:
import settings
@@ -48,14 +47,10 @@ PY3 = settings.PYTHON3_EXEC
def main():
import argparse
- parser = argparse.ArgumentParser(description="Import advanced enough po’s " \
- "from branches to trunk.")
- parser.add_argument('-t', '--threshold', type=int,
- help="Import threshold, as a percentage.")
- parser.add_argument('-s', '--strict', action="store_true",
- help="Raise an error if a po is broken.")
- parser.add_argument('langs', metavar='ISO_code', nargs='*',
- help="Restrict processed languages to those.")
+ parser = argparse.ArgumentParser(description="Import advanced enough po’s from branches to trunk.")
+ parser.add_argument('-t', '--threshold', type=float, help="Import threshold, as a percentage.")
+ parser.add_argument('-s', '--strict', action="store_true", help="Raise an error if a po is broken.")
+ parser.add_argument('langs', metavar='ISO_code', nargs='*', help="Restrict processed languages to those.")
args = parser.parse_args()
ret = 0
@@ -70,51 +65,40 @@ def main():
po = os.path.join(BRANCHES_DIR, lang, ".".join((lang, "po")))
if os.path.exists(po):
po_is_rtl = os.path.join(BRANCHES_DIR, lang, RTL_PREPROCESS_FILE)
- msgs, state, stats = utils.parse_messages(po)
- tot_msgs = stats["tot_msg"]
- trans_msgs = stats["trans_msg"]
+ msgs = utils.I18nMessages(iso=lang, kind='PO', src=po)
lvl = 0.0
- if tot_msgs:
- lvl = float(trans_msgs) / float(tot_msgs)
+ if msgs.nbr_msgs:
+ lvl = msgs.nbr_trans_msgs / msgs.nbr_msgs
if lvl > threshold:
- if state["is_broken"] and args.strict:
- print("{:<10}: {:>6.1%} done, but BROKEN, skipped." \
- "".format(lang, lvl))
+ if msgs.parsing_errors and args.strict:
+ print("{:<10}: {:>6.1%} done, but BROKEN, skipped.".format(lang, lvl))
ret = 1
else:
if os.path.exists(po_is_rtl):
- out_po = os.path.join(TRUNK_PO_DIR,
- ".".join((lang, "po")))
- out_raw_po = os.path.join(TRUNK_PO_DIR,
- "_".join((lang, "raw.po")))
+ out_po = os.path.join(TRUNK_PO_DIR, ".".join((lang, "po")))
+ out_raw_po = os.path.join(TRUNK_PO_DIR, "_".join((lang, "raw.po")))
keys = []
trans = []
- for k, m in msgs.items():
+ for k, m in msgs.msgs.items():
keys.append(k)
- trans.append("".join(m["msgstr_lines"]))
+ trans.append(m.msgstr)
trans = rtl_preprocess.log2vis(trans)
for k, t in zip(keys, trans):
- # Mono-line for now...
- msgs[k]["msgstr_lines"] = [t]
- utils.write_messages(out_po, msgs, state["comm_msg"],
- state["fuzzy_msg"])
+ msgs.msgs[k].msgstr = t
+ msgs.write(kind='PO', dest=out_po)
# Also copies org po!
shutil.copy(po, out_raw_po)
- print("{:<10}: {:>6.1%} done, enough translated " \
- "messages, processed and copied to trunk." \
+ print("{:<10}: {:>6.1%} done, enough translated messages, processed and copied to trunk."
"".format(lang, lvl))
else:
shutil.copy(po, TRUNK_PO_DIR)
- print("{:<10}: {:>6.1%} done, enough translated " \
- "messages, copied to trunk.".format(lang, lvl))
+ print("{:<10}: {:>6.1%} done, enough translated messages, copied to trunk.".format(lang, lvl))
else:
- if state["is_broken"] and args.strict:
- print("{:<10}: {:>6.1%} done, BROKEN and not enough " \
- "translated messages, skipped".format(lang, lvl))
+ if msgs.parsing_errors and args.strict:
+ print("{:<10}: {:>6.1%} done, BROKEN and not enough translated messages, skipped".format(lang, lvl))
ret = 1
else:
- print("{:<10}: {:>6.1%} done, not enough translated " \
- "messages, skipped.".format(lang, lvl))
+ print("{:<10}: {:>6.1%} done, not enough translated messages, skipped.".format(lang, lvl))
return ret
diff --git a/release/scripts/modules/bl_i18n_utils/languages_menu_utils.py b/release/scripts/modules/bl_i18n_utils/languages_menu_utils.py
new file mode 100755
index 00000000000..789b1315659
--- /dev/null
+++ b/release/scripts/modules/bl_i18n_utils/languages_menu_utils.py
@@ -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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+# Update "languages" text file used by Blender at runtime to build translations menu.
+
+
+import os
+
+
+OK = 0
+MISSING = 1
+TOOLOW = 2
+FORBIDDEN = 3
+FLAG_MESSAGES = {
+ OK: "",
+ MISSING: "No translation yet!",
+ TOOLOW: "Not enough advanced to be included...",
+ FORBIDDEN: "Explicitly forbidden!",
+}
+
+def gen_menu_file(stats, settings):
+ # Generate languages file used by Blender's i18n system.
+ # First, match all entries in LANGUAGES to a lang in stats, if possible!
+ tmp = []
+ for uid_num, label, uid, in settings.LANGUAGES:
+ if uid in stats:
+ if uid in settings.IMPORT_LANGUAGES_SKIP:
+ tmp.append((stats[uid], uid_num, label, uid, FORBIDDEN))
+ else:
+ tmp.append((stats[uid], uid_num, label, uid, OK))
+ else:
+ tmp.append((0.0, uid_num, label, uid, MISSING))
+ stats = tmp
+ limits = sorted(settings.LANGUAGES_CATEGORIES, key=lambda it: it[0], reverse=True)
+ idx = 0
+ stats = sorted(stats, key=lambda it: it[0], reverse=True)
+ langs_cats = [[] for i in range(len(limits))]
+ highest_uid = 0
+ for lvl, uid_num, label, uid, flag in stats:
+ if lvl < limits[idx][0]:
+ # Sub-sort languages by iso-codes.
+ langs_cats[idx].sort(key=lambda it: it[2])
+ idx += 1
+ if lvl < settings.IMPORT_MIN_LEVEL and flag == OK:
+ flag = TOOLOW
+ langs_cats[idx].append((uid_num, label, uid, flag))
+ if abs(uid_num) > highest_uid:
+ highest_uid = abs(uid_num)
+ # Sub-sort last group of languages by iso-codes!
+ langs_cats[idx].sort(key=lambda it: it[2])
+ data_lines = [
+ "# File used by Blender to know which languages (translations) are available, ",
+ "# and to generate translation menu.",
+ "#",
+ "# File format:",
+ "# ID:MENULABEL:ISOCODE",
+ "# ID must be unique, except for 0 value (marks categories for menu).",
+ "# Line starting with a # are comments!",
+ "#",
+ "# Automatically generated by bl_i18n_utils/update_languages_menu.py script.",
+ "# Highest ID currently in use: {}".format(highest_uid),
+ ]
+ for cat, langs_cat in zip(limits, langs_cats):
+ data_lines.append("#")
+ # Write "category menu label"...
+ if langs_cat:
+ data_lines.append("0:{}:".format(cat[1]))
+ else:
+ # Do not write the category if it has no language!
+ data_lines.append("# Void category! #0:{}:".format(cat[1]))
+ # ...and all matching language entries!
+ for uid_num, label, uid, flag in langs_cat:
+ if flag == OK:
+ data_lines.append("{}:{}:{}".format(uid_num, label, uid))
+ else:
+ # Non-existing, commented entry!
+ data_lines.append("# {} #{}:{}:{}".format(FLAG_MESSAGES[flag], uid_num, label, uid))
+ with open(os.path.join(settings.TRUNK_MO_DIR, settings.LANGUAGES_FILE), 'w') as f:
+ f.write("\n".join(data_lines))
diff --git a/release/scripts/modules/bl_i18n_utils/merge_po.py b/release/scripts/modules/bl_i18n_utils/merge_po.py
index baf67de2e81..610be0f15bd 100755
--- a/release/scripts/modules/bl_i18n_utils/merge_po.py
+++ b/release/scripts/modules/bl_i18n_utils/merge_po.py
@@ -37,26 +37,22 @@ except:
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="" \
- "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" \
- "The fuzzy flag is removed if necessary.\n" \
- "All other comments are never modified.\n" \
- "Commented messages in dst will always remain " \
- "commented, and commented messages are never merged " \
+ 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"
+ "The fuzzy flag is removed if necessary.\n"
+ "All other comments are never modified.\n"
+ "Commented messages in dst will always remain commented, and commented messages are never merged "
"from sources.")
- parser.add_argument('-s', '--stats', action="store_true",
- help="Show statistics info.")
+ parser.add_argument('-s', '--stats', action="store_true", help="Show statistics info.")
parser.add_argument('-r', '--replace', action="store_true",
help="Replace existing messages of same \"level\" already in dest po.")
- parser.add_argument('dst', metavar='dst.po',
- help="The dest po into which merge the others.")
- parser.add_argument('src', metavar='src.po', nargs='+',
- help="The po's to merge into the dst.po one.")
+ parser.add_argument('dst', metavar='dst.po', help="The dest po into which merge the others.")
+ parser.add_argument('src', metavar='src.po', nargs='+', help="The po's to merge into the dst.po one.")
args = parser.parse_args()
ret = 0
@@ -67,89 +63,78 @@ def main():
nbr_added = 0
nbr_unfuzzied = 0
- dst_messages, dst_states, dst_stats = utils.parse_messages(args.dst)
- if dst_states["is_broken"]:
+ dst_msgs = utils.I18nMessages(kind='PO', src=args.dst)
+ if dst_msgs.parsing_errors:
print("Dest po is BROKEN, aborting.")
return 1
if args.stats:
print("Dest po, before merging:")
- utils.print_stats(dst_stats, prefix="\t")
- # If we don’t want to replace existing valid translations, pre-populate
- # done_msgkeys and done_fuzzy_msgkeys.
+ dst_msgs.print_stats(prefix="\t")
+ # If we don’t want to replace existing valid translations, pre-populate done_msgkeys and done_fuzzy_msgkeys.
if not args.replace:
- done_msgkeys = dst_states["trans_msg"].copy()
- done_fuzzy_msgkeys = dst_states["fuzzy_msg"].copy()
+ done_msgkeys = dst_msgs.trans_msgs.copy()
+ done_fuzzy_msgkeys = dst_msgs.fuzzy_msgs.copy()
for po in args.src:
- messages, states, stats = utils.parse_messages(po)
- if states["is_broken"]:
+ msgs = utils.I18nMessages(kind='PO', src=po)
+ if msgs.parsing_errors:
print("\tSrc po {} is BROKEN, skipping.".format(po))
ret = 1
continue
print("\tMerging {}...".format(po))
if args.stats:
print("\t\tMerged po stats:")
- utils.print_stats(stats, prefix="\t\t\t")
- for msgkey, val in messages.items():
+ msgs.print_stats(prefix="\t\t\t")
+ for msgkey, msg in msgs.msgs.items():
msgctxt, msgid = msgkey
# This msgkey has already been completely merged, or is a commented one,
# or the new message is commented, skip it.
- if msgkey in (done_msgkeys | dst_states["comm_msg"] | states["comm_msg"]):
+ if msgkey in (done_msgkeys | dst_msgs.comm_msgs | msgs.comm_msgs):
continue
- is_ttip = utils.is_tooltip(msgid)
+ is_ttip = msg.is_tooltip
# New messages does not yet exists in dest.
- if msgkey not in dst_messages:
- dst_messages[msgkey] = messages[msgkey]
- if msgkey in states["fuzzy_msg"]:
+ if msgkey not in dst_msgs.msgs:
+ dst_msgs[msgkey] = msgs.msgs[msgkey]
+ if msgkey in msgs.fuzzy_msgs:
done_fuzzy_msgkeys.add(msgkey)
- dst_states["fuzzy_msg"].add(msgkey)
- elif msgkey in states["trans_msg"]:
+ dst_msgs.fuzzy_msgs.add(msgkey)
+ elif msgkey in msgs.trans_msgs:
done_msgkeys.add(msgkey)
- dst_states["trans_msg"].add(msgkey)
- dst_stats["trans_msg"] += 1
- if is_ttip:
- dst_stats["trans_ttips"] += 1
+ dst_msgs.trans_msgs.add(msgkey)
nbr_added += 1
- dst_stats["tot_msg"] += 1
- if is_ttip:
- dst_stats["tot_ttips"] += 1
# From now on, the new messages is already in dst.
# New message is neither translated nor fuzzy, skip it.
- elif msgkey not in (states["trans_msg"] | states["fuzzy_msg"]):
+ elif msgkey not in (msgs.trans_msgs | msgs.fuzzy_msgs):
continue
# From now on, the new message is either translated or fuzzy!
# The new message is translated.
- elif msgkey in states["trans_msg"]:
- dst_messages[msgkey]["msgstr_lines"] = messages[msgkey]["msgstr_lines"]
+ elif msgkey in msgs.trans_msgs:
+ dst_msgs.msgs[msgkey].msgstr = msg.msgstr
done_msgkeys.add(msgkey)
done_fuzzy_msgkeys.discard(msgkey)
- if msgkey in dst_states["fuzzy_msg"]:
- dst_states["fuzzy_msg"].remove(msgkey)
+ if msgkey in dst_msgs.fuzzy_msgs:
+ dst_msgs.fuzzy_msgs.remove(msgkey)
nbr_unfuzzied += 1
- if msgkey not in dst_states["trans_msg"]:
- dst_states["trans_msg"].add(msgkey)
- dst_stats["trans_msg"] += 1
- if is_ttip:
- dst_stats["trans_ttips"] += 1
+ if msgkey not in dst_msgs.trans_msgs:
+ dst_msgs.trans_msgs.add(msgkey)
else:
nbr_replaced += 1
nbr_merged += 1
- # The new message is fuzzy, org one is fuzzy too,
- # and this msgkey has not yet been merged.
- elif msgkey not in (dst_states["trans_msg"] | done_fuzzy_msgkeys):
- dst_messages[msgkey]["msgstr_lines"] = messages[msgkey]["msgstr_lines"]
+ # The new message is fuzzy, org one is fuzzy too, and this msgkey has not yet been merged.
+ elif msgkey not in (dst_msgs.trans_msgs | done_fuzzy_msgkeys):
+ dst_msgs[msgkey].msgstr = msg.msgstr
done_fuzzy_msgkeys.add(msgkey)
- dst_states["fuzzy_msg"].add(msgkey)
+ dst_msgs.fuzzy_msgs.add(msgkey)
nbr_merged += 1
nbr_replaced += 1
- utils.write_messages(args.dst, dst_messages, dst_states["comm_msg"], dst_states["fuzzy_msg"])
+ dst_msgs.write(kind='PO', dest=args.dst)
- print("Merged completed. {} messages were merged (among which {} were replaced), " \
- "{} were added, {} were \"un-fuzzied\"." \
- "".format(nbr_merged, nbr_replaced, nbr_added, nbr_unfuzzied))
+ print("Merged completed. {} messages were merged (among which {} were replaced), {} were added, "
+ "{} were \"un-fuzzied\".".format(nbr_merged, nbr_replaced, nbr_added, nbr_unfuzzied))
if args.stats:
+ dst_msgs.update_info()
print("Final merged po stats:")
- utils.print_stats(dst_stats, prefix="\t")
+ dst_msgs.print_stats(prefix="\t")
return ret
diff --git a/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py b/release/scripts/modules/bl_i18n_utils/rtl_utils.py
index d28f87cf042..0544f93a262 100755
--- a/release/scripts/modules/bl_i18n_utils/rtl_preprocess.py
+++ b/release/scripts/modules/bl_i18n_utils/rtl_utils.py
@@ -36,18 +36,6 @@ import sys
import ctypes
import re
-try:
- import settings
- import utils
-except:
- from . import (settings, utils)
-
-
-FRIBIDI_LIB = settings.FRIBIDI_LIB
-
-###### Import C library and recreate "defines". #####
-fbd = ctypes.CDLL(FRIBIDI_LIB)
-
#define FRIBIDI_MASK_NEUTRAL 0x00000040L /* Is neutral */
FRIBIDI_PAR_ON = 0x00000040
@@ -80,12 +68,9 @@ FRIBIDI_FLAG_REMOVE_SPECIALS = 0x00040000
FRIBIDI_FLAG_SHAPE_ARAB_PRES = 0x00000100
FRIBIDI_FLAG_SHAPE_ARAB_LIGA = 0x00000200
-FRIBIDI_FLAGS_DEFAULT = FRIBIDI_FLAG_SHAPE_MIRRORING | \
- FRIBIDI_FLAG_REORDER_NSM | \
- FRIBIDI_FLAG_REMOVE_SPECIALS
+FRIBIDI_FLAGS_DEFAULT = FRIBIDI_FLAG_SHAPE_MIRRORING | FRIBIDI_FLAG_REORDER_NSM | FRIBIDI_FLAG_REMOVE_SPECIALS
-FRIBIDI_FLAGS_ARABIC = FRIBIDI_FLAG_SHAPE_ARAB_PRES | \
- FRIBIDI_FLAG_SHAPE_ARAB_LIGA
+FRIBIDI_FLAGS_ARABIC = FRIBIDI_FLAG_SHAPE_ARAB_PRES | FRIBIDI_FLAG_SHAPE_ARAB_LIGA
MENU_DETECT_REGEX = re.compile("%x\\d+\\|")
@@ -158,11 +143,13 @@ def protect_format_seq(msg):
return "".join(ret)
-def log2vis(msgs):
+def log2vis(msgs, settings):
"""
Globally mimics deprecated fribidi_log2vis.
msgs should be an iterable of messages to rtl-process.
"""
+ fbd = ctypes.CDLL(settings.FRIBIDI_LIB)
+
for msg in msgs:
msg = protect_format_seq(msg)
@@ -206,52 +193,3 @@ def log2vis(msgs):
# print(*(ord(c) for c in fbc_str))
yield fbc_str.value
-
-
-##### Command line stuff. #####
-def main():
- import argparse
- parser = argparse.ArgumentParser(description="" \
- "Preprocesses right-to-left languages.\n" \
- "You can use it either standalone, or through " \
- "import_po_from_branches or update_trunk.\n\n" \
- "Note: This has been tested on Linux, not 100% it will " \
- "work nicely on Windows or OsX.\n" \
- "Note: This uses ctypes, as there is no py3 binding for " \
- "fribidi currently. This implies you only need the " \
- "compiled C library to run it.\n" \
- "Note: It handles some formating/escape codes (like " \
- "\\\", %s, %x12, %.4f, etc.), protecting them from ugly " \
- "(evil) fribidi, which seems completely unaware of such " \
- "things (as unicode is...).")
- parser.add_argument('dst', metavar='dst.po',
- help="The dest po into which write the " \
- "pre-processed messages.")
- parser.add_argument('src', metavar='src.po',
- help="The po's to pre-process messages.")
- args = parser.parse_args()
-
- msgs, state, u1 = utils.parse_messages(args.src)
- if state["is_broken"]:
- print("Source po is BROKEN, aborting.")
- return 1
-
- keys = []
- trans = []
- for key, val in msgs.items():
- keys.append(key)
- trans.append("".join(val["msgstr_lines"]))
- trans = log2vis(trans)
- for key, trn in zip(keys, trans):
- # Mono-line for now...
- msgs[key]["msgstr_lines"] = [trn]
-
- utils.write_messages(args.dst, msgs, state["comm_msg"], state["fuzzy_msg"])
-
- print("RTL pre-process completed.")
- return 0
-
-
-if __name__ == "__main__":
- print("\n\n *** Running {} *** \n".format(__file__))
- sys.exit(main())
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index c7414e84046..31eac77b358 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -24,8 +24,12 @@
# XXX This is a template, most values should be OK, but some you’ll have to
# edit (most probably, BLENDER_EXEC and SOURCE_DIR).
-import os.path
+import json
+import os
+import sys
+
+import bpy
###############################################################################
# MISC
@@ -80,29 +84,94 @@ LANGUAGES = (
(34, "Estonian (Eestlane)", "et_EE"),
(35, "Esperanto (Esperanto)", "eo"),
(36, "Spanish from Spain (Español de España)", "es_ES"),
+ (37, "Amharic (አማርኛ)", "am_ET"),
+ (38, "Uzbek (Oʻzbek)", "uz_UZ"),
+ (39, "Uzbek Cyrillic (Ўзбек)", "uz_UZ@cyrillic"),
+ (40, "Hindi (मानक हिनà¥à¤¦à¥€)", "hi_IN"),
)
+# Default context, in py!
+DEFAULT_CONTEXT = bpy.app.translations.contexts.default
+
# Name of language file used by Blender to generate translations' menu.
LANGUAGES_FILE = "languages"
-# The min level of completeness for a po file to be imported from /branches
-# into /trunk, as a percentage. -1 means "import everything".
-IMPORT_MIN_LEVEL = -1
+# The min level of completeness for a po file to be imported from /branches into /trunk, as a percentage.
+IMPORT_MIN_LEVEL = 0.0
# Languages in /branches we do not want to import in /trunk currently...
-IMPORT_LANGUAGES_SKIP = {'bg', 'ca', 'fi', 'el', 'ko', 'ne', 'pl', 'ro'}
+IMPORT_LANGUAGES_SKIP = {
+ 'am_ET', 'bg_BG', 'fi_FI', 'el_GR', 'et_EE', 'ne_NP', 'pl_PL', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic',
+}
+
+# Languages that need RTL pre-processing.
+IMPORT_LANGUAGES_RTL = {
+ 'ar_EG', 'fa_IR', 'he_IL',
+}
+
+# The comment prefix used in generated messages.txt file.
+MSG_COMMENT_PREFIX = "#~ "
# The comment prefix used in generated messages.txt file.
-COMMENT_PREFIX = "#~ "
+MSG_CONTEXT_PREFIX = "MSGCTXT:"
+
+# The default comment prefix used in po's.
+PO_COMMENT_PREFIX= "# "
# The comment prefix used to mark sources of msgids, in po's.
-COMMENT_PREFIX_SOURCE = "#: "
+PO_COMMENT_PREFIX_SOURCE = "#: "
-# The comment prefix used in generated messages.txt file.
-CONTEXT_PREFIX = "MSGCTXT:"
+# The comment prefix used to mark sources of msgids, in po's.
+PO_COMMENT_PREFIX_SOURCE_CUSTOM = "#. :src: "
+
+# The general "generated" comment prefix, in po's.
+PO_COMMENT_PREFIX_GENERATED = "#. "
+
+# The comment prefix used to comment entries in po's.
+PO_COMMENT_PREFIX_MSG= "#~ "
+
+# The comment prefix used to mark fuzzy msgids, in po's.
+PO_COMMENT_FUZZY = "#, fuzzy"
+
+# The prefix used to define context, in po's.
+PO_MSGCTXT = "msgctxt "
+
+# The prefix used to define msgid, in po's.
+PO_MSGID = "msgid "
+
+# The prefix used to define msgstr, in po's.
+PO_MSGSTR = "msgstr "
+
+# The 'header' key of po files.
+PO_HEADER_KEY = (DEFAULT_CONTEXT, "")
+
+PO_HEADER_MSGSTR = (
+ "Project-Id-Version: {blender_ver} (r{blender_rev})\\n\n"
+ "Report-Msgid-Bugs-To: \\n\n"
+ "POT-Creation-Date: {time}\\n\n"
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\n"
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\n"
+ "Language-Team: LANGUAGE <LL@li.org>\\n\n"
+ "Language: {uid}\\n\n"
+ "MIME-Version: 1.0\\n\n"
+ "Content-Type: text/plain; charset=UTF-8\\n\n"
+ "Content-Transfer-Encoding: 8bit\n"
+)
+PO_HEADER_COMMENT_COPYRIGHT = (
+ "# Blender's translation file (po format).\n"
+ "# Copyright (C) {year} The Blender Foundation.\n"
+ "# This file is distributed under the same license as the Blender package.\n"
+ "#\n"
+)
+PO_HEADER_COMMENT = (
+ "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n"
+ "#"
+)
+
+TEMPLATE_ISO_ID = "__TEMPLATE__"
-# Default context.
-CONTEXT_DEFAULT = ""
+# Num buttons report their label with a trailing ': '...
+NUM_BUTTON_SUFFIX = ": "
# Undocumented operator placeholder string.
UNDOC_OPS_STR = "(undocumented operator)"
@@ -118,8 +187,7 @@ PYGETTEXT_ALLOWED_EXTS = {".c", ".cpp", ".cxx", ".hpp", ".hxx", ".h"}
PYGETTEXT_MAX_MULTI_CTXT = 16
# Where to search contexts definitions, relative to SOURCE_DIR (defined below).
-PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blenfont",
- "BLF_translation.h")
+PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blenfont", "BLF_translation.h")
# Regex to extract contexts defined in BLF_translation.h
# XXX Not full-proof, but should be enough here!
@@ -143,11 +211,21 @@ _str_base = (
"(?P={_}2)" # And closing quote.
)
str_clean_re = _str_base.format(_="g", capt="P<clean>")
+_inbetween_str_re = (
+ # XXX Strings may have comments between their pieces too, not only spaces!
+ r"(?:\s*(?:"
+ # A C comment
+ r"/\*.*(?!\*/).\*/|"
+ # Or a C++ one!
+ r"//[^\n]*\n"
+ # And we are done!
+ r")?)*"
+)
# Here we have to consider two different cases (empty string and other).
_str_whole_re = (
_str_base.format(_="{_}1_", capt=":") +
# Optional loop start, this handles "split" strings...
- "(?:(?<=[\"'])\\s*(?=[\"'])(?:"
+ "(?:(?<=[\"'])" + _inbetween_str_re + "(?=[\"'])(?:"
+ _str_base.format(_="{_}2_", capt=":") +
# End of loop.
"))*"
@@ -165,9 +243,10 @@ PYGETTEXT_KEYWORDS = (() +
for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_N_")) +
tuple(("{}\\((?:[^\"',]+,){{1,2}}\\s*" + _msg_re + r"\s*(?:\)|,)").format(it)
- for it in ("BKE_report", "BKE_reportf", "BKE_reports_prepend", "BKE_reports_prependf")) +
+ for it in ("BKE_report", "BKE_reportf", "BKE_reports_prepend", "BKE_reports_prependf",
+ "CTX_wm_operator_poll_msg_set")) +
- tuple(("{}\\((?:[^\"',]+,){{3}}\\s*" + _msg_re + r"\s*,").format(it)
+ tuple(("{}\\((?:[^\"',]+,){{3}}\\s*" + _msg_re + r"\s*\)").format(it)
for it in ("BMO_error_raise",)) +
tuple(("{}\\((?:[^\"',]+,)\\s*" + _msg_re + r"\s*(?:\)|,)").format(it)
@@ -178,11 +257,6 @@ PYGETTEXT_KEYWORDS = (() +
for it in ("BLF_I18N_MSGID_MULTI_CTXT",))
)
-ESCAPE_RE = (
- (r'((?<!\\)"|(?<!\\)\\(?!\\|"))', r"\\\1"),
- ('\t', r"\\t"),
-)
-
# Should po parser warn when finding a first letter not capitalized?
WARN_MSGID_NOT_CAPITALIZED = True
@@ -228,34 +302,42 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
}
WARN_MSGID_NOT_CAPITALIZED_ALLOWED |= set(lng[2] for lng in LANGUAGES)
+WARN_MSGID_END_POINT_ALLOWED = {
+ "Numpad .",
+ "Circle|Alt .",
+ "Temp. Diff.",
+ "Float Neg. Exp.",
+}
+
+PARSER_CACHE_HASH = 'sha1'
+
+PARSER_TEMPLATE_ID = "__POT__"
+PARSER_PY_ID = "__PY__"
+
+PARSER_PY_MARKER_BEGIN = "\n# ##### BEGIN AUTOGENERATED I18N SECTION #####\n"
+PARSER_PY_MARKER_END = "\n# ##### END AUTOGENERATED I18N SECTION #####\n"
+
+PARSER_MAX_FILE_SIZE = 2**24 # in bytes, i.e. 16 Mb.
###############################################################################
# PATHS
###############################################################################
-# The tools path, should be OK.
-TOOLS_DIR = os.path.join(os.path.dirname(__file__))
-
# The Python3 executable.You’ll likely have to edit it in your user_settings.py
# if you’re under Windows.
PYTHON3_EXEC = "python3"
# The Blender executable!
-# This is just an example, you’ll most likely have to edit it in your user_settings.py!
-BLENDER_EXEC = os.path.abspath(os.path.join(TOOLS_DIR, "..", "..", "..", "..", "blender"))
-
-# The xgettext tool. You’ll likely have to edit it in your user_settings.py if you’re under Windows.
-GETTEXT_XGETTEXT_EXECUTABLE = "xgettext"
-
-# The gettext msgmerge tool. You’ll likely have to edit it in your user_settings.py if you’re under Windows.
-GETTEXT_MSGMERGE_EXECUTABLE = "msgmerge"
+# This is just an example, you’ll have to edit it in your user_settings.py!
+BLENDER_EXEC = os.path.abspath(os.path.join("foo", "bar", "blender"))
+# check for blender.bin
+if not os.path.exists(BLENDER_EXEC):
+ if os.path.exists(BLENDER_EXEC + ".bin"):
+ BLENDER_EXEC = BLENDER_EXEC + ".bin"
# The gettext msgfmt "compiler". You’ll likely have to edit it in your user_settings.py if you’re under Windows.
GETTEXT_MSGFMT_EXECUTABLE = "msgfmt"
-# The svn binary... You’ll likely have to edit it in your user_settings.py if you’re under Windows.
-SVN_EXECUTABLE = "svn"
-
# The FriBidi C compiled library (.so under Linux, .dll under windows...).
# You’ll likely have to edit it in your user_settings.py if you’re under Windows., e.g. using the included one:
# FRIBIDI_LIB = os.path.join(TOOLS_DIR, "libfribidi.dll")
@@ -265,50 +347,63 @@ FRIBIDI_LIB = "libfribidi.so.0"
RTL_PREPROCESS_FILE = "is_rtl"
# The Blender source root path.
-# This is just an example, you’ll most likely have to override it in your user_settings.py!
-SOURCE_DIR = os.path.abspath(os.path.join(TOOLS_DIR, "..", "..", "..", "..", "..", "..", "blender_msgs"))
+# This is just an example, you’ll have to override it in your user_settings.py!
+SOURCE_DIR = os.path.abspath(os.path.join("blender"))
-# The bf-translation repository (you'll likely have to override this in your user_settings.py).
-I18N_DIR = os.path.abspath(os.path.join(TOOLS_DIR, "..", "..", "..", "..", "..", "..", "i18n"))
+# The bf-translation repository (you'll have to override this in your user_settings.py).
+I18N_DIR = os.path.abspath(os.path.join("i18n"))
-# The /branches path (overriden in bf-translation's i18n_override_settings.py).
-BRANCHES_DIR = os.path.join(I18N_DIR, "branches")
+# The /branches path (relative to I18N_DIR).
+REL_BRANCHES_DIR = os.path.join("branches")
-# The /trunk path (overriden in bf-translation's i18n_override_settings.py).
-TRUNK_DIR = os.path.join(I18N_DIR, "trunk")
+# The /trunk path (relative to I18N_DIR).
+REL_TRUNK_DIR = os.path.join("trunk")
-# The /trunk/po path (overriden in bf-translation's i18n_override_settings.py).
-TRUNK_PO_DIR = os.path.join(TRUNK_DIR, "po")
+# The /trunk/po path (relative to I18N_DIR).
+REL_TRUNK_PO_DIR = os.path.join(REL_TRUNK_DIR, "po")
-# The /trunk/mo path (overriden in bf-translation's i18n_override_settings.py).
-TRUNK_MO_DIR = os.path.join(TRUNK_DIR, "locale")
+# The /trunk/mo path (relative to I18N_DIR).
+REL_TRUNK_MO_DIR = os.path.join(REL_TRUNK_DIR, "locale")
-# The file storing Blender-generated messages.
-FILE_NAME_MESSAGES = os.path.join(TRUNK_PO_DIR, "messages.txt")
+# The Blender source path to check for i18n macros (relative to SOURCE_DIR).
+REL_POTFILES_SOURCE_DIR = os.path.join("source")
-# The Blender source path to check for i18n macros.
-POTFILES_SOURCE_DIR = os.path.join(SOURCE_DIR, "source")
+# The template messages file (relative to I18N_DIR).
+REL_FILE_NAME_POT = os.path.join(REL_BRANCHES_DIR, DOMAIN + ".pot")
-# The "source" file storing which files should be processed by xgettext, used to create FILE_NAME_POTFILES
-FILE_NAME_SRC_POTFILES = os.path.join(TRUNK_PO_DIR, "_POTFILES.in")
+# Mo root datapath.
+REL_MO_PATH_ROOT = os.path.join(REL_TRUNK_DIR, "locale")
-# The final (generated) file storing which files should be processed by xgettext.
-FILE_NAME_POTFILES = os.path.join(TRUNK_PO_DIR, "POTFILES.in")
+# Mo path generator for a given language.
+REL_MO_PATH_TEMPLATE = os.path.join(REL_MO_PATH_ROOT, "{}", "LC_MESSAGES")
-# The template messages file.
-FILE_NAME_POT = os.path.join(TRUNK_PO_DIR, ".".join((DOMAIN, "pot")))
+# Mo path generator for a given language (relative to any "locale" dir).
+MO_PATH_ROOT_RELATIVE = os.path.join("locale")
+MO_PATH_TEMPLATE_RELATIVE = os.path.join(MO_PATH_ROOT_RELATIVE, "{}", "LC_MESSAGES")
-# Other py files that should be searched for ui strings, relative to SOURCE_DIR.
-# Needed for Cycles, currently...
-CUSTOM_PY_UI_FILES = [os.path.join("intern", "cycles", "blender", "addon", "ui.py"),]
+# Mo file name.
+MO_FILE_NAME = DOMAIN + ".mo"
+# Where to search for py files that may contain ui strings (relative to SOURCE_DIR).
+REL_CUSTOM_PY_UI_FILES = [
+ os.path.join("release", "scripts", "startup", "bl_ui"),
+ os.path.join("intern", "cycles", "blender", "addon", "ui.py"),
+ os.path.join("release", "scripts", "modules", "rna_prop_ui.py"),
+]
+
+# An optional text file listing files to force include/exclude from py_xgettext process.
+SRC_POTFILES = ""
# A cache storing validated msgids, to avoid re-spellchecking them.
SPELL_CACHE = os.path.join("/tmp", ".spell_cache")
+# Threshold defining whether a new msgid is similar enough with an old one to reuse its translation...
+SIMILAR_MSGID_THRESHOLD = 0.75
+
+# Additional import paths to add to sys.path (';' separated)...
+INTERN_PY_SYS_PATHS = ""
# Custom override settings must be one dir above i18n tools itself!
-import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
try:
from bl_i18n_override_settings import *
@@ -320,3 +415,105 @@ try:
from user_settings import *
except ImportError: # If no user_settings available, it’s no error!
pass
+
+
+for p in set(INTERN_PY_SYS_PATHS.split(";")):
+ if p:
+ sys.path.append(p)
+
+
+# The settings class itself!
+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!)
+ if os.path.isabs(path):
+ return os.path.relpath(path, ref)
+ else:
+ return path
+
+def _gen_get_set_path(ref, name):
+ def _get(self):
+ return _do_get(getattr(self, ref), getattr(self, name))
+ def _set(self, value):
+ 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)]
+ def _set(self, value):
+ setattr(self, name, [_do_set(getattr(self, ref), p) for p in value])
+ return _get, _set
+
+class I18nSettings:
+ """
+ Class allowing persistence of our settings!
+ Saved in JSon format, so settings should be JSon'able objects!
+ """
+ _settings = None
+
+ def __new__(cls, *args, **kwargs):
+ # Addon preferences are singleton by definition, so is this class!
+ if not I18nSettings._settings:
+ cls._settings = super(I18nSettings, cls).__new__(cls)
+ cls._settings.__dict__ = {uid: data for uid, data in globals().items() if not uid.startswith("_")}
+ return I18nSettings._settings
+
+ def from_json(self, string):
+ data = dict(json.loads(string))
+ # Special case... :/
+ if "INTERN_PY_SYS_PATHS" in data:
+ self.PY_SYS_PATHS = data["INTERN_PY_SYS_PATHS"]
+ self.__dict__.update(data)
+
+ def to_json(self):
+ # Only save the diff from default i18n_settings!
+ glob = globals()
+ export_dict = {uid: val for uid, val in self.__dict__.items() if glob.get(uid) != val}
+ return json.dumps(export_dict)
+
+ def load(self, fname, reset=False):
+ if reset:
+ self.__dict__ = {uid: data for uid, data in globals().items() if not uid.startswith("_")}
+ if isinstance(fname, str):
+ if not os.path.isfile(fname):
+ return
+ with open(fname) as f:
+ self.from_json(f.read())
+ # Else assume fname is already a file(like) object!
+ else:
+ self.from_json(fname.read())
+
+ def save(self, fname):
+ if isinstance(fname, str):
+ with open(fname, 'w') as f:
+ f.write(self.to_json())
+ # Else assume fname is already a file(like) object!
+ else:
+ fname.write(self.to_json())
+
+ BRANCHES_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_BRANCHES_DIR")))
+ TRUNK_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_TRUNK_DIR")))
+ TRUNK_PO_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_TRUNK_PO_DIR")))
+ TRUNK_MO_DIR = property(*(_gen_get_set_path("I18N_DIR", "REL_TRUNK_MO_DIR")))
+ POTFILES_SOURCE_DIR = property(*(_gen_get_set_path("SOURCE_DIR", "REL_POTFILES_SOURCE_DIR")))
+ FILE_NAME_POT = property(*(_gen_get_set_path("I18N_DIR", "REL_FILE_NAME_POT")))
+ MO_PATH_ROOT = property(*(_gen_get_set_path("I18N_DIR", "REL_MO_PATH_ROOT")))
+ MO_PATH_TEMPLATE = property(*(_gen_get_set_path("I18N_DIR", "REL_MO_PATH_TEMPLATE")))
+ CUSTOM_PY_UI_FILES = property(*(_gen_get_set_paths("SOURCE_DIR", "REL_CUSTOM_PY_UI_FILES")))
+
+ def _get_py_sys_paths(self):
+ return self.INTERN_PY_SYS_PATHS
+ def _set_py_sys_paths(self, val):
+ old_paths = set(self.INTERN_PY_SYS_PATHS.split(";")) - {""}
+ new_paths = set(val.split(";")) - {""}
+ for p in old_paths - new_paths:
+ if p in sys.path:
+ sys.path.remove(p)
+ for p in new_paths - old_paths:
+ sys.path.append(p)
+ self.INTERN_PY_SYS_PATHS = val
+ PY_SYS_PATHS = property(_get_py_sys_paths, _set_py_sys_paths)
diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
index fbe405a61c6..ffa68ef5da2 100644
--- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
+++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
@@ -18,511 +18,561 @@
# <pep8 compliant>
+import enchant
+import os
+import pickle
import re
-_valid_before = "(?<=[\\s*'\"`])|(?<=[a-zA-Z][/-])|(?<=^)"
-_valid_after = "(?=[\\s'\"`.!?,;:])|(?=[/-]\\s*[a-zA-Z])|(?=$)"
-_valid_words = "(?:{})(?:(?:[A-Z]+[a-z]*)|[A-Z]*|[a-z]*)(?:{})".format(_valid_before, _valid_after)
-_reg = re.compile(_valid_words)
+class SpellChecker():
+ """
+ A basic spell checker.
+ """
+ # These must be all lower case for comparisons
+ uimsgs = {
+ # OK words
+ "aren", # aren't
+ "betweens", # yuck! in-betweens!
+ "boolean", "booleans",
+ "couldn", # couldn't
+ "decrement",
+ "derivate",
+ "doesn", # doesn't
+ "fader",
+ "hasn", # hasn't
+ "hoc", # ad-hoc
+ "indices",
+ "iridas",
+ "isn", # isn't
+ "iterable",
+ "kyrgyz",
+ "latin",
+ "merchantability",
+ "mplayer",
+ "vertices",
-def split_words(text):
- return [w for w in _reg.findall(text) if w]
+ # Merged words
+ "addon", "addons",
+ "antialiasing",
+ "arcsine", "arccosine", "arctangent",
+ "autoclip",
+ "autocomplete",
+ "autoname",
+ "autosave",
+ "autoscale",
+ "autosmooth",
+ "autosplit",
+ "backface", "backfacing",
+ "backimage",
+ "backscattered",
+ "bandnoise",
+ "bindcode",
+ "bitrate",
+ "blendin",
+ "bonesize",
+ "boundbox",
+ "boxpack",
+ "buffersize",
+ "builtin", "builtins",
+ "bytecode",
+ "chunksize",
+ "de",
+ "defocus",
+ "denoise",
+ "despill", "despilling",
+ "filebrowser",
+ "filelist",
+ "filename", "filenames",
+ "filepath", "filepaths",
+ "forcefield", "forcefields",
+ "fulldome", "fulldomes",
+ "fullscreen",
+ "gridline",
+ "hemi",
+ "inbetween",
+ "inscatter", "inscattering",
+ "libdata",
+ "lightless",
+ "lookup", "lookups",
+ "mathutils",
+ "midlevel",
+ "midground",
+ "mixdown",
+ "multi",
+ "multifractal",
+ "multires", "multiresolution",
+ "multisampling",
+ "multitexture",
+ "multiuser",
+ "namespace",
+ "keyconfig",
+ "playhead",
+ "polyline",
+ "popup", "popups",
+ "pre",
+ "precalculate",
+ "prefetch",
+ "premultiply", "premultiplied",
+ "prepass",
+ "prepend",
+ "preprocess", "preprocessing",
+ "preseek",
+ "readonly",
+ "realtime",
+ "rekey",
+ "remesh",
+ "reprojection",
+ "resize",
+ "restpose",
+ "retarget", "retargets", "retargeting", "retargeted",
+ "ringnoise",
+ "rolloff",
+ "screencast", "screenshot", "screenshots",
+ "selfcollision",
+ "singletexture",
+ "startup",
+ "stateful",
+ "starfield",
+ "subflare", "subflares",
+ "subframe", "subframes",
+ "subclass", "subclasses", "subclassing",
+ "subdirectory", "subdirectories", "subdir", "subdirs",
+ "submodule", "submodules",
+ "subpath",
+ "subsize",
+ "substep", "substeps",
+ "targetless",
+ "textbox", "textboxes",
+ "tilemode",
+ "timestamp", "timestamps",
+ "timestep", "timesteps",
+ "todo",
+ "un",
+ "unbake",
+ "uncomment",
+ "undeformed",
+ "undistort", "undistortion",
+ "ungroup",
+ "unhide",
+ "unindent",
+ "unkeyed",
+ "unpremultiply",
+ "unprojected",
+ "unreacted",
+ "unregister",
+ "unselected",
+ "unsubdivided", "unsubdivide",
+ "unshadowed",
+ "unspill",
+ "unstitchable",
+ "vectorscope",
+ "whitespace", "whitespaces",
+ "worldspace",
+ "workflow",
+ # Neologisms, slangs
+ "affectable",
+ "automagic", "automagically",
+ "blobby",
+ "blockiness", "blocky",
+ "collider", "colliders",
+ "deformer", "deformers",
+ "determinator",
+ "editability",
+ "keyer",
+ "lacunarity",
+ "numerics",
+ "occluder",
+ "passepartout",
+ "perspectively",
+ "pixelate",
+ "polygonization",
+ "selectability",
+ "slurph",
+ "stitchable",
+ "symmetrize",
+ "trackability",
+ "transmissivity",
+ "rasterized", "rasterization", "rasterizer",
+ "renderer", "renderable", "renderability",
-# These must be all lower case for comparisons
-dict_uimsgs = {
- # OK words
- "aren", # aren't
- "betweens", # yuck! in-betweens!
- "boolean", "booleans",
- "couldn", #couldn't
- "decrement",
- "derivate",
- "doesn", # doesn't
- "fader",
- "hasn", # hasn't
- "hoc", # ad-hoc
- "indices",
- "iridas",
- "isn", # isn't
- "iterable",
- "kyrgyz",
- "latin",
- "merchantability",
- "mplayer",
- "vertices",
+ # Abbreviations
+ "aero",
+ "amb",
+ "anim",
+ "bool",
+ "calc",
+ "config", "configs",
+ "const",
+ "coord", "coords",
+ "degr",
+ "dof",
+ "dupli", "duplis",
+ "eg",
+ "esc",
+ "expr",
+ "fac",
+ "fra",
+ "frs",
+ "grless",
+ "http",
+ "init",
+ "kbit", "kb",
+ "lensdist",
+ "loc", "rot", "pos",
+ "lorem",
+ "luma",
+ "mem",
+ "multicam",
+ "num",
+ "ok",
+ "orco",
+ "ortho",
+ "persp",
+ "pref", "prefs",
+ "prev",
+ "param",
+ "premul",
+ "quad", "quads",
+ "quat", "quats",
+ "recalc", "recalcs",
+ "refl",
+ "sel",
+ "spec",
+ "struct", "structs",
+ "tex",
+ "tri", "tris",
+ "uv", "uvs", "uvw", "uw", "uvmap",
+ "vec",
+ "vel", # velocity!
+ "vert", "verts",
+ "vis",
+ "xyz", "xzy", "yxz", "yzx", "zxy", "zyx",
+ "xy", "xz", "yx", "yz", "zx", "zy",
- # Merged words
- "addon", "addons",
- "antialiasing",
- "arcsine", "arccosine", "arctangent",
- "autoclip",
- "autocomplete",
- "autoname",
- "autosave",
- "autoscale",
- "autosmooth",
- "autosplit",
- "backface", "backfacing",
- "backimage",
- "backscattered",
- "bandnoise",
- "bindcode",
- "bitrate",
- "blendin",
- "bonesize",
- "boundbox",
- "boxpack",
- "buffersize",
- "builtin", "builtins",
- "bytecode",
- "chunksize",
- "de",
- "defocus",
- "denoise",
- "despill", "despilling",
- "filebrowser",
- "filelist",
- "filename", "filenames",
- "filepath", "filepaths",
- "forcefield", "forcefields",
- "fulldome", "fulldomes",
- "fullscreen",
- "gridline",
- "hemi",
- "inbetween",
- "inscatter", "inscattering",
- "libdata",
- "lightless",
- "lookup", "lookups",
- "mathutils",
- "midlevel",
- "midground",
- "mixdown",
- "multi",
- "multifractal",
- "multires", "multiresolution",
- "multisampling",
- "multitexture",
- "multiuser",
- "namespace",
- "keyconfig",
- "playhead",
- "polyline",
- "popup", "popups",
- "pre",
- "precalculate",
- "prefetch",
- "premultiply", "premultiplied",
- "prepass",
- "prepend",
- "preprocess", "preprocessing",
- "preseek",
- "readonly",
- "realtime",
- "rekey",
- "remesh",
- "reprojection",
- "resize",
- "restpose",
- "retarget", "retargets", "retargeting", "retargeted",
- "ringnoise",
- "rolloff",
- "screencast", "screenshot", "screenshots",
- "selfcollision",
- "singletexture",
- "startup",
- "stateful",
- "starfield",
- "subflare", "subflares",
- "subframe", "subframes",
- "subclass", "subclasses", "subclassing",
- "subdirectory", "subdirectories", "subdir", "subdirs",
- "submodule", "submodules",
- "subpath",
- "subsize",
- "substep", "substeps",
- "targetless",
- "textbox", "textboxes",
- "tilemode",
- "timestamp", "timestamps",
- "timestep", "timesteps",
- "todo",
- "un",
- "unbake",
- "uncomment",
- "undeformed",
- "undistort", "undistortion",
- "ungroup",
- "unhide",
- "unindent",
- "unkeyed",
- "unpremultiply",
- "unprojected",
- "unreacted",
- "unregister",
- "unselected",
- "unsubdivided", "unsubdivide",
- "unshadowed",
- "unspill",
- "unstitchable",
- "vectorscope",
- "whitespace", "whitespaces",
- "worldspace",
- "workflow",
+ # General computer/science terms
+ "boid", "boids",
+ "equisolid",
+ "euler", "eulers",
+ "hashable",
+ "intrinsics",
+ "isosurface",
+ "jitter", "jittering", "jittered",
+ "keymap", "keymaps",
+ "lambertian",
+ "laplacian",
+ "metadata",
+ "nand", "xnor",
+ "normals",
+ "numpad",
+ "octree",
+ "opengl",
+ "pulldown", "pulldowns",
+ "quantized",
+ "samplerate",
+ "scrollback",
+ "scrollbar",
+ "scroller",
+ "searchable",
+ "spacebar",
+ "tooltip", "tooltips",
+ "trackpad",
+ "unicode",
+ "viewport", "viewports",
+ "viscoelastic",
+ "wildcard", "wildcards",
- # Neologisms, slangs
- "affectable",
- "automagic", "automagically",
- "blobby",
- "blockiness", "blocky",
- "collider", "colliders",
- "deformer", "deformers",
- "determinator",
- "editability",
- "keyer",
- "lacunarity",
- "numerics",
- "occluder",
- "passepartout",
- "perspectively",
- "polygonization",
- "selectability",
- "slurph",
- "stitchable",
- "symmetrize",
- "trackability",
- "transmissivity",
- "rasterized", "rasterization",
- "renderer", "renderable", "renderability",
+ # General computer graphics terms
+ "anaglyph",
+ "bezier", "beziers",
+ "bicubic",
+ "bilinear",
+ "blackpoint", "whitepoint",
+ "blinn",
+ "bokeh",
+ "catadioptric",
+ "centroid",
+ "chrominance",
+ "codec", "codecs",
+ "collada",
+ "compositing",
+ "crossfade",
+ "deinterlace",
+ "dropoff",
+ "dv",
+ "eigenvectors",
+ "equirectangular",
+ "fisheye",
+ "framerate",
+ "gimbal",
+ "grayscale",
+ "icosphere",
+ "inpaint",
+ "lightmap",
+ "lossless", "lossy",
+ "matcap",
+ "midtones",
+ "mipmap", "mipmaps", "mip",
+ "ngon", "ngons",
+ "ntsc",
+ "nurb", "nurbs",
+ "perlin",
+ "phong",
+ "radiosity",
+ "raytrace", "raytracing", "raytraced",
+ "renderfarm",
+ "shader", "shaders",
+ "specular", "specularity",
+ "spillmap",
+ "sobel",
+ "tonemap",
+ "toon",
+ "timecode",
+ "voronoi",
+ "voxel", "voxels",
+ "wireframe",
+ "zmask",
+ "ztransp",
- # Abbreviations
- "aero",
- "amb",
- "anim",
- "bool",
- "calc",
- "config", "configs",
- "const",
- "coord", "coords",
- "degr",
- "dof",
- "dupli", "duplis",
- "eg",
- "esc",
- "expr",
- "fac",
- "fra",
- "frs",
- "grless",
- "http",
- "init",
- "kbit",
- "lensdist",
- "loc", "rot", "pos",
- "lorem",
- "luma",
- "multicam",
- "num",
- "ok",
- "orco",
- "ortho",
- "persp",
- "pref", "prefs",
- "prev",
- "param",
- "premul",
- "quad", "quads",
- "quat", "quats",
- "recalc", "recalcs",
- "refl",
- "sel",
- "spec",
- "struct", "structs",
- "tex",
- "tri", "tris",
- "uv", "uvs", "uvw", "uw", "uvmap",
- "vec",
- "vert", "verts",
- "vis",
- "xyz", "xzy", "yxz", "yzx", "zxy", "zyx",
- "xy", "xz", "yx", "yz", "zx", "zy",
+ # Blender terms
+ "audaspace",
+ "bbone",
+ "breakdowner",
+ "bspline",
+ "bweight",
+ "colorband",
+ "datablock", "datablocks",
+ "despeckle",
+ "dopesheet",
+ "dupliface", "duplifaces",
+ "dupliframe", "dupliframes",
+ "dupliobject", "dupliob",
+ "dupligroup",
+ "duplivert",
+ "editbone",
+ "editmode",
+ "fcurve", "fcurves",
+ "fluidsim",
+ "frameserver",
+ "enum",
+ "keyframe", "keyframes", "keyframing", "keyframed",
+ "metaball", "metaballs",
+ "metaelement", "metaelements",
+ "metastrip", "metastrips",
+ "movieclip",
+ "mpoly",
+ "mtex",
+ "nabla",
+ "navmesh",
+ "outliner",
+ "paintmap", "paintmaps",
+ "polygroup", "polygroups",
+ "poselib",
+ "pushpull",
+ "pyconstraint", "pyconstraints",
+ "shapekey", "shapekeys",
+ "shrinkfatten",
+ "shrinkwrap",
+ "softbody",
+ "stucci",
+ "sunsky",
+ "subsurf",
+ "tessface", "tessfaces",
+ "texface",
+ "timeline", "timelines",
+ "tosphere",
+ "uilist",
+ "vcol", "vcols",
+ "vgroup", "vgroups",
+ "vinterlace",
+ "wetmap", "wetmaps",
+ "wpaint",
+ "uvwarp",
- # General computer/science terms
- "boid", "boids",
- "equisolid",
- "euler", "eulers",
- "hashable",
- "intrinsics",
- "isosurface",
- "jitter", "jittering", "jittered",
- "keymap", "keymaps",
- "lambertian",
- "laplacian",
- "metadata",
- "nand", "xnor",
- "normals",
- "numpad",
- "octree",
- "opengl",
- "pulldown", "pulldowns",
- "quantized",
- "samplerate",
- "scrollback",
- "scrollbar",
- "scroller",
- "searchable",
- "spacebar",
- "tooltip", "tooltips",
- "trackpad",
- "unicode",
- "viewport", "viewports",
- "viscoelastic",
- "wildcard", "wildcards",
+ # Algorithm names
+ "beckmann",
+ "catmull",
+ "catrom",
+ "chebychev",
+ "courant",
+ "kutta",
+ "lennard",
+ "minkowski",
+ "minnaert",
+ "musgrave",
+ "nayar",
+ "netravali",
+ "oren",
+ "prewitt",
+ "runge",
+ "verlet",
+ "worley",
- # General computer graphics terms
- "anaglyph",
- "bezier", "beziers",
- "bicubic",
- "bilinear",
- "blackpoint", "whitepoint",
- "blinn",
- "bokeh",
- "catadioptric",
- "centroid",
- "chrominance",
- "codec", "codecs",
- "collada",
- "compositing",
- "crossfade",
- "deinterlace",
- "dropoff",
- "dv",
- "eigenvectors",
- "equirectangular",
- "fisheye",
- "framerate",
- "gimbal",
- "grayscale",
- "icosphere",
- "inpaint",
- "lightmap",
- "lossless", "lossy",
- "midtones",
- "mipmap", "mipmaps", "mip",
- "ngon", "ngons",
- "ntsc",
- "nurb", "nurbs",
- "perlin",
- "phong",
- "radiosity",
- "raytrace", "raytracing", "raytraced",
- "renderfarm",
- "shader", "shaders",
- "specular", "specularity",
- "spillmap",
- "sobel",
- "tonemap",
- "toon",
- "timecode",
- "voronoi",
- "voxel", "voxels",
- "wireframe",
- "zmask",
- "ztransp",
+ # Acronyms
+ "aa", "msaa",
+ "api",
+ "asc", "cdl",
+ "ascii",
+ "atrac",
+ "bw",
+ "ccd",
+ "cmd",
+ "cpus",
+ "ctrl",
+ "cw", "ccw",
+ "dev",
+ "djv",
+ "dpi",
+ "dvar",
+ "dx",
+ "eo",
+ "fh",
+ "fov",
+ "fft",
+ "futura",
+ "gfx",
+ "gl",
+ "glsl",
+ "gpl",
+ "gpu", "gpus",
+ "hc",
+ "hdc",
+ "hdr",
+ "hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
+ "hsv", "hsva",
+ "id",
+ "itu",
+ "lhs",
+ "lmb", "mmb", "rmb",
+ "mux",
+ "ndof",
+ "ppc",
+ "precisa",
+ "px",
+ "qmc",
+ "rgb", "rgba",
+ "rhs",
+ "rv",
+ "sdl",
+ "sl",
+ "smpte",
+ "svn",
+ "ui",
+ "unix",
+ "vbo", "vbos",
+ "ycc", "ycca",
+ "yuv", "yuva",
- # Blender terms
- "audaspace",
- "bbone",
- "breakdowner",
- "bspline",
- "bweight",
- "colorband",
- "datablock", "datablocks",
- "despeckle",
- "dopesheet",
- "dupliface", "duplifaces",
- "dupliframe", "dupliframes",
- "dupliobject", "dupliob",
- "dupligroup",
- "duplivert",
- "editbone",
- "editmode",
- "fcurve", "fcurves",
- "fluidsim",
- "frameserver",
- "enum",
- "keyframe", "keyframes", "keyframing", "keyframed",
- "metaball", "metaballs",
- "metaelement", "metaelements",
- "metastrip", "metastrips",
- "movieclip",
- "mpoly",
- "mtex",
- "nabla",
- "navmesh",
- "outliner",
- "paintmap", "paintmaps",
- "polygroup", "polygroups",
- "poselib",
- "pushpull",
- "pyconstraint", "pyconstraints",
- "shapekey", "shapekeys",
- "shrinkfatten",
- "shrinkwrap",
- "softbody",
- "stucci",
- "sunsky",
- "subsurf",
- "tessface", "tessfaces",
- "texface",
- "timeline", "timelines",
- "tosphere",
- "vcol", "vcols",
- "vgroup", "vgroups",
- "vinterlace",
- "wetmap", "wetmaps",
- "wpaint",
+ # Blender acronyms
+ "bge",
+ "bli",
+ "bvh",
+ "dbvt",
+ "dop", # BLI K-Dop BVH
+ "ik",
+ "nla",
+ "py",
+ "qbvh",
+ "rna",
+ "rvo",
+ "simd",
+ "sph",
+ "svbvh",
- # Algorithm names
- "beckmann",
- "catmull",
- "catrom",
- "chebychev",
- "courant",
- "kutta",
- "lennard",
- "minkowski",
- "minnaert",
- "musgrave",
- "nayar",
- "netravali",
- "oren",
- "prewitt",
- "runge",
- "verlet",
- "worley",
+ # CG acronyms
+ "ao",
+ "bsdf",
+ "ior",
+ "mocap",
- # Acronyms
- "aa", "msaa",
- "api",
- "asc", "cdl",
- "ascii",
- "atrac",
- "bw",
- "ccd",
- "cmd",
- "cpus",
- "ctrl",
- "cw", "ccw",
- "dev",
- "djv",
- "dpi",
- "dvar",
- "dx",
- "eo",
- "fh",
- "fov",
- "fft",
- "futura",
- "gfx",
- "gl",
- "glsl",
- "gpl",
- "gpu", "gpus",
- "hc",
- "hdc",
- "hdr",
- "hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
- "hsv", "hsva",
- "id",
- "itu",
- "lhs",
- "lmb", "mmb", "rmb",
- "mux",
- "ndof",
- "ppc",
- "precisa",
- "px",
- "qmc",
- "rgb", "rgba",
- "rhs",
- "rv",
- "sdl",
- "sl",
- "smpte",
- "svn",
- "ui",
- "unix",
- "vbo", "vbos",
- "ycc", "ycca",
- "yuv", "yuva",
+ # Files types/formats
+ "avi",
+ "attrac",
+ "autocad",
+ "autodesk",
+ "bmp",
+ "btx",
+ "cineon",
+ "dpx",
+ "dxf",
+ "eps",
+ "exr",
+ "fbx",
+ "ffmpeg",
+ "flac",
+ "gzip",
+ "ico",
+ "jpg", "jpeg",
+ "matroska",
+ "mdd",
+ "mkv",
+ "mpeg", "mjpeg",
+ "mtl",
+ "ogg",
+ "openjpeg",
+ "osl",
+ "oso",
+ "piz",
+ "png",
+ "po",
+ "quicktime",
+ "rle",
+ "sgi",
+ "stl",
+ "svg",
+ "targa", "tga",
+ "tiff",
+ "theora",
+ "vorbis",
+ "wav",
+ "xiph",
+ "xml",
+ "xna",
+ "xvid",
+ }
- # Blender acronyms
- "bge",
- "bli",
- "bvh",
- "dbvt",
- "dop", # BLI K-Dop BVH
- "ik",
- "nla",
- "py",
- "qbvh",
- "rna",
- "rvo",
- "simd",
- "sph",
- "svbvh",
+ _valid_before = "(?<=[\\s*'\"`])|(?<=[a-zA-Z][/-])|(?<=^)"
+ _valid_after = "(?=[\\s'\"`.!?,;:])|(?=[/-]\\s*[a-zA-Z])|(?=$)"
+ _valid_words = "(?:{})(?:(?:[A-Z]+[a-z]*)|[A-Z]*|[a-z]*)(?:{})".format(_valid_before, _valid_after)
+ _split_words = re.compile(_valid_words).findall
- # CG acronyms
- "ao",
- "bsdf",
- "ior",
- "mocap",
+ @classmethod
+ def split_words(cls, text):
+ return [w for w in cls._split_words(text) if w]
- # Files types/formats
- "avi",
- "attrac",
- "autodesk",
- "bmp",
- "btx",
- "cineon",
- "dpx",
- "dxf",
- "eps",
- "exr",
- "fbx",
- "ffmpeg",
- "flac",
- "gzip",
- "ico",
- "jpg", "jpeg",
- "matroska",
- "mdd",
- "mkv",
- "mpeg", "mjpeg",
- "mtl",
- "ogg",
- "openjpeg",
- "osl",
- "oso",
- "piz",
- "png",
- "po",
- "quicktime",
- "rle",
- "sgi",
- "stl",
- "svg",
- "targa", "tga",
- "tiff",
- "theora",
- "vorbis",
- "wav",
- "xiph",
- "xml",
- "xna",
- "xvid",
-}
+ def __init__(self, settings, lang="en_US"):
+ self.settings = settings
+ self.dict_spelling = enchant.Dict(lang)
+ self.cache = set(self.uimsgs)
+
+ cache = self.settings.SPELL_CACHE
+ if cache and os.path.exists(cache):
+ with open(cache, 'rb') as f:
+ self.cache |= set(pickle.load(f))
+
+ def __del__(self):
+ cache = self.settings.SPELL_CACHE
+ if cache and os.path.exists(cache):
+ with open(cache, 'wb') as f:
+ pickle.dump(self.cache, f)
+
+ def check(self, txt):
+ ret = []
+
+ if txt in self.cache:
+ return ret
+
+ for w in self.split_words(txt):
+ w_lower = w.lower()
+ if w_lower in self.cache:
+ continue
+ if not self.dict_spelling.check(w):
+ ret.append((w, self.dict_spelling.suggest(w)))
+ else:
+ self.cache.add(w_lower)
+
+ if not ret:
+ self.cache.add(txt)
+
+ return ret
diff --git a/release/scripts/modules/bl_i18n_utils/update_branches.py b/release/scripts/modules/bl_i18n_utils/update_branches.py
index 4c38a2f71fb..1a22a9835dd 100755
--- a/release/scripts/modules/bl_i18n_utils/update_branches.py
+++ b/release/scripts/modules/bl_i18n_utils/update_branches.py
@@ -43,42 +43,31 @@ FILE_NAME_POT = settings.FILE_NAME_POT
def main():
import argparse
- parser = argparse.ArgumentParser(description="" \
- "Update all branches:\n" \
- "* Generate a temp messages.txt file.\n" \
- "* Use it to generate a temp .pot file.\n" \
- "* Use it to update all .po’s in /branches.")
- parser.add_argument('--pproc-contexts', action="store_true",
- help="Pre-process po’s to avoid having plenty of "
- "fuzzy msgids just because a context was "
- "added/changed!")
- parser.add_argument('-c', '--no_checks', default=True,
- action="store_false",
- help="No checks over UI messages.")
+ parser = argparse.ArgumentParser(description="Update all branches:\n"
+ "* Generate a temp messages.txt file.\n"
+ "* Use it to generate a blender.pot file.\n"
+ "* Use it to update all .po’s in /branches.")
+ #parser.add_argument('--pproc-contexts', action="store_true",
+ #help="Pre-process po’s to avoid having plenty of fuzzy msgids just because a context was "
+ #"added/changed!")
+ parser.add_argument('-c', '--no_checks', default=True, action="store_false", help="No checks over UI messages.")
parser.add_argument('-a', '--add', action="store_true",
- help="Add missing po’s (useful only when one or " \
- "more languages are given!).")
- parser.add_argument('langs', metavar='ISO_code', nargs='*',
- help="Restrict processed languages to those.")
+ help="Add missing po’s (useful only when one or more languages are given!).")
+ parser.add_argument('langs', metavar='ISO_code', nargs='*', help="Restrict processed languages to those.")
args = parser.parse_args()
ret = 0
# Generate a temp messages file.
- dummy, msgfile = tempfile.mkstemp(suffix=".txt",
- prefix="blender_messages_")
+ dummy, msgfile = tempfile.mkstemp(suffix=".txt", prefix="blender_messages_")
os.close(dummy)
cmd = (PY3, "./update_msg.py", "-o", msgfile)
t = subprocess.call(cmd)
if t:
ret = t
- # Generate a temp pot file.
- # Back to having a pot file in trunk/po. It's quite useful for translators that want to start
+ # Generate blender.pot file in trunk/po. It's quite useful for translators that want to start
# a new translation and not not want to bother generating their own po from scratch!
-# dummy, potfile = tempfile.mkstemp(suffix=".pot",
-# prefix="blender_pot_")
-# os.close(dummy)
potfile = FILE_NAME_POT
cmd = [PY3, "./update_pot.py", "-i", msgfile, "-o", potfile]
if not args.no_checks:
@@ -93,8 +82,8 @@ def main():
if args.add:
cmd.append("-a")
cmd += args.langs
- if args.pproc_contexts:
- cmd.append("--pproc-contexts")
+ #if args.pproc_contexts:
+ #cmd.append("--pproc-contexts")
t = subprocess.call(cmd)
if t:
ret = t
diff --git a/release/scripts/modules/bl_i18n_utils/update_languages_menu.py b/release/scripts/modules/bl_i18n_utils/update_languages_menu.py
deleted file mode 100755
index 9b4cb20fadf..00000000000
--- a/release/scripts/modules/bl_i18n_utils/update_languages_menu.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/python3
-
-# ***** 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 *****
-
-# <pep8 compliant>
-
-# Update "languages" text file used by Blender at runtime to build translations menu.
-
-import os
-import sys
-import shutil
-
-try:
- import settings
- import utils
-except:
- from . import (settings, utils)
-
-TRUNK_PO_DIR = settings.TRUNK_PO_DIR
-TRUNK_MO_DIR = settings.TRUNK_MO_DIR
-
-LANGUAGES_CATEGORIES = settings.LANGUAGES_CATEGORIES
-LANGUAGES = settings.LANGUAGES
-LANGUAGES_FILE = settings.LANGUAGES_FILE
-
-OK = 0
-MISSING = 1
-TOOLOW = 2
-FORBIDDEN = 3
-FLAG_MESSAGES = {
- OK: "",
- MISSING: "No translation yet!",
- TOOLOW: "Not enough advanced to be included...",
- FORBIDDEN: "Explicitly forbidden!",
-}
-
-def find_matching_po(languages, stats, forbidden):
- """Match languages defined in LANGUAGES setting to relevant po, if possible!"""
- ret = []
- for uid, label, org_key, in languages:
- key = org_key
- if key not in stats:
- # Try to simplify the key (eg from es_ES to es).
- if '_' in org_key:
- key = org_key[0:org_key.index('_')]
- # For stuff like sr_SR@latin -> sr@latin...
- if '@' in org_key:
- key = key + org_key[org_key.index('@'):]
- if key in stats:
- if key in forbidden:
- ret.append((stats[key], uid, label, org_key, FORBIDDEN))
- else:
- ret.append((stats[key], uid, label, org_key, OK))
- else:
- ret.append((0.0, uid, label, org_key, MISSING))
- return ret
-
-def main():
- import argparse
- parser = argparse.ArgumentParser(description=""
- "Update 'languages' text file used by Blender at runtime to build translations menu.")
- parser.add_argument('-m', '--min_translation', type=int, default=-100,
- help="Minimum level of translation, as a percentage "
- "(translations below this are commented out in menu).")
- parser.add_argument('langs', metavar='ISO_code', nargs='*',
- help="Unconditionally exclude those languages from the menu.")
- args = parser.parse_args()
-
- ret = 0
- min_trans = args.min_translation / 100.0
- forbidden = set(args.langs)
- # 'DEFAULT' and en_US are always valid, fully-translated "languages"!
- stats = {"DEFAULT": 1.0, "en_US": 1.0}
-
- # Get the "done level" of each po in trunk...
- for po in os.listdir(TRUNK_PO_DIR):
- if po.endswith(".po") and not po.endswith("_raw.po"):
- lang = os.path.basename(po)[:-3]
- u1, u2, _stats = utils.parse_messages(os.path.join(TRUNK_PO_DIR, po))
- stats[lang] = _stats["trans_msg"] / _stats["tot_msg"]
-
- # Generate languages file used by Blender's i18n system.
- # First, match all entries in LANGUAGES to a lang in stats, if possible!
- stats = find_matching_po(LANGUAGES, stats, forbidden)
- limits = sorted(LANGUAGES_CATEGORIES, key=lambda it: it[0], reverse=True)
- idx = 0
- stats = sorted(stats, key=lambda it: it[0], reverse=True)
- langs_cats = [[] for i in range(len(limits))]
- highest_uid = 0
- for prop, uid, label, key, flag in stats:
- if prop < limits[idx][0]:
- # Sub-sort languages by iso-codes.
- langs_cats[idx].sort(key=lambda it: it[2])
- idx += 1
- if prop < min_trans and flag == OK:
- flag = TOOLOW
- langs_cats[idx].append((uid, label, key, flag))
- if abs(uid) > highest_uid:
- highest_uid = abs(uid)
- # Sub-sort last group of languages by iso-codes!
- langs_cats[idx].sort(key=lambda it: it[2])
- with open(os.path.join(TRUNK_MO_DIR, LANGUAGES_FILE), 'w', encoding="utf-8") as f:
- f.write("# File used by Blender to know which languages (translations) are available, \n")
- f.write("# and to generate translation menu.\n")
- f.write("#\n")
- f.write("# File format:\n")
- f.write("# ID:MENULABEL:ISOCODE\n")
- f.write("# ID must be unique, except for 0 value (marks categories for menu).\n")
- f.write("# Line starting with a # are comments!\n")
- f.write("#\n")
- f.write("# Automatically generated by bl_i18n_utils/update_languages_menu.py script.\n")
- f.write("# Highest ID currently in use: {}\n".format(highest_uid))
- for cat, langs_cat in zip(limits, langs_cats):
- f.write("#\n")
- # Write "category menu label"...
- if langs_cat:
- f.write("0:{}::\n".format(cat[1]))
- else:
- # Do not write the category if it has no language!
- f.write("# Void category! #0:{}:\n".format(cat[1]))
- # ...and all matching language entries!
- for uid, label, key, flag in langs_cat:
- if flag == OK:
- f.write("{}:{}:{}\n".format(uid, label, key))
- else:
- # Non-existing, commented entry!
- f.write("# {} #{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key))
-
-
-if __name__ == "__main__":
- print("\n\n *** Running {} *** \n".format(__file__))
- sys.exit(main())
diff --git a/release/scripts/modules/bl_i18n_utils/update_mo.py b/release/scripts/modules/bl_i18n_utils/update_mo.py
index 7f68736593c..ab6fedc87a7 100755
--- a/release/scripts/modules/bl_i18n_utils/update_mo.py
+++ b/release/scripts/modules/bl_i18n_utils/update_mo.py
@@ -51,11 +51,11 @@ def process_po(po, lang, mo=None):
# show stats
cmd = (GETTEXT_MSGFMT_EXECUTABLE,
- "--statistics",
- po,
- "-o",
- mo or os.path.join(mo_dir, ".".join((DOMAIN, "mo"))),
- )
+ "--statistics",
+ po,
+ "-o",
+ mo or os.path.join(mo_dir, ".".join((DOMAIN, "mo"))),
+ )
print("Running ", " ".join(cmd))
ret = subprocess.call(cmd)
diff --git a/release/scripts/modules/bl_i18n_utils/update_po.py b/release/scripts/modules/bl_i18n_utils/update_po.py
index 4c6495c5cfe..eb12782264a 100755
--- a/release/scripts/modules/bl_i18n_utils/update_po.py
+++ b/release/scripts/modules/bl_i18n_utils/update_po.py
@@ -22,7 +22,7 @@
# Update po’s in the branches from blender.pot in /trunk/po dir.
-import subprocess
+import concurrent.futures
import os
import sys
from codecs import open
@@ -41,73 +41,25 @@ TRUNK_PO_DIR = settings.TRUNK_PO_DIR
FILE_NAME_POT = settings.FILE_NAME_POT
-def pproc_newcontext_po(po, pot_messages, pot_stats):
- print("Adding new contexts to {}...".format(po))
- messages, state, stats = utils.parse_messages(po)
- known_ctxt = stats["contexts"]
- print("Already known (present) context(s): {}".format(str(known_ctxt)))
-
- new_ctxt = set()
- added = 0
- # Only use valid already translated messages!
- allowed_keys = state["trans_msg"] - state["fuzzy_msg"] - state["comm_msg"]
- for key in pot_messages.keys():
- ctxt, msgid = key
- if ctxt in known_ctxt:
- continue
- new_ctxt.add(ctxt)
- for t_ctxt in known_ctxt:
- # XXX The first match will win, this might not be optimal...
- t_key = (t_ctxt, msgid)
- if t_key in allowed_keys:
- # Wrong comments (sources) will be removed by msgmerge...
- messages[key] = messages[t_key]
- messages[key]["msgctxt_lines"] = [ctxt]
- added += 1
-
- utils.write_messages(po, messages, state["comm_msg"], state["fuzzy_msg"])
- print("Finished!\n {} new context(s) was/were added {}, adding {} new "
- "messages.\n".format(len(new_ctxt), str(new_ctxt), added))
- return 0
-
-
-def process_po(po, lang):
+def process_po(data):
+ po, lang, pot_msgs = data
# update po file
- cmd = (GETTEXT_MSGMERGE_EXECUTABLE,
- "--update",
- "-w", "1", # XXX Ugly hack to prevent msgmerge merging
- # short source comments together!
- "--no-wrap",
- "--backup=none",
- "--lang={}".format(lang),
- po,
- FILE_NAME_POT,
- )
-
+ msg = utils.I18nMessages(iso=lang, kind='PO', src=po)
print("Updating {}...".format(po))
- print("Running ", " ".join(cmd))
- ret = subprocess.call(cmd)
- print("Finished!\n")
- return ret
+ msg.update(pot_msgs)
+ msg.write(kind='PO', dest=po)
+ print("Finished updating {}!\n".format(po))
+ return 0
def main():
import argparse
- parser = argparse.ArgumentParser(description="Write out messages.txt "
- "from Blender.")
- parser.add_argument('-t', '--trunk', action="store_true",
- help="Update po’s in /trunk/po rather than /branches.")
- parser.add_argument('-i', '--input', metavar="File",
- help="Input pot file path.")
- parser.add_argument('--pproc-contexts', action="store_true",
- help="Pre-process po’s to avoid having plenty of "
- "fuzzy msgids just because a context was "
- "added/changed!")
+ parser = argparse.ArgumentParser(description="Write out messages.txt from Blender.")
+ parser.add_argument('-t', '--trunk', action="store_true", help="Update po’s in /trunk/po rather than /branches.")
+ parser.add_argument('-i', '--input', metavar="File", help="Input pot file path.")
parser.add_argument('-a', '--add', action="store_true",
- help="Add missing po’s (useful only when one or "
- "more languages are given!).")
- parser.add_argument('langs', metavar='ISO_code', nargs='*',
- help="Restrict processed languages to those.")
+ help="Add missing po’s (useful only when one or more languages are given!).")
+ parser.add_argument('langs', metavar='ISO_code', nargs='*', help="Restrict processed languages to those.")
args = parser.parse_args()
if args.input:
@@ -115,12 +67,8 @@ def main():
FILE_NAME_POT = args.input
ret = 0
- if args.pproc_contexts:
- _ctxt_proc = pproc_newcontext_po
- pot_messages, _a, pot_stats = utils.parse_messages(FILE_NAME_POT)
- else:
- _ctxt_proc = lambda a, b, c: 0
- pot_messages, pot_stats = None, None
+ pot_msgs = utils.I18nMessages(kind='PO', src=FILE_NAME_POT)
+ pool_data = []
if args.langs:
for lang in args.langs:
@@ -136,37 +84,30 @@ def main():
if not os.path.exists(po):
shutil.copy(FILE_NAME_POT, po)
if args.add or os.path.exists(po):
- t = _ctxt_proc(po, pot_messages, pot_stats)
- if t:
- ret = t
- t = process_po(po, lang)
- if t:
- ret = t
+ pool_data.append((po, lang, pot_msgs))
elif args.trunk:
for po in os.listdir(TRUNK_PO_DIR):
if po.endswith(".po"):
lang = os.path.basename(po)[:-3]
po = os.path.join(TRUNK_PO_DIR, po)
- t = _ctxt_proc(po, pot_messages, pot_stats)
- if t:
- ret = t
- t = process_po(po, lang)
- if t:
- ret = t
+ pool_data.append((po, lang, pot_msgs))
else:
for lang in os.listdir(BRANCHES_DIR):
po = os.path.join(BRANCHES_DIR, lang, ".".join((lang, "po")))
if os.path.exists(po):
- t = _ctxt_proc(po, pot_messages, pot_stats)
- if t:
- ret = t
- t = process_po(po, lang)
- if t:
- ret = t
+ pool_data.append((po, lang, pot_msgs))
+
+ for r in map(process_po, pool_data):
+ if r != 0:
+ ret = r
+ #with concurrent.futures.ProcessPoolExecutor() as executor:
+ #for r in executor.map(process_po, pool_data, timeout=600):
+ #if r != 0:
+ #ret = r
return ret
if __name__ == "__main__":
print("\n\n *** Running {} *** \n".format(__file__))
- sys.exit(main())
+ sys.exit(main()) \ No newline at end of file
diff --git a/release/scripts/modules/bl_i18n_utils/update_pot.py b/release/scripts/modules/bl_i18n_utils/update_pot.py
index ecb5d837a09..e05e60937a8 100755
--- a/release/scripts/modules/bl_i18n_utils/update_pot.py
+++ b/release/scripts/modules/bl_i18n_utils/update_pot.py
@@ -23,6 +23,7 @@
# Update blender.pot file from messages.txt
import subprocess
+import collections
import os
import sys
import re
@@ -41,9 +42,11 @@ except:
LANGUAGES_CATEGORIES = settings.LANGUAGES_CATEGORIES
LANGUAGES = settings.LANGUAGES
-COMMENT_PREFIX = settings.COMMENT_PREFIX
-COMMENT_PREFIX_SOURCE = settings.COMMENT_PREFIX_SOURCE
-CONTEXT_PREFIX = settings.CONTEXT_PREFIX
+PO_COMMENT_PREFIX = settings.PO_COMMENT_PREFIX
+PO_COMMENT_PREFIX_SOURCE = settings.PO_COMMENT_PREFIX_SOURCE
+PO_COMMENT_PREFIX_SOURCE_CUSTOM = settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM
+MSG_COMMENT_PREFIX = settings.MSG_COMMENT_PREFIX
+MSG_CONTEXT_PREFIX = settings.MSG_CONTEXT_PREFIX
FILE_NAME_MESSAGES = settings.FILE_NAME_MESSAGES
FILE_NAME_POT = settings.FILE_NAME_POT
SOURCE_DIR = settings.SOURCE_DIR
@@ -79,6 +82,10 @@ _clean_str = re.compile(settings.str_clean_re).finditer
clean_str = lambda s: "".join(m.group("clean") for m in _clean_str(s))
+def _new_messages():
+ return getattr(collections, "OrderedDict", dict)()
+
+
def check_file(path, rel_path, messages):
def process_entry(ctxt, msg):
# Context.
@@ -207,20 +214,22 @@ def get_svnrev():
def gen_empty_pot():
+ blender_ver = ""
blender_rev = get_svnrev().decode()
utctime = time.gmtime()
time_str = time.strftime("%Y-%m-%d %H:%M+0000", utctime)
year_str = time.strftime("%Y", utctime)
- return utils.gen_empty_messages(blender_rev, time_str, year_str)
+ return utils.I18nMessages.gen_empty_messages("__POT__", blender_ver, blender_rev, time_str, year_str)
escape_re = tuple(re.compile(r[0]) for r in settings.ESCAPE_RE)
escape = lambda s, n: escape_re[n].sub(settings.ESCAPE_RE[n][1], s)
-def merge_messages(msgs, states, messages, do_checks, spell_cache):
- num_added = num_present = 0
+def merge_messages(msgs, messages, do_checks, spell_cache):
+ num_added = 0
+ num_present = msgs.nbr_msgs
for (context, msgid), srcs in messages.items():
if do_checks:
err = spell_check(msgid, spell_cache)
@@ -233,19 +242,15 @@ def merge_messages(msgs, states, messages, do_checks, spell_cache):
for n in range(len(escape_re)):
msgid = escape(msgid, n)
- srcs = [COMMENT_PREFIX_SOURCE + s for s in srcs]
-
key = (context, msgid)
- if key not in msgs:
- msgs[key] = {"msgid_lines": [msgid],
- "msgstr_lines": [""],
- "comment_lines": srcs,
- "msgctxt_lines": [context]}
+ if key not in msgs.msgs:
+ msg = utils.I18nMessage([context], [msgid], [""], [])
+ msg.sources = srcs
+ msgs.msgs[key] = msg
num_added += 1
else:
- # We need to merge comments!
- msgs[key]["comment_lines"].extend(srcs)
- num_present += 1
+ # We need to merge sources!
+ msgs.msgs[key].sources += srcs
return num_added, num_present
@@ -270,7 +275,7 @@ def main():
print("Running fake py gettext…")
# Not using any more xgettext, simpler to do it ourself!
- messages = utils.new_messages()
+ messages = _new_messages()
py_xgettext(messages)
print("Finished, found {} messages.".format(len(messages)))
@@ -281,55 +286,49 @@ def main():
spell_cache = set()
print("Generating POT file {}…".format(FILE_NAME_POT))
- msgs, states = gen_empty_pot()
- tot_messages, _a = merge_messages(msgs, states, messages,
- True, spell_cache)
+ msgs = gen_empty_pot()
+ tot_messages, _a = merge_messages(msgs, messages, True, spell_cache)
# add messages collected automatically from RNA
print("\tMerging RNA messages from {}…".format(FILE_NAME_MESSAGES))
- messages = utils.new_messages()
+ messages.clear()
with open(FILE_NAME_MESSAGES, encoding="utf-8") as f:
srcs = []
context = ""
for line in f:
line = utils.stripeol(line)
- if line.startswith(COMMENT_PREFIX):
- srcs.append(line[len(COMMENT_PREFIX):].strip())
- elif line.startswith(CONTEXT_PREFIX):
- context = line[len(CONTEXT_PREFIX):].strip()
+ if line.startswith(MSG_COMMENT_PREFIX):
+ srcs.append(line[len(MSG_COMMENT_PREFIX):].strip())
+ elif line.startswith(MSG_CONTEXT_PREFIX):
+ context = line[len(MSG_CONTEXT_PREFIX):].strip()
else:
key = (context, line)
messages[key] = srcs
srcs = []
context = ""
- num_added, num_present = merge_messages(msgs, states, messages,
- True, spell_cache)
+ num_added, num_present = merge_messages(msgs, messages, True, spell_cache)
tot_messages += num_added
- print("\tMerged {} messages ({} were already present)."
- "".format(num_added, num_present))
+ print("\tMerged {} messages ({} were already present).".format(num_added, num_present))
print("\tAdding languages labels...")
- messages = {(CONTEXT_DEFAULT, lng[1]):
- ("Languages’ labels from bl_i18n_utils/settings.py",)
- for lng in LANGUAGES}
- messages.update({(CONTEXT_DEFAULT, cat[1]):
- ("Language categories’ labels from bl_i18n_utils/settings.py",)
- for cat in LANGUAGES_CATEGORIES})
- num_added, num_present = merge_messages(msgs, states, messages,
- True, spell_cache)
+ messages.clear()
+ messages.update(((CONTEXT_DEFAULT, lng[1]), ("Languages’ labels from bl_i18n_utils/settings.py",))
+ for lng in LANGUAGES)
+ messages.update(((CONTEXT_DEFAULT, cat[1]), ("Language categories’ labels from bl_i18n_utils/settings.py",))
+ for cat in LANGUAGES_CATEGORIES)
+ num_added, num_present = merge_messages(msgs, messages, True, spell_cache)
tot_messages += num_added
print("\tAdded {} language messages.".format(num_added))
# Write back all messages into blender.pot.
- utils.write_messages(FILE_NAME_POT, msgs, states["comm_msg"],
- states["fuzzy_msg"])
+ msgs.write('PO', FILE_NAME_POT)
if SPELL_CACHE and spell_cache:
with open(SPELL_CACHE, 'wb') as f:
pickle.dump(spell_cache, f)
- print("Finished, total: {} messages!".format(tot_messages - 1))
+ print("Finished, total: {} messages!".format(tot_messages))
return 0
diff --git a/release/scripts/modules/bl_i18n_utils/update_trunk.py b/release/scripts/modules/bl_i18n_utils/update_trunk.py
index b84a227ae0a..d7d1a9741cb 100755
--- a/release/scripts/modules/bl_i18n_utils/update_trunk.py
+++ b/release/scripts/modules/bl_i18n_utils/update_trunk.py
@@ -25,8 +25,7 @@
# * Copy po’s from branches advanced enough.
# * Clean po’s in trunk.
# * Compile po’s in trunk in mo’s, keeping track of those failing.
-# * Remove po’s, mo’s (and their dir’s) that failed to compile or
-# are no more present in trunk.
+# * Remove po’s, mo’s (and their dir’s) that failed to compile or are no more present in trunk.
import subprocess
import os
@@ -50,25 +49,6 @@ LANGUAGES_FILE = settings.LANGUAGES_FILE
PY3 = settings.PYTHON3_EXEC
-def find_matching_po(languages, stats):
- """Match languages defined in LANGUAGES setting to relevant po, if possible!"""
- ret = []
- for uid, label, org_key in languages:
- key = org_key
- if key not in stats:
- # Try to simplify the key (eg from es_ES to es).
- if '_' in org_key:
- key = org_key[0:org_key.index('_')]
- if '@' in org_key:
- key = key + org_key[org_key.index('@'):]
- if key in stats:
- ret.append((stats[key], uid, label, org_key))
- else:
- # Mark invalid entries, so that we can put them in the languages file,
- # but commented!
- ret.append((0.0, -uid, label, org_key))
- return ret
-
def main():
import argparse
parser = argparse.ArgumentParser(description=""
@@ -99,7 +79,8 @@ def main():
os.remove(po)
# Copy po’s from branches.
- cmd = [PY3, "./import_po_from_branches.py", "-s"]
+ #cmd = [PY3, "./import_po_from_branches.py", "-s"]
+ cmd = [PY3, "./import_po_from_branches.py"]
if args.threshold is not None:
cmd += ["-t", str(args.threshold)]
if args.langs:
@@ -124,7 +105,8 @@ def main():
if args.langs and lang not in args.langs:
continue
- cmd = [PY3, "./clean_po.py", "-t", "-s", lang]
+ #cmd = [PY3, "./clean_po.py", "-t", "-s", lang]
+ cmd = [PY3, "./clean_po.py", "-t", lang]
t = subprocess.call(cmd)
if t:
ret = t
diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py
index 9481f750092..8d5cf76d476 100644
--- a/release/scripts/modules/bl_i18n_utils/utils.py
+++ b/release/scripts/modules/bl_i18n_utils/utils.py
@@ -20,357 +20,1386 @@
# Some misc utilities...
+import collections
+import concurrent.futures
+import copy
+import hashlib
import os
+import re
+import struct
import sys
-import collections
+import tempfile
-from bl_i18n_utils import settings
+from bl_i18n_utils import settings, rtl_utils
+import bpy
-COMMENT_PREFIX = settings.COMMENT_PREFIX
-WARN_NC = settings.WARN_MSGID_NOT_CAPITALIZED
-NC_ALLOWED = settings.WARN_MSGID_NOT_CAPITALIZED_ALLOWED
+##### Misc Utils #####
+from bpy.app.translations import locale_explode
-def stripeol(s):
- return s.rstrip("\n\r")
+_valid_po_path_re = re.compile(r"^\S+:[0-9]+$")
+def is_valid_po_path(path):
+ return bool(_valid_po_path_re.match(path))
-# XXX For now, we assume that all messages > 30 chars are tooltips!
-def is_tooltip(msgid):
- return len(msgid) > 30
+def get_best_similar(data):
+ import difflib
+ key, use_similar, similar_pool = data
-def new_messages():
- return getattr(collections, 'OrderedDict', dict)()
+ # try to find some close key in existing messages...
+ # Optimized code inspired by difflib.get_close_matches (as we only need the best match).
+ # We also consider to never make a match when len differs more than -len_key / 2, +len_key * 2 (which is valid
+ # as long as use_similar is not below ~0.7).
+ # Gives an overall ~20% of improvement!
+ #tmp = difflib.get_close_matches(key[1], similar_pool, n=1, cutoff=use_similar)
+ #if tmp:
+ #tmp = tmp[0]
+ tmp = None
+ s = difflib.SequenceMatcher()
+ s.set_seq2(key[1])
+ len_key = len(key[1])
+ min_len = len_key // 2
+ max_len = len_key * 2
+ for x in similar_pool:
+ if min_len < len(x) < max_len:
+ s.set_seq1(x)
+ if s.real_quick_ratio() >= use_similar and s.quick_ratio() >= use_similar:
+ sratio = s.ratio()
+ if sratio >= use_similar:
+ tmp = x
+ use_similar = sratio
+ return key, tmp
-def parse_messages(fname):
+def locale_match(loc1, loc2):
"""
- Returns a tupple (messages, states, stats).
- messages is an odereddict of dicts
- {(ctxt, msgid): {msgid_lines:, msgstr_lines:,
- comment_lines:, msgctxt_lines:}}.
- states is a dict of three sets of (msgid, ctxt), and a boolean flag
- indicating the .po is somewhat broken
- {trans_msg:, fuzzy_msg:, comm_msg:, is_broken:}.
- stats is a dict of values
- {tot_msg:, trans_msg:, tot_ttips:, trans_ttips:, comm_msg:,
- nbr_signs:, nbr_trans_signs:, contexts: set()}.
- Note: This function will silently "arrange" mis-formated entries, thus
- using afterward write_messages() should always produce a po-valid file,
- though not correct!
+ Return:
+ -n if loc1 is a subtype of loc2 (e.g. 'fr_FR' is a subtype of 'fr').
+ +n if loc2 is a subtype of loc1.
+ n becomes smaller when both locales are more similar (e.g. (sr, sr_SR) are more similar than (sr, sr_SR@latin)).
+ 0 if they are exactly the same.
+ ... (Ellipsis) if they cannot match!
+ Note: We consider that 'sr_SR@latin' is a subtype of 'sr@latin', 'sr_SR' and 'sr', but 'sr_SR' and 'sr@latin' won't
+ match (will return ...)!
+ Note: About similarity, diff in variants are more important than diff in countries, currently here are the cases:
+ (sr, sr_SR) -> 1
+ (sr@latin, sr_SR@latin) -> 1
+ (sr, sr@latin) -> 2
+ (sr_SR, sr_SR@latin) -> 2
+ (sr, sr_SR@latin) -> 3
"""
- tot_messages = 0
- tot_tooltips = 0
- trans_messages = 0
- trans_tooltips = 0
- comm_messages = 0
- nbr_signs = 0
- nbr_trans_signs = 0
- contexts = set()
- reading_msgid = False
- reading_msgstr = False
- reading_msgctxt = False
- reading_comment = False
- is_translated = False
- is_fuzzy = False
- is_commented = False
- is_broken = False
- msgid_lines = []
- msgstr_lines = []
- msgctxt_lines = []
- comment_lines = []
-
- messages = new_messages()
- translated_messages = set()
- fuzzy_messages = set()
- commented_messages = set()
-
- def clean_vars():
- nonlocal reading_msgid, reading_msgstr, reading_msgctxt, \
- reading_comment, is_fuzzy, is_translated, is_commented, \
- msgid_lines, msgstr_lines, msgctxt_lines, comment_lines
- reading_msgid = reading_msgstr = reading_msgctxt = \
- reading_comment = False
- is_tooltip = is_fuzzy = is_translated = is_commented = False
+ if loc1 == loc2:
+ return 0
+ l1, c1, v1, *_1 = locale_explode(loc1)
+ l2, c2, v2, *_2 = locale_explode(loc2)
+
+ if l1 == l2:
+ if c1 == c2:
+ if v1 == v2:
+ return 0
+ elif v2 is None:
+ return -2
+ elif v1 is None:
+ return 2
+ return ...
+ elif c2 is None:
+ if v1 == v2:
+ return -1
+ elif v2 is None:
+ return -3
+ return ...
+ elif c1 is None:
+ if v1 == v2:
+ return 1
+ elif v1 is None:
+ return 3
+ return ...
+ return ...
+
+
+##### Main Classes #####
+
+class I18nMessage:
+ """
+ Internal representation of a message.
+ """
+ __slots__ = ("msgctxt_lines", "msgid_lines", "msgstr_lines", "comment_lines", "is_fuzzy", "is_commented",
+ "settings")
+
+ def __init__(self, msgctxt_lines=[], msgid_lines=[], msgstr_lines=[], comment_lines=[],
+ is_commented=False, is_fuzzy=False, settings=settings):
+ self.settings = settings
+ self.msgctxt_lines = msgctxt_lines
+ self.msgid_lines = msgid_lines
+ self.msgstr_lines = msgstr_lines
+ self.comment_lines = comment_lines
+ self.is_fuzzy = is_fuzzy
+ self.is_commented = is_commented
+
+ def _get_msgctxt(self):
+ return "".join(self.msgctxt_lines)
+ def _set_msgctxt(self, ctxt):
+ self.msgctxt_lines = [ctxt]
+ msgctxt = property(_get_msgctxt, _set_msgctxt)
+
+ def _get_msgid(self):
+ return "".join(self.msgid_lines)
+ def _set_msgid(self, msgid):
+ self.msgid_lines = [msgid]
+ msgid = property(_get_msgid, _set_msgid)
+
+ def _get_msgstr(self):
+ return "".join(self.msgstr_lines)
+ def _set_msgstr(self, msgstr):
+ self.msgstr_lines = [msgstr]
+ msgstr = property(_get_msgstr, _set_msgstr)
+
+ def _get_sources(self):
+ lstrip1 = len(self.settings.PO_COMMENT_PREFIX_SOURCE)
+ lstrip2 = len(self.settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM)
+ return ([l[lstrip1:] for l in self.comment_lines if l.startswith(self.settings.PO_COMMENT_PREFIX_SOURCE)] +
+ [l[lstrip2:] for l in self.comment_lines
+ if l.startswith(self.settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM)])
+ def _set_sources(self, sources):
+ cmmlines = self.comment_lines.copy()
+ for l in cmmlines:
+ if (l.startswith(self.settings.PO_COMMENT_PREFIX_SOURCE) or
+ l.startswith(self.settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM)):
+ self.comment_lines.remove(l)
+ lines_src = []
+ lines_src_custom = []
+ for src in sources:
+ if is_valid_po_path(src):
+ lines_src.append(self.settings.PO_COMMENT_PREFIX_SOURCE + src)
+ else:
+ lines_src_custom.append(self.settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM + src)
+ self.comment_lines += lines_src_custom + lines_src
+ sources = property(_get_sources, _set_sources)
+
+ def _get_is_tooltip(self):
+ # XXX For now, we assume that all messages > 30 chars are tooltips!
+ return len(self.msgid) > 30
+ is_tooltip = property(_get_is_tooltip)
+
+ def copy(self):
+ # Deepcopy everything but the settings!
+ return self.__class__(msgctxt_lines=self.msgctxt_lines[:], msgid_lines=self.msgid_lines[:],
+ msgstr_lines=self.msgstr_lines[:], comment_lines=self.comment_lines[:],
+ is_commented=self.is_commented, is_fuzzy=self.is_fuzzy, settings=self.settings)
+
+ def normalize(self, max_len=80):
+ """
+ Normalize this message, call this before exporting it...
+ Currently normalize msgctxt, msgid and msgstr lines to given max_len (if below 1, make them single line).
+ """
+ max_len -= 2 # The two quotes!
+
+ def _splitlines(text):
+ lns = text.splitlines()
+ return [l + "\n" for l in lns[:-1]] + lns[-1:]
+
+ # We do not need the full power of textwrap... We just split first at escaped new lines, then into each line
+ # if needed... No word splitting, nor fancy spaces handling!
+ def _wrap(text, max_len, init_len):
+ if len(text) + init_len < max_len:
+ return [text]
+ lines = _splitlines(text)
+ ret = []
+ for l in lines:
+ tmp = []
+ cur_len = 0
+ words = l.split(' ')
+ for w in words:
+ cur_len += len(w) + 1
+ if cur_len > (max_len - 1) and tmp:
+ ret.append(" ".join(tmp) + " ")
+ del tmp[:]
+ cur_len = len(w) + 1
+ tmp.append(w)
+ if tmp:
+ ret.append(" ".join(tmp))
+ return ret
+
+ if max_len < 1:
+ self.msgctxt_lines = _splitlines(self.msgctxt)
+ self.msgid_lines = _splitlines(self.msgid)
+ self.msgstr_lines = _splitlines(self.msgstr)
+ else:
+ init_len = len(self.settings.PO_MSGCTXT) + 1
+ if self.is_commented:
+ init_len += len(self.settings.PO_COMMENT_PREFIX_MSG)
+ self.msgctxt_lines = _wrap(self.msgctxt, max_len, init_len)
+
+ init_len = len(self.settings.PO_MSGID) + 1
+ if self.is_commented:
+ init_len += len(self.settings.PO_COMMENT_PREFIX_MSG)
+ self.msgid_lines = _wrap(self.msgid, max_len, init_len)
+
+ init_len = len(self.settings.PO_MSGSTR) + 1
+ if self.is_commented:
+ init_len += len(self.settings.PO_COMMENT_PREFIX_MSG)
+ self.msgstr_lines = _wrap(self.msgstr, max_len, init_len)
+
+ # Be sure comment lines are not duplicated (can happen with sources...).
+ tmp = []
+ for l in self.comment_lines:
+ if l not in tmp:
+ tmp.append(l)
+ self.comment_lines = tmp
+
+ _esc_quotes = re.compile(r'(?!<\\)((?:\\\\)*)"')
+ _unesc_quotes = re.compile(r'(?!<\\)((?:\\\\)*)\\"')
+ _esc_names = ("msgctxt_lines", "msgid_lines", "msgstr_lines")
+ _esc_names_all = _esc_names + ("comment_lines",)
+
+ @classmethod
+ def do_escape(cls, txt):
+ """Replace some chars by their escaped versions!"""
+ txt = txt.replace("\n", "\\n").replace("\t", "\\t")
+ txt = cls._esc_quotes.sub(r'\1\"', txt)
+ return txt
+
+ @classmethod
+ def do_unescape(cls, txt):
+ """Replace escaped chars by real ones!"""
+ txt = txt.replace("\\n", "\n").replace("\\t", "\t")
+ txt = cls._unesc_quotes.sub(r'\1"', txt)
+ return txt
+
+ def escape(self, do_all=False):
+ names = self._esc_names_all if do_all else self._esc_names
+ for name in names:
+ setattr(self, name, [self.do_escape(l) for l in getattr(self, name)])
+
+ def unescape(self, do_all=True):
+ names = self._esc_names_all if do_all else self._esc_names
+ for name in names:
+ setattr(self, name, [self.do_unescape(l) for l in getattr(self, name)])
+ if None in getattr(self, name):
+ print(getattr(self, name))
+
+
+class I18nMessages:
+ """
+ Internal representation of messages for one language (iso code), with additional stats info.
+ """
+
+ # Avoid parsing again!
+ # Keys should be (pseudo) file-names, values are tuples (hash, I18nMessages)
+ # Note: only used by po parser currently!
+ #_parser_cache = {}
+
+ def __init__(self, uid=None, kind=None, key=None, src=None, settings=settings):
+ self.settings = settings
+ self.uid = uid if uid is not None else settings.PARSER_TEMPLATE_ID
+ self.msgs = self._new_messages()
+ self.trans_msgs = set()
+ self.fuzzy_msgs = set()
+ self.comm_msgs = set()
+ self.ttip_msgs = set()
+ self.contexts = set()
+ self.nbr_msgs = 0
+ self.nbr_trans_msgs = 0
+ self.nbr_ttips = 0
+ self.nbr_trans_ttips = 0
+ self.nbr_comm_msgs = 0
+ self.nbr_signs = 0
+ self.nbr_trans_signs = 0
+ self.parsing_errors = []
+ if kind and src:
+ self.parse(kind, key, src)
+ self.update_info()
+
+ self._reverse_cache = None
+
+ @staticmethod
+ def _new_messages():
+ return getattr(collections, 'OrderedDict', dict)()
+
+ @classmethod
+ def gen_empty_messages(cls, uid, blender_ver, blender_rev, time, year, default_copyright=True, settings=settings):
+ """Generate an empty I18nMessages object (only header is present!)."""
+ fmt = settings.PO_HEADER_MSGSTR
+ msgstr = fmt.format(blender_ver=str(blender_ver), blender_rev=int(blender_rev), time=str(time), uid=str(uid))
+ comment = ""
+ if default_copyright:
+ comment = settings.PO_HEADER_COMMENT_COPYRIGHT.format(year=str(year))
+ comment = comment + settings.PO_HEADER_COMMENT
+
+ msgs = cls(uid=uid, settings=settings)
+ key = settings.PO_HEADER_KEY
+ msgs.msgs[key] = I18nMessage([key[0]], [key[1]], msgstr.split("\n"), comment.split("\n"),
+ False, False, settings=settings)
+ msgs.update_info()
+
+ return msgs
+
+ def normalize(self, max_len=80):
+ for msg in self.msgs.values():
+ msg.normalize(max_len)
+
+ def escape(self, do_all=False):
+ for msg in self.msgs.values():
+ msg.escape(do_all)
+
+ def unescape(self, do_all=True):
+ for msg in self.msgs.values():
+ msg.unescape(do_all)
+
+ def check(self, fix=False):
+ """
+ Check consistency between messages and their keys!
+ Check messages using format stuff are consistant between msgid and msgstr!
+ If fix is True, tries to fix the issues.
+ Return a list of found errors (empty if everything went OK!).
+ """
+ ret = []
+ default_context = self.settings.DEFAULT_CONTEXT
+ _format = re.compile("%[.0-9]*[tslfd]").findall
+ done_keys = set()
+ tmp = {}
+ rem = set()
+ for key, msg in self.msgs.items():
+ msgctxt, msgid, msgstr = msg.msgctxt, msg.msgid, msg.msgstr
+ real_key = (msgctxt or default_context, msgid)
+ if key != real_key:
+ ret.append("Error! msg's context/message do not match its key ({} / {})".format(real_key, key))
+ if real_key in self.msgs:
+ ret.append("Error! msg's real_key already used!")
+ if fix:
+ rem.add(real_key)
+ elif fix:
+ tmp[real_key] = msg
+ done_keys.add(key)
+ if '%' in msgid and msgstr and len(_format(msgid)) != len(_format(msgstr)):
+ ret.append("Error! msg's format entities are not matched in msgid and msgstr ({})".format(real_key))
+ if fix:
+ msg.msgstr = ""
+ for k in rem:
+ del self.msgs[k]
+ self.msgs.update(tmp)
+ return ret
+
+ def clean_commented(self):
+ self.update_info()
+ nbr = len(self.comm_msgs)
+ for k in self.comm_msgs:
+ del self.msgs[k]
+ return nbr
+
+ def rtl_process(self):
+ keys = []
+ trans = []
+ for k, m in self.msgs.items():
+ keys.append(k)
+ trans.append(m.msgstr)
+ trans = rtl_utils.log2vis(trans, self.settings)
+ for k, t in zip(keys, trans):
+ self.msgs[k].msgstr = t
+
+ def merge(self, replace=False, *args):
+ # TODO
+ pass
+
+ def update(self, ref, use_similar=None, keep_old_commented=True):
+ """
+ Update this I18nMessage with the ref one. Translations from ref are never used. Source comments from ref
+ completely replace current ones. If use_similar is not 0.0, it will try to match new messages in ref with an
+ existing one. Messages no more found in ref will be marked as commented if keep_old_commented is True,
+ or removed.
+ """
+ if use_similar is None:
+ use_similar = self.settings.SIMILAR_MSGID_THRESHOLD
+
+ similar_pool = {}
+ if use_similar > 0.0:
+ for key, msg in self.msgs.items():
+ if msg.msgstr: # No need to waste time with void translations!
+ similar_pool.setdefault(key[1], set()).add(key)
+
+ msgs = self._new_messages().fromkeys(ref.msgs.keys())
+ ref_keys = set(ref.msgs.keys())
+ org_keys = set(self.msgs.keys())
+ new_keys = ref_keys - org_keys
+ removed_keys = org_keys - ref_keys
+
+ # First process keys present in both org and ref messages.
+ for key in ref_keys - new_keys:
+ msg, refmsg = self.msgs[key], ref.msgs[key]
+ msg.sources = refmsg.sources
+ msg.is_commented = refmsg.is_commented
+ msg.is_fuzzy = refmsg.is_fuzzy
+ msgs[key] = msg
+
+ # Next process new keys.
+ if use_similar > 0.0:
+ with concurrent.futures.ProcessPoolExecutor() as exctr:
+ for key, msgid in exctr.map(get_best_similar,
+ tuple((nk, use_similar, tuple(similar_pool.keys())) for nk in new_keys)):
+ #for key, msgid in map(get_best_similar,
+ #tuple((nk, use_similar, tuple(similar_pool.keys())) for nk in new_keys)):
+ if msgid:
+ # Try to get the same context, else just get one...
+ skey = (key[0], msgid)
+ if skey not in similar_pool[msgid]:
+ skey = tuple(similar_pool[msgid])[0]
+ # We keep org translation and comments, and mark message as fuzzy.
+ msg, refmsg = self.msgs[skey].copy(), ref.msgs[key]
+ msg.msgctxt = refmsg.msgctxt
+ msg.msgid = refmsg.msgid
+ msg.sources = refmsg.sources
+ msg.is_fuzzy = True
+ msg.is_commented = refmsg.is_commented
+ msgs[key] = msg
+ else:
+ msgs[key] = ref.msgs[key]
+ else:
+ for key in new_keys:
+ msgs[key] = ref.msgs[key]
+
+ # Add back all "old" and already commented messages as commented ones, if required
+ # (and translation was not void!).
+ if keep_old_commented:
+ for key in removed_keys:
+ msgs[key] = self.msgs[key]
+ msgs[key].is_commented = True
+ msgs[key].sources = []
+
+ # Special 'meta' message, change project ID version and pot creation date...
+ key = self.settings.PO_HEADER_KEY
+ rep = []
+ markers = ("Project-Id-Version:", "POT-Creation-Date:")
+ for mrk in markers:
+ for rl in ref.msgs[key].msgstr_lines:
+ if rl.startswith(mrk):
+ for idx, ml in enumerate(msgs[key].msgstr_lines):
+ if ml.startswith(mrk):
+ rep.append((idx, rl))
+ for idx, txt in rep:
+ msgs[key].msgstr_lines[idx] = txt
+
+ # And finalize the update!
+ self.msgs = msgs
+
+ def update_info(self):
+ self.trans_msgs.clear()
+ self.fuzzy_msgs.clear()
+ self.comm_msgs.clear()
+ self.ttip_msgs.clear()
+ self.contexts.clear()
+ self.nbr_signs = 0
+ self.nbr_trans_signs = 0
+ for key, msg in self.msgs.items():
+ if key == self.settings.PO_HEADER_KEY:
+ continue
+ if msg.is_commented:
+ self.comm_msgs.add(key)
+ else:
+ if msg.msgstr:
+ self.trans_msgs.add(key)
+ if msg.is_fuzzy:
+ self.fuzzy_msgs.add(key)
+ if msg.is_tooltip:
+ self.ttip_msgs.add(key)
+ self.contexts.add(key[0])
+ self.nbr_signs += len(msg.msgid)
+ self.nbr_trans_signs += len(msg.msgstr)
+ self.nbr_msgs = len(self.msgs)
+ self.nbr_trans_msgs = len(self.trans_msgs)
+ self.nbr_ttips = len(self.ttip_msgs)
+ self.nbr_trans_ttips = len(self.ttip_msgs & self.trans_msgs)
+ self.nbr_comm_msgs = len(self.comm_msgs)
+
+ def print_stats(self, prefix="", output=print):
+ """
+ Print out some stats about an I18nMessages object.
+ """
+ lvl = 0.0
+ lvl_ttips = 0.0
+ lvl_comm = 0.0
+ lvl_trans_ttips = 0.0
+ lvl_ttips_in_trans = 0.0
+ if self.nbr_msgs > 0:
+ lvl = float(self.nbr_trans_msgs) / float(self.nbr_msgs)
+ lvl_ttips = float(self.nbr_ttips) / float(self.nbr_msgs)
+ lvl_comm = float(self.nbr_comm_msgs) / float(self.nbr_msgs + self.nbr_comm_msgs)
+ if self.nbr_ttips > 0:
+ lvl_trans_ttips = float(self.nbr_trans_ttips) / float(self.nbr_ttips)
+ if self.nbr_trans_msgs > 0:
+ lvl_ttips_in_trans = float(self.nbr_trans_ttips) / float(self.nbr_trans_msgs)
+
+ lines = ("",
+ "{:>6.1%} done! ({} translated messages over {}).\n"
+ "".format(lvl, self.nbr_trans_msgs, self.nbr_msgs),
+ "{:>6.1%} of messages are tooltips ({} over {}).\n"
+ "".format(lvl_ttips, self.nbr_ttips, self.nbr_msgs),
+ "{:>6.1%} of tooltips are translated ({} over {}).\n"
+ "".format(lvl_trans_ttips, self.nbr_trans_ttips, self.nbr_ttips),
+ "{:>6.1%} of translated messages are tooltips ({} over {}).\n"
+ "".format(lvl_ttips_in_trans, self.nbr_trans_ttips, self.nbr_trans_msgs),
+ "{:>6.1%} of messages are commented ({} over {}).\n"
+ "".format(lvl_comm, self.nbr_comm_msgs, self.nbr_comm_msgs + self.nbr_msgs),
+ "This translation is currently made of {} signs.\n".format(self.nbr_trans_signs))
+ output(prefix.join(lines))
+
+ def invalidate_reverse_cache(self, rebuild_now=False):
+ """
+ Invalidate the reverse cache used by find_best_messages_matches.
+ """
+ self._reverse_cache = None
+ if rebuild_now:
+ src_to_msg, ctxt_to_msg, msgid_to_msg, msgstr_to_msg = {}, {}, {}, {}
+ for key, msg in self.msgs.items():
+ if msg.is_commented:
+ continue
+ ctxt, msgid = key
+ ctxt_to_msg.setdefault(ctxt, set()).add(key)
+ msgid_to_msg.setdefault(msgid, set()).add(key)
+ msgstr_to_msg.setdefault(msg.msgstr, set()).add(key)
+ for src in msg.sources:
+ src_to_msg.setdefault(src, set()).add(key)
+ self._reverse_cache = (src_to_msg, ctxt_to_msg, msgid_to_msg, msgstr_to_msg)
+
+ def find_best_messages_matches(self, msgs, msgmap, rna_ctxt, rna_struct_name, rna_prop_name, rna_enum_name):
+ """
+ Try to find the best I18nMessages (i.e. context/msgid pairs) for the given UI messages:
+ msgs: an object containing properties listed in msgmap's values.
+ msgmap: a dict of various messages to use for search:
+ {"but_label": subdict, "rna_label": subdict, "enum_label": subdict,
+ "but_tip": subdict, "rna_tip": subdict, "enum_tip": subdict}
+ each subdict being like that:
+ {"msgstr": id, "msgid": id, "msg_flags": id, "key": set()}
+ where msgstr and msgid are identifiers of string props in msgs (resp. translated and org message),
+ msg_flags is not used here, and key is a set of matching (msgctxt, msgid) keys for the item.
+ The other parameters are about the RNA element from which the strings come from, if it could be determined:
+ rna_ctxt: the labels' i18n context.
+ rna_struct_name, rna_prop_name, rna_enum_name: should be self-explanatory!
+ """
+ # Build helper mappings.
+ # Note it's user responsibility to know when to invalidate (and hence force rebuild) this cache!
+ if self._reverse_cache is None:
+ self.invalidate_reverse_cache(True)
+ src_to_msg, ctxt_to_msg, msgid_to_msg, msgstr_to_msg = self._reverse_cache
+
+ # print(len(src_to_msg), len(ctxt_to_msg), len(msgid_to_msg), len(msgstr_to_msg))
+
+ # Build RNA key.
+ src, src_rna, src_enum = bpy.utils.make_rna_paths(rna_struct_name, rna_prop_name, rna_enum_name)
+ print("src: ", src_rna, src_enum)
+
+ # Labels.
+ elbl = getattr(msgs, msgmap["enum_label"]["msgstr"])
+ if elbl:
+ # Enum items' labels have no i18n context...
+ k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
+ if elbl in msgid_to_msg:
+ k &= msgid_to_msg[elbl]
+ elif elbl in msgstr_to_msg:
+ k &= msgstr_to_msg[elbl]
+ else:
+ k = set()
+ # We assume if we already have only one key, it's the good one!
+ if len(k) > 1 and src_enum in src_to_msg:
+ k &= src_to_msg[src_enum]
+ msgmap["enum_label"]["key"] = k
+ rlbl = getattr(msgs, msgmap["rna_label"]["msgstr"])
+ #print("rna label: " + rlbl, rlbl in msgid_to_msg, rlbl in msgstr_to_msg)
+ if rlbl:
+ k = ctxt_to_msg[rna_ctxt].copy()
+ if k and rlbl in msgid_to_msg:
+ k &= msgid_to_msg[rlbl]
+ elif k and rlbl in msgstr_to_msg:
+ k &= msgstr_to_msg[rlbl]
+ else:
+ k = set()
+ # We assume if we already have only one key, it's the good one!
+ if len(k) > 1 and src_rna in src_to_msg:
+ k &= src_to_msg[src_rna]
+ msgmap["rna_label"]["key"] = k
+ blbl = getattr(msgs, msgmap["but_label"]["msgstr"])
+ blbls = [blbl]
+ if blbl.endswith(self.settings.NUM_BUTTON_SUFFIX):
+ # Num buttons report their label with a trailing ': '...
+ blbls.append(blbl[:-len(self.settings.NUM_BUTTON_SUFFIX)])
+ print("button label: " + blbl)
+ if blbl and elbl not in blbls and (rlbl not in blbls or rna_ctxt != self.settings.DEFAULT_CONTEXT):
+ # Always Default context for button label :/
+ k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
+ found = False
+ for bl in blbls:
+ if bl in msgid_to_msg:
+ k &= msgid_to_msg[bl]
+ found = True
+ break
+ elif bl in msgstr_to_msg:
+ k &= msgstr_to_msg[bl]
+ found = True
+ break
+ if not found:
+ k = set()
+ # XXX No need to check against RNA path here, if blabel is different
+ # from rlabel, should not match anyway!
+ msgmap["but_label"]["key"] = k
+
+ # Tips (they never have a specific context).
+ etip = getattr(msgs, msgmap["enum_tip"]["msgstr"])
+ #print("enum tip: " + etip)
+ if etip:
+ k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
+ if etip in msgid_to_msg:
+ k &= msgid_to_msg[etip]
+ elif etip in msgstr_to_msg:
+ k &= msgstr_to_msg[etip]
+ else:
+ k = set()
+ # We assume if we already have only one key, it's the good one!
+ if len(k) > 1 and src_enum in src_to_msg:
+ k &= src_to_msg[src_enum]
+ msgmap["enum_tip"]["key"] = k
+ rtip = getattr(msgs, msgmap["rna_tip"]["msgstr"])
+ #print("rna tip: " + rtip)
+ if rtip:
+ k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
+ if k and rtip in msgid_to_msg:
+ k &= msgid_to_msg[rtip]
+ elif k and rtip in msgstr_to_msg:
+ k &= msgstr_to_msg[rtip]
+ else:
+ k = set()
+ # We assume if we already have only one key, it's the good one!
+ if len(k) > 1 and src_rna in src_to_msg:
+ k &= src_to_msg[src_rna]
+ msgmap["rna_tip"]["key"] = k
+ #print(k)
+ btip = getattr(msgs, msgmap["but_tip"]["msgstr"])
+ #print("button tip: " + btip)
+ if btip and btip not in {rtip, etip}:
+ k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
+ if btip in msgid_to_msg:
+ k &= msgid_to_msg[btip]
+ elif btip in msgstr_to_msg:
+ k &= msgstr_to_msg[btip]
+ else:
+ k = set()
+ # XXX No need to check against RNA path here, if btip is different from rtip, should not match anyway!
+ msgmap["but_tip"]["key"] = k
+
+ def parse(self, kind, key, src):
+ del self.parsing_errors[:]
+ self.parsers[kind](self, src, key)
+ if self.parsing_errors:
+ print("WARNING! Errors while parsing {}:".format(key))
+ for line, error in self.parsing_errors:
+ print(" Around line {}: {}".format(line, error))
+ print("The parser solved them as well as it could...")
+ self.update_info()
+
+ def parse_messages_from_po(self, src, key=None):
+ """
+ Parse a po file.
+ Note: This function will silently "arrange" mis-formated entries, thus using afterward write_messages() should
+ always produce a po-valid file, though not correct!
+ """
+ reading_msgid = False
+ reading_msgstr = False
+ reading_msgctxt = False
+ reading_comment = False
+ is_commented = False
+ is_fuzzy = False
+ msgctxt_lines = []
msgid_lines = []
msgstr_lines = []
- msgctxt_lines = []
comment_lines = []
- def finalize_message():
- nonlocal reading_msgid, reading_msgstr, reading_msgctxt, \
- reading_comment, is_fuzzy, is_translated, is_commented, \
- msgid_lines, msgstr_lines, msgctxt_lines, comment_lines, \
- messages, translated_messages, fuzzy_messages, \
- commented_messages, \
- tot_messages, tot_tooltips, trans_messages, trans_tooltips, \
- comm_messages, nbr_signs, nbr_trans_signs, contexts
-
- msgid = "".join(msgid_lines)
- msgctxt = "".join(msgctxt_lines)
- msgkey = (msgctxt, msgid)
- is_ttip = is_tooltip(msgid)
-
- # Never allow overriding existing msgid/msgctxt pairs!
- if msgkey in messages:
- clean_vars()
- return
+ default_context = self.settings.DEFAULT_CONTEXT
- nbr_signs += len(msgid)
- if is_commented:
- commented_messages.add(msgkey)
- elif is_fuzzy:
- fuzzy_messages.add(msgkey)
- elif is_translated:
- translated_messages.add(msgkey)
- nbr_trans_signs += len("".join(msgstr_lines))
- messages[msgkey] = {"msgid_lines" : msgid_lines,
- "msgstr_lines" : msgstr_lines,
- "comment_lines": comment_lines,
- "msgctxt_lines": msgctxt_lines}
-
- if is_commented:
- comm_messages += 1
- else:
- tot_messages += 1
- if is_ttip:
- tot_tooltips += 1
- if not is_fuzzy and is_translated:
- trans_messages += 1
- if is_ttip:
- trans_tooltips += 1
- if msgctxt not in contexts:
- contexts.add(msgctxt)
-
- clean_vars()
-
- with open(fname, 'r', encoding="utf-8") as f:
- for line_nr, line in enumerate(f):
- line = stripeol(line)
+ # Helper function
+ def finalize_message(self, line_nr):
+ nonlocal reading_msgid, reading_msgstr, reading_msgctxt, reading_comment
+ nonlocal is_commented, is_fuzzy, msgid_lines, msgstr_lines, msgctxt_lines, comment_lines
+
+ msgid = I18nMessage.do_unescape("".join(msgid_lines))
+ msgctxt = I18nMessage.do_unescape("".join(msgctxt_lines))
+ msgkey = (msgctxt or default_context, msgid)
+
+ # Never allow overriding existing msgid/msgctxt pairs!
+ if msgkey in self.msgs:
+ self.parsing_errors.append((line_nr, "{} context/msgid is already in current messages!".format(msgkey)))
+ return
+
+ self.msgs[msgkey] = I18nMessage(msgctxt_lines, msgid_lines, msgstr_lines, comment_lines,
+ is_commented, is_fuzzy, settings=self.settings)
+
+ # Let's clean up and get ready for next message!
+ reading_msgid = reading_msgstr = reading_msgctxt = reading_comment = False
+ is_commented = is_fuzzy = False
+ msgctxt_lines = []
+ msgid_lines = []
+ msgstr_lines = []
+ comment_lines = []
+
+ # try to use src as file name...
+ if os.path.isfile(src):
+ if os.stat(src).st_size > self.settings.PARSER_MAX_FILE_SIZE:
+ # Security, else we could read arbitrary huge files!
+ print("WARNING: skipping file {}, too huge!".format(src))
+ return
+ if not key:
+ key = src
+ with open(src, 'r', encoding="utf-8") as f:
+ src = f.read()
+
+ _msgctxt = self.settings.PO_MSGCTXT
+ _comm_msgctxt = self.settings.PO_COMMENT_PREFIX_MSG + _msgctxt
+ _len_msgctxt = len(_msgctxt + '"')
+ _len_comm_msgctxt = len(_comm_msgctxt + '"')
+ _msgid = self.settings.PO_MSGID
+ _comm_msgid = self.settings.PO_COMMENT_PREFIX_MSG + _msgid
+ _len_msgid = len(_msgid + '"')
+ _len_comm_msgid = len(_comm_msgid + '"')
+ _msgstr = self.settings.PO_MSGSTR
+ _comm_msgstr = self.settings.PO_COMMENT_PREFIX_MSG + _msgstr
+ _len_msgstr = len(_msgstr + '"')
+ _len_comm_msgstr = len(_comm_msgstr + '"')
+ _comm_str = self.settings.PO_COMMENT_PREFIX_MSG
+ _comm_fuzzy = self.settings.PO_COMMENT_FUZZY
+ _len_comm_str = len(_comm_str + '"')
+
+ # Main loop over all lines in src...
+ for line_nr, line in enumerate(src.splitlines()):
if line == "":
- finalize_message()
+ if reading_msgstr:
+ finalize_message(self, line_nr)
+ continue
- elif line.startswith("msgctxt") or \
- line.startswith("".join((COMMENT_PREFIX, "msgctxt"))):
+ elif line.startswith(_msgctxt) or line.startswith(_comm_msgctxt):
reading_comment = False
reading_ctxt = True
- if line.startswith(COMMENT_PREFIX):
+ if line.startswith(_comm_str):
is_commented = True
- line = line[9 + len(COMMENT_PREFIX):-1]
+ line = line[_len_comm_msgctxt:-1]
else:
- line = line[9:-1]
+ line = line[_len_msgctxt:-1]
msgctxt_lines.append(line)
- elif line.startswith("msgid") or \
- line.startswith("".join((COMMENT_PREFIX, "msgid"))):
+ elif line.startswith(_msgid) or line.startswith(_comm_msgid):
reading_comment = False
reading_msgid = True
- if line.startswith(COMMENT_PREFIX):
+ if line.startswith(_comm_str):
+ if not is_commented and reading_ctxt:
+ self.parsing_errors.append((line_nr, "commented msgid following regular msgctxt"))
is_commented = True
- line = line[7 + len(COMMENT_PREFIX):-1]
+ line = line[_len_comm_msgid:-1]
else:
- line = line[7:-1]
+ line = line[_len_msgid:-1]
+ reading_ctxt = False
msgid_lines.append(line)
- elif line.startswith("msgstr") or \
- line.startswith("".join((COMMENT_PREFIX, "msgstr"))):
+ elif line.startswith(_msgstr) or line.startswith(_comm_msgstr):
if not reading_msgid:
- is_broken = True
+ self.parsing_errors.append((line_nr, "msgstr without a prior msgid"))
else:
reading_msgid = False
reading_msgstr = True
- if line.startswith(COMMENT_PREFIX):
- line = line[8 + len(COMMENT_PREFIX):-1]
+ if line.startswith(_comm_str):
+ line = line[_len_comm_msgstr:-1]
if not is_commented:
- is_broken = True
+ self.parsing_errors.append((line_nr, "commented msgstr following regular msgid"))
else:
- line = line[8:-1]
+ line = line[_len_msgstr:-1]
if is_commented:
- is_broken = True
+ self.parsing_errors.append((line_nr, "regular msgstr following commented msgid"))
msgstr_lines.append(line)
- if line:
- is_translated = True
- elif line.startswith("#"):
- if reading_msgid:
- if is_commented:
- msgid_lines.append(line[1 + len(COMMENT_PREFIX):-1])
- else:
- msgid_lines.append(line)
- is_broken = True
- elif reading_msgstr:
- if is_commented:
- msgstr_lines.append(line[1 + len(COMMENT_PREFIX):-1])
- else:
- msgstr_lines.append(line)
- is_broken = True
+ elif line.startswith(_comm_str[0]):
+ if line.startswith(_comm_str):
+ if reading_msgctxt:
+ if is_commented:
+ msgctxt_lines.append(line[_len_comm_str:-1])
+ else:
+ msgctxt_lines.append(line)
+ self.parsing_errors.append((line_nr, "commented string while reading regular msgctxt"))
+ elif reading_msgid:
+ if is_commented:
+ msgid_lines.append(line[_len_comm_str:-1])
+ else:
+ msgid_lines.append(line)
+ self.parsing_errors.append((line_nr, "commented string while reading regular msgid"))
+ elif reading_msgstr:
+ if is_commented:
+ msgstr_lines.append(line[_len_comm_str:-1])
+ else:
+ msgstr_lines.append(line)
+ self.parsing_errors.append((line_nr, "commented string while reading regular msgstr"))
else:
- if line.startswith("#, fuzzy"):
+ if reading_msgctxt or reading_msgid or reading_msgstr:
+ self.parsing_errors.append((line_nr,
+ "commented string within msgctxt, msgid or msgstr scope, ignored"))
+ elif line.startswith(_comm_fuzzy):
is_fuzzy = True
else:
comment_lines.append(line)
reading_comment = True
else:
- if reading_msgid:
+ if reading_msgctxt:
+ msgctxt_lines.append(line[1:-1])
+ elif reading_msgid:
msgid_lines.append(line[1:-1])
elif reading_msgstr:
line = line[1:-1]
msgstr_lines.append(line)
- if not is_translated and line:
- is_translated = True
else:
- is_broken = True
+ self.parsing_errors.append((line_nr, "regular string outside msgctxt, msgid or msgstr scope"))
+ #self.parsing_errors += (str(comment_lines), str(msgctxt_lines), str(msgid_lines), str(msgstr_lines))
# If no final empty line, last message is not finalized!
if reading_msgstr:
- finalize_message()
-
- return (messages,
- {"trans_msg": translated_messages,
- "fuzzy_msg": fuzzy_messages,
- "comm_msg" : commented_messages,
- "is_broken": is_broken},
- {"tot_msg" : tot_messages,
- "trans_msg" : trans_messages,
- "tot_ttips" : tot_tooltips,
- "trans_ttips" : trans_tooltips,
- "comm_msg" : comm_messages,
- "nbr_signs" : nbr_signs,
- "nbr_trans_signs": nbr_trans_signs,
- "contexts" : contexts})
-
-
-def write_messages(fname, messages, commented, fuzzy):
- "Write in fname file the content of messages (similar to parse_messages " \
- "returned values). commented and fuzzy are two sets containing msgid. " \
- "Returns the number of written messages."
- num = 0
- with open(fname, 'w', encoding="utf-8") as f:
- for msgkey, val in messages.items():
- msgctxt, msgid = msgkey
- f.write("\n".join(val["comment_lines"]))
- # Only mark as fuzzy if msgstr is not empty!
- if msgkey in fuzzy and "".join(val["msgstr_lines"]):
- f.write("\n#, fuzzy")
- if msgkey in commented:
- if msgctxt:
- f.write("\n{}msgctxt \"".format(COMMENT_PREFIX))
- f.write("\"\n{}\"".format(COMMENT_PREFIX).join(
- val["msgctxt_lines"]))
- f.write("\"")
- f.write("\n{}msgid \"".format(COMMENT_PREFIX))
- f.write("\"\n{}\"".format(COMMENT_PREFIX).join(
- val["msgid_lines"]))
- f.write("\"\n{}msgstr \"".format(COMMENT_PREFIX))
- f.write("\"\n{}\"".format(COMMENT_PREFIX).join(
- val["msgstr_lines"]))
- f.write("\"\n\n")
- else:
- if msgctxt:
- f.write("\nmsgctxt \"")
- f.write("\"\n\"".join(val["msgctxt_lines"]))
- f.write("\"")
- f.write("\nmsgid \"")
- f.write("\"\n\"".join(val["msgid_lines"]))
- f.write("\"\nmsgstr \"")
- f.write("\"\n\"".join(val["msgstr_lines"]))
- f.write("\"\n\n")
- num += 1
- return num
-
-
-def gen_empty_messages(blender_rev, time_str, year_str):
- """Generate an empty messages & state data (only header if present!)."""
- header_key = ("", "")
-
- messages = new_messages()
- messages[header_key] = {
- "msgid_lines": [""],
- "msgctxt_lines": [],
- "msgstr_lines": [
- "Project-Id-Version: Blender r{}\\n"
- "".format(blender_rev),
- "Report-Msgid-Bugs-To: \\n",
- "POT-Creation-Date: {}\\n"
- "".format(time_str),
- "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n",
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n",
- "Language-Team: LANGUAGE <LL@li.org>\\n",
- "Language: \\n",
- "MIME-Version: 1.0\\n",
- "Content-Type: text/plain; charset=UTF-8\\n",
- "Content-Transfer-Encoding: 8bit\\n"
- ],
- "comment_lines": [
- "# Blender's translation file (po format).",
- "# Copyright (C) {} The Blender Foundation."
- "".format(year_str),
- "# This file is distributed under the same "
- "# license as the Blender package.",
- "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.",
- "#",
- ],
- }
+ finalize_message(self, line_nr)
+ self.unescape()
+
+ def write(self, kind, dest):
+ self.writers[kind](self, dest)
- states = {"trans_msg": set(),
- "fuzzy_msg": {header_key},
- "comm_msg": set(),
- "is_broken": False}
+ def write_messages_to_po(self, fname):
+ """
+ Write messages in fname po file.
+ """
+ default_context = self.settings.DEFAULT_CONTEXT
- return messages, states
+ def _write(self, f):
+ _msgctxt = self.settings.PO_MSGCTXT
+ _msgid = self.settings.PO_MSGID
+ _msgstr = self.settings.PO_MSGSTR
+ _comm = self.settings.PO_COMMENT_PREFIX_MSG
+ self.escape()
+
+ for num, msg in enumerate(self.msgs.values()):
+ f.write("\n".join(msg.comment_lines))
+ # Only mark as fuzzy if msgstr is not empty!
+ if msg.is_fuzzy and msg.msgstr:
+ f.write("\n" + self.settings.PO_COMMENT_FUZZY)
+ _p = _comm if msg.is_commented else ""
+ chunks = []
+ if msg.msgctxt and msg.msgctxt != default_context:
+ if len(msg.msgctxt_lines) > 1:
+ chunks += [
+ "\n" + _p + _msgctxt + "\"\"\n" + _p + "\"",
+ ("\"\n" + _p + "\"").join(msg.msgctxt_lines),
+ "\"",
+ ]
+ else:
+ chunks += ["\n" + _p + _msgctxt + "\"" + msg.msgctxt + "\""]
+ if len(msg.msgid_lines) > 1:
+ chunks += [
+ "\n" + _p + _msgid + "\"\"\n" + _p + "\"",
+ ("\"\n" + _p + "\"").join(msg.msgid_lines),
+ "\"",
+ ]
+ else:
+ chunks += ["\n" + _p + _msgid + "\"" + msg.msgid + "\""]
+ if len(msg.msgstr_lines) > 1:
+ chunks += [
+ "\n" + _p + _msgstr + "\"\"\n" + _p + "\"",
+ ("\"\n" + _p + "\"").join(msg.msgstr_lines),
+ "\"",
+ ]
+ else:
+ chunks += ["\n" + _p + _msgstr + "\"" + msg.msgstr + "\""]
+ chunks += ["\n\n"]
+ f.write("".join(chunks))
+
+ self.unescape()
+
+ self.normalize(max_len=0) # No wrapping for now...
+ if isinstance(fname, str):
+ with open(fname, 'w', encoding="utf-8") as f:
+ _write(self, f)
+ # Else assume fname is already a file(like) object!
+ else:
+ _write(self, fname)
+
+ def write_messages_to_mo(self, fname):
+ """
+ Write messages in fname mo file.
+ """
+ # XXX Temp solution, until I can make own mo generator working...
+ import subprocess
+ with tempfile.NamedTemporaryFile(mode='w+', encoding="utf-8") as tmp_po_f:
+ self.write_messages_to_po(tmp_po_f)
+ cmd = (self.settings.GETTEXT_MSGFMT_EXECUTABLE,
+ "--statistics", # show stats
+ tmp_po_f.name,
+ "-o",
+ fname,
+ )
+ print("Running ", " ".join(cmd))
+ ret = subprocess.call(cmd)
+ print("Finished.")
+ return
+ # XXX Code below is currently broken (generates corrupted mo files it seems :( )!
+ # Using http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html notation.
+ # Not generating hash table!
+ # Only translated, unfuzzy messages are taken into account!
+ default_context = self.settings.DEFAULT_CONTEXT
+ msgs = tuple(v for v in self.msgs.values() if not (v.is_fuzzy or v.is_commented) and v.msgstr and v.msgid)
+ msgs = sorted(msgs[:2],
+ key=lambda e: (e.msgctxt + e.msgid) if (e.msgctxt and e.msgctxt != default_context) else e.msgid)
+ magic_nbr = 0x950412de
+ format_rev = 0
+ N = len(msgs)
+ O = 32
+ T = O + N * 8
+ S = 0
+ H = T + N * 8
+ # Prepare our data! we need key (optional context and msgid), translation, and offset and length of both.
+ # Offset are relative to start of their own list.
+ EOT = b"0x04" # Used to concatenate context and msgid
+ _msgid_offset = 0
+ _msgstr_offset = 0
+ def _gen(v):
+ nonlocal _msgid_offset, _msgstr_offset
+ msgid = v.msgid.encode("utf-8")
+ msgstr = v.msgstr.encode("utf-8")
+ if v.msgctxt and v.msgctxt != default_context:
+ msgctxt = v.msgctxt.encode("utf-8")
+ msgid = msgctxt + EOT + msgid
+ # Don't forget the final NULL char!
+ _msgid_len = len(msgid) + 1
+ _msgstr_len = len(msgstr) + 1
+ ret = ((msgid, _msgid_len, _msgid_offset), (msgstr, _msgstr_len, _msgstr_offset))
+ _msgid_offset += _msgid_len
+ _msgstr_offset += _msgstr_len
+ return ret
+ msgs = tuple(_gen(v) for v in msgs)
+ msgid_start = H
+ msgstr_start = msgid_start + _msgid_offset
+ print(N, msgstr_start + _msgstr_offset)
+ print(msgs)
+
+ with open(fname, 'wb') as f:
+ # Header...
+ f.write(struct.pack("=8I", magic_nbr, format_rev, N, O, T, S, H, 0))
+ # Msgid's length and offset.
+ f.write(b"".join(struct.pack("=2I", length, msgid_start + offset) for (_1, length, offset), _2 in msgs))
+ # Msgstr's length and offset.
+ f.write(b"".join(struct.pack("=2I", length, msgstr_start + offset) for _1, (_2, length, offset) in msgs))
+ # No hash table!
+ # Msgid's.
+ f.write(b"\0".join(msgid for (msgid, _1, _2), _3 in msgs) + b"\0")
+ # Msgstr's.
+ f.write(b"\0".join(msgstr for _1, (msgstr, _2, _3) in msgs) + b"\0")
+
+ parsers = {
+ "PO": parse_messages_from_po,
+ }
-def print_stats(stats, glob_stats=None, prefix=""):
+ writers = {
+ "PO": write_messages_to_po,
+ "MO": write_messages_to_mo,
+ }
+
+
+class I18n:
"""
- Print out some stats about a po file.
- glob_stats is for making global stats over several po's.
+ Internal representation of a whole translation set.
"""
- tot_msgs = stats["tot_msg"]
- trans_msgs = stats["trans_msg"]
- tot_ttips = stats["tot_ttips"]
- trans_ttips = stats["trans_ttips"]
- comm_msgs = stats["comm_msg"]
- nbr_signs = stats["nbr_signs"]
- nbr_trans_signs = stats["nbr_trans_signs"]
- contexts = stats["contexts"]
- lvl = lvl_ttips = lvl_trans_ttips = lvl_ttips_in_trans = lvl_comm = 0.0
-
- if tot_msgs > 0:
- lvl = float(trans_msgs) / float(tot_msgs)
- lvl_ttips = float(tot_ttips) / float(tot_msgs)
- lvl_comm = float(comm_msgs) / float(tot_msgs+comm_msgs)
- if tot_ttips > 0:
- lvl_trans_ttips = float(trans_ttips) / float(tot_ttips)
- if trans_msgs > 0:
- lvl_ttips_in_trans = float(trans_ttips) / float(trans_msgs)
-
- if glob_stats:
- glob_stats["nbr"] += 1.0
- glob_stats["lvl"] += lvl
- glob_stats["lvl_ttips"] += lvl_ttips
- glob_stats["lvl_trans_ttips"] += lvl_trans_ttips
- glob_stats["lvl_ttips_in_trans"] += lvl_ttips_in_trans
- glob_stats["lvl_comm"] += lvl_comm
- glob_stats["nbr_trans_signs"] += nbr_trans_signs
- if glob_stats["nbr_signs"] == 0:
- glob_stats["nbr_signs"] = nbr_signs
- glob_stats["contexts"] |= contexts
-
- lines = ("",
- "{:>6.1%} done! ({} translated messages over {}).\n"
- "".format(lvl, trans_msgs, tot_msgs),
- "{:>6.1%} of messages are tooltips ({} over {}).\n"
- "".format(lvl_ttips, tot_ttips, tot_msgs),
- "{:>6.1%} of tooltips are translated ({} over {}).\n"
- "".format(lvl_trans_ttips, trans_ttips, tot_ttips),
- "{:>6.1%} of translated messages are tooltips ({} over {}).\n"
- "".format(lvl_ttips_in_trans, trans_ttips, trans_msgs),
- "{:>6.1%} of messages are commented ({} over {}).\n"
- "".format(lvl_comm, comm_msgs, comm_msgs + tot_msgs),
- "This translation is currently made of {} signs.\n"
- "".format(nbr_trans_signs))
- print(prefix.join(lines))
- return 0
+
+ @staticmethod
+ def _parser_check_file(path, maxsize=settings.PARSER_MAX_FILE_SIZE, _begin_marker=None, _end_marker=None):
+ if os.stat(path).st_size > maxsize:
+ # Security, else we could read arbitrary huge files!
+ print("WARNING: skipping file {}, too huge!".format(path))
+ return None, None, None
+ txt = ""
+ with open(path) as f:
+ txt = f.read()
+ _in = 0
+ _out = len(txt)
+ if _begin_marker:
+ _in = None
+ if _begin_marker in txt:
+ _in = txt.index(_begin_marker) + len(_begin_marker)
+ if _end_marker:
+ _out = None
+ if _end_marker in txt:
+ _out = txt.index(_end_marker)
+ if _in is not None and _out is not None:
+ return txt[:_in], txt[_in:_out], txt[_out:]
+ return txt, None, None
+
+ @staticmethod
+ def _dst(self, path, uid, kind):
+ if kind == 'PO':
+ if uid == self.settings.PARSER_TEMPLATE_ID:
+ if not path.endswith(".pot"):
+ return os.path.join(os.path.dirname(path), "blender.pot")
+ if not path.endswith(".po"):
+ return os.path.join(os.path.dirname(path), uid + ".po")
+ elif kind == 'PY':
+ if not path.endswith(".py"):
+ if self.src.get(self.settings.PARSER_PY_ID):
+ return self.src[self.settings.PARSER_PY_ID]
+ return os.path.join(os.path.dirname(path), "translations.py")
+ return path
+
+ def __init__(self, kind=None, src=None, langs=set(), settings=settings):
+ self.settings = settings
+ self.trans = {}
+ self.src = {} # Should have the same keys as self.trans (plus PARSER_PY_ID for py file)!
+ self.dst = self._dst # A callable that transforms src_path into dst_path!
+ if kind and src:
+ self.parse(kind, src, langs)
+ self.update_info()
+
+ def _py_file_get(self):
+ return self.src.get(self.settings.PARSER_PY_ID)
+ def _py_file_set(self, value):
+ self.src[self.settings.PARSER_PY_ID] = value
+ py_file = property(_py_file_get, _py_file_set)
+
+ def escape(self, do_all=False):
+ for trans in self.trans.values():
+ trans.escape(do_all)
+
+ def unescape(self, do_all=True):
+ for trans in self.trans.values():
+ trans.unescape(do_all)
+
+ def update_info(self):
+ self.nbr_trans = 0
+ self.lvl = 0.0
+ self.lvl_ttips = 0.0
+ self.lvl_trans_ttips = 0.0
+ self.lvl_ttips_in_trans = 0.0
+ self.lvl_comm = 0.0
+ self.nbr_signs = 0
+ self.nbr_trans_signs = 0
+ self.contexts = set()
+
+ if self.settings.PARSER_TEMPLATE_ID in self.trans:
+ self.nbr_trans = len(self.trans) - 1
+ self.nbr_signs = self.trans[self.settings.PARSER_TEMPLATE_ID].nbr_signs
+ else:
+ self.nbr_trans = len(self.trans)
+ for msgs in self.trans.values():
+ msgs.update_info()
+ if msgs.nbr_msgs > 0:
+ self.lvl += float(msgs.nbr_trans_msgs) / float(msgs.nbr_msgs)
+ self.lvl_ttips += float(msgs.nbr_ttips) / float(msgs.nbr_msgs)
+ self.lvl_comm += float(msgs.nbr_comm_msgs) / float(msgs.nbr_msgs + msgs.nbr_comm_msgs)
+ if msgs.nbr_ttips > 0:
+ self.lvl_trans_ttips = float(msgs.nbr_trans_ttips) / float(msgs.nbr_ttips)
+ if msgs.nbr_trans_msgs > 0:
+ self.lvl_ttips_in_trans = float(msgs.nbr_trans_ttips) / float(msgs.nbr_trans_msgs)
+ if self.nbr_signs == 0:
+ self.nbr_signs = msgs.nbr_signs
+ self.nbr_trans_signs += msgs.nbr_trans_signs
+ self.contexts |= msgs.contexts
+
+ def print_stats(self, prefix="", print_msgs=True):
+ """
+ Print out some stats about an I18n object.
+ If print_msgs is True, it will also print all its translations' stats.
+ """
+ if print_msgs:
+ msgs_prefix = prefix + " "
+ for key, msgs in self.trans.items():
+ if key == self.settings.PARSER_TEMPLATE_ID:
+ continue
+ print(prefix + key + ":")
+ msgs.print_stats(prefix=msgs_prefix)
+ print(prefix)
+
+ nbr_contexts = len(self.contexts - {bpy.app.translations.contexts.default})
+ if nbr_contexts != 1:
+ if nbr_contexts == 0:
+ nbr_contexts = "No"
+ _ctx_txt = "s are"
+ else:
+ _ctx_txt = " is"
+ lines = (("",
+ "Average stats for all {} translations:\n".format(self.nbr_trans),
+ " {:>6.1%} done!\n".format(self.lvl / self.nbr_trans),
+ " {:>6.1%} of messages are tooltips.\n".format(self.lvl_ttips / self.nbr_trans),
+ " {:>6.1%} of tooltips are translated.\n".format(self.lvl_trans_ttips / self.nbr_trans),
+ " {:>6.1%} of translated messages are tooltips.\n".format(self.lvl_ttips_in_trans / self.nbr_trans),
+ " {:>6.1%} of messages are commented.\n".format(self.lvl_comm / self.nbr_trans),
+ " The org msgids are currently made of {} signs.\n".format(self.nbr_signs),
+ " All processed translations are currently made of {} signs.\n".format(self.nbr_trans_signs),
+ " {} specific context{} present:\n".format(self.nbr_contexts, _ctx_txt)) +
+ tuple(" " + c + "\n" for c in self.contexts - {bpy.app.translations.contexts.default}) +
+ ("\n",)
+ )
+ print(prefix.join(lines))
+
+ def parse(self, kind, src, langs=set()):
+ self.parsers[kind](self, src, langs)
+
+ def parse_from_po(self, src, langs=set()):
+ """
+ src must be a tuple (dir_of_pos, pot_file), where:
+ * dir_of_pos may either contains iso_CODE.po files, and/or iso_CODE/iso_CODE.po files.
+ * pot_file may be None (in which case there will be no ref messages).
+ if langs set is void, all languages found are loaded.
+ """
+ root_dir, pot_file = src
+ if pot_file and os.path.isfile(pot_file):
+ self.trans[self.settings.PARSER_TEMPLATE_ID] = I18nMessages(self.settings.PARSER_TEMPLATE_ID, 'PO',
+ pot_file, pot_file, settings=self.settings)
+ self.src_po[self.settings.PARSER_TEMPLATE_ID] = pot_file
+
+ for p in os.listdir(root_dir):
+ uid = po_file = None
+ if p.endswith(".po") and os.path.isfile(p):
+ uid = p[:-3]
+ if langs and uid not in langs:
+ continue
+ po_file = os.path.join(root_dir, p)
+ elif os.path.isdir(p):
+ uid = p
+ if langs and uid not in langs:
+ continue
+ po_file = os.path.join(root_dir, p, p + ".po")
+ if not os.path.isfile(po_file):
+ continue
+ else:
+ continue
+ if uid in self.trans:
+ printf("WARNING! {} id has been found more than once! only first one has been loaded!".format(uid))
+ continue
+ self.trans[uid] = I18nMessages(uid, 'PO', po_file, po_file, settings=self.settings)
+ self.src_po[uid] = po_file
+
+ def parse_from_py(self, src, langs=set()):
+ """
+ src must be a valid path, either a py file or a module directory (in which case all py files inside it
+ will be checked, first file macthing will win!).
+ if langs set is void, all languages found are loaded.
+ """
+ default_context = self.settings.DEFAULT_CONTEXT
+ txt = None
+ if os.path.isdir(src):
+ for root, dnames, fnames in os.walk(src):
+ for fname in fnames:
+ path = os.path.join(root, fname)
+ _1, txt, _2 = self._parser_check_file(path)
+ if txt is not None:
+ self.src[self.settings.PARSER_PY_ID] = path
+ break
+ if txt is not None:
+ break
+ elif src.endswith(".py") and os.path.isfile(src):
+ _1, txt, _2 = _check_file(src, self.settings.PARSER_PY_MARKER_BEGIN, self.settings.PARSER_PY_MARKER_END)
+ if txt is not None:
+ self.src[self.settings.PARSER_PY_ID] = src
+ if txt is None:
+ return
+ env = globals()
+ exec(txt, env)
+ if "translations_tuple" not in env:
+ return # No data...
+ msgs = env["translations_tuple"]
+ for key, (sources, gen_comments), *translations in msgs:
+ if self.settings.PARSER_TEMPLATE_ID not in self.trans:
+ self.trans[self.settings.PARSER_TEMPLATE_ID] = I18nMessages(self.settings.PARSER_TEMPLATE_ID,
+ settings=self.settings)
+ self.src[self.settings.PARSER_TEMPLATE_ID] = self.src[self.settings.PARSER_PY_ID]
+ if key in self.trans[self.settings.PARSER_TEMPLATE_ID].msgs:
+ print("ERROR! key {} is defined more than once! Skipping re-definitions!")
+ continue
+ custom_src = [c for c in sources if c.startswith("bpy.")]
+ src = [c for c in sources if not c.startswith("bpy.")]
+ common_comment_lines = [self.settings.PO_COMMENT_PREFIX_GENERATED + c for c in gen_comments] + \
+ [self.settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM + c for c in custom_src] + \
+ [self.settings.PO_COMMENT_PREFIX_SOURCE + c for c in src]
+ ctxt = [key[0]] if key[0] else [default_context]
+ self.trans[self.settings.PARSER_TEMPLATE_ID].msgs[key] = I18nMessage(ctxt, [key[1]], [""],
+ common_comment_lines, False, False,
+ settings=self.settings)
+ for uid, msgstr, (is_fuzzy, user_comments) in translations:
+ if uid not in self.trans:
+ self.trans[uid] = I18nMessages(uid, settings=self.settings)
+ self.src[uid] = self.src[self.settings.PARSER_PY_ID]
+ comment_lines = [self.settings.PO_COMMENT_PREFIX + c for c in user_comments] + common_comment_lines
+ self.trans[uid].msgs[key] = I18nMessage(ctxt, [key[1]], [msgstr], comment_lines, False, is_fuzzy,
+ settings=self.settings)
+ self.unescape()
+
+ def write(self, kind, langs=set()):
+ self.writers[kind](self, langs)
+
+ def write_to_po(self, langs=set()):
+ """
+ Write all translations into po files. By default, write in the same files (or dir) as the source, specify
+ a custom self.dst function to write somewhere else!
+ Note: If langs is set and you want to export the pot template as well, langs must contain PARSER_TEMPLATE_ID
+ ({} currently).
+ """.format(self.settings.PARSER_TEMPLATE_ID)
+ keys = self.trans.keys()
+ if langs:
+ keys &= langs
+ for uid in keys:
+ dst = self.dst(self, self.src.get(uid, ""), uid, 'PO')
+ self.trans[uid].write('PO', dst)
+
+ def write_to_py(self, langs=set()):
+ """
+ Write all translations as python code, either in a "translations.py" file under same dir as source(s), or in
+ specified file is self.py_file is set (default, as usual can be customized with self.dst callable!).
+ Note: If langs is set and you want to export the pot template as well, langs must contain PARSER_TEMPLATE_ID
+ ({} currently).
+ """.format(self.settings.PARSER_TEMPLATE_ID)
+ default_context = self.settings.DEFAULT_CONTEXT
+ def _gen_py(self, langs, tab=" "):
+ _lencomm = len(self.settings.PO_COMMENT_PREFIX)
+ _lengen = len(self.settings.PO_COMMENT_PREFIX_GENERATED)
+ _lensrc = len(self.settings.PO_COMMENT_PREFIX_SOURCE)
+ _lencsrc = len(self.settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM)
+ ret = [
+ "# NOTE: You can safely move around this auto-generated block (with the begin/end markers!), and "
+ "edit the translations by hand.",
+ "# Just carefully respect the format of the tuple!",
+ "",
+ "# Tuple of tuples "
+ "((msgctxt, msgid), (sources, gen_comments), (lang, translation, (is_fuzzy, comments)), ...)",
+ "translations_tuple = (",
+ ]
+ # First gather all keys (msgctxt, msgid) - theoretically, all translations should share the same, but...
+ keys = set()
+ for trans in self.trans.items:
+ keys |= trans.msgs.keys()
+ # Get the ref translation (ideally, PARSER_TEMPLATE_ID one, else the first one that pops up!
+ # Ref translation will be used to generate sources "comments"
+ ref = self.trans.get(self.settings.PARSER_TEMPLATE_ID) or self.trans[list(self.trans.keys())[0]]
+ # Get all languages (uids) and sort them (PARSER_TEMPLATE_ID excluded!)
+ translations = self.trans.keys() - {self.settings.PARSER_TEMPLATE_ID}
+ if langs:
+ translations &= langs
+ translations = [('"' + lng + '"', " " * len(lng) + 4, self.trans[lng]) for lng in sorted(translations)]
+ for key in keys:
+ if ref.msgs[key].is_commented:
+ continue
+ # Key (context + msgid).
+ msgctxt, msgid = key
+ if not msgctxt:
+ msgctxt = default_context
+ ret.append(tab + "(({}, \"{}\"),".format('"' + msgctxt + '"' if msgctxt else "None", msgid))
+ # Common comments (mostly sources!).
+ sources = []
+ gen_comments = []
+ for comment in ref.msgs[key].comment_lines:
+ if comment.startswith(self.settings.PO_COMMENT_PREFIX_SOURCE_CUSTOM):
+ sources.append(comment[_lencsrc:])
+ elif comment.startswith(self.settings.PO_COMMENT_PREFIX_SOURCE):
+ sources.append(comment[_lensrc:])
+ elif comment.startswith(self.settings.PO_COMMENT_PREFIX_GENERATED):
+ gen_comments.append(comment[_lengen:])
+ if not (sources or gen_comments):
+ ret.append(tab + " ((), ()),")
+ else:
+ if len(sources) > 1:
+ ret.append(tab + " ((\"" + sources[0] + "\",")
+ ret += [tab + " \"" + s + "\"," for s in sources[1:-1]]
+ ret.append(tab + " \"" + sources[-1] + "\"),")
+ else:
+ ret.append(tab + " ((" + ('"' + sources[0] + '",' if sources else "") + "),")
+ if len(gen_comments) > 1:
+ ret.append(tab + " (\"" + gen_comments[0] + "\",")
+ ret += [tab + " \"" + s + "\"," for s in gen_comments[1:-1]]
+ ret.append(tab + " \"" + gen_comments[-1] + "\")),")
+ else:
+ ret.append(tab + " (" + ('"' + gen_comments[0] + '",' if gen_comments else "") + ")),")
+ # All languages
+ for lngstr, lngsp, trans in translations:
+ if trans.msgs[key].is_commented:
+ continue
+ # Language code and translation.
+ ret.append(tab + " (" + lngstr + ", \"" + trans.msgs[key].msgstr + "\",")
+ # User comments and fuzzy.
+ comments = []
+ for comment in trans.msgs[key].comment_lines:
+ if comment.startswith(self.settings.PO_COMMENT_PREFIX):
+ comments.append(comment[_lencomm:])
+ ret.append(tab + lngsp + "(" + ("True" if trans.msgs[key].is_fuzzy else "False") + ",")
+ if len(comments) > 1:
+ ret.append(tab + lngsp + " (\"" + comments[0] + "\",")
+ ret += [tab + lngsp + " \"" + s + "\"," for s in comments[1:-1]]
+ ret.append(tab + lngsp + " \"" + comments[-1] + "\"))),")
+ else:
+ ret[-1] = ret[-1] + " " + ('"' + comments[0] + '",' if comments else "") + "))),"
+ ret.append(tab + "),")
+ ret += [
+ ")",
+ "",
+ "translations_dict = {}",
+ "for msg in translations_tuple:",
+ tab + "key = msg[0]",
+ tab + "for lang, trans, (is_fuzzy, comments) in msg[2:]:",
+ tab * 2 + "if trans and not is_fuzzy:",
+ tab * 3 + "translations_dict.setdefault(lang, {})[key] = trans",
+ "",
+ ]
+ return ret
+
+ self.escape(True)
+ dst = self.dst(self, self.src.get(self.settings.PARSER_PY_ID, ""), self.settings.PARSER_PY_ID, 'PY')
+ prev = txt = next = ""
+ if os.path.exists(dst):
+ if not os.path.isfile(dst):
+ print("WARNING: trying to write as python code into {}, which is not a file! Aborting.".format(dst))
+ return
+ prev, txt, next = self._parser_check_file(dst, self.settings.PARSER_MAX_FILE_SIZE,
+ self.settings.PARSER_PY_MARKER_BEGIN,
+ self.settings.PARSER_PY_MARKER_END)
+ if prev is None:
+ return
+ if txt is None:
+ print("WARNING: given python file {} has no auto-generated translations yet, will be added at "
+ "the end of the file, you can move that section later if needed...".format(dst))
+ txt = _gen_py(self, langs)
+ else:
+ printf("Creating python file {} containing translations.".format(dst))
+ txt = [
+ "# ***** 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 *****",
+ "",
+ self.settings.PARSER_PY_MARKER_BEGIN,
+ "",
+ ]
+ txt += _gen_py(self, langs)
+ txt += [
+ "",
+ self.settings.PARSER_PY_MARKER_END,
+ ]
+ with open(dst, 'w') as f:
+ f.write(prev + "\n".join(txt) + (next or ""))
+ self.unescape()
+
+ parsers = {
+ "PO": parse_from_po,
+ "PY": parse_from_py,
+ }
+
+ writers = {
+ "PO": write_to_po,
+ "PY": write_to_py,
+ }
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
index 34b7a9ea7b6..3a2f9bde2c7 100644
--- a/release/scripts/modules/bpy/__init__.py
+++ b/release/scripts/modules/bpy/__init__.py
@@ -58,6 +58,7 @@ def main():
# from bpy.types import Panel
sys.modules["bpy.app"] = app
sys.modules["bpy.app.handlers"] = app.handlers
+ sys.modules["bpy.app.translations"] = app.translations
sys.modules["bpy.types"] = types
#~ if "-d" in sys.argv: # Enable this to measure start up speed
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index d32b69b501c..6c91568cbc1 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -30,6 +30,9 @@ __all__ = (
"display_name",
"display_name_from_filepath",
"ensure_ext",
+ "extensions_image",
+ "extensions_movie",
+ "extensions_audio",
"is_subdir",
"module_names",
"relpath",
@@ -39,6 +42,11 @@ __all__ = (
import bpy as _bpy
import os as _os
+from _bpy_path import (extensions_audio,
+ extensions_movie,
+ extensions_image,
+ )
+
def abspath(path, start=None, library=None):
"""
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 4ad00eb267e..9c4117f0953 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -35,6 +35,7 @@ __all__ = (
"register_module",
"register_manual_map",
"unregister_manual_map",
+ "make_rna_paths",
"manual_map",
"resource_path",
"script_path_user",
@@ -57,6 +58,7 @@ import sys as _sys
import addon_utils as _addon_utils
+_user_preferences = _bpy.context.user_preferences
_script_module_dirs = "startup", "modules"
@@ -132,8 +134,6 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
"""
use_time = _bpy.app.debug_python
- prefs = _bpy.context.user_preferences
-
if use_time:
import time
t_main = time.time()
@@ -150,7 +150,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
# to reload. note that they will only actually reload of the
# modification time changes. This `won't` work for packages so...
# its not perfect.
- for module_name in [ext.module for ext in prefs.addons]:
+ for module_name in [ext.module for ext in _user_preferences.addons]:
_addon_utils.disable(module_name, default_set=False)
def register_module_call(mod):
@@ -218,24 +218,28 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
del _global_loaded_modules[:]
- for base_path in script_paths():
- for path_subdir in _script_module_dirs:
- path = _os.path.join(base_path, path_subdir)
- if _os.path.isdir(path):
- _sys_path_ensure(path)
+ from bpy_restrict_state import RestrictBlend
- # only add this to sys.modules, don't run
- if path_subdir == "modules":
- continue
+ with RestrictBlend():
+ for base_path in script_paths():
+ for path_subdir in _script_module_dirs:
+ path = _os.path.join(base_path, path_subdir)
+ if _os.path.isdir(path):
+ _sys_path_ensure(path)
- for mod in modules_from_path(path, loaded_modules):
- test_register(mod)
+ # only add this to sys.modules, don't run
+ if path_subdir == "modules":
+ continue
+
+ for mod in modules_from_path(path, loaded_modules):
+ test_register(mod)
# deal with addons separately
_addon_utils.reset_all(reload_scripts)
# run the active integration preset
- filepath = preset_find(prefs.inputs.active_keyconfig, "keyconfig")
+ filepath = preset_find(_user_preferences.inputs.active_keyconfig,
+ "keyconfig")
if filepath:
keyconfig_set(filepath)
@@ -264,7 +268,7 @@ def script_path_user():
def script_path_pref():
"""returns the user preference or None"""
- path = _bpy.context.user_preferences.filepaths.script_directory
+ path = _user_preferences.filepaths.script_directory
return _os.path.normpath(path) if path else None
@@ -637,3 +641,29 @@ def manual_map():
continue
yield prefix, url_manual_mapping
+
+
+# Build an RNA path from struct/property/enum names.
+def make_rna_paths(struct_name, prop_name, enum_name):
+ """
+ Create RNA "paths" from given names.
+
+ :arg struct_name: Name of a RNA struct (like e.g. "Scene").
+ :type struct_name: string
+ :arg prop_name: Name of a RNA struct's property.
+ :type prop_name: string
+ :arg enum_name: Name of a RNA enum identifier.
+ :type enum_name: string
+ :return: A triple of three "RNA paths" (most_complete_path, "struct.prop", "struct.prop:'enum'").
+ If no enum_name is given, the third element will always be void.
+ :rtype: tuple of strings
+ """
+ src = src_rna = src_enum = ""
+ if struct_name:
+ if prop_name:
+ src = src_rna = ".".join((struct_name, prop_name))
+ if enum_name:
+ src = src_enum = "{}:'{}'".format(src_rna, enum_name)
+ else:
+ src = src_rna = struct_name
+ return src, src_rna, src_enum
diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py
index b8d08628de4..20a9a412f26 100644
--- a/release/scripts/modules/bpy_extras/anim_utils.py
+++ b/release/scripts/modules/bpy_extras/anim_utils.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8-80 compliant>
+# <pep8 compliant>
__all__ = (
"bake_action",
@@ -52,7 +52,7 @@ def bake_action(frame_start,
:type do_pose: bool
:arg do_object: Bake objects.
:type do_object: bool
- :arg do_constraint_clear: Remove constraints.
+ :arg do_constraint_clear: Remove constraints (and do 'visual keying').
:type do_constraint_clear: bool
:arg do_clean: Remove redundant keyframes after baking.
:type do_clean: bool
@@ -65,61 +65,20 @@ def bake_action(frame_start,
"""
# -------------------------------------------------------------------------
- # Helper Functions
+ # Helper Functions and vars
- def pose_frame_info(obj):
- from mathutils import Matrix
+ def pose_frame_info(obj, do_visual_keying):
+ matrix = {}
+ for name, pbone in obj.pose.bones.items():
+ if do_visual_keying:
+ # Get the final transform of the bone in its own local space...
+ matrix[name] = obj.convert_space(pbone, pbone.matrix, 'POSE', 'LOCAL')
+ else:
+ matrix[name] = pbone.matrix_basis.copy()
+ return matrix
- info = {}
-
- pose = obj.pose
-
- pose_items = pose.bones.items()
-
- for name, pbone in pose_items:
- binfo = {}
- bone = pbone.bone
-
- binfo["parent"] = getattr(bone.parent, "name", None)
- binfo["bone"] = bone
- binfo["pbone"] = pbone
- binfo["matrix_local"] = bone.matrix_local.copy()
- try:
- binfo["matrix_local_inv"] = binfo["matrix_local"].inverted()
- except:
- binfo["matrix_local_inv"] = Matrix()
-
- binfo["matrix"] = bone.matrix.copy()
- binfo["matrix_pose"] = pbone.matrix.copy()
- try:
- binfo["matrix_pose_inv"] = binfo["matrix_pose"].inverted()
- except:
- binfo["matrix_pose_inv"] = Matrix()
-
- info[name] = binfo
-
- for name, pbone in pose_items:
- binfo = info[name]
- binfo_parent = binfo.get("parent", None)
- if binfo_parent:
- binfo_parent = info[binfo_parent]
-
- matrix = binfo["matrix_pose"]
- rest_matrix = binfo["matrix_local"]
-
- if binfo_parent:
- matrix = binfo_parent["matrix_pose_inv"] * matrix
- rest_matrix = binfo_parent["matrix_local_inv"] * rest_matrix
-
- binfo["matrix_key"] = rest_matrix.inverted() * matrix
-
- return info
-
- def obj_frame_info(obj):
- info = {}
- # parent = obj.parent
- info["matrix_key"] = obj.matrix_local.copy()
- return info
+ def obj_frame_info(obj, do_visual_keying):
+ return obj.matrix_local.copy() if do_visual_keying else obj.matrix_basis.copy()
# -------------------------------------------------------------------------
# Setup the Context
@@ -127,33 +86,30 @@ def bake_action(frame_start,
# TODO, pass data rather then grabbing from the context!
scene = bpy.context.scene
obj = bpy.context.object
- pose = obj.pose
frame_back = scene.frame_current
- if pose is None:
+ if obj.pose is None:
do_pose = False
- if do_pose is None and do_object is None:
+ if not (do_pose or do_object):
return None
pose_info = []
obj_info = []
+ options = {'INSERTKEY_NEEDED'}
+
frame_range = range(frame_start, frame_end + 1, frame_step)
# -------------------------------------------------------------------------
# Collect transformations
- # could speed this up by applying steps here too...
for f in frame_range:
scene.frame_set(f)
-
if do_pose:
- pose_info.append(pose_frame_info(obj))
+ pose_info.append(pose_frame_info(obj, do_constraint_clear))
if do_object:
- obj_info.append(obj_frame_info(obj))
-
- f += 1
+ obj_info.append(obj_frame_info(obj, do_constraint_clear))
# -------------------------------------------------------------------------
# Create action
@@ -164,57 +120,44 @@ def bake_action(frame_start,
action = bpy.data.actions.new("Action")
atd.action = action
- if do_pose:
- pose_items = pose.bones.items()
- else:
- pose_items = [] # skip
-
# -------------------------------------------------------------------------
# Apply transformations to action
# pose
- for name, pbone in (pose_items if do_pose else ()):
- if only_selected and not pbone.bone.select:
- continue
-
- if do_constraint_clear:
- while pbone.constraints:
- pbone.constraints.remove(pbone.constraints[0])
-
- # create compatible eulers
- euler_prev = None
-
- for f in frame_range:
- f_step = (f - frame_start) // frame_step
- matrix = pose_info[f_step][name]["matrix_key"]
-
- # pbone.location = matrix.to_translation()
- # pbone.rotation_quaternion = matrix.to_quaternion()
- pbone.matrix_basis = matrix
-
- pbone.keyframe_insert("location", -1, f, name)
-
- rotation_mode = pbone.rotation_mode
-
- if rotation_mode == 'QUATERNION':
- pbone.keyframe_insert("rotation_quaternion", -1, f, name)
- elif rotation_mode == 'AXIS_ANGLE':
- pbone.keyframe_insert("rotation_axis_angle", -1, f, name)
- else: # euler, XYZ, ZXY etc
-
- if euler_prev is not None:
- euler = pbone.rotation_euler.copy()
- euler.make_compatible(euler_prev)
- pbone.rotation_euler = euler
- euler_prev = euler
- del euler
-
- pbone.keyframe_insert("rotation_euler", -1, f, name)
-
- if euler_prev is None:
- euler_prev = pbone.rotation_euler.copy()
-
- pbone.keyframe_insert("scale", -1, f, name)
+ if do_pose:
+ for name, pbone in obj.pose.bones.items():
+ if only_selected and not pbone.bone.select:
+ continue
+
+ if do_constraint_clear:
+ while pbone.constraints:
+ pbone.constraints.remove(pbone.constraints[0])
+
+ # create compatible eulers
+ euler_prev = None
+
+ for (f, matrix) in zip(frame_range, pose_info):
+ pbone.matrix_basis = matrix[name].copy()
+
+ pbone.keyframe_insert("location", -1, f, name, options)
+
+ rotation_mode = pbone.rotation_mode
+ if rotation_mode == 'QUATERNION':
+ pbone.keyframe_insert("rotation_quaternion", -1, f, name, options)
+ elif rotation_mode == 'AXIS_ANGLE':
+ pbone.keyframe_insert("rotation_axis_angle", -1, f, name, options)
+ else: # euler, XYZ, ZXY etc
+ if euler_prev is not None:
+ euler = pbone.rotation_euler.copy()
+ euler.make_compatible(euler_prev)
+ pbone.rotation_euler = euler
+ euler_prev = euler
+ del euler
+ else:
+ euler_prev = pbone.rotation_euler.copy()
+ pbone.keyframe_insert("rotation_euler", -1, f, name, options)
+
+ pbone.keyframe_insert("scale", -1, f, name, options)
# object. TODO. multiple objects
if do_object:
@@ -225,18 +168,17 @@ def bake_action(frame_start,
# create compatible eulers
euler_prev = None
- for f in frame_range:
- matrix = obj_info[(f - frame_start) // frame_step]["matrix_key"]
- obj.matrix_local = matrix
+ for (f, matrix) in zip(frame_range, obj_info):
+ name = "Action Bake" # XXX: placeholder
+ obj.matrix_basis = matrix
- obj.keyframe_insert("location", -1, f)
+ obj.keyframe_insert("location", -1, f, name, options)
rotation_mode = obj.rotation_mode
-
if rotation_mode == 'QUATERNION':
- obj.keyframe_insert("rotation_quaternion", -1, f)
+ obj.keyframe_insert("rotation_quaternion", -1, f, name, options)
elif rotation_mode == 'AXIS_ANGLE':
- obj.keyframe_insert("rotation_axis_angle", -1, f)
+ obj.keyframe_insert("rotation_axis_angle", -1, f, name, options)
else: # euler, XYZ, ZXY etc
if euler_prev is not None:
euler = obj.rotation_euler.copy()
@@ -244,15 +186,11 @@ def bake_action(frame_start,
obj.rotation_euler = euler
euler_prev = euler
del euler
-
- obj.keyframe_insert("rotation_euler", -1, f)
-
- if euler_prev is None:
+ else:
euler_prev = obj.rotation_euler.copy()
+ obj.keyframe_insert("rotation_euler", -1, f, name, options)
- obj.keyframe_insert("scale", -1, f)
-
- scene.frame_set(frame_back)
+ obj.keyframe_insert("scale", -1, f, name, options)
# -------------------------------------------------------------------------
# Clean
@@ -271,4 +209,6 @@ def bake_action(frame_start,
else:
i += 1
+ scene.frame_set(frame_back)
+
return action
diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py
index 4457ecb43e6..dfb6c46ef87 100644
--- a/release/scripts/modules/bpy_extras/io_utils.py
+++ b/release/scripts/modules/bpy_extras/io_utils.py
@@ -79,20 +79,23 @@ class ExportHelper:
return {'RUNNING_MODAL'}
def check(self, context):
+ import os
change_ext = False
change_axis = _check_axis_conversion(self)
check_extension = self.check_extension
if check_extension is not None:
- filepath = bpy.path.ensure_ext(self.filepath,
- self.filename_ext
- if check_extension
- else "")
+ filepath = self.filepath
+ if os.path.basename(filepath):
+ filepath = bpy.path.ensure_ext(filepath,
+ self.filename_ext
+ if check_extension
+ else "")
- if filepath != self.filepath:
- self.filepath = filepath
- change_ext = True
+ if filepath != self.filepath:
+ self.filepath = filepath
+ change_ext = True
return (change_ext or change_axis)
@@ -338,7 +341,7 @@ path_reference_mode = EnumProperty(
('COPY', "Copy", "Copy the file to the destination path "
"(or subdirectory)"),
),
- default='AUTO'
+ default='AUTO',
)
@@ -433,10 +436,7 @@ def path_reference_copy(copy_set, report=print):
pass
else:
dir_to = os.path.dirname(file_dst)
-
- if not os.path.isdir(dir_to):
- os.makedirs(dir_to)
-
+ os.makedirs(dir_to, exist_ok=True)
shutil.copy(file_src, file_dst)
@@ -477,10 +477,10 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None, sep="."):
while name_new in name_dict_values:
count_str = "%03d" % count
name_new = "%.*s%s%s" % (name_max - (len(count_str) + 1),
- name_new_orig,
- sep,
- count_str,
- )
+ name_new_orig,
+ sep,
+ count_str,
+ )
count += 1
name_dict[key] = name_new
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index 0166f954dc9..f4fdfece947 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -152,10 +152,13 @@ def edge_face_count_dict(mesh):
faces using each edge.
:rtype: dict
"""
- face_edge_keys = [face.edge_keys for face in mesh.tessfaces]
+
face_edge_count = {}
- for face_keys in face_edge_keys:
- for key in face_keys:
+ loops = mesh.loops
+ edges = mesh.edges
+ for poly in mesh.polygons:
+ for i in poly.loop_indices:
+ key = edges[loops[i].edge_index].key
try:
face_edge_count[key] += 1
except:
@@ -247,7 +250,7 @@ def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()):
break
i = ed_adj.index(context_loop[-2])
- context_loop.append(ed_adj[not i])
+ context_loop.append(ed_adj[not i])
# Dont look at this again
del ed_adj[:]
@@ -530,12 +533,12 @@ def face_random_points(num_points, tessfaces):
tris.append((verts[fv[0]].co,
verts[fv[1]].co,
verts[fv[2]].co,
- ))
+ ))
if len(fv) == 4:
tris.append((verts[fv[0]].co,
verts[fv[3]].co,
verts[fv[2]].co,
- ))
+ ))
tri_faces.append(tris)
# For each face, generate the required number of random points
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 46731b807f7..ab5dc3e6aee 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -26,7 +26,6 @@ __all__ = (
import bpy
-import mathutils
from bpy.props import BoolProperty, FloatVectorProperty
@@ -80,7 +79,7 @@ def add_object_align_init(context, operator):
rotation = space_data.region_3d.view_matrix.to_3x3().inverted()
rotation.resize_4x4()
else:
- rotation = mathutils.Matrix()
+ rotation = Matrix()
# set the operator properties
if operator:
@@ -124,9 +123,10 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True):
base.layers[scene.active_layer] = True
else:
base.layers = [True if i == scene.active_layer
- else False for i in range(len(scene.layers))]
- if v3d:
- base.layers_from_view(context.space_data)
+ else False for i in range(len(scene.layers))]
+ else:
+ if v3d:
+ base.layers_from_view(context.space_data)
obj_new.matrix_world = add_object_align_init(context, operator)
diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py
index b2f366d5d1e..7a075e93e1a 100644
--- a/release/scripts/modules/bpy_extras/view3d_utils.py
+++ b/release/scripts/modules/bpy_extras/view3d_utils.py
@@ -50,7 +50,7 @@ def region_2d_to_vector_3d(region, rv3d, coord):
out = Vector(((2.0 * coord[0] / region.width) - 1.0,
(2.0 * coord[1] / region.height) - 1.0,
-0.5
- ))
+ ))
w = out.dot(persinv[3].xyz) + persinv[3][3]
@@ -89,7 +89,7 @@ def region_2d_to_origin_3d(region, rv3d, coord):
persinv = persmat.inverted()
origin_start = ((persinv.col[0].xyz * dx) +
(persinv.col[1].xyz * dy) +
- viewinv.translation)
+ viewinv.translation)
return origin_start
diff --git a/release/scripts/modules/bpy_restrict_state.py b/release/scripts/modules/bpy_restrict_state.py
new file mode 100644
index 00000000000..4aa3c5de573
--- /dev/null
+++ b/release/scripts/modules/bpy_restrict_state.py
@@ -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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+"""
+This module contains RestrictBlend context manager.
+"""
+
+__all__ = (
+ "RestrictBlend",
+ )
+
+import bpy as _bpy
+
+
+class _RestrictContext():
+ __slots__ = ()
+ _real_data = _bpy.data
+ # safe, the pointer never changes
+ _real_pref = _bpy.context.user_preferences
+
+ @property
+ def window_manager(self):
+ return self._real_data.window_managers[0]
+
+ @property
+ def user_preferences(self):
+ return self._real_pref
+
+
+class _RestrictData():
+ __slots__ = ()
+
+
+_context_restrict = _RestrictContext()
+_data_restrict = _RestrictData()
+
+
+class RestrictBlend():
+ __slots__ = ("context", "data")
+
+ def __enter__(self):
+ self.data = _bpy.data
+ self.context = _bpy.context
+ _bpy.data = _data_restrict
+ _bpy.context = _context_restrict
+
+ def __exit__(self, type, value, traceback):
+ _bpy.data = self.data
+ _bpy.context = self.context
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index e42ae43aed6..4398b1721f7 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -484,6 +484,18 @@ class Text(bpy_types.ID):
if cont.type == 'PYTHON']
)
+
+class NodeSocket(StructRNA): # , metaclass=RNAMeta
+ __slots__ = ()
+
+ @property
+ def links(self):
+ """List of node links from or to this socket"""
+ return tuple(link for link in self.id_data.links
+ if (link.from_socket == self or
+ link.to_socket == self))
+
+
# values are module: [(cls, path, line), ...]
TypeMap = {}
@@ -603,6 +615,10 @@ class KeyingSetInfo(StructRNA, metaclass=RNAMeta):
__slots__ = ()
+class AddonPreferences(StructRNA, metaclass=RNAMeta):
+ __slots__ = ()
+
+
class _GenericUI:
__slots__ = ()
@@ -664,6 +680,10 @@ class Panel(StructRNA, _GenericUI, metaclass=RNAMeta):
__slots__ = ()
+class UIList(StructRNA, _GenericUI, metaclass=RNAMeta):
+ __slots__ = ()
+
+
class Header(StructRNA, _GenericUI, metaclass=RNAMeta):
__slots__ = ()
@@ -698,7 +718,9 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
files.sort()
for f, filepath in files:
- props = layout.operator(operator, text=bpy.path.display_name(f))
+ props = layout.operator(operator,
+ text=bpy.path.display_name(f),
+ translate=False)
for attr, value in props_default.items():
setattr(props, attr, value)
@@ -717,3 +739,21 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
self.path_menu(bpy.utils.preset_paths(self.preset_subdir),
self.preset_operator,
filter_ext=lambda ext: ext.lower() in {".py", ".xml"})
+
+class Region(StructRNA):
+ __slots__ = ()
+
+ def callback_add(self, cb, args, draw_mode):
+ """
+ Append a draw function to this region,
+ deprecated, instead use bpy.types.SpaceView3D.draw_handler_add
+ """
+ for area in self.id_data.areas:
+ for region in area.regions:
+ if region == self:
+ spacetype = type(area.spaces[0])
+ return spacetype.draw_handler_add(cb, args, self.type,
+ draw_mode)
+
+ return None
+
diff --git a/release/scripts/modules/console/intellisense.py b/release/scripts/modules/console/intellisense.py
index a177b305fda..b694cceafea 100644
--- a/release/scripts/modules/console/intellisense.py
+++ b/release/scripts/modules/console/intellisense.py
@@ -148,7 +148,7 @@ def expand(line, cursor, namespace, private=True):
if prefix:
line = line[:cursor] + prefix + line[cursor:]
- cursor += len(prefix)
+ cursor += len(prefix.encode('utf-8'))
if no_calltip and prefix.endswith('('):
return expand(line, cursor, namespace, private)
return line, cursor, scrollback
diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py
index 60dfa2b6344..55ff84fea96 100644
--- a/release/scripts/modules/console_python.py
+++ b/release/scripts/modules/console_python.py
@@ -334,8 +334,8 @@ def banner(context):
add_scrollback("Cursor: Left/Right Home/End", 'OUTPUT')
add_scrollback("Remove: Backspace/Delete", 'OUTPUT')
add_scrollback("Execute: Enter", 'OUTPUT')
- add_scrollback("Autocomplete: Ctrl+Space", 'OUTPUT')
- add_scrollback("Ctrl +/- Wheel: Zoom", 'OUTPUT')
+ add_scrollback("Autocomplete: Ctrl-Space", 'OUTPUT')
+ add_scrollback("Zoom: Ctrl +/-, Ctrl-Wheel", 'OUTPUT')
add_scrollback("Builtin Modules: bpy, bpy.data, bpy.ops, "
"bpy.props, bpy.types, bpy.context, bpy.utils, "
"bgl, blf, mathutils",
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 32c8ed11bc5..dd0cd632413 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -92,6 +92,9 @@ def draw(layout, context, context_member, property_type, use_edit=True):
if not rna_item:
return
+ if rna_item.id_data.library is not None:
+ use_edit = False
+
assert(isinstance(rna_item, property_type))
items = rna_item.items()
@@ -132,11 +135,11 @@ def draw(layout, context, context_member, property_type, use_edit=True):
else:
row = box.row()
- row.label(text=key)
+ row.label(text=key, translate=False)
# explicit exception for arrays
if to_dict or to_list:
- row.label(text=val_draw)
+ row.label(text=val_draw, translate=False)
else:
if key in rna_properties:
row.prop(rna_item, key, text="")
@@ -145,7 +148,7 @@ def draw(layout, context, context_member, property_type, use_edit=True):
if use_edit:
row = split.row(align=True)
- props = row.operator("wm.properties_edit", text="edit")
+ props = row.operator("wm.properties_edit", text="Edit")
assign_props(props, val_draw, key)
props = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py
index e21ccd08a35..08b60ebc6f8 100644
--- a/release/scripts/modules/rna_xml.py
+++ b/release/scripts/modules/rna_xml.py
@@ -265,7 +265,15 @@ def xml2rna(root_xml,
tp_name = 'ARRAY'
# print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type))
- setattr(value, attr, value_xml_coerce)
+ try:
+ setattr(value, attr, value_xml_coerce)
+ except ValueError:
+ # size mismatch
+ val = getattr(value, attr)
+ if len(val) < len(value_xml_coerce):
+ setattr(value, attr, value_xml_coerce[:len(val)])
+ else:
+ setattr(value, attr, list(value_xml_coerce) + list(val)[len(value_xml_coerce):])
# ---------------------------------------------------------------------
# Complex attributes
diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml
index 0a77aa132a8..05216841cbd 100644
--- a/release/scripts/presets/interface_theme/back_to_black.xml
+++ b/release/scripts/presets/interface_theme/back_to_black.xml
@@ -1,7 +1,9 @@
<bpy>
<Theme>
<user_interface>
- <ThemeUserInterface icon_file=""
+ <ThemeUserInterface menu_shadow_fac="0.5"
+ menu_shadow_width="12"
+ icon_file=""
icon_alpha="1"
axis_x="#dc0000"
axis_y="#00dc00"
@@ -220,16 +222,10 @@
blend="0.1">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#000000ff"
- show_header="FALSE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#222222"
- panel="#a5a5a57f"
wire="#888888"
lamp="#c1d40028"
speaker="#535353"
@@ -281,24 +277,35 @@
camera_path="#5a5a5a"
skin_root="#000000">
<space>
- <ThemeSpaceGeneric back="#0f0f0f"
- title="#5d5d5d"
- text="#7d7d7d"
- text_hi="#ffffff"
- header="#000000"
- header_text="#979797"
- header_text_hi="#ffffff"
- button="#000000"
- button_title="#c5c5c5"
- button_text="#c3c3c3"
- button_text_hi="#ffffff">
- </ThemeSpaceGeneric>
+ <ThemeSpaceGradient title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#00000057"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ <gradients>
+ <ThemeGradientColors show_grad="FALSE"
+ gradient="#393939"
+ high_gradient="#000000">
+ </ThemeGradientColors>
+ </gradients>
+ </ThemeSpaceGradient>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#262626"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#6d6d6d"
vertex="#ffffff"
@@ -331,10 +338,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +362,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#354d66"
- tiles="#343434"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#b1b1b1"
@@ -361,10 +374,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +420,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c3c3c3"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +464,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +510,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +548,23 @@
header="#000000"
header_text="#f3f3f3"
header_text_hi="#ffffff"
- button="#020202"
+ button="#02020242"
button_title="#bdbdbd"
button_text="#dddddd"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#000000"
title="#5d5d5d"
@@ -525,10 +573,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -538,7 +593,10 @@
selected_text="#202020"
cursor="#ff0000"
syntax_builtin="#cf3d99"
+ syntax_symbols="#4c4c4c"
syntax_special="#969629"
+ syntax_preprocessor="#32008c"
+ syntax_reserved="#8c3c00"
syntax_comment="#249d60"
syntax_string="#cc3535"
syntax_numbers="#3c68ff">
@@ -550,10 +608,17 @@
header="#000000"
header_text="#b9b9b9"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#d8d8d8"
button_text="#cccccc"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +634,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -589,6 +661,8 @@
operator_node="#0e3157"
group_node="#091a07"
frame_node="#9a9b9ba0"
+ matte_node="#977474"
+ distor_node="#749797"
noodle_curving="5">
<space>
<ThemeSpaceGeneric back="#000000"
@@ -598,10 +672,17 @@
header="#000000"
header_text="#c7c7c7"
header_text_hi="#ffffff"
- button="#000000"
+ button="#0000002f"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +695,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#a5a5a5">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#070707"
title="#5d5d5d"
@@ -623,10 +704,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +730,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +755,17 @@
header="#000000"
header_text="#adadad"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +780,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -691,7 +800,8 @@
line_input="#cecece"
line_info="#00aa00"
line_error="#dc6060"
- cursor="#dc6060">
+ cursor="#dc6060"
+ select="#ffffff30">
<space>
<ThemeSpaceGeneric back="#0f0f0f"
title="#5d5d5d"
@@ -700,10 +810,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +849,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#070707"
+ button="#070707ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml
index 18ae3072208..48a3ee951aa 100644
--- a/release/scripts/presets/interface_theme/blender_24x.xml
+++ b/release/scripts/presets/interface_theme/blender_24x.xml
@@ -1,7 +1,9 @@
<bpy>
<Theme>
<user_interface>
- <ThemeUserInterface icon_file=""
+ <ThemeUserInterface menu_shadow_fac="0.5"
+ menu_shadow_width="12"
+ icon_file=""
icon_alpha="1"
axis_x="#dc0000"
axis_y="#00dc00"
@@ -220,16 +222,10 @@
blend="0.5">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000019"
- show_header="FALSE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#5c5c5c"
- panel="#a5a5a5ff"
wire="#000000"
lamp="#00000028"
speaker="#000000"
@@ -281,24 +277,35 @@
camera_path="#000000"
skin_root="#000000">
<space>
- <ThemeSpaceGeneric back="#757575"
- title="#000000"
- text="#000000"
- text_hi="#ffffff"
- header="#b4b4b4"
- header_text="#000000"
- header_text_hi="#ffffff"
- button="#b4b4b4"
- button_title="#5a5a5a"
- button_text="#5a5a5a"
- button_text_hi="#ffffff">
- </ThemeSpaceGeneric>
+ <ThemeSpaceGradient title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b457"
+ button_title="#5a5a5a"
+ button_text="#5a5a5a"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ <gradients>
+ <ThemeGradientColors show_grad="FALSE"
+ gradient="#000000"
+ high_gradient="#757575">
+ </ThemeGradientColors>
+ </gradients>
+ </ThemeSpaceGradient>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#818181"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#707070"
vertex="#000000"
@@ -331,10 +338,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +362,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#a0a0d0"
- tiles="#b4b4b4"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#828282"
@@ -361,10 +374,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +420,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +464,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +510,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +548,23 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b442"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#b4b4b4"
title="#000000"
@@ -525,10 +573,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -538,7 +593,10 @@
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">
@@ -550,10 +608,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +634,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -589,6 +661,8 @@
operator_node="#6c696f"
group_node="#69756e"
frame_node="#9a9b9ba0"
+ matte_node="#977474"
+ distor_node="#749797"
noodle_curving="5">
<space>
<ThemeSpaceGeneric back="#757575"
@@ -598,10 +672,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b42f"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +695,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#a5a5a5">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#b4b4b4"
title="#000000"
@@ -623,10 +704,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +730,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +755,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +780,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -691,7 +800,8 @@
line_input="#ffffff"
line_info="#00aa00"
line_error="#dc6060"
- cursor="#dc6060">
+ cursor="#dc6060"
+ select="#c6777799">
<space>
<ThemeSpaceGeneric back="#b4b4b4"
title="#000000"
@@ -700,10 +810,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +849,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml
index c10eb108000..3ea49edc7f5 100644
--- a/release/scripts/presets/interface_theme/elsyiun.xml
+++ b/release/scripts/presets/interface_theme/elsyiun.xml
@@ -1,7 +1,9 @@
<bpy>
<Theme>
<user_interface>
- <ThemeUserInterface icon_file=""
+ <ThemeUserInterface menu_shadow_fac="0.5"
+ menu_shadow_width="12"
+ icon_file=""
icon_alpha="1"
axis_x="#dc0000"
axis_y="#00dc00"
@@ -220,16 +222,10 @@
blend="0.5">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000019"
- show_header="FALSE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#585858"
- panel="#a5a5a57f"
wire="#000000"
lamp="#00000028"
speaker="#000000"
@@ -281,24 +277,35 @@
camera_path="#000000"
skin_root="#000000">
<space>
- <ThemeSpaceGeneric back="#4b4b4b"
- title="#000000"
- text="#b8b8b8"
- text_hi="#e9e9e9"
- header="#3b3b3b"
- header_text="#b9b9b9"
- header_text_hi="#ffffff"
- button="#3b3b3b"
- button_title="#979797"
- button_text="#979797"
- button_text_hi="#ffffff">
- </ThemeSpaceGeneric>
+ <ThemeSpaceGradient title="#000000"
+ text="#b8b8b8"
+ text_hi="#e9e9e9"
+ header="#3b3b3b"
+ header_text="#b9b9b9"
+ header_text_hi="#ffffff"
+ button="#3b3b3b57"
+ button_title="#979797"
+ button_text="#979797"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ <gradients>
+ <ThemeGradientColors show_grad="FALSE"
+ gradient="#000000"
+ high_gradient="#4b4b4b">
+ </ThemeGradientColors>
+ </gradients>
+ </ThemeSpaceGradient>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#585858"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#707070"
vertex="#000000"
@@ -331,10 +338,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +362,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#755129"
- tiles="#3b3b3b"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#828282"
@@ -361,10 +374,17 @@
header="#3b3b3b"
header_text="#8b8b8b"
header_text_hi="#ffffff"
- button="#303030"
+ button="#303030ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +420,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +464,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#aaaaaa"
+ button="#aaaaaaff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +510,17 @@
header="#303030"
header_text="#000000"
header_text_hi="#ffffff"
- button="#303030"
+ button="#303030ff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +548,23 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3b42"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#3b3b3b"
title="#979797"
@@ -525,10 +573,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#b8b8b8"
button_text="#b8b8b8"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -538,7 +593,10 @@
selected_text="#4e4e8f"
cursor="#8b8bff"
syntax_builtin="#808bed"
+ syntax_symbols="#4c4c4c"
syntax_special="#c080d0"
+ syntax_preprocessor="#409090"
+ syntax_reserved="#8c3c00"
syntax_comment="#cd8b00"
syntax_string="#ffcd8b"
syntax_numbers="#f0ad6d">
@@ -550,10 +608,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +634,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -589,6 +661,8 @@
operator_node="#2c6f6f"
group_node="#1e7524"
frame_node="#9a9b9ba0"
+ matte_node="#977474"
+ distor_node="#749797"
noodle_curving="5">
<space>
<ThemeSpaceGeneric back="#3b3b3b"
@@ -598,10 +672,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3b2f"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +695,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#3b3b3b">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#3b3b3b"
title="#000000"
@@ -623,10 +704,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +730,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +755,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#000000"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#000000">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +780,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -691,7 +800,8 @@
line_input="#ffffff"
line_info="#00aa00"
line_error="#dc6060"
- cursor="#dc6060">
+ cursor="#dc6060"
+ select="#4e4e8f80">
<space>
<ThemeSpaceGeneric back="#202020"
title="#000000"
@@ -700,10 +810,17 @@
header="#303030"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +849,17 @@
header="#313131"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml
index ad514bbbafa..299df3860f5 100644
--- a/release/scripts/presets/interface_theme/hexagon.xml
+++ b/release/scripts/presets/interface_theme/hexagon.xml
@@ -1,7 +1,9 @@
<bpy>
<Theme>
<user_interface>
- <ThemeUserInterface icon_file=""
+ <ThemeUserInterface menu_shadow_fac="0.5"
+ menu_shadow_width="12"
+ icon_file=""
icon_alpha="1"
axis_x="#dc0000"
axis_y="#00dc00"
@@ -220,16 +222,10 @@
blend="0.5">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000019"
- show_header="TRUE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#5e5e83"
- panel="#a5a5a5ff"
wire="#000000"
lamp="#00000028"
speaker="#000000"
@@ -281,24 +277,35 @@
camera_path="#000000"
skin_root="#000000">
<space>
- <ThemeSpaceGeneric back="#7f818d"
- title="#000000"
- text="#000000"
- text_hi="#ffffff"
- header="#646875"
- header_text="#000000"
- header_text_hi="#ffffff"
- button="#6c717f"
- button_title="#eaeaea"
- button_text="#d7d7d7"
- button_text_hi="#ffffff">
- </ThemeSpaceGeneric>
+ <ThemeSpaceGradient title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#646875"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#6c717f57"
+ button_title="#eaeaea"
+ button_text="#d7d7d7"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ <gradients>
+ <ThemeGradientColors show_grad="FALSE"
+ gradient="#000000"
+ high_gradient="#7f818d">
+ </ThemeGradientColors>
+ </gradients>
+ </ThemeSpaceGradient>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#58587c"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#707070"
vertex="#000000"
@@ -331,10 +338,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +362,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#69a5be"
- tiles="#5c606c"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#859cb9"
@@ -361,10 +374,17 @@
header="#5c606c"
header_text="#dddddd"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#d7d7d7"
button_text="#d7d7d7"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +420,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +464,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +510,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#eeeeee"
button_text="#eeeeee"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +548,23 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#64687542"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#646875"
title="#ffffff"
@@ -525,10 +573,17 @@
header="#646875"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -538,7 +593,10 @@
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">
@@ -550,10 +608,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +634,17 @@
header="#565863"
header_text="#000000"
header_text_hi="#ffffff"
- button="#5a5e6a"
+ button="#5a5e6aff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -589,6 +661,8 @@
operator_node="#6c697e"
group_node="#69756e"
frame_node="#9a9b9ba0"
+ matte_node="#977474"
+ distor_node="#749797"
noodle_curving="5">
<space>
<ThemeSpaceGeneric back="#7c7e88"
@@ -598,10 +672,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#6468752f"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +695,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#a5a5a5">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#7c7e88"
title="#000000"
@@ -623,10 +704,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#d7d7d7"
button_text="#d7d7d7"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +730,17 @@
header="#6c717f"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +755,17 @@
header="#646875"
header_text="#dddddd"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +780,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -691,7 +800,8 @@
line_input="#ffffff"
line_info="#00aa00"
line_error="#dc0606"
- cursor="#dc6060">
+ cursor="#dc6060"
+ select="#ffffff30">
<space>
<ThemeSpaceGeneric back="#7c7e88"
title="#000000"
@@ -700,10 +810,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +849,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
index 8f4a42b6ab7..38ab35d4b7b 100644
--- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
+++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
@@ -1,7 +1,9 @@
<bpy>
<Theme>
<user_interface>
- <ThemeUserInterface icon_file=""
+ <ThemeUserInterface menu_shadow_fac="0.5"
+ menu_shadow_width="12"
+ icon_file=""
icon_alpha="1"
axis_x="#dc0000"
axis_y="#00dc00"
@@ -220,16 +222,10 @@
blend="0.1">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000000"
- show_header="TRUE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#3c3b37"
- panel="#a5a5a57f"
wire="#93237f"
lamp="#ffffff34"
speaker="#93237f"
@@ -281,24 +277,35 @@
camera_path="#7dbd00"
skin_root="#000000">
<space>
- <ThemeSpaceGeneric back="#131311"
- title="#9c9c9c"
- text="#9c9c9c"
- text_hi="#ffffff"
- header="#464541"
- header_text="#acacac"
- header_text_hi="#ffffff"
- button="#3c3b37"
- button_title="#9c9c9c"
- button_text="#9c9c9c"
- button_text_hi="#ffffff">
- </ThemeSpaceGeneric>
+ <ThemeSpaceGradient title="#9c9c9c"
+ text="#9c9c9c"
+ text_hi="#ffffff"
+ header="#464541"
+ header_text="#acacac"
+ header_text_hi="#ffffff"
+ button="#3c3b3757"
+ button_title="#9c9c9c"
+ button_text="#9c9c9c"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ <gradients>
+ <ThemeGradientColors show_grad="FALSE"
+ gradient="#000000"
+ high_gradient="#131311">
+ </ThemeGradientColors>
+ </gradients>
+ </ThemeSpaceGradient>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#3c3b37"
- panel="#ffffff"
window_sliders="#95948f"
channels_region="#707070"
vertex="#ffffff"
@@ -331,10 +338,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#9c9c9c"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +362,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#6b395a"
- tiles="#3c3b37"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#eeedeb"
@@ -361,10 +374,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +420,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +464,17 @@
header="#464541"
header_text="#cacaca"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#9c9c9c"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +510,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#b1b1b1"
button_text="#b9b9b9"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +548,23 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b3742"
button_title="#acacac"
button_text="#acacac"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#3c3b37">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#3c3b37"
title="#acacac"
@@ -525,10 +573,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -538,7 +593,10 @@
selected_text="#641f44"
cursor="#f47421"
syntax_builtin="#d6ff01"
+ syntax_symbols="#4c4c4c"
syntax_special="#33a500"
+ syntax_preprocessor="#be00ff"
+ syntax_reserved="#8c3c00"
syntax_comment="#249d60"
syntax_string="#6e00ff"
syntax_numbers="#972144">
@@ -550,10 +608,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#191919"
+ button="#191919ff"
button_title="#64645e"
button_text="#95948f"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +634,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#9c9c9c"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -589,6 +661,8 @@
operator_node="#000000"
group_node="#19b6ee"
frame_node="#9a9b9ba0"
+ matte_node="#977474"
+ distor_node="#749797"
noodle_curving="5">
<space>
<ThemeSpaceGeneric back="#29001b"
@@ -598,10 +672,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#353430"
+ button="#3534302f"
button_title="#acacac"
button_text="#acacac"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +695,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#acacac">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#29001b"
title="#000000"
@@ -623,10 +704,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#353430"
+ button="#353430ff"
button_title="#7d7d7d"
button_text="#acacac"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +730,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#f47421">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +755,17 @@
header="#464541"
header_text="#ffffff"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#eeedeb"
button_text="#eeedeb"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +780,17 @@
header="#3c3b37"
header_text="#d3d2cd"
header_text_hi="#ffffff"
- button="#696965"
+ button="#696965ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -691,7 +800,8 @@
line_input="#19b6ee"
line_info="#f47421"
line_error="#ff0000"
- cursor="#f47421">
+ cursor="#f47421"
+ select="#641f4480">
<space>
<ThemeSpaceGeneric back="#131311"
title="#000000"
@@ -700,10 +810,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +849,17 @@
header="#464541"
header_text="#9c9c9c"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#ffffff"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py
index ec8efc8d371..d6805fb3484 100644
--- a/release/scripts/presets/keyconfig/maya.py
+++ b/release/scripts/presets/keyconfig/maya.py
@@ -138,41 +138,49 @@ kmi.properties.extend = False
kmi.properties.center = False
kmi.properties.object = False
kmi.properties.enumerate = False
+kmi.properties.toggle = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True)
-kmi.properties.extend = True
+kmi.properties.extend = False
kmi.properties.center = False
kmi.properties.object = False
kmi.properties.enumerate = False
+kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True)
kmi.properties.extend = False
kmi.properties.center = True
kmi.properties.object = False
kmi.properties.enumerate = False
+kmi.properties.toggle = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', alt=True)
kmi.properties.extend = False
kmi.properties.center = False
kmi.properties.object = False
kmi.properties.enumerate = True
+kmi.properties.toggle = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True)
kmi.properties.extend = True
kmi.properties.center = True
kmi.properties.object = False
kmi.properties.enumerate = False
+kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True, alt=True)
kmi.properties.extend = False
kmi.properties.center = True
kmi.properties.object = False
kmi.properties.enumerate = True
+kmi.properties.toggle = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, alt=True)
kmi.properties.extend = True
kmi.properties.center = False
kmi.properties.object = False
kmi.properties.enumerate = True
+kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True, alt=True)
kmi.properties.extend = True
kmi.properties.center = True
kmi.properties.object = False
kmi.properties.enumerate = True
+kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY')
kmi.properties.extend = False
kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
@@ -218,7 +226,9 @@ kmi.properties.use = True
kmi = km.keymap_items.new('transform.mirror', 'M', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.context_toggle', 'TAB', 'PRESS', shift=True)
kmi.properties.data_path = 'tool_settings.use_snap'
-kmi = km.keymap_items.new('transform.snap_type', 'TAB', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('WM_OT_context_menu_enum', 'TAB', 'PRESS', shift=True, ctrl=True)
+kmi.properties.data_path = 'tool_settings.snap_element'
+
kmi = km.keymap_items.new('view3d.enable_manipulator', 'W', 'PRESS')
kmi.properties.translate = True
kmi = km.keymap_items.new('view3d.enable_manipulator', 'E', 'PRESS')
diff --git a/release/scripts/presets/operator/wm.collada_export/second_life_rigged.py b/release/scripts/presets/operator/wm.collada_export/second_life_rigged.py
index 2c695a22ff9..81769a82728 100644
--- a/release/scripts/presets/operator/wm.collada_export/second_life_rigged.py
+++ b/release/scripts/presets/operator/wm.collada_export/second_life_rigged.py
@@ -7,6 +7,7 @@ op.export_mesh_type_selection = 'view'
op.selected = True
op.include_children = False
op.include_armatures = True
+op.include_shapekeys = False
op.deform_bones_only = True
op.active_uv_only = True
op.include_uv_textures = True
diff --git a/release/scripts/presets/operator/wm.collada_export/second_life_static.py b/release/scripts/presets/operator/wm.collada_export/second_life_static.py
index 081788b7e9d..ad06909a276 100644
--- a/release/scripts/presets/operator/wm.collada_export/second_life_static.py
+++ b/release/scripts/presets/operator/wm.collada_export/second_life_static.py
@@ -7,6 +7,7 @@ op.export_mesh_type_selection = 'view'
op.selected = True
op.include_children = False
op.include_armatures = False
+op.include_shapekeys = False
op.deform_bones_only = False
op.active_uv_only = True
op.include_uv_textures = True
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py
index ecbbe34dbb4..3ff02420bbd 100644
--- a/release/scripts/startup/bl_operators/__init__.py
+++ b/release/scripts/startup/bl_operators/__init__.py
@@ -35,6 +35,7 @@ _modules = (
"object_randomize_transform",
"object_quick_effects",
"presets",
+ "rigidbody",
"screen_play_rendered_anim",
"sequencer",
"uvcalc_follow_active",
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py
index 552247f0940..63e796e2b5d 100644
--- a/release/scripts/startup/bl_operators/add_mesh_torus.py
+++ b/release/scripts/startup/bl_operators/add_mesh_torus.py
@@ -19,7 +19,6 @@
# <pep8-80 compliant>
import bpy
from bpy.types import Operator
-import mathutils
from bpy.props import (FloatProperty,
IntProperty,
@@ -31,9 +30,7 @@ from bpy_extras import object_utils
def add_torus(major_rad, minor_rad, major_seg, minor_seg):
from math import cos, sin, pi
-
- Vector = mathutils.Vector
- Quaternion = mathutils.Quaternion
+ from mathutils import Vector, Quaternion
PI_2 = pi * 2.0
z_axis = 0.0, 0.0, 1.0
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index 902c7007fb9..e34e9a981a6 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -187,17 +187,20 @@ class BakeAction(Operator):
)
only_selected = BoolProperty(
name="Only Selected",
+ description="Only key selected object/bones",
default=True,
)
clear_constraints = BoolProperty(
name="Clear Constraints",
+ description="Remove all constraints from keyed object/bones, and do 'visual' keying",
default=False,
)
bake_types = EnumProperty(
name="Bake Data",
+ description="Which data's transformations to bake",
options={'ENUM_FLAG'},
- items=(('POSE', "Pose", ""),
- ('OBJECT', "Object", ""),
+ items=(('POSE', "Pose", "Bake bones transformations"),
+ ('OBJECT', "Object", "Bake object transformations"),
),
default={'POSE'},
)
@@ -208,12 +211,12 @@ class BakeAction(Operator):
action = anim_utils.bake_action(self.frame_start,
self.frame_end,
- self.step,
- self.only_selected,
- 'POSE' in self.bake_types,
- 'OBJECT' in self.bake_types,
- self.clear_constraints,
- True,
+ frame_step=self.step,
+ only_selected=self.only_selected,
+ do_pose='POSE' in self.bake_types,
+ do_object='OBJECT' in self.bake_types,
+ do_constraint_clear=self.clear_constraints,
+ do_clean=True,
)
if action is None:
diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index fb264cb3429..bc0224db765 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -20,7 +20,85 @@
import bpy
from bpy.types import Operator
-from bpy.props import EnumProperty
+from bpy.props import BoolProperty, EnumProperty, StringProperty
+
+
+# Base class for node 'Add' operators
+class NodeAddOperator():
+ @staticmethod
+ def store_mouse_cursor(context, event):
+ space = context.space_data
+ v2d = context.region.view2d
+
+ # convert mouse position to the View2D for later node placement
+ space.cursor_location = v2d.region_to_view(event.mouse_region_x,
+ event.mouse_region_y)
+
+ def create_node(self, context, node_type):
+ space = context.space_data
+ tree = space.edit_tree
+
+ # select only the new node
+ for n in tree.nodes:
+ n.select = False
+
+ node = tree.nodes.new(type=node_type)
+
+ node.select = True
+ tree.nodes.active = node
+ node.location = space.cursor_location
+ return node
+
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ # needs active node editor and a tree to add nodes to
+ return (space.type == 'NODE_EDITOR' and space.edit_tree)
+
+ # Default invoke stores the mouse position to place the node correctly
+ def invoke(self, context, event):
+ self.store_mouse_cursor(context, event)
+ return self.execute(context)
+
+
+# Simple basic operator for adding a node
+class NODE_OT_add_node(NodeAddOperator, Operator):
+ '''Add a node to the active tree'''
+ bl_idname = "node.add_node"
+ bl_label = "Add Node"
+
+ type = StringProperty(
+ name="Node Type",
+ description="Node type",
+ )
+ # optional group tree parameter for group nodes
+ group_tree = StringProperty(
+ name="Group tree",
+ description="Group node tree name",
+ )
+ use_transform = BoolProperty(
+ name="Use Transform",
+ description="Start transform operator after inserting the node",
+ default=False,
+ )
+
+ def execute(self, context):
+ node = self.create_node(context, self.type)
+
+ # set the node group tree of a group node
+ if self.properties.is_property_set('group_tree'):
+ node.node_tree = bpy.data.node_groups[self.group_tree]
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ self.store_mouse_cursor(context, event)
+ result = self.execute(context)
+ if self.use_transform and ('FINISHED' in result):
+ return bpy.ops.transform.translate('INVOKE_DEFAULT')
+ else:
+ return result
+
# XXX These node item lists should actually be generated by a callback at
# operator execution time (see node_type_items below),
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 9e449f325d6..f8eb55db42e 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -110,6 +110,12 @@ class SelectCamera(Operator):
bl_label = "Select Camera"
bl_options = {'REGISTER', 'UNDO'}
+ extend = BoolProperty(
+ name="Extend",
+ description="Extend the selection",
+ default=False
+ )
+
def execute(self, context):
scene = context.scene
view = context.space_data
@@ -123,6 +129,8 @@ class SelectCamera(Operator):
elif camera.name not in scene.objects:
self.report({'WARNING'}, "Active camera is not in this scene")
else:
+ if not self.extend:
+ bpy.ops.object.select_all(action='DESELECT')
context.scene.objects.active = camera
camera.select = True
return {'FINISHED'}
@@ -297,7 +305,7 @@ class ShapeTransfer(Operator):
('RELATIVE_EDGE',
"Relative Edge",
"Calculate relative position (using edges)",
- ),
+ ),
),
name="Transformation Mode",
description="Relative shape positions to the new shape method",
@@ -373,11 +381,8 @@ class ShapeTransfer(Operator):
(orig_shape_coords[i] - orig_coords[i]))
elif mode == 'RELATIVE_FACE':
- loops_vidxs = me.loops.foreach_get("vert_index")
for poly in me.polygons:
- l_start = l_stop = poly.loop_start
- l_stop += poly.loop_total
- idxs = loops_vidxs[l_start:l_stop]
+ idxs = poly.vertices[:]
v_before = idxs[-2]
v = idxs[-1]
for v_after in idxs:
@@ -674,7 +679,7 @@ class TransformsToDeltasAnim(Operator):
"scale" : "delta_scale"
}
DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values()
-
+
# try to apply on each selected object
success = False
for obj in context.selected_editable_objects:
@@ -684,7 +689,7 @@ class TransformsToDeltasAnim(Operator):
"No animation data to convert on object: %r" %
obj.name)
continue
-
+
# first pass over F-Curves: ensure that we don't have conflicting
# transforms already (e.g. if this was applied already) [#29110]
existingFCurves = {}
@@ -700,7 +705,7 @@ class TransformsToDeltasAnim(Operator):
else:
# non-transform - ignore
continue
-
+
# a delta path like this for the same index shouldn't
# exist already, otherwise we've got a conflict
if dpath in existingFCurves:
@@ -708,8 +713,9 @@ class TransformsToDeltasAnim(Operator):
if fcu.array_index in existingFCurves[dpath]:
# conflict
self.report({'ERROR'},
- "Object '%r' already has '%r' F-Curve(s). Remove these before trying again" %
- (obj.name, dpath))
+ "Object '%r' already has '%r' F-Curve(s). "
+ "Remove these before trying again" %
+ (obj.name, dpath))
return {'CANCELLED'}
else:
# no conflict here
@@ -717,8 +723,7 @@ class TransformsToDeltasAnim(Operator):
else:
# no conflict yet
existingFCurves[dpath] = [fcu.array_index]
-
-
+
# if F-Curve uses standard transform path
# just append "delta_" to this path
for fcu in adt.action.fcurves:
@@ -758,7 +763,7 @@ class DupliOffsetFromCursor(Operator):
@classmethod
def poll(cls, context):
- return context.active_object is not None
+ return (context.active_object is not None)
def execute(self, context):
scene = context.scene
diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py
index a32bb8c5353..e843209da3c 100644
--- a/release/scripts/startup/bl_operators/object_align.py
+++ b/release/scripts/startup/bl_operators/object_align.py
@@ -114,31 +114,32 @@ def GlobalBB_HQ(obj):
return Vector((left, front, up)), Vector((right, back, down))
-def align_objects(align_x,
+def align_objects(context,
+ align_x,
align_y,
align_z,
align_mode,
relative_to,
bb_quality):
- cursor = bpy.context.scene.cursor_location
+ cursor = context.scene.cursor_location
Left_Front_Up_SEL = [0.0, 0.0, 0.0]
Right_Back_Down_SEL = [0.0, 0.0, 0.0]
flag_first = True
- objs = []
+ objects = []
- for obj in bpy.context.selected_objects:
+ for obj in context.selected_objects:
matrix_world = obj.matrix_world.copy()
bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
- objs.append((obj, bb_world))
+ objects.append((obj, bb_world))
- if not objs:
+ if not objects:
return False
- for obj, bb_world in objs:
+ for obj, bb_world in objects:
if bb_quality and obj.type == 'MESH':
GBB = GlobalBB_HQ(obj)
@@ -150,7 +151,7 @@ def align_objects(align_x,
# Active Center
- if obj == bpy.context.active_object:
+ if obj == context.active_object:
center_active_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
center_active_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
@@ -200,7 +201,7 @@ def align_objects(align_x,
# Main Loop
- for obj, bb_world in objs:
+ for obj, bb_world in objects:
matrix_world = obj.matrix_world.copy()
bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
@@ -386,7 +387,8 @@ class AlignObjects(Operator):
def execute(self, context):
align_axis = self.align_axis
- ret = align_objects('X' in align_axis,
+ ret = align_objects(context,
+ 'X' in align_axis,
'Y' in align_axis,
'Z' in align_axis,
self.align_mode,
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index cd0b63a6b78..47012f0c459 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -72,7 +72,7 @@ class QuickFur(Operator):
)
def execute(self, context):
- fake_context = bpy.context.copy()
+ fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if obj.type == 'MESH']
@@ -161,7 +161,7 @@ class QuickExplode(Operator):
)
def execute(self, context):
- fake_context = bpy.context.copy()
+ fake_context = context.copy()
obj_act = context.active_object
if obj_act is None or obj_act.type != 'MESH':
@@ -311,7 +311,7 @@ class QuickSmoke(Operator):
)
def execute(self, context):
- fake_context = bpy.context.copy()
+ fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if obj.type == 'MESH']
min_co = Vector((100000.0, 100000.0, 100000.0))
@@ -432,7 +432,7 @@ class QuickFluid(Operator):
)
def execute(self, context):
- fake_context = bpy.context.copy()
+ fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if (obj.type == 'MESH' and not 0.0 in obj.dimensions)]
min_co = Vector((100000, 100000, 100000))
diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py
index a6efc9dfd85..38110328603 100644
--- a/release/scripts/startup/bl_operators/object_randomize_transform.py
+++ b/release/scripts/startup/bl_operators/object_randomize_transform.py
@@ -23,7 +23,8 @@ from bpy.types import Operator
from mathutils import Vector
-def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
+def randomize_selected(context, seed, delta,
+ loc, rot, scale, scale_even, scale_min):
import random
from random import uniform
@@ -33,7 +34,7 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
def rand_vec(vec_range):
return Vector(uniform(-val, val) for val in vec_range)
- for obj in bpy.context.selected_objects:
+ for obj in context.selected_objects:
if loc:
if delta:
@@ -180,6 +181,7 @@ class RandomizeLocRotSize(Operator):
#scale_min = self.scale_min
scale_min = 0
- randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min)
+ randomize_selected(context, seed, delta,
+ loc, rot, scale, scale_even, scale_min)
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index ee9769d8b43..dac7adecaff 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -320,13 +320,13 @@ class AddPresetFluid(AddPresetBase, Operator):
preset_menu = "FLUID_MT_presets"
preset_defines = [
- "fluid = bpy.context.fluid"
- ]
+ "fluid = bpy.context.fluid"
+ ]
preset_values = [
- "fluid.settings.viscosity_base",
- "fluid.settings.viscosity_exponent",
- ]
+ "fluid.settings.viscosity_base",
+ "fluid.settings.viscosity_exponent",
+ ]
preset_subdir = "fluid"
@@ -477,7 +477,7 @@ class AddPresetNodeColor(AddPresetBase, Operator):
class AddPresetInterfaceTheme(AddPresetBase, Operator):
"""Add a theme preset"""
bl_idname = "wm.interface_theme_preset_add"
- bl_label = "Add Tracking Settings Preset"
+ bl_label = "Add Theme Preset"
preset_menu = "USERPREF_MT_interface_theme_presets"
preset_subdir = "interface_theme"
diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py
new file mode 100644
index 00000000000..f327c602fb6
--- /dev/null
+++ b/release/scripts/startup/bl_operators/rigidbody.py
@@ -0,0 +1,292 @@
+# ##### 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 #####
+
+# <pep8-80 compliant>
+
+import bpy
+from bpy.types import Operator
+from bpy.props import IntProperty
+from bpy.props import EnumProperty
+
+
+class CopyRigidbodySettings(Operator):
+ '''Copy Rigid Body settings from active object to selected'''
+ bl_idname = "rigidbody.object_settings_copy"
+ bl_label = "Copy Rigid Body Settings"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body)
+
+ def execute(self, context):
+ obj = context.object
+ scene = context.scene
+
+ # deselect all but mesh objects
+ for o in context.selected_objects:
+ if o.type != 'MESH':
+ o.select = False
+
+ 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)
+
+ # copy settings
+ for o in objects:
+ if o.rigid_body is None:
+ continue
+
+ o.rigid_body.type = obj.rigid_body.type
+ o.rigid_body.kinematic = obj.rigid_body.kinematic
+ o.rigid_body.mass = obj.rigid_body.mass
+ o.rigid_body.collision_shape = obj.rigid_body.collision_shape
+ o.rigid_body.use_margin = obj.rigid_body.use_margin
+ o.rigid_body.collision_margin = obj.rigid_body.collision_margin
+ o.rigid_body.friction = obj.rigid_body.friction
+ o.rigid_body.restitution = obj.rigid_body.restitution
+ o.rigid_body.use_deactivation = obj.rigid_body.use_deactivation
+ o.rigid_body.start_deactivated = obj.rigid_body.start_deactivated
+ o.rigid_body.deactivate_linear_velocity = obj.rigid_body.deactivate_linear_velocity
+ o.rigid_body.deactivate_angular_velocity = obj.rigid_body.deactivate_angular_velocity
+ o.rigid_body.linear_damping = obj.rigid_body.linear_damping
+ o.rigid_body.angular_damping = obj.rigid_body.angular_damping
+ o.rigid_body.collision_groups = obj.rigid_body.collision_groups
+
+ return {'FINISHED'}
+
+
+class BakeToKeyframes(Operator):
+ '''Bake rigid body transformations of selected objects to keyframes'''
+ bl_idname = "rigidbody.bake_to_keyframes"
+ bl_label = "Bake To Keyframes"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ frame_start = IntProperty(
+ name="Start Frame",
+ description="Start frame for baking",
+ min=0, max=300000,
+ default=1,
+ )
+ frame_end = IntProperty(
+ name="End Frame",
+ description="End frame for baking",
+ min=1, max=300000,
+ default=250,
+ )
+ step = IntProperty(
+ name="Frame Step",
+ description="Frame Step",
+ min=1, max=120,
+ default=1,
+ )
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body)
+
+ def execute(self, context):
+ bake = []
+ objects = []
+ scene = context.scene
+ frame_orig = scene.frame_current
+ frames_step = range(self.frame_start, self.frame_end + 1, self.step)
+ frames_full = range(self.frame_start, self.frame_end + 1)
+
+ # filter objects selection
+ for obj in context.selected_objects:
+ if not obj.rigid_body or obj.rigid_body.type != 'ACTIVE':
+ obj.select = False
+
+ objects = context.selected_objects
+
+ if objects:
+ # store transformation data
+ # need to start at scene start frame so simulation is run from the beginning
+ for f in frames_full:
+ scene.frame_set(f)
+ if f in frames_step:
+ mat = {}
+ for i, obj in enumerate(objects):
+ mat[i] = obj.matrix_world.copy()
+ bake.append(mat)
+
+ # apply transformations as keyframes
+ for i, f in enumerate(frames_step):
+ scene.frame_set(f)
+ obj_prev = objects[0]
+ for j, obj in enumerate(objects):
+ mat = bake[i][j]
+
+ obj.location = mat.to_translation()
+
+ rot_mode = obj.rotation_mode
+ if rot_mode == 'QUATERNION':
+ obj.rotation_quaternion = mat.to_quaternion()
+ elif rot_mode == 'AXIS_ANGLE':
+ # this is a little roundabout but there's no better way right now
+ aa = mat.to_quaternion().to_axis_angle()
+ obj.rotation_axis_angle = (aa[1], ) + aa[0][:]
+ else: # euler
+ # make sure euler rotation is compatible to previous frame
+ obj.rotation_euler = mat.to_euler(rot_mode, obj_prev.rotation_euler)
+
+ obj_prev = obj
+
+ bpy.ops.anim.keyframe_insert(type='BUILTIN_KSI_LocRot', confirm_success=False)
+
+ # remove baked objects from simulation
+ bpy.ops.rigidbody.objects_remove()
+
+ # clean up keyframes
+ for obj in objects:
+ action = obj.animation_data.action
+ for fcu in action.fcurves:
+ keyframe_points = fcu.keyframe_points
+ i = 1
+ # remove unneeded keyframes
+ while i < len(keyframe_points) - 1:
+ val_prev = keyframe_points[i - 1].co[1]
+ val_next = keyframe_points[i + 1].co[1]
+ val = keyframe_points[i].co[1]
+
+ if abs(val - val_prev) + abs(val - val_next) < 0.0001:
+ keyframe_points.remove(keyframe_points[i])
+ else:
+ i += 1
+ # use linear interpolation for better visual results
+ for keyframe in keyframe_points:
+ keyframe.interpolation = 'LINEAR'
+
+ # return to the frame we started on
+ scene.frame_set(frame_orig)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ scene = context.scene
+ self.frame_start = scene.frame_start
+ self.frame_end = scene.frame_end
+
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self)
+
+
+class ConnectRigidBodies(Operator):
+ '''Create rigid body constraints between selected rigid bodies'''
+ bl_idname = "rigidbody.connect"
+ bl_label = "Connect Rigid Bodies"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ con_type = EnumProperty(
+ name="Type",
+ description="Type of generated constraint",
+ # XXX Would be nice to get icons too, but currently not possible ;)
+ items=tuple((e.identifier, e.name, e.description, e. value)
+ for e in bpy.types.RigidBodyConstraint.bl_rna.properties["type"].enum_items),
+ default='FIXED',)
+
+ pivot_type = EnumProperty(
+ name="Location",
+ description="Constraint pivot location",
+ items=(('CENTER', "Center", "Pivot location is between the constrained rigid bodies"),
+ ('ACTIVE', "Active", "Pivot location is at the active object position"),
+ ('SELECTED', "Selected", "Pivot location is at the selected object position")),
+ default='CENTER',)
+
+ connection_pattern = EnumProperty(
+ name="Connection Pattern",
+ description="Pattern used to connect objects",
+ items=(('SELECTED_TO_ACTIVE', "Selected to Active", "Connect selected objects to the active object"),
+ ('CHAIN_DISTANCE', "Chain by Distance", "Connect objects as a chain based on distance, starting at the active object")),
+ default='SELECTED_TO_ACTIVE',)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body)
+
+ def _add_constraint(self, context, object1, object2):
+ if object1 == object2:
+ return
+
+ if self.pivot_type == 'ACTIVE':
+ loc = object1.location
+ elif self.pivot_type == 'SELECTED':
+ loc = object2.location
+ else:
+ loc = (object1.location + object2.location) / 2.0
+
+ ob = bpy.data.objects.new("Constraint", object_data=None)
+ ob.location = loc
+ context.scene.objects.link(ob)
+ context.scene.objects.active = ob
+ ob.select = True
+
+ bpy.ops.rigidbody.constraint_add()
+ con_obj = context.active_object
+ con_obj.empty_draw_type = 'ARROWS'
+ con = con_obj.rigid_body_constraint
+ con.type = self.con_type
+
+ con.object1 = object1
+ con.object2 = object2
+
+ def execute(self, context):
+ scene = context.scene
+ objects = context.selected_objects
+ obj_act = context.active_object
+ change = False
+
+ if self.connection_pattern == 'CHAIN_DISTANCE':
+ objs_sorted = [obj_act]
+ objects_tmp = context.selected_objects
+ if obj_act.select:
+ objects_tmp.remove(obj_act)
+ objects_tmp.sort(key=lambda o: (obj_act.location - o.location).length)
+ last_obj = obj_act
+
+ while (len(objects_tmp)):
+ objects_tmp.sort(key=lambda o: (last_obj.location - o.location).length)
+ objs_sorted.append(objects_tmp[0])
+ last_obj = objects_tmp[0]
+ objects_tmp.remove(objects_tmp[0])
+
+ for i in range(1, len(objs_sorted)):
+ self._add_constraint(context, objs_sorted[i-1], objs_sorted[i])
+ change = True
+
+ else: # SELECTED_TO_ACTIVE
+ for obj in objects:
+ self._add_constraint(context, obj_act, obj)
+ change = True;
+
+ if change:
+ # restore selection
+ bpy.ops.object.select_all(action='DESELECT')
+ for obj in objects:
+ obj.select = True
+ scene.objects.active = obj_act
+ return {'FINISHED'}
+ else:
+ self.report({'WARNING'}, "No other objects selected")
+ return {'CANCELLED'}
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
index 727c4ad739f..ee3ae2878dc 100644
--- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py
+++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
@@ -26,17 +26,18 @@ from bpy.types import Operator
def extend(obj, operator, EXTEND_MODE):
+
import bmesh
me = obj.data
# script will fail without UVs
if not me.uv_textures:
me.uv_textures.new()
-
+
bm = bmesh.from_edit_mesh(me)
-
+
f_act = bm.faces.active
uv_act = bm.loops.layers.uv.active
-
+
if f_act is None:
operator.report({'ERROR'}, "No active face")
return
@@ -46,12 +47,17 @@ def extend(obj, operator, EXTEND_MODE):
faces = [f for f in bm.faces if f.select and len(f.verts) == 4]
- for f in faces:
- f.tag = False
- f_act.tag = True
-
-
# our own local walker
+ def walk_face_init(faces, f_act):
+ # first tag all faces True (so we dont uvmap them)
+ for f in bm.faces:
+ f.tag = True
+ # then tag faces arg False
+ for f in faces:
+ f.tag = False
+ # tag the active face True since we begin there
+ f_act.tag = True
+
def walk_face(f):
# all faces in this list must be tagged
f.tag = True
@@ -73,6 +79,29 @@ def extend(obj, operator, EXTEND_MODE):
faces_a, faces_b = faces_b, faces_a
faces_b.clear()
+ def walk_edgeloop(l):
+ """
+ Could make this a generic function
+ """
+ e_first = l.edge
+ e = None
+ while True:
+ e = l.edge
+ yield e
+
+ # don't step past non-manifold edges
+ if e.is_manifold:
+ # welk around the quad and then onto the next face
+ l = l.link_loop_radial_next
+ if len(l.face.verts) == 4:
+ l = l.link_loop_next.link_loop_next
+ if l.edge is e_first:
+ break
+ else:
+ break
+ else:
+ break
+
def extrapolate_uv(fac,
l_a_outer, l_a_inner,
l_b_outer, l_b_inner):
@@ -82,7 +111,7 @@ def extend(obj, operator, EXTEND_MODE):
def apply_uv(f_prev, l_prev, f_next):
l_a = [None, None, None, None]
l_b = [None, None, None, None]
-
+
l_a[0] = l_prev
l_a[1] = l_a[0].link_loop_next
l_a[2] = l_a[1].link_loop_next
@@ -103,7 +132,7 @@ def extend(obj, operator, EXTEND_MODE):
# +-----------+
# copy from this face to the one above.
- # get the other loops
+ # get the other loops
l_next = l_prev.link_loop_radial_next
if l_next.vert != l_prev.vert:
l_b[1] = l_next
@@ -119,7 +148,9 @@ def extend(obj, operator, EXTEND_MODE):
l_a_uv = [l[uv_act].uv for l in l_a]
l_b_uv = [l[uv_act].uv for l in l_b]
- if EXTEND_MODE == 'LENGTH':
+ if EXTEND_MODE == 'LENGTH_AVERAGE':
+ fac = edge_lengths[l_b[2].edge.index][0] / edge_lengths[l_a[1].edge.index][0]
+ elif EXTEND_MODE == 'LENGTH':
a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co
a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co
@@ -140,6 +171,40 @@ def extend(obj, operator, EXTEND_MODE):
l_a_uv[2], l_a_uv[1],
l_b_uv[2], l_b_uv[1])
+ # -------------------------------------------
+ # Calculate average length per loop if needed
+
+ if EXTEND_MODE == 'LENGTH_AVERAGE':
+ bm.edges.index_update()
+ edge_lengths = [None] * len(bm.edges)
+
+ for f in faces:
+ # we know its a quad
+ l_quad = f.loops[:]
+ l_pair_a = (l_quad[0], l_quad[2])
+ l_pair_b = (l_quad[1], l_quad[3])
+
+ for l_pair in (l_pair_a, l_pair_b):
+ if edge_lengths[l_pair[0].edge.index] is None:
+
+ edge_length_store = [-1.0]
+ edge_length_accum = 0.0
+ edge_length_total = 0
+
+ for l in l_pair:
+ if edge_lengths[l.edge.index] is None:
+ for e in walk_edgeloop(l):
+ if edge_lengths[e.index] is None:
+ edge_lengths[e.index] = edge_length_store
+ edge_length_accum += e.calc_length()
+ edge_length_total += 1
+
+ edge_length_store[0] = edge_length_accum / edge_length_total
+
+ # done with average length
+ # ------------------------
+
+ walk_face_init(faces, f_act)
for f_triple in walk_face(f_act):
apply_uv(*f_triple)
@@ -162,8 +227,10 @@ class FollowActiveQuads(Operator):
name="Edge Length Mode",
description="Method to space UV edge loops",
items=(('EVEN', "Even", "Space all UVs evenly"),
- ('LENGTH', "Length", "Average space UVs edge length of each loop")),
- default='LENGTH',
+ ('LENGTH', "Length", "Average space UVs edge length of each loop"),
+ ('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"),
+ ),
+ default='LENGTH_AVERAGE',
)
@classmethod
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 198b3660ff8..b24a71365b4 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -189,14 +189,14 @@ class prettyface(object):
def lightmap_uvpack(meshes,
- PREF_SEL_ONLY=True,
- PREF_NEW_UVLAYER=False,
- PREF_PACK_IN_ONE=False,
- PREF_APPLY_IMAGE=False,
- PREF_IMG_PX_SIZE=512,
- PREF_BOX_DIV=8,
- PREF_MARGIN_DIV=512
- ):
+ PREF_SEL_ONLY=True,
+ PREF_NEW_UVLAYER=False,
+ PREF_PACK_IN_ONE=False,
+ PREF_APPLY_IMAGE=False,
+ PREF_IMG_PX_SIZE=512,
+ PREF_BOX_DIV=8,
+ PREF_MARGIN_DIV=512
+ ):
"""
BOX_DIV if the maximum division of the UV map that
a box may be consolidated into.
@@ -516,7 +516,7 @@ def lightmap_uvpack(meshes,
def unwrap(operator, context, **kwargs):
- is_editmode = (bpy.context.object.mode == 'EDIT')
+ is_editmode = (context.object.mode == 'EDIT')
if is_editmode:
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
index bfbde2f4b07..e2a820b761a 100644
--- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py
+++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
@@ -127,13 +127,14 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
col[0] = tone * col[0]
col[1] = tone * col[1]
col[2] = tone * col[2]
-
+ me.update()
return {'FINISHED'}
import bpy
from bpy.types import Operator
from bpy.props import FloatProperty, IntProperty, BoolProperty
+from math import pi
class VertexPaintDirt(Operator):
@@ -156,14 +157,16 @@ class VertexPaintDirt(Operator):
clean_angle = FloatProperty(
name="Highlight Angle",
description="Less than 90 limits the angle used in the tonal range",
- min=0.0, max=180.0,
- default=180.0,
+ min=0.0, max=pi,
+ default=pi,
+ unit="ROTATION",
)
dirt_angle = FloatProperty(
name="Dirt Angle",
description="Less than 90 limits the angle used in the tonal range",
- min=0.0, max=180.0,
+ min=0.0, max=pi,
default=0.0,
+ unit="ROTATION",
)
dirt_only = BoolProperty(
name="Dirt Only",
@@ -171,20 +174,21 @@ class VertexPaintDirt(Operator):
default=False,
)
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.type == 'MESH')
+
def execute(self, context):
import time
from math import radians
- obj = context.object
-
- if not obj or obj.type != 'MESH':
- self.report({'ERROR'}, "Error, no active mesh object, aborting")
- return {'CANCELLED'}
+ obj = context.object
mesh = obj.data
t = time.time()
- ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, radians(self.dirt_angle), radians(self.clean_angle), self.dirt_only)
+ 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))
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 105b532ac38..b2f094e7ccc 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -35,6 +35,7 @@ class MESH_OT_delete_edgeloop(Operator):
"""to a single face loop"""
bl_idname = "mesh.delete_edgeloop"
bl_label = "Delete Edge Loop"
+ bl_options = {'UNDO', 'REGISTER'}
@classmethod
def poll(cls, context):
@@ -44,7 +45,7 @@ class MESH_OT_delete_edgeloop(Operator):
mesh = context.object.data
use_mirror_x = mesh.use_mirror_x
mesh.use_mirror_x = False
- if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0):
+ if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0, correct_uv=True):
bpy.ops.mesh.select_more()
bpy.ops.mesh.remove_doubles()
ret = {'FINISHED'}
@@ -500,18 +501,16 @@ class WM_MT_context_menu_enum(Menu):
def draw(self, context):
data_path = self.data_path
- value = context_path_validate(bpy.context, data_path)
+ value = context_path_validate(context, data_path)
if value is Ellipsis:
return {'PASS_THROUGH'}
base_path, prop_string = data_path.rsplit(".", 1)
value_base = context_path_validate(context, base_path)
+ prop = value_base.bl_rna.properties[prop_string]
- values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].enum_items]
-
- for name, identifier in values:
- props = self.layout.operator("wm.context_set_enum", text=name)
- props.data_path = data_path
- props.value = identifier
+ layout = self.layout
+ layout.label(prop.name, icon=prop.icon)
+ layout.prop(value_base, prop_string, expand=True)
class WM_OT_context_menu_enum(Operator):
@@ -821,25 +820,42 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""):
elif len(id_split) == 2: # rna, class.prop
class_name, class_prop = id_split
+ # an operator (common case - just button referencing an op)
if hasattr(bpy.types, class_name.upper() + "_OT_" + class_prop):
if do_url:
url = ("%s/bpy.ops.%s.html#bpy.ops.%s.%s" % (url_prefix, class_name, class_name, class_prop))
else:
rna = "bpy.ops.%s.%s" % (class_name, class_prop)
else:
+ rna_class = getattr(bpy.types, class_name)
+
+ # an operator setting (selected from a running operator), rare case
+ # note: Py defined operators are subclass of Operator,
+ # C defined operators are subclass of OperatorProperties.
+ # we may need to check on this at some point.
+ if issubclass(rna_class, (bpy.types.Operator, bpy.types.OperatorProperties)):
+ # note: ignore the prop name since we don't have a way to link into it
+ class_name, class_prop = class_name.split("_OT_", 1)
+ class_name = class_name.lower()
+ if do_url:
+ url = ("%s/bpy.ops.%s.html#bpy.ops.%s.%s" % (url_prefix, class_name, class_name, class_prop))
+ else:
+ rna = "bpy.ops.%s.%s" % (class_name, class_prop)
+ else:
+ # an RNA setting, common case
- # detect if this is a inherited member and use that name instead
- rna_parent = getattr(bpy.types, class_name).bl_rna
- rna_prop = rna_parent.properties[class_prop]
- rna_parent = rna_parent.base
- while rna_parent and rna_prop == rna_parent.properties.get(class_prop):
- class_name = rna_parent.identifier
+ # detect if this is a inherited member and use that name instead
+ rna_parent = rna_class.bl_rna
+ rna_prop = rna_parent.properties[class_prop]
rna_parent = rna_parent.base
+ while rna_parent and rna_prop == rna_parent.properties.get(class_prop):
+ class_name = rna_parent.identifier
+ rna_parent = rna_parent.base
- if do_url:
- url = ("%s/bpy.types.%s.html#bpy.types.%s.%s" % (url_prefix, class_name, class_name, class_prop))
- else:
- rna = ("bpy.types.%s.%s" % (class_name, class_prop))
+ if do_url:
+ url = ("%s/bpy.types.%s.html#bpy.types.%s.%s" % (url_prefix, class_name, class_name, class_prop))
+ else:
+ rna = ("bpy.types.%s.%s" % (class_name, class_prop))
return url if do_url else rna
@@ -1255,13 +1271,6 @@ class WM_OT_copy_prev_settings(Operator):
else:
shutil.copytree(path_src, path_dst, symlinks=True)
- # in 2.57 and earlier windows installers, system scripts were copied
- # into the configuration directory, don't want to copy those
- system_script = os.path.join(path_dst, "scripts/modules/bpy_types.py")
- if os.path.isfile(system_script):
- shutil.rmtree(os.path.join(path_dst, "scripts"))
- shutil.rmtree(os.path.join(path_dst, "plugins"))
-
# don't loose users work if they open the splash later.
if bpy.data.is_saved is bpy.data.is_dirty is False:
bpy.ops.wm.read_homefile()
@@ -1596,7 +1605,7 @@ class WM_OT_addon_enable(Operator):
"version %d.%d.%d and might not "
"function (correctly), "
"though it is enabled") %
- info_ver)
+ info_ver)
return {'FINISHED'}
else:
return {'CANCELLED'}
@@ -1620,7 +1629,7 @@ class WM_OT_addon_disable(Operator):
class WM_OT_theme_install(Operator):
- "Install a theme"
+ "Load and apply a Blender XML theme file"
bl_idname = "wm.theme_install"
bl_label = "Install Theme..."
@@ -1739,7 +1748,7 @@ class WM_OT_addon_install(Operator):
# don't use bpy.utils.script_paths("addons") because we may not be able to write to it.
path_addons = bpy.utils.user_resource('SCRIPTS', "addons", create=True)
else:
- path_addons = bpy.context.user_preferences.filepaths.script_directory
+ path_addons = context.user_preferences.filepaths.script_directory
if path_addons:
path_addons = os.path.join(path_addons, "addons")
@@ -1748,8 +1757,7 @@ class WM_OT_addon_install(Operator):
return {'CANCELLED'}
# create dir is if missing.
- if not os.path.exists(path_addons):
- os.makedirs(path_addons)
+ os.makedirs(path_addons, exist_ok=True)
# Check if we are installing from a target path,
# doing so causes 2+ addons of same name or when the same from/to
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index e4be84d5396..09813d8b1c2 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -48,6 +48,8 @@ _modules = (
"properties_physics_dynamicpaint",
"properties_physics_field",
"properties_physics_fluid",
+ "properties_physics_rigidbody",
+ "properties_physics_rigidbody_constraint",
"properties_physics_smoke",
"properties_physics_softbody",
"properties_render",
@@ -132,3 +134,11 @@ def register():
def unregister():
bpy.utils.unregister_module(__name__)
+
+
+# Define a default UIList, when a list does not need any custom drawing...
+# Keep in sync with its #defined name in UI_interface.h
+class UI_UL_list(bpy.types.UIList):
+ pass
+
+bpy.utils.register_class(UI_UL_list)
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 845beb0f862..74f33170384 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -124,7 +124,7 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
rows = 2
if group:
rows = 5
- row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
+ row.template_list("UI_UL_list", "bone_groups", pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
col = row.column(align=True)
col.active = (ob.proxy is None)
@@ -184,7 +184,8 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
if poselib:
# list of poses in pose library
row = layout.row()
- row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
+ row.template_list("UI_UL_list", "pose_markers", poselib, "pose_markers",
+ poselib.pose_markers, "active_index", rows=5)
# column of operators for active pose
# - goes beside list
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index fdaee6b7cde..a8954a1c33e 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -170,6 +170,8 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
if ob and pchan:
col.label(text="Bone Group:")
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="")
+ col.label(text="Object Children:")
+ col.prop(bone, "use_relative_parent")
col = split.column()
col.label(text="Parent:")
@@ -181,11 +183,11 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
sub = col.column()
sub.active = (bone.parent is not None)
sub.prop(bone, "use_connect")
- sub.prop(bone, "use_inherit_rotation", text="Inherit Rotation")
- sub.prop(bone, "use_inherit_scale", text="Inherit Scale")
+ sub.prop(bone, "use_inherit_rotation")
+ sub.prop(bone, "use_inherit_scale")
sub = col.column()
sub.active = (not bone.parent or not bone.use_connect)
- sub.prop(bone, "use_local_location", text="Local Location")
+ sub.prop(bone, "use_local_location")
class BONE_PT_display(BoneButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 25cecc90c70..c74560e14ac 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -80,7 +80,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
row = col.row()
if cam.lens_unit == 'MILLIMETERS':
row.prop(cam, "lens")
- elif cam.lens_unit == 'DEGREES':
+ elif cam.lens_unit == 'FOV':
row.prop(cam, "angle")
row.prop(cam, "lens_unit", text="")
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 6125540d491..86a48999663 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel
@@ -34,10 +34,11 @@ class MESH_MT_vertex_group_specials(Menu):
layout.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA')
layout.operator("object.vertex_group_copy_to_selected", icon='LINK_AREA')
layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT')
- layout.operator("object.vertex_group_remove", icon='X', text="Delete All").all = True
+ layout.operator("object.vertex_group_remove", icon='X', text="Delete All Vertex Groups").all = True
+ layout.operator("object.vertex_group_remove_from", icon='X', text="Remove Selected from All Vertex Groups").all = True
layout.separator()
- layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All").action = 'SELECT'
- layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All").action = 'DESELECT'
+ layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All").action = 'LOCK'
+ layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All").action = 'UNLOCK'
layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Invert All").action = 'INVERT'
@@ -54,6 +55,53 @@ class MESH_MT_shape_key_specials(Menu):
layout.operator("object.shape_key_add", icon='ZOOMIN', text="New Shape From Mix").from_mix = True
+class MESH_UL_vgroups(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.VertexGroup)
+ vgroup = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(text=vgroup.name, translate=False, icon_value=icon)
+ icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
+ layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
+class MESH_UL_shape_keys(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.ShapeKey)
+ obj = active_data
+ key = data
+ key_block = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ split = layout.split(0.66, False)
+ split.label(text=item.name, translate=False, icon_value=icon)
+ row = split.row(True)
+ if key_block.mute or (obj.mode == 'EDIT' and not (obj.use_shape_key_edit_mode and obj.type == 'MESH')):
+ row.active = False
+ if not item.relative_key or index > 0:
+ row.prop(key_block, "value", text="", emboss=False)
+ else:
+ row.label(text="")
+ row.prop(key_block, "mute", text="", emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
+class MESH_UL_uvmaps_vcols(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, (bpy.types.MeshTexturePolyLayer, bpy.types.MeshLoopColorLayer))
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(text=item.name, translate=False, icon_value=icon)
+ icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON'
+ layout.prop(item, "active_render", text="", icon=icon, emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
class MeshButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -144,7 +192,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
rows = 5
row = layout.row()
- row.template_list(ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
+ row.template_list("MESH_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
col = row.column(align=True)
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
@@ -202,7 +250,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
rows = 2
if kb:
rows = 5
- row.template_list(key, "key_blocks", ob, "active_shape_key_index", rows=rows)
+ row.template_list("MESH_UL_shape_keys", "", key, "key_blocks", ob, "active_shape_key_index", rows=rows)
col = row.column()
@@ -282,7 +330,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(me, "uv_textures", me.uv_textures, "active_index", rows=2)
+ col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_textures", me.uv_textures, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
@@ -305,7 +353,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
+ col.template_list("MESH_UL_uvmaps_vcols", "vcols", me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")
@@ -324,17 +372,20 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- # me = context.mesh
+ obj = context.object
+ me = context.mesh
col = layout.column()
- # sticky has no UI access since 2.49 - we may remove
- '''
- row = col.row(align=True)
- row.operator("mesh.customdata_create_sticky")
- row.operator("mesh.customdata_clear_sticky", icon='X')
- '''
+
col.operator("mesh.customdata_clear_mask", icon='X')
col.operator("mesh.customdata_clear_skin", icon='X')
+ col = layout.column()
+
+ col.enabled = (obj.mode != 'EDIT')
+ col.prop(me, "use_customdata_vertex_bevel")
+ col.prop(me, "use_customdata_edge_bevel")
+ col.prop(me, "use_customdata_edge_crease")
+
class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 62461d800f6..05e189c86be 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Panel
+from bpy.app.translations import pgettext_iface as iface_
class ModifierButtonsPanel():
@@ -123,20 +124,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
split.prop(md, "width")
split.prop(md, "use_only_vertices")
- # -- new modifier only, this may be reverted in favor of 2.62 mod.
- '''
- split = layout.split()
- split.prop(md, "use_even_offset")
- split.prop(md, "use_distance_offset")
- '''
- # -- end
+ layout.prop(md, "segments")
layout.label(text="Limit Method:")
layout.row().prop(md, "limit_method", expand=True)
if md.limit_method == 'ANGLE':
layout.prop(md, "angle_limit")
- elif md.limit_method == 'WEIGHT':
- layout.row().prop(md, "edge_weight_method", expand=True)
+ elif md.limit_method == 'VGROUP':
+ layout.label(text="Vertex Group:")
+ layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+ # elif md.limit_method == 'WEIGHT':
+ # layout.row().prop(md, "edge_weight_method", expand=True)
def BOOLEAN(self, layout, ob, md):
split = layout.split()
@@ -162,6 +160,44 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
sub.active = md.use_random_order
sub.prop(md, "seed")
+ def MESH_CACHE(self, layout, ob, md):
+ layout.prop(md, "cache_format")
+ layout.prop(md, "filepath")
+
+ layout.label(text="Evaluation:")
+ layout.prop(md, "factor", slider=True)
+ layout.prop(md, "deform_mode")
+ layout.prop(md, "interpolation")
+
+ layout.label(text="Time Mapping:")
+
+ row = layout.row()
+ row.prop(md, "time_mode", expand=True)
+ row = layout.row()
+ row.prop(md, "play_mode", expand=True)
+ if md.play_mode == 'SCENE':
+ layout.prop(md, "frame_start")
+ layout.prop(md, "frame_scale")
+ else:
+ time_mode = md.time_mode
+ if time_mode == 'FRAME':
+ layout.prop(md, "eval_frame")
+ elif time_mode == 'TIME':
+ layout.prop(md, "eval_time")
+ elif time_mode == 'FACTOR':
+ layout.prop(md, "eval_factor")
+
+ layout.label(text="Axis Mapping:")
+ split = layout.split(percentage=0.5, align=True)
+ split.alert = (md.forward_axis[-1] == md.up_axis[-1])
+ split.label("Forward/Up Axis:")
+ split.prop(md, "forward_axis", text="")
+ split.prop(md, "up_axis", text="")
+ split = layout.split(percentage=0.5)
+ split.label(text="Flip Axis:")
+ row = split.row()
+ row.prop(md, "flip_axis")
+
def CAST(self, layout, ob, md):
split = layout.split(percentage=0.25)
@@ -227,7 +263,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.prop(md, "angle_limit")
layout.prop(md, "use_dissolve_boundaries")
- layout.label(text="Face Count" + ": %d" % md.face_count)
+ layout.label(text=iface_("Face Count: %d") % md.face_count, translate=False)
def DISPLACE(self, layout, ob, md):
has_texture = (md.texture is not None)
@@ -333,23 +369,24 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
def LAPLACIANSMOOTH(self, layout, ob, md):
layout.prop(md, "iterations")
-
+
split = layout.split(percentage=0.25)
-
+
col = split.column()
col.label(text="Axis:")
col.prop(md, "use_x")
col.prop(md, "use_y")
col.prop(md, "use_z")
-
+
col = split.column()
col.label(text="Lambda:")
col.prop(md, "lambda_factor", text="Factor")
col.prop(md, "lambda_border", text="Border")
-
+
col.separator()
col.prop(md, "use_volume_preserve")
-
+ col.prop(md, "use_normalized")
+
layout.label(text="Vertex Group:")
layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
@@ -489,11 +526,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.prop(md, "time")
- col.prop(md, "resolution")
+ col.prop(md, "depth")
+ col.prop(md, "random_seed")
col = split.column()
+ col.prop(md, "resolution")
+ col.prop(md, "size")
col.prop(md, "spatial_size")
- col.prop(md, "depth")
layout.label("Waves:")
@@ -534,7 +573,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
if md.is_cached:
layout.operator("object.ocean_bake", text="Free Bake").free = True
else:
- layout.operator("object.ocean_bake")
+ layout.operator("object.ocean_bake").free = False
split = layout.split()
split.enabled = not md.is_cached
@@ -547,7 +586,14 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.label(text="Cache path:")
col.prop(md, "filepath", text="")
- #col.prop(md, "bake_foam_fade")
+ split = layout.split()
+ split.enabled = not md.is_cached
+
+ col = split.column()
+ col.active = md.use_foam
+ col.prop(md, "bake_foam_fade")
+
+ col = split.column()
def PARTICLE_INSTANCE(self, layout, ob, md):
layout.prop(md, "object")
@@ -1032,5 +1078,47 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
def TRIANGULATE(self, layout, ob, md):
layout.prop(md, "use_beauty")
+ def UV_WARP(self, layout, ob, md):
+ split = layout.split()
+ col = split.column()
+ col.prop(md, "center")
+
+ col = split.column()
+ col.label(text="UV Axis:")
+ col.prop(md, "axis_u", text="")
+ col.prop(md, "axis_v", text="")
+
+ split = layout.split()
+ col = split.column()
+ col.label(text="From:")
+ col.prop(md, "object_from", text="")
+
+ col = split.column()
+ col.label(text="To:")
+ col.prop(md, "object_to", text="")
+
+ split = layout.split()
+ col = split.column()
+ obj = md.object_from
+ if obj and obj.type == 'ARMATURE':
+ col.label(text="Bone:")
+ col.prop_search(md, "bone_from", obj.data, "bones", text="")
+
+ col = split.column()
+ obj = md.object_to
+ if obj and obj.type == 'ARMATURE':
+ col.label(text="Bone:")
+ col.prop_search(md, "bone_to", obj.data, "bones", text="")
+
+ split = layout.split()
+
+ col = split.column()
+ col.label(text="Vertex Group:")
+ col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
+ col = split.column()
+ col.label(text="UV Map:")
+ col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index bf0c9eb762a..1f05c8eea5a 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -199,6 +199,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
col = split.column()
col.prop(game, "collision_mask")
+
class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
bl_label = "Collision Bounds"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -402,13 +403,18 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
layout = self.layout
gs = context.scene.game_settings
+ col = layout.column()
+ row = col.row()
+ col = row.column()
+ col.prop(gs, "use_frame_rate")
+ col.prop(gs, "restrict_animation_updates")
+ col.prop(gs, "use_material_caching")
+ col = row.column()
+ col.prop(gs, "use_display_lists")
+ col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
row = layout.row()
- row.prop(gs, "use_frame_rate")
- row.prop(gs, "restrict_animation_updates")
-
- row = layout.row()
- row.prop(gs, "use_display_lists")
+ row.prop(gs, "raster_storage")
row = layout.row()
row.label("Exit Key")
@@ -615,7 +621,9 @@ class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
layout.prop(gs, "physics_engine")
if gs.physics_engine != 'NONE':
- layout.prop(gs, "physics_gravity", text="Gravity")
+ col = layout.column()
+ col.prop(gs, "physics_gravity", text="Gravity")
+ col.prop(gs, "occlusion_culling_resolution", text="Culling Resolution")
split = layout.split()
@@ -638,12 +646,6 @@ class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
sub = col.row()
sub.prop(gs, "deactivation_time", text="Time")
- col = layout.column()
- col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
- sub = col.column()
- sub.active = gs.use_occlusion_culling
- sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
-
else:
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index 208b0a63075..4ceaffbaf8d 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -22,7 +22,25 @@
# menus are referenced `as is`
import bpy
-from bpy.types import Menu
+from bpy.types import Menu, UIList
+
+
+class MASK_UL_layers(UIList):
+ def draw_item(self, context, layout, data, item, icon,
+ active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MaskLayer)
+ mask = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ split = layout.split()
+ split.label(text=mask.name, translate=False, icon_value=icon)
+ row = split.row(align=True)
+ row.prop(mask, "alpha", text="", emboss=False)
+ row.prop(mask, "hide", text="", emboss=False)
+ row.prop(mask, "hide_select", text="", emboss=False)
+ row.prop(mask, "hide_render", text="", emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
class MASK_PT_mask:
@@ -69,7 +87,7 @@ class MASK_PT_layers:
rows = 5 if active_layer else 2
row = layout.row()
- row.template_list(mask, "layers",
+ row.template_list("MASK_UL_layers", "", mask, "layers",
mask, "active_layer_index", rows=rows)
sub = row.column(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 951644db752..9a3957fe353 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -18,8 +18,9 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel
+from bpy.app.translations import pgettext_iface as iface_
def active_node_mat(mat):
@@ -69,6 +70,25 @@ class MATERIAL_MT_specials(Menu):
layout.operator("material.paste", icon='PASTEDOWN')
+class MATERIAL_UL_matslots(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MaterialSlot)
+ ob = data
+ slot = item
+ ma = slot.material
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(text=ma.name if ma else "", translate=False, icon_value=icon)
+ if ma and not context.scene.render.use_shading_nodes:
+ manode = ma.active_node_material
+ if manode:
+ layout.label(text=iface_("Node %s") % manode.name, translate=False, icon_value=layout.icon(manode))
+ elif ma.use_nodes:
+ layout.label(text="Node <none>")
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
class MaterialButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -104,7 +124,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
if ob:
row = layout.row()
- row.template_list(ob, "material_slots", ob, "active_material_index", rows=2)
+ row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=2)
col = row.column(align=True)
col.operator("object.material_slot_add", icon='ZOOMIN', text="")
@@ -544,7 +564,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel, Panel):
row.prop(halo, toggle, text="")
sub = row.column()
sub.active = getattr(halo, toggle)
- sub.prop(halo, number, text=name)
+ sub.prop(halo, number, text=name, translate=False)
if not color == "":
sub.prop(mat, color, text="")
@@ -571,9 +591,9 @@ class MATERIAL_PT_halo(MaterialButtonsPanel, Panel):
col.prop(halo, "use_soft")
col = split.column()
- number_but(col, "use_ring", "ring_count", "Rings", "mirror_color")
- number_but(col, "use_lines", "line_count", "Lines", "specular_color")
- number_but(col, "use_star", "star_tip_count", "Star tips", "")
+ number_but(col, "use_ring", "ring_count", iface_("Rings"), "mirror_color")
+ number_but(col, "use_lines", "line_count", iface_("Lines"), "specular_color")
+ number_but(col, "use_star", "star_tip_count", iface_("Star Tips"), "")
class MATERIAL_PT_flare(MaterialButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 8a668b5d95b..b9dcdc19162 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -230,6 +230,7 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel):
col.prop(ob, "show_x_ray", text="X-Ray")
if ob.type == 'MESH':
col.prop(ob, "show_transparent", text="Transparency")
+ col.prop(ob, "show_all_edges")
class OBJECT_PT_duplication(ObjectButtonsPanel, Panel):
@@ -289,6 +290,9 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
row.active = ((ob.parent is not None) and (ob.use_slow_parent))
row.prop(ob, "slow_parent_offset", text="Offset")
+ layout.prop(ob, "extra_recalc_object")
+ layout.prop(ob, "extra_recalc_data")
+
from bl_ui.properties_animviz import (MotionPathButtonsPanel,
OnionSkinButtonsPanel)
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py
index eb0929895f8..6478e49f464 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_object_constraint.py
@@ -172,7 +172,6 @@ class ConstraintButtonsPanel():
sub.active = con.use_rotation
sub.prop(con, "orient_weight", text="Rotation", slider=True)
-
def IK_COPY_POSE(self, context, layout, con):
self.target_template(layout, con)
self.ik_template(layout, con)
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 53cf640beb9..7c06aefe575 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -70,34 +70,40 @@ class UnifiedPaintPanel():
# Used in both the View3D toolbar and texture properties
-def sculpt_brush_texture_settings(layout, brush):
+def brush_texture_settings(layout, brush, sculpt):
tex_slot = brush.texture_slot
layout.label(text="Brush Mapping:")
# map_mode
- layout.row().prop(tex_slot, "map_mode", text="")
- layout.separator()
-
- # angle and texture_angle_source
- col = layout.column()
- col.active = brush.sculpt_capabilities.has_texture_angle_source
- col.label(text="Angle:")
- if brush.sculpt_capabilities.has_random_texture_angle:
- col.prop(brush, "texture_angle_source_random", text="")
+ if sculpt:
+ layout.row().prop(tex_slot, "map_mode", text="")
+ layout.separator()
else:
- col.prop(brush, "texture_angle_source_no_random", text="")
+ layout.row().prop(tex_slot, "tex_paint_map_mode", text="")
+ layout.separator()
+ # angle and texture_angle_source
col = layout.column()
- col.active = brush.sculpt_capabilities.has_texture_angle
- col.prop(tex_slot, "angle", text="")
+ if sculpt:
+ col.active = brush.sculpt_capabilities.has_texture_angle_source
+ col.label(text="Angle:")
+ if brush.sculpt_capabilities.has_random_texture_angle:
+ col.prop(brush, "texture_angle_source_random", text="")
+ else:
+ col.prop(brush, "texture_angle_source_no_random", text="")
+
+ col = layout.column()
+ col.active = brush.sculpt_capabilities.has_texture_angle
+ col.prop(tex_slot, "angle", text="")
# scale and offset
split = layout.split()
split.prop(tex_slot, "offset")
split.prop(tex_slot, "scale")
- # texture_sample_bias
- col = layout.column(align=True)
- col.label(text="Sample Bias:")
- col.prop(brush, "texture_sample_bias", slider=True, text="")
+ if sculpt:
+ # texture_sample_bias
+ col = layout.column(align=True)
+ col.label(text="Sample Bias:")
+ col.prop(brush, "texture_sample_bias", slider=True, text="")
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 3f672d2a977..f6784cbbaa3 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -20,6 +20,7 @@
import bpy
from bpy.types import Panel
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,
@@ -96,7 +97,8 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
if ob:
row = layout.row()
- row.template_list(ob, "particle_systems", ob.particle_systems, "active_index", rows=2)
+ row.template_list("UI_UL_list", "particle_systems", ob, "particle_systems",
+ ob.particle_systems, "active_index", rows=2)
col = row.column(align=True)
col.operator("object.particle_system_add", icon='ZOOMIN', text="")
@@ -148,7 +150,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
#row.label(text="Render")
if part.is_fluid:
- layout.label(text="%d fluid particles for this frame" % part.count)
+ layout.label(text=iface_("%d fluid particles for this frame") % part.count, translate=False)
return
row = col.row()
@@ -490,11 +492,13 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
col.prop(part, "integrator", text="")
col.prop(part, "timestep")
sub = col.row()
- if part.adaptive_subframes:
- sub.prop(part, "courant_target", text="Threshold")
- else:
- sub.prop(part, "subframes")
- sub.prop(part, "adaptive_subframes", text="")
+ sub.prop(part, "subframes")
+ supports_courant = part.physics_type == 'FLUID'
+ subsub = sub.row()
+ subsub.enabled = supports_courant
+ subsub.prop(part, "adaptive_subframes", text="")
+ if supports_courant and part.adaptive_subframes:
+ col.prop(part, "courant_target", text="Threshold")
row = layout.row()
row.prop(part, "use_size_deflect")
@@ -504,6 +508,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
fluid = part.fluid
split = layout.split()
+ sub = split.row()
+ sub.prop(fluid, "solver", expand=True)
+
+ split = layout.split()
col = split.column()
col.label(text="Fluid properties:")
@@ -514,13 +522,14 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
col = split.column()
col.label(text="Advanced:")
- sub = col.row()
- sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
- sub.prop(fluid, "factor_repulsion", text="")
+ if fluid.solver == 'DDR':
+ sub = col.row()
+ sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
+ sub.prop(fluid, "factor_repulsion", text="")
- sub = col.row()
- sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
- sub.prop(fluid, "factor_stiff_viscosity", text="")
+ sub = col.row()
+ sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
+ sub.prop(fluid, "factor_stiff_viscosity", text="")
sub = col.row()
sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius)
@@ -530,27 +539,37 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
sub.prop(fluid, "rest_density", slider=fluid.factor_density)
sub.prop(fluid, "factor_density", text="")
- split = layout.split()
-
- col = split.column()
- col.label(text="Springs:")
- col.prop(fluid, "spring_force", text="Force")
- col.prop(fluid, "use_viscoelastic_springs")
- sub = col.column(align=True)
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "yield_ratio", slider=True)
- sub.prop(fluid, "plasticity", slider=True)
-
- col = split.column()
- col.label(text="Advanced:")
- sub = col.row()
- sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
- sub.prop(fluid, "factor_rest_length", text="")
- col.label(text="")
- sub = col.column()
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "use_initial_rest_length")
- sub.prop(fluid, "spring_frames", text="Frames")
+ if fluid.solver == 'CLASSICAL':
+ # With the classical solver, it is possible to calculate the
+ # spacing between particles when the fluid is at rest. This
+ # makes it easier to set stable initial conditions.
+ particle_volume = part.mass / fluid.rest_density
+ spacing = pow(particle_volume, 1.0 / 3.0)
+ sub = col.row()
+ sub.label(text="Spacing: %g" % spacing)
+
+ elif fluid.solver == 'DDR':
+ split = layout.split()
+
+ col = split.column()
+ col.label(text="Springs:")
+ col.prop(fluid, "spring_force", text="Force")
+ col.prop(fluid, "use_viscoelastic_springs")
+ sub = col.column(align=True)
+ sub.active = fluid.use_viscoelastic_springs
+ sub.prop(fluid, "yield_ratio", slider=True)
+ sub.prop(fluid, "plasticity", slider=True)
+
+ col = split.column()
+ col.label(text="Advanced:")
+ sub = col.row()
+ sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
+ sub.prop(fluid, "factor_rest_length", text="")
+ col.label(text="")
+ sub = col.column()
+ sub.active = fluid.use_viscoelastic_springs
+ sub.prop(fluid, "use_initial_rest_length")
+ sub.prop(fluid, "spring_frames", text="Frames")
elif part.physics_type == 'KEYED':
split = layout.split()
@@ -619,7 +638,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
layout.label(text="Fluid interaction:")
row = layout.row()
- row.template_list(psys, "targets", psys, "active_particle_target_index")
+ row.template_list("UI_UL_list", "particle_targets", psys, "targets", psys, "active_particle_target_index")
col = row.column()
sub = col.row()
@@ -685,7 +704,8 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
# Currently boids can only use the first state so these are commented out for now.
#row = layout.row()
- #row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
+ #row.template_list("UI_UL_list", "particle_boids", boids, "states",
+ # boids, "active_boid_state_index", compact="True")
#col = row.row()
#sub = col.row(align=True)
#sub.operator("boid.state_add", icon='ZOOMIN', text="")
@@ -706,7 +726,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
row.label(text="")
row = layout.row()
- row.template_list(state, "rules", state, "active_boid_rule_index")
+ row.template_list("UI_UL_list", "particle_boids_rules", state, "rules", state, "active_boid_rule_index")
col = row.column()
sub = col.row()
@@ -869,7 +889,8 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
if part.use_group_count and not part.use_whole_group:
row = layout.row()
- row.template_list(part, "dupli_weights", part, "active_dupliweight_index")
+ row.template_list("UI_UL_list", "particle_dupli_weights", part, "dupli_weights",
+ part, "active_dupliweight_index")
col = row.column()
sub = col.row()
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index 5a44294f0e0..91b4cc0ae49 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -91,7 +91,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
sub.prop(cloth, "pin_stiffness", text="Stiffness")
col.label(text="Pre roll:")
- col.prop(cloth, "pre_roll", text="Frame")
+ col.prop(cloth, "pre_roll", text="Frames")
# Disabled for now
"""
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index 405e877d1e2..2d9d4649e28 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -21,6 +21,8 @@
import bpy
from bpy.types import Panel
+i18n_default_ctxt = bpy.app.translations.contexts.default
+
class PhysicButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -37,12 +39,20 @@ def physics_add(self, layout, md, name, type, typeicon, toggles):
sub = layout.row(align=True)
if md:
sub.context_pointer_set("modifier", md)
- sub.operator("object.modifier_remove", text=name, icon='X')
+ sub.operator("object.modifier_remove", text=name, text_ctxt=i18n_default_ctxt, icon='X')
if(toggles):
sub.prop(md, "show_render", text="")
sub.prop(md, "show_viewport", text="")
else:
- sub.operator("object.modifier_add", text=name, icon=typeicon).type = type
+ sub.operator("object.modifier_add", text=name, text_ctxt=i18n_default_ctxt, icon=typeicon).type = type
+
+
+def physics_add_special(self, layout, data, name, addop, removeop, typeicon):
+ sub = layout.row(align=True)
+ if data:
+ sub.operator(removeop, text=name, text_ctxt=i18n_default_ctxt, icon='X')
+ else:
+ sub.operator(addop, text=name, text_ctxt=i18n_default_ctxt, icon=typeicon)
class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
@@ -76,6 +86,18 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
physics_add(self, col, context.fluid, "Fluid", 'FLUID_SIMULATION', 'MOD_FLUIDSIM', True)
physics_add(self, col, context.smoke, "Smoke", 'SMOKE', 'MOD_SMOKE', True)
+ if(ob.type == 'MESH'):
+ physics_add_special(self, col, ob.rigid_body, "Rigid Body",
+ "rigidbody.object_add",
+ "rigidbody.object_remove",
+ 'MESH_ICOSPHERE') # XXX: need dedicated icon
+
+ # all types of objects can have rigid body constraint
+ physics_add_special(self, col, ob.rigid_body_constraint, "Rigid Body Constraint",
+ "rigidbody.constraint_add",
+ "rigidbody.constraint_remove",
+ 'CONSTRAINT') # RB_TODO needs better icon
+
# cache-type can be 'PSYS' 'HAIR' 'SMOKE' etc
@@ -84,11 +106,13 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
layout.context_pointer_set("point_cache", cache)
- row = layout.row()
- row.template_list(cache, "point_caches", cache.point_caches, "active_index", rows=2)
- col = row.column(align=True)
- col.operator("ptcache.add", icon='ZOOMIN', text="")
- col.operator("ptcache.remove", icon='ZOOMOUT', text="")
+ if not cachetype == 'RIGID_BODY':
+ row = layout.row()
+ row.template_list("UI_UL_list", "point_caches", cache, "point_caches",
+ cache.point_caches, "active_index", rows=2)
+ col = row.column(align=True)
+ col.operator("ptcache.add", icon='ZOOMIN', text="")
+ col.operator("ptcache.remove", icon='ZOOMOUT', text="")
row = layout.row()
if cachetype in {'PSYS', 'HAIR', 'SMOKE'}:
@@ -131,13 +155,13 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
row.enabled = enabled
row.prop(cache, "frame_start")
row.prop(cache, "frame_end")
- if cachetype not in {'SMOKE', 'CLOTH', 'DYNAMIC_PAINT'}:
+ if cachetype not in {'SMOKE', 'CLOTH', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
row.prop(cache, "frame_step")
-
+
if cachetype != 'SMOKE':
layout.label(text=cache.info)
- if cachetype not in {'SMOKE', 'DYNAMIC_PAINT'}:
+ if cachetype not in {'SMOKE', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
split = layout.split()
split.enabled = enabled and bpy.data.is_saved
diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
index 1df2936b2d4..7ee63ee7a2f 100644
--- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
@@ -18,13 +18,34 @@
# <pep8 compliant>
import bpy
-from bpy.types import Panel
+from bpy.types import Panel, UIList
from bl_ui.properties_physics_common import (point_cache_ui,
effector_weights_ui,
)
+class PHYSICS_UL_dynapaint_surfaces(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.DynamicPaintSurface)
+ surf = item
+ sticon = layout.enum_item_icon(surf, "surface_type", surf.surface_type)
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ row = layout.row(align=True)
+ row.label(text="", icon_value=icon)
+ row.label(text=surf.name, translate=False, icon_value=sticon)
+ row = layout.row(align=True)
+ if surf.use_color_preview:
+ row.prop(surf, "show_preview", text="", emboss=False,
+ icon='RESTRICT_VIEW_OFF' if surf.show_preview else 'RESTRICT_VIEW_ON')
+ row.prop(surf, "is_active", text="")
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ row = layout.row(align=True)
+ row.label(text="", icon_value=icon)
+ row.label(text="", icon_value=sticon)
+
+
class PhysicButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -58,7 +79,8 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
surface = canvas.canvas_surfaces.active
row = layout.row()
- row.template_list(canvas, "canvas_surfaces", canvas.canvas_surfaces, "active_index", rows=2)
+ row.template_list("PHYSICS_UL_dynapaint_surfaces", "", canvas, "canvas_surfaces",
+ canvas.canvas_surfaces, "active_index", rows=2)
col = row.column(align=True)
col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py
index 08278c02693..2164b86f486 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fluid.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Panel, Menu
+from bpy.app.translations import pgettext_iface as iface_
class FLUID_MT_presets(Menu):
@@ -64,7 +65,8 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
if fluid.type == 'DOMAIN':
# odd formatting here so translation script can extract string
- layout.operator("fluid.bake", text="Bake (Req. Memory:" + " %s)" % fluid.memory_estimate, icon='MOD_FLUIDSIM')
+ layout.operator("fluid.bake", text=iface_("Bake (Req. Memory: %s)") % fluid.memory_estimate,
+ translate=False, icon='MOD_FLUIDSIM')
split = layout.split()
col = split.column()
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
new file mode 100644
index 00000000000..d7ed7bb4d1a
--- /dev/null
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
@@ -0,0 +1,132 @@
+# ##### 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 #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Panel
+
+
+class PHYSICS_PT_rigidbody_panel():
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "physics"
+
+
+class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel):
+ bl_label = "Rigid Body"
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body and
+ (not context.scene.render.use_game_engine))
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ rbo = ob.rigid_body
+
+ if rbo is not None:
+ layout.prop(rbo, "type", text="Type")
+ row = layout.row()
+ if rbo.type == 'ACTIVE':
+ row.prop(rbo, "enabled", text="Dynamic")
+ row.prop(rbo, "kinematic", text="Animated")
+
+ if rbo.type == 'ACTIVE':
+ layout.prop(rbo, "mass")
+
+
+class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
+ bl_label = "Rigid Body Collisions"
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body and
+ (not context.scene.render.use_game_engine))
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ rbo = ob.rigid_body
+
+ layout.prop(rbo, "collision_shape", text="Shape")
+
+ split = layout.split()
+
+ col = split.column()
+ col.label(text="Surface Response:")
+ col.prop(rbo, "friction")
+ col.prop(rbo, "restitution", text="Bounciness")
+
+ col = split.column()
+ col.label(text="Sensitivity:")
+ if rbo.collision_shape in {'MESH', 'CONE'}:
+ col.prop(rbo, "collision_margin", text="Margin")
+ else:
+ col.prop(rbo, "use_margin")
+ sub = col.column()
+ sub.active = rbo.use_margin
+ sub.prop(rbo, "collision_margin", text="Margin")
+
+ layout.prop(rbo, "collision_groups")
+
+
+class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
+ bl_label = "Rigid Body Dynamics"
+ bl_default_closed = True
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body and
+ obj.rigid_body.type == 'ACTIVE' and
+ (not context.scene.render.use_game_engine))
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ rbo = ob.rigid_body
+
+ #col = layout.column(align=1)
+ #col.label(text="Activation:")
+ # XXX: settings such as activate on collison/etc.
+
+ split = layout.split()
+
+ col = split.column()
+ col.label(text="Deactivation:")
+ col.prop(rbo, "use_deactivation")
+ sub = col.column()
+ sub.active = rbo.use_deactivation
+ sub.prop(rbo, "start_deactivated")
+ sub.prop(rbo, "deactivate_linear_velocity", text="Linear Vel")
+ sub.prop(rbo, "deactivate_angular_velocity", text="Angular Vel")
+ # TODO: other params such as time?
+
+ col = split.column()
+ col.label(text="Damping:")
+ col.prop(rbo, "linear_damping", text="Translation")
+ col.prop(rbo, "angular_damping", text="Rotation")
+
+if __name__ == "__main__": # only for live edit.
+ bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
new file mode 100644
index 00000000000..a49c6d623ca
--- /dev/null
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
@@ -0,0 +1,233 @@
+# ##### 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 #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Panel
+
+
+class PHYSICS_PT_rigidbody_constraint_panel():
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "physics"
+
+
+class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel):
+ bl_label = "Rigid Body Constraint"
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.object
+ rd = context.scene.render
+ return (ob and ob.rigid_body_constraint and (not rd.use_game_engine))
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ rbc = ob.rigid_body_constraint
+
+ layout.prop(rbc, "type")
+
+ row = layout.row()
+ row.prop(rbc, "enabled")
+ row.prop(rbc, "disable_collisions")
+
+ layout.prop(rbc, "object1")
+ layout.prop(rbc, "object2")
+
+ if rbc.type != 'MOTOR':
+ row = layout.row()
+ row.prop(rbc, "use_breaking")
+ sub = row.row()
+ sub.active = rbc.use_breaking
+ sub.prop(rbc, "breaking_threshold", text="Threshold")
+
+ row = layout.row()
+ row.prop(rbc, "override_solver_iterations", text="Override Iterations")
+ sub = row.row()
+ sub.active = rbc.override_solver_iterations
+ sub.prop(rbc, "num_solver_iterations", text="Iterations")
+
+ if rbc.type == 'HINGE':
+ col = layout.column(align=True)
+ col.label("Limits:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_ang_z", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_ang_z
+ sub.prop(rbc, "limit_ang_z_lower", text="Lower")
+ sub.prop(rbc, "limit_ang_z_upper", text="Upper")
+
+ elif rbc.type == 'SLIDER':
+ col = layout.column(align=True)
+ col.label("Limits:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_lin_x", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_lin_x
+ sub.prop(rbc, "limit_lin_x_lower", text="Lower")
+ sub.prop(rbc, "limit_lin_x_upper", text="Upper")
+
+ elif rbc.type == 'PISTON':
+ col = layout.column(align=True)
+ col.label("Limits:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_lin_x", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_lin_x
+ sub.prop(rbc, "limit_lin_x_lower", text="Lower")
+ sub.prop(rbc, "limit_lin_x_upper", text="Upper")
+
+ col = layout.column(align=True)
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_ang_x", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_ang_x
+ sub.prop(rbc, "limit_ang_x_lower", text="Lower")
+ sub.prop(rbc, "limit_ang_x_upper", text="Upper")
+
+ elif rbc.type == 'MOTOR':
+ col = layout.column(align=True)
+ col.label("Linear motor:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_motor_lin", toggle=True, text="Enable")
+ sub = row.row()
+ sub.active = rbc.use_motor_lin
+ sub.prop(rbc, "motor_lin_target_velocity", text="Target Velocity")
+ sub.prop(rbc, "motor_lin_max_impulse", text="Max Impulse")
+
+ col.label("Angular motor:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_motor_ang", toggle=True, text="Enable")
+ sub = row.row()
+ sub.active = rbc.use_motor_ang
+ sub.prop(rbc, "motor_ang_target_velocity", text="Target Velocity")
+ sub.prop(rbc, "motor_ang_max_impulse", text="Max Impulse")
+
+ elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}:
+ col = layout.column(align=True)
+ col.label("Limits:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_lin_x", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_lin_x
+ sub.prop(rbc, "limit_lin_x_lower", text="Lower")
+ sub.prop(rbc, "limit_lin_x_upper", text="Upper")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_lin_y", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_lin_y
+ sub.prop(rbc, "limit_lin_y_lower", text="Lower")
+ sub.prop(rbc, "limit_lin_y_upper", text="Upper")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_lin_z", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_lin_z
+ sub.prop(rbc, "limit_lin_z_lower", text="Lower")
+ sub.prop(rbc, "limit_lin_z_upper", text="Upper")
+
+ col = layout.column(align=True)
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_ang_x", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_ang_x
+ sub.prop(rbc, "limit_ang_x_lower", text="Lower")
+ sub.prop(rbc, "limit_ang_x_upper", text="Upper")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_ang_y", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_ang_y
+ sub.prop(rbc, "limit_ang_y_lower", text="Lower")
+ sub.prop(rbc, "limit_ang_y_upper", text="Upper")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_limit_ang_z", toggle=True)
+ sub = row.row()
+ sub.active = rbc.use_limit_ang_z
+ sub.prop(rbc, "limit_ang_z_lower", text="Lower")
+ sub.prop(rbc, "limit_ang_z_upper", text="Upper")
+
+ if rbc.type == 'GENERIC_SPRING':
+ col = layout.column(align=True)
+ col.label("Springs:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.1
+ sub.prop(rbc, "use_spring_x", toggle=True, text="X")
+ sub = row.row()
+ sub.active = rbc.use_spring_x
+ sub.prop(rbc, "spring_stiffness_x", text="Stiffness")
+ sub.prop(rbc, "spring_damping_x")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.1
+ sub.prop(rbc, "use_spring_y", toggle=True, text="Y")
+ sub = row.row()
+ sub.active = rbc.use_spring_y
+ sub.prop(rbc, "spring_stiffness_y", text="Stiffness")
+ sub.prop(rbc, "spring_damping_y")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.1
+ sub.prop(rbc, "use_spring_z", toggle=True, text="Z")
+ sub = row.row()
+ sub.active = rbc.use_spring_z
+ sub.prop(rbc, "spring_stiffness_z", text="Stiffness")
+ sub.prop(rbc, "spring_damping_z")
+
+if __name__ == "__main__": # only for live edit.
+ bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py
index ce5053f0ecf..487f43aa973 100644
--- a/release/scripts/startup/bl_ui/properties_physics_smoke.py
+++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py
@@ -76,7 +76,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
elif md.smoke_type == 'FLOW':
flow = md.flow_settings
-
+
layout.prop(flow, "smoke_flow_type", expand=False)
if flow.smoke_flow_type != "OUTFLOW":
@@ -118,7 +118,8 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
col = split.column()
col.prop(coll, "collision_type")
-
+
+
class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel):
bl_label = "Smoke Flow Advanced"
bl_options = {'DEFAULT_CLOSED'}
@@ -132,7 +133,7 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel):
layout = self.layout
ob = context.object
flow = context.smoke.flow_settings
-
+
split = layout.split()
col = split.column()
@@ -147,11 +148,12 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel):
if flow.texture_map_type == "AUTO":
sub.prop(flow, "texture_size")
sub.prop(flow, "texture_offset")
-
+
col = split.column()
col.label(text="Vertex Group:")
col.prop_search(flow, "density_vertex_group", ob, "vertex_groups", text="")
+
class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel):
bl_label = "Smoke Flames"
bl_options = {'DEFAULT_CLOSED'}
@@ -179,7 +181,8 @@ class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel):
col.prop(domain, "flame_ignition")
col.prop(domain, "flame_max_temp")
col.prop(domain, "flame_smoke_color")
-
+
+
class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel):
bl_label = "Smoke Adaptive Domain"
bl_options = {'DEFAULT_CLOSED'}
@@ -199,10 +202,10 @@ class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel):
domain = context.smoke.domain_settings
layout.active = domain.use_adaptive_domain
-
+
split = layout.split()
- split.enabled = not domain.point_cache.is_baked
-
+ split.enabled = (not domain.point_cache.is_baked)
+
col = split.column(align=True)
col.label(text="Resolution:")
col.prop(domain, "additional_res")
@@ -212,6 +215,7 @@ class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel):
col.label(text="Advanced:")
col.prop(domain, "adapt_threshold")
+
class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel):
bl_label = "Smoke High Resolution"
bl_options = {'DEFAULT_CLOSED'}
@@ -249,6 +253,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel):
layout.prop(md, "show_high_resolution")
+
class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel):
bl_label = "Smoke Groups"
bl_options = {'DEFAULT_CLOSED'}
@@ -262,7 +267,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
domain = context.smoke.domain_settings
-
+
split = layout.split()
col = split.column()
@@ -276,6 +281,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel):
col.label(text="Collision Group:")
col.prop(domain, "collision_group", text="")
+
class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel):
bl_label = "Smoke Cache"
bl_options = {'DEFAULT_CLOSED'}
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 9814dd7e902..1cd58328332 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -1,4 +1,5 @@
# ##### 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
@@ -18,7 +19,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
class RENDER_MT_presets(Menu):
@@ -42,6 +43,18 @@ class RENDER_MT_framerate_presets(Menu):
draw = Menu.draw_preset
+class RENDER_UL_renderlayers(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.SceneRenderLayer)
+ layer = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(text=layer.name, translate=False, icon_value=icon)
+ layout.prop(layer, "use", text="", index=index)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
class RenderButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -83,7 +96,7 @@ class RENDER_PT_layers(RenderButtonsPanel, Panel):
rd = scene.render
row = layout.row()
- row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
+ row.template_list("RENDER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
col = row.column(align=True)
col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
@@ -338,7 +351,7 @@ class RENDER_PT_performance(RenderButtonsPanel, Panel):
subsub = sub.column()
subsub.enabled = rd.threads_mode == 'FIXED'
subsub.prop(rd, "threads")
-
+
sub = col.column(align=True)
sub.label(text="Tile Size:")
sub.prop(rd, "tile_x", text="X")
@@ -573,7 +586,7 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
layout.prop(rd, "bake_type")
multires_bake = False
- if rd.bake_type in ['NORMALS', 'DISPLACEMENT']:
+ if rd.bake_type in ['NORMALS', 'DISPLACEMENT', 'AO']:
layout.prop(rd, "use_bake_multires")
multires_bake = rd.use_bake_multires
@@ -591,9 +604,12 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
split = layout.split()
col = split.column()
- col.prop(rd, "use_bake_clear")
- col.prop(rd, "bake_margin")
- col.prop(rd, "bake_quad_split", text="Split")
+ col.prop(rd, "use_bake_to_vertex_color")
+ sub = col.column()
+ sub.active = not rd.use_bake_to_vertex_color
+ sub.prop(rd, "use_bake_clear")
+ sub.prop(rd, "bake_margin")
+ sub.prop(rd, "bake_quad_split", text="Split")
col = split.column()
col.prop(rd, "use_bake_selected_to_active")
@@ -602,11 +618,19 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
sub.prop(rd, "bake_distance")
sub.prop(rd, "bake_bias")
else:
- if rd.bake_type == 'DISPLACEMENT':
- layout.prop(rd, "use_bake_lores_mesh")
+ split = layout.split()
+
+ col = split.column()
+ col.prop(rd, "use_bake_clear")
+ col.prop(rd, "bake_margin")
- layout.prop(rd, "use_bake_clear")
- layout.prop(rd, "bake_margin")
+ if rd.bake_type == 'DISPLACEMENT':
+ col = split.column()
+ col.prop(rd, "use_bake_lores_mesh")
+ if rd.bake_type == 'AO':
+ col = split.column()
+ col.prop(rd, "bake_bias")
+ col.prop(rd, "bake_samples")
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 518b253d0b0..519f9ca47fa 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -18,9 +18,26 @@
# <pep8 compliant>
import bpy
-from bpy.types import Panel
+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,
+ )
+
+
+class SCENE_UL_keying_set_paths(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.KeyingSetPath)
+ kspath = item
+ icon = layout.enum_item_icon(kspath, "id_type", kspath.id_type)
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(text=kspath.data_path, translate=False, icon_value=icon)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
class SceneButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -47,36 +64,6 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel):
layout.prop(scene, "active_clip", text="Active Clip")
-class SCENE_PT_audio(SceneButtonsPanel, Panel):
- bl_label = "Audio"
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- rd = context.scene.render
- ffmpeg = rd.ffmpeg
-
- layout.prop(scene, "audio_volume")
- layout.operator("sound.bake_animation")
-
- split = layout.split()
-
- col = split.column()
- col.label("Listener:")
- col.prop(scene, "audio_distance_model", text="")
- col.prop(scene, "audio_doppler_speed", text="Speed")
- col.prop(scene, "audio_doppler_factor", text="Doppler")
-
- col = split.column()
- col.label("Format:")
- col.prop(ffmpeg, "audio_channels", text="")
- col.prop(ffmpeg, "audio_mixrate", text="Rate")
-
- layout.operator("sound.mixdown")
-
-
class SCENE_PT_unit(SceneButtonsPanel, Panel):
bl_label = "Units"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -107,7 +94,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(scene, "keying_sets", scene.keying_sets, "active_index", rows=2)
+ col.template_list("UI_UL_list", "keying_sets", scene, "keying_sets", scene.keying_sets, "active_index", rows=2)
col = row.column(align=True)
col.operator("anim.keying_set_add", icon='ZOOMIN', text="")
@@ -151,7 +138,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(ks, "paths", ks.paths, "active_index", rows=2)
+ col.template_list("SCENE_UL_keying_set_paths", "", ks, "paths", ks.paths, "active_index", rows=2)
col = row.column(align=True)
col.operator("anim.keying_set_path_add", icon='ZOOMIN', text="")
@@ -186,6 +173,63 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
col.prop(ksp, "bl_options")
+class SCENE_PT_color_management(SceneButtonsPanel, Panel):
+ bl_label = "Color Management"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ rd = scene.render
+
+ col = layout.column()
+ col.label(text="Display:")
+ col.prop(scene.display_settings, "display_device")
+
+ col = layout.column()
+ col.separator()
+ col.label(text="Render:")
+ col.template_colormanaged_view_settings(scene, "view_settings")
+
+ col = layout.column()
+ col.separator()
+ col.label(text="Sequencer:")
+ col.prop(scene.sequencer_colorspace_settings, "name")
+
+
+class SCENE_PT_audio(SceneButtonsPanel, Panel):
+ bl_label = "Audio"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ rd = context.scene.render
+ ffmpeg = rd.ffmpeg
+
+ layout.prop(scene, "audio_volume")
+ layout.operator("sound.bake_animation")
+
+ split = layout.split()
+
+ col = split.column()
+ col.label("Listener:")
+ col.prop(scene, "audio_distance_model", text="")
+ col.prop(scene, "audio_doppler_speed", text="Speed")
+ col.prop(scene, "audio_doppler_factor", text="Doppler")
+
+ col = split.column()
+ col.label("Format:")
+ col.prop(ffmpeg, "audio_channels", text="")
+ col.prop(ffmpeg, "audio_mixrate", text="Rate")
+
+ layout.operator("sound.mixdown")
+
+
class SCENE_PT_physics(SceneButtonsPanel, Panel):
bl_label = "Gravity"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -203,6 +247,88 @@ class SCENE_PT_physics(SceneButtonsPanel, Panel):
layout.prop(scene, "gravity", text="")
+class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel):
+ bl_label = "Rigid Body World"
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ @classmethod
+ def poll(cls, context):
+ scene = context.scene
+ rd = scene.render
+ return scene and (rd.engine in cls.COMPAT_ENGINES)
+
+ def draw_header(self, context):
+ scene = context.scene
+ rbw = scene.rigidbody_world
+ if rbw is not None:
+ self.layout.prop(rbw, "enabled", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+
+ rbw = scene.rigidbody_world
+
+ if rbw is None:
+ layout.operator("rigidbody.world_add")
+ else:
+ layout.operator("rigidbody.world_remove")
+
+ col = layout.column()
+ col.active = rbw.enabled
+
+ col = col.column()
+ col.prop(rbw, "group")
+ col.prop(rbw, "constraints")
+
+ split = col.split()
+
+ col = split.column()
+ col.prop(rbw, "time_scale", text="Speed")
+ col.prop(rbw, "use_split_impulse")
+
+ col = split.column()
+ col.prop(rbw, "steps_per_second", text="Steps Per Second")
+ col.prop(rbw, "num_solver_iterations", text="Solver Iterations")
+
+
+class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel):
+ bl_label = "Rigid Body Cache"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ @classmethod
+ def poll(cls, context):
+ rd = context.scene.render
+ scene = context.scene
+ return scene and scene.rigidbody_world and (rd.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ scene = context.scene
+ rbw = scene.rigidbody_world
+
+ point_cache_ui(self, context, rbw.point_cache, rbw.point_cache.is_baked is False and rbw.enabled, 'RIGID_BODY')
+
+
+class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel):
+ bl_label = "Rigid Body Field Weights"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ @classmethod
+ def poll(cls, context):
+ rd = context.scene.render
+ scene = context.scene
+ return scene and scene.rigidbody_world and (rd.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ scene = context.scene
+ rbw = scene.rigidbody_world
+
+ effector_weights_ui(self, context, rbw.effector_weights, 'RIGID_BODY')
+
+
class SCENE_PT_simplify(SceneButtonsPanel, Panel):
bl_label = "Simplify"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -231,34 +357,6 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel):
col.prop(rd, "simplify_ao_sss", text="AO and SSS")
-class SCENE_PT_color_management(Panel):
- bl_label = "Color Management"
- bl_space_type = 'PROPERTIES'
- bl_region_type = 'WINDOW'
- bl_context = "scene"
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- rd = scene.render
-
- col = layout.column()
- col.label(text="Display:")
- col.prop(scene.display_settings, "display_device")
-
- col = layout.column()
- col.separator()
- col.label(text="Render:")
- col.template_colormanaged_view_settings(scene, "view_settings")
- col.prop(rd, "use_color_unpremultiply")
-
- col = layout.column()
- col.separator()
- col.label(text="Sequencer:")
- col.prop(scene.sequencer_colorspace_settings, "name")
-
-
class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "scene"
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index e623d034b48..dd30627abff 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
from bpy.types import (Brush,
Lamp,
@@ -30,7 +30,7 @@ from bpy.types import (Brush,
from rna_prop_ui import PropertyPanel
-from bl_ui.properties_paint_common import sculpt_brush_texture_settings
+from bl_ui.properties_paint_common import brush_texture_settings
class TEXTURE_MT_specials(Menu):
@@ -55,6 +55,22 @@ class TEXTURE_MT_envmap_specials(Menu):
layout.operator("texture.envmap_clear", icon='FILE_REFRESH')
layout.operator("texture.envmap_clear_all", icon='FILE_REFRESH')
+
+class TEXTURE_UL_texslots(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MaterialTextureSlot)
+ ma = data
+ slot = item
+ tex = slot.texture if slot else None
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(text=tex.name if tex else "", translate=False, icon_value=icon)
+ if tex and isinstance(item, bpy.types.MaterialTextureSlot):
+ layout.prop(ma, "use_textures", text="", index=index)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
from bl_ui.properties_material import active_node_mat
@@ -142,7 +158,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
if tex_collection:
row = layout.row()
- row.template_list(idblock, "texture_slots", idblock, "active_texture_index", rows=2)
+ row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots", idblock, "active_texture_index", rows=2)
col = row.column(align=True)
col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
@@ -416,6 +432,12 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def draw(self, context):
+ if context.scene.render.engine == 'BLENDER_GAME':
+ self.draw_bge(context)
+ else:
+ self.draw_bi(context)
+
+ def draw_bi(self, context):
layout = self.layout
idblock = context_tex_datablock(context)
@@ -426,7 +448,6 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
col = split.column()
col.label(text="Alpha:")
- col.prop(tex, "use_alpha", text="Use")
col.prop(tex, "use_calculate_alpha", text="Calculate")
col.prop(tex, "invert_alpha", text="Invert")
col.separator()
@@ -453,6 +474,33 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
texture_filter_common(tex, col)
+ def draw_bge(self, context):
+ layout = self.layout
+
+ idblock = context_tex_datablock(context)
+ tex = context.texture
+ slot = getattr(context, "texture_slot", None)
+
+ split = layout.split()
+
+ col = split.column()
+ col.label(text="Alpha:")
+ col.prop(tex, "use_calculate_alpha", text="Calculate")
+ col.prop(tex, "invert_alpha", text="Invert")
+
+ col = split.column()
+
+ #Only for Material based textures, not for Lamp/World...
+ if slot and isinstance(idblock, Material):
+ col.prop(tex, "use_normal_map")
+ row = col.row()
+ row.active = tex.use_normal_map
+ row.prop(slot, "normal_map_space", text="")
+
+ row = col.row()
+ row.active = not tex.use_normal_map
+ row.prop(tex, "use_derivative_map")
+
class TEXTURE_PT_image_mapping(TextureTypePanel, Panel):
bl_label = "Image Mapping"
@@ -869,8 +917,8 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
split.prop(tex, "object", text="")
if isinstance(idblock, Brush):
- if context.sculpt_object:
- sculpt_brush_texture_settings(layout, idblock)
+ if context.sculpt_object or context.image_paint_object:
+ brush_texture_settings(layout, idblock, context.sculpt_object)
else:
if isinstance(idblock, Material):
split = layout.split(percentage=0.3)
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index cb88226b55a..e32db805a29 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -19,7 +19,24 @@
# <pep8-80 compliant>
import bpy
-from bpy.types import Panel, Header, Menu
+from bpy.types import Panel, Header, Menu, UIList
+from bpy.app.translations import pgettext_iface as iface_
+
+
+class CLIP_UL_tracking_objects(UIList):
+ def draw_item(self, context, layout, data, item, icon,
+ active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MovieTrackingObject)
+ tobj = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(text=tobj.name, translate=False,
+ icon='CAMERA_DATA' if tobj.is_camera
+ else 'OBJECT_DATA')
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="",
+ icon='CAMERA_DATA' if tobj.is_camera
+ else 'OBJECT_DATA')
class CLIP_HT_header(Header):
@@ -322,7 +339,8 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
col = layout.column(align=True)
col.active = not settings.use_tripod_solver
- col.prop(settings, "use_fallback_reconstruction", text="Allow Fallback")
+ col.prop(settings, "use_fallback_reconstruction",
+ text="Allow Fallback")
sub = col.column()
sub.active = settings.use_fallback_reconstruction
sub.prop(settings, "reconstruction_success_threshold")
@@ -471,7 +489,7 @@ class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
tracking = sc.clip.tracking
row = layout.row()
- row.template_list(tracking, "objects",
+ row.template_list("CLIP_UL_tracking_objects", "", tracking, "objects",
tracking, "active_object_index", rows=3)
sub = row.column(align=True)
@@ -728,7 +746,8 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
layout.active = stab.use_2d_stabilization
row = layout.row()
- row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
+ row.template_list("UI_UL_list", "stabilization_tracks", stab, "tracks",
+ stab, "active_track_index", rows=3)
sub = row.column(align=True)
@@ -893,10 +912,11 @@ class CLIP_MT_view(Menu):
ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
+ text = iface_("Zoom %d:%d")
for a, b in ratios:
- text = "Zoom %d:%d" % (a, b)
layout.operator("clip.view_zoom_ratio",
- text=text).ratio = a / b
+ text=text % (a, b),
+ translate=False).ratio = a / b
else:
if sc.view == 'GRAPH':
layout.operator_context = 'INVOKE_REGION_PREVIEW'
diff --git a/release/scripts/startup/bl_ui/space_console.py b/release/scripts/startup/bl_ui/space_console.py
index 23d16c14f2d..70e0fb4fcf2 100644
--- a/release/scripts/startup/bl_ui/space_console.py
+++ b/release/scripts/startup/bl_ui/space_console.py
@@ -80,7 +80,9 @@ class CONSOLE_MT_language(Menu):
languages.sort()
for language in languages:
- layout.operator("console.language", text=language[0].upper() + language[1:]).language = language
+ layout.operator("console.language",
+ text=language.title(),
+ translate=False).language = language
def add_scrollback(text, text_type):
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 5535070c1c4..adeae9da790 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -241,6 +241,10 @@ class DOPESHEET_MT_channel(Menu):
layout.operator("anim.channels_delete")
layout.separator()
+ layout.operator("anim.channels_group")
+ layout.operator("anim.channels_ungroup")
+
+ layout.separator()
layout.operator_menu_enum("anim.channels_setting_toggle", "type")
layout.operator_menu_enum("anim.channels_setting_enable", "type")
layout.operator_menu_enum("anim.channels_setting_disable", "type")
@@ -275,8 +279,8 @@ class DOPESHEET_MT_key(Menu):
layout.operator("action.keyframe_insert")
layout.separator()
- layout.operator("action.frame_jump")
-
+ layout.operator("action.frame_jump")
+
layout.separator()
layout.operator("action.duplicate_move")
layout.operator("action.delete")
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 4cb6538458f..2d0b1c93d13 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -161,6 +161,10 @@ class GRAPH_MT_channel(Menu):
layout.operator("anim.channels_delete")
layout.separator()
+ layout.operator("anim.channels_group")
+ layout.operator("anim.channels_ungroup")
+
+ layout.separator()
layout.operator_menu_enum("anim.channels_setting_toggle", "type")
layout.operator_menu_enum("anim.channels_setting_enable", "type")
layout.operator_menu_enum("anim.channels_setting_disable", "type")
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 1ea20d96386..01b67667cfb 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -19,7 +19,8 @@
# <pep8 compliant>
import bpy
from bpy.types import Header, Menu, Panel
-from bl_ui.properties_paint_common import UnifiedPaintPanel
+from bl_ui.properties_paint_common import UnifiedPaintPanel, brush_texture_settings
+from bpy.app.translations import pgettext_iface as iface_
class ImagePaintPanel(UnifiedPaintPanel):
@@ -71,7 +72,7 @@ class IMAGE_MT_view(Menu):
ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
for a, b in ratios:
- layout.operator("image.view_zoom_ratio", text="Zoom" + " %d:%d" % (a, b)).ratio = a / b
+ layout.operator("image.view_zoom_ratio", text=iface_("Zoom %d:%d") % (a, b), translate=False).ratio = a / b
layout.separator()
@@ -146,9 +147,7 @@ class IMAGE_MT_image(Menu):
if not show_render:
layout.separator()
- if ima.packed_file:
- layout.operator("image.unpack")
- else:
+ if not ima.packed_file:
layout.operator("image.pack")
# only for dirty && specific image types, perhaps
@@ -722,7 +721,8 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
col = layout.column()
col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
- col.prop(brush, "use_fixed_texture")
+
+ brush_texture_settings(col, brush, 0)
class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 8df117e27a0..51c975c3e70 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -65,7 +65,7 @@ class INFO_HT_header(Header):
row = layout.row(align=True)
row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
- row.label(text=scene.statistics())
+ row.label(text=scene.statistics(), translate=False)
# XXX: BEFORE RELEASE, MOVE FILE MENU OUT OF INFO!!!
"""
@@ -112,7 +112,7 @@ class INFO_MT_file(Menu):
layout.separator()
- layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA'
+ layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA'
layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK')
layout.operator_context = 'INVOKE_AREA'
@@ -124,8 +124,9 @@ class INFO_MT_file(Menu):
layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
- layout.operator_context = 'EXEC_AREA'
+ layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.save_homefile", icon='SAVE_PREFS')
+ layout.operator_context = 'EXEC_AREA'
layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY')
layout.separator()
@@ -361,6 +362,12 @@ class INFO_MT_window(Menu):
layout.operator("wm.window_duplicate")
layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER')
+
+ layout.separator()
+
+ layout.operator("screen.screenshot").full = True
+ layout.operator("screen.screencast").full = True
+
if sys.platform[:3] == "win":
layout.separator()
layout.operator("wm.console_toggle", icon='CONSOLE')
@@ -373,7 +380,7 @@ class INFO_MT_help(Menu):
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="Release Log", icon='URL').url = "http://www.blender.org/development/release-logs/blender-265"
+ layout.operator("wm.url_open", text="Release Log", icon='URL').url = "http://www.blender.org/development/release-logs/blender-266"
layout.separator()
layout.operator("wm.url_open", text="Blender Website", icon='URL').url = "http://www.blender.org"
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index c46b1c20738..104c1500756 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -252,6 +252,7 @@ class NODE_PT_quality(bpy.types.Panel):
col = layout.column()
col.prop(tree, "use_opencl")
+ col.prop(tree, "use_groupnode_buffer")
col.prop(tree, "two_pass")
col.prop(snode, "show_highlight")
col.prop(snode, "use_hidden_preview")
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index fdfd43157c7..7841acf01b3 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 bpy.app.translations import pgettext_iface as iface_
def act_strip(context):
@@ -422,23 +423,25 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel, Panel):
col = layout.column(align=True)
row = col.row()
- row.label(text="Final Length" + ": %s" % bpy.utils.smpte_from_frame(strip.frame_final_duration))
+ row.label(text=iface_("Final Length: %s") % bpy.utils.smpte_from_frame(strip.frame_final_duration),
+ translate=False)
row = col.row()
row.active = (frame_current >= strip.frame_start and frame_current <= strip.frame_start + strip.frame_duration)
- row.label(text="Playhead" + ": %d" % (frame_current - strip.frame_start))
+ row.label(text=iface_("Playhead: %d") % (frame_current - strip.frame_start), translate=False)
- col.label(text="Frame Offset" + " %d:%d" % (strip.frame_offset_start, strip.frame_offset_end))
- col.label(text="Frame Still" + " %d:%d" % (strip.frame_still_start, strip.frame_still_end))
+ col.label(text=iface_("Frame Offset %d:%d") % (strip.frame_offset_start, strip.frame_offset_end),
+ translate=False)
+ col.label(text=iface_("Frame Still %d:%d") % (strip.frame_still_start, strip.frame_still_end), translate=False)
elem = False
if strip.type == 'IMAGE':
- elem = strip.getStripElem(frame_current)
+ elem = strip.strip_elem_from_frame(frame_current)
elif strip.type == 'MOVIE':
elem = strip.elements[0]
if elem and elem.orig_width > 0 and elem.orig_height > 0:
- col.label(text="Original Dimension" + ": %dx%d" % (elem.orig_width, elem.orig_height))
+ col.label(text=iface_("Original Dimension: %dx%d") % (elem.orig_width, elem.orig_height), translate=False)
else:
col.label(text="Original Dimension: None")
@@ -595,13 +598,14 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
# Current element for the filename
- elem = strip.getStripElem(context.scene.frame_current)
+ elem = strip.strip_elem_from_frame(context.scene.frame_current)
if elem:
split = layout.split(percentage=0.2)
split.label(text="File:")
split.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
layout.prop(strip.colorspace_settings, "name")
+ layout.prop(strip, "alpha_mode")
layout.operator("sequencer.change_path")
@@ -714,7 +718,7 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
if scene:
sta = scene.frame_start
end = scene.frame_end
- layout.label(text="Original frame range" + ": %d-%d (%d)" % (sta, end, end - sta + 1))
+ layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
@@ -743,7 +747,7 @@ class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
if mask:
sta = mask.frame_start
end = mask.frame_end
- layout.label(text="Original frame range" + ": %d-%d (%d)" % (sta, end, end - sta + 1))
+ layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
@@ -797,7 +801,6 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
col.label(text="Colors:")
col.prop(strip, "color_saturation", text="Saturation")
col.prop(strip, "color_multiply", text="Multiply")
- col.prop(strip, "use_premultiply")
col.prop(strip, "use_float")
@@ -867,6 +870,10 @@ class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel):
#col.active = render.use_sequencer_gl_preview
col.prop(render, "sequencer_gl_preview", text="")
+ row = col.row()
+ row.active = render.sequencer_gl_preview == 'SOLID'
+ row.prop(render, "use_sequencer_gl_textured_solid")
+
class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
bl_label = "View Settings"
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index fa8752c21be..4264fc95cea 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -19,6 +19,7 @@
# <pep8-80 compliant>
import bpy
from bpy.types import Header, Menu, Panel
+from bpy.app.translations import pgettext_iface as iface_
class TEXT_HT_header(Header):
@@ -66,16 +67,17 @@ class TEXT_HT_header(Header):
row.operator("text.run_script")
row = layout.row()
+ row.active = text.name.endswith(".py")
row.prop(text, "use_module")
row = layout.row()
if text.filepath:
if text.is_dirty:
- row.label(text="File" + ": *%r " %
- text.filepath + "(unsaved)")
+ row.label(text=iface_("File: *%r (unsaved)") %
+ text.filepath, translate=False)
else:
- row.label(text="File" + ": %r" %
- text.filepath)
+ row.label(text=iface_("File: %r") %
+ text.filepath, translate=False)
else:
row.label(text="Text: External"
if text.library
@@ -151,7 +153,7 @@ class TEXT_MT_view(Menu):
layout = self.layout
layout.operator("text.properties", icon='MENU_PANEL')
-
+
layout.separator()
layout.operator("text.move",
@@ -193,16 +195,35 @@ class TEXT_MT_text(Menu):
layout.operator("text.run_script")
-class TEXT_MT_templates(Menu):
- bl_label = "Templates"
+class TEXT_MT_templates_py(Menu):
+ bl_label = "Python"
def draw(self, context):
- self.path_menu(bpy.utils.script_paths("templates"),
+ self.path_menu(bpy.utils.script_paths("templates_py"),
"text.open",
{"internal": True},
)
+class TEXT_MT_templates_osl(Menu):
+ bl_label = "Open Shading Language"
+
+ def draw(self, context):
+ self.path_menu(bpy.utils.script_paths("templates_osl"),
+ "text.open",
+ {"internal": True},
+ )
+
+
+class TEXT_MT_templates(Menu):
+ bl_label = "Templates"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.menu("TEXT_MT_templates_py")
+ layout.menu("TEXT_MT_templates_osl")
+
+
class TEXT_MT_edit_select(Menu):
bl_label = "Select"
@@ -281,6 +302,7 @@ class TEXT_MT_edit(Menu):
layout.operator("text.jump")
layout.operator("text.properties", text="Find...")
+ layout.operator("text.autocomplete")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index cb9e2444793..6af9f377237 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -152,6 +152,7 @@ class TIME_MT_cache(Menu):
col.prop(st, "cache_cloth")
col.prop(st, "cache_smoke")
col.prop(st, "cache_dynamicpaint")
+ col.prop(st, "cache_rigidbody")
class TIME_MT_frame(Menu):
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 0bb25e98456..017f75b7583 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -19,7 +19,28 @@
# <pep8 compliant>
import bpy
from bpy.types import Header, Menu, Panel
-import os
+from bpy.app.translations import pgettext_iface as iface_
+
+
+def ui_style_items(col, context):
+ """ UI Style settings """
+
+ split = col.split()
+
+ col = split.column()
+ col.label(text="Kerning Style:")
+ col.row().prop(context, "font_kerning_style", expand=True)
+ col.prop(context, "points")
+
+ col = split.column()
+ col.label(text="Shadow Offset:")
+ col.prop(context, "shadow_offset_x", text="X")
+ col.prop(context, "shadow_offset_y", text="Y")
+
+ col = split.column()
+ col.prop(context, "shadow")
+ col.prop(context, "shadowalpha")
+ col.prop(context, "shadowcolor")
def ui_items_general(col, context):
@@ -84,7 +105,7 @@ class USERPREF_HT_header(Header):
userpref = context.user_preferences
layout.operator_context = 'EXEC_AREA'
- layout.operator("wm.save_homefile", text="Save As Default")
+ layout.operator("wm.save_userpref")
layout.operator_context = 'INVOKE_DEFAULT'
@@ -162,6 +183,7 @@ class USERPREF_PT_interface(Panel):
return (userpref.active_section == 'INTERFACE')
def draw(self, context):
+ import sys
layout = self.layout
userpref = context.user_preferences
@@ -247,7 +269,7 @@ class USERPREF_PT_interface(Panel):
col.prop(view, "show_splash")
- if os.name == "nt":
+ if sys.platform[:3] == "win":
col.prop(view, "use_quit_dialog")
@@ -382,6 +404,7 @@ class USERPREF_PT_system(Panel):
return (userpref.active_section == 'SYSTEM')
def draw(self, context):
+ import sys
layout = self.layout
userpref = context.user_preferences
@@ -445,6 +468,10 @@ class USERPREF_PT_system(Panel):
col.label(text="Window Draw Method:")
col.prop(system, "window_draw_method", text="")
col.prop(system, "multi_sample", text="")
+ if sys.platform == "linux" and system.multi_sample != 'NONE':
+ col.label(text="Might fail for Mesh editing selection!")
+ col.separator()
+ col.prop(system, "use_region_overlap")
col.label(text="Text Draw Options:")
col.prop(system, "use_text_antialiasing")
col.label(text="Textures:")
@@ -491,15 +518,15 @@ class USERPREF_PT_system(Panel):
sub.active = system.use_weight_color_range
sub.template_color_ramp(system, "weight_color_range", expand=True)
- column.separator()
-
- column.prop(system, "use_international_fonts")
- if system.use_international_fonts:
- column.prop(system, "language")
- row = column.row()
- row.label(text="Translate:")
- row.prop(system, "use_translate_interface", text="Interface")
- row.prop(system, "use_translate_tooltips", text="Tooltips")
+ if bpy.app.build_options.international:
+ column.separator()
+ column.prop(system, "use_international_fonts")
+ if system.use_international_fonts:
+ column.prop(system, "language")
+ row = column.row()
+ row.label(text="Translate:")
+ row.prop(system, "use_translate_interface", text="Interface")
+ row.prop(system, "use_translate_tooltips", text="Tooltips")
class USERPREF_MT_interface_theme_presets(Menu):
@@ -685,7 +712,8 @@ class USERPREF_PT_theme(Panel):
col.separator()
ui = theme.user_interface
- col.label("Icons:")
+
+ col.label("Menu Shadow:")
row = col.row()
@@ -694,20 +722,19 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- colsub.row().prop(ui, "icon_file")
+ colsub.row().prop(ui, "menu_shadow_fac")
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, "menu_shadow_width")
col.separator()
col.separator()
- ui = theme.user_interface.panel
- col.label("Panels:")
+ col.label("Icons:")
row = col.row()
@@ -716,16 +743,14 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- rowsub = colsub.row()
- rowsub.prop(ui, "show_header")
- rowsub.label()
+ colsub.row().prop(ui, "icon_file")
subsplit = row.split(percentage=0.85)
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- colsub.row().prop(ui, "header")
+ colsub.row().prop(ui, "icon_alpha")
col.separator()
col.separator()
@@ -743,20 +768,20 @@ class USERPREF_PT_theme(Panel):
colsub.row().prop(ui, "axis_x")
colsub.row().prop(ui, "axis_y")
colsub.row().prop(ui, "axis_z")
-
+
subsplit = row.split(percentage=0.85)
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
-
+
layout.separator()
layout.separator()
elif theme.theme_area == 'BONE_COLOR_SETS':
col = split.column()
for i, ui in enumerate(theme.bone_color_sets):
- col.label(text="Color Set" + " %d:" % (i + 1)) # i starts from 0
+ col.label(text=iface_("Color Set %d:") % (i + 1), translate=False) # i starts from 0
row = col.row()
@@ -775,6 +800,28 @@ class USERPREF_PT_theme(Panel):
colsub = padding.column()
colsub = padding.column()
colsub.row().prop(ui, "show_colored_constraints")
+ elif theme.theme_area == 'STYLE':
+ col = split.column()
+
+ style = context.user_preferences.ui_styles[0]
+
+ ui = style.panel_title
+ col.label(text="Panel Title:")
+ ui_style_items(col, ui)
+
+ col.separator()
+ col.separator()
+
+ ui = style.widget
+ col.label(text="Widget:")
+ ui_style_items(col, ui)
+
+ col.separator()
+ col.separator()
+
+ ui = style.widget_label
+ col.label(text="Widget Label:")
+ ui_style_items(col, ui)
else:
self._theme_generic(split, getattr(theme, theme.theme_area.lower()))
@@ -855,6 +902,7 @@ class USERPREF_PT_file(Panel):
col.prop(paths, "recent_files")
col.prop(paths, "use_save_preview_images")
col.label(text="Auto Save:")
+ col.prop(paths, "use_keep_session")
col.prop(paths, "use_auto_save_temporary_files")
sub = col.column()
sub.active = paths.use_auto_save_temporary_files
@@ -920,6 +968,8 @@ class USERPREF_PT_input(Panel, InputKeyMapPanel):
return (userpref.active_section == 'INPUT')
def draw_input_prefs(self, inputs, layout):
+ import sys
+
# General settings
row = layout.row()
col = row.column()
@@ -972,6 +1022,11 @@ class USERPREF_PT_input(Panel, InputKeyMapPanel):
sub.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction")
#sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
+ if sys.platform == "darwin":
+ sub = col.column()
+ sub.label(text="Trackpad:")
+ sub.prop(inputs, "use_trackpad_natural")
+
col.separator()
sub = col.column()
sub.label(text="NDOF Device:")
@@ -1034,6 +1089,8 @@ class USERPREF_PT_addons(Panel):
@staticmethod
def is_user_addon(mod, user_addon_paths):
+ import os
+
if not user_addon_paths:
for path in (bpy.utils.script_path_user(),
bpy.utils.script_path_pref()):
@@ -1056,6 +1113,7 @@ class USERPREF_PT_addons(Panel):
box.label(l)
def draw(self, context):
+ import os
import addon_utils
layout = self.layout
@@ -1064,8 +1122,8 @@ class USERPREF_PT_addons(Panel):
used_ext = {ext.module for ext in userpref.addons}
userpref_addons_folder = os.path.join(userpref.filepaths.script_directory, "addons")
- scripts_addons_folder = bpy.utils.user_resource('SCRIPTS', "addons")
-
+ scripts_addons_folder = bpy.utils.user_resource('SCRIPTS', "addons")
+
# collect the categories that can be filtered on
addons = [(mod, addon_utils.module_bl_info(mod)) for mod in addon_utils.modules(addon_utils.addons_fake_modules)]
@@ -1116,7 +1174,7 @@ class USERPREF_PT_addons(Panel):
(filter == "Enabled" and is_enabled) or
(filter == "Disabled" and not is_enabled) or
(filter == "User" and (mod.__file__.startswith((scripts_addons_folder, userpref_addons_folder))))
- ):
+ ):
if search and search not in info["name"].lower():
if info["author"]:
@@ -1126,7 +1184,8 @@ class USERPREF_PT_addons(Panel):
continue
# Addon UI Code
- box = col.column().box()
+ col_box = col.column()
+ box = col_box.box()
colsub = box.column()
row = colsub.row()
@@ -1159,15 +1218,15 @@ class USERPREF_PT_addons(Panel):
if mod:
split = colsub.row().split(percentage=0.15)
split.label(text="File:")
- split.label(text=mod.__file__)
+ split.label(text=mod.__file__, translate=False)
if info["author"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Author:")
- split.label(text=info["author"])
+ split.label(text=info["author"], translate=False)
if info["version"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Version:")
- split.label(text='.'.join(str(x) for x in info["version"]))
+ split.label(text='.'.join(str(x) for x in info["version"]), translate=False)
if info["warning"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Warning:")
@@ -1189,6 +1248,24 @@ class USERPREF_PT_addons(Panel):
for i in range(4 - tot_row):
split.separator()
+ # Show addon user preferences
+ if is_enabled:
+ addon_preferences = userpref.addons[module_name].preferences
+ if addon_preferences is not None:
+ draw = getattr(addon_preferences, "draw", None)
+ if draw is not None:
+ addon_preferences_class = type(addon_preferences)
+ box_prefs = col_box.box()
+ box_prefs.label("Preferences:")
+ addon_preferences_class.layout = box_prefs
+ try:
+ draw(context)
+ except:
+ import traceback
+ traceback.print_exc()
+ box_prefs.label(text="Error (see console)", icon='ERROR')
+ del addon_preferences_class.layout
+
# Append missing scripts
# First collect scripts that are used but have no script file.
module_names = {mod.__name__ for mod, info in addons}
@@ -1206,7 +1283,7 @@ class USERPREF_PT_addons(Panel):
colsub = box.column()
row = colsub.row()
- row.label(text=module_name, icon='ERROR')
+ row.label(text=module_name, translate=False, icon='ERROR')
if is_enabled:
row.operator("wm.addon_disable", icon='CHECKBOX_HLT', text="", emboss=False).module = module_name
diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py
index 81d67aa662c..e9eb2aa8b8f 100644
--- a/release/scripts/startup/bl_ui/space_userpref_keymap.py
+++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu
+from bpy.app.translations import pgettext_iface as iface_
class USERPREF_MT_keyconfigs(Menu):
@@ -97,7 +98,7 @@ class InputKeyMapPanel:
subcol = self.indented_layout(col, level + 1)
subrow = subcol.row()
subrow.prop(km, "show_expanded_items", text="", emboss=False)
- subrow.label(text="%s " % km.name + "(Global)")
+ subrow.label(text=iface_("%s (Global)") % km.name, translate=False)
else:
km.show_expanded_items = True
@@ -172,17 +173,17 @@ class InputKeyMapPanel:
if kmi.show_expanded:
box = col.box()
- if map_type not in {'TEXTINPUT', 'TIMER'}:
- split = box.split(percentage=0.4)
- sub = split.row()
+ split = box.split(percentage=0.4)
+ sub = split.row()
- if km.is_modal:
- sub.prop(kmi, "propvalue", text="")
- else:
- # One day...
- #~ sub.prop_search(kmi, "idname", bpy.context.window_manager, "operators_all", text="")
- sub.prop(kmi, "idname", text="")
+ if km.is_modal:
+ sub.prop(kmi, "propvalue", text="")
+ else:
+ # One day...
+ #~ sub.prop_search(kmi, "idname", bpy.context.window_manager, "operators_all", text="")
+ sub.prop(kmi, "idname", text="")
+ if map_type not in {'TEXTINPUT', 'TIMER'}:
sub = split.column()
subrow = sub.row(align=True)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index b1dfc397ce0..1965d11c22f 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -70,7 +70,8 @@ class VIEW3D_HT_header(Header):
row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
# Occlude geometry
- if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH')):
+ if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
+ (mode == 'WEIGHT_PAINT')):
row.prop(view, "use_occlude_geometry", text="")
# Proportional editing
@@ -1065,12 +1066,14 @@ class VIEW3D_MT_make_links(Menu):
def draw(self, context):
layout = self.layout
-
+ operator_context_default = layout.operator_context
if(len(bpy.data.scenes) > 10):
- layout.operator_context = 'INVOKE_DEFAULT'
+ layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("object.make_links_scene", text="Objects to Scene...", icon='OUTLINER_OB_EMPTY')
else:
+ layout.operator_context = 'EXEC_REGION_WIN'
layout.operator_menu_enum("object.make_links_scene", "scene", text="Objects to Scene...")
+ layout.operator_context = operator_context_default
layout.operator_enum("object.make_links_data", "type") # inline
@@ -1536,7 +1539,7 @@ class VIEW3D_MT_pose_group(Menu):
def draw(self, context):
layout = self.layout
-
+
pose = context.active_object.pose
layout.operator_context = 'EXEC_AREA'
@@ -1609,6 +1612,8 @@ class BoneOptions:
def draw(self, context):
layout = self.layout
+ default_context = bpy.app.translations.contexts.default
+
options = [
"show_wire",
"use_deform",
@@ -1628,7 +1633,8 @@ class BoneOptions:
opt_suffix = "bone."
for opt in options:
- props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name)
+ props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name,
+ text_ctxt=default_context)
props.data_path_iter = data_path_iter
props.data_path_item = opt_suffix + opt
props.type = self.type
@@ -1679,7 +1685,6 @@ class VIEW3D_MT_edit_mesh(Menu):
layout.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
layout.operator("mesh.duplicate_move")
layout.menu("VIEW3D_MT_edit_mesh_delete")
- layout.menu("VIEW3D_MT_edit_mesh_dissolve")
layout.separator()
@@ -1709,19 +1714,37 @@ class VIEW3D_MT_edit_mesh_specials(Menu):
layout.operator("mesh.subdivide", text="Subdivide").smoothness = 0.0
layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0
+
+ layout.separator()
+
layout.operator("mesh.merge", text="Merge...")
layout.operator("mesh.remove_doubles")
+
+ layout.separator()
+
layout.operator("mesh.hide", text="Hide").unselected = False
layout.operator("mesh.reveal", text="Reveal")
layout.operator("mesh.select_all", text="Select Inverse").action = 'INVERT'
+
+ layout.separator()
+
layout.operator("mesh.flip_normals")
layout.operator("mesh.vertices_smooth", text="Smooth")
layout.operator("mesh.vertices_smooth_laplacian", text="Laplacian Smooth")
+
+ layout.separator()
+
layout.operator("mesh.inset")
layout.operator("mesh.bevel", text="Bevel")
layout.operator("mesh.bridge_edge_loops")
+
+ layout.separator()
+
layout.operator("mesh.faces_shade_smooth")
layout.operator("mesh.faces_shade_flat")
+
+ layout.separator()
+
layout.operator("mesh.blend_from_shape")
layout.operator("mesh.shape_propagate_to_all")
layout.operator("mesh.select_vertex_path")
@@ -1788,10 +1811,11 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
layout.operator("mesh.split")
layout.operator_menu_enum("mesh.separate", "type")
layout.operator("mesh.vert_connect")
- layout.operator("mesh.vert_slide")
+ layout.operator("transform.vert_slide")
layout.separator()
+ layout.operator("mesh.bevel").vertex_only = True
layout.operator("mesh.vertices_smooth")
layout.operator("mesh.remove_doubles")
layout.operator("mesh.sort_elements", text="Sort Vertices").elements = {'VERT'}
@@ -1923,21 +1947,12 @@ class VIEW3D_MT_edit_mesh_delete(Menu):
layout.separator()
layout.operator("mesh.dissolve")
- layout.operator("mesh.edge_collapse")
- layout.operator("mesh.delete_edgeloop", text="Edge Loop")
-
-
-class VIEW3D_MT_edit_mesh_dissolve(Menu):
- bl_label = "Dissolve"
-
- def draw(self, context):
- layout = self.layout
-
- layout.operator("mesh.dissolve")
+ layout.operator("mesh.dissolve_limited")
layout.separator()
- layout.operator("mesh.dissolve_limited")
+ layout.operator("mesh.edge_collapse")
+ layout.operator("mesh.delete_edgeloop", text="Edge Loop")
class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu):
@@ -2381,9 +2396,6 @@ class VIEW3D_PT_view3d_display(Panel):
col.prop(view, "show_outline_selected")
col.prop(view, "show_all_objects_origin")
col.prop(view, "show_relationship_lines")
- if ob and ob.type == 'MESH':
- mesh = ob.data
- col.prop(mesh, "show_all_edges")
col = layout.column()
col.active = display_all
@@ -2408,7 +2420,10 @@ class VIEW3D_PT_view3d_display(Panel):
col.label(text="Shading:")
col.prop(gs, "material_mode", text="")
col.prop(view, "show_textured_solid")
-
+ if view.viewport_shade == 'SOLID':
+ col.prop(view, "use_matcap")
+ if view.use_matcap:
+ col.template_icon_view(view, "matcap_icon")
col.prop(view, "show_backface_culling")
layout.separator()
@@ -2665,6 +2680,8 @@ class VIEW3D_PT_etch_a_ton(Panel):
col.prop(toolsettings, "use_etch_quick")
col.prop(toolsettings, "use_etch_overdraw")
+ col.separator()
+
col.prop(toolsettings, "etch_convert_mode")
if toolsettings.etch_convert_mode == 'LENGTH':
@@ -2676,11 +2693,20 @@ class VIEW3D_PT_etch_a_ton(Panel):
elif toolsettings.etch_convert_mode == 'RETARGET':
col.prop(toolsettings, "etch_template")
col.prop(toolsettings, "etch_roll_mode")
- col.prop(toolsettings, "use_etch_autoname")
- col.prop(toolsettings, "etch_number")
- col.prop(toolsettings, "etch_side")
- col.operator("sketch.convert", text="Convert")
+ col.separator()
+
+ colsub = col.column(align=True)
+ colsub.prop(toolsettings, "use_etch_autoname")
+ sub = colsub.column()
+ sub.enabled = not toolsettings.use_etch_autoname
+ sub.prop(toolsettings, "etch_number")
+ sub.prop(toolsettings, "etch_side")
+
+ col.separator()
+
+ col.operator("sketch.convert", text="Convert to Bones")
+ col.operator("sketch.delete", text="Delete Strokes")
class VIEW3D_PT_context_properties(Panel):
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 91132a72b07..05c1793b29f 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -20,7 +20,7 @@
import bpy
from bpy.types import Menu, Panel
from bl_ui.properties_paint_common import UnifiedPaintPanel
-from bl_ui.properties_paint_common import sculpt_brush_texture_settings
+from bl_ui.properties_paint_common import brush_texture_settings
class View3DPanel():
@@ -108,6 +108,33 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
draw_repeat_tools(context, layout)
draw_gpencil_tools(context, layout)
+ col = layout.column(align=True)
+
+
+class VIEW3D_PT_tools_rigidbody(View3DPanel, Panel):
+ bl_context = "objectmode"
+ bl_label = "Rigid Body Tools"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ col = layout.column(align=True)
+ col.label(text="Add/Remove:")
+ row = col.row()
+ row.operator("rigidbody.objects_add", text="Add Active").type = 'ACTIVE'
+ row.operator("rigidbody.objects_add", text="Add Passive").type = 'PASSIVE'
+ row = col.row()
+ row.operator("rigidbody.objects_remove", text="Remove")
+
+ col = layout.column(align=True)
+ col.label(text="Object Tools:")
+ col.operator("rigidbody.shape_change", text="Change Shape")
+ col.operator("rigidbody.mass_calculate", text="Calculate Mass")
+ col.operator("rigidbody.object_settings_copy", text="Copy from Active")
+ col.operator("rigidbody.bake_to_keyframes", text="Bake To Keyframes")
+ col.label(text="Constraints:")
+ col.operator("rigidbody.connect", text="Connect")
# ********** default tools for editmode_mesh ****************
@@ -237,6 +264,8 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
col.operator("curve.cyclic_toggle")
col.operator("curve.switch_direction")
col.operator("curve.spline_type_set")
+ col.operator("curve.radius_set")
+ col.operator("curve.smooth_radius")
col = layout.column(align=True)
col.label(text="Handles:")
@@ -251,6 +280,7 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
col.label(text="Modeling:")
col.operator("curve.extrude_move", text="Extrude")
col.operator("curve.subdivide")
+ col.operator("curve.smooth")
draw_repeat_tools(context, layout)
@@ -720,12 +750,10 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
col = layout.column()
col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
- if brush.use_paint_image:
- col.prop(brush, "use_fixed_texture")
- if context.sculpt_object:
- sculpt_brush_texture_settings(col, brush)
+ brush_texture_settings(col, brush, context.sculpt_object)
+ if context.sculpt_object:
# use_texture_overlay and texture_overlay_alpha
col = layout.column(align=True)
col.active = brush.sculpt_capabilities.has_overlay
@@ -854,6 +882,36 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
+class VIEW3D_PT_sculpt_topology(Panel, View3DPaintPanel):
+ bl_label = "Topology"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ return (context.sculpt_object and context.tool_settings.sculpt)
+
+ def draw(self, context):
+ layout = self.layout
+
+ toolsettings = context.tool_settings
+ sculpt = toolsettings.sculpt
+
+ if context.sculpt_object.use_dynamic_topology_sculpting:
+ layout.operator("sculpt.dynamic_topology_toggle", icon='X', text="Disable Dynamic")
+ else:
+ layout.operator("sculpt.dynamic_topology_toggle", icon='SCULPT_DYNTOPO', text="Enable Dynamic")
+
+ col = layout.column()
+ col.active = context.sculpt_object.use_dynamic_topology_sculpting
+ col.prop(sculpt, "detail_size")
+ col.prop(sculpt, "use_smooth_shading")
+ col.prop(sculpt, "use_edge_collapse")
+ col.operator("sculpt.optimize")
+ col.separator()
+ col.prop(sculpt, "symmetrize_direction")
+ col.operator("sculpt.symmetrize")
+
+
class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
bl_label = "Options"
bl_options = {'DEFAULT_CLOSED'}
@@ -971,6 +1029,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
col.operator("object.vertex_group_transfer_weight", text="Transfer Weights")
col.operator("object.vertex_group_limit_total", text="Limit Total")
col.operator("object.vertex_group_fix", text="Fix Deforms")
+ col.operator("paint.weight_gradient")
class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
@@ -998,6 +1057,11 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
col.prop(wpaint, "input_samples")
+ col.label("Show Zero Weights:")
+ rowsub = col.row()
+ rowsub.active = (not tool_settings.use_multipaint)
+ rowsub.prop(tool_settings, "vertex_group_user", expand=True)
+
self.unified_paint_settings(col, context)
# Commented out because the Apply button isn't an operator yet, making these settings useless
@@ -1086,14 +1150,14 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
row = split.row()
row.active = (ipaint.use_stencil_layer)
stencil_text = mesh.uv_texture_stencil.name if mesh.uv_texture_stencil else ""
- row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text)
+ row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False)
row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
- row = layout.row()
- row.active = (settings.brush.image_tool == 'CLONE')
- row.prop(ipaint, "use_clone_layer", text="Clone")
+ col = layout.column()
+ col.active = (settings.brush.image_tool == 'CLONE')
+ col.prop(ipaint, "use_clone_layer", text="Clone from UV map")
clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else ""
- row.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text)
+ col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text, translate=False)
layout.prop(ipaint, "seam_bleed")
@@ -1132,7 +1196,7 @@ class VIEW3D_MT_tools_projectpaint_clone(Menu):
layout = self.layout
for i, tex in enumerate(context.active_object.data.uv_textures):
- props = layout.operator("wm.context_set_int", text=tex.name)
+ props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
props.data_path = "active_object.data.uv_texture_clone_index"
props.value = i
@@ -1143,7 +1207,7 @@ class VIEW3D_MT_tools_projectpaint_stencil(Menu):
def draw(self, context):
layout = self.layout
for i, tex in enumerate(context.active_object.data.uv_textures):
- props = layout.operator("wm.context_set_int", text=tex.name)
+ props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
props.data_path = "active_object.data.uv_texture_stencil_index"
props.value = i
@@ -1166,7 +1230,8 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
if pe.type == 'PARTICLES':
if ob.particle_systems:
if len(ob.particle_systems) > 1:
- layout.template_list(ob, "particle_systems", ob.particle_systems, "active_index", rows=2, maxrows=3)
+ layout.template_list("UI_UL_list", "particle_systems", ob, "particle_systems",
+ ob.particle_systems, "active_index", rows=2, maxrows=3)
ptcache = ob.particle_systems.active.point_cache
else:
@@ -1175,7 +1240,8 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
ptcache = md.point_cache
if ptcache and len(ptcache.point_caches) > 1:
- layout.template_list(ptcache, "point_caches", ptcache.point_caches, "active_index", rows=2, maxrows=3)
+ layout.template_list("UI_UL_list", "particles_point_caches", ptcache, "point_caches",
+ ptcache.point_caches, "active_index", rows=2, maxrows=3)
if not pe.is_editable:
layout.label(text="Point cache must be baked")
diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py
index 6ad87375738..4f06f8a7be3 100644
--- a/release/scripts/startup/keyingsets_builtins.py
+++ b/release/scripts/startup/keyingsets_builtins.py
@@ -181,7 +181,7 @@ class BUILTIN_KSI_RotScale(KeyingSetInfo):
# ------------
-# Location
+# VisualLocation
class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
"""
Insert a keyframe on each of the location channels, taking into account
@@ -201,7 +201,7 @@ class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
generate = keyingsets_utils.RKS_GEN_location
-# Rotation
+# VisualRotation
class BUILTIN_KSI_VisualRot(KeyingSetInfo):
"""
Insert a keyframe on each of the rotation channels, taking into account
@@ -221,6 +221,26 @@ class BUILTIN_KSI_VisualRot(KeyingSetInfo):
generate = keyingsets_utils.RKS_GEN_rotation
+# VisualScaling
+class BUILTIN_KSI_VisualScaling(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the scale channels, taking into account
+ effects of constraints and relationships
+ """
+ bl_label = "Visual Scaling"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator - use callback for location
+ generate = keyingsets_utils.RKS_GEN_scaling
+
+
# VisualLocRot
class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
"""
@@ -244,6 +264,80 @@ class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
# rotation
keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
+
+# VisualLocScale
+class BUILTIN_KSI_VisualLocScale(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the location and scaling channels,
+ taking into account effects of constraints and relationships
+ """
+ bl_label = "Visual LocScale"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator
+ def generate(self, context, ks, data):
+ # location
+ keyingsets_utils.RKS_GEN_location(self, context, ks, data)
+ # scaling
+ keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+
+
+# VisualLocRotScale
+class BUILTIN_KSI_VisualLocRotScale(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the location, rotation and scaling channels,
+ taking into account effects of constraints and relationships
+ """
+ bl_label = "Visual LocRotScale"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator
+ def generate(self, context, ks, data):
+ # location
+ keyingsets_utils.RKS_GEN_location(self, context, ks, data)
+ # rotation
+ keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
+ # scaling
+ keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+
+
+# VisualRotScale
+class BUILTIN_KSI_VisualRotScale(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the rotation and scaling channels,
+ taking into account effects of constraints and relationships
+ """
+ bl_label = "Visual RotScale"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator
+ def generate(self, context, ks, data):
+ # rotation
+ keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
+ # scaling
+ keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+
# ------------
diff --git a/release/scripts/templates_osl/empty_shader.osl b/release/scripts/templates_osl/empty_shader.osl
new file mode 100644
index 00000000000..e2c9a4a257e
--- /dev/null
+++ b/release/scripts/templates_osl/empty_shader.osl
@@ -0,0 +1,6 @@
+
+shader name()
+{
+
+}
+
diff --git a/release/scripts/templates_osl/noise.osl b/release/scripts/templates_osl/noise.osl
new file mode 100644
index 00000000000..05cc31687c0
--- /dev/null
+++ b/release/scripts/templates_osl/noise.osl
@@ -0,0 +1,18 @@
+
+shader noise(
+ float Time = 1.0,
+ point Point = P,
+ output float Cell = 0.0,
+ output color Perlin = 0.8,
+ output color UPerlin = 0.8)
+{
+ /* Cell Noise */
+ Cell = noise("cell", Point);
+
+ /* Perlin 4D Noise*/
+ Perlin = noise("perlin", Point, Time);
+
+ /* UPerlin 4D Noise*/
+ UPerlin = noise("uperlin", Point, Time);
+}
+
diff --git a/release/scripts/templates_osl/wireframe.osl b/release/scripts/templates_osl/wireframe.osl
new file mode 100644
index 00000000000..00e4506e73c
--- /dev/null
+++ b/release/scripts/templates_osl/wireframe.osl
@@ -0,0 +1,11 @@
+
+#include "oslutil.h"
+
+shader wireframe(
+ float Line_Width = 2.0,
+ int Raster = 1,
+ output float Wire = 0.0)
+{
+ Wire = wireframe("triangles", Line_Width, Raster);
+}
+
diff --git a/release/scripts/templates/addon_add_object.py b/release/scripts/templates_py/addon_add_object.py
index a4df5fb7436..66da6a969c7 100644
--- a/release/scripts/templates/addon_add_object.py
+++ b/release/scripts/templates_py/addon_add_object.py
@@ -2,7 +2,7 @@ bl_info = {
"name": "New Object",
"author": "Your Name Here",
"version": (1, 0),
- "blender": (2, 5, 5),
+ "blender": (2, 65, 0),
"location": "View3D > Add > Mesh > New Object",
"description": "Adds a new Mesh Object",
"warning": "",
diff --git a/release/scripts/templates/background_job.py b/release/scripts/templates_py/background_job.py
index 11b51e5a9b5..11b51e5a9b5 100644
--- a/release/scripts/templates/background_job.py
+++ b/release/scripts/templates_py/background_job.py
diff --git a/release/scripts/templates/batch_export.py b/release/scripts/templates_py/batch_export.py
index 45d26f4b525..45d26f4b525 100644
--- a/release/scripts/templates/batch_export.py
+++ b/release/scripts/templates_py/batch_export.py
diff --git a/release/scripts/templates/bmesh_simple.py b/release/scripts/templates_py/bmesh_simple.py
index 45e6b52d578..45e6b52d578 100644
--- a/release/scripts/templates/bmesh_simple.py
+++ b/release/scripts/templates_py/bmesh_simple.py
diff --git a/release/scripts/templates/bmesh_simple_editmode.py b/release/scripts/templates_py/bmesh_simple_editmode.py
index d79ba02c2cb..d79ba02c2cb 100644
--- a/release/scripts/templates/bmesh_simple_editmode.py
+++ b/release/scripts/templates_py/bmesh_simple_editmode.py
diff --git a/release/scripts/templates/builtin_keyingset.py b/release/scripts/templates_py/builtin_keyingset.py
index 19f92dc75e7..19f92dc75e7 100644
--- a/release/scripts/templates/builtin_keyingset.py
+++ b/release/scripts/templates_py/builtin_keyingset.py
diff --git a/release/scripts/templates/driver_functions.py b/release/scripts/templates_py/driver_functions.py
index 1c6af0e574f..1c6af0e574f 100644
--- a/release/scripts/templates/driver_functions.py
+++ b/release/scripts/templates_py/driver_functions.py
diff --git a/release/scripts/templates/gamelogic.py b/release/scripts/templates_py/gamelogic.py
index 01ac27c56cd..01ac27c56cd 100644
--- a/release/scripts/templates/gamelogic.py
+++ b/release/scripts/templates_py/gamelogic.py
diff --git a/release/scripts/templates/gamelogic_module.py b/release/scripts/templates_py/gamelogic_module.py
index 88c8cf0d75b..88c8cf0d75b 100644
--- a/release/scripts/templates/gamelogic_module.py
+++ b/release/scripts/templates_py/gamelogic_module.py
diff --git a/release/scripts/templates/gamelogic_simple.py b/release/scripts/templates_py/gamelogic_simple.py
index dbfcf948b18..dbfcf948b18 100644
--- a/release/scripts/templates/gamelogic_simple.py
+++ b/release/scripts/templates_py/gamelogic_simple.py
diff --git a/release/scripts/templates/operator_file_export.py b/release/scripts/templates_py/operator_file_export.py
index 9511cb163bc..9511cb163bc 100644
--- a/release/scripts/templates/operator_file_export.py
+++ b/release/scripts/templates_py/operator_file_export.py
diff --git a/release/scripts/templates/operator_file_import.py b/release/scripts/templates_py/operator_file_import.py
index 9940a1b98eb..9940a1b98eb 100644
--- a/release/scripts/templates/operator_file_import.py
+++ b/release/scripts/templates_py/operator_file_import.py
diff --git a/release/scripts/templates/operator_mesh_add.py b/release/scripts/templates_py/operator_mesh_add.py
index fa248cb9005..fa248cb9005 100644
--- a/release/scripts/templates/operator_mesh_add.py
+++ b/release/scripts/templates_py/operator_mesh_add.py
diff --git a/release/scripts/templates/operator_modal.py b/release/scripts/templates_py/operator_modal.py
index 88e5ee80590..88e5ee80590 100644
--- a/release/scripts/templates/operator_modal.py
+++ b/release/scripts/templates_py/operator_modal.py
diff --git a/release/scripts/templates/operator_modal_draw.py b/release/scripts/templates_py/operator_modal_draw.py
index f1c4e113b0a..d11ddf0b467 100644
--- a/release/scripts/templates/operator_modal_draw.py
+++ b/release/scripts/templates_py/operator_modal_draw.py
@@ -42,20 +42,22 @@ class ModalDrawOperator(bpy.types.Operator):
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
elif event.type == 'LEFTMOUSE':
- context.region.callback_remove(self._handle)
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'FINISHED'}
elif event.type in {'RIGHTMOUSE', 'ESC'}:
- context.region.callback_remove(self._handle)
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
if context.area.type == 'VIEW_3D':
+ # the arguments we pass the the callback
+ args = (self, context)
# Add the region OpenGL drawing callback
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
- self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
+ self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
self.mouse_path = []
diff --git a/release/scripts/templates/operator_modal_timer.py b/release/scripts/templates_py/operator_modal_timer.py
index 72c153df9d2..3088d59fbcf 100644
--- a/release/scripts/templates/operator_modal_timer.py
+++ b/release/scripts/templates_py/operator_modal_timer.py
@@ -14,7 +14,7 @@ class ModalTimerOperator(bpy.types.Operator):
if event.type == 'TIMER':
# change theme color, silly!
- color = context.user_preferences.themes[0].view_3d.space.back
+ color = context.user_preferences.themes[0].view_3d.space.gradients.high_gradient
color.s = 1.0
color.h += 0.01
diff --git a/release/scripts/templates/operator_modal_view3d.py b/release/scripts/templates_py/operator_modal_view3d.py
index c870bbffdcf..c870bbffdcf 100644
--- a/release/scripts/templates/operator_modal_view3d.py
+++ b/release/scripts/templates_py/operator_modal_view3d.py
diff --git a/release/scripts/templates/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py
index 3236c08cc8c..eac76922187 100644
--- a/release/scripts/templates/operator_modal_view3d_raycast.py
+++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py
@@ -16,7 +16,6 @@ def main(context, event, ray_max=10000.0):
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
ray_target = ray_origin + (view_vector * ray_max)
- scene.cursor_location = ray_target
def visible_objects_and_duplis():
"""Loop over (object, matrix) pairs (mesh only)"""
@@ -58,7 +57,9 @@ def main(context, event, ray_max=10000.0):
if obj.type == 'MESH':
hit, normal, face_index = obj_ray_cast(obj, matrix)
if hit is not None:
- length_squared = (hit - ray_origin).length_squared
+ hit_world = matrix * hit
+ scene.cursor_location = hit_world
+ length_squared = (hit_world - ray_origin).length_squared
if length_squared < best_length_squared:
best_length_squared = length_squared
best_obj = obj
@@ -67,6 +68,7 @@ def main(context, event, ray_max=10000.0):
# we could do lots of stuff but for the example just select.
if best_obj is not None:
best_obj.select = True
+ context.scene.objects.active = best_obj
class ViewOperatorRayCast(bpy.types.Operator):
@@ -105,3 +107,4 @@ def unregister():
if __name__ == "__main__":
register()
+
diff --git a/release/scripts/templates/operator_node.py b/release/scripts/templates_py/operator_node.py
index b689ce7634e..b689ce7634e 100644
--- a/release/scripts/templates/operator_node.py
+++ b/release/scripts/templates_py/operator_node.py
diff --git a/release/scripts/templates/operator_simple.py b/release/scripts/templates_py/operator_simple.py
index 715daa3a8b4..715daa3a8b4 100644
--- a/release/scripts/templates/operator_simple.py
+++ b/release/scripts/templates_py/operator_simple.py
diff --git a/release/scripts/templates/operator_uv.py b/release/scripts/templates_py/operator_uv.py
index fdd0b993f8b..fdd0b993f8b 100644
--- a/release/scripts/templates/operator_uv.py
+++ b/release/scripts/templates_py/operator_uv.py
diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates_py/script_stub.py
index 44c7b802e2c..44c7b802e2c 100644
--- a/release/scripts/templates/script_stub.py
+++ b/release/scripts/templates_py/script_stub.py
diff --git a/release/scripts/templates_py/ui_list.py b/release/scripts/templates_py/ui_list.py
new file mode 100644
index 00000000000..f71b342c854
--- /dev/null
+++ b/release/scripts/templates_py/ui_list.py
@@ -0,0 +1,79 @@
+import bpy
+
+
+class MATERIAL_UL_matslots_example(bpy.types.UIList):
+ # The draw_item function is called for each item of the collection that is visible in the list.
+ # data is the RNA object containing the collection,
+ # item is the current drawn item of the collection,
+ # icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
+ # have custom icons ID, which are not available as enum items).
+ # active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
+ # active item of the collection).
+ # active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
+ # index is index of the current item in the collection.
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ ob = data
+ slot = item
+ ma = slot.material
+ # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ # You should always start your row layout by a label (icon + text), this will also make the row easily
+ # selectable in the list!
+ # We use icon_value of label, as our given icon is an integer value, not an enum ID.
+ # Note "data" names should never be translated!
+ layout.label(text=ma.name if ma else "", translate=False, icon_value=icon)
+ # And now we can add other UI stuff...
+ # Here, we add nodes info if this material uses (old!) shading nodes.
+ if ma and not context.scene.render.use_shading_nodes:
+ manode = ma.active_node_material
+ if manode:
+ # The static method UILayout.icon returns the integer value of the icon ID "computed" for the given
+ # RNA object.
+ layout.label(text="Node %s" % manode.name, translate=False, icon_value=layout.icon(manode))
+ elif ma.use_nodes:
+ layout.label(text="Node <none>", translate=False)
+ else:
+ layout.label(text="")
+ # 'GRID' layout type should be as compact as possible (typically a single icon!).
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
+# And now we can use this list everywhere in Blender. Here is a small example panel.
+class UIListPanelExample(bpy.types.Panel):
+ """Creates a Panel in the Object properties window"""
+ bl_label = "UIList Panel"
+ bl_idname = "OBJECT_PT_ui_list_example"
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "object"
+
+ def draw(self, context):
+ layout = self.layout
+
+ obj = context.object
+
+ # template_list now takes two new args.
+ # The first one is the identifier of the registered UIList to use (if you want only the default list,
+ # with no custom draw code, use "UI_UL_list").
+ layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index")
+
+ # The second one can usually be left as an empty string. It's an additional ID used to distinguish lists in case you
+ # use the same list several times in a given area.
+ layout.template_list("MATERIAL_UL_matslots_example", "compact", obj, "material_slots",
+ obj, "active_material_index", type='COMPACT')
+
+
+def register():
+ bpy.utils.register_class(MATERIAL_UL_matslots_example)
+ bpy.utils.register_class(UIListPanelExample)
+
+
+def unregister():
+ bpy.utils.unregister_class(MATERIAL_UL_matslots_example)
+ bpy.utils.unregister_class(UIListPanelExample)
+
+
+if __name__ == "__main__":
+ register() \ No newline at end of file
diff --git a/release/scripts/templates/ui_menu.py b/release/scripts/templates_py/ui_menu.py
index a21e5ed86c8..a21e5ed86c8 100644
--- a/release/scripts/templates/ui_menu.py
+++ b/release/scripts/templates_py/ui_menu.py
diff --git a/release/scripts/templates/ui_menu_simple.py b/release/scripts/templates_py/ui_menu_simple.py
index 2129dfd81a4..2129dfd81a4 100644
--- a/release/scripts/templates/ui_menu_simple.py
+++ b/release/scripts/templates_py/ui_menu_simple.py
diff --git a/release/scripts/templates/ui_panel.py b/release/scripts/templates_py/ui_panel.py
index cacdb83e815..cacdb83e815 100644
--- a/release/scripts/templates/ui_panel.py
+++ b/release/scripts/templates_py/ui_panel.py
diff --git a/release/scripts/templates/ui_panel_simple.py b/release/scripts/templates_py/ui_panel_simple.py
index 9bcc750560f..9bcc750560f 100644
--- a/release/scripts/templates/ui_panel_simple.py
+++ b/release/scripts/templates_py/ui_panel_simple.py
diff --git a/release/text/readme.html b/release/text/readme.html
index 414a7d8e744..54d112c5e2b 100644
--- a/release/text/readme.html
+++ b/release/text/readme.html
@@ -12,18 +12,18 @@
</style>
</head>
<body>
-<p class="title"><b>Blender 2.65</b></p>
+<p class="title"><b>Blender 2.66</b></p>
<p><br></p>
<p class="header"><b>About</b></p>
<p class="body">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, Windows and FreeBSD and has a large world-wide community.</p>
<p class="body">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="body">For more information, visit <a href="http://www.blender.org">blender.org</a>.</p>
<p><br></p>
-<p class="header"><b>2.65</b></p>
-<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.65. This release is the sixth official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features. <a href="http://www.blender.org/development/release-logs/blender-265/">More information about this release</a>.</p>
+<p class="header"><b>2.66</b></p>
+<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.66. This release is the seventh official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features. <a href="http://www.blender.org/development/release-logs/blender-266/">More information about this release</a>.</p>
<p><br></p>
<p class="header"><b>Bugs</b></p>
-<p class="body">Although Blender 2.65 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 → 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="body">Although Blender 2.66 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 → 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><br></p>
<p class="header"><b>Package Contents</b></p>
<p class="body">The downloaded Blender package includes:</p>
@@ -47,7 +47,7 @@
<p class="header"><b>Links</b></p>
<p class="body">Users:</p>
<p class="body"> General information <a href="http://www.blender.org">www.blender.org</a> <br>
- Full release log <a href="http://www.blender.org/development/release-logs/blender-265/">www.blender.org/development/release-logs/blender-265/</a><br>
+ Full release log <a href="http://www.blender.org/development/release-logs/blender-266/">www.blender.org/development/release-logs/blender-266/</a><br>
Tutorials <a href="http://www.blender.org/education-help/">www.blender.org/education-help/</a> <br>
Manual <a href="http://wiki.blender.org/index.php/Doc:2.6/Manual">wiki.blender.org/index.php/Doc:2.6/Manual</a><br>
User Forum <a href="http://www.blenderartists.org">www.blenderartists.org</a><br>
diff --git a/source/SConscript b/source/SConscript
index fdd126b28c6..432cfb31c7d 100644
--- a/source/SConscript
+++ b/source/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
SConscript(['blender/SConscript'])
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index ae3f3dce396..50e13188965 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -66,6 +66,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_packedFile_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_particle_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_property_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_rigidbody_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_scene_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_screen_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_sdna_types.h
@@ -107,7 +108,6 @@ add_subdirectory(makesdna)
add_subdirectory(makesrna)
if(WITH_COMPOSITOR)
- add_subdirectory(opencl) # later on this may be used more generally
add_subdirectory(compositor)
endif()
diff --git a/source/blender/SConscript b/source/blender/SConscript
index e1f81f9aaba..8a4e2a39aa1 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import sys
@@ -39,5 +65,4 @@ if env['WITH_BF_COLLADA']:
SConscript (['collada/SConscript'])
if env['WITH_BF_COMPOSITOR']:
- SConscript (['compositor/SConscript',
- 'opencl/SConscript'])
+ SConscript (['compositor/SConscript'])
diff --git a/source/blender/avi/SConscript b/source/blender/avi/SConscript
index 4d2ce8fd845..0e46781b768 100644
--- a/source/blender/avi/SConscript
+++ b/source/blender/avi/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c
index d6301b723a7..fcc9526b58a 100644
--- a/source/blender/avi/intern/avi.c
+++ b/source/blender/avi/intern/avi.c
@@ -950,7 +950,6 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...)
{
AviList list;
AviChunk chunk;
- AviIndexEntry *temp;
va_list ap;
int stream;
int64_t rec_off;
@@ -965,15 +964,7 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...)
if (frame_num + 1 > movie->index_entries) {
const size_t entry_size = (movie->header->Streams + 1) * sizeof(AviIndexEntry);
-
- if (movie->entries != NULL) {
- temp = (AviIndexEntry *)MEM_recallocN(movie->entries, (frame_num + 1) * entry_size);
- }
- else {
- temp = (AviIndexEntry *) MEM_callocN((frame_num + 1) * entry_size, "newidxentry");
- }
-
- movie->entries = temp;
+ movie->entries = (AviIndexEntry *)MEM_recallocN(movie->entries, (frame_num + 1) * entry_size);
movie->index_entries = frame_num + 1;
}
diff --git a/source/blender/avi/intern/avi_endian.c b/source/blender/avi/intern/avi_endian.c
index 70add8bd90f..9720d83f2c8 100644
--- a/source/blender/avi/intern/avi_endian.c
+++ b/source/blender/avi/intern/avi_endian.c
@@ -49,7 +49,7 @@
#ifdef __BIG_ENDIAN__
/* copied from BLI_endian_switch_inline.h */
-static void invert(int *num)
+static void invert(int *val)
{
int tval = *val;
*val = ((tval >> 24)) |
diff --git a/source/blender/avi/intern/avi_intern.h b/source/blender/avi/intern/avi_intern.h
index c8d54fe99e9..5dc48657831 100644
--- a/source/blender/avi/intern/avi_intern.h
+++ b/source/blender/avi/intern/avi_intern.h
@@ -37,9 +37,27 @@
unsigned int GET_FCC (FILE *fp);
unsigned int GET_TCC (FILE *fp);
-#define PUT_FCC(ch4, fp) putc(ch4[0],fp); putc(ch4[1],fp); putc(ch4[2],fp); putc(ch4[3],fp)
-#define PUT_FCCN(num, fp) putc((num>>0)&0377,fp); putc((num>>8)&0377,fp); putc((num>>16)&0377,fp); putc((num>>24)&0377,fp)
-#define PUT_TCC(ch2, fp) putc(ch2[0],fp); putc(ch2[1],fp)
+#define PUT_FCC(ch4, fp) \
+{ \
+ putc(ch4[0], fp); \
+ putc(ch4[1], fp); \
+ putc(ch4[2], fp); \
+ putc(ch4[3], fp); \
+} (void)0
+
+#define PUT_FCCN(num, fp) \
+{ \
+ putc((num >> 0) & 0377, fp); \
+ putc((num >> 8) & 0377, fp); \
+ putc((num >> 16) & 0377, fp); \
+ putc((num >> 24) & 0377, fp); \
+} (void)0
+
+#define PUT_TCC(ch2, fp) \
+{ \
+ putc(ch2[0], fp); \
+ putc(ch2[1], fp); \
+} (void)0
void *avi_format_convert (AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size);
diff --git a/source/blender/avi/intern/avi_mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c
index 396f1199cd9..91b8fa5a060 100644
--- a/source/blender/avi/intern/avi_mjpeg.c
+++ b/source/blender/avi/intern/avi_mjpeg.c
@@ -206,7 +206,7 @@ static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsign
return 1;
}
-static void Compress_JPEG(int quality, unsigned char *outbuffer, unsigned char *inBuffer, int width, int height, int bufsize)
+static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned char *inBuffer, int width, int height, int bufsize)
{
int i, rowstride;
unsigned int y;
@@ -316,7 +316,8 @@ static int check_and_decode_jpeg(unsigned char *inbuf, unsigned char *outbuf, in
}
}
-static void check_and_compress_jpeg(int quality, unsigned char *outbuf, unsigned char *inbuf, int width, int height, int bufsize)
+static void check_and_compress_jpeg(int quality, unsigned char *outbuf, const unsigned char *inbuf,
+ int width, int height, int bufsize)
{
/* JPEG's are always multiples of 16, extra is ignored in AVI's */
if ((width & 0xF) || (height & 0xF)) {
@@ -379,7 +380,11 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 1");
if (!movie->interlace) {
- check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100, buf, buffer, movie->header->Width, movie->header->Height, bufsize);
+ check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100,
+ buf, buffer,
+ movie->header->Width,
+ movie->header->Height,
+ bufsize);
}
else {
deinterlace(movie->odd_fields, buf, buffer, movie->header->Width, movie->header->Height);
@@ -388,10 +393,18 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buffer = buf;
buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 2");
- check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100, buf, buffer, movie->header->Width, movie->header->Height / 2, bufsize / 2);
+ check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100,
+ buf, buffer,
+ movie->header->Width,
+ movie->header->Height / 2,
+ bufsize / 2);
*size += numbytes;
numbytes = 0;
- check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100, buf + *size, buffer + (movie->header->Height / 2) * movie->header->Width * 3, movie->header->Width, movie->header->Height / 2, bufsize / 2);
+ check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100,
+ buf + *size, buffer + (movie->header->Height / 2) * movie->header->Width * 3,
+ movie->header->Width,
+ movie->header->Height / 2,
+ bufsize / 2);
}
*size += numbytes;
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 6f348ccc267..0ca97975d87 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -37,6 +37,7 @@ struct ColorManagedDisplay;
int BLF_init(int points, int dpi);
void BLF_exit(void);
+void BLF_default_dpi(int dpi);
void BLF_cache_clear(void);
@@ -182,6 +183,7 @@ void BLF_dir_free(char **dirs, int count);
#define BLF_KERNING_DEFAULT (1 << 3)
#define BLF_MATRIX (1 << 4)
#define BLF_ASPECT (1 << 5)
+#define BLF_HINTING (1 << 6)
#define BLF_DRAW_STR_DUMMY_MAX 1024
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h
index 159d4b067b6..cbfc7c28d8d 100644
--- a/source/blender/blenfont/BLF_translation.h
+++ b/source/blender/blenfont/BLF_translation.h
@@ -33,6 +33,8 @@
#ifndef __BLF_TRANSLATION_H__
#define __BLF_TRANSLATION_H__
+#include "BLI_utildefines.h" /* for bool type */
+
#define TEXT_DOMAIN_NAME "blender"
/* blf_lang.c */
@@ -48,24 +50,30 @@ void BLF_lang_free(void);
/* Set the current locale. */
void BLF_lang_set(const char *);
-/* Get the current locale (short code, e.g. es_ES). */
+/* Get the current locale ([partial] ISO code, e.g. es_ES). */
const char *BLF_lang_get(void);
+/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant,
+ * *variant and *language_variant will always be NULL).
+ * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them.
+ * NOTE: Always available, even in non-WITH_INTERNATIONAL builds.
+ */
+void BLF_locale_explode(const char *locale, char **language, char **country, char **variant,
+ char **language_country, char **language_variant);
+
/* Get EnumPropertyItem's for translations menu. */
struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void);
/* blf_translation.c */
-#ifdef WITH_INTERNATIONAL
unsigned char *BLF_get_unifont(int *unifont_size);
void BLF_free_unifont(void);
-#endif
const char *BLF_pgettext(const char *msgctxt, const char *msgid);
/* translation */
-int BLF_translate_iface(void);
-int BLF_translate_tooltips(void);
+bool BLF_translate_iface(void);
+bool BLF_translate_tooltips(void);
const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid);
const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
@@ -76,17 +84,17 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
/* Those macros should be used everywhere in UI code. */
#ifdef WITH_INTERNATIONAL
-/* #define _(msgid) BLF_gettext(msgid) */
- #define IFACE_(msgid) BLF_translate_do_iface(NULL, msgid)
- #define TIP_(msgid) BLF_translate_do_tooltip(NULL, msgid)
- #define CTX_IFACE_(context, msgid) BLF_translate_do_iface(context, msgid)
- #define CTX_TIP_(context, msgid) BLF_translate_do_tooltip(context, msgid)
+/*# define _(msgid) BLF_gettext(msgid) */
+# define IFACE_(msgid) BLF_translate_do_iface(NULL, msgid)
+# define TIP_(msgid) BLF_translate_do_tooltip(NULL, msgid)
+# define CTX_IFACE_(context, msgid) BLF_translate_do_iface(context, msgid)
+# define CTX_TIP_(context, msgid) BLF_translate_do_tooltip(context, msgid)
#else
-/* #define _(msgid) msgid */
- #define IFACE_(msgid) msgid
- #define TIP_(msgid) msgid
- #define CTX_IFACE_(context, msgid) ((void)context, msgid)
- #define CTX_TIP_(context, msgid) ((void)context, msgid)
+/*# define _(msgid) msgid */
+# define IFACE_(msgid) msgid
+# define TIP_(msgid) msgid
+# define CTX_IFACE_(context, msgid) msgid
+# define CTX_TIP_(context, msgid) msgid
#endif
/* Helper macro, when we want to define a same msgid for multiple msgctxt...
@@ -102,8 +110,15 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
* things, and limit the number of existing contexts!
*/
-/* Default, void context. Just in case... */
-#define BLF_I18NCONTEXT_DEFAULT ""
+/* Default, void context.
+ * WARNING! The "" context is not the same as no (NULL) context at mo/boost::locale level!
+ * NOTE: We translate BLF_I18NCONTEXT_DEFAULT as BLF_I18NCONTEXT_DEFAULT_BPY in Python, as we can't use "natural"
+ * None value in rna string properties... :/
+ * For perf reason, we only use the first char to detect this context, so other contexts should never start
+ * with the same char!
+ */
+#define BLF_I18NCONTEXT_DEFAULT NULL
+#define BLF_I18NCONTEXT_DEFAULT_BPY "*"
/* Default context for operator names/labels. */
#define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator"
@@ -143,4 +158,53 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
#define BLF_I18NCONTEXT_ID_MOVIECLIP "MovieClip"
#define BLF_I18NCONTEXT_ID_MASK "Mask"
+/* Helper for bpy.app.i18n object... */
+typedef struct
+{
+ const char *c_id;
+ const char *py_id;
+ const char *value;
+} BLF_i18n_contexts_descriptor;
+
+#define BLF_I18NCONTEXTS_ITEM(ctxt_id, py_id) {#ctxt_id, py_id, ctxt_id}
+
+#define BLF_I18NCONTEXTS_DESC { \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT, "default_real"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT_BPY, "default"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "operator_default"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ACTION, "id_action"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ARMATURE, "id_armature"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_BRUSH, "id_brush"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_CAMERA, "id_camera"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_CURVE, "id_curve"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_GPENCIL, "id_gpencil"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_GROUP, "id_group"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ID, "id_id"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_IMAGE, "id_image"), \
+ /*BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_IPO, "id_ipo"),*/ \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SHAPEKEY, "id_shapekey"), \
+ 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_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_NODETREE, "id_nodetree"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_OBJECT, "id_object"), \
+ 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"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SEQUENCE, "id_sequence"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SPEAKER, "id_speaker"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SOUND, "id_sound"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_TEXTURE, "id_texture"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_TEXT, "id_text"), \
+ 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} \
+}
+
#endif /* __BLF_TRANSLATION_H__ */
diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt
index 90baef14a74..7bb80c34323 100644
--- a/source/blender/blenfont/CMakeLists.txt
+++ b/source/blender/blenfont/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../editors/include
../makesdna
../makesrna
+ ../python
../imbuf
../../../intern/guardedalloc
../../../intern/locale
diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript
index c0591c877ef..3529330a308 100644
--- a/source/blender/blenfont/SConscript
+++ b/source/blender/blenfont/SConscript
@@ -1,11 +1,37 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
sources = env.Glob('intern/*.c')
incs = '. intern #/intern/guardedalloc #/intern/locale ../blenkernel ../blenlib ../blenloader'
-incs += ' ../makesdna ../makesrna ../imbuf ../editors/include'
+incs += ' ../makesdna ../makesrna ../python ../imbuf ../editors/include'
incs += ' #/extern/glew/include'
incs += ' ' + env['BF_FREETYPE_INC']
@@ -17,4 +43,4 @@ if sys.platform == 'win32' or env['OURPLATFORM'] == 'linuxcross':
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
-env.BlenderLib ( 'bf_blenfont', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[210,210] )
+env.BlenderLib ( 'bf_blenfont', sources, Split(incs), defines=defs, libtype=['core','player'], priority=[210,210] )
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 778b6c11e5a..061e8e28607 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -43,6 +43,8 @@
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
+#include "BLI_math.h"
+
#include "BIF_gl.h"
#include "BLF_api.h"
@@ -87,6 +89,11 @@ int BLF_init(int points, int dpi)
return blf_font_init();
}
+void BLF_default_dpi(int dpi)
+{
+ global_font_dpi = dpi;
+}
+
void BLF_exit(void)
{
FontBLF *font;
@@ -511,8 +518,8 @@ static void blf_draw__start(FontBLF *font, GLint *mode, GLint *param)
if (font->flags & BLF_ASPECT)
glScalef(font->aspect[0], font->aspect[1], font->aspect[2]);
- if (font->flags & BLF_ROTATION)
- glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
+ if (font->flags & BLF_ROTATION) /* radians -> degrees */
+ glRotatef(font->angle * (float)(180.0 / M_PI), 0.0f, 0.0f, 1.0f);
if (font->shadow || font->blur)
glGetFloatv(GL_CURRENT_COLOR, font->orig_col);
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 91ecded88be..a6b04b24399 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -83,7 +83,7 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
memset(gc->bucket, 0, sizeof(gc->bucket));
- gc->textures = (GLuint *)malloc(sizeof(GLuint) * 256);
+ gc->textures = (GLuint *)MEM_mallocN(sizeof(GLuint) * 256, __func__);
gc->ntex = 256;
gc->cur_tex = -1;
gc->x_offs = 0;
@@ -150,7 +150,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
if (gc->cur_tex + 1 > 0)
glDeleteTextures(gc->cur_tex + 1, gc->textures);
- free((void *)gc->textures);
+ MEM_freeN((void *)gc->textures);
MEM_freeN(gc);
}
@@ -178,8 +178,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
gc->p2_height = font->max_tex_size;
tot_mem = gc->p2_width * gc->p2_height;
- buf = (unsigned char *)malloc(tot_mem);
- memset((void *)buf, 0, tot_mem);
+ buf = (unsigned char *)MEM_callocN(tot_mem, __func__);
glGenTextures(1, &gc->textures[gc->cur_tex]);
glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = gc->textures[gc->cur_tex]));
@@ -189,7 +188,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buf);
- free((void *)buf);
+ MEM_freeN((void *)buf);
}
GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
@@ -214,6 +213,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
FT_Error err;
FT_Bitmap bitmap, tempbitmap;
int sharp = (U.text_render & USER_TEXT_DISABLE_AA);
+ int flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
FT_BBox bbox;
unsigned int key;
@@ -221,10 +221,13 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
if (g)
return g;
+ if (font->flags & BLF_HINTING)
+ flags &= ~FT_LOAD_NO_HINTING;
+
if (sharp)
err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO);
else
- err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP); /* Sure about NO_* flags? */
+ err = FT_Load_Glyph(font->face, (FT_UInt)index, flags);
if (err)
return NULL;
@@ -383,7 +386,7 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
if (gc->cur_tex == -1) {
blf_glyph_cache_texture(font, gc);
gc->x_offs = gc->pad;
- gc->y_offs = gc->pad;
+ gc->y_offs = 0;
}
if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) {
@@ -391,7 +394,7 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
gc->y_offs += gc->max_glyph_height;
if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) {
- gc->y_offs = gc->pad;
+ gc->y_offs = 0;
blf_glyph_cache_texture(font, gc);
}
}
@@ -400,6 +403,19 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
g->xoff = gc->x_offs;
g->yoff = gc->y_offs;
+ /* prevent glTexSubImage2D from failing if the character
+ * asks for pixels out of bounds, this tends only to happen
+ * with very small sizes (5px high or less) */
+ if (UNLIKELY((g->xoff + g->width) > gc->p2_width)) {
+ g->width -= (g->xoff + g->width) - gc->p2_width;
+ BLI_assert(g->width > 0);
+ }
+ if (UNLIKELY((g->yoff + g->height) > gc->p2_height)) {
+ g->height -= (g->yoff + g->height) - gc->p2_height;
+ BLI_assert(g->height > 0);
+ }
+
+
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 1acc3dad4cf..de6e70e4461 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -166,7 +166,7 @@ typedef struct FontBLF {
/* initial position for draw the text. */
float pos[3];
- /* angle in degrees. */
+ /* angle in radians. */
float angle;
/* blur: 3 or 5 large kernel */
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 0ed48623dd5..73294f1aed6 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -27,30 +27,28 @@
* \ingroup blf
*/
-
-#include "BLF_translation.h" /* own include */
-
-#ifdef WITH_INTERNATIONAL
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "boost_locale_wrapper.h"
-
-#include "BKE_global.h"
-
-#include "DNA_userdef_types.h"
-
#include "RNA_types.h"
-#include "MEM_guardedalloc.h"
+#include "BLF_translation.h" /* own include */
#include "BLI_fileops.h"
#include "BLI_linklist.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
+
+#include "BKE_global.h"
+
+#include "DNA_userdef_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#ifdef WITH_INTERNATIONAL
+
+#include "boost_locale_wrapper.h"
/* Locale options. */
static const char **locales = NULL;
@@ -58,9 +56,6 @@ static int num_locales = 0;
static EnumPropertyItem *locales_menu = NULL;
static int num_locales_menu = 0;
-#define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0)
-#define LOCALE(_id) (locales ? locales[_id] : "")
-
static void free_locales(void)
{
if (locales) {
@@ -99,7 +94,7 @@ static void fill_locales(void)
/* First loop to find highest locale ID */
while (line) {
int t;
- str = (char*) line->link;
+ str = (char *)line->link;
if (str[0] == '#' || str[0] == '\0') {
line = line->next;
continue; /* Comment or void... */
@@ -112,17 +107,17 @@ static void fill_locales(void)
}
num_locales_menu++; /* The "closing" void item... */
- /* And now, buil locales and locale_menu! */
+ /* And now, build locales and locale_menu! */
locales_menu = MEM_callocN(num_locales_menu * sizeof(EnumPropertyItem), __func__);
line = lines;
/* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */
if (num_locales > 0) {
- locales = MEM_callocN(num_locales * sizeof(char*), __func__);
+ locales = MEM_callocN(num_locales * sizeof(char *), __func__);
while (line) {
int id;
char *loc, *sep1, *sep2, *sep3;
- str = (char*) line->link;
+ str = (char *)line->link;
if (str[0] == '#' || str[0] == '\0') {
line = line->next;
continue;
@@ -176,14 +171,20 @@ static void fill_locales(void)
BLI_file_free_lines(lines);
}
+#endif /* WITH_INTERNATIONAL */
EnumPropertyItem *BLF_RNA_lang_enum_properties(void)
{
+#ifdef WITH_INTERNATIONAL
return locales_menu;
+#else
+ return NULL;
+#endif
}
void BLF_lang_init(void)
{
+#ifdef WITH_INTERNATIONAL
char *messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
if (messagepath) {
@@ -193,15 +194,24 @@ void BLF_lang_init(void)
else {
printf("%s: 'locale' data path for translations not found, continuing\n", __func__);
}
+#else
+#endif
}
void BLF_lang_free(void)
{
+#ifdef WITH_INTERNATIONAL
free_locales();
+#else
+#endif
}
+#define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0)
+#define LOCALE(_id) (locales ? locales[(_id)] : "")
+
void BLF_lang_set(const char *str)
{
+#ifdef WITH_INTERNATIONAL
int ulang = ULANGUAGE;
const char *short_locale = str ? str : LOCALE(ulang);
const char *short_locale_utf8 = NULL;
@@ -229,40 +239,79 @@ void BLF_lang_set(const char *str)
bl_locale_set(short_locale_utf8);
if (short_locale[0]) {
- MEM_freeN((void*)short_locale_utf8);
+ MEM_freeN((void *)short_locale_utf8);
}
+#else
+ (void)str;
+#endif
}
+/* Get the current locale (short code, e.g. es_ES). */
const char *BLF_lang_get(void)
{
- int uilang = ULANGUAGE;
- return LOCALE(uilang);
+#ifdef WITH_INTERNATIONAL
+ const char *locale = LOCALE(ULANGUAGE);
+ if (locale[0] == '\0') {
+ /* Default locale, we have to find which one we are actually using! */
+ locale = bl_locale_get();
+ }
+ return locale;
+#else
+ return "";
+#endif
}
#undef LOCALE
#undef ULANGUAGE
-#else /* ! WITH_INTERNATIONAL */
-
-void BLF_lang_init(void)
+/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant,
+ * *variant and *language_variant will always be NULL).
+ * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them.
+ * NOTE: Keep that one always available, you never know, may become useful even in no-WITH_INTERNATIONAL context...
+ */
+void BLF_locale_explode(const char *locale, char **language, char **country, char **variant,
+ char **language_country, char **language_variant)
{
- return;
-}
+ char *m1, *m2, *_t = NULL;
-void BLF_lang_free(void)
-{
- return;
-}
+ m1 = strchr(locale, '_');
+ m2 = strchr(locale, '@');
-void BLF_lang_set(const char *str)
-{
- (void)str;
- return;
-}
-
-const char *BLF_lang_get(void)
-{
- return "";
+ if (language || language_variant) {
+ if (m1 || m2) {
+ _t = m1 ? BLI_strdupn(locale, m1 - locale) : BLI_strdupn(locale, m2 - locale);
+ if (language)
+ *language = _t;
+ }
+ else if (language) {
+ *language = BLI_strdup(locale);
+ }
+ }
+ if (country) {
+ if (m1)
+ *country = m2 ? BLI_strdupn(m1 + 1, m2 - (m1 + 1)) : BLI_strdup(m1 + 1);
+ else
+ *country = NULL;
+ }
+ if (variant) {
+ if (m2)
+ *variant = BLI_strdup(m2 + 1);
+ else
+ *variant = NULL;
+ }
+ if (language_country) {
+ if (m1)
+ *language_country = m2 ? BLI_strdupn(locale, m2 - locale) : BLI_strdup(locale);
+ else
+ *language_country = NULL;
+ }
+ if (language_variant) {
+ if (m2)
+ *language_variant = m1 ? BLI_strdupcat(_t, m2) : BLI_strdup(locale);
+ else
+ *language_variant = NULL;
+ }
+ if (_t && !language) {
+ MEM_freeN(_t);
+ }
}
-
-#endif /* WITH_INTERNATIONAL */
diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c
index 5d4b631688a..b5b72b68677 100644
--- a/source/blender/blenfont/intern/blf_translation.c
+++ b/source/blender/blenfont/intern/blf_translation.c
@@ -33,26 +33,28 @@
#include "BLF_translation.h"
-#ifdef WITH_INTERNATIONAL
-
-#include "boost_locale_wrapper.h"
-
#include "MEM_guardedalloc.h"
-#include "BLI_utildefines.h"
+#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BLI_path_util.h"
-#include "BLI_fileops.h"
#include "DNA_userdef_types.h" /* For user settings. */
+#include "BPY_extern.h"
+
+#ifdef WITH_INTERNATIONAL
+
+#include "boost_locale_wrapper.h"
+
static const char unifont_filename[] = "droidsans.ttf.gz";
static unsigned char *unifont_ttf = NULL;
static int unifont_size = 0;
+#endif /* WITH_INTERNATIONAL */
unsigned char *BLF_get_unifont(int *unifont_size_r)
{
+#ifdef WITH_INTERNATIONAL
if (unifont_ttf == NULL) {
char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
if (fontpath) {
@@ -70,21 +72,41 @@ unsigned char *BLF_get_unifont(int *unifont_size_r)
*unifont_size_r = unifont_size;
return unifont_ttf;
+#else
+ (void)unifont_size_r;
+ return NULL;
+#endif
}
void BLF_free_unifont(void)
{
+#ifdef WITH_INTERNATIONAL
if (unifont_ttf)
MEM_freeN(unifont_ttf);
-}
-
+#else
#endif
+}
const char *BLF_pgettext(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
if (msgid && msgid[0]) {
- return bl_locale_pgettext(msgctxt, msgid);
+ const char *ret;
+
+ /*if (msgctxt && !strcmp(msgctxt, BLF_I18NCONTEXT_DEFAULT_BPY_INTERN)) { */
+ if (msgctxt && msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPY[0]) {
+ /* BLF_I18NCONTEXT_DEFAULT_BPY context is reserved and considered the same as default NULL one. */
+ msgctxt = BLF_I18NCONTEXT_DEFAULT;
+ }
+ ret = bl_locale_pgettext(msgctxt, msgid);
+ /* We assume if the returned string is the same (memory level) as the msgid, no translation was found,
+ * and we can try py scripts' ones!
+ */
+ if (ret == msgid) {
+ ret = BPY_app_translations_py_pgettext(msgctxt, msgid);
+ }
+
+ return ret;
}
return "";
#else
@@ -93,21 +115,21 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid)
#endif
}
-int BLF_translate_iface(void)
+bool BLF_translate_iface(void)
{
#ifdef WITH_INTERNATIONAL
return (U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_IFACE);
#else
- return 0;
+ return false;
#endif
}
-int BLF_translate_tooltips(void)
+bool BLF_translate_tooltips(void)
{
#ifdef WITH_INTERNATIONAL
return (U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_TOOLTIPS);
#else
- return 0;
+ return false;
#endif
}
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 617c4cd2bc8..486834f9540 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -95,6 +95,8 @@ struct BMEditMesh;
struct ListBase;
struct PBVH;
+#define DM_OMP_LIMIT 10000 /* setting zero so we can catch bugs in OpenMP/BMesh */
+
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
#define SUB_ELEMS_EDGE 2
@@ -105,6 +107,11 @@ struct PBVH;
* Also, the mface origindex layer indexes mpolys, not mfaces.
*/
+typedef struct DMCoNo {
+ float co[3];
+ float no[3];
+} DMCoNo;
+
typedef struct DMGridAdjacency {
int index[4];
int rotation[4];
@@ -168,6 +175,9 @@ struct DerivedMesh {
float auto_bump_scale;
DMDirtyFlag dirty;
+ /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
+ char cd_flag;
+
/** Calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
@@ -603,7 +613,7 @@ void vDM_ColorBand_store(struct ColorBand *coba);
/** Simple function to get me->totvert amount of vertices/normals,
* correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
* In use now by vertex/weight paint and particles */
-float *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
+DMCoNo *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
/* */
DerivedMesh *mesh_get_derived_final(struct Scene *scene, struct Object *ob,
@@ -721,4 +731,4 @@ BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int
return (j != ORIGINDEX_NONE) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : ORIGINDEX_NONE;
}
-#endif
+#endif /* __BKE_DERIVEDMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 2d7030b2d42..12c9f6b449f 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -44,6 +44,7 @@ struct FCurve;
struct bPose;
struct bItasc;
struct bPoseChannel;
+struct Main;
struct Object;
struct Scene;
struct ID;
@@ -56,7 +57,7 @@ extern "C" {
/* Action Lib Stuff ----------------- */
/* Allocate a new bAction with the given name */
-struct bAction *add_empty_action(const char name[]);
+struct bAction *add_empty_action(struct Main *bmain, const char name[]);
/* Allocate a copy of the given Action and all its data */
struct bAction *BKE_action_copy(struct bAction *src);
@@ -220,7 +221,7 @@ void BKE_pose_remove_group(struct Object *ob);
void what_does_obaction(struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, char groupname[], float cframe);
/* for proxy */
-void BKE_pose_copy_result(struct bPose *to, struct bPose *from);
+bool BKE_pose_copy_result(struct bPose *to, struct bPose *from);
/* clear all transforms */
void BKE_pose_rest(struct bPose *pose);
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp b/source/blender/blenkernel/BKE_addon.h
index 142318cc7c2..eafaec3e605 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -15,31 +15,28 @@
* 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.
+ * Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
+#ifndef __BKE_ADDON_H__
+#define __BKE_ADDON_H__
-/** \file gameengine/Physics/common/PHY_IPhysicsEnvironment.cpp
- * \ingroup phys
- */
-
-
-#include "PHY_IPhysicsEnvironment.h"
+#include "RNA_types.h"
-/**
-* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
-* A derived class may be able to 'construct' entities by loading and/or converting
-*/
+typedef struct bAddonPrefType {
+ /* type info */
+ char idname[64]; // best keep the same size as BKE_ST_MAXNAME
+ /* RNA integration */
+ ExtensionRNA ext;
+} bAddonPrefType;
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet);
+void BKE_addon_pref_type_add(bAddonPrefType *apt);
+void BKE_addon_pref_type_remove(bAddonPrefType *apt);
-PHY_IPhysicsEnvironment::~PHY_IPhysicsEnvironment()
-{
+void BKE_addon_pref_type_init(void);
+void BKE_addon_pref_type_free(void);
-}
+#endif /* __BKE_ADDON_H__ */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index b0f372e0bac..fb9e9f4e691 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -73,7 +73,7 @@ typedef struct PoseTree {
extern "C" {
#endif
-struct bArmature *BKE_armature_add(const char *name);
+struct bArmature *BKE_armature_add(struct Main *bmain, const char *name);
struct bArmature *BKE_armature_from_object(struct Object *ob);
void BKE_armature_bonelist_free(struct ListBase *lb);
void BKE_armature_free(struct bArmature *arm);
@@ -97,28 +97,28 @@ void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPose
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);
/* get_objectspace_bone_matrix has to be removed still */
-void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int root, int posed);
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]);
-void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll);
+void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int root, int posed);
+void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]);
+void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll);
/* Common Conversions Between Co-ordinate Spaces */
-void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]);
+void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[4][4], float outmat[4][4]);
void BKE_armature_loc_world_to_pose(struct Object *ob, const float inloc[3], float outloc[3]);
-void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]);
+void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan, const float inloc[3], float outloc[3]);
-void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]);
-void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
+void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
+void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]);
-void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]);
+void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
-void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[][3], short use_compat);
-void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_comat);
+void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], short use_compat);
+void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], short use_comat);
void BKE_pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]);
void BKE_pchan_calc_mat(struct bPoseChannel *pchan);
/* Get the "pchan to pose" transform matrix. These matrices apply the effects of
* HINGE/NO_SCALE/NO_LOCAL_LOCATION options over the pchan loc/rot/scale transformations. */
-void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]);
+void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4]);
/* Rotation Mode Conversions - Used for PoseChannels + Objects... */
void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index b624d0f9c3a..d66909449e4 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -41,7 +41,7 @@ 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 265
+#define BLENDER_VERSION 266
#define BLENDER_SUBVERSION 0
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
@@ -52,7 +52,7 @@ extern "C" {
/* can be left blank, otherwise a,b,c... etc with no quotes */
#define BLENDER_VERSION_CHAR
/* alpha/beta/rc/release, docs use this */
-#define BLENDER_VERSION_CYCLE release
+#define BLENDER_VERSION_CYCLE alpha
extern char versionstr[]; /* from blender.c */
@@ -62,6 +62,7 @@ struct bContext;
struct ReportList;
struct Scene;
struct Main;
+struct ID;
int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *reports);
@@ -72,12 +73,17 @@ int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *r
int BKE_read_file_from_memory(struct bContext *C, char *filebuf, int filelength, struct ReportList *reports);
int BKE_read_file_from_memfile(struct bContext *C, struct MemFile *memfile, struct ReportList *reports);
+int BKE_read_file_userdef(const char *filepath, struct ReportList *reports);
+int BKE_write_file_userdef(const char *filepath, struct ReportList *reports);
+
void free_blender(void);
void initglobals(void);
/* load new userdef from file, exit blender */
void BKE_userdef_free(void);
-
+/* handle changes in userdef */
+void BKE_userdef_state(void);
+
/* set this callback when a UI is running */
void set_blender_test_break_cb(void (*func)(void) );
int blender_test_break(void);
@@ -93,9 +99,15 @@ extern void BKE_reset_undo(void);
extern char *BKE_undo_menu_string(void);
extern void BKE_undo_number(struct bContext *C, int nr);
extern const char *BKE_undo_get_name(int nr, int *active);
-extern void BKE_undo_save_quit(void);
+extern int BKE_undo_save_file(const char *filename);
extern struct Main *BKE_undo_get_main(struct Scene **scene);
+ /* copybuffer */
+void BKE_copybuffer_begin(void);
+void BKE_copybuffer_tag_ID(struct ID *id);
+int BKE_copybuffer_save(char *filename, struct ReportList *reports);
+ int BKE_copybuffer_paste(struct bContext *C, char *libname, struct ReportList *reports);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h
index 8bfee836c0d..4bc21625cf3 100644
--- a/source/blender/blenkernel/BKE_bmesh.h
+++ b/source/blender/blenkernel/BKE_bmesh.h
@@ -38,7 +38,7 @@
/*NOTE: this is the bmesh 1.0 code. it's completely outdated.*/
/* uncomment to use the new bevel operator as a modifier */
-// #define USE_BM_BEVEL_OP_AS_MOD
+#define USE_BM_BEVEL_OP_AS_MOD
/* bevel tool defines */
/* element flags */
@@ -53,6 +53,7 @@
#define BME_BEVEL_RADIUS (1 << 2)
#define BME_BEVEL_ANGLE (1 << 3)
#define BME_BEVEL_WEIGHT (1 << 4)
+#define BME_BEVEL_VGROUP (1 << 5)
//~ #define BME_BEVEL_EWEIGHT (1<<4)
//~ #define BME_BEVEL_VWEIGHT (1<<5)
#define BME_BEVEL_PERCENT (1 << 6)
diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenkernel/BKE_bpath.h
index 438bffb2fc5..16a8b1be85b 100644
--- a/source/blender/blenlib/BLI_bpath.h
+++ b/source/blender/blenkernel/BKE_bpath.h
@@ -25,14 +25,14 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file BLI_bpath.h
- * \ingroup bli
+/** \file BKE_bpath.h
+ * \ingroup bke
* \attention Based on ghash, difference is ghash is not a fixed size,
* so for BPath we don't need to malloc
*/
-#ifndef __BLI_BPATH_H__
-#define __BLI_BPATH_H__
+#ifndef __BKE_BPATH_H__
+#define __BKE_BPATH_H__
struct ID;
struct ListBase;
@@ -43,20 +43,20 @@ struct ReportList;
* path has changed, and in that case, should write the result to pathOut. */
typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src);
/* Executes 'visit' for each path associated with 'id'. */
-void BLI_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata);
-void BLI_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata);
-void BLI_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata);
-int BLI_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
+void BKE_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata);
+void BKE_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata);
+void BKE_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata);
+int BKE_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
/* Functions for temp backup/restore of paths, path count must NOT change */
-void *BLI_bpath_list_backup(struct Main *bmain, const int flag);
-void BLI_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle);
-void BLI_bpath_list_free(void *ls_handle);
+void *BKE_bpath_list_backup(struct Main *bmain, const int flag);
+void BKE_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle);
+void BKE_bpath_list_free(void *ls_handle);
-#define BLI_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */
-#define BLI_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */
-#define BLI_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */
-#define BLI_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg.
+#define BKE_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */
+#define BKE_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */
+#define BKE_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */
+#define BKE_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg.
* sequence strip images and pointcache. in this case only use the first
* file, this is needed for directory manipulation functions which might
* otherwise modify the same directory multiple times */
@@ -64,9 +64,9 @@ void BLI_bpath_list_free(void *ls_handle);
/* high level funcs */
/* creates a text file with missing files if there are any */
-void BLI_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports);
-void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports);
-void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
-void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
+void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports);
+void BKE_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports);
+void BKE_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
+void BKE_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
-#endif /* __BLI_BPATH_H__ */
+#endif /* __BKE_BPATH_H__ */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index cbffb6c0cea..cfae15961d7 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -36,12 +36,14 @@
struct ID;
struct Brush;
struct ImBuf;
+struct ImagePool;
+struct Main;
struct Scene;
struct wmOperator;
// enum CurveMappingPreset;
/* datablock functions */
-struct Brush *BKE_brush_add(const char *name);
+struct Brush *BKE_brush_add(struct Main *bmain, const char *name);
struct Brush *BKE_brush_copy(struct Brush *brush);
void BKE_brush_make_local(struct Brush *brush);
void BKE_brush_free(struct Brush *brush);
@@ -67,7 +69,8 @@ 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 */
/* sampling */
-void BKE_brush_sample_tex(const struct Scene *scene, struct Brush *brush, const float xy[2], float rgba[4], const int thread);
+void BKE_brush_sample_tex(const struct Scene *scene, struct Brush *brush, const float sampleco[3], float rgba[4], const int thread, struct ImagePool *pool);
+void BKE_brush_sample_tex_2D(const struct Scene *scene, struct Brush *brush, const float xy[2], float rgba[4], const int thread);
void BKE_brush_imbuf_new(const struct Scene *scene, struct Brush *brush, short flt, short texfalloff, int size,
struct ImBuf **imbuf, int use_color_correction);
@@ -99,6 +102,7 @@ float BKE_brush_unprojected_radius_get(const struct Scene *scene, struct Brush *
void BKE_brush_unprojected_radius_set(struct Scene *scene, struct Brush *brush, float value);
float BKE_brush_alpha_get(const struct Scene *scene, struct Brush *brush);
+void BKE_brush_alpha_set(Scene *scene, struct Brush *brush, float alpha);
float BKE_brush_weight_get(const Scene *scene, struct Brush *brush);
void BKE_brush_weight_set(const Scene *scene, struct Brush *brush, float value);
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 2a27934c038..057cd79b9e4 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -39,6 +39,7 @@ extern "C" {
#include "DNA_vec_types.h"
struct Camera;
+struct Main;
struct Object;
struct RegionView3D;
struct RenderData;
@@ -48,7 +49,7 @@ struct View3D;
/* Camera Datablock */
-void *BKE_camera_add(const char *name);
+void *BKE_camera_add(struct Main *bmain, const char *name);
struct Camera *BKE_camera_copy(struct Camera *cam);
void BKE_camera_make_local(struct Camera *cam);
void BKE_camera_free(struct Camera *ca);
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 2b2497f3f50..af5e925987d 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -63,14 +63,12 @@ DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_
/* merge verts */
DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap);
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob);
-
/* creates a CDDerivedMesh from the given curve object */
struct DerivedMesh *CDDM_from_curve(struct Object *ob);
/* creates a CDDerivedMesh from the given curve object and specified dispbase */
/* useful for OrcoDM creation for curves with constructive modifiers */
-DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr);
+DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
/* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data.
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 96e05aa87b9..e0b7e68bafc 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -42,14 +42,6 @@ struct Histogram;
struct ImBuf;
struct rctf;
-#if defined _MSC_VER
-# define DO_INLINE __inline
-#elif defined(__sun) || defined(__sun__)
-# define DO_INLINE
-#else
-# define DO_INLINE static inline
-#endif
-
void curvemapping_set_defaults(struct CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy);
struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
void curvemapping_free_data(struct CurveMapping *cumap);
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 686a60ab2c9..c79dc62bb61 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -108,8 +108,8 @@ typedef struct bConstraintTypeInfo {
} bConstraintTypeInfo;
/* Function Prototypes for bConstraintTypeInfo's */
-bConstraintTypeInfo *constraint_get_typeinfo(struct bConstraint *con);
-bConstraintTypeInfo *get_constraint_typeinfo(int type);
+bConstraintTypeInfo *BKE_constraint_get_typeinfo(struct bConstraint *con);
+bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type);
/* ---------------------------------------------------------------------------- */
/* Useful macros for testing various common flag combinations */
@@ -120,38 +120,38 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type);
/* ---------------------------------------------------------------------------- */
/* Constraint function prototypes */
-void unique_constraint_name(struct bConstraint *con, struct ListBase *list);
+void BKE_unique_constraint_name(struct bConstraint *con, struct ListBase *list);
-void free_constraints(struct ListBase *list);
-void copy_constraints(struct ListBase *dst, const struct ListBase *src, int do_extern);
-void relink_constraints(struct ListBase *list);
-void id_loop_constraints(struct ListBase *list, ConstraintIDFunc func, void *userdata);
-void free_constraint_data(struct bConstraint *con);
+void BKE_free_constraints(struct ListBase *list);
+void BKE_copy_constraints(struct ListBase *dst, const struct ListBase *src, int do_extern);
+void BKE_relink_constraints(struct ListBase *list);
+void BKE_id_loop_constraints(struct ListBase *list, ConstraintIDFunc func, void *userdata);
+void BKE_free_constraint_data(struct bConstraint *con);
/* Constraint API function prototypes */
-struct bConstraint *constraints_get_active(struct ListBase *list);
-void constraints_set_active(ListBase *list, struct bConstraint *con);
-struct bConstraint *constraints_findByName(struct ListBase *list, const char *name);
-
-struct bConstraint *add_ob_constraint(struct Object *ob, const char *name, short type);
-struct bConstraint *add_pose_constraint(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
+struct bConstraint *BKE_constraints_get_active(struct ListBase *list);
+void BKE_constraints_set_active(ListBase *list, struct bConstraint *con);
+struct bConstraint *BKE_constraints_findByName(struct ListBase *list, const char *name);
+
+struct bConstraint *BKE_add_ob_constraint(struct Object *ob, const char *name, short type);
+struct bConstraint *BKE_add_pose_constraint(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
-int remove_constraint(ListBase *list, struct bConstraint *con);
-void remove_constraints_type(ListBase *list, short type, short last_only);
+int BKE_remove_constraint(ListBase *list, struct bConstraint *con);
+void BKE_remove_constraints_type(ListBase *list, short type, short last_only);
/* Constraints + Proxies function prototypes */
-void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
-short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
+void BKE_extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
+short BKE_proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Evaluation function prototypes */
-struct bConstraintOb *constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
-void constraints_clear_evalob(struct bConstraintOb *cob);
+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 constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to);
+void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
-void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime);
-void get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
-void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
+void BKE_get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
+void BKE_get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
+void BKE_solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 22b8f474cca..285077f258c 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -185,6 +185,7 @@ enum {
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
ListBase CTX_data_collection_get(const bContext *C, const char *member);
+ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all);
ListBase CTX_data_dir_get(const bContext *C);
int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type);
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 536bbecb79b..358f884f74e 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -39,6 +39,7 @@ struct Curve;
struct EditNurb;
struct ListBase;
struct ListBase;
+struct Main;
struct Nurb;
struct Object;
struct Scene;
@@ -57,7 +58,7 @@ struct Scene;
void BKE_curve_unlink(struct Curve *cu);
void BKE_curve_free(struct Curve *cu);
void BKE_curve_editfont_free(struct Curve *cu);
-struct Curve *BKE_curve_add(const char *name, int type);
+struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type);
struct Curve *BKE_curve_copy(struct Curve *cu);
void BKE_curve_make_local(struct Curve *cu);
short BKE_curve_type_get(struct Curve *cu);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 4736e7b7312..36733d1ced0 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -39,6 +39,7 @@ extern "C" {
#endif
#include "../blenloader/BLO_sys_types.h" /* XXX, should have a more generic include for this */
+#include "BLI_utildefines.h"
struct BMesh;
struct ID;
@@ -215,6 +216,8 @@ void CustomData_free_elem(struct CustomData *data, int index, int count);
void CustomData_interp(const struct CustomData *source, struct CustomData *dest,
int *src_indices, float *weights, float *sub_weights,
int count, int dest_index);
+void CustomData_bmesh_interp_n(struct CustomData *data, void **src_blocks, const float *weights,
+ const float *sub_weights, int count, void *dest_block, int n);
void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks,
const float *weights, const float *sub_weights, int count,
void *dest_block);
@@ -246,6 +249,8 @@ void *CustomData_get_layer(const struct CustomData *data, int type);
void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
void *CustomData_get_layer_named(const struct CustomData *data, int type,
const char *name);
+int CustomData_get_offset(const struct CustomData *data, int type);
+int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
int CustomData_get_layer_index(const struct CustomData *data, int type);
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n);
@@ -304,7 +309,7 @@ void CustomData_bmesh_free_block(struct CustomData *data, void **block);
/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
* blocks of data. the CustomData's must not be compatible */
void CustomData_to_bmesh_block(const struct CustomData *source,
- struct CustomData *dest, int src_index, void **dest_block);
+ struct CustomData *dest, int src_index, void **dest_block, bool use_default_init);
void CustomData_from_bmesh_block(const struct CustomData *source,
struct CustomData *dest, void *src_block, int dest_index);
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 8306da71432..b209e8bf667 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -55,6 +55,11 @@ void defvert_add_index_notest(struct MDeformVert *dv, int de
void defvert_remove_group(struct MDeformVert *dvert, struct MDeformWeight *dw);
void defvert_clear(struct MDeformVert *dvert);
int defvert_find_shared(const struct MDeformVert *dvert_a, const struct MDeformVert *dvert_b);
+bool defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_tot);
+
+void BKE_defvert_array_free_elems(struct MDeformVert *dvert, int totvert);
+void BKE_defvert_array_free(struct MDeformVert *dvert, int totvert);
+void BKE_defvert_array_copy(struct MDeformVert *dst, const struct MDeformVert *src, int totvert);
float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup);
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup);
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index cf7e4b24288..4cdfc1cba95 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -36,13 +36,14 @@ extern "C" {
// #define DEPS_DEBUG
-struct ID;
-struct Main;
-struct Scene;
-struct DagNodeQueue;
struct DagForest;
struct DagNode;
+struct DagNodeQueue;
struct GHash;
+struct ID;
+struct Main;
+struct Object;
+struct Scene;
/* **** DAG relation types *** */
@@ -98,8 +99,16 @@ int is_acyclic(struct DagForest *dag);
/* ********** API *************** */
/* Note that the DAG never executes changes in Objects, only sets flags in Objects */
-/* (re)-create dependency graph for scene */
-void DAG_scene_sort(struct Main *bmain, struct Scene *sce);
+/* clear all dependency graphs, call this when changing relations between objects.
+ * the dependency graphs will be rebuilt just before they are used to avoid them
+ * getting rebuild many times during operators */
+void DAG_relations_tag_update(struct Main *bmain);
+
+/* (re)-create the dependency graph before using it */
+void DAG_scene_relations_update(struct Main *bmain, struct Scene *sce);
+
+/* force an immediate rebuild of the dependency graph, only needed in rare cases */
+void DAG_scene_relations_rebuild(struct Main *bmain, struct Scene *scene);
/* flag all objects that need recalc because they're animated */
void DAG_scene_update_flags(struct Main *bmain, struct Scene *sce, unsigned int lay, const short do_time);
@@ -108,10 +117,8 @@ void DAG_scene_flush_update(struct Main *bmain, struct Scene *sce, unsigned i
/* tag objects for update on file load */
void DAG_on_visible_update(struct Main *bmain, const short do_time);
-/* when setting manual RECALC flags, call this afterwards */
-void DAG_ids_flush_update(struct Main *bmain, int time);
-
/* tag datablock to get updated for the next redraw */
+void DAG_id_tag_update_ex(struct Main *bmain, struct ID *id, short flag);
void DAG_id_tag_update(struct ID *id, short flag);
/* flush all tagged updates */
void DAG_ids_flush_tagged(struct Main *bmain);
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 758a2a8a2e8..6b986cdceda 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -83,7 +83,7 @@ void BKE_displist_elem_free(DispList *dl);
DispList *BKE_displist_find_or_create(struct ListBase *lb, int type);
DispList *BKE_displist_find(struct ListBase *lb, int type);
void BKE_displist_normals_add(struct ListBase *lb);
-void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface);
+void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *tottri);
void BKE_displist_free(struct ListBase *lb);
int BKE_displist_has_faces(struct ListBase *lb);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index bf2f1262eee..6ce7b952b97 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -41,6 +41,7 @@ struct FModifier;
struct ChannelDriver;
struct DriverVar;
struct DriverTarget;
+struct FCM_EnvelopeData;
struct bAction;
struct BezTriple;
@@ -181,6 +182,8 @@ void evaluate_value_fmodifiers(ListBase *modifiers, struct FCurve *fcu, float *c
void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
+int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array, float frame, int arraylen, short *exists);
+
/* ************** F-Curves API ******************** */
/* -------- Data Managemnt -------- */
diff --git a/source/blender/blenkernel/BKE_fluidsim.h b/source/blender/blenkernel/BKE_fluidsim.h
index c3fa6621c98..433c10b82f1 100644
--- a/source/blender/blenkernel/BKE_fluidsim.h
+++ b/source/blender/blenkernel/BKE_fluidsim.h
@@ -47,7 +47,7 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
int useGlobalCoords, int modifierIndex);
/* bounding box & memory estimate */
-void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[][4],
+void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[4][4],
float start[3], float size[3]);
void fluid_estimate_memory(struct Object *ob, struct FluidsimSettings *fss, char *value);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index f6276a69d57..5458568433d 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -114,7 +114,7 @@ typedef struct Global {
#define G_BACKBUFSEL (1 << 4)
#define G_PICKSEL (1 << 5)
-/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */
+/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_FACE_SEL) */
#define G_SCRIPT_AUTOEXEC (1 << 13)
#define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
@@ -149,7 +149,7 @@ enum {
/* #define G_FILE_SHOW_PROFILE (1 << 6) */ /* deprecated */
#define G_FILE_LOCK (1 << 7)
#define G_FILE_SIGN (1 << 8)
-/* #define G_FILE_PUBLISH (1 << 9) */ /* deprecated */
+#define G_FILE_USERPREFS (1 << 9)
#define G_FILE_NO_UI (1 << 10)
/* #define G_FILE_GAME_TO_IPO (1 << 11) */ /* deprecated */
#define G_FILE_GAME_MAT (1 << 12) /* deprecated */
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 3e9803a908b..8c36a73a088 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -36,13 +36,14 @@
struct Base;
struct Group;
struct GroupObject;
+struct Main;
struct Object;
struct bAction;
struct Scene;
void BKE_group_free(struct Group *group);
void BKE_group_unlink(struct Group *group);
-struct Group *add_group(const char *name);
+struct Group *add_group(struct Main *bmain, const char *name);
struct Group *BKE_group_copy(struct Group *group);
int add_to_group(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
int rem_from_group(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index a9f6a61a655..ad3e4bb2251 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -315,6 +315,8 @@ __attribute__((nonnull))
* the actual struct IDProperty struct either.*/
void IDP_FreeProperty(struct IDProperty *prop);
+void IDP_ClearProperty(IDProperty *prop);
+
/** Unlinks any struct IDProperty<->ID linkage that might be going on.*/
void IDP_UnlinkProperty(struct IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1f9630d9fce..dd7e06259bd 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -44,6 +44,7 @@ struct anim;
struct Scene;
struct Object;
struct ImageFormatData;
+struct ImagePool;
struct Main;
#define IMA_MAX_SPACE 64
@@ -60,8 +61,10 @@ int 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 short is_copy);
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames);
-int BKE_add_image_extension(char *string, const char imtype);
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const struct ImageFormatData *im_format, const short use_ext, const short use_frames);
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short 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);
@@ -144,13 +147,21 @@ int BKE_image_has_ibuf(struct Image *ima, struct ImageUser *iuser);
struct ImBuf *BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **lock_r);
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock);
+struct ImagePool *BKE_image_pool_new(void);
+void BKE_image_pool_free(struct ImagePool *pool);
+struct ImBuf *BKE_image_pool_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, struct ImagePool *pool);
+void BKE_image_pool_release_ibuf(struct Image *ima, struct ImBuf *ibuf, struct ImagePool *pool);
+
+/* set an alpha mode based on file extension */
+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(const char *filepath);
+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(const char *filepath);
/* adds image, adds ibuf, generates color or pattern */
-struct Image *BKE_image_add_generated(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short uvtestgrid, float color[4]);
+struct Image *BKE_image_add_generated(struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4]);
/* adds image from imbuf, owns imbuf */
struct Image *BKE_image_add_from_imbuf(struct ImBuf *ibuf);
@@ -197,7 +208,7 @@ void BKE_image_memorypack(struct Image *ima);
void BKE_image_print_memlist(void);
/* empty image block, of similar type and filename */
-struct Image *BKE_image_copy(struct Image *ima);
+struct Image *BKE_image_copy(struct Main *bmain, struct Image *ima);
/* merge source into dest, and free source */
void BKE_image_merge(struct Image *dest, struct Image *source);
@@ -217,6 +228,10 @@ void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width,
void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int height, int width);
void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int height, int width);
+/* Cycles hookup */
+unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame);
+float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index d7d75b4c4c9..a159cbb13d4 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -59,7 +59,7 @@ 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 *do_ob_key(struct Scene *scene, struct Object *ob);
+float *BKE_key_evaluate_object(struct Scene *scene, struct Object *ob, int *r_totelem);
struct Key *BKE_key_from_object(struct Object *ob);
struct KeyBlock *BKE_keyblock_from_object(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_lamp.h b/source/blender/blenkernel/BKE_lamp.h
index 244decf9d52..205c7c7d1e6 100644
--- a/source/blender/blenkernel/BKE_lamp.h
+++ b/source/blender/blenkernel/BKE_lamp.h
@@ -37,9 +37,10 @@ extern "C" {
#endif
struct Lamp;
+struct Main;
struct Scene;
-struct Lamp *BKE_lamp_add(const char *name) WARN_UNUSED;
+struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) WARN_UNUSED;
struct Lamp *BKE_lamp_copy(struct Lamp *la) WARN_UNUSED;
struct Lamp *localize_lamp(struct Lamp *la) WARN_UNUSED;
void BKE_lamp_make_local(struct Lamp *la);
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index 34baa48dbe2..b195af18a8e 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -35,6 +35,7 @@
*/
struct Lattice;
+struct Main;
struct Object;
struct Scene;
struct DerivedMesh;
@@ -42,7 +43,7 @@ struct BPoint;
struct MDeformVert;
void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb);
-struct Lattice *BKE_lattice_add(const char *name);
+struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name);
struct Lattice *BKE_lattice_copy(struct Lattice *lt);
void BKE_lattice_free(struct Lattice *lt);
void BKE_lattice_make_local(struct Lattice *lt);
@@ -59,7 +60,7 @@ void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object
struct DerivedMesh *dm, float (*vertexCos)[3],
int numVerts, const char *vgroup, short defaxis);
void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target,
- float orco[3], float vec[3], float mat[][3], int no_rot_axis);
+ float orco[3], float vec[3], float mat[3][3], int no_rot_axis);
void lattice_deform_verts(struct Object *laOb, struct Object *target,
struct DerivedMesh *dm, float (*vertexCos)[3],
@@ -75,5 +76,10 @@ void BKE_lattice_modifiers_calc(struct Scene *scene, struct Object *ob);
struct MDeformVert *BKE_lattice_deform_verts_get(struct Object *lattice);
+void BKE_lattice_minmax(struct Lattice *lt, float min[3], float max[3]);
+void BKE_lattice_center_median(struct Lattice *lt, float cent[3]);
+void BKE_lattice_center_bounds(struct Lattice *lt, float cent[3]);
+void BKE_lattice_translate(struct Lattice *lt, float offset[3], int do_keys);
+
#endif
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index bc081b7f308..5aa82be0541 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -51,6 +51,12 @@ __attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
+void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id)
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+__attribute__((nonnull))
+#endif
+;
void *BKE_libblock_copy(struct ID *id)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -62,6 +68,7 @@ void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const shor
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
void id_lib_extern(struct ID *id);
void BKE_library_filepath_set(struct Library *lib, const char *filepath);
+void id_us_ensure_real(struct ID *id);
void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index cfdcf1436bf..8e4d370e8a0 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -51,9 +51,10 @@ struct Library;
typedef struct Main {
struct Main *next, *prev;
char name[1024]; /* 1024 = FILE_MAX */
- short versionfile, subversionfile;
+ short versionfile, subversionfile; /* see BLENDER_VERSION, BLENDER_SUBVERSION */
short minversionfile, minsubversionfile;
- int revision; /* svn revision of binary that saved file */
+ int revision; /* svn revision of binary that saved file */
+ short recovered; /* indicate the main->name (file) is the recovered one */
struct Library *curlib;
ListBase scene;
@@ -91,10 +92,11 @@ typedef struct Main {
char id_tag_update[256];
} Main;
+#define MAIN_VERSION_ATLEAST(main, ver, subver) \
+ ((main)->versionfile > (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver)))
#ifdef __cplusplus
}
#endif
-#endif
-
+#endif /* __BKE_MAIN_H__ */
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index cc15ceecbac..b40ad4814f0 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -98,7 +98,7 @@ void BKE_mask_point_select_set(struct MaskSplinePoint *point, const short do_sel
void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const short do_select);
/* general */
-struct Mask *BKE_mask_new(const char *name);
+struct Mask *BKE_mask_new(struct Main *bmain, const char *name);
struct Mask *BKE_mask_copy_nolib(struct Mask *mask);
struct Mask *BKE_mask_copy(struct Mask *mask);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index dd1b1a7752b..350eaf23f6f 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -52,7 +52,7 @@ void BKE_material_free_ex(struct Material *ma, int do_id_user);
void test_object_materials(struct ID *id);
void resize_object_material(struct Object *ob, const short totcol);
void init_material(struct Material *ma);
-struct Material *BKE_material_add(const char *name);
+struct Material *BKE_material_add(struct Main *bmain, const char *name);
struct Material *BKE_material_copy(struct Material *ma);
struct Material *localize_material(struct Material *ma);
struct Material *give_node_material(struct Material *ma); /* returns node material or self */
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 7a0eea1b009..662bfab10a1 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -32,6 +32,7 @@
* \since March 2001
* \author nzc
*/
+struct Main;
struct MetaBall;
struct Object;
struct Scene;
@@ -39,7 +40,7 @@ struct MetaElem;
void BKE_mball_unlink(struct MetaBall *mb);
void BKE_mball_free(struct MetaBall *mb);
-struct MetaBall *BKE_mball_add(const char *name);
+struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name);
struct MetaBall *BKE_mball_copy(struct MetaBall *mb);
void BKE_mball_make_local(struct MetaBall *mb);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index e53d0efffbd..24535eb1fd6 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -39,6 +39,7 @@ struct DispList;
struct ListBase;
struct BMEditMesh;
struct BMesh;
+struct Main;
struct Mesh;
struct MPoly;
struct MLoop;
@@ -100,6 +101,16 @@ void BKE_mesh_calc_poly_center(struct MPoly *mpoly, struct MLoop *loopstart,
float BKE_mesh_calc_poly_area(struct MPoly *mpoly, struct MLoop *loopstart,
struct MVert *mvarray, const float polynormal[3]);
+void BKE_mesh_calc_relative_deform(
+ const struct MPoly *mpoly, const int totpoly,
+ const struct MLoop *mloop, const int totvert,
+
+ const float (*vert_cos_src)[3],
+ const float (*vert_cos_dst)[3],
+
+ const float (*vert_cos_org)[3],
+ float (*vert_cos_new)[3]);
+
/* Find the index of the loop in 'poly' which references vertex,
* returns -1 if not found */
int poly_find_loop_from_vert(const struct MPoly *poly,
@@ -123,16 +134,28 @@ void BKE_mesh_flush_hidden_from_verts(const struct MVert *mvert,
struct MEdge *medge, int totedge,
struct MPoly *mpoly, int totpoly);
+void BKE_mesh_flush_select_from_polys_ex(struct MVert *mvert, const int totvert,
+ struct MLoop *mloop,
+ struct MEdge *medge, const int totedge,
+ const struct MPoly *mpoly, const int totpoly);
+void BKE_mesh_flush_select_from_polys(struct Mesh *me);
+void BKE_mesh_flush_select_from_verts_ex(const struct MVert *mvert, const int totvert,
+ struct MLoop *mloop,
+ struct MEdge *medge, const int totedge,
+ struct MPoly *mpoly, const int totpoly);
+void BKE_mesh_flush_select_from_verts(struct Mesh *me);
+
void BKE_mesh_unlink(struct Mesh *me);
void BKE_mesh_free(struct Mesh *me, int unlink);
-struct Mesh *BKE_mesh_add(const char *name);
+struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
+struct Mesh *BKE_mesh_copy_ex(struct Main *bmain, struct Mesh *me);
struct Mesh *BKE_mesh_copy(struct Mesh *me);
void mesh_update_customdata_pointers(struct Mesh *me, const short do_ensure_tess_cd);
void BKE_mesh_make_local(struct Mesh *me);
void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]);
void BKE_mesh_texspace_calc(struct Mesh *me);
-float *BKE_mesh_orco_verts_get(struct Object *ob);
+float (*BKE_mesh_orco_verts_get(struct Object *ob))[3];
void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert);
int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
struct Mesh *BKE_mesh_from_object(struct Object *ob);
@@ -143,16 +166,10 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot
int *totloop, int *totpoly);
int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert,
struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly,
- int *_totloop, int *_totpoly, int **orco_index_ptr);
-void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly,
- struct MLoop *mloops, struct MLoopUV *mloopuvs,
- float (*orco)[3], int (*orco_index)[4]);
+ struct MLoopUV **alluv, int *_totloop, int *_totpoly);
+void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv);
void BKE_mesh_from_nurbs(struct Object *ob);
-void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase,
- int **orco_index_ptr);
void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
-void free_dverts(struct MDeformVert *dvert, int totvert);
-void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
void BKE_mesh_delete_material_index(struct Mesh *me, short index);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
@@ -229,8 +246,6 @@ typedef struct UvElement {
/* Next UvElement corresponding to same vertex */
struct UvElement *next;
/* Face the element belongs to */
- struct BMFace *face;
- /* Index in the editFace of the uv */
struct BMLoop *l;
/* index in loop. */
unsigned short tfindex;
@@ -327,6 +342,8 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData
void BKE_mesh_poly_calc_angles(struct MVert *mvert, struct MLoop *mloop,
struct MPoly *mp, float angles[]);
+void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 2fa78b30835..cc260b8f60c 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -358,8 +358,6 @@ int modifiers_isCorrectableDeformed(struct Object *ob);
void modifier_freeTemporaryData(struct ModifierData *md);
int modifiers_isPreview(struct Object *ob);
-int modifiers_indexInObject(struct Object *ob, struct ModifierData *md);
-
typedef struct CDMaskLink {
struct CDMaskLink *next;
CustomDataMask mask;
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 25d2678ea47..5777a4094bc 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -43,7 +43,7 @@ struct MovieDistortion;
void BKE_movieclip_free(struct MovieClip *clip);
void BKE_movieclip_unlink(struct Main *bmain, struct MovieClip *clip);
-struct MovieClip *BKE_movieclip_file_add(const char *name);
+struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
void BKE_movieclip_reload(struct MovieClip *clip);
struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index b8f168cbdea..19fe621ade9 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -261,6 +261,12 @@ typedef struct bNodeType {
#define SOCK_IN 1
#define SOCK_OUT 2
+typedef enum eNodeSizePreset {
+ NODE_SIZE_DEFAULT,
+ NODE_SIZE_SMALL,
+ NODE_SIZE_LARGE
+} eNodeSizePreset;
+
struct bNodeTreeExec;
typedef void (*bNodeTreeCallback)(void *calldata, struct ID *owner_id, struct bNodeTree *ntree);
@@ -299,7 +305,7 @@ struct bNodeTreeType *ntreeGetType(int type);
struct bNodeType *ntreeGetNodeType(struct bNodeTree *ntree);
struct bNodeSocketType *ntreeGetSocketType(int type);
-struct bNodeTree *ntreeAddTree(const char *name, int type, int nodetype);
+struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, int type, int nodetype);
void ntreeInitTypes(struct bNodeTree *ntree);
/* copy/free funcs, need to manage ID users */
@@ -419,6 +425,7 @@ void node_type_base(struct bNodeTreeType *ttype, struct bNodeType *nt
const char *name, short nclass, short flag);
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs);
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth);
+void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size);
void node_type_init(struct bNodeType *ntype, void (*initfunc)(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp));
void node_type_valid(struct bNodeType *ntype, int (*validfunc)(struct bNodeTree *ntree, struct bNodeTemplate *ntemp));
void node_type_storage(struct bNodeType *ntype,
@@ -557,6 +564,7 @@ struct ShadeResult;
#define SH_NODE_BSDF_REFRACTION 173
#define SH_NODE_TANGENT 174
#define SH_NODE_NORMAL_MAP 175
+#define SH_NODE_HAIR_INFO 176
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
@@ -576,7 +584,7 @@ struct ShadeResult;
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
-void ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
+bool ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode);
void nodeShaderSynchronizeID(struct bNode *node, int copyto);
@@ -736,8 +744,6 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
/* API */
struct CompBuf;
-struct bNodeTreeExec *ntreeCompositBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
-void ntreeCompositEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int rendering, int do_previews,
const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings);
void ntreeCompositTagRender(struct Scene *sce);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index ec0703248fd..89860cd0da9 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -49,6 +49,8 @@ struct bAction;
struct RenderData;
struct rctf;
struct MovieClip;
+struct Main;
+struct RigidBodyWorld;
void BKE_object_workob_clear(struct Object *workob);
void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob);
@@ -76,29 +78,33 @@ void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
void BKE_object_unlink(struct Object *ob);
int BKE_object_exists_check(struct Object *obtest);
-
-struct Object *BKE_object_add_only_object(int type, const char *name);
+int BKE_object_is_in_editmode(struct Object *ob);
+
+struct Object *BKE_object_add_only_object(struct Main *bmain, int type, const char *name);
struct Object *BKE_object_add(struct Scene *scene, int type);
void *BKE_object_obdata_add_from_type(int type);
+struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, int copy_caches);
struct Object *BKE_object_copy(struct Object *ob);
-struct Object *BKE_object_copy_with_caches(struct Object *ob);
void BKE_object_make_local(struct Object *ob);
int BKE_object_is_libdata(struct Object *ob);
int BKE_object_obdata_is_libdata(struct Object *ob);
-void BKE_object_scale_to_mat3(struct Object *ob, float mat[][3]);
-void BKE_object_rot_to_mat3(struct Object *ob, float mat[][3]);
-void BKE_object_mat3_to_rot(struct Object *ob, float mat[][3], short use_compat);
-void BKE_object_to_mat3(struct Object *ob, float mat[][3]);
-void BKE_object_to_mat4(struct Object *ob, float mat[][4]);
-void BKE_object_apply_mat4(struct Object *ob, float mat[][4], const short use_compat, const short use_parent);
+void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]);
+void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3], short use_drot);
+void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], short use_compat);
+void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
+void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
+void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const short use_compat, const short use_parent);
int BKE_object_pose_context_check(struct Object *ob);
struct Object *BKE_object_pose_armature_get(struct Object *ob);
void BKE_object_where_is_calc(struct Scene *scene, struct Object *ob);
+void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob);
void BKE_object_where_is_calc_time(struct Scene *scene, struct Object *ob, float ctime);
+void BKE_object_where_is_calc_time_ex(struct Scene *scene, struct Object *ob, float ctime,
+ struct RigidBodyWorld *rbw);
void BKE_object_where_is_calc_simul(struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float obmat[4][4]);
@@ -144,6 +150,8 @@ void BKE_object_tfm_protected_restore(struct Object *ob,
const short protectflag);
void BKE_object_handle_update(struct Scene *scene, struct Object *ob);
+void BKE_object_handle_update_ex(struct Scene *scene, struct Object *ob,
+ struct RigidBodyWorld *rbw);
void BKE_object_sculpt_modifiers_changed(struct Object *ob);
int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index 603cb1f22a6..b19a2092206 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -35,6 +35,7 @@
#define RET_OK 0
#define RET_ERROR 1
+struct ID;
struct bSound;
struct Image;
struct Main;
@@ -48,6 +49,7 @@ struct PackedFile *newPackedFile(struct ReportList *reports, const char *filenam
struct PackedFile *newPackedFileMemory(void *mem, int memlen);
void packAll(struct Main *bmain, struct ReportList *reports);
+void packLibraries(struct Main *bmain, struct ReportList *reports);
/* unpack */
char *unpackFile(struct ReportList *reports, const char *abs_name, const char *local_name, struct PackedFile *pf, int how);
@@ -55,6 +57,7 @@ int unpackVFont(struct ReportList *reports, struct VFont *vfont, int how);
int unpackSound(struct Main *bmain, struct ReportList *reports, struct bSound *sound, int how);
int unpackImage(struct ReportList *reports, struct Image *ima, int how);
void unpackAll(struct Main *bmain, struct ReportList *reports, int how);
+int unpackLibraries(struct Main *bmain, struct ReportList *reports);
int writePackedFile(struct ReportList *reports, const char *filename, struct PackedFile *pf, int guimode);
@@ -70,5 +73,10 @@ int seekPackedFile(struct PackedFile *pf, int offset, int whence);
void rewindPackedFile(struct PackedFile *pf);
int readPackedFile(struct PackedFile *pf, void *data, int size);
+/* ID should be not NULL, return 1 if there's a packed file */
+int BKE_pack_check(struct ID *id);
+/* ID should be not NULL, throws error when ID is Library */
+void BKE_unpack_id(struct Main *bmain, struct ID *id, struct ReportList *reports, int how);
+
#endif
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index c452c177143..211b6189fa8 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -33,6 +33,8 @@
*/
struct bContext;
+struct BMesh;
+struct BMFace;
struct Brush;
struct MDisps;
struct MeshElemMap;
@@ -45,6 +47,7 @@ struct Paint;
struct PBVH;
struct Scene;
struct StrokeCache;
+struct ImagePool;
extern const char PAINT_CURSOR_SCULPT[3];
extern const char PAINT_CURSOR_VERTEX_PAINT[3];
@@ -71,6 +74,7 @@ int paint_vertsel_test(struct Object *ob);
int paint_is_face_hidden(const struct MFace *f, const struct MVert *mvert);
int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
int gridsize, int x, int y);
+int paint_is_bmesh_face_hidden(struct BMFace *f);
/* paint masks */
float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level,
@@ -92,6 +96,12 @@ typedef struct SculptSession {
/* Mesh connectivity */
const struct MeshElemMap *pmap;
+ /* BMesh for dynamic topology sculpting */
+ struct BMesh *bm;
+ int bm_smooth_shading;
+ /* Undo/redo log for dynamic topology sculpting */
+ struct BMLog *bm_log;
+
/* PBVH acceleration structure */
struct PBVH *pbvh;
int show_diffuse_color;
@@ -107,6 +117,7 @@ typedef struct SculptSession {
/* Used to cache the render of the active texture */
unsigned int texcache_side, *texcache, texcache_actual;
+ struct ImagePool *tex_pool;
/* Layer brush persistence between strokes */
float (*layer_co)[3]; /* Copy of the mesh vertices' locations */
@@ -121,5 +132,6 @@ typedef struct SculptSession {
void free_sculptsession(struct Object *ob);
void free_sculptsession_deformMats(struct SculptSession *ss);
+void sculptsession_bm_to_me(struct Object *ob, int reorder);
#endif
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index ec03f53dbdb..6c207675cb1 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -20,7 +20,9 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Adaptive time step
+ * Classical SPH
+ * Copyright 2011-2012 AutoCRC
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -58,6 +60,7 @@ struct RNG;
struct SurfaceModifierData;
struct BVHTreeRay;
struct BVHTreeRayHit;
+struct EdgeHash;
#define PARTICLE_P ParticleData * pa; int p
#define LOOP_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++)
@@ -85,6 +88,24 @@ typedef struct ParticleSimulationData {
float courant_num;
} ParticleSimulationData;
+typedef struct SPHData {
+ ParticleSystem *psys[10];
+ ParticleData *pa;
+ float mass;
+ struct EdgeHash *eh;
+ float *gravity;
+ float hfac;
+ /* Average distance to neighbours (other particles in the support domain),
+ * for calculating the Courant number (adaptive time step). */
+ int pass;
+ float element_size;
+ float flow[3];
+
+ /* Integrator callbacks. This allows different SPH implementations. */
+ void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
+ void (*density_cb) (void *rangedata_v, int index, float squared_dist);
+} SPHData;
+
typedef struct ParticleTexture {
float ivel; /* used in reset */
float time, life, exist, size; /* used in init */
@@ -199,7 +220,10 @@ typedef struct ParticleCollision {
ParticleCollisionElement pce;
- float total_time, inv_timestep;
+ /* total_time is the amount of time in this subframe
+ * inv_total_time is the opposite
+ * inv_timestep is the inverse of the amount of time in this frame */
+ float total_time, inv_total_time, inv_timestep;
float radius;
float co1[3], co2[3];
@@ -247,7 +271,7 @@ void BKE_particlesettings_free(struct ParticleSettings *part);
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
void psys_free(struct Object *ob, struct ParticleSystem *psys);
-void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset);
+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);
int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
@@ -283,12 +307,16 @@ 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, int vel);
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);
+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]);
+
/* for anim.c */
void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part,
struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa,
float uv[2], float orco[3]);
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa,
- struct ParticleCacheKey *cache, float mat[][4], float *scale);
+ struct ParticleCacheKey *cache, float mat[4][4], float *scale);
ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
void psys_threads_free(ParticleThread *threads);
@@ -322,9 +350,9 @@ 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_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]);
-void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
-void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
+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]);
+void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
float psys_get_dietime_from_cache(struct PointCache *cache, int index);
diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 59ecdb359c9..99ed978561e 100644
--- a/source/blender/blenlib/BLI_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -18,22 +18,27 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_PBVH_H__
-#define __BLI_PBVH_H__
+#ifndef __BKE_PBVH_H__
+#define __BKE_PBVH_H__
-/** \file BLI_pbvh.h
- * \ingroup bli
+/** \file BKE_pbvh.h
+ * \ingroup bke
* \brief A BVH for high poly meshes.
*/
#include "BLI_bitmap.h"
+#include "BLI_ghash.h"
+#include "BLI_utildefines.h"
+
+/* Needed for BMesh functions used in the PBVH iterator macro */
+#include "bmesh.h"
struct CCGElem;
struct CCGKey;
struct CustomData;
struct DMFlagMat;
struct DMGridAdjacency;
-struct ListBase;
+struct GHash;
struct MFace;
struct MVert;
struct PBVH;
@@ -49,32 +54,35 @@ typedef struct {
/* Callbacks */
/* returns 1 if the search should continue from this node, 0 otherwise */
-typedef int (*BLI_pbvh_SearchCallback)(PBVHNode *node, void *data);
+typedef int (*BKE_pbvh_SearchCallback)(PBVHNode *node, void *data);
-typedef void (*BLI_pbvh_HitCallback)(PBVHNode *node, void *data);
-typedef void (*BLI_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *tmin);
+typedef void (*BKE_pbvh_HitCallback)(PBVHNode *node, void *data);
+typedef void (*BKE_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *tmin);
/* Building */
-PBVH *BLI_pbvh_new(void);
-void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
+PBVH *BKE_pbvh_new(void);
+void BKE_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
int totface, int totvert, struct CustomData *vdata);
-void BLI_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
+void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
struct DMGridAdjacency *gridadj, int totgrid,
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
unsigned int **grid_hidden);
-void BLI_pbvh_free(PBVH *bvh);
+void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, int smooth_shading,
+ struct BMLog *log);
+
+void BKE_pbvh_free(PBVH *bvh);
/* Hierarchical Search in the BVH, two methods:
* - for each hit calling a callback
* - gather nodes in an array (easy to multithread) */
-void BLI_pbvh_search_callback(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitCallback hcb, void *hit_data);
+void BKE_pbvh_search_callback(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitCallback hcb, void *hit_data);
-void BLI_pbvh_search_gather(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
+void BKE_pbvh_search_gather(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
PBVHNode ***array, int *tot);
/* Raycast
@@ -82,33 +90,48 @@ void BLI_pbvh_search_gather(PBVH *bvh,
* it's up to the callback to find the primitive within the leaves that is
* hit first */
-void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
+void BKE_pbvh_raycast(PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data,
const float ray_start[3], const float ray_normal[3],
int original);
-int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
+int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
const float ray_start[3], const float ray_normal[3],
float *dist);
/* Drawing */
-void BLI_pbvh_node_draw(PBVHNode *node, void *data);
-void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
- int (*setMaterial)(int, void *attribs));
+void BKE_pbvh_node_draw(PBVHNode *node, void *data);
+void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
+ int (*setMaterial)(int, void *attribs), int wireframe);
/* PBVH Access */
typedef enum {
PBVH_FACES,
PBVH_GRIDS,
+ PBVH_BMESH
} PBVHType;
-PBVHType BLI_pbvh_type(const PBVH *bvh);
+PBVHType BKE_pbvh_type(const PBVH *bvh);
+
+/* Get the PBVH root's bounding box */
+void BKE_pbvh_bounding_box(const PBVH *bvh, float min[3], float max[3]);
/* multires hidden data, only valid for type == PBVH_GRIDS */
-unsigned int **BLI_pbvh_grid_hidden(const PBVH *bvh);
+unsigned int **BKE_pbvh_grid_hidden(const PBVH *bvh);
/* multires level, only valid for type == PBVH_GRIDS */
-void BLI_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
+void BKE_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
+
+/* Only valid for type == PBVH_BMESH */
+BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
+void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size);
+
+typedef enum {
+ PBVH_Subdivide = 1,
+ PBVH_Collapse = 2,
+} PBVHTopologyUpdateMode;
+int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+ const float center[3], float radius);
/* Node Access */
@@ -122,45 +145,60 @@ typedef enum {
PBVH_UpdateRedraw = 32,
PBVH_RebuildDrawBuffers = 64,
- PBVH_FullyHidden = 128
+ PBVH_FullyHidden = 128,
+
+ PBVH_UpdateTopology = 256,
} PBVHNodeFlags;
-void BLI_pbvh_node_mark_update(PBVHNode *node);
-void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node);
-void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+void BKE_pbvh_node_mark_update(PBVHNode *node);
+void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node);
+void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+void BKE_pbvh_node_mark_topology_update(PBVHNode *node);
-void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
+void BKE_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
int **grid_indices, int *totgrid, int *maxgrid, int *gridsize,
struct CCGElem ***grid_elems, struct DMGridAdjacency **gridadj);
-void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node,
+void BKE_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node,
int *uniquevert, int *totvert);
-void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
+void BKE_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
int **vert_indices, struct MVert **verts);
-void BLI_pbvh_node_get_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
-void BLI_pbvh_node_get_original_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_node_get_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_node_get_original_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
-float BLI_pbvh_node_get_tmin(PBVHNode *node);
+float BKE_pbvh_node_get_tmin(PBVHNode *node);
/* test if AABB is at least partially inside the planes' volume */
-int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data);
+int BKE_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data);
/* test if AABB is at least partially outside the planes' volume */
-int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
+int BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
+
+struct GHash *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node);
+struct GHash *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node);
+void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node);
+void BKE_pbvh_bmesh_after_stroke(PBVH *bvh);
/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
-void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
-void BLI_pbvh_redraw_BB(PBVH * bvh, float bb_min[3], float bb_max[3]);
-void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
-void BLI_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
+void BKE_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
+void BKE_pbvh_redraw_BB(PBVH * bvh, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
+void BKE_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
struct DMGridAdjacency *gridadj, void **gridfaces,
struct DMFlagMat *flagmats, unsigned int **grid_hidden);
-/* vertex deformer */
-float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];
-void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
-int BLI_pbvh_isDeformed(struct PBVH *pbvh);
+/* Layer displacement */
+
+/* Get the node's displacement layer, creating it if necessary */
+float *BKE_pbvh_node_layer_disp_get(PBVH *pbvh, PBVHNode *node);
+/* If the node has a displacement layer, free it and set to null */
+void BKE_pbvh_node_layer_disp_free(PBVHNode *node);
+
+/* vertex deformer */
+float (*BKE_pbvh_get_vertCos(struct PBVH *pbvh))[3];
+void BKE_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
+int BKE_pbvh_isDeformed(struct PBVH *pbvh);
/* Vertex Iterator */
@@ -197,9 +235,15 @@ typedef struct PBVHVertexIter {
int *vert_indices;
float *vmask;
+ /* bmesh */
+ struct GHashIterator bm_unique_verts;
+ struct GHashIterator bm_other_verts;
+ struct CustomData *bm_vdata;
+
/* result: these are all computed in the macro, but we assume
* that compiler optimization's will skip the ones we don't use */
struct MVert *mvert;
+ struct BMVert *bm_vert;
float *co;
short *no;
float *fno;
@@ -213,7 +257,7 @@ typedef struct PBVHVertexIter {
void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
PBVHVertexIter *vi, int mode);
-#define BLI_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
+#define BKE_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
pbvh_vertex_iter_init(bvh, node, &vi, mode); \
\
for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \
@@ -241,7 +285,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
continue; \
} \
} \
- else { \
+ else if (vi.mverts) { \
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \
continue; \
@@ -250,21 +294,39 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
if (vi.vmask) \
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
} \
-
-#define BLI_pbvh_vertex_iter_end \
+ else { \
+ if (!BLI_ghashIterator_isDone(&vi.bm_unique_verts)) {\
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_unique_verts); \
+ BLI_ghashIterator_step(&vi.bm_unique_verts); \
+ } \
+ else { \
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_other_verts); \
+ BLI_ghashIterator_step(&vi.bm_other_verts); \
+ } \
+ if (mode == PBVH_ITER_UNIQUE && \
+ BM_elem_flag_test(vi.bm_vert, BM_ELEM_HIDDEN)) \
+ continue; \
+ vi.co = vi.bm_vert->co; \
+ vi.fno = vi.bm_vert->no; \
+ vi.mask = CustomData_bmesh_get(vi.bm_vdata, \
+ vi.bm_vert->head.data, \
+ CD_PAINT_MASK); \
+ }
+
+#define BKE_pbvh_vertex_iter_end \
} \
} \
}
-void BLI_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count);
-void BLI_pbvh_node_free_proxies(PBVHNode *node);
-PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node);
-void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***nodes, int *totnode);
+void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count);
+void BKE_pbvh_node_free_proxies(PBVHNode *node);
+PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node);
+void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***nodes, int *totnode);
-//void BLI_pbvh_node_BB_reset(PBVHNode *node);
-//void BLI_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
+//void BKE_pbvh_node_BB_reset(PBVHNode *node);
+//void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
void pbvh_show_diffuse_color_set(PBVH *bvh, int show_diffuse_color);
-#endif /* __BLI_PBVH_H__ */
+#endif /* __BKE_PBVH_H__ */
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 77b35e1a25c..1cb50425c40 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -67,6 +67,7 @@
#define PTCACHE_TYPE_SMOKE_DOMAIN 3
#define PTCACHE_TYPE_SMOKE_HIGHRES 4
#define PTCACHE_TYPE_DYNAMICPAINT 5
+#define PTCACHE_TYPE_RIGIDBODY 6
/* high bits reserved for flags that need to be stored in file */
#define PTCACHE_TYPEFLAG_COMPRESS (1 << 16)
@@ -91,6 +92,7 @@ struct PointCache;
struct Scene;
struct SmokeModifierData;
struct SoftBody;
+struct RigidBodyWorld;
/* temp structure for read/write */
typedef struct PTCacheData {
@@ -260,6 +262,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct Par
void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd);
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd);
void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, struct Object *ob, struct DynamicPaintSurface *surface);
+void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw);
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis);
@@ -294,10 +297,6 @@ int BKE_ptcache_read(PTCacheID *pid, float cfra);
/* Main cache writing call. */
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra);
-/****************** Continue physics ***************/
-void BKE_ptcache_set_continue_physics(struct Main *bmain, struct Scene *scene, int enable);
-int BKE_ptcache_get_continue_physics(void);
-
/******************* Allocate & free ***************/
struct PointCache *BKE_ptcache_add(struct ListBase *ptcaches);
void BKE_ptcache_free_mem(struct ListBase *mem_cache);
diff --git a/source/blender/blenkernel/BKE_property.h b/source/blender/blenkernel/BKE_property.h
index e0eb8c04b60..99e60757f15 100644
--- a/source/blender/blenkernel/BKE_property.h
+++ b/source/blender/blenkernel/BKE_property.h
@@ -47,6 +47,7 @@ void BKE_bproperty_object_set(struct Object *ob, struct bProperty *
// int BKE_bproperty_cmp(struct bProperty *prop, const char *str);
void BKE_bproperty_set(struct bProperty *prop, const char *str);
void BKE_bproperty_add(struct bProperty *prop, const char *str);
-void BKE_bproperty_set_valstr(struct bProperty *prop, char *str);
+/* should really be called '_get_valstr()' or '_as_string()' */
+void BKE_bproperty_set_valstr(struct bProperty *prop, char str[MAX_PROPSTRING]);
#endif
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 4d69a013101..e659954a3ac 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -35,6 +35,7 @@ extern "C" {
#endif
#include "DNA_windowmanager_types.h"
+#include "BLI_utildefines.h"
/* Reporting Information and Errors
*
@@ -72,7 +73,10 @@ void BKE_reports_print(ReportList *reports, ReportType level);
Report *BKE_reports_last_displayable(ReportList *reports);
int BKE_reports_contain(ReportList *reports, ReportType level);
-
+
+bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header);
+bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
new file mode 100644
index 00000000000..12779a697b6
--- /dev/null
+++ b/source/blender/blenkernel/BKE_rigidbody.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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file BKE_rigidbody.h
+ * \ingroup blenkernel
+ * \brief API for Blender-side Rigid Body stuff
+ */
+
+
+#ifndef __BKE_RIGIDBODY_H__
+#define __BKE_RIGIDBODY_H__
+
+struct RigidBodyWorld;
+struct RigidBodyOb;
+
+struct Scene;
+struct Object;
+struct Group;
+
+/* -------------- */
+/* Memory Management */
+
+void BKE_rigidbody_free_world(struct RigidBodyWorld *rbw);
+void BKE_rigidbody_free_object(struct Object *ob);
+void BKE_rigidbody_free_constraint(struct Object *ob);
+
+/* ...... */
+
+struct RigidBodyOb *BKE_rigidbody_copy_object(struct Object *ob);
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(struct Object *ob);
+void BKE_rigidbody_relink_constraint(struct RigidBodyCon *rbc);
+
+/* -------------- */
+/* Setup */
+
+/* create Blender-side settings data - physics objects not initialised yet */
+struct RigidBodyWorld *BKE_rigidbody_create_world(struct Scene *scene);
+struct RigidBodyOb *BKE_rigidbody_create_object(struct Scene *scene, struct Object *ob, short type);
+struct RigidBodyCon *BKE_rigidbody_create_constraint(struct Scene *scene, struct Object *ob, short type);
+
+/* 'validate' (i.e. make new or replace old) Physics-Engine objects */
+void BKE_rigidbody_validate_sim_world(struct Scene *scene, struct RigidBodyWorld *rbw, short rebuild);
+void BKE_rigidbody_validate_sim_object(struct RigidBodyWorld *rbw, struct Object *ob, short rebuild);
+void BKE_rigidbody_validate_sim_shape(struct Object *ob, short rebuild);
+void BKE_rigidbody_validate_sim_constraint(struct RigidBodyWorld *rbw, struct Object *ob, short rebuild);
+
+/* -------------- */
+/* Utilities */
+
+struct RigidBodyWorld *BKE_rigidbody_get_world(struct Scene *scene);
+void BKE_rigidbody_remove_object(struct Scene *scene, struct Object *ob);
+void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob);
+
+/* -------------- */
+/* Utility Macros */
+
+/* get mass of Rigid Body Object to supply to RigidBody simulators */
+#define RBO_GET_MASS(rbo) \
+ ((rbo && ((rbo->type == RBO_TYPE_PASSIVE) || (rbo->flag & RBO_FLAG_KINEMATIC) || (rbo->flag & RBO_FLAG_DISABLED))) ? (0.0f) : (rbo->mass))
+/* get collision margin for Rigid Body Object, triangle mesh and cone shapes cannot embed margin, convex hull always uses custom margin */
+#define RBO_GET_MARGIN(rbo) \
+ ((rbo->flag & RBO_FLAG_USE_MARGIN || rbo->shape == RB_SHAPE_CONVEXH || rbo->shape == RB_SHAPE_TRIMESH || rbo->shape == RB_SHAPE_CONE) ? (rbo->margin) : (0.04f))
+
+/* -------------- */
+/* Simulation */
+
+void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle);
+void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime);
+void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
+void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime);
+
+#endif /* __BKE_RIGIDBODY_H__ */
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 9927c7a42ed..9bf0991272a 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -47,7 +47,7 @@ struct RenderData;
struct SceneRenderLayer;
struct Scene;
struct Text;
-struct Text;
+struct Main;
#define SCE_COPY_NEW 0
#define SCE_COPY_EMPTY 1
@@ -67,11 +67,12 @@ void free_avicodecdata(struct AviCodecData *acd);
void free_qtcodecdata(struct QuicktimeCodecData *acd);
void BKE_scene_free(struct Scene *sce);
-struct Scene *BKE_scene_add(const char *name);
+struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
/* base functions */
struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
+void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
void BKE_scene_base_deselect_all(struct Scene *sce);
void BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
int BKE_scene_base_iter_next(struct Scene **scene, int val, struct Base **base, struct Object **ob);
@@ -115,6 +116,7 @@ int BKE_scene_use_new_shading_nodes(struct Scene *scene);
void BKE_scene_disable_color_management(struct Scene *scene);
int BKE_scene_check_color_management_enabled(const struct Scene *scene);
+int BKE_scene_check_rigidbody_active(const struct Scene *scene);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 8aa08beec57..629acab9e34 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -46,6 +46,7 @@ struct bContext;
struct bContextDataResult;
struct bScreen;
struct uiLayout;
+struct uiList;
struct uiMenuItem;
struct wmKeyConfig;
struct wmNotifier;
@@ -181,6 +182,23 @@ typedef struct PanelType {
ExtensionRNA ext;
} PanelType;
+/* uilist types */
+
+/* draw an item in the uiList */
+typedef void (*uiListDrawItemFunc)(struct uiList *, struct bContext *, struct uiLayout *, struct PointerRNA *,
+ struct PointerRNA *, int, struct PointerRNA *, const char *, int);
+
+typedef struct uiListType {
+ struct uiListType *next, *prev;
+
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+
+ uiListDrawItemFunc draw_item;
+
+ /* RNA integration */
+ ExtensionRNA ext;
+} uiListType;
+
/* header types */
typedef struct HeaderType {
@@ -243,6 +261,7 @@ void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
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_big_area(struct bScreen *sc, const int spacetype, const short min);
void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 88294cb30b6..eef134a6872 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -356,6 +356,8 @@ typedef struct SeqLoadInfo {
typedef struct Sequence *(*SeqLoadFunc)(struct bContext *, ListBase *, struct SeqLoadInfo *);
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);
struct Sequence *BKE_sequencer_add_image_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
@@ -363,7 +365,7 @@ struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seq
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, int, int, char[256]);
+typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, int, int, int, char[256]);
extern SequencerDrawView sequencer_view3d_cb;
/* copy/paste */
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index d1332ba937e..61d82e6c604 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -121,7 +121,8 @@ typedef struct ShrinkwrapCalcData {
} ShrinkwrapCalcData;
-void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts);
+void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts);
/*
* This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is:
@@ -130,9 +131,12 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object
* then the input (vert, dir, BVHTreeRayHit) must be defined in ob1 coordinates space
* and the BVHTree must be built in ob2 coordinate space.
*
- * Thus it provides an easy way to cast the same ray across several trees (where each tree was built on its own coords space)
+ * Thus it provides an easy way to cast the same ray across several trees
+ * (where each tree was built on its own coords space)
*/
-int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata);
+int normal_projection_project_vertex(char options, const float vert[3], const float dir[3],
+ const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
+ BVHTree_RayCastCallback callback, void *userdata);
/*
* NULL initializers to local data
@@ -142,6 +146,4 @@ int normal_projection_project_vertex(char options, const float *vert, const floa
#define NULL_BVHTreeRayHit {NULL, }
#define NULL_BVHTreeNearest {0, }
-
-#endif
-
+#endif /* __BKE_SHRINKWRAP_H__ */
diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h
index 52c177fce57..e2f0fa50a86 100644
--- a/source/blender/blenkernel/BKE_speaker.h
+++ b/source/blender/blenkernel/BKE_speaker.h
@@ -33,7 +33,9 @@
* \brief General operations for speakers.
*/
-void *BKE_speaker_add(const char *name);
+struct Main;
+
+void *BKE_speaker_add(struct Main *bmain, const char *name);
struct Speaker *BKE_speaker_copy(struct Speaker *spk);
void BKE_speaker_make_local(struct Speaker *spk);
void BKE_speaker_free(struct Speaker *spk);
diff --git a/source/blender/blenkernel/BKE_suggestions.h b/source/blender/blenkernel/BKE_suggestions.h
index 9b61d9141fb..c36a2d61968 100644
--- a/source/blender/blenkernel/BKE_suggestions.h
+++ b/source/blender/blenkernel/BKE_suggestions.h
@@ -75,7 +75,7 @@ short texttool_text_is_active(Text *text);
/* Suggestions */
void texttool_suggest_add(const char *name, char type);
-void texttool_suggest_prefix(const char *prefix);
+void texttool_suggest_prefix(const char *prefix, const int prefix_len);
void texttool_suggest_clear(void);
SuggItem *texttool_suggest_first(void);
SuggItem *texttool_suggest_last(void);
diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h
index dea5e726671..b3e6ab37273 100644
--- a/source/blender/blenkernel/BKE_tessmesh.h
+++ b/source/blender/blenkernel/BKE_tessmesh.h
@@ -80,12 +80,11 @@ typedef struct BMEditMesh {
/*temp variables for x-mirror editing*/
int mirror_cdlayer; /* -1 is invalid */
- int mirr_free_arrays;
} BMEditMesh;
-void BMEdit_RecalcTessellation(BMEditMesh *tm);
-BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate);
-BMEditMesh *BMEdit_Copy(BMEditMesh *tm);
+void BMEdit_RecalcTessellation(BMEditMesh *em);
+BMEditMesh *BMEdit_Create(BMesh *bm, const bool do_tessellate);
+BMEditMesh *BMEdit_Copy(BMEditMesh *em);
BMEditMesh *BMEdit_FromObject(struct Object *ob);
void BMEdit_Free(BMEditMesh *em);
void BMEdit_UpdateLinkedCustomData(BMEditMesh *em);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index accac8694a9..3d7b5d1c8e4 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -45,10 +45,10 @@ struct SpaceText;
void BKE_text_free (struct Text *text);
void txt_set_undostate (int u);
int txt_get_undostate (void);
-struct Text* BKE_text_add (const char *name);
+struct Text* BKE_text_add (struct Main *bmain, const char *name);
int txt_extended_ascii_as_utf8(char **str);
int BKE_text_reload (struct Text *text);
-struct Text* BKE_text_load (const char *file, const char *relpath);
+struct Text* BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
struct Text* BKE_text_copy (struct Text *ta);
void BKE_text_unlink (struct Main *bmain, struct Text *text);
void BKE_text_clear (struct Text *text);
@@ -66,8 +66,8 @@ void txt_move_up (struct Text *text, short sel);
void txt_move_down (struct Text *text, short sel);
void txt_move_left (struct Text *text, short sel);
void txt_move_right (struct Text *text, short sel);
-void txt_jump_left (struct Text *text, short sel);
-void txt_jump_right (struct Text *text, short sel);
+void txt_jump_left (struct Text *text, bool sel, bool use_init_step);
+void txt_jump_right (struct Text *text, bool sel, bool use_init_step);
void txt_move_bof (struct Text *text, short sel);
void txt_move_eof (struct Text *text, short sel);
void txt_move_bol (struct Text *text, short sel);
@@ -105,7 +105,13 @@ int text_check_bracket(const char ch);
int text_check_delim(const char ch);
int text_check_digit(const char ch);
int text_check_identifier(const char ch);
+int text_check_identifier_nodigit(const char ch);
int text_check_whitespace(const char ch);
+int text_find_identifier_start(const char *str, int i);
+
+/* defined in bpy_interface.c */
+extern int text_check_identifier_unicode(const unsigned int ch);
+extern int text_check_identifier_nodigit_unicode(const unsigned int ch);
enum {
TXT_MOVE_LINE_UP = -1,
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 78fdd26c9e0..f1796373367 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -44,6 +44,7 @@ struct EnvMap;
struct HaloRen;
struct Lamp;
struct LampRen;
+struct Main;
struct Material;
struct MTex;
struct OceanTex;
@@ -69,7 +70,7 @@ int colorband_element_remove(struct ColorBand *coba, int index);
void colorband_update_sort(struct ColorBand *coba);
void default_tex(struct Tex *tex);
-struct Tex *add_texture(const char *name);
+struct Tex *add_texture(struct Main *bmain, const char *name);
void tex_set_type(struct Tex *tex, int type);
void default_mtex(struct MTex *mtex);
struct MTex *add_mtex(void);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index eb7004b1ced..9bdc96e187d 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -46,6 +46,7 @@ struct MovieDistortion;
struct Camera;
struct Object;
struct Scene;
+struct rcti;
/* **** Common functions **** */
@@ -156,6 +157,8 @@ struct ImBuf *BKE_tracking_undistort_frame(struct MovieTracking *tracking, struc
struct ImBuf *BKE_tracking_distort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf,
int calibration_width, int calibration_height, float overscan);
+void BKE_tracking_max_undistortion_delta_across_bound(struct MovieTracking *tracking, struct rcti *rect, float delta[2]);
+
/* **** Image sampling **** */
struct ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height,
struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index 7a23bff0184..6bb35e46539 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -33,11 +33,12 @@
* \author nzc
*/
+struct Main;
struct World;
void BKE_world_free(struct World *sc);
void BKE_world_free_ex(struct World *sc, int do_id_user);
-struct World *add_world(const char *name);
+struct World *add_world(struct Main *bmian, const char *name);
struct World *BKE_world_copy(struct World *wrld);
struct World *localize_world(struct World *wrld);
void BKE_world_make_local(struct World *wrld);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2da9b402d59..cb6da194dad 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -58,6 +58,7 @@ set(SRC
intern/CCGSubSurf.c
intern/DerivedMesh.c
intern/action.c
+ intern/addon.c
intern/anim.c
intern/anim_sys.c
intern/armature.c
@@ -65,6 +66,7 @@ set(SRC
intern/bmfont.c
intern/boids.c
intern/booleanops_mesh.c
+ intern/bpath.c
intern/brush.c
intern/bullet.c
intern/bvhutils.c
@@ -101,9 +103,9 @@ set(SRC
intern/lamp.c
intern/lattice.c
intern/library.c
+ intern/mask.c
intern/mask_evaluate.c
intern/mask_rasterize.c
- intern/mask.c
intern/material.c
intern/mball.c
intern/mesh.c
@@ -121,9 +123,12 @@ set(SRC
intern/paint.c
intern/particle.c
intern/particle_system.c
+ intern/pbvh.c
+ intern/pbvh_bmesh.c
intern/pointcache.c
intern/property.c
intern/report.c
+ intern/rigidbody.c
intern/sca.c
intern/scene.c
intern/screen.c
@@ -147,9 +152,10 @@ set(SRC
intern/world.c
intern/writeavi.c
intern/writeframeserver.c
-
+
BKE_DerivedMesh.h
BKE_action.h
+ BKE_addon.h
BKE_anim.h
BKE_animsys.h
BKE_armature.h
@@ -159,6 +165,7 @@ set(SRC
BKE_bmfont_types.h
BKE_boids.h
BKE_booleanops_mesh.h
+ BKE_bpath.h
BKE_brush.h
BKE_bullet.h
BKE_bvhutils.h
@@ -209,9 +216,11 @@ set(SRC
BKE_packedFile.h
BKE_paint.h
BKE_particle.h
+ BKE_pbvh.h
BKE_pointcache.h
BKE_property.h
BKE_report.h
+ BKE_rigidbody.h
BKE_sca.h
BKE_scene.h
BKE_screen.h
@@ -234,9 +243,11 @@ set(SRC
BKE_world.h
BKE_writeavi.h
BKE_writeframeserver.h
+
depsgraph_private.h
nla_private.h
intern/CCGSubSurf.h
+ intern/pbvh_intern.h
)
add_definitions(-DGLEW_STATIC)
@@ -250,9 +261,12 @@ endif()
if(WITH_BULLET)
list(APPEND INC_SYS
- ../../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
+ )
+ list(APPEND INC
+ ../../../intern/rigidbody
)
- add_definitions(-DUSE_BULLET)
+ add_definitions(-DWITH_BULLET)
endif()
#if(WITH_MOD_CLOTH_ELTOPO)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 22be2f78ea7..aa7d8a51b8c 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import os
@@ -15,6 +41,7 @@ incs += ' ../render/extern/include ../makesrna'
incs += ' ../imbuf ../ikplugin ../avi #/intern/elbeem/extern ../nodes ../modifiers'
incs += ' #/intern/iksolver/extern ../blenloader'
incs += ' #/extern/bullet2/src'
+incs += ' #/intern/rigidbody'
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
incs += ' ../gpu #/extern/glew/include'
incs += ' ../bmesh'
@@ -84,7 +111,7 @@ if env['WITH_BF_QUICKTIME']:
incs += ' ' + env['BF_QUICKTIME_INC']
if env['WITH_BF_BULLET']:
- defs.append('USE_BULLET')
+ defs.append('WITH_BULLET')
if env['OURPLATFORM'] == 'darwin':
if env['WITH_BF_OPENMP']:
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index cc20470b4d5..e58d484b0c0 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -16,12 +16,6 @@
#include "BLI_utildefines.h" /* for BLI_assert */
-#ifdef _MSC_VER
-# define CCG_INLINE __inline
-#else
-# define CCG_INLINE inline
-#endif
-
/* used for normalize_v3 in BLI_math_vector
* float.h's FLT_EPSILON causes trouble with subsurf normals - campbell */
#define EPSILON (1.0e-35f)
@@ -236,7 +230,7 @@ int ccg_gridsize(int level)
{
BLI_assert(level > 0);
BLI_assert(level <= 31);
-
+
return (1 << (level - 1)) + 1;
}
@@ -305,7 +299,7 @@ struct CCGVert {
// byte *userData;
};
-static CCG_INLINE byte *VERT_getLevelData(CCGVert *v)
+BLI_INLINE byte *VERT_getLevelData(CCGVert *v)
{
return (byte *)(&(v)[1]);
}
@@ -324,7 +318,7 @@ struct CCGEdge {
// byte *userData;
};
-static CCG_INLINE byte *EDGE_getLevelData(CCGEdge *e)
+BLI_INLINE byte *EDGE_getLevelData(CCGEdge *e)
{
return (byte *)(&(e)[1]);
}
@@ -342,17 +336,17 @@ struct CCGFace {
// byte *userData;
};
-static CCG_INLINE CCGVert **FACE_getVerts(CCGFace *f)
+BLI_INLINE CCGVert **FACE_getVerts(CCGFace *f)
{
return (CCGVert **)(&f[1]);
}
-static CCG_INLINE CCGEdge **FACE_getEdges(CCGFace *f)
+BLI_INLINE CCGEdge **FACE_getEdges(CCGFace *f)
{
return (CCGEdge **)(&(FACE_getVerts(f)[f->numVerts]));
}
-static CCG_INLINE byte *FACE_getCenterData(CCGFace *f)
+BLI_INLINE byte *FACE_getCenterData(CCGFace *f)
{
return (byte *)(&(FACE_getEdges(f)[(f)->numVerts]));
}
@@ -698,28 +692,28 @@ static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int
return f;
}
-static CCG_INLINE void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize)
+BLI_INLINE void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize)
{
int maxGridSize = ccg_gridsize(levels);
int spacing = ccg_spacing(levels, lvl);
byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
return &gridBase[dataSize * x * spacing];
}
-static CCG_INLINE void *_face_getIENo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset)
+BLI_INLINE void *_face_getIENo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset)
{
int maxGridSize = ccg_gridsize(levels);
int spacing = ccg_spacing(levels, lvl);
byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
return &gridBase[dataSize * x * spacing + normalDataOffset];
}
-static CCG_INLINE void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize)
+BLI_INLINE void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize)
{
int maxGridSize = ccg_gridsize(levels);
int spacing = ccg_spacing(levels, lvl);
byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
return &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing)];
}
-static CCG_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset)
+BLI_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset)
{
int maxGridSize = ccg_gridsize(levels);
int spacing = ccg_spacing(levels, lvl);
@@ -742,7 +736,7 @@ static int _face_getEdgeIndex(CCGFace *f, CCGEdge *e)
return i;
return -1;
}
-static CCG_INLINE void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize)
+BLI_INLINE void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize)
{
int maxGridSize = ccg_gridsize(levels);
int spacing = ccg_spacing(levels, lvl);
@@ -1422,18 +1416,25 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
float no[3];
for (S = 0; S < f->numVerts; S++) {
- for (y = 0; y < gridSize - 1; y++)
- for (x = 0; x < gridSize - 1; x++)
+ for (y = 0; y < gridSize - 1; y++) {
+ for (x = 0; x < gridSize - 1; x++) {
NormZero(FACE_getIFNo(f, lvl, S, x, y));
+ }
+ }
- if (FACE_getEdges(f)[(S - 1 + f->numVerts) % f->numVerts]->flags & Edge_eEffected)
- for (x = 0; x < gridSize - 1; x++)
+ if (FACE_getEdges(f)[(S - 1 + f->numVerts) % f->numVerts]->flags & Edge_eEffected) {
+ for (x = 0; x < gridSize - 1; x++) {
NormZero(FACE_getIFNo(f, lvl, S, x, gridSize - 1));
- if (FACE_getEdges(f)[S]->flags & Edge_eEffected)
- for (y = 0; y < gridSize - 1; y++)
+ }
+ }
+ if (FACE_getEdges(f)[S]->flags & Edge_eEffected) {
+ for (y = 0; y < gridSize - 1; y++) {
NormZero(FACE_getIFNo(f, lvl, S, gridSize - 1, y));
- if (FACE_getVerts(f)[S]->flags & Vert_eEffected)
+ }
+ }
+ if (FACE_getVerts(f)[S]->flags & Vert_eEffected) {
NormZero(FACE_getIFNo(f, lvl, S, gridSize - 1, gridSize - 1));
+ }
}
for (S = 0; S < f->numVerts; S++) {
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d09bea0f662..6b3c95a5cd3 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -47,10 +47,10 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_array.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
+#include "BKE_pbvh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_displist.h"
#include "BKE_key.h"
@@ -169,7 +169,7 @@ static MPoly *dm_getPolyArray(DerivedMesh *dm)
static MVert *dm_dupVertArray(DerivedMesh *dm)
{
- MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
+ MVert *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumVerts(dm),
"dm_dupVertArray tmp");
if (tmp) dm->copyVertArray(dm, tmp);
@@ -179,7 +179,7 @@ static MVert *dm_dupVertArray(DerivedMesh *dm)
static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
{
- MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm),
+ MEdge *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumEdges(dm),
"dm_dupEdgeArray tmp");
if (tmp) dm->copyEdgeArray(dm, tmp);
@@ -189,7 +189,7 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
static MFace *dm_dupFaceArray(DerivedMesh *dm)
{
- MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
+ MFace *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
"dm_dupFaceArray tmp");
if (tmp) dm->copyTessFaceArray(dm, tmp);
@@ -199,7 +199,7 @@ static MFace *dm_dupFaceArray(DerivedMesh *dm)
static MLoop *dm_dupLoopArray(DerivedMesh *dm)
{
- MLoop *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumLoops(dm),
+ MLoop *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumLoops(dm),
"dm_dupLoopArray tmp");
if (tmp) dm->copyLoopArray(dm, tmp);
@@ -209,7 +209,7 @@ static MLoop *dm_dupLoopArray(DerivedMesh *dm)
static MPoly *dm_dupPolyArray(DerivedMesh *dm)
{
- MPoly *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumPolys(dm),
+ MPoly *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumPolys(dm),
"dm_dupPolyArray tmp");
if (tmp) dm->copyPolyArray(dm, tmp);
@@ -313,6 +313,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type
CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
CD_CALLOC, numPolys);
+ dm->cd_flag = source->cd_flag;
+
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
@@ -483,11 +485,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
totedge = tmp.totedge = dm->getNumEdges(dm);
totloop = tmp.totloop = dm->getNumLoops(dm);
totpoly = tmp.totpoly = dm->getNumPolys(dm);
+ tmp.totface = 0;
CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
+ me->cd_flag = dm->cd_flag;
if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
KeyBlock *kb;
@@ -538,9 +542,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
}
/* yes, must be before _and_ after tessellate */
- mesh_update_customdata_pointers(&tmp, TRUE);
+ mesh_update_customdata_pointers(&tmp, false);
- BKE_mesh_tessface_calc(&tmp);
+ /* since 2.65 caller must do! */
+ // BKE_mesh_tessface_calc(&tmp);
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
@@ -557,6 +562,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
tmp.key = NULL;
}
+ /* Clear selection history */
+ tmp.mselect = NULL;
+ tmp.totselect = 0;
+ if (me->mselect) {
+ MEM_freeN(me->mselect);
+ }
+
*me = tmp;
}
@@ -569,7 +581,7 @@ void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb)
if (totvert == 0 || me->totvert == 0 || me->totvert != totvert) return;
if (kb->data) MEM_freeN(kb->data);
- kb->data = MEM_callocN(me->key->elemsize * me->totvert, "kb->data");
+ kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data");
kb->totelem = totvert;
fp = kb->data;
@@ -857,30 +869,27 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
return dm;
}
-static float *get_editbmesh_orco_verts(BMEditMesh *em)
+static float (*get_editbmesh_orco_verts(BMEditMesh *em))[3]
{
BMIter iter;
BMVert *eve;
- float *orco;
- int a, totvert;
+ float (*orco)[3];
+ int i;
/* these may not really be the orco's, but it's only for preview.
* could be solver better once, but isn't simple */
-
- totvert = em->bm->totvert;
- orco = MEM_mallocN(sizeof(float) * 3 * totvert, "BMEditMesh Orco");
+ orco = MEM_mallocN(sizeof(float) * 3 * em->bm->totvert, "BMEditMesh Orco");
- eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
- for (a = 0; eve; eve = BM_iter_step(&iter), a += 3) {
- copy_v3_v3(orco + a, eve->co);
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ copy_v3_v3(orco[i], eve->co);
}
return orco;
}
/* orco custom data layer */
-static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free)
+static float (*get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free))[3]
{
*free = 0;
@@ -889,9 +898,9 @@ static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free
*free = 1;
if (em)
- return (float(*)[3])get_editbmesh_orco_verts(em);
+ return get_editbmesh_orco_verts(em);
else
- return (float(*)[3])BKE_mesh_orco_verts_get(ob);
+ return BKE_mesh_orco_verts_get(ob);
}
else if (layer == CD_CLOTH_ORCO) {
/* apply shape key for cloth, this should really be solved
@@ -1008,8 +1017,12 @@ void weight_to_rgb(float r_rgb[3], const float weight)
/* draw_flag's for calc_weightpaint_vert_color */
enum {
- CALC_WP_MULTIPAINT = (1 << 0),
- CALC_WP_AUTO_NORMALIZE = (1 << 1)
+ /* only one of these should be set, keep first (for easy bit-shifting) */
+ CALC_WP_GROUP_USER_ACTIVE = (1 << 1),
+ CALC_WP_GROUP_USER_ALL = (1 << 2),
+
+ CALC_WP_MULTIPAINT = (1 << 3),
+ CALC_WP_AUTO_NORMALIZE = (1 << 4)
};
static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
@@ -1041,7 +1054,7 @@ static void calc_weightpaint_vert_color(
{
float input = 0.0f;
- int make_black = FALSE;
+ bool make_black = false;
if ((defbase_sel_tot > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
int was_a_nonzero = FALSE;
@@ -1063,7 +1076,7 @@ static void calc_weightpaint_vert_color(
/* make it black if the selected groups have no weight on a vertex */
if (was_a_nonzero == FALSE) {
- make_black = TRUE;
+ make_black = true;
}
else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) {
input /= defbase_sel_tot; /* get the average */
@@ -1072,6 +1085,17 @@ static void calc_weightpaint_vert_color(
else {
/* default, non tricky behavior */
input = defvert_find_weight(dv, defbase_act);
+
+ if (draw_flag & CALC_WP_GROUP_USER_ACTIVE) {
+ if (input == 0.0f) {
+ make_black = true;
+ }
+ }
+ else if (draw_flag & CALC_WP_GROUP_USER_ALL) {
+ if (input == 0.0f) {
+ make_black = defvert_is_weight_zero(dv, defbase_tot);
+ }
+ }
}
if (make_black) { /* TODO, theme color */
@@ -1129,7 +1153,12 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i
}
else {
int col_i;
- weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
+ if (draw_flag & (CALC_WP_GROUP_USER_ACTIVE | CALC_WP_GROUP_USER_ALL)) {
+ col_i = 0;
+ }
+ else {
+ weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
+ }
fill_vn_i((int *)wtcol_v, numVerts, col_i);
}
@@ -1343,9 +1372,13 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
int has_multires = mmd != NULL, multires_applied = 0;
int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
+ int sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm);
- const int draw_flag = ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
+ const int draw_flag = ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT :
+ /* CALC_WP_GROUP_USER_ACTIVE or CALC_WP_GROUP_USER_ALL*/
+ (1 << scene->toolsettings->weightuser)) |
(scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
+
/* Generic preview only in object mode! */
const int do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
#if 0 /* XXX Will re-enable this when we have global mod stack options. */
@@ -1410,7 +1443,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
if (!modifier_isEnabled(scene, md, required_mode)) continue;
if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
- if (mti->type == eModifierTypeType_OnlyDeform) {
+ if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
if (!deformedVerts)
deformedVerts = mesh_getVertexCos(me, &numVerts);
@@ -1421,7 +1454,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
/* grab modifiers until index i */
- if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
+ if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index))
break;
}
@@ -1468,9 +1501,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
modifier_setError(md, "Modifier requires original data, bad stack position");
continue;
}
- if (sculpt_mode && (!has_multires || multires_applied)) {
+ if (sculpt_mode &&
+ (!has_multires || multires_applied || ob->sculpt->bm))
+ {
int unsupported = 0;
+ if (sculpt_dyntopo)
+ unsupported = TRUE;
+
if (scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM)
unsupported |= mti->type != eModifierTypeType_OnlyDeform;
@@ -1576,9 +1614,15 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
- range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0);
- range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0);
- range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0);
+#pragma omp parallel sections if (dm->numVertData + dm->numEdgeData + dm->numPolyData >= DM_OMP_LIMIT)
+ {
+#pragma omp section
+ { range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); }
+#pragma omp section
+ { range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); }
+#pragma omp section
+ { range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); }
+ }
}
}
@@ -1666,7 +1710,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
/* grab modifiers until index i */
- if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
+ if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index))
break;
if (sculpt_mode && md->type == eModifierType_Multires)
@@ -1815,17 +1859,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
BLI_linklist_free((LinkNode *)datamasks, NULL);
}
-float (*editbmesh_get_vertex_cos(BMEditMesh * em, int *numVerts_r))[3]
+float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *numVerts_r))[3]
{
- int i, numVerts = *numVerts_r = em->bm->totvert;
- float (*cos)[3];
BMIter iter;
BMVert *eve;
+ float (*cos)[3];
+ int i;
- cos = MEM_mallocN(sizeof(float) * 3 * numVerts, "vertexcos");
+ *numVerts_r = em->bm->totvert;
- eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
- for (i = 0; eve; eve = BM_iter_step(&iter), i++) {
+ cos = MEM_mallocN(sizeof(float) * 3 * em->bm->totvert, "vertexcos");
+
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
copy_v3_v3(cos[i], eve->co);
}
@@ -2312,20 +2357,19 @@ DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
static void make_vertexcosnos__mapFunc(void *userData, int index, const float co[3],
const float no_f[3], const short no_s[3])
{
- float *vec = userData;
-
- vec += 6 * index;
+ DMCoNo *co_no = &((DMCoNo *)userData)[index];
/* check if we've been here before (normal should not be 0) */
- if (vec[3] || vec[4] || vec[5]) return;
+ if (!is_zero_v3(co_no->no)) {
+ return;
+ }
- copy_v3_v3(vec, co);
- vec += 3;
+ copy_v3_v3(co_no->co, co);
if (no_f) {
- copy_v3_v3(vec, no_f);
+ copy_v3_v3(co_no->no, no_f);
}
else {
- normal_short_to_float_v3(vec, no_s);
+ normal_short_to_float_v3(co_no->no, no_s);
}
}
@@ -2334,29 +2378,28 @@ static void make_vertexcosnos__mapFunc(void *userData, int index, const float co
/* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */
/* in use now by vertex/weight paint and particle generating */
-float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
+DMCoNo *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
{
Mesh *me = ob->data;
DerivedMesh *dm;
- float *vertexcosnos;
+ DMCoNo *vertexcosnos;
/* lets prevent crashing... */
if (ob->type != OB_MESH || me->totvert == 0)
return NULL;
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
- vertexcosnos = MEM_callocN(6 * sizeof(float) * me->totvert, "vertexcosnos map");
if (dm->foreachMappedVert) {
+ vertexcosnos = MEM_callocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map");
dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos);
}
else {
- float *fp = vertexcosnos;
+ DMCoNo *v_co_no = vertexcosnos = MEM_mallocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map");
int a;
-
- for (a = 0; a < me->totvert; a++, fp += 6) {
- dm->getVertCo(dm, a, fp);
- dm->getVertNo(dm, a, fp + 3);
+ for (a = 0; a < me->totvert; a++, v_co_no++) {
+ dm->getVertCo(dm, a, v_co_no->co);
+ dm->getVertNo(dm, a, v_co_no->no);
}
}
@@ -2700,7 +2743,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->tottface++;
attribs->tface[a].array = tfdata->layers[layer].data;
- attribs->tface[a].em_offset = tfdata->layers[layer].offset;
+ attribs->tface[a].em_offset = ldata->layers[layer].offset;
attribs->tface[a].gl_index = gattribs->layer[b].glindex;
attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
}
@@ -2737,7 +2780,8 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->totmcol++;
attribs->mcol[a].array = tfdata->layers[layer].data;
- attribs->mcol[a].em_offset = tfdata->layers[layer].offset;
+ /* 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;
attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
}
}
@@ -2753,6 +2797,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->totmcol++;
attribs->mcol[a].array = tfdata->layers[layer].data;
+ /* odd, store the offset for a different layer type here, but editmode draw code expects it */
attribs->mcol[a].em_offset = tfdata->layers[layer].offset;
attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index dd27cc70ba3..509442b1d4e 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -43,7 +43,6 @@
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -79,11 +78,11 @@
/* ***************** Library data level operations on action ************** */
-bAction *add_empty_action(const char name[])
+bAction *add_empty_action(Main *bmain, const char name[])
{
bAction *act;
- act = BKE_libblock_alloc(&G.main->action, ID_AC, name);
+ act = BKE_libblock_alloc(&bmain->action, ID_AC, name);
return act;
}
@@ -544,7 +543,7 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon)
for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
/* TODO: rename this argument... */
if (copycon) {
- copy_constraints(&listb, &pchan->constraints, TRUE); // copy_constraints NULLs listb
+ BKE_copy_constraints(&listb, &pchan->constraints, TRUE); // BKE_copy_constraints NULLs listb
pchan->constraints = listb;
pchan->mpath = NULL; /* motion paths should not get copied yet... */
}
@@ -622,7 +621,7 @@ void BKE_pose_channel_free(bPoseChannel *pchan)
pchan->mpath = NULL;
}
- free_constraints(&pchan->constraints);
+ BKE_free_constraints(&pchan->constraints);
if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
@@ -712,7 +711,7 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f
pchan->iklinweight = pchan_from->iklinweight;
/* constraints */
- copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
+ BKE_copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
/* id-properties */
if (pchan->prop) {
@@ -1119,18 +1118,18 @@ void BKE_pose_rest(bPose *pose)
}
/* both poses should be in sync */
-void BKE_pose_copy_result(bPose *to, bPose *from)
+bool BKE_pose_copy_result(bPose *to, bPose *from)
{
bPoseChannel *pchanto, *pchanfrom;
if (to == NULL || from == NULL) {
- printf("pose result copy error to:%p from:%p\n", (void *)to, (void *)from); /* debug temp */
- return;
+ printf("Pose copy error, pose to:%p from:%p\n", (void *)to, (void *)from); /* debug temp */
+ return false;
}
if (to == from) {
printf("BKE_pose_copy_result source and target are the same\n");
- return;
+ return false;
}
@@ -1154,6 +1153,7 @@ void BKE_pose_copy_result(bPose *to, bPose *from)
pchanto->protectflag = pchanfrom->protectflag;
}
}
+ return true;
}
/* For the calculation of the effects of an Action at the given frame on an object
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
new file mode 100644
index 00000000000..7f475cd4732
--- /dev/null
+++ b/source/blender/blenkernel/intern/addon.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.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#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;
+
+
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet)
+{
+ if (idname[0]) {
+ bAddonPrefType *apt;
+
+ apt = BLI_ghash_lookup(global_addonpreftype_hash, idname);
+ if (apt) {
+ return apt;
+ }
+
+ if (!quiet) {
+ printf("search for unknown addon-pref '%s'\n", idname);
+ }
+ }
+ else {
+ if (!quiet) {
+ printf("search for empty addon-pref");
+ }
+ }
+
+ return NULL;
+}
+
+void BKE_addon_pref_type_add(bAddonPrefType *apt)
+{
+ BLI_ghash_insert(global_addonpreftype_hash, (void *)apt->idname, apt);
+}
+
+void BKE_addon_pref_type_remove(bAddonPrefType *apt)
+{
+ BLI_ghash_remove(global_addonpreftype_hash, (void *)apt->idname, NULL, (GHashValFreeFP)MEM_freeN);
+}
+
+void BKE_addon_pref_type_init(void)
+{
+ BLI_assert(global_addonpreftype_hash == NULL);
+ global_addonpreftype_hash = BLI_ghash_str_new(__func__);
+}
+
+void BKE_addon_pref_type_free(void)
+{
+ BLI_ghash_free(global_addonpreftype_hash, NULL, (GHashValFreeFP)MEM_freeN);
+ global_addonpreftype_hash = NULL;
+}
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 9a2462e9724..4eb26e81ae2 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -76,7 +76,7 @@
/* --------------------- */
/* forward declarations */
-static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4],
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4],
int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag);
/* ******************************************************************** */
@@ -311,7 +311,7 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
BLI_addhead(&scene->base, base);
mpt->ob->flag |= BA_TEMP_TAG;
-
+
/* we really don't need to continue anymore once this happens, but this line might really 'break' */
break;
}
@@ -319,37 +319,45 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
}
/* "brew me a list that's sorted a bit faster now depsy" */
- DAG_scene_sort(G.main, scene);
+ DAG_scene_relations_rebuild(G.main, scene);
}
/* update scene for current frame */
static void motionpaths_calc_update_scene(Scene *scene)
{
#if 1 // 'production' optimizations always on
- Base *base, *last = NULL;
-
- /* only stuff that moves or needs display still */
- DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
-
- /* find the last object with the tag
- * - all those afterwards are assumed to not be relevant for our calculations
- */
- /* optimize further by moving out... */
- for (base = scene->base.first; base; base = base->next) {
- if (base->object->flag & BA_TEMP_TAG)
- last = base;
+
+ /* rigid body simulation needs complete update to work correctly for now */
+ /* RB_TODO investigate if we could avoid updating everything */
+ if (BKE_scene_check_rigidbody_active(scene)) {
+ BKE_scene_update_for_newframe(G.main, scene, scene->lay);
}
-
- /* perform updates for tagged objects */
- /* XXX: this will break if rigs depend on scene or other data that
- * is animated but not attached to/updatable from objects */
- for (base = scene->base.first; base; base = base->next) {
- /* update this object */
- BKE_object_handle_update(scene, base->object);
+ else { /* otherwise we can optimize by restricting updates */
+ Base *base, *last = NULL;
- /* if this is the last one we need to update, let's stop to save some time */
- if (base == last)
- break;
+ /* only stuff that moves or needs display still */
+ DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
+
+ /* find the last object with the tag
+ * - all those afterwards are assumed to not be relevant for our calculations
+ */
+ /* optimize further by moving out... */
+ for (base = scene->base.first; base; base = base->next) {
+ if (base->object->flag & BA_TEMP_TAG)
+ last = base;
+ }
+
+ /* perform updates for tagged objects */
+ /* XXX: this will break if rigs depend on scene or other data that
+ * is animated but not attached to/updatable from objects */
+ for (base = scene->base.first; base; base = base->next) {
+ /* update this object */
+ BKE_object_handle_update(scene, base->object);
+
+ /* if this is the last one we need to update, let's stop to save some time */
+ if (base == last)
+ break;
+ }
}
#else // original, 'always correct' version
/* do all updates
@@ -706,7 +714,7 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
#define DUPLILIST_FOR_RENDER 2
#define DUPLILIST_ANIMATED 4
-static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay,
+static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[4][4], int lay,
int persistent_id[MAX_DUPLI_RECUR], int level, int index, int type, short flag)
{
DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject");
@@ -930,7 +938,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
}
}
-static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR],
+static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR],
int level, short flag)
{
Object *ob, *ob_iter;
@@ -957,7 +965,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
}
else
- dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
if (flag & DUPLILIST_FOR_RENDER) {
vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
@@ -1054,7 +1062,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
dm->release(dm);
}
-static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR],
+static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR],
int level, short flag)
{
Object *ob, *ob_iter;
@@ -1084,7 +1092,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
}
else {
- dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
}
totface = dm->getNumPolys(dm);
@@ -1240,7 +1248,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
dm->release(dm);
}
-static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys,
+static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4],
+ int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys,
int level, short flag)
{
GroupObject *go;
@@ -1479,7 +1488,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
/* blender internal needs this to be set to dupligroup to render
* groups correctly, but we don't want this hack for cycles */
- if(dupli_type_hack && GS(id->name) == ID_GR)
+ if (dupli_type_hack && GS(id->name) == ID_GR)
dupli_type = OB_DUPLIGROUP;
/* to give ipos in object correct offset */
@@ -1635,7 +1644,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persiste
/* ------------- */
-static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4],
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4],
int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag)
{
if ((ob->transflag & OB_DUPLI) == 0)
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 40b883e3f4e..74e44eab281 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -499,15 +499,15 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
if (srcAdt->action) {
/* set up an action if necessary, and name it in a similar way so that it can be easily found again */
if (dstAdt->action == NULL) {
- dstAdt->action = add_empty_action(srcAdt->action->id.name + 2);
+ dstAdt->action = add_empty_action(G.main, srcAdt->action->id.name + 2);
}
else if (dstAdt->action == srcAdt->action) {
printf("Argh! Source and Destination share animation! ('%s' and '%s' both use '%s') Making new empty action\n",
srcID->name, dstID->name, srcAdt->action->id.name);
-
+
/* TODO: review this... */
id_us_min(&dstAdt->action->id);
- dstAdt->action = add_empty_action(dstAdt->action->id.name + 2);
+ dstAdt->action = add_empty_action(G.main, dstAdt->action->id.name + 2);
}
/* loop over base paths, trying to fix for each one... */
@@ -533,9 +533,9 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
/* just need to change lists */
BLI_remlink(&srcAdt->drivers, fcu);
BLI_addtail(&dstAdt->drivers, fcu);
-
+
/* TODO: add depsgraph flushing calls? */
-
+
/* can stop now, as moved already */
break;
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 1970df54339..480814a28c3 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -75,11 +74,11 @@
/* **************** Generic Functions, data level *************** */
-bArmature *BKE_armature_add(const char *name)
+bArmature *BKE_armature_add(Main *bmain, const char *name)
{
bArmature *arm;
- arm = BKE_libblock_alloc(&G.main->armature, ID_AR, name);
+ arm = BKE_libblock_alloc(&bmain->armature, ID_AR, name);
arm->deformflag = ARM_DEF_VGROUP | ARM_DEF_ENVELOPE;
arm->flag = ARM_COL_CUSTOM; /* custom bone-group colors */
arm->layer = 1;
@@ -640,7 +639,7 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info
}
}
-static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[][3])
+static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[3][3])
{
Mat4 *b_bone = pdef_info->b_bone_mats;
float (*mat)[4] = b_bone[0].mat;
@@ -722,7 +721,7 @@ float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3
}
}
-static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[][3], float mat[][3])
+static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[3][3], float mat[3][3])
{
float wmat[3][3];
@@ -736,7 +735,7 @@ static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonem
}
static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float vec[3], DualQuat *dq,
- float mat[][3], const float co[3])
+ float mat[3][3], const float co[3])
{
Bone *bone = pchan->bone;
float fac, contrib = 0.0;
@@ -783,7 +782,7 @@ static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, f
}
static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float vec[3], DualQuat *dq,
- float mat[][3], const float co[3], float *contrib)
+ float mat[3][3], const float co[3], float *contrib)
{
float cop[3], bbonemat[3][3];
DualQuat bbonedq;
@@ -1089,7 +1088,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
/* ************ END Armature Deform ******************* */
-void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int UNUSED(root),
+void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int UNUSED(root),
int UNUSED(posed))
{
copy_m4_m4(M_accumulatedMatrix, bone->arm_mat);
@@ -1098,7 +1097,7 @@ void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][
/* **************** Space to Space API ****************** */
/* Convert World-Space Matrix to Pose-Space Matrix */
-void BKE_armature_mat_world_to_pose(Object *ob, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_world_to_pose(Object *ob, float inmat[4][4], float outmat[4][4])
{
float obmat[4][4];
@@ -1132,7 +1131,7 @@ void BKE_armature_loc_world_to_pose(Object *ob, const float inloc[3], float outl
/* Simple helper, computes the offset bone matrix.
* offs_bone = yoffs(b-1) + root(b) + bonemat(b).
* Not exported, as it is only used in this file currently... */
-static void get_offset_bone_mat(Bone *bone, float offs_bone[][4])
+static void get_offset_bone_mat(Bone *bone, float offs_bone[4][4])
{
if (!bone->parent)
return;
@@ -1164,7 +1163,7 @@ static void get_offset_bone_mat(Bone *bone, float offs_bone[][4])
* pose-channel into its local space (i.e. 'visual'-keyframing).
* (note: I don't understand that, so I keep it :p --mont29).
*/
-void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4])
+void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4])
{
Bone *bone, *parbone;
bPoseChannel *parchan;
@@ -1253,7 +1252,7 @@ void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float l
/* Convert Pose-Space Matrix to Bone-Space Matrix.
* NOTE: this cannot be used to convert to pose-space transforms of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing) */
-void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4];
@@ -1269,7 +1268,7 @@ void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float
}
/* Convert Bone-Space Matrix to Pose-Space Matrix. */
-void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4];
@@ -1298,7 +1297,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl
copy_v3_v3(outloc, nLocMat[3]);
}
-void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
bPoseChannel work_pchan = *pchan;
@@ -1316,7 +1315,7 @@ void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inm
}
/* same as BKE_object_mat3_to_rot() */
-void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat)
+void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], short use_compat)
{
switch (pchan->rotmode) {
case ROT_MODE_QUAT:
@@ -1335,7 +1334,7 @@ void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat
/* Apply a 4x4 matrix to the pose bone,
* similar to BKE_object_apply_mat4() */
-void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat)
+void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], short use_compat)
{
float rot[3][3];
mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
@@ -1345,7 +1344,7 @@ void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat)
/* Remove rest-position effects from pose-transform for obtaining
* 'visual' transformation of pose-channel.
* (used by the Visual-Keyframing stuff) */
-void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4])
+void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4])
{
float imat[4][4];
@@ -1425,7 +1424,7 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float
* *************************************************************************** */
/* Computes vector and roll based on a rotation.
* "mat" must contain only a rotation, and no scaling. */
-void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll)
+void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll)
{
if (r_vec) {
copy_v3_v3(r_vec, mat[1]);
@@ -1444,7 +1443,7 @@ void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll)
/* Calculates the rest matrix of a bone based
* On its vector and a roll around that vector */
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3])
+void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
{
float nor[3], axis[3], target[3] = {0, 1, 0};
float theta;
@@ -1621,15 +1620,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
* 2. copy proxy-pchan's constraints on-to new
* 3. add extracted local constraints back on top
*
- * Note for copy_constraints: when copying constraints, disable 'do_extern' otherwise
- * we get the libs direct linked in this blend. */
- extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
- copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
+ * Note for BKE_copy_constraints: when copying constraints, disable 'do_extern' otherwise
+ * we get the libs direct linked in this blend.
+ */
+ BKE_extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
+ BKE_copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1655,7 +1655,8 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
else {
/* always copy custom shape */
pchan->custom = pchanp->custom;
- pchan->custom_tx = pchanp->custom_tx;
+ if (pchanp->custom_tx)
+ pchan->custom_tx = BKE_pose_channel_find_name(pose, pchanp->custom_tx->name);
/* ID-Property Syncing */
{
@@ -2258,7 +2259,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
{
bActionModifier *amod;
bActionStrip *strip, *strip2;
- float scene_cfra = (float)scene->r.cfra;
+ float scene_cfra = BKE_scene_frame_get(scene);
int do_modif;
for (strip = armob->nlastrips.first; strip; strip = strip->next) {
@@ -2427,15 +2428,15 @@ void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float
/* prepare PoseChannel for Constraint solving
* - makes a copy of matrix, and creates temporary struct to use
*/
- cob = constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
+ cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
/* Solve PoseChannel's Constraints */
- solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
+ BKE_solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
/* cleanup after Constraint Solving
* - applies matrix back to pchan, and frees temporary struct used
*/
- constraints_clear_evalob(cob);
+ BKE_constraints_clear_evalob(cob);
/* prevent constraints breaking a chain */
if (pchan->bone->flag & BONE_CONNECTED) {
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index f0d201ea3f7..be316197078 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -54,9 +54,9 @@
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
+#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BLI_callbacks.h"
@@ -65,6 +65,7 @@
#include "IMB_moviecache.h"
#include "BKE_blender.h"
+#include "BKE_bpath.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
@@ -80,8 +81,11 @@
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "BKE_sound.h"
+
#include "RE_pipeline.h"
+#include "BLF_api.h"
+
#include "BLO_undofile.h"
#include "BLO_readfile.h"
#include "BLO_writefile.h"
@@ -179,7 +183,7 @@ static void clean_paths(Main *main)
{
Scene *scene;
- BLI_bpath_traverse_main(main, clean_paths_visit_cb, BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL);
+ BKE_bpath_traverse_main(main, clean_paths_visit_cb, BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL);
for (scene = main->scene.first; scene; scene = scene->id.next) {
BLI_clean(scene->r.pic);
@@ -230,6 +234,9 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* but use new Scene pointer */
curscene = bfd->curscene;
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 */
@@ -270,7 +277,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
G.fileflags = bfd->fileflags;
CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
- CTX_data_scene_set(C, bfd->curscreen->scene);
+ CTX_data_scene_set(C, bfd->curscene);
CTX_wm_area_set(C, NULL);
CTX_wm_region_set(C, NULL);
CTX_wm_menu_set(C, NULL);
@@ -280,7 +287,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
if (CTX_data_scene(C) == NULL) {
/* in case we don't even have a local scene, add one */
if (!G.main->scene.first)
- BKE_scene_add("Scene");
+ BKE_scene_add(G.main, "Scene");
CTX_data_scene_set(C, G.main->scene.first);
CTX_wm_screen(C)->scene = CTX_data_scene(C);
@@ -310,23 +317,38 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
if (G.main->versionfile < 250)
do_versions_ipos_to_animato(G.main);
- if (recover && bfd->filename[0] && G.relbase_valid) {
+ G.main->recovered = 0;
+
+ /* startup.blend or recovered startup */
+ if (bfd->filename[0] == 0) {
+ G.main->name[0] = 0;
+ }
+ else if (recover && G.relbase_valid) {
/* in case of autosave or quit.blend, use original filename instead
* use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */
filepath = bfd->filename;
+ G.main->recovered = 1;
+
+ /* these are the same at times, should never copy to the same location */
+ if (G.main->name != filepath)
+ BLI_strncpy(G.main->name, filepath, FILE_MAX);
}
-#if 0
- else if (!G.relbase_valid) {
- /* otherwise, use an empty string as filename, rather than <memory2> */
- filepath = "";
- }
-#endif
- /* these are the same at times, should never copy to the same location */
- if (G.main->name != filepath)
- BLI_strncpy(G.main->name, filepath, FILE_MAX);
-
/* baseflags, groups, make depsgraph, etc */
+ /* first handle case if other windows have different scenes visible */
+ if (mode == 0) {
+ wmWindowManager *wm = G.main->wm.first;
+
+ if (wm) {
+ wmWindow *win;
+
+ for (win = wm->windows.first; win; win = win->next) {
+ if (win->screen && win->screen->scene) /* zealous check... */
+ if (win->screen->scene != CTX_data_scene(C))
+ BKE_scene_set_background(G.main, win->screen->scene);
+ }
+ }
+ }
BKE_scene_set_background(G.main, CTX_data_scene(C));
if (mode != 'u') {
@@ -335,7 +357,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
MEM_freeN(bfd);
- (void)curscene; /* quiet warning */
}
static int handle_subversion_warning(Main *main, ReportList *reports)
@@ -366,6 +387,7 @@ void BKE_userdef_free(void)
wmKeyMap *km;
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
+ bAddon *addon, *addon_next;
for (km = U.user_keymaps.first; km; km = km->next) {
for (kmdi = km->diff_items.first; kmdi; kmdi = kmdi->next) {
@@ -386,11 +408,30 @@ void BKE_userdef_free(void)
BLI_freelistN(&km->items);
}
+ for (addon = U.addons.first; addon; addon = addon_next) {
+ addon_next = addon->next;
+ if (addon->prop) {
+ IDP_FreeProperty(addon->prop);
+ MEM_freeN(addon->prop);
+ }
+ MEM_freeN(addon);
+ }
+
BLI_freelistN(&U.uistyles);
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
BLI_freelistN(&U.user_keymaps);
- BLI_freelistN(&U.addons);
+}
+
+/* handle changes in settings that need recalc */
+void BKE_userdef_state(void)
+{
+ /* prevent accidents */
+ if (U.pixelsize == 0) U.pixelsize = 1;
+
+ BLF_default_dpi(U.pixelsize * U.dpi);
+ U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
+
}
int BKE_read_file(bContext *C, const char *filepath, ReportList *reports)
@@ -439,14 +480,57 @@ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *report
BlendFileData *bfd;
bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports);
- if (bfd)
+ if (bfd) {
+ /* remove the unused screens and wm */
+ while (bfd->main->wm.first)
+ BKE_libblock_free(&bfd->main->wm, bfd->main->wm.first);
+ while (bfd->main->screen.first)
+ BKE_libblock_free(&bfd->main->screen, bfd->main->screen.first);
+
setup_app_data(C, bfd, "<memory1>");
+ }
else
BKE_reports_prepend(reports, "Loading failed: ");
return (bfd ? 1 : 0);
}
+/* only read the userdef from a .blend */
+int BKE_read_file_userdef(const char *filepath, ReportList *reports)
+{
+ BlendFileData *bfd;
+ int retval = 0;
+
+ bfd = BLO_read_from_file(filepath, reports);
+ if (bfd->user) {
+ retval = BKE_READ_FILE_OK_USERPREFS;
+
+ /* only here free userdef themes... */
+ BKE_userdef_free();
+
+ U = *bfd->user;
+ MEM_freeN(bfd->user);
+ }
+ free_main(bfd->main);
+ MEM_freeN(bfd);
+
+ return retval;
+}
+
+/* only write the userdef in a .blend */
+int BKE_write_file_userdef(const char *filepath, ReportList *reports)
+{
+ Main *mainb = MEM_callocN(sizeof(Main), "empty main");
+ int retval = 0;
+
+ if (BLO_write_file(mainb, filepath, G_FILE_USERPREFS, reports, NULL)) {
+ retval = 1;
+ }
+
+ MEM_freeN(mainb);
+
+ return retval;
+}
/* ***************** testing for break ************* */
@@ -728,48 +812,39 @@ char *BKE_undo_menu_string(void)
return menu;
}
-/* saves quit.blend */
-void BKE_undo_save_quit(void)
+/* saves .blend using undo buffer, returns 1 == success */
+int BKE_undo_save_file(const char *filename)
{
UndoElem *uel;
MemFileChunk *chunk;
- char str[FILE_MAX];
const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL;
int file;
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
- return;
+ return 0;
}
uel = curundo;
if (uel == NULL) {
fprintf(stderr, "No undo buffer to save recovery file\n");
- return;
- }
-
- /* no undo state to save */
- if (undobase.first == undobase.last) {
- return;
+ return 0;
}
- /* save the undo state as quit.blend */
- BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend");
-
/* first try create the file, if it exists call without 'O_CREAT',
* to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
errno = 0;
- file = BLI_open(str, flag, 0666);
+ file = BLI_open(filename, flag, 0666);
if (file == -1) {
if (errno == EEXIST) {
errno = 0;
- file = BLI_open(str, flag & ~O_CREAT, 0666);
+ file = BLI_open(filename, flag & ~O_CREAT, 0666);
}
}
if (file == -1) {
fprintf(stderr, "Unable to save '%s': %s\n",
- str, errno ? strerror(errno) : "Unknown error opening file");
- return;
+ filename, errno ? strerror(errno) : "Unknown error opening file");
+ return 0;
}
for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) {
@@ -777,16 +852,15 @@ void BKE_undo_save_quit(void)
break;
}
}
-
+
close(file);
if (chunk) {
fprintf(stderr, "Unable to save '%s': %s\n",
- str, errno ? strerror(errno) : "Unknown error writing file");
- }
- else {
- printf("Saved session recovery to '%s'\n", str);
+ filename, errno ? strerror(errno) : "Unknown error writing file");
+ return 0;
}
+ return 1;
}
/* sets curscene */
@@ -806,3 +880,130 @@ Main *BKE_undo_get_main(Scene **scene)
return mainp;
}
+/* ************** copy paste .blend, partial saves ********** */
+
+/* assumes data is in G.main */
+
+void BKE_copybuffer_begin(void)
+{
+ /* set all id flags to zero; */
+ flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0);
+}
+
+void BKE_copybuffer_tag_ID(ID *id)
+{
+ id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
+}
+
+static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid)
+{
+ if (vid) {
+ ID *id = vid;
+ id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
+ }
+}
+
+/* frees main in end */
+int BKE_copybuffer_save(char *filename, ReportList *reports)
+{
+ Main *mainb = MEM_callocN(sizeof(Main), "copybuffer");
+ ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
+ int a, retval;
+
+ BLO_main_expander(copybuffer_doit);
+ BLO_expand_main(NULL, G.main);
+
+ /* move over all tagged blocks */
+ set_listbasepointers(G.main, fromarray);
+ a = set_listbasepointers(mainb, lbarray);
+ while (a--) {
+ ID *id, *nextid;
+ ListBase *lb1 = lbarray[a], *lb2 = fromarray[a];
+
+ for (id = lb2->first; id; id = nextid) {
+ nextid = id->next;
+ if (id->flag & LIB_DOIT) {
+ BLI_remlink(lb2, id);
+ BLI_addtail(lb1, id);
+ }
+ }
+ }
+
+
+ /* save the buffer */
+ retval = BLO_write_file(mainb, filename, 0, reports, NULL);
+
+ /* move back the main, now sorted again */
+ set_listbasepointers(G.main, lbarray);
+ a = set_listbasepointers(mainb, fromarray);
+ while (a--) {
+ ID *id;
+ ListBase *lb1 = lbarray[a], *lb2 = fromarray[a];
+
+ while (lb2->first) {
+ id = lb2->first;
+ BLI_remlink(lb2, id);
+ BLI_addtail(lb1, id);
+ id_sort_by_name(lb1, id);
+ }
+ }
+
+ MEM_freeN(mainb);
+
+ /* set id flag to zero; */
+ flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0);
+
+ return retval;
+}
+
+/* return success (1) */
+int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Main *mainl = NULL;
+ Library *lib;
+ BlendHandle *bh;
+
+ bh = BLO_blendhandle_from_file(libname, reports);
+
+ if (bh == NULL) {
+ /* error reports will have been made by BLO_blendhandle_from_file() */
+ return 0;
+ }
+
+ BKE_scene_base_deselect_all(scene);
+
+ /* tag everything, all untagged data can be made local
+ * its also generally useful to know what is new
+ *
+ * take extra care flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
+
+ /* here appending/linking starts */
+ mainl = BLO_library_append_begin(bmain, &bh, libname);
+
+ BLO_library_append_all(mainl, bh);
+
+ BLO_library_append_end(C, mainl, &bh, 0, 0);
+
+ /* mark all library linked objects to be updated */
+ recalc_all_library_objects(bmain);
+ IMB_colormanagement_check_file_config(bmain);
+
+ /* append, rather than linking */
+ lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
+ BKE_library_make_local(bmain, lib, 1);
+
+ /* important we unset, otherwise these object wont
+ * link into other scenes from this blend file */
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
+
+ /* recreate dependency graph to include new objects */
+ DAG_relations_tag_update(bmain);
+
+ BLO_blendhandle_close(bh);
+ /* remove library... */
+
+ return 1;
+}
diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c
index 0495e729937..fc83b24da5b 100644
--- a/source/blender/blenkernel/intern/bmfont.c
+++ b/source/blender/blenkernel/intern/bmfont.c
@@ -65,8 +65,8 @@ void printfGlyph(bmGlyph * glyph)
printf(" advan: %3d reser: %3d\n", glyph->advance, glyph->reserved);
}
-#define MAX2(x,y) ((x) > (y) ? (x) : (y))
-#define MAX3(x,y,z) MAX2(MAX2((x), (y)), (z))
+#define MAX2(x, y) ((x) > (y) ? (x) : (y))
+#define MAX3(x, y, z) (MAX2(MAX2((x), (y)), (z)))
void calcAlpha(ImBuf * ibuf)
{
diff --git a/source/blender/blenkernel/intern/booleanops_mesh.c b/source/blender/blenkernel/intern/booleanops_mesh.c
index 461b945282f..f53a89fccfd 100644
--- a/source/blender/blenkernel/intern/booleanops_mesh.c
+++ b/source/blender/blenkernel/intern/booleanops_mesh.c
@@ -56,7 +56,7 @@ CSG_DestroyBlenderMeshInternals(
CSG_MeshDescriptor *mesh
) {
/* Free face and vertex iterators. */
- FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));
+ FreeMeshDescriptors(&(mesh->m_face_iterator), &(mesh->m_vertex_iterator));
}
@@ -138,7 +138,7 @@ CSG_AddMeshToBlender(
if (mesh == NULL) return 0;
if (mesh->base == NULL) return 0;
- invert_m4_m4(inv_mat,mesh->base->object->obmat);
+ invert_m4_m4(inv_mat, mesh->base->object->obmat);
/* Create a new blender mesh object - using 'base' as
* a template for the new object. */
@@ -191,7 +191,7 @@ CSG_PerformOp(
default : op_type = e_csg_intersection;
}
- output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
+ output->m_descriptor = CSG_DescibeOperands(bool_op, mesh1->m_descriptor, mesh2->m_descriptor);
output->base = mesh1->base;
if (output->m_descriptor.user_face_vertex_data_size) {
@@ -228,8 +228,8 @@ CSG_PerformOp(
/* get the ouput mesh descriptors. */
- CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
- CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
+ CSG_OutputFaceDescriptor(bool_op, &(output->m_face_iterator));
+ CSG_OutputVertexDescriptor(bool_op, &(output->m_vertex_iterator));
output->m_destroy_func = CSG_DestroyCSGMeshInternals;
return 1;
@@ -242,20 +242,20 @@ NewBooleanMeshTest(
int op_type
) {
- CSG_MeshDescriptor m1,m2,output;
- CSG_MeshDescriptor output2,output3;
+ CSG_MeshDescriptor m1, m2, output;
+ CSG_MeshDescriptor output2, output3;
- if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
+ if (!MakeCSGMeshFromBlenderBase(base, &m1)) {
return 0;
}
- if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
+ if (!MakeCSGMeshFromBlenderBase(base_select, &m2)) {
return 0;
}
- CSG_PerformOp(&m1,&m2,1,&output);
- CSG_PerformOp(&m1,&m2,2,&output2);
- CSG_PerformOp(&m1,&m2,3,&output3);
+ CSG_PerformOp(&m1, &m2, 1, &output);
+ CSG_PerformOp(&m1, &m2, 2, &output2);
+ CSG_PerformOp(&m1, &m2, 3, &output3);
if (!CSG_AddMeshToBlender(&output)) {
return 0;
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index c650438a31e..b0021050e8f 100644
--- a/source/blender/blenlib/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -25,7 +25,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/blenlib/intern/bpath.c
+/** \file blender/blenkernel/intern/bpath.c
* \ingroup bli
*/
@@ -72,7 +72,6 @@
#include "DNA_smoke_types.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_utildefines.h"
#include "BKE_font.h"
@@ -83,6 +82,8 @@
#include "BKE_sequencer.h"
#include "BKE_image.h" /* so we can check the image's type */
+#include "BKE_bpath.h" /* own include */
+
static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
{
ReportList *reports = (ReportList *)userdata;
@@ -95,9 +96,9 @@ static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), co
}
/* high level function */
-void BLI_bpath_missing_files_check(Main *bmain, ReportList *reports)
+void BKE_bpath_missing_files_check(Main *bmain, ReportList *reports)
{
- BLI_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BLI_BPATH_TRAVERSE_ABS, reports);
+ BKE_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BKE_BPATH_TRAVERSE_ABS, reports);
}
typedef struct BPathRemap_Data {
@@ -132,7 +133,7 @@ static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char
}
}
-void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports)
+void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports)
{
BPathRemap_Data data = {NULL};
@@ -144,7 +145,7 @@ void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *re
data.basedir = basedir;
data.reports = reports;
- BLI_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data);
+ BKE_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data);
BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
"Total files %d | Changed %d | Failed %d",
@@ -174,8 +175,8 @@ static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char
}
}
-/* similar to BLI_bpath_relative_convert - keep in sync! */
-void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports)
+/* similar to BKE_bpath_relative_convert - keep in sync! */
+void BKE_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports)
{
BPathRemap_Data data = {NULL};
@@ -187,7 +188,7 @@ void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *re
data.basedir = basedir;
data.reports = reports;
- BLI_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data);
+ BKE_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data);
BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
"Total files %d | Changed %d | Failed %d",
@@ -298,14 +299,14 @@ static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char
}
}
-void BLI_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports)
+void BKE_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports)
{
struct BPathFind_Data data = {NULL};
data.reports = reports;
BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir));
- BLI_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data);
+ BKE_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data);
}
/* Run a visitor on a string, replacing the contents of the string as needed. */
@@ -383,11 +384,11 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *ab
}
/* Run visitor function 'visit' on all paths contained in 'id'. */
-void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
+void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
{
- const char *absbase = (flag & BLI_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL;
+ const char *absbase = (flag & BKE_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL;
- if ((flag & BLI_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) {
+ if ((flag & BKE_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) {
return;
}
@@ -396,7 +397,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
{
Image *ima;
ima = (Image *)id;
- if (ima->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
+ if (ima->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data);
}
@@ -458,6 +459,10 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
OceanModifierData *omd = (OceanModifierData *) md;
rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data);
}
+ else if (md->type == eModifierType_MeshCache) {
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *) md;
+ rewrite_path_fixed(mcmd->filepath, visit_cb, absbase, bpath_user_data);
+ }
}
if (ob->soft) {
@@ -475,7 +480,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
case ID_SO:
{
bSound *sound = (bSound *)id;
- if (sound->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
+ if (sound->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data);
}
break;
@@ -488,7 +493,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
case ID_VF:
{
VFont *vfont = (VFont *)id;
- if (vfont->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
+ if (vfont->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
if (BKE_vfont_is_builtin(vfont) == FALSE) {
rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data);
}
@@ -555,7 +560,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
int len = MEM_allocN_len(se) / sizeof(*se);
int i;
- if (flag & BLI_BPATH_TRAVERSE_SKIP_MULTIFILE) {
+ if (flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) {
/* only operate on one path */
len = MIN2(1, len);
}
@@ -587,8 +592,11 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
case ID_LI:
{
Library *lib = (Library *)id;
- if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
- BKE_library_filepath_set(lib, lib->name);
+ /* keep packedfile paths always relative to the blend */
+ if (lib->packedfile == NULL) {
+ if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
+ BKE_library_filepath_set(lib, lib->name);
+ }
}
break;
}
@@ -604,26 +612,26 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
}
}
-void BLI_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
+void BKE_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
{
ID *id;
for (id = lb->first; id; id = id->next) {
- BLI_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data);
+ BKE_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data);
}
}
-void BLI_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
+void BKE_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
{
ListBase *lbarray[MAX_LIBARRAY];
int a = set_listbasepointers(bmain, lbarray);
while (a--) {
- BLI_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data);
+ BKE_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data);
}
}
/* Rewrites a relative path to be relative to the main file - unless the path is
* absolute, in which case it is not altered. */
-int BLI_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src)
+int BKE_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src)
{
/* be sure there is low chance of the path being too short */
char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
@@ -700,23 +708,23 @@ static int bpath_list_restore(void *userdata, char *path_dst, const char *path_s
}
/* return ls_handle */
-void *BLI_bpath_list_backup(Main *bmain, const int flag)
+void *BKE_bpath_list_backup(Main *bmain, const int flag)
{
ListBase *ls = MEM_callocN(sizeof(ListBase), __func__);
- BLI_bpath_traverse_main(bmain, bpath_list_append, flag, ls);
+ BKE_bpath_traverse_main(bmain, bpath_list_append, flag, ls);
return ls;
}
-void BLI_bpath_list_restore(Main *bmain, const int flag, void *ls_handle)
+void BKE_bpath_list_restore(Main *bmain, const int flag, void *ls_handle)
{
ListBase *ls = ls_handle;
- BLI_bpath_traverse_main(bmain, bpath_list_restore, flag, ls);
+ BKE_bpath_traverse_main(bmain, bpath_list_restore, flag, ls);
}
-void BLI_bpath_list_free(void *ls_handle)
+void BKE_bpath_list_free(void *ls_handle)
{
ListBase *ls = ls_handle;
BLI_assert(ls->first == NULL); /* assumes we were used */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index f310895f590..ba69fa4336e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -29,27 +29,15 @@
* \ingroup bke
*/
-
-#include <math.h>
-#include <string.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_brush_types.h"
-#include "DNA_color_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "WM_types.h"
-#include "RNA_access.h"
-
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_rand.h"
-#include "BLI_utildefines.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
@@ -65,7 +53,6 @@
#include "IMB_imbuf_types.h"
#include "RE_render_ext.h" /* externtex */
-#include "RE_shader_ext.h"
static void brush_defaults(Brush *brush)
{
@@ -122,11 +109,11 @@ static void brush_defaults(Brush *brush)
/* Datablock add/copy/free/make_local */
-Brush *BKE_brush_add(const char *name)
+Brush *BKE_brush_add(Main *bmain, const char *name)
{
Brush *brush;
- brush = BKE_libblock_alloc(&G.main->brush, ID_BR, name);
+ brush = BKE_libblock_alloc(&bmain->brush, ID_BR, name);
/* enable fake user by default */
brush->id.flag |= LIB_FAKEUSER;
@@ -272,7 +259,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_FIXED_TEX);
BR_TEST_FLAG(BRUSH_RAKE);
BR_TEST_FLAG(BRUSH_ANCHORED);
BR_TEST_FLAG(BRUSH_DIR_IN);
@@ -433,7 +419,7 @@ int BKE_brush_texture_set_nr(Brush *brush, int nr)
idtest = (ID *)BLI_findlink(&G.main->tex, nr - 1);
if (idtest == NULL) { /* new tex */
if (id) idtest = (ID *)BKE_texture_copy((Tex *)id);
- else idtest = (ID *)add_texture("Tex");
+ else idtest = (ID *)add_texture(G.main, "Tex");
idtest->us--;
}
if (idtest != id) {
@@ -485,8 +471,49 @@ int BKE_brush_clone_image_delete(Brush *brush)
return 0;
}
-/* Brush Sampling */
-void BKE_brush_sample_tex(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread)
+/* Brush Sampling for 3d brushes. Currently used for texture painting only, but should be generalized */
+void BKE_brush_sample_tex(const Scene *scene, Brush *brush, const float sampleco[3], float rgba[4], const int thread, struct ImagePool *pool)
+{
+ MTex *mtex = &brush->mtex;
+
+ if (mtex && mtex->tex) {
+ float tin, tr, tg, tb, ta;
+ int hasrgb;
+ const int radius = BKE_brush_size_get(scene, brush);
+
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
+ hasrgb = externtex(mtex, sampleco, &tin, &tr, &tg, &tb, &ta, thread, pool);
+ }
+ else {
+ float co[3];
+
+ co[0] = sampleco[0] / radius;
+ co[1] = sampleco[1] / radius;
+ co[2] = 0.0f;
+
+ hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread, pool);
+ }
+
+ if (hasrgb) {
+ rgba[0] = tr;
+ rgba[1] = tg;
+ rgba[2] = tb;
+ rgba[3] = ta;
+ }
+ else {
+ rgba[0] = tin;
+ rgba[1] = tin;
+ rgba[2] = tin;
+ rgba[3] = 1.0f;
+ }
+ }
+ else {
+ rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0f;
+ }
+}
+
+/* Brush Sampling for 2D brushes. when we unify the brush systems this will be necessarily a separate function */
+void BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread)
{
MTex *mtex = &brush->mtex;
@@ -499,7 +526,7 @@ void BKE_brush_sample_tex(const Scene *scene, Brush *brush, const float xy[2], f
co[1] = xy[1] / radius;
co[2] = 0.0f;
- hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread);
+ hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread, NULL);
if (hasrgb) {
rgba[0] = tr;
@@ -519,7 +546,8 @@ void BKE_brush_sample_tex(const Scene *scene, Brush *brush, const float xy[2], f
}
}
-/* TODO, use define for 'texfall' arg */
+/* TODO, use define for 'texfall' arg
+ * NOTE: only used for 2d brushes currently! */
void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
{
ImBuf *ibuf;
@@ -558,13 +586,18 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
dstf[3] = alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
}
else if (texfall == 1) {
- BKE_brush_sample_tex(scene, brush, xy, dstf, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, dstf, 0);
}
- else {
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
+ else if (texfall == 2) {
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
mul_v3_v3v3(dstf, rgba, brush_rgb);
dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
}
+ else {
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
+ copy_v3_v3(dstf, brush_rgb);
+ dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
+ }
}
}
}
@@ -588,11 +621,11 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
dst[3] = FTOCHAR(alpha_f);
}
else if (texfall == 1) {
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
rgba_float_to_uchar(dst, rgba);
}
else if (texfall == 2) {
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
mul_v3_v3(rgba, brush->rgb);
alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
@@ -601,7 +634,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
dst[3] = FTOCHAR(alpha_f);
}
else {
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
dst[0] = crgb[0];
@@ -628,13 +661,15 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
* available. my ussual solution to this is to use the
* ratio of change of the size to change the unprojected
* radius. Not completely convinced that is correct.
- * In anycase, a better solution is needed to prevent
+ * In any case, a better solution is needed to prevent
* inconsistency. */
void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
-
+
+ size = (int)((float)size / U.pixelsize);
+
if (ups->flag & UNIFIED_PAINT_SIZE)
ups->size = size;
else
@@ -644,8 +679,9 @@ void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
int BKE_brush_size_get(const Scene *scene, Brush *brush)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
-
- return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
+ int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
+
+ return (int)((float)size * U.pixelsize);
}
int BKE_brush_use_locked_size(const Scene *scene, Brush *brush)
@@ -694,7 +730,7 @@ float BKE_brush_unprojected_radius_get(const Scene *scene, Brush *brush)
brush->unprojected_radius;
}
-static void brush_alpha_set(Scene *scene, Brush *brush, float alpha)
+void BKE_brush_alpha_set(Scene *scene, Brush *brush, float alpha)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
@@ -752,315 +788,6 @@ void BKE_brush_scale_size(int *r_brush_size,
(*r_brush_size) = (int)((float)(*r_brush_size) * scale);
}
-/* Brush Painting */
-
-typedef struct BrushPainterCache {
- short enabled;
-
- int size; /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
- short flt; /* need float imbuf? */
- short texonly; /* no alpha, color or fallof, only texture in imbuf */
-
- int lastsize;
- float lastalpha;
- float lastjitter;
-
- ImBuf *ibuf;
- ImBuf *texibuf;
- ImBuf *maskibuf;
-} BrushPainterCache;
-
-struct BrushPainter {
- Scene *scene;
- Brush *brush;
-
- float lastmousepos[2]; /* mouse position of last paint call */
-
- float accumdistance; /* accumulated distance of brush since last paint op */
- float lastpaintpos[2]; /* position of last paint op */
- float startpaintpos[2]; /* position of first paint */
-
- double accumtime; /* accumulated time since last paint op (airbrush) */
- double lasttime; /* time of last update */
-
- float lastpressure;
-
- short firsttouch; /* first paint op */
-
- float startsize;
- float startalpha;
- float startjitter;
- float startspacing;
-
- BrushPainterCache cache;
-};
-
-BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
-{
- BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
-
- painter->brush = brush;
- painter->scene = scene;
- painter->firsttouch = 1;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
-
- painter->startsize = BKE_brush_size_get(scene, brush);
- painter->startalpha = BKE_brush_alpha_get(scene, brush);
- painter->startjitter = brush->jitter;
- painter->startspacing = brush->spacing;
-
- return painter;
-}
-
-void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
-{
- if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
- ((painter->cache.texonly != texonly) && texonly))
- {
- if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
- if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
- painter->cache.ibuf = painter->cache.maskibuf = NULL;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
- }
-
- if (painter->cache.flt != flt) {
- if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
- painter->cache.texibuf = NULL;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
- }
-
- painter->cache.size = size;
- painter->cache.flt = flt;
- painter->cache.texonly = texonly;
- painter->cache.enabled = 1;
-}
-
-void BKE_brush_painter_free(BrushPainter *painter)
-{
- Brush *brush = painter->brush;
-
- BKE_brush_size_set(painter->scene, brush, painter->startsize);
- brush_alpha_set(painter->scene, brush, painter->startalpha);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
- if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
- if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
- if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
- MEM_freeN(painter);
-}
-
-static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
- int x, int y, int w, int h, int xt, int yt,
- const float pos[2])
-{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- ImBuf *ibuf, *maskibuf, *texibuf;
- float *bf, *mf, *tf, *otf = NULL, xoff, yoff, xy[2], rgba[4];
- unsigned char *b, *m, *t, *ot = NULL;
- int dotexold, origx = x, origy = y;
- const int radius = BKE_brush_size_get(painter->scene, brush);
-
- xoff = -radius + 0.5f;
- yoff = -radius + 0.5f;
- xoff += (int)pos[0] - (int)painter->startpaintpos[0];
- yoff += (int)pos[1] - (int)painter->startpaintpos[1];
-
- ibuf = painter->cache.ibuf;
- texibuf = painter->cache.texibuf;
- maskibuf = painter->cache.maskibuf;
-
- dotexold = (oldtexibuf != NULL);
-
- /* not sure if it's actually needed or it's a mistake in coords/sizes
- * calculation in brush_painter_fixed_tex_partial_update(), but without this
- * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
- w = min_ii(w, ibuf->x);
- h = min_ii(h, ibuf->y);
-
- if (painter->cache.flt) {
- for (; y < h; y++) {
- bf = ibuf->rect_float + (y * ibuf->x + origx) * 4;
- tf = texibuf->rect_float + (y * texibuf->x + origx) * 4;
- mf = maskibuf->rect_float + (y * maskibuf->x + origx) * 4;
-
- if (dotexold)
- otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
-
- for (x = origx; x < w; x++, bf += 4, mf += 4, tf += 4) {
- if (dotexold) {
- copy_v3_v3(tf, otf);
- tf[3] = otf[3];
- otf += 4;
- }
- else {
- xy[0] = x + xoff;
- xy[1] = y + yoff;
-
- BKE_brush_sample_tex(scene, brush, xy, tf, 0);
- }
-
- bf[0] = tf[0] * mf[0];
- bf[1] = tf[1] * mf[1];
- bf[2] = tf[2] * mf[2];
- bf[3] = tf[3] * mf[3];
- }
- }
- }
- else {
- for (; y < h; y++) {
- b = (unsigned char *)ibuf->rect + (y * ibuf->x + origx) * 4;
- t = (unsigned char *)texibuf->rect + (y * texibuf->x + origx) * 4;
- m = (unsigned char *)maskibuf->rect + (y * maskibuf->x + origx) * 4;
-
- if (dotexold)
- ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
-
- for (x = origx; x < w; x++, b += 4, m += 4, t += 4) {
- if (dotexold) {
- t[0] = ot[0];
- t[1] = ot[1];
- t[2] = ot[2];
- t[3] = ot[3];
- ot += 4;
- }
- else {
- xy[0] = x + xoff;
- xy[1] = y + yoff;
-
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
- rgba_float_to_uchar(t, rgba);
- }
-
- b[0] = t[0] * m[0] / 255;
- b[1] = t[1] * m[1] / 255;
- b[2] = t[2] * m[2] / 255;
- b[3] = t[3] * m[3] / 255;
- }
- }
- }
-}
-
-static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, const float pos[2])
-{
- const Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- BrushPainterCache *cache = &painter->cache;
- ImBuf *oldtexibuf, *ibuf;
- int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
- const int diameter = 2 * BKE_brush_size_get(scene, brush);
-
- imbflag = (cache->flt) ? IB_rectfloat : IB_rect;
- if (!cache->ibuf)
- cache->ibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
- ibuf = cache->ibuf;
-
- oldtexibuf = cache->texibuf;
- cache->texibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
-
- if (oldtexibuf) {
- srcx = srcy = 0;
- destx = (int)painter->lastpaintpos[0] - (int)pos[0];
- desty = (int)painter->lastpaintpos[1] - (int)pos[1];
- w = oldtexibuf->x;
- h = oldtexibuf->y;
-
- IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
- }
- else {
- srcx = srcy = 0;
- destx = desty = 0;
- w = h = 0;
- }
-
- x1 = destx;
- y1 = desty;
- x2 = destx + w;
- y2 = desty + h;
-
- /* blend existing texture in new position */
- if ((x1 < x2) && (y1 < y2))
- brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
-
- if (oldtexibuf)
- IMB_freeImBuf(oldtexibuf);
-
- /* sample texture in new areas */
- if ((0 < x1) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
- if ((x2 < ibuf->x) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
- if ((x1 < x2) && (0 < y1))
- brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
- if ((x1 < x2) && (y2 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
-}
-
-static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
-{
- const Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- BrushPainterCache *cache = &painter->cache;
- MTex *mtex = &brush->mtex;
- int size;
- short flt;
- const int diameter = 2 * BKE_brush_size_get(scene, brush);
- const float alpha = BKE_brush_alpha_get(scene, brush);
-
- if (diameter != cache->lastsize ||
- alpha != cache->lastalpha ||
- brush->jitter != cache->lastjitter)
- {
- if (cache->ibuf) {
- IMB_freeImBuf(cache->ibuf);
- cache->ibuf = NULL;
- }
- if (cache->maskibuf) {
- IMB_freeImBuf(cache->maskibuf);
- cache->maskibuf = NULL;
- }
-
- flt = cache->flt;
- size = (cache->size) ? cache->size : diameter;
-
- if (brush->flag & BRUSH_FIXED_TEX) {
- BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
- brush_painter_fixed_tex_partial_update(painter, pos);
- }
- else
- BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
-
- cache->lastsize = diameter;
- cache->lastalpha = alpha;
- cache->lastjitter = brush->jitter;
- }
- else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
- int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
- int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
-
- if ((dx != 0) || (dy != 0))
- brush_painter_fixed_tex_partial_update(painter, pos);
- }
-}
-
-void BKE_brush_painter_break_stroke(BrushPainter *painter)
-{
- painter->firsttouch = 1;
-}
-
-static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
-{
- if (BKE_brush_use_alpha_pressure(painter->scene, brush))
- brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
- if (BKE_brush_use_size_pressure(painter->scene, brush))
- BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
- if (brush->flag & BRUSH_JITTER_PRESSURE)
- brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
- if (brush->flag & BRUSH_SPACING_PRESSURE)
- brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
-}
-
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
{
int use_jitter = brush->jitter != 0;
@@ -1088,165 +815,6 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2],
}
}
-int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
- void *user, int use_color_correction)
-{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- int totpaintops = 0;
-
- if (pressure == 0.0f) {
- if (painter->lastpressure) // XXX - hack, operator misses
- pressure = painter->lastpressure;
- else
- pressure = 1.0f; /* zero pressure == not using tablet */
- }
- if (painter->firsttouch) {
- /* paint exactly once on first touch */
- painter->startpaintpos[0] = pos[0];
- painter->startpaintpos[1] = pos[1];
-
- brush_pressure_apply(painter, brush, pressure);
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, pos, use_color_correction);
- totpaintops += func(user, painter->cache.ibuf, pos, pos);
-
- painter->lasttime = time;
- painter->firsttouch = 0;
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- }
-#if 0
- else if (painter->brush->flag & BRUSH_AIRBRUSH) {
- float spacing, step, paintpos[2], dmousepos[2], len;
- double starttime, curtime = time;
-
- /* compute brush spacing adapted to brush size */
- spacing = brush->rate; //radius*brush->spacing*0.01f;
-
- /* setup starting time, direction vector and accumulated time */
- starttime = painter->accumtime;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumtime += curtime - painter->lasttime;
-
- /* do paint op over unpainted time distance */
- while (painter->accumtime >= spacing) {
- step = (spacing - starttime) * len;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter);
- totpaintops += func(user, painter->cache.ibuf,
- painter->lastpaintpos, paintpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumtime -= spacing;
- starttime -= spacing;
- }
-
- painter->lasttime = curtime;
- }
-#endif
- else {
- float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
- float t, len, press;
- const int radius = BKE_brush_size_get(scene, brush);
-
- /* compute brush spacing adapted to brush radius, spacing may depend
- * on pressure, so update it */
- brush_pressure_apply(painter, brush, painter->lastpressure);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- /* setup starting distance, direction vector and accumulated distance */
- startdistance = painter->accumdistance;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumdistance += len;
-
- if (brush->flag & BRUSH_SPACE) {
- /* do paint op over unpainted distance */
- while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
- step = spacing - startdistance;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- t = step / len;
- press = (1.0f - t) * painter->lastpressure + t * pressure;
- brush_pressure_apply(painter, brush, press);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumdistance -= spacing;
- startdistance -= spacing;
- }
- }
- else {
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
-
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- painter->accumdistance = 0;
- }
-
- /* do airbrush paint ops, based on the number of paint ops left over
- * from regular painting. this is a temporary solution until we have
- * accurate time stamps for mouse move events */
- if (brush->flag & BRUSH_AIRBRUSH) {
- double curtime = time;
- double painttime = brush->rate * totpaintops;
-
- painter->accumtime += curtime - painter->lasttime;
- if (painter->accumtime <= painttime)
- painter->accumtime = 0.0;
- else
- painter->accumtime -= painttime;
-
- while (painter->accumtime >= (double)brush->rate) {
- brush_pressure_apply(painter, brush, pressure);
-
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
- painter->accumtime -= (double)brush->rate;
- }
-
- painter->lasttime = curtime;
- }
- }
-
- painter->lastmousepos[0] = pos[0];
- painter->lastmousepos[1] = pos[1];
- painter->lastpressure = pressure;
-
- brush_alpha_set(scene, brush, painter->startalpha);
- BKE_brush_size_set(scene, brush, painter->startsize);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
- return totpaintops;
-}
-
/* 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)
{
@@ -1273,48 +841,6 @@ float BKE_brush_curve_strength(Brush *br, float p, const float 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)
-{
- unsigned int *texcache = NULL;
- MTex *mtex = &br->mtex;
- TexResult texres = {0};
- int hasrgb, ix, iy;
- int side = half_side * 2;
-
- if (mtex->tex) {
- float x, y, step = 2.0 / side, co[3];
-
- texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
-
- /*do normalized cannonical view coords for texture*/
- for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
- for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
- co[0] = x;
- co[1] = y;
- co[2] = 0.0f;
-
- /* This is copied from displace modifier code */
- hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, so calculate one (formula from do_material_tex).
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if (hasrgb & TEX_RGB)
- texres.tin = rgb_to_grayscale(&texres.tr);
-
- ((char *)texcache)[(iy * side + ix) * 4] =
- ((char *)texcache)[(iy * side + ix) * 4 + 1] =
- ((char *)texcache)[(iy * side + ix) * 4 + 2] =
- ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
- }
- }
- }
-
- return texcache;
-}
-
/**** Radial Control ****/
struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br)
{
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index ad828a70dd8..5028d978351 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -38,11 +38,11 @@
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
+#include "BLI_math.h"
#include "BKE_DerivedMesh.h"
#include "BKE_tessmesh.h"
-#include "BLI_math.h"
#include "MEM_guardedalloc.h"
/* Math stuff for ray casting on mesh faces and for nearest surface */
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 57c88919021..34c2d144f4c 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -50,11 +50,11 @@
/****************************** Camera Datablock *****************************/
-void *BKE_camera_add(const char *name)
+void *BKE_camera_add(Main *bmain, const char *name)
{
Camera *cam;
- cam = BKE_libblock_alloc(&G.main->camera, ID_CA, name);
+ cam = BKE_libblock_alloc(&bmain->camera, ID_CA, name);
cam->lens = 35.0f;
cam->sensor_x = DEFAULT_SENSOR_WIDTH;
@@ -237,6 +237,9 @@ void BKE_camera_params_from_object(CameraParams *params, Object *ob)
params->clipsta = la->clipsta;
params->clipend = la->clipend;
}
+ else {
+ params->lens = 35.0f;
+ }
}
void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView3D *rv3d)
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 54bbe4bf495..7f2d9437c3d 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -40,12 +40,12 @@
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
#include "BLI_array.h"
#include "BLI_smallhash.h"
#include "BLI_utildefines.h"
#include "BLI_scanfill.h"
+#include "BKE_pbvh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
@@ -262,6 +262,17 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
}
+ /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */
+ if (!cddm->pbvh && ob->sculpt->bm) {
+ cddm->pbvh = BKE_pbvh_new();
+ cddm->pbvh_draw = TRUE;
+
+ BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm,
+ ob->sculpt->bm_smooth_shading,
+ ob->sculpt->bm_log);
+ }
+
+
/* always build pbvh from original mesh, and only use it for drawing if
* this derivedmesh is just original mesh. it's the multires subsurf dm
* that this is actually for, to support a pbvh on a modified mesh */
@@ -270,14 +281,14 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
Mesh *me = ob->data;
int deformed = 0;
- cddm->pbvh = BLI_pbvh_new();
+ cddm->pbvh = BKE_pbvh_new();
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
BKE_mesh_tessface_ensure(me);
- BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
+ BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert, &me->vdata);
deformed = ss->modifiers_active || me->key;
@@ -290,7 +301,7 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
totvert = deformdm->getNumVerts(deformdm);
vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM_getPBVH vertCos");
deformdm->getVertCos(deformdm, vertCos);
- BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos);
MEM_freeN(vertCos);
}
}
@@ -310,7 +321,7 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
+ BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
}
static void cdDM_drawVerts(DerivedMesh *dm)
@@ -414,6 +425,14 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges
MVert *mvert = cddm->mvert;
MEdge *medge = cddm->medge;
int i;
+
+ if (cddm->pbvh && cddm->pbvh_draw &&
+ BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH)
+ {
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, TRUE);
+
+ return;
+ }
if (GPU_buffer_legacy(dm)) {
DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
@@ -530,7 +549,8 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
if (dm->numTessFaceData) {
float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
+ BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors,
+ setMaterial, FALSE);
glShadeModel(GL_FLAT);
}
@@ -627,6 +647,23 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
index_mp_to_orig = NULL;
}
+ /* TODO: not entirely correct, but currently dynamic topology will
+ * destroy UVs anyway, so textured display wouldn't work anyway
+ *
+ * this will do more like solid view with lights set up for
+ * textured view, but object itself will be displayed gray
+ * (the same as it'll display without UV maps in textured view)
+ */
+ if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
+ if (dm->numTessFaceData) {
+ glDisable(GL_TEXTURE_2D);
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE);
+ glEnable(GL_TEXTURE_2D);
+ }
+
+ return;
+ }
+
colType = CD_TEXTURE_MCOL;
mcol = dm->getTessFaceDataArray(dm, colType);
if (!mcol) {
@@ -664,8 +701,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
else {
if (nors) {
- nors += 3; continue;
+ nors += 3;
}
+ continue;
}
}
else if (drawParamsMapped) {
@@ -673,8 +711,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
else {
if (nors) {
- nors += 3; continue;
+ nors += 3;
}
+ continue;
}
}
@@ -1072,6 +1111,19 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
index_mp_to_orig = NULL;
}
+ /* TODO: same as for solid draw, not entirely correct, but works fine for now,
+ * will skip using textures (dyntopo currently destroys UV anyway) and
+ * works fine for matcap
+ */
+ if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
+ if (dm->numTessFaceData) {
+ setMaterial(1, &gattribs);
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE);
+ }
+
+ return;
+ }
+
cdDM_update_normals_from_pbvh(dm);
matnr = -1;
@@ -1373,6 +1425,19 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
index_mp_to_orig = NULL;
}
+ /* TODO: same as for solid draw, not entirely correct, but works fine for now,
+ * will skip using textures (dyntopo currently destroys UV anyway) and
+ * works fine for matcap
+ */
+ if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
+ if (dm->numTessFaceData) {
+ setMaterial(userData, 1, &gattribs);
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE);
+ }
+
+ return;
+ }
+
cdDM_update_normals_from_pbvh(dm);
matnr = -1;
@@ -1704,6 +1769,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
mesh->totloop, mesh->totpoly);
dm->deformedOnly = 1;
+ dm->cd_flag = mesh->cd_flag;
alloctype = CD_REFERENCE;
@@ -1735,49 +1801,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
DerivedMesh *CDDM_from_curve(Object *ob)
{
- return CDDM_from_curve_displist(ob, &ob->disp, NULL);
+ return CDDM_from_curve_displist(ob, &ob->disp);
}
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
-{
- int *orco_index_ptr = NULL;
- int (*orco_index)[4] = NULL;
- float (*orco)[3] = NULL;
- DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
-
- if (orco_index_ptr) {
- orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
- }
-
- if (orco && orco_index_ptr) {
- const char *uvname = "Orco";
-
- int totpoly = dm->getNumPolys(dm);
-
- MPoly *mpolys = dm->getPolyArray(dm);
- MLoop *mloops = dm->getLoopArray(dm);
-
- MLoopUV *mloopuvs;
-
- CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
- mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname);
-
- BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
- mloops, mloopuvs,
- orco, orco_index);
- }
-
- if (orco_index) {
- MEM_freeN(orco_index);
- }
- if (orco) {
- MEM_freeN(orco);
- }
-
- return dm;
-}
-
-DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
{
DerivedMesh *dm;
CDDerivedMesh *cddm;
@@ -1788,7 +1815,8 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco
int totvert, totedge, totloop, totpoly;
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
- &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+ &totedge, &allloop, &allpoly, NULL,
+ &totloop, &totpoly) != 0)
{
/* Error initializing mdata. This often happens when curve is empty */
return CDDM_new(0, 0, 0, 0, 0);
@@ -1875,7 +1903,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
bm->totface);
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- BMIter iter, liter;
+ BMIter iter;
BMVert *eve;
BMEdge *eed;
BMFace *efa;
@@ -1887,13 +1915,12 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
int *index, add_orig;
- int has_crease, has_edge_bweight, has_vert_bweight;
CustomDataMask mask;
unsigned int i, j;
- has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
- has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
- has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
dm->deformedOnly = 1;
@@ -1913,7 +1940,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
CD_CALLOC, dm->numLoopData);
CustomData_merge(&bm->pdata, &dm->polyData, mask,
CD_CALLOC, dm->numPolyData);
-
+
/* add tessellation mface layers */
if (use_tessface) {
CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
@@ -1933,8 +1960,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
mv->flag = BM_vert_flag_to_mflag(eve);
- if (has_vert_bweight)
- mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
+ if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
if (add_orig) *index = i;
@@ -1952,11 +1978,6 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
med->v1 = BM_elem_index_get(eed->v1);
med->v2 = BM_elem_index_get(eed->v2);
- if (has_crease)
- med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
- if (has_edge_bweight)
- med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
-
med->flag = BM_edge_flag_to_mflag(eed);
/* handle this differently to editmode switching,
@@ -1967,6 +1988,9 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
}
}
+ if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
+
CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
if (add_orig) *index = i;
}
@@ -2002,7 +2026,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
j = 0;
efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
- BMLoop *l;
+ BMLoop *l_iter;
+ BMLoop *l_first;
MPoly *mp = &mpoly[i];
BM_elem_index_set(efa, i); /* set_inline */
@@ -2011,15 +2036,16 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
mp->flag = BM_face_flag_to_mflag(efa);
mp->loopstart = j;
mp->mat_nr = efa->mat_nr;
-
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- mloop->v = BM_elem_index_get(l->v);
- mloop->e = BM_elem_index_get(l->e);
- CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ mloop->v = BM_elem_index_get(l_iter->v);
+ mloop->e = BM_elem_index_get(l_iter->e);
+ CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
j++;
mloop++;
- }
+ } while ((l_iter = l_iter->next) != l_first);
CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
@@ -2027,6 +2053,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
}
bm->elem_index_dirty &= ~BM_FACE;
+ dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
return dm;
}
@@ -2064,6 +2092,7 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
numLoops, numPolys);
dm->deformedOnly = source->deformedOnly;
+ dm->cd_flag = source->cd_flag;
dm->dirty = source->dirty;
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
@@ -2282,6 +2311,7 @@ void CDDM_calc_normals_tessface(DerivedMesh *dm)
*/
DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
{
+// #define USE_LOOPS
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
CDDerivedMesh *cddm2 = NULL;
MVert *mv, *mvert = NULL;
@@ -2293,18 +2323,27 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
MLoop *ml, *mloop = NULL;
BLI_array_declare(mloop);
EdgeHash *ehash = BLI_edgehash_new();
- int *newv = NULL, *newe = NULL, *newl = NULL;
+ int *newv = NULL, *newe = NULL;
+#ifdef USE_LOOPS
+ int *newl = NULL;
+#endif
int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
- int i, j, c, totloop, totpoly;
-
+ int i, j, c, totpoly;
+#ifdef USE_LOOPS
+ int totloop;
+#endif
+
+#ifdef USE_LOOPS
totloop = dm->numLoopData;
+#endif
totpoly = dm->numPolyData;
- newv = MEM_callocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
- newe = MEM_callocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
- newl = MEM_callocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
-
+ newv = MEM_mallocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
+ newe = MEM_mallocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
+#ifdef USE_LOOPS
+ newl = MEM_mallocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
+#endif
/* fill newl with destination vertex indices */
mv = cddm->mvert;
c = 0;
@@ -2314,6 +2353,10 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
newv[i] = c++;
BLI_array_append(mvert, *mv);
}
+ else {
+ /* dummy value */
+ newv[i] = 0;
+ }
}
/* now link target vertices to destination indices */
@@ -2382,7 +2425,9 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
for (j = 0; j < mp->totloop; j++, ml++) {
med = cddm->medge + ml->e;
if (LIKELY(med->v1 != med->v2)) {
+#ifdef USE_LOOPS
newl[j + mp->loopstart] = BLI_array_count(mloop);
+#endif
BLI_array_append(oldl, j + mp->loopstart);
BLI_array_append(mloop, *ml);
c++;
@@ -2448,8 +2493,10 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
MEM_freeN(newv);
if (newe)
MEM_freeN(newe);
+#ifdef USE_LOOPS
if (newl)
MEM_freeN(newl);
+#endif
if (oldv)
MEM_freeN(oldv);
if (olde)
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index f1d73c7777a..c1293542963 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -483,7 +483,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
/* handle continuous simulation with the play button */
- if (BKE_ptcache_get_continue_physics() || ((clmd->sim_parms->preroll > 0) && (framenr > startframe - clmd->sim_parms->preroll) && (framenr < startframe))) {
+ if ((clmd->sim_parms->preroll > 0) && (framenr > startframe - clmd->sim_parms->preroll) && (framenr < startframe)) {
BKE_ptcache_invalidate(cache);
/* do simulation */
@@ -1153,7 +1153,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
if ( !mface[i].v4 )
continue;
- spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+ spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
if (!spring) {
cloth_free_errorsprings(cloth, edgehash, edgelist);
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 4641a02265a..061657c8f2d 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -59,7 +59,7 @@
#include "BKE_modifier.h"
#include "BKE_DerivedMesh.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "Bullet-C-Api.h"
#endif
#include "BLI_kdopbvh.h"
@@ -385,7 +385,7 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
CollisionModifierData *collmd = (CollisionModifierData *) md2;
/* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
MFace *face1=NULL, *face2 = NULL;
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
ClothVertex *verts1 = clmd->clothObject->verts;
#endif
double distance = 0;
@@ -458,7 +458,7 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
}
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
// calc distance + normal
distance = plNearestPoints (
verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa, collpair->pb, collpair->vector );
@@ -528,7 +528,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
/* extend array */
if (*numobj >= *maxobj) {
*maxobj *= 2;
- *objs= MEM_reallocN(*objs, sizeof(Object*)*(*maxobj));
+ *objs= MEM_reallocN(*objs, sizeof(Object *)*(*maxobj));
}
(*objs)[*numobj] = ob;
@@ -567,7 +567,9 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned
Scene *sce_iter;
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {
- if (base->lay & self->lay)
+ /* Need to check for active layers, too.
+ Otherwise this check fails if the objects are not on the same layer - DG */
+ if ((base->lay & self->lay) || (base->lay & scene->lay))
add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0, modifier_type);
}
@@ -738,7 +740,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
/* 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);
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
if (!collmd->bvhtree)
continue;
@@ -758,7 +760,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
// check all collision objects
for (i = 0; i < numcollobj; i++) {
Object *collob= collobjs[i];
- CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
BVHTreeOverlap *overlap = NULL;
unsigned int result = 0;
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 529fe07cab3..d08c16eac9e 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -895,7 +895,7 @@ void curvemapping_table_RGBA(const CurveMapping *cumap, float **array, int *size
#define INV_255 (1.f / 255.f)
-DO_INLINE int get_bin_float(float f)
+BLI_INLINE int get_bin_float(float f)
{
int bin = (int)((f * 255.0f) + 0.5f); /* 0.5 to prevent quantisation differences */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 97d750854f4..48ad3f51389 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -96,7 +96,7 @@
/* -------------- Naming -------------- */
/* Find the first available, non-duplicate name for a given constraint */
-void unique_constraint_name(bConstraint *con, ListBase *list)
+void BKE_unique_constraint_name(bConstraint *con, ListBase *list)
{
BLI_uniquename(list, con, "Const", '.', offsetof(bConstraint, name), sizeof(con->name));
}
@@ -105,7 +105,7 @@ void unique_constraint_name(bConstraint *con, ListBase *list)
/* package an object/bone for use in constraint evaluation */
/* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
-bConstraintOb *constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
+bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
{
bConstraintOb *cob;
@@ -169,7 +169,7 @@ bConstraintOb *constraints_make_evalob(Scene *scene, Object *ob, void *subdata,
}
/* cleanup after constraint evaluation */
-void constraints_clear_evalob(bConstraintOb *cob)
+void BKE_constraints_clear_evalob(bConstraintOb *cob)
{
float delta[4][4], imat[4][4];
@@ -219,7 +219,7 @@ void 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 constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
+void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to)
{
float diff_mat[4][4];
float imat[4][4];
@@ -242,7 +242,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* use pose-space as stepping stone for other spaces... */
if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -278,7 +278,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -293,7 +293,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -345,7 +345,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* ------------ General Target Matrix Tools ---------- */
/* function that sets the given matrix based on given vertex group in mesh */
-static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[][4])
+static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4])
{
DerivedMesh *dm = NULL;
BMEditMesh *em = BMEdit_FromObject(ob);
@@ -441,7 +441,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
}
/* function that sets the given matrix based on given vertex group in lattice */
-static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[][4])
+static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[4][4])
{
Lattice *lt = (Lattice *)ob->data;
@@ -494,12 +494,12 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
/* generic function to get the appropriate matrix for most target cases */
/* The cases where the target can be object data have not been implemented */
-static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[][4], short from, short to, float headtail)
+static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[4][4], short from, short to, float headtail)
{
/* Case OBJECT */
if (!strlen(substring)) {
copy_m4_m4(mat, ob->obmat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
/* Case VERTEXGROUP */
/* Current method just takes the average location of all the points in the
@@ -512,11 +512,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);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
else if (ob->type == OB_LATTICE) {
contarget_get_lattice_mat(ob, substring, mat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
/* Case BONE */
else {
@@ -549,7 +549,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 */
- constraint_mat_convertspace(ob, pchan, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, from, to);
}
}
@@ -890,7 +890,7 @@ static int basis_cross(int n, int m)
}
}
-static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[][3])
+static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[3][3])
{
float n[3];
float u[3]; /* vector specifying the up axis */
@@ -4211,7 +4211,7 @@ static void constraints_init_typeinfo(void)
/* This function should be used for getting the appropriate type-info when only
* a constraint type is known
*/
-bConstraintTypeInfo *get_constraint_typeinfo(int type)
+bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type)
{
/* initialize the type-info list? */
if (CTI_INIT) {
@@ -4236,11 +4236,11 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type)
/* This function should always be used to get the appropriate type-info, as it
* has checks which prevent segfaults in some weird cases.
*/
-bConstraintTypeInfo *constraint_get_typeinfo(bConstraint *con)
+bConstraintTypeInfo *BKE_constraint_get_typeinfo(bConstraint *con)
{
/* only return typeinfo for valid constraints */
if (con)
- return get_constraint_typeinfo(con->type);
+ return BKE_get_constraint_typeinfo(con->type);
else
return NULL;
}
@@ -4252,7 +4252,7 @@ bConstraintTypeInfo *constraint_get_typeinfo(bConstraint *con)
/* ---------- Data Management ------- */
-/* helper function for free_constraint_data() - unlinks references */
+/* helper function for BKE_free_constraint_data() - unlinks references */
static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
{
if (*idpoin && isReference)
@@ -4261,12 +4261,12 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isRe
/* Free data of a specific constraint if it has any info.
* be sure to run BIK_clear_data() when freeing an IK constraint,
- * unless DAG_scene_sort is called.
+ * unless DAG_relations_tag_update is called.
*/
-void free_constraint_data(bConstraint *con)
+void BKE_free_constraint_data(bConstraint *con)
{
if (con->data) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti) {
/* perform any special freeing constraint may have */
@@ -4284,13 +4284,13 @@ void free_constraint_data(bConstraint *con)
}
/* Free all constraints from a constraint-stack */
-void free_constraints(ListBase *list)
+void BKE_free_constraints(ListBase *list)
{
bConstraint *con;
/* Free constraint data and also any extra data */
for (con = list->first; con; con = con->next)
- free_constraint_data(con);
+ BKE_free_constraint_data(con);
/* Free the whole list */
BLI_freelistN(list);
@@ -4298,10 +4298,10 @@ void free_constraints(ListBase *list)
/* Remove the specified constraint from the given constraint stack */
-int remove_constraint(ListBase *list, bConstraint *con)
+int BKE_remove_constraint(ListBase *list, bConstraint *con)
{
if (con) {
- free_constraint_data(con);
+ BKE_free_constraint_data(con);
BLI_freelinkN(list, con);
return 1;
}
@@ -4310,7 +4310,7 @@ int remove_constraint(ListBase *list, bConstraint *con)
}
/* Remove all the constraints of the specified type from the given constraint stack */
-void remove_constraints_type(ListBase *list, short type, short last_only)
+void BKE_remove_constraints_type(ListBase *list, short type, short last_only)
{
bConstraint *con, *conp;
@@ -4322,7 +4322,7 @@ void remove_constraints_type(ListBase *list, short type, short last_only)
conp = con->prev;
if (con->type == type) {
- remove_constraint(list, con);
+ BKE_remove_constraint(list, con);
if (last_only)
return;
}
@@ -4335,7 +4335,7 @@ void remove_constraints_type(ListBase *list, short type, short last_only)
static bConstraint *add_new_constraint_internal(const char *name, short type)
{
bConstraint *con = MEM_callocN(sizeof(bConstraint), "Constraint");
- bConstraintTypeInfo *cti = get_constraint_typeinfo(type);
+ bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(type);
const char *newName;
/* Set up a generic constraint datablock */
@@ -4385,17 +4385,17 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
* (otherwise unique-naming code will fail, since it assumes element exists in list)
*/
BLI_addtail(list, con);
- unique_constraint_name(con, list);
+ BKE_unique_constraint_name(con, list);
/* if the target list is a list on some PoseChannel belonging to a proxy-protected
* Armature layer, we must tag newly added constraints with a flag which allows them
* to persist after proxy syncing has been done
*/
- if (proxylocked_constraints_owner(ob, pchan))
+ if (BKE_proxylocked_constraints_owner(ob, pchan))
con->flag |= CONSTRAINT_PROXY_LOCAL;
/* make this constraint the active one */
- constraints_set_active(list, con);
+ BKE_constraints_set_active(list, con);
}
/* set type+owner specific immutable settings */
@@ -4419,7 +4419,7 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
/* ......... */
/* Add new constraint for the given bone */
-bConstraint *add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
+bConstraint *BKE_add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
{
if (pchan == NULL)
return NULL;
@@ -4428,14 +4428,14 @@ bConstraint *add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *na
}
/* Add new constraint for the given object */
-bConstraint *add_ob_constraint(Object *ob, const char *name, short type)
+bConstraint *BKE_add_ob_constraint(Object *ob, const char *name, short type)
{
return add_new_constraint(ob, NULL, name, type);
}
/* ......... */
-/* helper for relink_constraints() - call ID_NEW() on every ID reference the constraint has */
+/* helper for BKE_relink_constraints() - call ID_NEW() on every ID reference the constraint has */
static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userdata))
{
/* ID_NEW() expects a struct with inline "id" member as first
@@ -4449,20 +4449,20 @@ static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED
}
/* Reassign links that constraints have to other data (called during file loading?) */
-void relink_constraints(ListBase *conlist)
+void BKE_relink_constraints(ListBase *conlist)
{
/* just a wrapper around ID-loop for just calling ID_NEW() on all ID refs */
- id_loop_constraints(conlist, con_relink_id_cb, NULL);
+ BKE_id_loop_constraints(conlist, con_relink_id_cb, NULL);
}
/* Run the given callback on all ID-blocks in list of constraints */
-void id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdata)
+void BKE_id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdata)
{
bConstraint *con;
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti) {
if (cti->id_looper)
@@ -4473,14 +4473,14 @@ void id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdat
/* ......... */
-/* helper for copy_constraints(), to be used for making sure that ID's are valid */
+/* helper for BKE_copy_constraints(), to be used for making sure that ID's are valid */
static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userData))
{
if (*idpoin && (*idpoin)->lib)
id_lib_extern(*idpoin);
}
-/* helper for copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
+/* helper for BKE_copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
{
/* increment usercount if this is a reference type */
@@ -4489,7 +4489,7 @@ static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short
}
/* duplicate all of the constraints in a constraint stack */
-void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
+void BKE_copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
{
bConstraint *con, *srccon;
@@ -4497,7 +4497,7 @@ void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
BLI_duplicatelist(dst, src);
for (con = dst->first, srccon = src->first; con && srccon; srccon = srccon->next, con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
/* make a new copy of the constraint's data */
con->data = MEM_dupallocN(con->data);
@@ -4524,13 +4524,13 @@ void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
/* ......... */
-bConstraint *constraints_findByName(ListBase *list, const char *name)
+bConstraint *BKE_constraints_findByName(ListBase *list, const char *name)
{
return BLI_findstring(list, name, offsetof(bConstraint, name));
}
/* finds the 'active' constraint in a constraint stack */
-bConstraint *constraints_get_active(ListBase *list)
+bConstraint *BKE_constraints_get_active(ListBase *list)
{
bConstraint *con;
@@ -4547,7 +4547,7 @@ bConstraint *constraints_get_active(ListBase *list)
}
/* Set the given constraint as the active one (clearing all the others) */
-void constraints_set_active(ListBase *list, bConstraint *con)
+void BKE_constraints_set_active(ListBase *list, bConstraint *con)
{
bConstraint *c;
@@ -4564,7 +4564,7 @@ void constraints_set_active(ListBase *list, bConstraint *con)
/* -------- Constraints and Proxies ------- */
/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
-void extract_proxylocal_constraints(ListBase *dst, ListBase *src)
+void BKE_extract_proxylocal_constraints(ListBase *dst, ListBase *src)
{
bConstraint *con, *next;
@@ -4581,7 +4581,7 @@ void extract_proxylocal_constraints(ListBase *dst, ListBase *src)
}
/* Returns if the owner of the constraint is proxy-protected */
-short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
+short BKE_proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
{
/* Currently, constraints can only be on object or bone level */
if (ob && ob->proxy) {
@@ -4610,9 +4610,9 @@ short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
* None of the actual calculations of the matrices should be done here! Also, this function is
* not to be used by any new constraints, particularly any that have multiple targets.
*/
-void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime)
+void BKE_get_constraint_target_matrix(Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintOb *cob;
bConstraintTarget *ct;
@@ -4657,10 +4657,8 @@ void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n,
cti->get_constraint_targets(con, &targets);
/* only calculate the target matrix on the first target */
- ct = (bConstraintTarget *)targets.first;
- while (ct && n-- > 0)
- ct = ct->next;
-
+ ct = (bConstraintTarget *)BLI_findlink(&targets, index);
+
if (ct) {
if (cti->get_target_matrix)
cti->get_target_matrix(con, cob, ct, ctime);
@@ -4679,9 +4677,9 @@ void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n,
}
/* Get the list of targets required for solving a constraint */
-void get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+void BKE_get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti && cti->get_constraint_targets) {
bConstraintTarget *ct;
@@ -4711,10 +4709,10 @@ void get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, Li
/* This function is called whenever constraints need to be evaluated. Currently, all
* constraints that can be evaluated are everytime this gets run.
*
- * constraints_make_evalob and constraints_clear_evalob should be called before and
+ * BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
* after running this function, to sort out cob
*/
-void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
+void BKE_solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
float oldmat[4][4];
@@ -4726,7 +4724,7 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
/* loop over available constraints, solving and blending them */
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
/* these we can skip completely (invalid constraints...) */
@@ -4746,10 +4744,10 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
copy_m4_m4(oldmat, cob->matrix);
/* move owner matrix into right space */
- 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);
/* prepare targets for constraint solving */
- get_constraint_targets_for_solving(con, cob, &targets, ctime);
+ BKE_get_constraint_targets_for_solving(con, cob, &targets, ctime);
/* Solve the constraint and put result in cob->matrix */
cti->evaluate_constraint(con, cob, &targets);
@@ -4764,7 +4762,7 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
/* move owner back into worldspace for next constraint/other business */
if ((con->flag & CONSTRAINT_SPACEONCE) == 0)
- 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);
/* 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 ffb93139358..a9e3d52f223 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -29,6 +29,7 @@
#include <string.h>
+#include <stdlib.h>
#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -47,6 +48,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_screen.h"
@@ -327,10 +330,13 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member)
{
bContextDataResult result;
- if (C && ctx_data_get((bContext *)C, member, &result) == 1)
+ if (C && ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr.data;
-
- return NULL;
+ }
+ else {
+ return NULL;
+ }
}
static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
@@ -343,6 +349,7 @@ static int ctx_data_pointer_verify(const bContext *C, const char *member, void *
return 1;
}
else if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
*pointer = result.ptr.data;
return 1;
}
@@ -357,6 +364,7 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
*list = result.list;
return 1;
}
@@ -371,10 +379,13 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
{
bContextDataResult result;
- if (ctx_data_get((bContext *)C, member, &result) == 1)
+ if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr;
- else
+ }
+ else {
return PointerRNA_NULL;
+ }
}
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
@@ -399,6 +410,7 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member)
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
return result.list;
}
else {
@@ -427,11 +439,11 @@ int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListB
return ret;
}
-static void data_dir_add(ListBase *lb, const char *member)
+static void data_dir_add(ListBase *lb, const char *member, const short use_all)
{
LinkData *link;
- if (strcmp(member, "scene") == 0) /* exception */
+ if ((use_all == FALSE) && strcmp(member, "scene") == 0) /* exception */
return;
if (BLI_findstring(lb, member, offsetof(LinkData, data)))
@@ -442,7 +454,13 @@ static void data_dir_add(ListBase *lb, const char *member)
BLI_addtail(lb, link);
}
-ListBase CTX_data_dir_get(const bContext *C)
+/**
+ * \param C Context
+ * \param use_store Use 'C->wm.store'
+ * \param use_rna Use Include the properties from 'RNA_Context'
+ * \param use_all Don't skip values (currently only "scene")
+ */
+ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all)
{
bContextDataResult result;
ListBase lb;
@@ -453,11 +471,33 @@ ListBase CTX_data_dir_get(const bContext *C)
memset(&lb, 0, sizeof(lb));
- if (C->wm.store) {
+ if (use_rna) {
+ char name[256], *nameptr;
+ int namelen;
+
+ PropertyRNA *iterprop;
+ PointerRNA ctx_ptr;
+ RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr);
+
+ iterprop = RNA_struct_iterator_property(ctx_ptr.type);
+
+ RNA_PROP_BEGIN (&ctx_ptr, itemptr, iterprop)
+ {
+ nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
+ data_dir_add(&lb, name, use_all);
+ if (nameptr) {
+ if (name != nameptr) {
+ MEM_freeN(nameptr);
+ }
+ }
+ }
+ RNA_PROP_END;
+ }
+ if (use_store && C->wm.store) {
bContextStoreEntry *entry;
for (entry = C->wm.store->entries.first; entry; entry = entry->next)
- data_dir_add(&lb, entry->name);
+ data_dir_add(&lb, entry->name, use_all);
}
if ((ar = CTX_wm_region(C)) && ar->type && ar->type->context) {
memset(&result, 0, sizeof(result));
@@ -465,7 +505,7 @@ ListBase CTX_data_dir_get(const bContext *C)
if (result.dir)
for (a = 0; result.dir[a]; a++)
- data_dir_add(&lb, result.dir[a]);
+ data_dir_add(&lb, result.dir[a], use_all);
}
if ((sa = CTX_wm_area(C)) && sa->type && sa->type->context) {
memset(&result, 0, sizeof(result));
@@ -473,7 +513,7 @@ ListBase CTX_data_dir_get(const bContext *C)
if (result.dir)
for (a = 0; result.dir[a]; a++)
- data_dir_add(&lb, result.dir[a]);
+ data_dir_add(&lb, result.dir[a], use_all);
}
if ((sc = CTX_wm_screen(C)) && sc->context) {
bContextDataCallback cb = sc->context;
@@ -482,12 +522,17 @@ ListBase CTX_data_dir_get(const bContext *C)
if (result.dir)
for (a = 0; result.dir[a]; a++)
- data_dir_add(&lb, result.dir[a]);
+ data_dir_add(&lb, result.dir[a], use_all);
}
return lb;
}
+ListBase CTX_data_dir_get(const bContext *C)
+{
+ return CTX_data_dir_get_ex(C, TRUE, FALSE, FALSE);
+}
+
int CTX_data_equals(const char *member, const char *str)
{
return (strcmp(member, str) == 0);
@@ -808,7 +853,7 @@ void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
const char *CTX_wm_operator_poll_msg_get(bContext *C)
{
- return C->wm.operator_poll_msg;
+ return IFACE_(C->wm.operator_poll_msg);
}
/* data context */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 754a4fbc0c8..2da75ec64be 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -36,7 +36,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_bpath.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -68,7 +67,7 @@
/* local */
static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3],
short cox, short coy,
- float *labda, float *mu, float vec[3]);
+ float *lambda, float *mu, float vec[3]);
void BKE_curve_unlink(Curve *cu)
{
@@ -168,11 +167,11 @@ void BKE_curve_free(Curve *cu)
MEM_freeN(cu->tb);
}
-Curve *BKE_curve_add(const char *name, int type)
+Curve *BKE_curve_add(Main *bmain, const char *name, int type)
{
Curve *cu;
- cu = BKE_libblock_alloc(&G.main->curve, ID_CU, name);
+ cu = BKE_libblock_alloc(&bmain->curve, ID_CU, name);
copy_v3_fl(cu->size, 1.0f);
cu->flag = CU_FRONT | CU_BACK | CU_DEFORM_BOUNDS_OFF | CU_PATH_RADIUS;
cu->pathlen = 100;
@@ -876,7 +875,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv)
-/* coord_array has to be 3*4*resolu*resolv in size, and zero-ed */
+/* coord_array has to be (3 * 4 * resolu * resolv) in size, and zero-ed */
{
BPoint *bp;
float *basisu, *basis, *basisv, *sum, *fp, *in;
@@ -1615,7 +1614,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende
static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3],
short cox, short coy,
- float *labda, float *mu, float vec[3])
+ float *lambda, float *mu, float vec[3])
{
/* return:
* -1: collinear
@@ -1629,22 +1628,22 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c
if (deler == 0.0f)
return -1;
- *labda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]);
- *labda = -(*labda / deler);
+ *lambda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]);
+ *lambda = -(*lambda / deler);
deler = v3[coy] - v4[coy];
if (deler == 0) {
deler = v3[cox] - v4[cox];
- *mu = -(*labda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler;
+ *mu = -(*lambda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler;
}
else {
- *mu = -(*labda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler;
+ *mu = -(*lambda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler;
}
- vec[cox] = *labda * (v2[cox] - v1[cox]) + v1[cox];
- vec[coy] = *labda * (v2[coy] - v1[coy]) + v1[coy];
+ vec[cox] = *lambda * (v2[cox] - v1[cox]) + v1[cox];
+ vec[coy] = *lambda * (v2[coy] - v1[coy]) + v1[coy];
- if (*labda >= 0.0f && *labda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) {
- if (*labda == 0.0f || *labda == 1.0f || *mu == 0.0f || *mu == 1.0f)
+ if (*lambda >= 0.0f && *lambda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) {
+ if (*lambda == 0.0f || *lambda == 1.0f || *mu == 0.0f || *mu == 1.0f)
return 1;
return 2;
}
@@ -1654,7 +1653,7 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c
static short bevelinside(BevList *bl1, BevList *bl2)
{
- /* is bl2 INSIDE bl1 ? with left-right method and "labda's" */
+ /* is bl2 INSIDE bl1 ? with left-right method and "lambda's" */
/* returns '1' if correct hole */
BevPoint *bevp, *prevbevp;
float min, max, vec[3], hvec1[3], hvec2[3], lab, mu;
@@ -1747,7 +1746,7 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
else
t02 = (saacos(t02)) / 2.0f;
- t02 = (float)sin(t02);
+ t02 = sinf(t02);
if (t02 == 0.0f)
t02 = 1.0f;
@@ -2203,6 +2202,70 @@ static void make_bevel_list_segment_3D(BevList *bl)
copy_qt_qt(bevp2->quat, bevp1->quat);
}
+/* only for 2 points */
+static void make_bevel_list_segment_2D(BevList *bl)
+{
+ BevPoint *bevp2 = (BevPoint *)(bl + 1);
+ BevPoint *bevp1 = bevp2 + 1;
+
+ const float x1 = bevp1->vec[0] - bevp2->vec[0];
+ const float y1 = bevp1->vec[1] - bevp2->vec[1];
+
+ calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa));
+ bevp2->sina = bevp1->sina;
+ bevp2->cosa = bevp1->cosa;
+
+ /* fill in dir & quat */
+ make_bevel_list_segment_3D(bl);
+}
+
+static void make_bevel_list_2D(BevList *bl)
+{
+ /* note: bevp->dir and bevp->quat are not needed for beveling but are
+ * used when making a path from a 2D curve, therefor they need to be set - Campbell */
+
+ BevPoint *bevp2 = (BevPoint *)(bl + 1);
+ BevPoint *bevp1 = bevp2 + (bl->nr - 1);
+ BevPoint *bevp0 = bevp1 - 1;
+ int nr;
+
+ nr = bl->nr;
+ while (nr--) {
+ const float x1 = bevp1->vec[0] - bevp0->vec[0];
+ const float x2 = bevp1->vec[0] - bevp2->vec[0];
+ const float y1 = bevp1->vec[1] - bevp0->vec[1];
+ const float y2 = bevp1->vec[1] - bevp2->vec[1];
+
+ calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
+
+ /* from: make_bevel_list_3D_zup, could call but avoid a second loop.
+ * no need for tricky tilt calculation as with 3D curves */
+ bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
+ vec_to_quat(bevp1->quat, bevp1->dir, 5, 1);
+ /* done with inline make_bevel_list_3D_zup */
+
+ bevp0 = bevp1;
+ bevp1 = bevp2;
+ bevp2++;
+ }
+
+ /* correct non-cyclic cases */
+ if (bl->poly == -1) {
+ BevPoint *bevp = (BevPoint *)(bl + 1);
+ bevp1 = bevp + 1;
+ bevp->sina = bevp1->sina;
+ bevp->cosa = bevp1->cosa;
+ bevp = (BevPoint *)(bl + 1);
+ bevp += (bl->nr - 1);
+ bevp1 = bevp - 1;
+ bevp->sina = bevp1->sina;
+ bevp->cosa = bevp1->cosa;
+
+ /* correct for the dir/quat, see above why its needed */
+ bevel_list_cyclic_fix_3D(bl);
+ }
+}
+
void BKE_curve_bevelList_make(Object *ob)
{
/*
@@ -2217,10 +2280,11 @@ void BKE_curve_bevelList_make(Object *ob)
BPoint *bp;
BevList *bl, *blnew, *blnext;
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
- float min, inp, x1, x2, y1, y2;
+ float min, inp;
struct bevelsort *sortdata, *sd, *sd1;
int a, b, nr, poly, resolu = 0, len = 0;
int do_tilt, do_radius, do_weight;
+ int is_editmode = 0;
/* this function needs an object, because of tflag and upflag */
cu = ob->data;
@@ -2234,12 +2298,17 @@ void BKE_curve_bevelList_make(Object *ob)
if (cu->editnurb && ob->type != OB_FONT) {
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
nu = nurbs->first;
+ is_editmode = 1;
}
else {
nu = cu->nurb.first;
}
- while (nu) {
+ for (; nu; nu = nu->next) {
+
+ if (nu->hide && is_editmode)
+ continue;
+
/* check if we will calculate tilt data */
do_tilt = CU_DO_TILT(cu, nu);
do_radius = CU_DO_RADIUS(cu, nu); /* normal display uses the radius, better just to calculate them */
@@ -2385,7 +2454,6 @@ void BKE_curve_bevelList_make(Object *ob)
}
}
}
- nu = nu->next;
}
/* STEP 2: DOUBLE POINTS AND AUTOMATIC RESOLUTION, REDUCE DATABLOCKS */
@@ -2530,76 +2598,22 @@ void BKE_curve_bevelList_make(Object *ob)
/* STEP 4: 2D-COSINES or 3D ORIENTATION */
if ((cu->flag & CU_3D) == 0) {
- /* note: bevp->dir and bevp->quat are not needed for beveling but are
- * used when making a path from a 2D curve, therefor they need to be set - Campbell */
- bl = cu->bev.first;
- while (bl) {
-
+ /* 2D Curves */
+ for (bl = cu->bev.first; bl; bl = bl->next) {
if (bl->nr < 2) {
/* do nothing */
}
else if (bl->nr == 2) { /* 2 pnt, treat separate */
- bevp2 = (BevPoint *)(bl + 1);
- bevp1 = bevp2 + 1;
-
- x1 = bevp1->vec[0] - bevp2->vec[0];
- y1 = bevp1->vec[1] - bevp2->vec[1];
-
- calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa));
- bevp2->sina = bevp1->sina;
- bevp2->cosa = bevp1->cosa;
-
- /* fill in dir & quat */
- make_bevel_list_segment_3D(bl);
+ make_bevel_list_segment_2D(bl);
}
else {
- bevp2 = (BevPoint *)(bl + 1);
- bevp1 = bevp2 + (bl->nr - 1);
- bevp0 = bevp1 - 1;
-
- nr = bl->nr;
- while (nr--) {
- x1 = bevp1->vec[0] - bevp0->vec[0];
- x2 = bevp1->vec[0] - bevp2->vec[0];
- y1 = bevp1->vec[1] - bevp0->vec[1];
- y2 = bevp1->vec[1] - bevp2->vec[1];
-
- calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
-
- /* from: make_bevel_list_3D_zup, could call but avoid a second loop.
- * no need for tricky tilt calculation as with 3D curves */
- bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
- vec_to_quat(bevp1->quat, bevp1->dir, 5, 1);
- /* done with inline make_bevel_list_3D_zup */
-
- bevp0 = bevp1;
- bevp1 = bevp2;
- bevp2++;
- }
-
- /* correct non-cyclic cases */
- if (bl->poly == -1) {
- bevp = (BevPoint *)(bl + 1);
- bevp1 = bevp + 1;
- bevp->sina = bevp1->sina;
- bevp->cosa = bevp1->cosa;
- bevp = (BevPoint *)(bl + 1);
- bevp += (bl->nr - 1);
- bevp1 = bevp - 1;
- bevp->sina = bevp1->sina;
- bevp->cosa = bevp1->cosa;
-
- /* correct for the dir/quat, see above why its needed */
- bevel_list_cyclic_fix_3D(bl);
- }
+ make_bevel_list_2D(bl);
}
- bl = bl->next;
}
}
- else { /* 3D Curves */
- bl = cu->bev.first;
- while (bl) {
-
+ else {
+ /* 3D Curves */
+ for (bl = cu->bev.first; bl; bl = bl->next) {
if (bl->nr < 2) {
/* do nothing */
}
@@ -2609,7 +2623,6 @@ void BKE_curve_bevelList_make(Object *ob)
else {
make_bevel_list_3D(bl, (int)(resolu * cu->twist_smooth), cu->twist_mode);
}
- bl = bl->next;
}
}
}
@@ -3432,7 +3445,9 @@ int BKE_curve_center_median(Curve *cu, float cent[3])
}
}
- mul_v3_fl(cent, 1.0f / (float)total);
+ if (total) {
+ mul_v3_fl(cent, 1.0f / (float)total);
+ }
return (total != 0);
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index b2f8db0dcce..580a69466c9 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1242,12 +1242,15 @@ void CustomData_update_typemap(CustomData *data)
}
}
+/* currently only used in BLI_assert */
+#ifndef NDEBUG
static int customdata_typemap_is_valid(const CustomData *data)
{
CustomData data_copy = *data;
CustomData_update_typemap(&data_copy);
return (memcmp(data->typemap, data_copy.typemap, sizeof(data->typemap)) == 0);
}
+#endif
void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
CustomDataMask mask, int alloctype, int totelem)
@@ -2095,6 +2098,23 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type,
return data->layers[layer_index].data;
}
+int CustomData_get_offset(const CustomData *data, int type)
+{
+ /* get the layer index of the active layer of type */
+ int layer_index = CustomData_get_active_layer_index(data, type);
+ if (layer_index < 0) return -1;
+
+ return data->layers[layer_index].offset;
+}
+
+int CustomData_get_n_offset(const CustomData *data, int type, int n)
+{
+ /* get the layer index of the active layer of type */
+ int layer_index = CustomData_get_layer_index_n(data, type, n);
+ if (layer_index < 0) return -1;
+
+ return data->layers[layer_index].offset;
+}
int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
{
@@ -2104,7 +2124,7 @@ int CustomData_set_layer_name(const CustomData *data, int type, int n, const cha
if (layer_index < 0) return 0;
if (!name) return 0;
- strcpy(data->layers[layer_index].name, name);
+ BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name));
return 1;
}
@@ -2298,34 +2318,46 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
BMIter iter;
CustomData destold;
void *tmp;
- int t;
+ int iter_type;
+ int totelem;
/* copy old layer description so that old data can be copied into
* the new allocation */
destold = *dest;
- if (destold.layers) destold.layers = MEM_dupallocN(destold.layers);
-
- CustomData_merge(source, dest, mask, alloctype, 0);
- dest->pool = NULL;
- CustomData_bmesh_init_pool(dest, 512, htype);
+ if (destold.layers) {
+ destold.layers = MEM_dupallocN(destold.layers);
+ }
switch (htype) {
case BM_VERT:
- t = BM_VERTS_OF_MESH; break;
+ iter_type = BM_VERTS_OF_MESH;
+ totelem = bm->totvert;
+ break;
case BM_EDGE:
- t = BM_EDGES_OF_MESH; break;
+ iter_type = BM_EDGES_OF_MESH;
+ totelem = bm->totedge;
+ break;
case BM_LOOP:
- t = BM_LOOPS_OF_FACE; break;
+ iter_type = BM_LOOPS_OF_FACE;
+ totelem = bm->totloop;
+ break;
case BM_FACE:
- t = BM_FACES_OF_MESH; break;
+ iter_type = BM_FACES_OF_MESH;
+ totelem = bm->totface;
+ break;
default: /* should never happen */
BLI_assert(!"invalid type given");
- t = BM_VERTS_OF_MESH;
+ iter_type = BM_VERTS_OF_MESH;
+ totelem = bm->totvert;
}
- if (t != BM_LOOPS_OF_FACE) {
+ CustomData_merge(source, dest, mask, alloctype, 0);
+ dest->pool = NULL;
+ CustomData_bmesh_init_pool(dest, totelem, htype);
+
+ if (iter_type != BM_LOOPS_OF_FACE) {
/*ensure all current elements follow new customdata layout*/
- BM_ITER_MESH (h, &iter, bm, t) {
+ BM_ITER_MESH (h, &iter, bm, iter_type) {
tmp = NULL;
CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
CustomData_bmesh_free_block(&destold, &h->data);
@@ -2618,6 +2650,19 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so
memcpy(dest, source, typeInfo->size);
}
+/**
+ * \param src_blocks must be pointers to the data, offset by layer->offset already.
+ */
+void CustomData_bmesh_interp_n(CustomData *data, void **src_blocks, const float *weights,
+ const float *sub_weights, int count, void *dest_block, int n)
+{
+ CustomDataLayer *layer = &data->layers[n];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+
+ typeInfo->interp(src_blocks, weights, sub_weights, count,
+ (char *)dest_block + layer->offset);
+}
+
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *weights,
const float *sub_weights, int count, void *dest_block)
{
@@ -2640,36 +2685,47 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w
for (j = 0; j < count; ++j) {
sources[j] = (char *)src_blocks[j] + layer->offset;
}
-
- typeInfo->interp(sources, weights, sub_weights, count,
- (char *)dest_block + layer->offset);
+ CustomData_bmesh_interp_n(data, sources, weights, sub_weights, count, dest_block, i);
}
}
if (count > SOURCE_BUF_SIZE) MEM_freeN(sources);
}
-void CustomData_bmesh_set_default(CustomData *data, void **block)
+static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
{
const LayerTypeInfo *typeInfo;
+ int offset = data->layers[n].offset;
+
+ typeInfo = layerType_getInfo(data->layers[n].type);
+
+ if (typeInfo->set_default) {
+ typeInfo->set_default((char *)*block + offset, 1);
+ }
+ else {
+ memset((char *)*block + offset, 0, typeInfo->size);
+ }
+}
+
+void CustomData_bmesh_set_default(CustomData *data, void **block)
+{
int i;
if (*block == NULL)
CustomData_bmesh_alloc_block(data, block);
for (i = 0; i < data->totlayer; ++i) {
- int offset = data->layers[i].offset;
-
- typeInfo = layerType_getInfo(data->layers[i].type);
-
- if (typeInfo->set_default)
- typeInfo->set_default((char *)*block + offset, 1);
- else memset((char *)*block + offset, 0, typeInfo->size);
+ CustomData_bmesh_set_default_n(data, block, i);
}
}
+/**
+ * \param use_default_init initializes data which can't be copied,
+ * typically you'll want to use this if the BM_xxx create function
+ * is called with BM_CREATE_SKIP_CD flag
+ */
void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
- int src_index, void **dest_block)
+ int src_index, void **dest_block, bool use_default_init)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, src_offset;
@@ -2685,11 +2741,14 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
+ if (use_default_init) {
+ CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+ }
dest_i++;
}
/* if there are no more dest layers, we're done */
- if (dest_i >= dest->totlayer) return;
+ if (dest_i >= dest->totlayer) break;
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -2712,6 +2771,13 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
dest_i++;
}
}
+
+ if (use_default_init) {
+ while (dest_i < dest->totlayer) {
+ CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+ dest_i++;
+ }
+ }
}
void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
@@ -2854,10 +2920,11 @@ void CustomData_validate_layer_name(const CustomData *data, int type, const char
* deleted, so assign the active layer to name
*/
index = CustomData_get_active_layer_index(data, type);
- strcpy(outname, data->layers[index].name);
+ BLI_strncpy(outname, data->layers[index].name, MAX_CUSTOMDATA_LAYER_NAME);
+ }
+ else {
+ BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME);
}
- else
- strcpy(outname, name);
}
int CustomData_verify_versions(struct CustomData *data, int index)
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 7c13ca388e0..439180e8d76 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -34,20 +34,20 @@
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
+#include <stddef.h>
#include "MEM_guardedalloc.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BKE_deform.h"
-
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BKE_deform.h" /* own include */
void defgroup_copy_list(ListBase *outbase, ListBase *inbase)
{
@@ -337,37 +337,12 @@ void defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip
bDeformGroup *defgroup_find_name(Object *ob, const char *name)
{
- /* return a pointer to the deform group with this name
- * or return NULL otherwise.
- */
- bDeformGroup *curdef;
-
- for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
- if (!strcmp(curdef->name, name)) {
- return curdef;
- }
- }
- return NULL;
+ return BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name));
}
int defgroup_name_index(Object *ob, const char *name)
{
- /* Return the location of the named deform group within the list of
- * deform groups. This function is a combination of BLI_findlink and
- * defgroup_find_name. The other two could be called instead, but that
- * require looping over the vertexgroups twice.
- */
- bDeformGroup *curdef;
- int def_nr;
-
- if (name && name[0] != '\0') {
- for (curdef = ob->defbase.first, def_nr = 0; curdef; curdef = curdef->next, def_nr++) {
- if (!strcmp(curdef->name, name))
- return def_nr;
- }
- }
-
- return -1;
+ return (name) ? BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) : -1;
}
/* note, must be freed */
@@ -810,3 +785,73 @@ int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
return -1;
}
+
+/**
+ * return true if has no weights
+ */
+bool defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_tot)
+{
+ MDeformWeight *dw = dvert->dw;
+ unsigned int i;
+ for (i = dvert->totweight; i != 0; i--, dw++) {
+ if (dw->weight != 0.0f) {
+ /* check the group is in-range, happens on rare situations */
+ if (LIKELY(dw->def_nr < defgroup_tot)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/* -------------------------------------------------------------------- */
+/* Defvert Array functions */
+
+void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int copycount)
+{
+ /* Assumes dst is already set up */
+ int i;
+
+ if (!src || !dst)
+ return;
+
+ memcpy(dst, src, copycount * sizeof(MDeformVert));
+
+ for (i = 0; i < copycount; i++) {
+ if (src[i].dw) {
+ dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
+ memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
+ }
+ }
+
+}
+
+void BKE_defvert_array_free_elems(MDeformVert *dvert, int totvert)
+{
+ /* Instead of freeing the verts directly,
+ * call this function to delete any special
+ * vert data */
+ int i;
+
+ if (!dvert)
+ return;
+
+ /* Free any special data from the verts */
+ for (i = 0; i < totvert; i++) {
+ if (dvert[i].dw) MEM_freeN(dvert[i].dw);
+ }
+}
+
+void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
+{
+ /* Instead of freeing the verts directly,
+ * call this function to delete any special
+ * vert data */
+ if (!dvert)
+ return;
+
+ /* Free any special data from the verts */
+ BKE_defvert_array_free_elems(dvert, totvert);
+
+ MEM_freeN(dvert);
+}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 3ed759392b6..8c55ad02dc6 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -424,7 +424,7 @@ static void dag_add_lamp_driver_relations(DagForest *dag, DagNode *node, Lamp *l
dag_add_shader_nodetree_driver_relations(dag, node, la->nodetree);
}
-static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield)
+static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield, bool no_collision)
{
Base *base;
DagNode *node2;
@@ -435,7 +435,7 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec
if ((base->lay & ob->lay) && base->object->pd) {
Object *ob1 = base->object;
if ((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) {
- if (skip_forcefield && ob1->pd->forcefield == skip_forcefield)
+ if ((skip_forcefield && ob1->pd->forcefield == skip_forcefield) || (no_collision && ob1->pd->forcefield == 0))
continue;
node2 = dag_get_node(dag, ob1);
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision");
@@ -472,7 +472,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -599,10 +599,13 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
modifiers_isModifierEnabled(ob, eModifierType_Cloth) ||
modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint))
{
- dag_add_collision_field_relation(dag, scene, ob, node, 0); /* TODO: use effectorweight->group */
+ dag_add_collision_field_relation(dag, scene, ob, node, 0, false); /* TODO: use effectorweight->group */
}
else if (modifiers_isModifierEnabled(ob, eModifierType_Smoke)) {
- dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW);
+ dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW, false);
+ }
+ else if (ob->rigidbody_object) {
+ dag_add_collision_field_relation(dag, scene, ob, node, 0, true);
}
}
@@ -754,7 +757,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
/* object constraints */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -834,7 +837,6 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask)
DagAdjList *itA;
dag = sce->theDag;
- sce->dagisvalid = 1;
if (dag)
free_forest(dag);
else {
@@ -1843,8 +1845,18 @@ static void scene_sort_groups(Main *bmain, Scene *sce)
}
}
+/* free the depency graph */
+static void dag_scene_free(Scene *sce)
+{
+ if (sce->theDag) {
+ free_forest(sce->theDag);
+ MEM_freeN(sce->theDag);
+ sce->theDag = NULL;
+ }
+}
+
/* sort the base list on dependency order */
-void DAG_scene_sort(Main *bmain, Scene *sce)
+static void dag_scene_build(Main *bmain, Scene *sce)
{
DagNode *node, *rootnode;
DagNodeQueue *nqueue;
@@ -1853,7 +1865,7 @@ void DAG_scene_sort(Main *bmain, Scene *sce)
int skip = 0;
ListBase tempbase;
Base *base;
-
+
tempbase.first = tempbase.last = NULL;
build_dag(bmain, sce, DAG_RL_ALL_BUT_DATA);
@@ -1933,10 +1945,34 @@ void DAG_scene_sort(Main *bmain, Scene *sce)
printf(" %s\n", base->object->id.name);
}
}
+
/* temporal...? */
sce->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */
}
+/* clear all dependency graphs */
+void DAG_relations_tag_update(Main *bmain)
+{
+ Scene *sce;
+
+ for (sce = bmain->scene.first; sce; sce = sce->id.next)
+ dag_scene_free(sce);
+}
+
+/* rebuild dependency graph only for a given scene */
+void DAG_scene_relations_rebuild(Main *bmain, Scene *sce)
+{
+ dag_scene_free(sce);
+ DAG_scene_relations_update(bmain, sce);
+}
+
+/* create dependency graph if it was cleared or didn't exist yet */
+void DAG_scene_relations_update(Main *bmain, Scene *sce)
+{
+ if (!sce->theDag)
+ dag_scene_build(bmain, sce);
+}
+
static void lib_id_recalc_tag(Main *bmain, ID *id)
{
id->flag |= LIB_ID_RECALC;
@@ -2174,7 +2210,7 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho
if (sce->theDag == NULL) {
printf("DAG zero... not allowed to happen!\n");
- DAG_scene_sort(bmain, sce);
+ DAG_scene_relations_update(bmain, sce);
}
firstnode = sce->theDag->DagNode.first; /* always scene node */
@@ -2290,12 +2326,12 @@ static short animdata_use_time(AnimData *adt)
return 0;
}
-static void dag_object_time_update_flags(Object *ob)
+static void dag_object_time_update_flags(Scene *scene, Object *ob)
{
if (ob->constraints.first) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2350,6 +2386,10 @@ static void dag_object_time_update_flags(Object *ob)
if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
+ // XXX: scene here may not be the scene that contains the rigidbody world affecting this!
+ if (ob->rigidbody_object && BKE_scene_check_rigidbody_active(scene))
+ ob->recalc |= OB_RECALC_OB;
+
{
AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
Mesh *me;
@@ -2434,7 +2474,11 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
if (do_time) {
/* now if DagNode were part of base, the node->lay could be checked... */
/* we do all now, since the scene_flush checks layers and clears recalc flags even */
- dag_object_time_update_flags(ob);
+
+ /* NOTE: "sce_iter" not "scene" so that rigidbodies in background scenes work
+ * (i.e. muting + rbw availability can be checked and tagged properly) [#33970]
+ */
+ dag_object_time_update_flags(sce_iter, ob);
}
/* handled in next loop */
@@ -2447,7 +2491,7 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
for (group = bmain->group.first; group; group = group->id.next) {
if (group->id.flag & LIB_DOIT) {
for (go = group->gobject.first; go; go = go->next) {
- dag_object_time_update_flags(go->ob);
+ dag_object_time_update_flags(scene, go->ob);
}
}
}
@@ -2466,7 +2510,7 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
/* hrmf... an exception to look at once, for invisible camera object we do it over */
if (scene->camera)
- dag_object_time_update_flags(scene->camera);
+ dag_object_time_update_flags(scene, scene->camera);
}
/* and store the info in groupobject */
@@ -2482,30 +2526,51 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
}
-static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay)
+/* struct returned by DagSceneLayer */
+typedef struct DagSceneLayer {
+ struct DagSceneLayer *next, *prev;
+ Scene *scene;
+ unsigned int layer;
+} DagSceneLayer;
+
+/* returns visible scenes with valid DAG */
+static void dag_current_scene_layers(Main *bmain, ListBase *lb)
{
wmWindowManager *wm;
wmWindow *win;
+
+ lb->first = lb->last = NULL;
- /* only one scene supported currently, making more scenes work
- * correctly requires changes beyond just the dependency graph */
-
- *sce = NULL;
- *lay = 0;
-
+ /* if we have a windowmanager, look into windows */
if ((wm = bmain->wm.first)) {
- /* if we have a windowmanager, look into windows */
+
+ flag_listbase_ids(&bmain->scene, LIB_DOIT, 1);
+
for (win = wm->windows.first; win; win = win->next) {
- if (win->screen) {
- if (*sce == NULL) *sce = win->screen->scene;
- *lay |= BKE_screen_visible_layers(win->screen, win->screen->scene);
+ if (win->screen && win->screen->scene->theDag) {
+ Scene *scene = win->screen->scene;
+
+ if (scene->id.flag & LIB_DOIT) {
+ DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
+
+ BLI_addtail(lb, dsl);
+
+ dsl->scene = scene;
+ dsl->layer = BKE_screen_visible_layers(win->screen, scene);
+
+ scene->id.flag &= ~LIB_DOIT;
+ }
}
}
}
else {
/* if not, use the first sce */
- *sce = bmain->scene.first;
- if (*sce) *lay = (*sce)->lay;
+ DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
+
+ BLI_addtail(lb, dsl);
+
+ dsl->scene = bmain->scene.first;
+ dsl->layer = dsl->scene->lay;
/* XXX for background mode, we should get the scene
* from somewhere, for the -S option, but it's in
@@ -2513,31 +2578,24 @@ static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay
}
}
-void DAG_ids_flush_update(Main *bmain, int time)
-{
- Scene *sce;
- unsigned int lay;
-
- dag_current_scene_layers(bmain, &sce, &lay);
-
- if (sce)
- DAG_scene_flush_update(bmain, sce, lay, time);
-}
-
void DAG_on_visible_update(Main *bmain, const short do_time)
{
- Scene *scene;
- Base *base;
- Object *ob;
- Group *group;
- GroupObject *go;
- DagNode *node;
- unsigned int lay, oblay;
-
- dag_current_scene_layers(bmain, &scene, &lay);
-
- if (scene && scene->theDag) {
+ ListBase listbase;
+ DagSceneLayer *dsl;
+
+ /* get list of visible scenes and layers */
+ dag_current_scene_layers(bmain, &listbase);
+
+ for (dsl = listbase.first; dsl; dsl = dsl->next) {
+ Scene *scene = dsl->scene;
Scene *sce_iter;
+ Base *base;
+ Object *ob;
+ Group *group;
+ GroupObject *go;
+ DagNode *node;
+ unsigned int lay = dsl->layer, oblay;
+
/* derivedmeshes and displists are not saved to file so need to be
* remade, tag them so they get remade in the scene update loop,
* note armature poses or object matrices are preserved and do not
@@ -2574,6 +2632,8 @@ void DAG_on_visible_update(Main *bmain, const short do_time)
DAG_scene_update_flags(bmain, scene, lay, do_time);
scene->lay_updated |= lay;
}
+
+ BLI_freelistN(&listbase);
/* hack to get objects updating on layer changes */
DAG_id_type_tag(bmain, ID_OB);
@@ -2708,7 +2768,7 @@ static void dag_id_flush_update(Scene *sce, ID *id)
for (obt = bmain->object.first; obt; obt = obt->id.next) {
bConstraint *con;
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
CONSTRAINT_TYPE_OBJECTSOLVER))
{
@@ -2758,14 +2818,15 @@ static void dag_id_flush_update(Scene *sce, ID *id)
void DAG_ids_flush_tagged(Main *bmain)
{
+ ListBase listbase;
+ DagSceneLayer *dsl;
ListBase *lbarray[MAX_LIBARRAY];
- Scene *sce;
- unsigned int lay;
int a, do_flush = FALSE;
+
+ /* get list of visible scenes and layers */
+ dag_current_scene_layers(bmain, &listbase);
- dag_current_scene_layers(bmain, &sce, &lay);
-
- if (!sce || !sce->theDag)
+ if (listbase.first == NULL)
return;
/* loop over all ID types */
@@ -2780,7 +2841,10 @@ void DAG_ids_flush_tagged(Main *bmain)
if (id && bmain->id_tag_update[id->name[0]]) {
for (; id; id = id->next) {
if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) {
- dag_id_flush_update(sce, id);
+
+ for (dsl = listbase.first; dsl; dsl = dsl->next)
+ dag_id_flush_update(dsl->scene, id);
+
do_flush = TRUE;
}
}
@@ -2788,8 +2852,12 @@ void DAG_ids_flush_tagged(Main *bmain)
}
/* flush changes to other objects */
- if (do_flush)
- DAG_scene_flush_update(bmain, sce, lay, 0);
+ if (do_flush) {
+ for (dsl = listbase.first; dsl; dsl = dsl->next)
+ DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, 0);
+ }
+
+ BLI_freelistN(&listbase);
}
void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
@@ -2846,12 +2914,10 @@ void DAG_ids_clear_recalc(Main *bmain)
memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
}
-void DAG_id_tag_update(ID *id, short flag)
+void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag)
{
- Main *bmain = G.main;
-
if (id == NULL) return;
-
+
/* tag ID for update */
if (flag) {
if (flag & OB_RECALC_OB)
@@ -2906,6 +2972,11 @@ void DAG_id_tag_update(ID *id, short flag)
}
}
+void DAG_id_tag_update(ID *id, short flag)
+{
+ DAG_id_tag_update_ex(G.main, id, flag);
+}
+
void DAG_id_type_tag(Main *bmain, short idtype)
{
if (idtype == ID_NT) {
@@ -2992,7 +3063,7 @@ void DAG_pose_sort(Object *ob)
addtoroot = 0;
}
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -3120,7 +3191,7 @@ void DAG_print_dependencies(Main *bmain, Scene *scene, Object *ob)
}
else {
printf("\nDEPENDENCY RELATIONS for %s\n\n", scene->id.name + 2);
- DAG_scene_sort(bmain, scene);
+ DAG_scene_relations_rebuild(bmain, scene);
}
dag_print_dependencies = 0;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 083cb02fd3d..6f85d4de60e 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -63,6 +63,7 @@
#include "BLO_sys_types.h" // for intptr_t support
static void boundbox_displist(Object *ob);
+static void boundbox_dispbase(BoundBox *bb, ListBase *dispbase);
void BKE_displist_elem_free(DispList *dl)
{
@@ -225,29 +226,48 @@ void BKE_displist_normals_add(ListBase *lb)
}
}
-void BKE_displist_count(ListBase *lb, int *totvert, int *totface)
+void BKE_displist_count(ListBase *lb, int *totvert, int *totface, int *tottri)
{
DispList *dl;
- dl = lb->first;
- while (dl) {
+ for (dl = lb->first; dl; dl = dl->next) {
+ int vert_tot = 0;
+ int face_tot = 0;
+ int tri_tot = 0;
+
switch (dl->type) {
case DL_SURF:
- *totvert += dl->nr * dl->parts;
- *totface += (dl->nr - 1) * (dl->parts - 1);
+ {
+ vert_tot = dl->nr * dl->parts;
+ face_tot = (dl->nr - 1) * (dl->parts - 1);
+ tri_tot = face_tot * 2;
break;
+ }
case DL_INDEX3:
+ {
+ vert_tot = dl->nr;
+ face_tot = dl->parts;
+ tri_tot = face_tot;
+ break;
+ }
case DL_INDEX4:
- *totvert += dl->nr;
- *totface += dl->parts;
+ {
+ vert_tot = dl->nr;
+ face_tot = dl->parts;
+ tri_tot = face_tot * 2;
break;
+ }
case DL_POLY:
case DL_SEGM:
- *totvert += dl->nr * dl->parts;
+ {
+ vert_tot = dl->nr * dl->parts;
break;
+ }
}
- dl = dl->next;
+ *totvert += vert_tot;
+ *totface += face_tot;
+ *tottri += tri_tot;
}
}
@@ -290,10 +310,11 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i
BPoint *bp;
float *data;
int a, len, resolu;
+ const int editmode = (!forRender && (cu->editnurb || cu->editfont));
nu = nubase->first;
while (nu) {
- if (nu->hide == 0) {
+ if (nu->hide == 0 || editmode == 0) {
if (forRender && cu->resolu_ren != 0)
resolu = cu->resolu_ren;
else
@@ -486,8 +507,8 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal)
dl = dl->next;
}
- /* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */
- if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) {
+ /* XXX (obedit && obedit->actcol) ? (obedit->actcol-1) : 0)) { */
+ if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_HOLES))) {
if (tot) {
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;
@@ -738,7 +759,7 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, int fo
/* this modifiers are moving point of tessellation automatically
* (some of them even can't be applied on tessellated curve), set flag
- * for incformation button in modifier's header
+ * for information button in modifier's header
*/
md->mode |= eModifierMode_ApplyOnSpline;
}
@@ -780,7 +801,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
required_mode |= eModifierMode_Editmode;
if (cu->editnurb == NULL) {
- keyVerts = do_ob_key(scene, ob);
+ keyVerts = BKE_key_evaluate_object(scene, ob, &numVerts);
if (keyVerts) {
/* split coords from key data, the latter also includes
@@ -789,7 +810,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
* shape key modifier yet. */
deformedVerts = BKE_curve_keyVertexCos_get(cu, nurb, keyVerts);
originalVerts = MEM_dupallocN(deformedVerts);
- numVerts = BKE_nurbList_verts_count(nurb);
+ BLI_assert(BKE_nurbList_verts_count(nurb) == numVerts);
}
}
@@ -956,7 +977,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
curve_to_filledpoly(cu, nurb, dispbase);
}
- dm = CDDM_from_curve_displist(ob, dispbase, NULL);
+ dm = CDDM_from_curve_displist(ob, dispbase);
CDDM_calc_normals_mapping(dm);
}
@@ -1046,7 +1067,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
/* OrcoDM should be created from underformed disp lists */
BKE_displist_make_curveTypes_forOrco(scene, ob, &disp);
- dm = CDDM_from_curve_displist(ob, &disp, NULL);
+ dm = CDDM_from_curve_displist(ob, &disp);
BKE_displist_free(&disp);
@@ -1466,8 +1487,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
float *cur_data = data;
if (cu->taperobj == NULL) {
- if ( (cu->bevobj != NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
- fac = bevp->radius;
+ fac = bevp->radius;
}
else {
float len, taper_fac;
@@ -1579,15 +1599,15 @@ void BKE_displist_make_curveTypes(Scene *scene, Object *ob, int forOrco)
if (ob->derivedFinal) {
DM_set_object_boundbox(ob, ob->derivedFinal);
+
+ /* always keep curve's BB in sync with non-deformed displist */
+ if (cu->bb == NULL)
+ cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox");
+
+ boundbox_dispbase(cu->bb, &cu->disp);
}
else {
boundbox_displist(ob);
-
- /* if there is no derivedMesh, object's boundbox is unneeded */
- if (ob->bb) {
- MEM_freeN(ob->bb);
- ob->bb = NULL;
- }
}
}
@@ -1623,42 +1643,50 @@ float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *derivedFina
return orco;
}
-/* this is confusing, there's also min_max_object, appplying the obmat... */
-static void boundbox_displist(Object *ob)
+static void boundbox_dispbase(BoundBox *bb, ListBase *dispbase)
{
- BoundBox *bb = NULL;
float min[3], max[3];
DispList *dl;
float *vert;
int a, tot = 0;
+ int doit = 0;
INIT_MINMAX(min, max);
+ for (dl = dispbase->first; dl; dl = dl->next) {
+ tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts;
+ vert = dl->verts;
+ for (a = 0; a < tot; a++, vert += 3) {
+ minmax_v3v3_v3(min, max, vert);
+ }
+ doit |= (tot != 0);
+ }
+
+ if (!doit) {
+ /* there's no geometry in displist, use zero-sized boundbox */
+ zero_v3(min);
+ zero_v3(max);
+ }
+
+ BKE_boundbox_init_from_minmax(bb, min, max);
+}
+
+/* this is confusing, there's also min_max_object, appplying the obmat... */
+static void boundbox_displist(Object *ob)
+{
if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
Curve *cu = ob->data;
- int doit = 0;
-
- if (cu->bb == NULL) cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox");
- bb = cu->bb;
- for (dl = ob->disp.first; dl; dl = dl->next) {
- tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts;
- vert = dl->verts;
- for (a = 0; a < tot; a++, vert += 3) {
- minmax_v3v3_v3(min, max, vert);
- }
- doit = (tot != 0);
- }
+ /* calculate curve's BB based on non-deformed displist */
+ if (cu->bb == NULL)
+ cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox");
- if (!doit) {
- /* there's no geometry in displist, use zero-sized boundbox */
- zero_v3(min);
- zero_v3(max);
- }
+ boundbox_dispbase(cu->bb, &cu->disp);
- }
+ /* object's BB is calculated from final displist */
+ if (ob->bb == NULL)
+ ob->bb = MEM_callocN(sizeof(BoundBox), "boundbox");
- if (bb) {
- BKE_boundbox_init_from_minmax(bb, min, max);
+ boundbox_dispbase(ob->bb, &ob->disp);
}
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index ed85e5b627b..685d66195c7 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -397,7 +397,7 @@ void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface)
}
else {
strcpy(surface->output_name, "dp_");
- strcpy(surface->output_name2, surface->output_name);
+ BLI_strncpy(surface->output_name2, surface->output_name, sizeof(surface->output_name2));
surface->flags &= ~MOD_DPAINT_ANTIALIAS;
surface->depth_clamp = 0.0f;
}
@@ -529,7 +529,7 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, float fram
/* also update constraint targets */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
@@ -687,7 +687,7 @@ static void boundInsert(Bounds3D *b, float point[3])
static float getSurfaceDimension(PaintSurfaceData *sData)
{
Bounds3D *mb = &sData->bData->mesh_bounds;
- return MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
+ return max_fff((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
}
static void freeGrid(PaintSurfaceData *data)
@@ -754,14 +754,14 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
/* get dimensions */
sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min);
copy_v3_v3(td, dim);
- min_dim = MAX3(td[0], td[1], td[2]) / 1000.f;
+ min_dim = max_fff(td[0], td[1], td[2]) / 1000.f;
/* deactivate zero axises */
for (i = 0; i < 3; i++) {
if (td[i] < min_dim) { td[i] = 1.0f; axis -= 1; }
}
- if (axis == 0 || MAX3(td[0], td[1], td[2]) < 0.0001f) {
+ if (axis == 0 || max_fff(td[0], td[1], td[2]) < 0.0001f) {
MEM_freeN(grid_bounds);
MEM_freeN(bData->grid);
bData->grid = NULL;
@@ -1193,7 +1193,68 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn
/* Copy data */
if (tpmd->canvas) {
+ DynamicPaintSurface *surface;
tpmd->canvas->pmd = tpmd;
+ /* free default surface */
+ if (tpmd->canvas->surfaces.first)
+ dynamicPaint_freeSurface(tpmd->canvas->surfaces.first);
+
+ /* copy existing surfaces */
+ for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
+ DynamicPaintSurface *t_surface = dynamicPaint_createNewSurface(tpmd->canvas, NULL);
+
+ /* surface settings */
+ t_surface->brush_group = surface->brush_group;
+ MEM_freeN(t_surface->effector_weights);
+ t_surface->effector_weights = MEM_dupallocN(surface->effector_weights);
+
+ BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name));
+ t_surface->format = surface->format;
+ t_surface->type = surface->type;
+ t_surface->disp_type = surface->disp_type;
+ t_surface->image_fileformat = surface->image_fileformat;
+ t_surface->effect_ui = surface->effect_ui;
+ t_surface->preview_id = surface->preview_id;
+ t_surface->init_color_type = surface->init_color_type;
+ t_surface->flags = surface->flags;
+ t_surface->effect = surface->effect;
+
+ t_surface->image_resolution = surface->image_resolution;
+ t_surface->substeps = surface->substeps;
+ t_surface->start_frame = surface->start_frame;
+ t_surface->end_frame = surface->end_frame;
+
+ copy_v4_v4(t_surface->init_color, surface->init_color);
+ t_surface->init_texture = surface->init_texture;
+ BLI_strncpy(t_surface->init_layername, surface->init_layername, sizeof(t_surface->init_layername));
+
+ t_surface->dry_speed = surface->dry_speed;
+ t_surface->diss_speed = surface->diss_speed;
+ t_surface->color_dry_threshold = surface->color_dry_threshold;
+ t_surface->depth_clamp = surface->depth_clamp;
+ t_surface->disp_factor = surface->disp_factor;
+
+
+ t_surface->spread_speed = surface->spread_speed;
+ t_surface->color_spread_speed = surface->color_spread_speed;
+ t_surface->shrink_speed = surface->shrink_speed;
+ t_surface->drip_vel = surface->drip_vel;
+ t_surface->drip_acc = surface->drip_acc;
+
+ t_surface->influence_scale = surface->influence_scale;
+ t_surface->radius_scale = surface->radius_scale;
+
+ t_surface->wave_damping = surface->wave_damping;
+ t_surface->wave_speed = surface->wave_speed;
+ t_surface->wave_timescale = surface->wave_timescale;
+ t_surface->wave_spring = surface->wave_spring;
+
+ BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name));
+ BLI_strncpy(t_surface->image_output_path, surface->image_output_path, sizeof(t_surface->image_output_path));
+ BLI_strncpy(t_surface->output_name, surface->output_name, sizeof(t_surface->output_name));
+ BLI_strncpy(t_surface->output_name2, surface->output_name2, sizeof(t_surface->output_name2));
+ }
+ dynamicPaint_resetPreview(tpmd->canvas);
}
else if (tpmd->brush) {
DynamicPaintBrushSettings *brush = pmd->brush, *t_brush = tpmd->brush;
@@ -1422,7 +1483,9 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface)
/* for vertex surface loop through tfaces and find uv color
* that provides highest alpha */
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
- #pragma omp parallel for schedule(static)
+ struct ImagePool *pool = BKE_image_pool_new();
+
+ #pragma omp parallel for schedule(static) shared(pool)
for (i = 0; i < numOfFaces; i++) {
int numOfVert = (mface[i].v4) ? 4 : 3;
float uv[3] = {0.0f};
@@ -1435,7 +1498,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface)
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);
+ multitex_ext_safe(tex, uv, &texres, pool);
if (texres.tin > pPoint[*vert].alpha) {
copy_v3_v3(pPoint[*vert].color, &texres.tr);
@@ -1443,6 +1506,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface)
}
}
}
+ BKE_image_pool_free(pool);
}
else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data;
@@ -1468,7 +1532,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface)
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);
+ multitex_ext_safe(tex, uv_final, &texres, NULL);
/* apply color */
copy_v3_v3(pPoint[i].color, &texres.tr);
@@ -2315,7 +2379,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
dot11 = d2[0] * d2[0] + d2[1] * d2[1];
dot12 = d2[0] * d3[0] + d2[1] * d3[1];
- invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ invDenom = (dot00 * dot11 - dot01 * dot01);
+ invDenom = invDenom ? 1.0f / invDenom : 1.0f;
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
@@ -2335,7 +2400,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
dot11 = d2[0] * d2[0] + d2[1] * d2[1];
dot12 = d2[0] * d3[0] + d2[1] * d3[1];
- invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ invDenom = (dot00 * dot11 - dot01 * dot01);
+ invDenom = invDenom ? 1.0f / invDenom : 1.0f;
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
@@ -2628,7 +2694,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(output_file, format);
+ BKE_add_image_extension_from_type(output_file, format);
/* Validate output file path */
BLI_path_abs(output_file, G.main->name);
@@ -2778,7 +2844,9 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats)
/*
* Get material diffuse color and alpha (including linked textures) in given coordinates
*/
-static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm)
+static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb,
+ const float volume_co[3], const float surface_co[3],
+ int faceIndex, short isQuad, DerivedMesh *orcoDm)
{
Material *mat = bMats->mat;
MFace *mface = orcoDm->getTessFaceArray(orcoDm);
@@ -4199,7 +4267,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
if (surface->effect & MOD_DPAINT_EFFECT_DO_SHRINK)
shrink_speed = surface->shrink_speed;
- fastest_effect = MAX3(spread_speed, shrink_speed, average_force);
+ fastest_effect = max_fff(spread_speed, shrink_speed, average_force);
avg_dist = bData->average_dist * CANVAS_REL_SIZE / getSurfaceDimension(sData);
steps = (int)ceil(1.5f * EFF_MOVEMENT_PER_FRAME * fastest_effect / avg_dist * timescale);
@@ -4383,8 +4451,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
float dt, min_dist, damp_factor;
float wave_speed = surface->wave_speed;
double average_dist = 0.0f;
- Bounds3D *mb = &sData->bData->mesh_bounds;
- float canvas_size = MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
+ const float canvas_size = getSurfaceDimension(sData);
float wave_scale = CANVAS_REL_SIZE / canvas_size;
/* allocate memory */
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 321a61ce238..11c05772962 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -39,8 +39,8 @@
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
@@ -69,26 +69,26 @@
extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
-BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate)
+BMEditMesh *BMEdit_Create(BMesh *bm, const bool do_tessellate)
{
- BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), __func__);
+ BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__);
- tm->bm = bm;
+ em->bm = bm;
if (do_tessellate) {
- BMEdit_RecalcTessellation(tm);
+ BMEdit_RecalcTessellation(em);
}
- return tm;
+ return em;
}
-BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
+BMEditMesh *BMEdit_Copy(BMEditMesh *em)
{
- BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), __func__);
- *tm2 = *tm;
+ BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__);
+ *em_copy = *em;
- tm2->derivedCage = tm2->derivedFinal = NULL;
+ em_copy->derivedCage = em_copy->derivedFinal = NULL;
- tm2->bm = BM_mesh_copy(tm->bm);
+ em_copy->bm = BM_mesh_copy(em->bm);
/* The tessellation is NOT calculated on the copy here,
* because currently all the callers of this function use
@@ -97,55 +97,59 @@ BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
* reasons, in that case it makes more sense to do the
* tessellation only when/if that copy ends up getting
* used.*/
- tm2->looptris = NULL;
+ em_copy->looptris = NULL;
- tm2->vert_index = NULL;
- tm2->edge_index = NULL;
- tm2->face_index = NULL;
+ em_copy->vert_index = NULL;
+ em_copy->edge_index = NULL;
+ em_copy->face_index = NULL;
- return tm2;
+ return em_copy;
}
-static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
+static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
{
/* use this to avoid locking pthread for _every_ polygon
* and calling the fill function */
#define USE_TESSFACE_SPEEDUP
- BMesh *bm = tm->bm;
- BMLoop *(*looptris)[3] = NULL;
- BLI_array_declare(looptris);
- BMIter iter, liter;
+ BMesh *bm = em->bm;
+
+ /* this assumes all faces can be scan-filled, which isn't always true,
+ * worst case we over alloc a little which is acceptable */
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ const int looptris_tot_prev_alloc = em->looptris ? (MEM_allocN_len(em->looptris) / sizeof(*em->looptris)) : 0;
+
+ BMLoop *(*looptris)[3];
+ BMIter iter;
BMFace *efa;
BMLoop *l;
- int i = 0, j;
+ int i = 0;
ScanFillContext sf_ctx;
#if 0
/* note, we could be clever and re-use this array but would need to ensure
* its realloced at some point, for now just free it */
- if (tm->looptris) MEM_freeN(tm->looptris);
+ if (em->looptris) MEM_freeN(em->looptris);
- /* Use tm->tottri when set, this means no reallocs while transforming,
+ /* Use em->tottri when set, this means no reallocs while transforming,
* (unless scanfill fails), otherwise... */
/* allocate the length of totfaces, avoid many small reallocs,
* if all faces are tri's it will be correct, quads == 2x allocs */
- BLI_array_reserve(looptris, (tm->tottri && tm->tottri < bm->totface * 3) ? tm->tottri : bm->totface);
+ BLI_array_reserve(looptris, (em->tottri && em->tottri < bm->totface * 3) ? em->tottri : bm->totface);
#else
/* this means no reallocs for quad dominant models, for */
- if ( (tm->looptris != NULL) &&
- (tm->tottri != 0) &&
- /* (totrti <= bm->totface * 2) would be fine for all quads,
- * but in case there are some ngons, still re-use the array */
- (tm->tottri <= bm->totface * 3))
+ if ((em->looptris != NULL) &&
+ /* (em->tottri >= looptris_tot)) */
+ /* check against alloc'd size incase we over alloc'd a little */
+ ((looptris_tot_prev_alloc >= looptris_tot) && (looptris_tot_prev_alloc <= looptris_tot * 2)))
{
- looptris = tm->looptris;
+ looptris = em->looptris;
}
else {
- if (tm->looptris) MEM_freeN(tm->looptris);
- BLI_array_reserve(looptris, bm->totface);
+ if (em->looptris) MEM_freeN(em->looptris);
+ looptris = MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__);
}
#endif
@@ -161,16 +165,25 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
/* no need to ensure the loop order, we know its ok */
else if (efa->len == 3) {
- BLI_array_grow_one(looptris);
+#if 0
+ int j;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
looptris[i][j] = l;
}
i += 1;
+#else
+ /* more cryptic but faster */
+ BMLoop **l_ptr = looptris[i++];
+ l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
+ l_ptr[1] = l = l->next;
+ l_ptr[2] = l->next;
+#endif
}
else if (efa->len == 4) {
+#if 0
BMLoop *ltmp[4];
+ int j;
BLI_array_grow_items(looptris, 2);
-
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
ltmp[j] = l;
}
@@ -184,11 +197,24 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
looptris[i][1] = ltmp[2];
looptris[i][2] = ltmp[3];
i += 1;
+#else
+ /* more cryptic but faster */
+ BMLoop **l_ptr_a = looptris[i++];
+ BMLoop **l_ptr_b = looptris[i++];
+ (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa));
+ (l_ptr_a[1] = l = l->next);
+ (l_ptr_a[2] = l_ptr_b[1] = l = l->next);
+ ( l_ptr_b[2] = l->next);
+#endif
}
#endif /* USE_TESSFACE_SPEEDUP */
else {
+ int j;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL;
/* ScanFillEdge *e; */ /* UNUSED */
ScanFillFace *sf_tri;
@@ -197,28 +223,35 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
BLI_scanfill_begin(&sf_ctx);
/* scanfill time */
- BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
- /*mark order */
- BM_elem_index_set(l, j); /* set_loop */
-
- sf_vert = BLI_scanfill_vert_add(&sf_ctx, l->v->co);
- sf_vert->tmp.p = l;
+ j = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co);
+ sf_vert->tmp.p = l_iter;
if (sf_vert_last) {
/* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
}
sf_vert_last = sf_vert;
- if (sf_vert_first == NULL) sf_vert_first = sf_vert;
- }
+ if (sf_vert_first == NULL) {
+ sf_vert_first = sf_vert;
+ }
+
+ /*mark order */
+ BM_elem_index_set(l_iter, j++); /* set_loop */
+
+ } while ((l_iter = l_iter->next) != l_first);
/* complete the loop */
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
- BLI_array_grow_items(looptris, totfilltri);
+ BLI_assert(totfilltri <= efa->len - 2);
+ (void)totfilltri;
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
+ BMLoop **l_ptr = looptris[i++];
BMLoop *l1 = sf_tri->v1->tmp.p;
BMLoop *l2 = sf_tri->v2->tmp.p;
BMLoop *l3 = sf_tri->v3->tmp.p;
@@ -227,18 +260,19 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
if (BM_elem_index_get(l2) > BM_elem_index_get(l3)) { SWAP(BMLoop *, l2, l3); }
if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop *, l1, l2); }
- looptris[i][0] = l1;
- looptris[i][1] = l2;
- looptris[i][2] = l3;
- i += 1;
+ l_ptr[0] = l1;
+ l_ptr[1] = l2;
+ l_ptr[2] = l3;
}
BLI_scanfill_end(&sf_ctx);
}
}
- tm->tottri = i;
- tm->looptris = looptris;
+ em->tottri = i;
+ em->looptris = looptris;
+
+ BLI_assert(em->tottri <= looptris_tot);
#undef USE_TESSFACE_SPEEDUP
@@ -749,22 +783,18 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
if (poly_prev != GL_ZERO) glEnd();
}
-static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3],
- int has_uv, int has_col)
+static void bmdm_get_tri_uv(BMLoop *ls[3], MLoopUV *luv[3], const int cd_loop_uv_offset)
{
- if (has_uv) {
- luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV);
- luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV);
- luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV);
- }
-
- if (has_col) {
- lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL);
- lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL);
- lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL);
- }
-
+ luv[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_uv_offset);
+ luv[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_uv_offset);
+ luv[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_uv_offset);
+}
+static void bmdm_get_tri_col(BMLoop *ls[3], MLoopCol *lcol[3], const int cd_loop_color_offset)
+{
+ lcol[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_color_offset);
+ lcol[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_color_offset);
+ lcol[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_color_offset);
}
static void emDM_drawFacesTex_common(DerivedMesh *dm,
@@ -780,15 +810,19 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
float (*vertexNos)[3] = bmdm->vertexNos;
BMFace *efa;
MLoopUV *luv[3], dummyluv = {{0}};
- MLoopCol *lcol[3] = {NULL}, dummylcol = {0};
- int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
- int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
+ MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
+ const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+ bool has_uv = (cd_loop_uv_offset != -1);
+ bool has_vcol = (cd_loop_color_offset != -1);
+ int i;
(void) compareDrawOptions;
luv[0] = luv[1] = luv[2] = &dummyluv;
- dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255;
+ // dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; /* UNUSED */
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
@@ -800,7 +834,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
for (i = 0; i < em->tottri; i++) {
BMLoop **ls = em->looptris[i];
- MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
+ MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
@@ -808,7 +842,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
efa = ls[0]->f;
- if (has_uv) {
+ if (cd_poly_tex_offset != -1) {
ME_MTEXFACE_CPY(&mtf, tp);
}
@@ -825,25 +859,27 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (!drawSmooth) {
glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]);
glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]);
glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
}
else {
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
glTexCoord2fv(luv[0]->uv);
if (lcol[0])
@@ -872,7 +908,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
for (i = 0; i < em->tottri; i++) {
BMLoop **ls = em->looptris[i];
- MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
+ MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
@@ -880,12 +916,12 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
efa = ls[0]->f;
- if (has_uv) {
+ if (cd_poly_tex_offset != -1) {
ME_MTEXFACE_CPY(&mtf, tp);
}
if (drawParams)
- draw_option = drawParams(&mtf, has_vcol, efa->mat_nr);
+ draw_option = drawParams(&mtf, (has_vcol), efa->mat_nr);
else if (drawParamsMapped)
draw_option = drawParamsMapped(userData, BM_elem_index_get(efa));
else
@@ -897,46 +933,42 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (!drawSmooth) {
glNormal3fv(efa->no);
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
- if (luv[0])
- glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ glTexCoord2fv(luv[0]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glVertex3fv(ls[0]->v->co);
- if (luv[1])
- glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ glTexCoord2fv(luv[1]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glVertex3fv(ls[1]->v->co);
- if (luv[2])
- glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ glTexCoord2fv(luv[2]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glVertex3fv(ls[2]->v->co);
}
else {
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
- if (luv[0])
- glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ glTexCoord2fv(luv[0]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glNormal3fv(ls[0]->v->no);
glVertex3fv(ls[0]->v->co);
- if (luv[1])
- glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ glTexCoord2fv(luv[1]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glNormal3fv(ls[1]->v->no);
glVertex3fv(ls[1]->v->co);
- if (luv[2])
- glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ glTexCoord2fv(luv[2]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glNormal3fv(ls[2]->v->no);
glVertex3fv(ls[2]->v->co);
@@ -965,6 +997,43 @@ static void emDM_drawMappedFacesTex(DerivedMesh *dm,
emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
}
+/**
+ * \note
+ *
+ * For UV's:
+ * const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
+ *
+ * This is intentionally different to calling:
+ * CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, i);
+ *
+ * ... because the material may use layer names to select different UV's
+ * see: [#34378]
+ */
+static void emdm_pass_attrib_vertex_glsl(DMVertexAttribs *attribs, BMLoop *loop, int index_in_face)
+{
+ BMVert *eve = loop->v;
+ int i;
+
+ if (attribs->totorco) {
+ const float *orco = attribs->orco.array[BM_elem_index_get(eve)];
+ glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
+ }
+ for (i = 0; i < attribs->tottface; i++) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
+ glVertexAttrib2fvARB(attribs->tface[i].gl_index, luv->uv);
+ }
+ for (i = 0; i < attribs->totmcol; i++) {
+ const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
+ GLubyte col[4];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ glVertexAttrib4ubvARB(attribs->mcol[i].gl_index, col);
+ }
+ if (attribs->tottang) {
+ const float *tang = attribs->tang.array[i * 4 + index_in_face];
+ glVertexAttrib3fvARB(attribs->tang.gl_index, tang);
+ }
+}
+
static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
DMSetMaterial setMaterial,
DMSetDrawOptions setDrawOptions,
@@ -980,7 +1049,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
DMVertexAttribs attribs;
GPUVertexAttribs gattribs;
- int i, b, matnr, new_matnr, do_draw;
+ int i, matnr, new_matnr, do_draw;
do_draw = FALSE;
matnr = -1;
@@ -991,30 +1060,6 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glShadeModel(GL_SMOOTH);
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
-#define PASSATTRIB(loop, eve, vert) { \
- if (attribs.totorco) { \
- float *orco = attribs.orco.array[BM_elem_index_get(eve)]; \
- glVertexAttrib3fvARB(attribs.orco.gl_index, orco); \
- } \
- for (b = 0; b < attribs.tottface; b++) { \
- MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPUV, b); \
- glVertexAttrib2fvARB(attribs.tface[b].gl_index, _luv->uv); \
- } \
- for (b = 0; b < attribs.totmcol; b++) { \
- MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPCOL, b); \
- GLubyte _col[4]; \
- _col[0] = _cp->b; _col[1] = _cp->g; _col[2] = _cp->r; _col[3] = _cp->a; \
- glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, _col); \
- } \
- if (attribs.tottang) { \
- float *tang = attribs.tang.array[i * 4 + vert]; \
- glVertexAttrib3fvARB(attribs.tang.gl_index, tang); \
- } \
- } (void)0
-
-
for (i = 0, ltri = em->looptris[0]; i < em->tottri; i++, ltri += 3) {
int drawSmooth;
@@ -1037,20 +1082,20 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
else glNormal3fv(efa->no);
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
else glVertex3fv(ltri[0]->v->co);
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
else glVertex3fv(ltri[1]->v->co);
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
else glVertex3fv(ltri[2]->v->co);
}
else {
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
@@ -1060,7 +1105,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glVertex3fv(ltri[0]->v->co);
}
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
@@ -1070,7 +1115,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glVertex3fv(ltri[1]->v->co);
}
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
@@ -1083,7 +1128,6 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glEnd();
}
}
-#undef PASSATTRIB
}
static void emDM_drawFacesGLSL(DerivedMesh *dm,
@@ -1092,6 +1136,38 @@ static void emDM_drawFacesGLSL(DerivedMesh *dm,
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
}
+/* emdm_pass_attrib_vertex_glsl's note about em_offset use applies here */
+static void emdm_pass_attrib_vertex_mat(DMVertexAttribs *attribs, BMLoop *loop, int index_in_face)
+{
+ BMVert *eve = loop->v;
+ int i;
+
+ if (attribs->totorco) {
+ float *orco = attribs->orco.array[BM_elem_index_get(eve)];
+ if (attribs->orco.gl_texco)
+ glTexCoord3fv(orco);
+ else
+ glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
+ }
+ for (i = 0; i < attribs->tottface; i++) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
+ if (attribs->tface[i].gl_texco)
+ glTexCoord2fv(luv->uv);
+ else
+ glVertexAttrib2fvARB(attribs->tface[i].gl_index, luv->uv);
+ }
+ for (i = 0; i < attribs->totmcol; i++) {
+ const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
+ GLubyte col[4];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ glVertexAttrib4ubvARB(attribs->mcol[i].gl_index, col);
+ }
+ if (attribs->tottang) {
+ float *tang = attribs->tang.array[i * 4 + index_in_face];
+ glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
+ }
+}
+
static void emDM_drawMappedFacesMat(DerivedMesh *dm,
void (*setMaterial)(void *userData, int, void *attribs),
int (*setFace)(void *userData, int index), void *userData)
@@ -1105,7 +1181,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
BMLoop **ltri;
DMVertexAttribs attribs = {{{0}}};
GPUVertexAttribs gattribs;
- int i, b, matnr, new_matnr;
+ int i, matnr, new_matnr;
matnr = -1;
@@ -1114,35 +1190,6 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
-#define PASSATTRIB(loop, eve, vert) { \
- if (attribs.totorco) { \
- float *orco = attribs.orco.array[BM_elem_index_get(eve)]; \
- if (attribs.orco.gl_texco) \
- glTexCoord3fv(orco); \
- else \
- glVertexAttrib3fvARB(attribs.orco.gl_index, orco); \
- } \
- for (b = 0; b < attribs.tottface; b++) { \
- MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPUV, b); \
- if (attribs.tface[b].gl_texco) \
- glTexCoord2fv(_luv->uv); \
- else \
- glVertexAttrib2fvARB(attribs.tface[b].gl_index, _luv->uv); \
- } \
- for (b = 0; b < attribs.totmcol; b++) { \
- MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPCOL, b); \
- GLubyte _col[4]; \
- _col[0] = _cp->b; _col[1] = _cp->g; _col[2] = _cp->r; _col[3] = _cp->a; \
- glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, _col); \
- } \
- if (attribs.tottang) { \
- float *tang = attribs.tang.array[i * 4 + vert]; \
- glVertexAttrib4fvARB(attribs.tang.gl_index, tang); \
- } \
- } (void)0
-
for (i = 0, ltri = em->looptris[0]; i < em->tottri; i++, ltri += 3) {
int drawSmooth;
@@ -1166,21 +1213,21 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
else glNormal3fv(efa->no);
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[0], 0);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
else glVertex3fv(ltri[0]->v->co);
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[1], 1);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
else glVertex3fv(ltri[1]->v->co);
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[2], 2);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
else glVertex3fv(ltri[2]->v->co);
}
else {
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[0], 0);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
@@ -1190,7 +1237,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
glVertex3fv(ltri[0]->v->co);
}
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[1], 1);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
@@ -1200,7 +1247,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
glVertex3fv(ltri[1]->v->co);
}
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[2], 2);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
@@ -1212,7 +1259,6 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
}
glEnd();
}
-#undef PASSATTRIB
}
static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
@@ -1276,14 +1322,16 @@ static int emDM_getNumPolys(DerivedMesh *dm)
static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
{
+ float *f;
+
copy_v3_v3(vert_r->co, ev->co);
normal_float_to_short_v3(vert_r->no, ev->no);
vert_r->flag = BM_vert_flag_to_mflag(ev);
- if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT) * 255.0f);
+ if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) {
+ vert_r->bweight = (unsigned char)((*f) * 255.0f);
}
return 1;
@@ -1299,8 +1347,8 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
return;
}
- // ev = EDBM_vert_at_index(bmdm->tc, index);
- ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
+ ev = bmdm->tc->vert_index[index]; /* should be EDBM_vert_at_index() */
+ // ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
bmvert_to_mvert(bmdm->tc->bm, ev, vert_r);
if (bmdm->vertexCos)
@@ -1312,27 +1360,27 @@ static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->tc->bm;
BMEdge *e;
+ float *f;
if (index < 0 || index >= bmdm->te) {
printf("error in emDM_getEdge.\n");
return;
}
- // e = EDBM_edge_at_index(bmdm->tc, index);
- e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
-
- if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
- edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) * 255.0f);
- }
-
- if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
- edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE) * 255.0f);
- }
+ e = bmdm->tc->edge_index[index]; /* should be EDBM_edge_at_index() */
+ // e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
edge_r->flag = BM_edge_flag_to_mflag(e);
edge_r->v1 = BM_elem_index_get(e->v1);
edge_r->v2 = BM_elem_index_get(e->v2);
+
+ if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) {
+ edge_r->bweight = (unsigned char)((*f) * 255.0f);
+ }
+ if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) {
+ edge_r->crease = (unsigned char)((*f) * 255.0f);
+ }
}
static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
@@ -1367,7 +1415,7 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
BMesh *bm = bmdm->tc->bm;
BMVert *eve;
BMIter iter;
- const int has_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
if (bmdm->vertexCos) {
int i;
@@ -1377,9 +1425,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
normal_float_to_short_v3(vert_r->no, eve->no);
vert_r->flag = BM_vert_flag_to_mflag(eve);
- if (has_bweight) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
- }
+ vert_r->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
+
vert_r++;
}
}
@@ -1389,9 +1436,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
normal_float_to_short_v3(vert_r->no, eve->no);
vert_r->flag = BM_vert_flag_to_mflag(eve);
- if (has_bweight) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
- }
+ vert_r->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
+
vert_r++;
}
}
@@ -1402,24 +1448,20 @@ static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
BMEdge *eed;
BMIter iter;
- const int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
- const int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
+
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (has_bweight) {
- edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
- }
-
- if (has_crease) {
- edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
- }
+ edge_r->v1 = BM_elem_index_get(eed->v1);
+ edge_r->v2 = BM_elem_index_get(eed->v2);
edge_r->flag = BM_edge_flag_to_mflag(eed);
- edge_r->v1 = BM_elem_index_get(eed->v1);
- edge_r->v2 = BM_elem_index_get(eed->v2);
+ edge_r->crease = (cd_edge_crease_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset) : 0;
+ edge_r->bweight = (cd_edge_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset) : 0;
edge_r++;
}
@@ -1442,6 +1484,7 @@ static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
face_r->mat_nr = (unsigned char) ef->mat_nr;
face_r->flag = BM_face_flag_to_mflag(ef);
+ face_r->edcode = 0;
face_r->v1 = BM_elem_index_get(l[0]->v);
face_r->v2 = BM_elem_index_get(l[1]->v);
@@ -1627,6 +1670,9 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert,
em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
+ /* could also get from the objects mesh directly */
+ bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
bmdm->dm.getVertCos = emDM_getVertCos;
bmdm->dm.getMinMax = emDM_getMinMax;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 1f6db19ac27..9e8693e957e 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -562,7 +562,7 @@ int closest_point_on_surface(SurfaceModifierData *surmd, const float co[3], floa
if (mface->v4)
add_v3_v3(surface_vel, surmd->v[mface->v4].co);
- mul_v3_fl(surface_vel, mface->v4 ? 0.25f : 0.333f);
+ mul_v3_fl(surface_vel, mface->v4 ? 0.25f : (1.0f / 3.0f));
}
return 1;
}
@@ -769,7 +769,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
mul_m4_v3(eff->ob->imat, tex_co);
}
- hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result);
+ hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL);
if (hasrgb && mode==PFIELD_TEX_RGB) {
force[0] = (0.5f - result->tr) * strength;
@@ -780,15 +780,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);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL);
tex_co[0] -= nabla;
tex_co[1] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL);
tex_co[1] -= nabla;
tex_co[2] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL);
if (mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we don't have rgb fall back to grad */
/* generate intensity if texture only has rgb value */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index ec61311d89e..23f3a3ad3fd 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -500,8 +500,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
BLI_assert(bezt_last != NULL);
if (include_handles) {
- xminv = MIN3(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]);
- xmaxv = MAX3(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
+ xminv = min_fff(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]);
+ xmaxv = max_fff(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
}
else {
xminv = min_ff(xminv, bezt_first->vec[1][0]);
@@ -517,8 +517,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
if ((do_sel_only == FALSE) || BEZSELECTED(bezt)) {
if (include_handles) {
- yminv = MIN4(yminv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
- ymaxv = MAX4(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
+ yminv = min_ffff(yminv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
+ ymaxv = max_ffff(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
}
else {
yminv = min_ff(yminv, bezt->vec[1][1]);
@@ -859,7 +859,7 @@ void testhandles_fcurve(FCurve *fcu, const short use_handle)
short flag = 0;
/* flag is initialized as selection status
- * of beztriple control-points (labelled 0,1,2)
+ * of beztriple control-points (labelled 0, 1, 2)
*/
if (bezt->f2 & SELECT) flag |= (1 << 1); // == 2
if (use_handle == FALSE) {
@@ -1192,7 +1192,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);
- 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);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1217,7 +1217,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);
- 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);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1288,7 +1288,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);
- 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);
}
else {
/* specially calculate local matrix, since chan_mat is not valid
@@ -1315,7 +1315,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);
- 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);
}
else {
/* transforms to matrix */
@@ -2022,12 +2022,12 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
}
else {
/* bezier interpolation */
- /* v1,v2 are the first keyframe and its 2nd handle */
+ /* (v1, v2) are the first keyframe and its 2nd handle */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
v2[0] = prevbezt->vec[2][0];
v2[1] = prevbezt->vec[2][1];
- /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
+ /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
v3[0] = bezt->vec[0][0];
v3[1] = bezt->vec[0][1];
v4[0] = bezt->vec[1][0];
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 2b393b4d90b..c3fc659137d 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -141,55 +141,34 @@ static void fcm_generator_verify(FModifier *fcm)
switch (data->mode) {
case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */
{
+ const int arraysize_new = data->poly_order + 1;
/* arraysize needs to be order+1, so resize if not */
- if (data->arraysize != (data->poly_order + 1)) {
- float *nc;
-
- /* make new coefficients array, and copy over as much data as can fit */
- nc = MEM_callocN(sizeof(float) * (data->poly_order + 1), "FMod_Generator_Coefs");
-
+ if (data->arraysize != arraysize_new) {
if (data->coefficients) {
- if ((int)data->arraysize > (data->poly_order + 1))
- memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order + 1));
- else
- memcpy(nc, data->coefficients, sizeof(float) * data->arraysize);
-
- /* free the old data */
- MEM_freeN(data->coefficients);
+ data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
}
-
- /* set the new data */
- data->coefficients = nc;
- data->arraysize = data->poly_order + 1;
+ else {
+ data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
+ }
+ data->arraysize = arraysize_new;
}
+ break;
}
- break;
-
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */
{
- /* arraysize needs to be 2*order, so resize if not */
- if (data->arraysize != (data->poly_order * 2)) {
- float *nc;
-
- /* make new coefficients array, and copy over as much data as can fit */
- nc = MEM_callocN(sizeof(float) * (data->poly_order * 2), "FMod_Generator_Coefs");
-
+ const int arraysize_new = data->poly_order * 2;
+ /* arraysize needs to be (2 * order), so resize if not */
+ if (data->arraysize != arraysize_new) {
if (data->coefficients) {
- if (data->arraysize > (unsigned int)(data->poly_order * 2))
- memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order * 2));
- else
- memcpy(nc, data->coefficients, sizeof(float) * data->arraysize);
-
- /* free the old data */
- MEM_freeN(data->coefficients);
+ data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
}
-
- /* set the new data */
- data->coefficients = nc;
- data->arraysize = data->poly_order * 2;
+ else {
+ data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
+ }
+ data->arraysize = arraysize_new;
}
+ break;
}
- break;
}
}
@@ -501,6 +480,92 @@ static FModifierTypeInfo FMI_ENVELOPE = {
fcm_envelope_evaluate /* evaluate */
};
+/* exported function for finding points */
+
+/* Binary search algorithm for finding where to insert Envelope Data Point.
+ * Returns the index to insert at (data already at that index will be offset if replace is 0)
+ */
+#define BINARYSEARCH_FRAMEEQ_THRESH 0.0001f
+
+int BKE_fcm_envelope_find_index(FCM_EnvelopeData array[], float frame, int arraylen, short *exists)
+{
+ int start = 0, end = arraylen;
+ int loopbreaker = 0, maxloop = arraylen * 2;
+
+ /* initialize exists-flag first */
+ *exists = 0;
+
+ /* sneaky optimizations (don't go through searching process if...):
+ * - keyframe to be added is to be added out of current bounds
+ * - keyframe to be added would replace one of the existing ones on bounds
+ */
+ if ((arraylen <= 0) || (array == NULL)) {
+ printf("Warning: binarysearch_fcm_envelopedata_index() encountered invalid array\n");
+ return 0;
+ }
+ else {
+ /* check whether to add before/after/on */
+ float framenum;
+
+ /* 'First' Point (when only one point, this case is used) */
+ framenum = array[0].time;
+ if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *exists = 1;
+ return 0;
+ }
+ else if (frame < framenum) {
+ return 0;
+ }
+
+ /* 'Last' Point */
+ framenum = array[(arraylen - 1)].time;
+ if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *exists = 1;
+ return (arraylen - 1);
+ }
+ else if (frame > framenum) {
+ return arraylen;
+ }
+ }
+
+
+ /* most of the time, this loop is just to find where to put it
+ * - 'loopbreaker' is just here to prevent infinite loops
+ */
+ for (loopbreaker = 0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
+ /* compute and get midpoint */
+ int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
+ float midfra = array[mid].time;
+
+ /* check if exactly equal to midpoint */
+ if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *exists = 1;
+ return mid;
+ }
+
+ /* repeat in upper/lower half */
+ if (frame > midfra) {
+ start = mid + 1;
+ }
+ else if (frame < midfra) {
+ end = mid - 1;
+ }
+ }
+
+ /* print error if loop-limit exceeded */
+ if (loopbreaker == (maxloop - 1)) {
+ printf("Error: binarysearch_fcm_envelopedata_index() was taking too long\n");
+
+ // include debug info
+ printf("\tround = %d: start = %d, end = %d, arraylen = %d\n", loopbreaker, start, end, arraylen);
+ }
+
+ /* not found, so return where to place it */
+ return start;
+}
+#undef BINARYSEARCH_FRAMEEQ_THRESH
+
+
/* Cycles F-Curve Modifier --------------------------- */
/* This modifier changes evaltime to something that exists within the curve's frame-range,
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index d4634748c71..3e1e55132d8 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -962,9 +962,9 @@ makebreak:
float si, co;
ct = chartransdata + cu->pos;
- si = (float)sin(ct->rot);
- co = (float)cos(ct->rot);
-
+ si = sinf(ct->rot);
+ co = cosf(ct->rot);
+
f = cu->editfont->textcurs[0];
f[0] = cu->fsize * (-0.1f * co + ct->xof);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index a7d0152a799..755030bd208 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -183,12 +183,12 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive)
gpl->thickness = 3;
/* auto-name */
- strcpy(gpl->info, name);
+ BLI_strncpy(gpl->info, name, sizeof(gpl->info));
BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
/* make this one the active one */
if (setactive)
- gpencil_layer_setactive(gpd, gpl);
+ gpencil_layer_setactive(gpd, gpl);
/* return layer */
return gpl;
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 20d874e7243..639d256a067 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -127,11 +127,11 @@ void BKE_group_unlink(Group *group)
group->id.us = 0;
}
-Group *add_group(const char *name)
+Group *add_group(Main *bmain, const char *name)
{
Group *group;
- group = BKE_libblock_alloc(&G.main->group, ID_GR, name);
+ group = BKE_libblock_alloc(&bmain->group, ID_GR, name);
group->layer = (1 << 20) - 1;
return group;
}
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index d8c3e260399..9c265814b8f 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -51,6 +51,8 @@
#include "BLO_sys_types.h" // for intptr_t support
+#include "GPU_extensions.h"
+
/* GLOBALS */
static GHash *gIcons = NULL;
@@ -138,7 +140,10 @@ void BKE_previewimg_freefunc(void *link)
MEM_freeN(prv->rect[i]);
prv->rect[i] = NULL;
}
+ if (prv->gputexture[i])
+ GPU_texture_free(prv->gputexture[i]);
}
+
MEM_freeN(prv);
}
}
@@ -165,6 +170,7 @@ PreviewImage *BKE_previewimg_copy(PreviewImage *prv)
else {
prv_img->rect[i] = NULL;
}
+ prv_img->gputexture[i] = NULL;
}
}
return prv_img;
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 5dd0f08dc71..19ef1e3971d 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -27,7 +27,6 @@
* \ingroup bke
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -455,7 +454,7 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
if (strcmp(loop->name, prop->name) == 0) {
IDProperty *copy = IDP_CopyProperty(prop);
- BLI_insertlink(&dest->data.group, loop, copy);
+ BLI_insertlinkafter(&dest->data.group, loop, copy);
BLI_remlink(&dest->data.group, loop);
IDP_FreeProperty(loop);
@@ -480,7 +479,7 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
{
IDProperty *loop;
if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) {
- BLI_insertlink(&group->data.group, loop, prop);
+ BLI_insertlinkafter(&group->data.group, loop, prop);
BLI_remlink(&group->data.group, loop);
IDP_FreeProperty(loop);
@@ -533,7 +532,7 @@ int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew)
{
if (IDP_GetPropertyFromGroup(group, pnew->name) == NULL) {
group->len++;
- BLI_insertlink(&group->data.group, previous, pnew);
+ BLI_insertlinkafter(&group->data.group, previous, pnew);
return 1;
}
@@ -663,7 +662,7 @@ int IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const int is_s
{
IDProperty *link1, *link2;
- if (is_strict && BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group))
+ if (is_strict && prop1->len != prop2->len)
return 0;
for (link1 = prop1->data.group.first; link1; link1 = link1->next) {
@@ -815,6 +814,13 @@ void IDP_FreeProperty(IDProperty *prop)
}
}
+void IDP_ClearProperty(IDProperty *prop)
+{
+ IDP_FreeProperty(prop);
+ prop->data.pointer = NULL;
+ prop->len = prop->totallen = 0;
+}
+
/* Unlinks any IDProperty<->ID linkage that might be going on.
* note: currently unused.*/
void IDP_UnlinkProperty(IDProperty *prop)
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index f09f128e874..3655afdf088 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -68,7 +68,6 @@
#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BKE_bmfont.h"
#include "BKE_colortools.h"
@@ -243,11 +242,11 @@ void BKE_image_free(Image *ima)
}
/* only image block itself */
-static Image *image_alloc(const char *name, short source, short type)
+static Image *image_alloc(Main *bmain, const char *name, short source, short type)
{
Image *ima;
- ima = BKE_libblock_alloc(&G.main->image, ID_IM, name);
+ ima = BKE_libblock_alloc(&bmain->image, ID_IM, name);
if (ima) {
ima->ok = IMA_OK;
@@ -313,10 +312,6 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
break;
ibuf->index = index;
- if (ima->flag & IMA_CM_PREDIVIDE)
- ibuf->flags |= IB_cm_predivide;
- else
- ibuf->flags &= ~IB_cm_predivide;
/* this function accepts (link == NULL) */
BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
@@ -328,9 +323,9 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
}
/* empty image block, of similar type and filename */
-Image *BKE_image_copy(Image *ima)
+Image *BKE_image_copy(Main *bmain, Image *ima)
{
- Image *nima = image_alloc(ima->id.name + 2, ima->source, ima->type);
+ Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type);
BLI_strncpy(nima->name, ima->name, sizeof(ima->name));
@@ -348,6 +343,9 @@ Image *BKE_image_copy(Image *ima)
BKE_color_managed_colorspace_settings_copy(&nima->colorspace_settings, &ima->colorspace_settings);
+ if (ima->packedfile)
+ nima->packedfile = dupPackedFile(ima->packedfile);
+
return nima;
}
@@ -438,7 +436,7 @@ void BKE_image_make_local(struct Image *ima)
extern_local_image(ima);
}
else if (is_local && is_lib) {
- Image *ima_new = BKE_image_copy(ima);
+ Image *ima_new = BKE_image_copy(bmain, ima);
ima_new->id.us = 0;
@@ -553,7 +551,41 @@ int BKE_image_scale(Image *image, int width, int height)
return (ibuf != NULL);
}
-Image *BKE_image_load(const char *filepath)
+static void image_init_color_management(Image *ima)
+{
+ ImBuf *ibuf;
+ char name[FILE_MAX];
+
+ BKE_image_user_file_path(NULL, ima, name);
+
+ /* will set input color space to image format default's */
+ ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, ima->colorspace_settings.name);
+
+ if (ibuf) {
+ if (ibuf->flags & IB_alphamode_premul)
+ ima->alpha_mode = IMA_ALPHA_PREMUL;
+ else
+ ima->alpha_mode = IMA_ALPHA_STRAIGHT;
+
+ IMB_freeImBuf(ibuf);
+ }
+}
+
+void BKE_image_alpha_mode_from_extension(Image *image)
+{
+ if (BLI_testextensie(image->name, ".exr") ||
+ BLI_testextensie(image->name, ".cin") ||
+ BLI_testextensie(image->name, ".dpx") ||
+ BLI_testextensie(image->name, ".hdr"))
+ {
+ image->alpha_mode = IMA_ALPHA_PREMUL;
+ }
+ else {
+ image->alpha_mode = IMA_ALPHA_STRAIGHT;
+ }
+}
+
+Image *BKE_image_load(Main *bmain, const char *filepath)
{
Image *ima;
int file, len;
@@ -561,7 +593,7 @@ Image *BKE_image_load(const char *filepath)
char str[FILE_MAX];
BLI_strncpy(str, filepath, sizeof(str));
- BLI_path_abs(str, G.main->name);
+ BLI_path_abs(str, bmain->name);
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
@@ -574,12 +606,14 @@ Image *BKE_image_load(const char *filepath)
while (len > 0 && filepath[len - 1] != '/' && filepath[len - 1] != '\\') len--;
libname = filepath + len;
- ima = image_alloc(libname, IMA_SRC_FILE, IMA_TYPE_IMAGE);
+ ima = image_alloc(bmain, libname, IMA_SRC_FILE, IMA_TYPE_IMAGE);
BLI_strncpy(ima->name, filepath, sizeof(ima->name));
if (BLI_testextensie_array(filepath, imb_ext_movie))
ima->source = IMA_SRC_MOVIE;
+ image_init_color_management(ima);
+
return ima;
}
@@ -614,7 +648,7 @@ Image *BKE_image_load_exists(const char *filepath)
}
}
- return BKE_image_load(filepath);
+ return BKE_image_load(G.main, filepath);
}
static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type,
@@ -667,17 +701,17 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
/* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */
IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
- ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ TRUE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
return ibuf;
}
/* adds new image block, creates ImBuf and initializes color */
-Image *BKE_image_add_generated(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4])
+Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4])
{
/* on save, type is changed to FILE in editsima.c */
- Image *ima = image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
+ Image *ima = image_alloc(bmain, name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
if (ima) {
ImBuf *ibuf;
@@ -703,7 +737,7 @@ Image *BKE_image_add_from_imbuf(ImBuf *ibuf)
/* on save, type is changed to FILE in editsima.c */
Image *ima;
- ima = image_alloc(BLI_path_basename(ibuf->name), IMA_SRC_FILE, IMA_TYPE_IMAGE);
+ ima = image_alloc(G.main, BLI_path_basename(ibuf->name), IMA_SRC_FILE, IMA_TYPE_IMAGE);
if (ima) {
BLI_strncpy(ima->name, ibuf->name, FILE_MAX);
@@ -887,7 +921,7 @@ void BKE_image_free_all_textures(void)
image_free_buffers(ima);
}
}
- /* printf("freed total %d MB\n", totsize/(1024*1024)); */
+ /* printf("freed total %d MB\n", totsize / (1024 * 1024)); */
}
/* except_frame is weak, only works for seqs without offset... */
@@ -938,7 +972,7 @@ int BKE_imtype_to_ftype(const char imtype)
return RADHDR;
#endif
else if (imtype == R_IMF_IMTYPE_PNG)
- return PNG;
+ return PNG | 90;
#ifdef WITH_DDS
else if (imtype == R_IMF_IMTYPE_DDS)
return DDS;
@@ -1120,6 +1154,8 @@ char BKE_imtype_valid_depths(const char imtype)
return R_IMF_CHAN_DEPTH_10;
case R_IMF_IMTYPE_JP2:
return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16;
+ case R_IMF_IMTYPE_PNG:
+ return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_16;
/* most formats are 8bit only */
default:
return R_IMF_CHAN_DEPTH_8;
@@ -1166,9 +1202,10 @@ char BKE_imtype_from_arg(const char *imtype_arg)
else return R_IMF_IMTYPE_INVALID;
}
-int BKE_add_image_extension(char *string, const char imtype)
+static int do_add_image_extension(char *string, const char imtype, const ImageFormatData *im_format)
{
const char *extension = NULL;
+ (void)im_format; /* may be unused, depends on build options */
if (imtype == R_IMF_IMTYPE_IRIS) {
if (!BLI_testextensie(string, ".rgb"))
@@ -1233,8 +1270,22 @@ int BKE_add_image_extension(char *string, const char imtype)
}
#ifdef WITH_OPENJPEG
else if (imtype == R_IMF_IMTYPE_JP2) {
- if (!BLI_testextensie(string, ".jp2"))
- extension = ".jp2";
+ if (im_format) {
+ if (im_format->jp2_codec == R_IMF_JP2_CODEC_JP2) {
+ if (!BLI_testextensie(string, ".jp2"))
+ extension = ".jp2";
+ }
+ else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
+ if (!BLI_testextensie(string, ".j2c"))
+ extension = ".j2c";
+ }
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in im_format->jp2_codec");
+ }
+ else {
+ if (!BLI_testextensie(string, ".jp2"))
+ extension = ".jp2";
+ }
}
#endif
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90, R_IMF_IMTYPE_QUICKTIME etc
@@ -1260,11 +1311,22 @@ int BKE_add_image_extension(char *string, const char imtype)
}
}
+int BKE_add_image_extension(char *string, const ImageFormatData *im_format)
+{
+ return do_add_image_extension(string, im_format->imtype, im_format);
+}
+
+int BKE_add_image_extension_from_type(char *string, const char imtype)
+{
+ return do_add_image_extension(string, imtype, NULL);
+}
+
void BKE_imformat_defaults(ImageFormatData *im_format)
{
memset(im_format, 0, sizeof(*im_format));
im_format->planes = R_IMF_PLANES_RGB;
im_format->imtype = R_IMF_IMTYPE_PNG;
+ im_format->depth = R_IMF_CHAN_DEPTH_8;
im_format->quality = 90;
im_format->compress = 90;
@@ -1289,9 +1351,13 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
im_format->imtype = R_IMF_IMTYPE_RADHDR;
#endif
- else if (ftype == PNG)
+ else if (ftype == PNG) {
im_format->imtype = R_IMF_IMTYPE_PNG;
+ if (custom_flags & PNG_16BIT)
+ im_format->depth = R_IMF_CHAN_DEPTH_16;
+ }
+
#ifdef WITH_DDS
else if (ftype == DDS)
im_format->imtype = R_IMF_IMTYPE_DDS;
@@ -1352,6 +1418,13 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
if (ftype & JP2_CINE_48FPS)
im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_48;
}
+
+ if (ftype & JP2_JP2)
+ im_format->jp2_codec = R_IMF_JP2_CODEC_JP2;
+ else if (ftype & JP2_J2K)
+ im_format->jp2_codec = R_IMF_JP2_CODEC_J2K;
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in file type");
}
#endif
@@ -1400,7 +1473,9 @@ static void timecode_simple_string(char *text, size_t text_size, const int cfra,
}
}
-/* could allow access externally - 512 is for long names, 64 is for id names */
+#define STAMP_NAME_SIZE ((MAX_ID_NAME - 2) + 16)
+/* could allow access externally - 512 is for long names,
+ * STAMP_NAME_SIZE is for id names, allowing them some room for description */
typedef struct StampData {
char file[512];
char note[512];
@@ -1408,12 +1483,13 @@ typedef struct StampData {
char marker[512];
char time[512];
char frame[512];
- char camera[64];
- char cameralens[64];
- char scene[64];
- char strip[64];
- char rendertime[64];
+ char camera[STAMP_NAME_SIZE];
+ char cameralens[STAMP_NAME_SIZE];
+ char scene[STAMP_NAME_SIZE];
+ char strip[STAMP_NAME_SIZE];
+ char rendertime[STAMP_NAME_SIZE];
} StampData;
+#undef STAMP_NAME_SIZE
static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int do_prefix)
{
@@ -1813,8 +1889,12 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
else if (ELEM5(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG, R_IMF_IMTYPE_H264, R_IMF_IMTYPE_THEORA, R_IMF_IMTYPE_XVID)) {
ibuf->ftype = PNG;
- if (imtype == R_IMF_IMTYPE_PNG)
+ if (imtype == R_IMF_IMTYPE_PNG) {
+ if (imf->depth == R_IMF_CHAN_DEPTH_16)
+ ibuf->ftype |= PNG_16BIT;
+
ibuf->ftype |= compress;
+ }
}
#ifdef WITH_DDS
@@ -1904,6 +1984,13 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
if (imf->jp2_flag & R_IMF_JP2_FLAG_CINE_48)
ibuf->ftype |= JP2_CINE_48FPS;
}
+
+ if (imf->jp2_codec == R_IMF_JP2_CODEC_JP2)
+ ibuf->ftype |= JP2_JP2;
+ else if (imf->jp2_codec == R_IMF_JP2_CODEC_J2K)
+ ibuf->ftype |= JP2_J2K;
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in im_format->jp2_codec");
}
#endif
else {
@@ -1954,7 +2041,8 @@ int BKE_imbuf_write_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, cons
}
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
+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)
{
if (string == NULL) return;
BLI_strncpy(string, base, FILE_MAX - 10); /* weak assumption */
@@ -1964,8 +2052,17 @@ void BKE_makepicstring(char *string, const char *base, const char *relbase, int
BLI_path_frame(string, frame, 4);
if (use_ext)
- BKE_add_image_extension(string, imtype);
+ do_add_image_extension(string, imtype, im_format);
+}
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const ImageFormatData *im_format, const short use_ext, const short use_frames)
+{
+ do_makepicstring(string, base, relbase, frame, im_format->imtype, im_format, use_ext, use_frames);
+}
+
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
+{
+ do_makepicstring(string, base, relbase, frame, imtype, NULL, use_ext, use_frames);
}
/* used by sequencer too */
@@ -2024,7 +2121,7 @@ Image *BKE_image_verify_viewer(int type, const char *name)
break;
if (ima == NULL)
- ima = image_alloc(name, IMA_SRC_VIEWER, type);
+ ima = image_alloc(G.main, name, IMA_SRC_VIEWER, type);
/* happens on reload, imagewindow cannot be image user when hidden*/
if (ima->id.us == 0)
@@ -2125,9 +2222,20 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
}
}
+#if 0
/* force reload on first use, but not for multilayer, that makes nodes and buttons in ui drawing fail */
if (ima->type != IMA_TYPE_MULTILAYER)
image_free_buffers(ima);
+#else
+ /* image buffers for non-sequence multilayer will share buffers with RenderResult,
+ * however sequence multilayer will own buffers. Such logic makes switching from
+ * single multilayer file to sequence completely instable
+ * since changes in nodes seems this workaround isn't needed anymore, all sockets
+ * are nicely detecting anyway, but freeing buffers always here makes multilayer
+ * sequences behave stable
+ */
+ image_free_buffers(ima);
+#endif
ima->ok = 1;
if (iuser)
@@ -2282,7 +2390,7 @@ void BKE_image_backup_render(Scene *scene, Image *ima)
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
{
const char *colorspace = ima->colorspace_settings.name;
- int predivide = ima->flag & IMA_CM_PREDIVIDE;
+ int predivide = ima->alpha_mode == IMA_ALPHA_PREMUL;
ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
@@ -2314,6 +2422,18 @@ static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
}
+static int imbuf_alpha_flags_for_image(Image *ima)
+{
+ int flag = 0;
+
+ if (ima->flag & IMA_IGNORE_ALPHA)
+ flag |= IB_ignore_alpha;
+ else if (ima->alpha_mode == IMA_ALPHA_PREMUL)
+ flag |= IB_alphamode_premul;
+
+ return flag;
+}
+
static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
{
struct ImBuf *ibuf;
@@ -2328,8 +2448,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
BKE_image_user_file_path(iuser, ima, name);
flag = IB_rect | IB_multilayer;
- if (ima->flag & IMA_DO_PREMUL)
- flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
/* read ibuf */
ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name);
@@ -2488,15 +2607,14 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
/* is there a PackedFile with this image ? */
if (ima->packedfile) {
flag = IB_rect | IB_multilayer;
- if (ima->flag & IMA_DO_PREMUL) flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, ima->packedfile->size, flag,
ima->colorspace_settings.name, "<packed data>");
}
else {
flag = IB_rect | IB_multilayer | IB_metadata;
- if (ima->flag & IMA_DO_PREMUL)
- flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
/* get the right string */
BKE_image_user_frame_calc(iuser, cfra, 0);
@@ -2633,6 +2751,14 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
if (rres.have_combined && layer == 0) {
/* pass */
}
+ else if (rect && layer == 0) {
+ /* rect32 is set when there's a Sequence pass, this pass seems
+ * to have layer=0 (this is from image_buttons.c)
+ * in this case we ignore float buffer, because it could have
+ * hung from previous pass which was float
+ */
+ rectf = NULL;
+ }
else if (rres.layers.first) {
RenderLayer *rl = BLI_findlink(&rres.layers, layer - (rres.have_combined ? 1 : 0));
if (rl) {
@@ -2716,20 +2842,33 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
ibuf->dither = dither;
- if (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) {
- ibuf->flags |= IB_cm_predivide;
- ima->flag |= IMA_CM_PREDIVIDE;
- }
- else {
- ibuf->flags &= ~IB_cm_predivide;
- ima->flag &= ~IMA_CM_PREDIVIDE;
- }
-
ima->ok = IMA_OK_LOADED;
return ibuf;
}
+static void image_get_fame_and_index(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
+{
+ int frame = 0, index = 0;
+
+ /* see if we already have an appropriate ibuf, with image source and type */
+ if (ima->source == IMA_SRC_MOVIE) {
+ frame = iuser ? iuser->framenr : ima->lastframe;
+ }
+ else if (ima->source == IMA_SRC_SEQUENCE) {
+ if (ima->type == IMA_TYPE_IMAGE) {
+ frame = iuser ? iuser->framenr : ima->lastframe;
+ }
+ else if (ima->type == IMA_TYPE_MULTILAYER) {
+ frame = iuser ? iuser->framenr : ima->lastframe;
+ index = iuser ? iuser->multi_index : IMA_NO_INDEX;
+ }
+ }
+
+ *frame_r = frame;
+ *index_r = index;
+}
+
static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
{
ImBuf *ibuf = NULL;
@@ -2785,6 +2924,21 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
return ibuf;
}
+BLI_INLINE int image_quick_test(Image *ima, ImageUser *iuser)
+{
+ if (ima == NULL)
+ return FALSE;
+
+ if (iuser) {
+ if (iuser->ok == 0)
+ return FALSE;
+ }
+ else if (ima->ok == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
/* Checks optional ImageUser and verifies/creates ImBuf.
*
* not thread-safe, so callee should worry about thread locks
@@ -2799,14 +2953,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
*lock_r = NULL;
/* quick reject tests */
- if (ima == NULL)
- return NULL;
-
- if (iuser) {
- if (iuser->ok == 0)
- return NULL;
- }
- else if (ima->ok == 0)
+ if (!image_quick_test(ima, iuser))
return NULL;
ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
@@ -2930,14 +3077,7 @@ int BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
ImBuf *ibuf;
/* quick reject tests */
- if (ima == NULL)
- return FALSE;
-
- if (iuser) {
- if (iuser->ok == 0)
- return FALSE;
- }
- else if (ima->ok == 0)
+ if (!image_quick_test(ima, iuser))
return FALSE;
ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL);
@@ -2956,6 +3096,122 @@ int BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
return ibuf != NULL;
}
+/* ******** Pool for image buffers ******** */
+
+typedef struct ImagePoolEntry {
+ struct ImagePoolEntry *next, *prev;
+ Image *image;
+ ImBuf *ibuf;
+ int index;
+ int frame;
+} ImagePoolEntry;
+
+typedef struct ImagePool {
+ ListBase image_buffers;
+} ImagePool;
+
+ImagePool *BKE_image_pool_new(void)
+{
+ ImagePool *pool = MEM_callocN(sizeof(ImagePool), "Image Pool");
+
+ return pool;
+}
+
+void BKE_image_pool_free(ImagePool *pool)
+{
+ ImagePoolEntry *entry, *next_entry;
+
+ /* use single lock to dereference all the image buffers */
+ BLI_spin_lock(&image_spin);
+
+ for (entry = pool->image_buffers.first; entry; entry = next_entry) {
+ next_entry = entry->next;
+
+ if (entry->ibuf)
+ IMB_freeImBuf(entry->ibuf);
+
+ MEM_freeN(entry);
+ }
+
+ BLI_spin_unlock(&image_spin);
+
+ MEM_freeN(pool);
+}
+
+BLI_INLINE ImBuf *image_pool_find_entry(ImagePool *pool, Image *image, int frame, int index, int *found)
+{
+ ImagePoolEntry *entry;
+
+ *found = FALSE;
+
+ for (entry = pool->image_buffers.first; entry; entry = entry->next) {
+ if (entry->image == image && entry->frame == frame && entry->index == index) {
+ *found = TRUE;
+ return entry->ibuf;
+ }
+ }
+
+ return NULL;
+}
+
+ImBuf *BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool)
+{
+ ImBuf *ibuf;
+ int index, frame, found;
+
+ if (!image_quick_test(ima, iuser))
+ return NULL;
+
+ if (pool == NULL) {
+ /* pool could be NULL, in this case use general acquire function */
+ return BKE_image_acquire_ibuf(ima, iuser, NULL);
+ }
+
+ image_get_fame_and_index(ima, iuser, &frame, &index);
+
+ ibuf = image_pool_find_entry(pool, ima, frame, index, &found);
+ if (found)
+ return ibuf;
+
+ BLI_spin_lock(&image_spin);
+
+ ibuf = image_pool_find_entry(pool, ima, frame, index, &found);
+
+ /* will also create entry even in cases image buffer failed to load,
+ * prevents trying to load the same buggy file multiple times
+ */
+ if (!found) {
+ ImagePoolEntry *entry;
+
+ ibuf = image_acquire_ibuf(ima, iuser, NULL);
+
+ if (ibuf)
+ IMB_refImBuf(ibuf);
+
+ entry = MEM_callocN(sizeof(ImagePoolEntry), "Image Pool Entry");
+ entry->image = ima;
+ entry->frame = frame;
+ entry->index = index;
+ entry->ibuf = ibuf;
+
+ BLI_addtail(&pool->image_buffers, entry);
+ }
+
+ BLI_spin_unlock(&image_spin);
+
+ return ibuf;
+}
+
+void BKE_image_pool_release_ibuf(Image *ima, ImBuf *ibuf, ImagePool *pool)
+{
+ /* if pool wasn't actually used, use general release stuff,
+ * for pools image buffers will be dereferenced on pool free
+ */
+ if (pool == NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+}
+
int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range)
{
const int len = (iuser->fie_ima * iuser->frames) / 2;
@@ -3118,3 +3374,57 @@ void BKE_image_get_aspect(Image *image, float *aspx, float *aspy)
else
*aspy = 1.0f;
}
+
+unsigned char *BKE_image_get_pixels_for_frame(struct Image *image, int frame)
+{
+ ImageUser iuser = {0};
+ void *lock;
+ ImBuf *ibuf;
+ unsigned char *pixels = NULL;
+
+ iuser.framenr = frame;
+ iuser.ok = TRUE;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf) {
+ pixels = (unsigned char *) ibuf->rect;
+
+ if (pixels)
+ pixels = MEM_dupallocN(pixels);
+
+ BKE_image_release_ibuf(image, ibuf, lock);
+ }
+
+ if (!pixels)
+ return NULL;
+
+ return pixels;
+}
+
+float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame)
+{
+ ImageUser iuser = {0};
+ void *lock;
+ ImBuf *ibuf;
+ float *pixels = NULL;
+
+ iuser.framenr = frame;
+ iuser.ok = TRUE;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf) {
+ pixels = ibuf->rect_float;
+
+ if (pixels)
+ pixels = MEM_dupallocN(pixels);
+
+ BKE_image_release_ibuf(image, ibuf, lock);
+ }
+
+ if (!pixels)
+ return NULL;
+
+ return pixels;
+}
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 59dd02849dd..c5364744b2d 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1548,7 +1548,7 @@ static void ipo_to_animdata(ID *id, Ipo *ipo, char actname[], char constname[],
BLI_snprintf(nameBuf, sizeof(nameBuf), "CDA:%s", ipo->id.name + 2);
- adt->action = add_empty_action(nameBuf);
+ adt->action = add_empty_action(G.main, nameBuf);
if (G.debug & G_DEBUG) printf("\t\tadded new action - '%s'\n", nameBuf);
}
@@ -2093,7 +2093,7 @@ void do_versions_ipos_to_animato(Main *main)
bAction *new_act;
/* add a new action for this, and convert all data into that action */
- new_act = add_empty_action(id->name + 2);
+ new_act = add_empty_action(main, id->name + 2);
ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers);
new_act->idroot = ipo->blocktype;
}
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 782d796b8a7..f3dc391738e 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -108,19 +108,6 @@ void BKE_key_free_nolib(Key *key)
}
-/* GS reads the memory pointed at in a specific ordering. There are,
- * however two definitions for it. I have jotted them down here, both,
- * but I think the first one is actually used. The thing is that
- * big-endian systems might read this the wrong way round. OTOH, we
- * constructed the IDs that are read out with this macro explicitly as
- * well. I expect we'll sort it out soon... */
-
-/* from blendef: */
-#define GS(a) (*((short *)(a)))
-
-/* from misc_util: flip the bytes from x */
-/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-
Key *BKE_key_add(ID *id) /* common function */
{
Key *key;
@@ -259,7 +246,7 @@ void BKE_key_sort(Key *key)
/* find the right location and insert before */
for (kb2 = key->block.first; kb2; kb2 = kb2->next) {
if (kb2->pos > kb->pos) {
- BLI_insertlink(&key->block, kb2->prev, kb);
+ BLI_insertlinkafter(&key->block, kb2->prev, kb);
break;
}
}
@@ -1078,7 +1065,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int
if (key->slurph && key->type != KEY_RELATIVE) {
const float ctime_scaled = key->ctime / 100.0f;
float delta = (float)key->slurph / tot;
- float cfra = (float)scene->r.cfra;
+ float cfra = BKE_scene_frame_get(scene);
int step, a;
if (tot > 100 && slurph_opt) {
@@ -1176,7 +1163,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in
if (key->slurph && key->type != KEY_RELATIVE) {
const float ctime_scaled = key->ctime / 100.0f;
float delta = (float)key->slurph / tot;
- float cfra = (float)scene->r.cfra;
+ float cfra = BKE_scene_frame_get(scene);
Nurb *nu;
int i = 0, remain = 0;
int step, a;
@@ -1258,7 +1245,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int
if (key->slurph && key->type != KEY_RELATIVE) {
const float ctime_scaled = key->ctime / 100.0f;
float delta = (float)key->slurph / tot;
- float cfra = (float)scene->r.cfra;
+ float cfra = BKE_scene_frame_get(scene);
int a;
for (a = 0; a < tot; a++, cfra += delta) {
@@ -1300,13 +1287,13 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int
}
/* returns key coordinates (+ tilt) when key applied, NULL otherwise */
-float *do_ob_key(Scene *scene, Object *ob)
+float *BKE_key_evaluate_object(Scene *scene, Object *ob, int *r_totelem)
{
Key *key = BKE_key_from_object(ob);
KeyBlock *actkb = BKE_keyblock_from_object(ob);
char *out;
int tot = 0, size = 0;
-
+
if (key == NULL || key->block.first == NULL)
return NULL;
@@ -1344,7 +1331,7 @@ float *do_ob_key(Scene *scene, Object *ob)
return NULL;
/* allocate array */
- out = MEM_callocN(size, "do_ob_key out");
+ out = MEM_callocN(size, "BKE_key_evaluate_object out");
/* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
key->from = (ID *)ob->data;
@@ -1373,7 +1360,7 @@ float *do_ob_key(Scene *scene, Object *ob)
}
else {
/* do shapekey local drivers */
- float ctime = (float)scene->r.cfra; // XXX this needs to be checked
+ float ctime = BKE_scene_frame_get(scene);
BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
@@ -1383,6 +1370,9 @@ float *do_ob_key(Scene *scene, Object *ob)
else if (ob->type == OB_SURF) do_curve_key(scene, ob, key, out, tot);
}
+ if (r_totelem) {
+ *r_totelem = tot;
+ }
return (float *)out;
}
@@ -1732,7 +1722,7 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
}
/************************* vert coords ************************/
-float (*BKE_key_convert_to_vertcos(Object * ob, KeyBlock * kb))[3]
+float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
{
float (*vertCos)[3], *co;
float *fp = kb->data;
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 2f37db846f3..32cc5c6c22e 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -54,11 +54,11 @@
#include "BKE_main.h"
#include "BKE_node.h"
-Lamp *BKE_lamp_add(const char *name)
+Lamp *BKE_lamp_add(Main *bmain, const char *name)
{
Lamp *la;
- la = BKE_libblock_alloc(&G.main->lamp, ID_LA, name);
+ la = BKE_libblock_alloc(&bmain->lamp, ID_LA, name);
la->r = la->g = la->b = la->k = 1.0f;
la->haint = la->energy = 1.0f;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index a15ca7cb5ce..c3e7a963c04 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -89,7 +88,7 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
/* vertex weight groups are just freed all for now */
if (lt->dvert) {
- free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
lt->dvert = NULL;
}
@@ -181,11 +180,11 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
MEM_freeN(vertexCos);
}
-Lattice *BKE_lattice_add(const char *name)
+Lattice *BKE_lattice_add(Main *bmain, const char *name)
{
Lattice *lt;
- lt = BKE_libblock_alloc(&G.main->latt, ID_LT, name);
+ lt = BKE_libblock_alloc(&bmain->latt, ID_LT, name);
lt->flag = LT_GRID;
@@ -210,7 +209,7 @@ Lattice *BKE_lattice_copy(Lattice *lt)
if (lt->dvert) {
int tot = lt->pntsu * lt->pntsv * lt->pntsw;
ltn->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- copy_dverts(ltn->dvert, lt->dvert, tot);
+ BKE_defvert_array_copy(ltn->dvert, lt->dvert, tot);
}
ltn->editlatt = NULL;
@@ -221,12 +220,12 @@ Lattice *BKE_lattice_copy(Lattice *lt)
void BKE_lattice_free(Lattice *lt)
{
if (lt->def) MEM_freeN(lt->def);
- if (lt->dvert) free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ if (lt->dvert) BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
if (lt->editlatt) {
Lattice *editlt = lt->editlatt->latt;
if (editlt->def) MEM_freeN(editlt->def);
- if (editlt->dvert) free_dverts(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ if (editlt->dvert) BKE_defvert_array_free(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
MEM_freeN(editlt);
MEM_freeN(lt->editlatt);
@@ -753,7 +752,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
/* orco is original not-animated or deformed reference point */
/* result written in vec and mat */
void curve_deform_vector(Scene *scene, Object *cuOb, Object *target,
- float orco[3], float vec[3], float mat[][3], int no_rot_axis)
+ float orco[3], float vec[3], float mat[3][3], int no_rot_axis)
{
CurveDeform cd;
float quat[4];
@@ -913,7 +912,7 @@ void outside_lattice(Lattice *lt)
bp->vec[1] += (1.0f - fac1) * bp1->vec[1] + fac1 * bp2->vec[1];
bp->vec[2] += (1.0f - fac1) * bp1->vec[2] + fac1 * bp2->vec[2];
- mul_v3_fl(bp->vec, 0.3333333f);
+ mul_v3_fl(bp->vec, 1.0f / 3.0f);
}
}
@@ -1004,3 +1003,66 @@ struct MDeformVert *BKE_lattice_deform_verts_get(struct Object *oblatt)
if (lt->editlatt) lt = lt->editlatt->latt;
return lt->dvert;
}
+
+void BKE_lattice_center_median(struct Lattice *lt, float cent[3])
+{
+ int i, numVerts;
+
+ if (lt->editlatt) lt = lt->editlatt->latt;
+ numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ zero_v3(cent);
+
+ for (i = 0; i < numVerts; i++)
+ add_v3_v3(cent, lt->def[i].vec);
+
+ mul_v3_fl(cent, 1.0f / (float)numVerts);
+}
+
+void BKE_lattice_minmax(struct Lattice *lt, float min[3], float max[3])
+{
+ int i, numVerts;
+
+ if (lt->editlatt) lt = lt->editlatt->latt;
+ numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ for (i = 0; i < numVerts; i++)
+ minmax_v3v3_v3(min, max, lt->def[i].vec);
+}
+
+void BKE_lattice_center_bounds(struct Lattice *lt, float cent[3])
+{
+ float min[3], max[3];
+
+ INIT_MINMAX(min, max);
+
+ BKE_lattice_minmax(lt, min, max);
+ mid_v3_v3v3(cent, min, max);
+}
+
+void BKE_lattice_translate(Lattice *lt, float offset[3], int do_keys)
+{
+ int i, numVerts;
+
+ numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ if (lt->def)
+ for (i = 0; i < numVerts; i++)
+ add_v3_v3(lt->def[i].vec, offset);
+
+ if (lt->editlatt)
+ for (i = 0; i < numVerts; i++)
+ add_v3_v3(lt->editlatt->latt->def[i].vec, offset);
+
+ if (do_keys && lt->key) {
+ KeyBlock *kb;
+
+ for (kb = lt->key->block.first; kb; kb = kb->next) {
+ float *fp = kb->data;
+ for (i = kb->totelem; i--; fp += 3) {
+ add_v3_v3(fp, offset);
+ }
+ }
+ }
+}
+
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index eb0612a75bd..0c5e2b89cf7 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -47,6 +47,7 @@
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
#include "DNA_group_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
@@ -54,6 +55,8 @@
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "DNA_nla_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
@@ -64,51 +67,49 @@
#include "DNA_vfont_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_world_types.h"
-#include "DNA_gpencil_types.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_mask_types.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
+#include "BKE_bpath.h"
+#include "BKE_action.h"
#include "BKE_animsys.h"
+#include "BKE_armature.h"
+#include "BKE_brush.h"
#include "BKE_camera.h"
#include "BKE_context.h"
-#include "BKE_lamp.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_global.h"
-#include "BKE_sound.h"
-#include "BKE_object.h"
-#include "BKE_screen.h"
-#include "BKE_mesh.h"
-#include "BKE_material.h"
#include "BKE_curve.h"
-#include "BKE_mball.h"
-#include "BKE_text.h"
-#include "BKE_texture.h"
-#include "BKE_scene.h"
+#include "BKE_fcurve.h"
+#include "BKE_font.h"
+#include "BKE_global.h"
+#include "BKE_group.h"
+#include "BKE_gpencil.h"
+#include "BKE_idprop.h"
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
-#include "BKE_world.h"
-#include "BKE_font.h"
-#include "BKE_group.h"
+#include "BKE_lamp.h"
#include "BKE_lattice.h"
-#include "BKE_armature.h"
-#include "BKE_action.h"
+#include "BKE_library.h"
+#include "BKE_mesh.h"
+#include "BKE_material.h"
+#include "BKE_main.h"
+#include "BKE_mball.h"
+#include "BKE_movieclip.h"
+#include "BKE_mask.h"
#include "BKE_node.h"
-#include "BKE_brush.h"
-#include "BKE_idprop.h"
+#include "BKE_object.h"
#include "BKE_particle.h"
-#include "BKE_gpencil.h"
-#include "BKE_fcurve.h"
+#include "BKE_packedFile.h"
#include "BKE_speaker.h"
-#include "BKE_movieclip.h"
-#include "BKE_mask.h"
+#include "BKE_sound.h"
+#include "BKE_screen.h"
+#include "BKE_scene.h"
+#include "BKE_text.h"
+#include "BKE_texture.h"
+#include "BKE_world.h"
#include "RNA_access.h"
@@ -122,9 +123,6 @@
* only use this definition, makes little and big endian systems
* work fine, in conjunction with MAKE_ID */
-/* from blendef: */
-#define GS(a) (*((short *)(a)))
-
/* ************* general ************************ */
@@ -136,9 +134,9 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
{
char *bpath_user_data[2] = {bmain->name, lib->filepath};
- BLI_bpath_traverse_id(bmain, id,
- BLI_bpath_relocate_visitor,
- BLI_BPATH_TRAVERSE_SKIP_MULTIFILE,
+ BKE_bpath_traverse_id(bmain, id,
+ BKE_bpath_relocate_visitor,
+ BKE_BPATH_TRAVERSE_SKIP_MULTIFILE,
bpath_user_data);
}
@@ -152,6 +150,16 @@ void id_lib_extern(ID *id)
}
}
+/* ensure we have a real user */
+void id_us_ensure_real(ID *id)
+{
+ if (id) {
+ if (ID_REAL_USERS(id) <= 0) {
+ id->us = MAX2(id->us, 0) + 1;
+ }
+ }
+}
+
void id_us_plus(ID *id)
{
if (id) {
@@ -304,7 +312,7 @@ int id_copy(ID *id, ID **newid, int test)
if (!test) *newid = (ID *)BKE_texture_copy((Tex *)id);
return 1;
case ID_IM:
- if (!test) *newid = (ID *)BKE_image_copy((Image *)id);
+ if (!test) *newid = (ID *)BKE_image_copy(G.main, (Image *)id);
return 1;
case ID_LT:
if (!test) *newid = (ID *)BKE_lattice_copy((Lattice *)id);
@@ -734,13 +742,13 @@ void BKE_libblock_copy_data(ID *id, const ID *id_from, const short do_action)
}
/* used everywhere in blenkernel */
-void *BKE_libblock_copy(ID *id)
+void *BKE_libblock_copy_ex(Main *bmain, ID *id)
{
ID *idn;
ListBase *lb;
size_t idn_len;
- lb = which_libbase(G.main, GS(id->name));
+ lb = which_libbase(bmain, GS(id->name));
idn = BKE_libblock_alloc(lb, GS(id->name), id->name + 2);
assert(idn != NULL);
@@ -761,9 +769,15 @@ void *BKE_libblock_copy(ID *id)
return idn;
}
-static void BKE_library_free(Library *UNUSED(lib))
+void *BKE_libblock_copy(ID *id)
+{
+ return BKE_libblock_copy_ex(G.main, id);
+}
+
+static void BKE_library_free(Library *lib)
{
- /* no freeing needed for libraries yet */
+ if (lib->packedfile)
+ freePackedFile(lib->packedfile);
}
static void (*free_windowmanager_cb)(bContext *, wmWindowManager *) = NULL;
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index bda924060d5..960432d6b3d 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -698,18 +698,18 @@ void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const short do_sel
}
/* only mask block itself */
-static Mask *mask_alloc(const char *name)
+static Mask *mask_alloc(Main *bmain, const char *name)
{
Mask *mask;
- mask = BKE_libblock_alloc(&G.main->mask, ID_MSK, name);
+ mask = BKE_libblock_alloc(&bmain->mask, ID_MSK, name);
mask->id.flag |= LIB_FAKEUSER;
return mask;
}
-Mask *BKE_mask_new(const char *name)
+Mask *BKE_mask_new(Main *bmain, const char *name)
{
Mask *mask;
char mask_name[MAX_ID_NAME - 2];
@@ -719,7 +719,7 @@ Mask *BKE_mask_new(const char *name)
else
strcpy(mask_name, "Mask");
- mask = mask_alloc(mask_name);
+ mask = mask_alloc(bmain, mask_name);
/* arbitrary defaults */
mask->sfra = 1;
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 2fa928e7c07..e3423c93f3c 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -213,7 +213,7 @@ MaskRasterHandle *BKE_maskrasterize_handle_new(void)
{
MaskRasterHandle *mr_handle;
- mr_handle = MEM_callocN(sizeof(MaskRasterHandle), STRINGIFY(MaskRasterHandle));
+ mr_handle = MEM_callocN(sizeof(MaskRasterHandle), "MaskRasterHandle");
return mr_handle;
}
@@ -569,7 +569,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
unsigned int masklay_index;
mr_handle->layers_tot = BLI_countlist(&mask->masklayers);
- mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, STRINGIFY(MaskRasterLayer));
+ mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, "MaskRasterLayer");
BLI_rctf_init_minmax(&mr_handle->bounds);
for (masklay = mask->masklayers.first, masklay_index = 0; masklay; masklay = masklay->next, masklay_index++) {
@@ -933,7 +933,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
}
/* main scan-fill */
- sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, 0, zvec);
+ sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_HOLES, zvec);
face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index");
face_index = 0;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index ea317956255..47117658b5e 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -52,7 +52,6 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BLI_string.h"
#include "BKE_animsys.h"
@@ -207,11 +206,11 @@ void init_material(Material *ma)
ma->preview = NULL;
}
-Material *BKE_material_add(const char *name)
+Material *BKE_material_add(Main *bmain, const char *name)
{
Material *ma;
- ma = BKE_libblock_alloc(&G.main->mat, ID_MA, name);
+ ma = BKE_libblock_alloc(&bmain->mat, ID_MA, name);
init_material(ma);
@@ -629,11 +628,14 @@ Material *give_current_material(Object *ob, short act)
if (totcolp == NULL || ob->totcol == 0) return NULL;
if (act < 0) {
- printf("no!\n");
+ printf("Negative material index!\n");
}
- if (act > ob->totcol) act = ob->totcol;
- else if (act <= 0) act = 1;
+ /* return NULL for invalid 'act', can happen for mesh face indices */
+ if (act > ob->totcol)
+ return NULL;
+ else if (act <= 0)
+ return NULL;
if (ob->matbits && ob->matbits[act - 1]) { /* in object */
ma = ob->mat[act - 1];
@@ -679,19 +681,6 @@ Material *give_node_material(Material *ma)
return NULL;
}
-/* GS reads the memory pointed at in a specific ordering. There are,
- * however two definitions for it. I have jotted them down here, both,
- * but I think the first one is actually used. The thing is that
- * big-endian systems might read this the wrong way round. OTOH, we
- * constructed the IDs that are read out with this macro explicitly as
- * well. I expect we'll sort it out soon... */
-
-/* from blendef: */
-#define GS(a) (*((short *)(a)))
-
-/* from misc_util: flip the bytes from x */
-/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-
void resize_object_material(Object *ob, const short totcol)
{
Material **newmatar;
@@ -1235,6 +1224,11 @@ int object_remove_material_slot(Object *ob)
if (*matarar == NULL) return FALSE;
+ /* can happen on face selection in editmode */
+ if (ob->actcol > ob->totcol) {
+ ob->actcol = ob->totcol;
+ }
+
/* we delete the actcol */
mao = (*matarar)[ob->actcol - 1];
if (mao) mao->id.us--;
@@ -1784,7 +1778,7 @@ static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
}
/* create a new material */
else {
- ma = BKE_material_add(idname + 2);
+ ma = BKE_material_add(main, idname + 2);
if (ma) {
printf("TexFace Convert: Material \"%s\" created.\n", idname + 2);
@@ -1856,7 +1850,7 @@ static void convert_tfacematerial(Main *main, Material *ma)
mat_new = BKE_material_copy(ma);
if (mat_new) {
/* rename the material*/
- strcpy(mat_new->id.name, idname);
+ BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name));
id_us_min((ID *)mat_new);
mat_nr = mesh_addmaterial(me, mat_new);
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 805e77cf84f..5cc3145213c 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -50,8 +50,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
-
#include "BKE_global.h"
#include "BKE_main.h"
@@ -198,11 +196,11 @@ void BKE_mball_free(MetaBall *mb)
if (mb->disp.first) BKE_displist_free(&mb->disp);
}
-MetaBall *BKE_mball_add(const char *name)
+MetaBall *BKE_mball_add(Main *bmain, const char *name)
{
MetaBall *mb;
- mb = BKE_libblock_alloc(&G.main->mball, ID_MB, name);
+ mb = BKE_libblock_alloc(&bmain->mball, ID_MB, name);
mb->size[0] = mb->size[1] = mb->size[2] = 1.0;
mb->texflag = MB_AUTOSPACE;
@@ -1516,7 +1514,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
float in_v /*, out_v*/;
float workp[3];
float dvec[3];
- float tmp_v, workp_v, max_len, len, nx, ny, nz, MAXN;
+ float tmp_v, workp_v, max_len, nx, ny, nz, max_dim;
calc_mballco(ml, in);
in_v = mbproc->function(in[0], in[1], in[2]);
@@ -1575,17 +1573,17 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
ny = abs((out[1] - in[1]) / mbproc->size);
nz = abs((out[2] - in[2]) / mbproc->size);
- MAXN = MAX3(nx, ny, nz);
- if (MAXN != 0.0f) {
- dvec[0] = (out[0] - in[0]) / MAXN;
- dvec[1] = (out[1] - in[1]) / MAXN;
- dvec[2] = (out[2] - in[2]) / MAXN;
+ max_dim = max_fff(nx, ny, nz);
+ if (max_dim != 0.0f) {
+ float len = 0.0f;
+
+ dvec[0] = (out[0] - in[0]) / max_dim;
+ dvec[1] = (out[1] - in[1]) / max_dim;
+ dvec[2] = (out[2] - in[2]) / max_dim;
- len = 0.0;
while (len <= max_len) {
- workp[0] += dvec[0];
- workp[1] += dvec[1];
- workp[2] += dvec[2];
+ add_v3_v3(workp, dvec);
+
/* compute value of implicite function */
tmp_v = mbproc->function(workp[0], workp[1], workp[2]);
/* add cube to the stack, when value of implicite function crosses zero value */
@@ -1656,6 +1654,14 @@ static void polygonize(PROCESS *mbproc, MetaBall *mb)
}
}
+/* could move to math api */
+BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z)
+{
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+}
+
static float init_meta(Scene *scene, Object *ob) /* return totsize */
{
Scene *sce_iter = scene;
@@ -1732,6 +1738,7 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
float temp1[4][4], temp2[4][4], temp3[4][4];
float (*mat)[4] = NULL, (*imat)[4] = NULL;
float max_x, max_y, max_z, min_x, min_y, min_z;
+ float expx, expy, expz;
max_x = max_y = max_z = -3.4e38;
min_x = min_y = min_z = 3.4e38;
@@ -1772,39 +1779,27 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
G_mb.mainb[a]->mat = (float *) mat;
G_mb.mainb[a]->imat = (float *) imat;
+ if (!MB_TYPE_SIZE_SQUARED(ml->type)) {
+ expx = ml->expx;
+ expy = ml->expy;
+ expz = ml->expz;
+ }
+ else {
+ expx = ml->expx * ml->expx;
+ expy = ml->expy * ml->expy;
+ expz = ml->expz * ml->expz;
+ }
+
/* untransformed Bounding Box of MetaElem */
- /* 0 */
- G_mb.mainb[a]->bb->vec[0][0] = -ml->expx;
- G_mb.mainb[a]->bb->vec[0][1] = -ml->expy;
- G_mb.mainb[a]->bb->vec[0][2] = -ml->expz;
- /* 1 */
- G_mb.mainb[a]->bb->vec[1][0] = ml->expx;
- G_mb.mainb[a]->bb->vec[1][1] = -ml->expy;
- G_mb.mainb[a]->bb->vec[1][2] = -ml->expz;
- /* 2 */
- G_mb.mainb[a]->bb->vec[2][0] = ml->expx;
- G_mb.mainb[a]->bb->vec[2][1] = ml->expy;
- G_mb.mainb[a]->bb->vec[2][2] = -ml->expz;
- /* 3 */
- G_mb.mainb[a]->bb->vec[3][0] = -ml->expx;
- G_mb.mainb[a]->bb->vec[3][1] = ml->expy;
- G_mb.mainb[a]->bb->vec[3][2] = -ml->expz;
- /* 4 */
- G_mb.mainb[a]->bb->vec[4][0] = -ml->expx;
- G_mb.mainb[a]->bb->vec[4][1] = -ml->expy;
- G_mb.mainb[a]->bb->vec[4][2] = ml->expz;
- /* 5 */
- G_mb.mainb[a]->bb->vec[5][0] = ml->expx;
- G_mb.mainb[a]->bb->vec[5][1] = -ml->expy;
- G_mb.mainb[a]->bb->vec[5][2] = ml->expz;
- /* 6 */
- G_mb.mainb[a]->bb->vec[6][0] = ml->expx;
- G_mb.mainb[a]->bb->vec[6][1] = ml->expy;
- G_mb.mainb[a]->bb->vec[6][2] = ml->expz;
- /* 7 */
- G_mb.mainb[a]->bb->vec[7][0] = -ml->expx;
- G_mb.mainb[a]->bb->vec[7][1] = ml->expy;
- G_mb.mainb[a]->bb->vec[7][2] = ml->expz;
+ /* TODO, its possible the elem type has been changed and the exp* values can use a fallback */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
+ copy_v3_fl3(G_mb.mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
/* transformation of Metalem bb */
for (i = 0; i < 8; i++)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 036f8f5e673..c9c86e6739f 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -46,7 +46,6 @@
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_scanfill.h"
@@ -431,42 +430,6 @@ void BKE_mesh_free(Mesh *me, int unlink)
if (me->edit_btmesh) MEM_freeN(me->edit_btmesh);
}
-void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
-{
- /* Assumes dst is already set up */
- int i;
-
- if (!src || !dst)
- return;
-
- memcpy(dst, src, copycount * sizeof(MDeformVert));
-
- for (i = 0; i < copycount; i++) {
- if (src[i].dw) {
- dst[i].dw = MEM_callocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
- memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
- }
- }
-
-}
-
-void free_dverts(MDeformVert *dvert, int totvert)
-{
- /* Instead of freeing the verts directly,
- * call this function to delete any special
- * vert data */
- int i;
-
- if (!dvert)
- return;
-
- /* Free any special data from the verts */
- for (i = 0; i < totvert; i++) {
- if (dvert[i].dw) MEM_freeN(dvert[i].dw);
- }
- MEM_freeN(dvert);
-}
-
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
{
if (free_customdata) {
@@ -482,11 +445,11 @@ static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
mesh->totface = 0;
}
-Mesh *BKE_mesh_add(const char *name)
+Mesh *BKE_mesh_add(Main *bmain, const char *name)
{
Mesh *me;
- me = BKE_libblock_alloc(&G.main->mesh, ID_ME, name);
+ me = BKE_libblock_alloc(&bmain->mesh, ID_ME, name);
me->size[0] = me->size[1] = me->size[2] = 1.0;
me->smoothresh = 30;
@@ -503,7 +466,7 @@ Mesh *BKE_mesh_add(const char *name)
return me;
}
-Mesh *BKE_mesh_copy(Mesh *me)
+Mesh *BKE_mesh_copy_ex(Main *bmain, Mesh *me)
{
Mesh *men;
MTFace *tface;
@@ -511,7 +474,7 @@ Mesh *BKE_mesh_copy(Mesh *me)
int a, i;
const int do_tessface = ((me->totface != 0) && (me->totpoly == 0)); /* only do tessface if we have no polys */
- men = BKE_libblock_copy(&me->id);
+ men = BKE_libblock_copy_ex(bmain, &me->id);
men->mat = MEM_dupallocN(me->mat);
for (a = 0; a < men->totcol; a++) {
@@ -564,13 +527,18 @@ Mesh *BKE_mesh_copy(Mesh *me)
return men;
}
+Mesh *BKE_mesh_copy(Mesh *me)
+{
+ return BKE_mesh_copy_ex(G.main, me);
+}
+
BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob)
{
BMesh *bm;
bm = BM_mesh_create(&bm_mesh_allocsize_default);
- BM_mesh_bm_from_me(bm, me, TRUE, ob->shapenr);
+ BM_mesh_bm_from_me(bm, me, true, ob->shapenr);
return bm;
}
@@ -732,7 +700,7 @@ void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_siz
if (r_size) copy_v3_v3(r_size, me->size);
}
-float *BKE_mesh_orco_verts_get(Object *ob)
+float (*BKE_mesh_orco_verts_get(Object *ob))[3]
{
Mesh *me = ob->data;
MVert *mvert = NULL;
@@ -749,7 +717,7 @@ float *BKE_mesh_orco_verts_get(Object *ob)
copy_v3_v3(vcos[a], mvert->co);
}
- return (float *)vcos;
+ return vcos;
}
void BKE_mesh_orco_verts_transform(Mesh *me, float (*orco)[3], int totvert, int invert)
@@ -1241,8 +1209,8 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp,
allvert, totvert,
alledge, totedge,
- allloop, allpoly,
- totloop, totpoly, NULL);
+ allloop, allpoly, NULL,
+ totloop, totpoly);
}
/* BMESH: this doesn't calculate all edges from polygons,
@@ -1250,25 +1218,24 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
/* use specified dispbase */
-/* TODO: orco values for non DL_SURF types */
int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
MVert **allvert, int *_totvert,
MEdge **alledge, int *_totedge,
MLoop **allloop, MPoly **allpoly,
- int *_totloop, int *_totpoly,
- int **orco_index_ptr)
+ MLoopUV **alluv,
+ int *_totloop, int *_totpoly)
{
DispList *dl;
Curve *cu;
MVert *mvert;
MPoly *mpoly;
MLoop *mloop;
+ MLoopUV *mloopuv = NULL;
MEdge *medge;
float *data;
int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0;
int p1, p2, p3, p4, *index;
int conv_polys = 0;
- int (*orco_index)[4] = NULL;
cu = ob->data;
@@ -1315,15 +1282,13 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
*alledge = medge = MEM_callocN(sizeof(MEdge) * totedge, "nurbs_init medge");
*allloop = mloop = MEM_callocN(sizeof(MLoop) * totvlak * 4, "nurbs_init mloop"); // totloop
*allpoly = mpoly = MEM_callocN(sizeof(MPoly) * totvlak, "nurbs_init mloop");
+
+ if (alluv)
+ *alluv = mloopuv = MEM_callocN(sizeof(MLoopUV) * totvlak * 4, "nurbs_init mloopuv");
/* verts and faces */
vertcount = 0;
- if (orco_index_ptr) {
- *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco");
- orco_index = (int (*)[4]) *orco_index_ptr;
- }
-
dl = dispbase->first;
while (dl) {
int smooth = dl->rt & CU_SMOOTH ? 1 : 0;
@@ -1396,6 +1361,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
mpoly->totloop = 3;
mpoly->mat_nr = dl->col;
+ if (mloopuv) {
+ int i;
+
+ for (i = 0; i < 3; i++, mloopuv++) {
+ mloopuv->uv[0] = (mloop[i].v - startvert) / (float)(dl->nr - 1);
+ mloopuv->uv[1] = 0.0f;
+ }
+ }
+
if (smooth) mpoly->flag |= ME_SMOOTH;
mpoly++;
mloop += 3;
@@ -1445,13 +1419,29 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
mpoly->totloop = 4;
mpoly->mat_nr = dl->col;
- if (orco_index) {
- const int poly_index = mpoly - *allpoly;
- const int p_orco_base = startvert + ((dl->nr + 1) * a) + b;
- orco_index[poly_index][0] = p_orco_base + 1;
- orco_index[poly_index][1] = p_orco_base + dl->nr + 2;
- orco_index[poly_index][2] = p_orco_base + dl->nr + 1;
- orco_index[poly_index][3] = p_orco_base;
+ if (mloopuv) {
+ int orco_sizeu = dl->nr - 1;
+ int orco_sizev = dl->parts - 1;
+ int i;
+
+ /* exception as handled in convertblender.c too */
+ if (dl->flag & DL_CYCL_U) {
+ orco_sizeu++;
+ if (dl->flag & DL_CYCL_V)
+ orco_sizev++;
+ }
+
+ for (i = 0; i < 4; i++, mloopuv++) {
+ /* find uv based on vertex index into grid array */
+ int v = mloop[i].v - startvert;
+
+ mloopuv->uv[0] = (v / dl->nr) / (float)orco_sizev;
+ mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu;
+
+ /* cyclic correction */
+ if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f)
+ mloopuv->uv[1] = 1.0f;
+ }
}
if (smooth) mpoly->flag |= ME_SMOOTH;
@@ -1464,7 +1454,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
p1++;
}
}
-
}
dl = dl->next;
@@ -1485,33 +1474,8 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
}
-MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2])
-{
- r[0] = 0.5f + a[0] * 0.5f;
- r[1] = 0.5f + a[1] * 0.5f;
-}
-
-/**
- * orco is normally from #BKE_curve_make_orco
- */
-void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly,
- MLoop *mloops, MLoopUV *mloopuvs,
- float (*orco)[3], int (*orco_index)[4])
-{
- MPoly *mp;
-
- int i, j;
- for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
- MLoop *ml = mloops + mp->loopstart;
- MLoopUV *mluv = mloopuvs + mp->loopstart;
- for (j = 0; j < mp->totloop; j++, ml++, mluv++) {
- copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]);
- }
- }
-}
-
/* this may fail replacing ob->data, be sure to check ob->type */
-void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_uv)
{
Main *bmain = G.main;
Object *ob1;
@@ -1521,6 +1485,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
MVert *allvert = NULL;
MEdge *alledge = NULL;
MLoop *allloop = NULL;
+ MLoopUV *alluv = NULL;
MPoly *allpoly = NULL;
int totvert, totedge, totloop, totpoly;
@@ -1529,14 +1494,15 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
if (dm == NULL) {
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
&alledge, &totedge, &allloop,
- &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+ &allpoly, (use_orco_uv) ? &alluv : NULL,
+ &totloop, &totpoly) != 0)
{
/* Error initializing */
return;
}
/* make mesh */
- me = BKE_mesh_add("Mesh");
+ me = BKE_mesh_add(G.main, "Mesh");
me->totvert = totvert;
me->totedge = totedge;
me->totloop = totloop;
@@ -1547,12 +1513,18 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
+ if (alluv) {
+ const char *uvname = "Orco";
+ me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
+ me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
+ }
+
BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
BKE_mesh_calc_edges(me, TRUE);
}
else {
- me = BKE_mesh_add("Mesh");
+ me = BKE_mesh_add(G.main, "Mesh");
DM_to_mesh(dm, me, ob);
}
@@ -1585,7 +1557,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
void BKE_mesh_from_nurbs(Object *ob)
{
- BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL);
+ BKE_mesh_from_nurbs_displist(ob, &ob->disp, false);
}
typedef struct EdgeLink {
@@ -1668,7 +1640,7 @@ void BKE_mesh_from_curve(Scene *scene, Object *ob)
BLI_edgehash_free(eh, NULL);
if (edges.first) {
- Curve *cu = BKE_curve_add(ob->id.name + 2, OB_CURVE);
+ Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
cu->flag |= CU_3D;
while (edges.first) {
@@ -2489,7 +2461,7 @@ void BKE_mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
*/
int BKE_mesh_recalc_tessellation(CustomData *fdata,
CustomData *ldata, CustomData *pdata,
- MVert *mvert, int totface, int UNUSED(totloop),
+ MVert *mvert, int totface, int totloop,
int totpoly,
/* when tessellating to recalculate normals after
* we can skip copying here */
@@ -2504,15 +2476,15 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
#define TESSFACE_SCANFILL (1 << 0)
#define TESSFACE_IS_QUAD (1 << 1)
+ const int looptris_tot = poly_to_tri_count(totpoly, totloop);
+
MPoly *mp, *mpoly;
MLoop *ml, *mloop;
- MFace *mface = NULL, *mf;
- BLI_array_declare(mface);
+ MFace *mface, *mf;
ScanFillContext sf_ctx;
ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first;
ScanFillFace *sf_tri;
- int *mface_to_poly_map = NULL;
- BLI_array_declare(mface_to_poly_map);
+ int *mface_to_poly_map;
int lindex[4]; /* only ever use 3 in this case */
int poly_index, j, mface_index;
@@ -2526,8 +2498,9 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
/* allocate the length of totfaces, avoid many small reallocs,
* if all faces are tri's it will be correct, quads == 2x allocs */
- BLI_array_reserve(mface_to_poly_map, totpoly);
- BLI_array_reserve(mface, totpoly);
+ /* take care. we are _not_ calloc'ing so be sure to initialize each field */
+ mface_to_poly_map = MEM_mallocN(sizeof(*mface_to_poly_map) * looptris_tot, __func__);
+ mface = MEM_mallocN(sizeof(*mface) * looptris_tot, __func__);
mface_index = 0;
mp = mpoly;
@@ -2539,8 +2512,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
#ifdef USE_TESSFACE_SPEEDUP
#define ML_TO_MF(i1, i2, i3) \
- BLI_array_grow_one(mface_to_poly_map); \
- BLI_array_grow_one(mface); \
mface_to_poly_map[mface_index] = poly_index; \
mf = &mface[mface_index]; \
/* set loop indices, transformed to vert indices later */ \
@@ -2550,12 +2521,11 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
mf->v4 = 0; \
mf->mat_nr = mp->mat_nr; \
mf->flag = mp->flag; \
+ mf->edcode = 0; \
(void)0
/* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */
#define ML_TO_MF_QUAD() \
- BLI_array_grow_one(mface_to_poly_map); \
- BLI_array_grow_one(mface); \
mface_to_poly_map[mface_index] = poly_index; \
mf = &mface[mface_index]; \
/* set loop indices, transformed to vert indices later */ \
@@ -2565,7 +2535,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
mf->v4 = mp->loopstart + 3; /* EXCEPTION */ \
mf->mat_nr = mp->mat_nr; \
mf->flag = mp->flag; \
- mf->edcode |= TESSFACE_IS_QUAD; /* EXCEPTION */ \
+ mf->edcode = TESSFACE_IS_QUAD; /* EXCEPTION */ \
(void)0
@@ -2608,29 +2578,27 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert_first);
totfilltri = BLI_scanfill_calc(&sf_ctx, 0);
- if (totfilltri) {
- BLI_array_grow_items(mface_to_poly_map, totfilltri);
- BLI_array_grow_items(mface, totfilltri);
+ BLI_assert(totfilltri <= mp->totloop - 2);
+ (void)totfilltri;
- for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) {
- mface_to_poly_map[mface_index] = poly_index;
- mf = &mface[mface_index];
+ for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) {
+ mface_to_poly_map[mface_index] = poly_index;
+ mf = &mface[mface_index];
- /* set loop indices, transformed to vert indices later */
- mf->v1 = sf_tri->v1->keyindex;
- mf->v2 = sf_tri->v2->keyindex;
- mf->v3 = sf_tri->v3->keyindex;
- mf->v4 = 0;
+ /* set loop indices, transformed to vert indices later */
+ mf->v1 = sf_tri->v1->keyindex;
+ mf->v2 = sf_tri->v2->keyindex;
+ mf->v3 = sf_tri->v3->keyindex;
+ mf->v4 = 0;
- mf->mat_nr = mp->mat_nr;
- mf->flag = mp->flag;
+ mf->mat_nr = mp->mat_nr;
+ mf->flag = mp->flag;
#ifdef USE_TESSFACE_SPEEDUP
- mf->edcode |= TESSFACE_SCANFILL; /* tag for sorting loop indices */
+ mf->edcode = TESSFACE_SCANFILL; /* tag for sorting loop indices */
#endif
- mface_index++;
- }
+ mface_index++;
}
BLI_scanfill_end(&sf_ctx);
@@ -2640,9 +2608,10 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
CustomData_free(fdata, totface);
totface = mface_index;
+ BLI_assert(totface <= looptris_tot);
/* not essential but without this we store over-alloc'd memory in the CustomData layers */
- if (LIKELY((MEM_allocN_len(mface) / sizeof(*mface)) != totface)) {
+ if (LIKELY(looptris_tot != totface)) {
mface = MEM_reallocN(mface, sizeof(*mface) * totface);
mface_to_poly_map = MEM_reallocN(mface_to_poly_map, sizeof(*mface_to_poly_map) * totface);
}
@@ -3009,9 +2978,9 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
else {
int i;
MLoop *l_iter = loopstart;
- float area, polynorm_local[3], (*vertexcos)[3];
+ float area, polynorm_local[3];
+ float (*vertexcos)[3] = BLI_array_alloca(vertexcos, mpoly->totloop);
const float *no = polynormal ? polynormal : polynorm_local;
- BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__);
/* pack vertex cos into an array for area_poly_v3 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
@@ -3026,12 +2995,102 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
/* finally calculate the area */
area = area_poly_v3(mpoly->totloop, vertexcos, no);
- BLI_array_fixedstack_free(vertexcos);
-
return area;
}
}
+/* note, results won't be correct if polygon is non-planar */
+static float mesh_calc_poly_planar_area_centroid(MPoly *mpoly, MLoop *loopstart, MVert *mvarray, float cent[3])
+{
+ int i;
+ float tri_area;
+ float total_area = 0.0f;
+ float v1[3], v2[3], v3[3], normal[3], tri_cent[3];
+
+ BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, normal);
+ copy_v3_v3(v1, mvarray[loopstart[0].v].co);
+ copy_v3_v3(v2, mvarray[loopstart[1].v].co);
+ zero_v3(cent);
+
+ for (i = 2; i < mpoly->totloop; i++) {
+ copy_v3_v3(v3, mvarray[loopstart[i].v].co);
+
+ tri_area = area_tri_signed_v3(v1, v2, v3, normal);
+ total_area += tri_area;
+
+ cent_tri_v3(tri_cent, v1, v2, v3);
+ madd_v3_v3fl(cent, tri_cent, tri_area);
+
+ copy_v3_v3(v2, v3);
+ }
+
+ mul_v3_fl(cent, 1.0f / total_area);
+
+ return total_area;
+}
+
+/**
+ * This function takes the difference between 2 vertex-coord-arrays
+ * (\a vert_cos_src, \a vert_cos_dst),
+ * and applies the difference to \a vert_cos_new relative to \a vert_cos_org.
+ *
+ * \param vert_cos_src reference deform source.
+ * \param vert_cos_dst reference deform destination.
+ *
+ * \param vert_cos_org reference for the output location.
+ * \param vert_cos_new resulting coords.
+ */
+void BKE_mesh_calc_relative_deform(
+ const MPoly *mpoly, const int totpoly,
+ const MLoop *mloop, const int totvert,
+
+ const float (*vert_cos_src)[3],
+ const float (*vert_cos_dst)[3],
+
+ const float (*vert_cos_org)[3],
+ float (*vert_cos_new)[3])
+{
+ const MPoly *mp;
+ int i;
+
+ int *vert_accum = MEM_callocN(sizeof(*vert_accum) * totvert, __func__);
+
+ memset(vert_cos_new, '\0', sizeof(*vert_cos_new) * totvert);
+
+ for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
+ const MLoop *loopstart = mloop + mp->loopstart;
+ int j;
+
+ for (j = 0; j < mp->totloop; j++) {
+ int v_prev = (loopstart + ((mp->totloop + (j - 1)) % mp->totloop))->v;
+ int v_curr = (loopstart + j)->v;
+ int v_next = (loopstart + ((j + 1) % mp->totloop))->v;
+
+ float tvec[3];
+
+ barycentric_transform(
+ tvec, vert_cos_dst[v_curr],
+ vert_cos_org[v_prev], vert_cos_org[v_curr], vert_cos_org[v_next],
+ vert_cos_src[v_prev], vert_cos_src[v_curr], vert_cos_src[v_next]
+ );
+
+ add_v3_v3(vert_cos_new[v_curr], tvec);
+ vert_accum[v_curr] += 1;
+ }
+ }
+
+ for (i = 0; i < totvert; i++) {
+ if (vert_accum[i]) {
+ mul_v3_fl(vert_cos_new[i], 1.0f / (float)vert_accum[i]);
+ }
+ else {
+ copy_v3_v3(vert_cos_new[i], vert_cos_org[i]);
+ }
+ }
+
+ MEM_freeN(vert_accum);
+}
+
/* Find the index of the loop in 'poly' which references vertex,
* returns -1 if not found */
int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart,
@@ -3110,6 +3169,107 @@ void BKE_mesh_flush_hidden_from_verts(const MVert *mvert,
}
}
+/**
+ * simple poly -> vert/edge selection.
+ */
+void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, const int totvert,
+ MLoop *mloop,
+ MEdge *medge, const int totedge,
+ const MPoly *mpoly, const int totpoly)
+{
+ MVert *mv;
+ MEdge *med;
+ const MPoly *mp;
+ int i;
+
+ i = totvert;
+ for (mv = mvert; i--; mv++) {
+ mv->flag &= ~SELECT;
+ }
+
+ i = totedge;
+ for (med = medge; i--; med++) {
+ med->flag &= ~SELECT;
+ }
+
+ i = totpoly;
+ for (mp = mpoly; i--; mp++) {
+ /* assume if its selected its not hidden and none of its verts/edges are hidden
+ * (a common assumption)*/
+ if (mp->flag & ME_FACE_SEL) {
+ MLoop *ml;
+ int j;
+ j = mp->totloop;
+ for (ml = &mloop[mp->loopstart]; j--; ml++) {
+ mvert[ml->v].flag |= SELECT;
+ medge[ml->e].flag |= SELECT;
+ }
+ }
+ }
+}
+void BKE_mesh_flush_select_from_polys(Mesh *me)
+{
+ BKE_mesh_flush_select_from_polys_ex(me->mvert, me->totvert,
+ me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
+}
+
+void BKE_mesh_flush_select_from_verts_ex(const MVert *mvert, const int UNUSED(totvert),
+ MLoop *mloop,
+ MEdge *medge, const int totedge,
+ MPoly *mpoly, const int totpoly)
+{
+ MEdge *med;
+ MPoly *mp;
+ int i;
+
+ /* edges */
+ i = totedge;
+ for (med = medge; i--; med++) {
+ if ((med->flag & ME_HIDE) == 0) {
+ if ((mvert[med->v1].flag & SELECT) && (mvert[med->v2].flag & SELECT)) {
+ med->flag |= SELECT;
+ }
+ else {
+ med->flag &= ~SELECT;
+ }
+ }
+ }
+
+ /* polys */
+ i = totpoly;
+ for (mp = mpoly; i--; mp++) {
+ if ((mp->flag & ME_HIDE) == 0) {
+ int ok = TRUE;
+ MLoop *ml;
+ int j;
+ j = mp->totloop;
+ for (ml = &mloop[mp->loopstart]; j--; ml++) {
+ if ((mvert[ml->v].flag & SELECT) == 0) {
+ ok = FALSE;
+ break;
+ }
+ }
+
+ if (ok) {
+ mp->flag |= ME_FACE_SEL;
+ }
+ else {
+ mp->flag &= ~ME_FACE_SEL;
+ }
+ }
+ }
+}
+void BKE_mesh_flush_select_from_verts(Mesh *me)
+{
+ BKE_mesh_flush_select_from_verts_ex(me->mvert, me->totvert,
+ me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
+}
+
+
/* basic vertex data functions */
int BKE_mesh_minmax(Mesh *me, float r_min[3], float r_max[3])
{
@@ -3162,9 +3322,8 @@ int BKE_mesh_center_centroid(Mesh *me, float cent[3])
/* calculate a weighted average of polygon centroids */
for (mpoly = me->mpoly; i--; mpoly++) {
- BKE_mesh_calc_poly_center(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
- poly_area = BKE_mesh_calc_poly_area(mpoly, me->mloop + mpoly->loopstart, me->mvert, NULL);
-
+ poly_area = mesh_calc_poly_planar_area_centroid(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
+
madd_v3_v3fl(cent, poly_cent, poly_area);
total_area += poly_area;
}
@@ -3279,3 +3438,39 @@ void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop,
}
}
#endif
+
+
+void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
+{
+ if (UNLIKELY(mesh->cd_flag)) {
+ return;
+ }
+ else {
+ MVert *mv;
+ MEdge *med;
+ int i;
+
+ for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
+ if (mv->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ break;
+ }
+ }
+
+ for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
+ if (med->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ break;
+ }
+ }
+ if (med->crease != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ break;
+ }
+ }
+ }
+
+ }
+}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 25b70ce1793..2aeda614f07 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -621,16 +621,6 @@ int modifiers_isPreview(Object *ob)
return FALSE;
}
-int modifiers_indexInObject(Object *ob, ModifierData *md_seek)
-{
- int i = 0;
- ModifierData *md;
-
- for (md = ob->modifiers.first; (md && md_seek != md); md = md->next, i++) ;
- if (!md) return -1; /* modifier isn't in the object */
- return i;
-}
-
void modifier_freeTemporaryData(ModifierData *md)
{
if (md->type == eModifierType_Armature) {
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 381e4350391..a6c2325c740 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -40,7 +40,11 @@
#include "BKE_bmesh.h"
#include "BKE_tessmesh.h"
-/* main function for copying DerivedMesh data into BMesh */
+/**
+ * The main function for copying DerivedMesh data into BMesh.
+ *
+ * \note The mesh may already have geometry. see 'is_init'
+ */
void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
{
MVert *mv, *mvert;
@@ -55,7 +59,20 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
BLI_array_declare(verts);
BLI_array_declare(edges);
int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ;
- int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0);
+ bool is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0);
+ bool is_cddm = (dm->type == DM_TYPE_CDDM); /* duplicate the arrays for non cddm */
+ char has_orig_hflag = 0;
+
+ int cd_vert_bweight_offset;
+ int cd_edge_bweight_offset;
+ int cd_edge_crease_offset;
+
+ if (is_init == FALSE) {
+ /* check if we have an origflag */
+ has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0;
+ has_orig_hflag |= CustomData_has_layer(&bm->edata, CD_ORIGINDEX) ? BM_EDGE : 0;
+ has_orig_hflag |= CustomData_has_layer(&bm->pdata, CD_ORIGINDEX) ? BM_FACE : 0;
+ }
/*merge custom data layout*/
CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT);
@@ -63,38 +80,45 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP);
CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE);
+ if (is_init) {
+ BM_mesh_cd_flag_apply(bm, dm->cd_flag);
+ }
+
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
/* totface = dm->getNumPolys(dm); */ /* UNUSED */
- /* add crease layer */
- BM_data_layer_add(bm, &bm->edata, CD_CREASE);
- /* add bevel weight layers */
- BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
- BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
-
vtable = MEM_callocN(sizeof(void **) * totvert, __func__);
etable = MEM_callocN(sizeof(void **) * totedge, __func__);
/*do verts*/
- mv = mvert = dm->dupVertArray(dm);
+ mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm);
for (i = 0; i < totvert; i++, mv++) {
v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD);
normal_short_to_float_v3(v->no, mv->no);
v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
BM_elem_index_set(v, i); /* set_inline */
- CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data);
+ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true);
+ vtable[i] = v;
/* add bevel weight */
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f);
- vtable[i] = v;
+ if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mv->bweight / 255.0f);
+
+ if (UNLIKELY(has_orig_hflag & BM_VERT)) {
+ int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX);
+ *orig_index = ORIGINDEX_NONE;
+ }
}
- MEM_freeN(mvert);
+ if (!is_cddm) MEM_freeN(mvert);
if (is_init) bm->elem_index_dirty &= ~BM_VERT;
/*do edges*/
- me = medge = dm->dupEdgeArray(dm);
+ me = medge = is_cddm ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm);
for (i = 0; i < totedge; i++, me++) {
//BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL);
e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD);
@@ -102,15 +126,18 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
e->head.hflag = BM_edge_flag_from_mflag(me->flag);
BM_elem_index_set(e, i); /* set_inline */
- CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
+ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true);
etable[i] = e;
- /* add crease */
- BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f);
- /* add bevel weight */
- BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f);
+ if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)me->bweight / 255.0f);
+ if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)me->crease / 255.0f);
+
+ if (UNLIKELY(has_orig_hflag & BM_EDGE)) {
+ int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX);
+ *orig_index = ORIGINDEX_NONE;
+ }
}
- MEM_freeN(medge);
+ if (!is_cddm) MEM_freeN(medge);
if (is_init) bm->elem_index_dirty &= ~BM_EDGE;
/* do faces */
@@ -134,7 +161,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
edges[j] = etable[ml->e];
}
- f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD);
+ f = BM_face_create(bm, verts, edges, mp->totloop, BM_CREATE_SKIP_CD);
if (UNLIKELY(f == NULL)) {
continue;
@@ -147,10 +174,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) {
- CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data);
+ CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data, true);
}
- CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
+ CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);
if (face_normals) {
copy_v3_v3(f->no, face_normals[i]);
@@ -158,6 +185,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
else {
BM_face_normal_update(f);
}
+
+ if (UNLIKELY(has_orig_hflag & BM_FACE)) {
+ int *orig_index = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_ORIGINDEX);
+ *orig_index = ORIGINDEX_NONE;
+ }
}
if (is_init) bm->elem_index_dirty &= ~BM_FACE;
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 4156b5b4367..eceac61ddb6 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -216,7 +216,7 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
colorspace = clip->colorspace_settings.name;
}
- loadflag = IB_rect | IB_multilayer;
+ loadflag = IB_rect | IB_multilayer | IB_alphamode_detect;
/* read ibuf */
ibuf = IMB_loadiffname(name, loadflag, colorspace);
@@ -479,11 +479,11 @@ static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, i
/*********************** common functions *************************/
/* only image block itself */
-static MovieClip *movieclip_alloc(const char *name)
+static MovieClip *movieclip_alloc(Main *bmain, const char *name)
{
MovieClip *clip;
- clip = BKE_libblock_alloc(&G.main->movieclip, ID_MC, name);
+ clip = BKE_libblock_alloc(&bmain->movieclip, ID_MC, name);
clip->aspx = clip->aspy = 1.0f;
@@ -542,7 +542,7 @@ static void detect_clip_source(MovieClip *clip)
* otherwise creates new.
* does not load ibuf itself
* pass on optional frame for #name images */
-MovieClip *BKE_movieclip_file_add(const char *name)
+MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
{
MovieClip *clip;
int file, len;
@@ -550,7 +550,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
char str[FILE_MAX], strtest[FILE_MAX];
BLI_strncpy(str, name, sizeof(str));
- BLI_path_abs(str, G.main->name);
+ BLI_path_abs(str, bmain->name);
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
@@ -559,7 +559,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
close(file);
/* ** first search an identical clip ** */
- for (clip = G.main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
BLI_strncpy(strtest, clip->name, sizeof(clip->name));
BLI_path_abs(strtest, G.main->name);
@@ -580,7 +580,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
len--;
libname = name + len;
- clip = movieclip_alloc(libname);
+ clip = movieclip_alloc(bmain, libname);
BLI_strncpy(clip->name, name, sizeof(clip->name));
detect_clip_source(clip);
@@ -1325,7 +1325,7 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data;
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index c737dccc5d2..722e1f2b918 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -43,9 +43,9 @@
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
@@ -379,7 +379,7 @@ void multires_force_update(Object *ob)
ob->derivedFinal = NULL;
}
if (ob->sculpt && ob->sculpt->pbvh) {
- BLI_pbvh_free(ob->sculpt->pbvh);
+ BKE_pbvh_free(ob->sculpt->pbvh);
ob->sculpt->pbvh = NULL;
}
}
@@ -1407,7 +1407,7 @@ void multires_stitch_grids(Object *ob)
int totface;
if (ccgdm->pbvh) {
- BLI_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void ***)&faces, &totface);
+ BKE_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void ***)&faces, &totface);
if (totface) {
ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface);
@@ -1559,7 +1559,7 @@ static void old_mdisps_convert(MFace *mface, MDisps *mdisp)
if (S == 1) { (*out)[1] = -(*out)[1]; }
else if (S == 2) { SWAP(float, (*out)[0], (*out)[1]); }
else if (S == 3) { (*out)[0] = -(*out)[0]; }
- else if (S == 0) { SWAP(float, (*out)[0], (*out)[1]); (*out)[0] = -(*out)[0]; (*out)[1] = -(*out)[1]; };
+ else if (S == 0) { SWAP(float, (*out)[0], (*out)[1]); (*out)[0] = -(*out)[0]; (*out)[1] = -(*out)[1]; }
}
}
}
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 6f585198524..143f2186020 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1447,9 +1447,9 @@ void BKE_nla_validate_state(AnimData *adt)
if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
/* 1) First strip must be set to extend hold, otherwise, stuff before acts dodgy
* 2) Only overwrite extend mode if *not* changing it will most probably result in
- * occlusion problems, which will occur iff
- * - blendmode = REPLACE
- * - all channels the same (this is fiddly to test, so is currently assumed)
+ * occlusion problems, which will occur if...
+ * - blendmode = REPLACE
+ * - all channels the same (this is fiddly to test, so is currently assumed)
*
* Should fix problems such as [#29869]
*/
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 17dcf34b71f..86fe47268d6 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -656,7 +656,7 @@ void nodeDetachNode(struct bNode *node)
}
}
-bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
+bNodeTree *ntreeAddTree(Main *bmain, const char *name, int type, int nodetype)
{
bNodeTree *ntree;
bNodeType *ntype;
@@ -670,7 +670,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
BLI_strncpy(ntree->id.name + 2, name, sizeof(ntree->id.name));
}
else
- ntree = BKE_libblock_alloc(&G.main->nodetree, ID_NT, name);
+ ntree = BKE_libblock_alloc(&bmain->nodetree, ID_NT, name);
ntree->type = type;
ntree->nodetype = nodetype;
@@ -1035,9 +1035,6 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
*/
if (ntree->execdata) {
switch (ntree->type) {
- case NTREE_COMPOSIT:
- ntreeCompositEndExecTree(ntree->execdata, 1);
- break;
case NTREE_SHADER:
ntreeShaderEndExecTree(ntree->execdata, 1);
break;
@@ -1161,11 +1158,11 @@ void ntreeSetOutput(bNodeTree *ntree)
bNodeTree *ntreeFromID(ID *id)
{
switch (GS(id->name)) {
- case ID_MA: return ((Material*)id)->nodetree;
- case ID_LA: return ((Lamp*)id)->nodetree;
- case ID_WO: return ((World*)id)->nodetree;
- case ID_TE: return ((Tex*)id)->nodetree;
- case ID_SCE: return ((Scene*)id)->nodetree;
+ case ID_MA: return ((Material *)id)->nodetree;
+ case ID_LA: return ((Lamp *)id)->nodetree;
+ case ID_WO: return ((World *)id)->nodetree;
+ case ID_TE: return ((Tex *)id)->nodetree;
+ case ID_SCE: return ((Scene *)id)->nodetree;
default: return NULL;
}
}
@@ -1637,7 +1634,7 @@ void BKE_node_clipboard_add_node(bNode *node)
{
#ifdef USE_NODE_CB_VALIDATE
/* add extra info */
- bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), STRINGIFY(bNodeClipboardExtraInfo));
+ bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), "bNodeClipboardExtraInfo");
node_info->id = node->id;
if (node->id) {
@@ -2031,9 +2028,8 @@ void node_type_base(bNodeTreeType *ttype, bNodeType *ntype, int type, const char
ntype->update_internal_links = ttype->update_internal_links;
/* default size values */
- ntype->width = 140;
- ntype->minwidth = 100;
- ntype->maxwidth = 320;
+ node_type_size_preset(ntype, NODE_SIZE_DEFAULT);
+
ntype->height = 100;
ntype->minheight = 30;
ntype->maxheight = FLT_MAX;
@@ -2065,6 +2061,21 @@ void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwid
ntype->maxwidth = maxwidth;
}
+void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
+{
+ switch (size) {
+ case NODE_SIZE_DEFAULT:
+ node_type_size(ntype, 140, 100, 320);
+ break;
+ case NODE_SIZE_SMALL:
+ node_type_size(ntype, 100, 80, 320);
+ break;
+ case NODE_SIZE_LARGE:
+ node_type_size(ntype, 140, 120, 500);
+ break;
+ }
+}
+
void node_type_storage(bNodeType *ntype, const char *storagename, void (*freestoragefunc)(struct bNode *), void (*copystoragefunc)(struct bNode *, struct bNode *))
{
if (storagename)
@@ -2162,6 +2173,24 @@ void nodeRegisterType(bNodeTreeType *ttype, bNodeType *ntype)
if (found == NULL)
BLI_addtail(typelist, ntype);
+
+ /* Associate the RNA struct type with the bNodeType.
+ * Dynamically registered nodes will create an RNA type at runtime
+ * and call RNA_struct_blender_type_set, so this only needs to be done for old RNA types
+ * created in makesrna, which can not be associated to a bNodeType immediately,
+ * since bNodeTypes are registered afterward ...
+ */
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (ID == ntype->type) { \
+ StructRNA *srna = RNA_struct_find(STRINGIFY_ARG(Category##StructName)); \
+ BLI_assert(srna != NULL); \
+ RNA_struct_blender_type_set(srna, ntype); \
+ }
+
+ /* XXX hack, this file will be moved to the nodes folder in customnodes branch,
+ * then this stupid include path is not needed any more.
+ */
+ #include "intern/rna_nodetree_types.h"
}
static void registerCompositNodes(bNodeTreeType *ttype)
@@ -2305,6 +2334,7 @@ static void registerShaderNodes(bNodeTreeType *ttype)
register_node_type_sh_layer_weight(ttype);
register_node_type_sh_tex_coord(ttype);
register_node_type_sh_particle_info(ttype);
+ register_node_type_sh_hair_info(ttype);
register_node_type_sh_bump(ttype);
register_node_type_sh_script(ttype);
register_node_type_sh_tangent(ttype);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 47ca502d247..95b1809bbae 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -57,14 +57,15 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
+#include "DNA_property_types.h"
+#include "DNA_rigidbody_types.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
+#include "BKE_pbvh.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
@@ -73,6 +74,7 @@
#include "BKE_bullet.h"
#include "BKE_colortools.h"
#include "BKE_deform.h"
+#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_animsys.h"
#include "BKE_anim.h"
@@ -83,6 +85,7 @@
#include "BKE_fcurve.h"
#include "BKE_group.h"
#include "BKE_icons.h"
+#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
@@ -97,6 +100,7 @@
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_property.h"
+#include "BKE_rigidbody.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
@@ -264,20 +268,53 @@ void free_sculptsession_deformMats(SculptSession *ss)
ss->deform_imats = NULL;
}
+/* Write out the sculpt dynamic-topology BMesh to the Mesh */
+void sculptsession_bm_to_me(struct Object *ob, int reorder)
+{
+ if (ob && ob->sculpt) {
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->bm) {
+ if (ob->data) {
+ BMIter iter;
+ BMFace *efa;
+ BM_ITER_MESH (efa, &iter, ss->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_SMOOTH,
+ ss->bm_smooth_shading);
+ }
+ if (reorder)
+ BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
+ BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
+ }
+ }
+ }
+}
+
void free_sculptsession(Object *ob)
{
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
DerivedMesh *dm = ob->derivedFinal;
+ if (ss->bm) {
+ sculptsession_bm_to_me(ob, TRUE);
+ BM_mesh_free(ss->bm);
+ }
+
if (ss->pbvh)
- BLI_pbvh_free(ss->pbvh);
+ BKE_pbvh_free(ss->pbvh);
+ if (ss->bm_log)
+ BM_log_free(ss->bm_log);
+
if (dm && dm->getPBVH)
dm->getPBVH(NULL, dm); /* signal to clear */
if (ss->texcache)
MEM_freeN(ss->texcache);
+ if (ss->tex_pool)
+ BKE_image_pool_free(ss->tex_pool);
+
if (ss->layer_co)
MEM_freeN(ss->layer_co);
@@ -349,9 +386,11 @@ void BKE_object_free(Object *ob)
free_controllers(&ob->controllers);
free_actuators(&ob->actuators);
- free_constraints(&ob->constraints);
+ BKE_free_constraints(&ob->constraints);
free_partdeflect(ob->pd);
+ BKE_rigidbody_free_object(ob);
+ BKE_rigidbody_free_constraint(ob);
if (ob->soft) sbFree(ob->soft);
if (ob->bsoft) bsbFree(ob->bsoft);
@@ -368,7 +407,8 @@ static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Objec
if (*obpoin == unlinkOb) {
*obpoin = NULL;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; // XXX: should this just be OB_RECALC_DATA?
+ // XXX: should this just be OB_RECALC_DATA?
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
@@ -402,14 +442,14 @@ void BKE_object_unlink(Object *ob)
obt->proxy = NULL;
if (obt->proxy_from == ob) {
obt->proxy_from = NULL;
- obt->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB);
}
if (obt->proxy_group == ob)
obt->proxy_group = NULL;
if (obt->parent == ob) {
obt->parent = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
modifiers_foreachObjectLink(obt, unlink_object__unlinkModifierLinks, ob);
@@ -419,22 +459,22 @@ void BKE_object_unlink(Object *ob)
if (cu->bevobj == ob) {
cu->bevobj = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
if (cu->taperobj == ob) {
cu->taperobj = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
if (cu->textoncurve == ob) {
cu->textoncurve = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
else if (obt->type == OB_ARMATURE && obt->pose) {
bPoseChannel *pchan;
for (pchan = obt->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -445,7 +485,7 @@ void BKE_object_unlink(Object *ob)
if (ct->tar == ob) {
ct->tar = NULL;
ct->subtarget[0] = '\0';
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
}
@@ -459,13 +499,13 @@ void BKE_object_unlink(Object *ob)
}
else if (ELEM(OB_MBALL, ob->type, obt->type)) {
if (BKE_mball_is_basis_for(obt, ob))
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
sca_remove_ob_poin(obt, ob);
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -476,7 +516,7 @@ void BKE_object_unlink(Object *ob)
if (ct->tar == ob) {
ct->tar = NULL;
ct->subtarget[0] = '\0';
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
}
@@ -488,12 +528,12 @@ void BKE_object_unlink(Object *ob)
/* object is deflector or field */
if (ob->pd) {
if (obt->soft)
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
/* cloth */
for (md = obt->modifiers.first; md; md = md->next)
if (md->type == eModifierType_Cloth)
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
/* strips */
@@ -522,14 +562,14 @@ void BKE_object_unlink(Object *ob)
for (; pt; pt = pt->next) {
if (pt->ob == ob) {
pt->ob = NULL;
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
break;
}
}
if (tpsys->target_ob == ob) {
tpsys->target_ob = NULL;
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
if (tpsys->part->dup_ob == ob)
@@ -564,7 +604,7 @@ void BKE_object_unlink(Object *ob)
}
}
if (ob->pd)
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
obt = obt->id.next;
@@ -729,6 +769,50 @@ void BKE_object_unlink(Object *ob)
}
}
+/* actual check for internal data, not context or flags */
+int BKE_object_is_in_editmode(Object *ob)
+{
+ if (ob->data == NULL)
+ return 0;
+
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ if (me->edit_btmesh)
+ return 1;
+ }
+ else if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
+
+ if (arm->edbo)
+ return 1;
+ }
+ else if (ob->type == OB_FONT) {
+ Curve *cu = ob->data;
+
+ if (cu->editfont)
+ return 1;
+ }
+ else if (ob->type == OB_MBALL) {
+ MetaBall *mb = ob->data;
+
+ if (mb->editelems)
+ return 1;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = ob->data;
+
+ if (lt->editlatt)
+ return 1;
+ }
+ else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
+ Curve *cu = ob->data;
+
+ if (cu->editnurb)
+ return 1;
+ }
+ return 0;
+}
+
int BKE_object_exists_check(Object *obtest)
{
Object *ob;
@@ -748,16 +832,16 @@ int BKE_object_exists_check(Object *obtest)
void *BKE_object_obdata_add_from_type(int type)
{
switch (type) {
- case OB_MESH: return BKE_mesh_add("Mesh");
- case OB_CURVE: return BKE_curve_add("Curve", OB_CURVE);
- case OB_SURF: return BKE_curve_add("Surf", OB_SURF);
- case OB_FONT: return BKE_curve_add("Text", OB_FONT);
- case OB_MBALL: return BKE_mball_add("Meta");
- case OB_CAMERA: return BKE_camera_add("Camera");
- case OB_LAMP: return BKE_lamp_add("Lamp");
- case OB_LATTICE: return BKE_lattice_add("Lattice");
- case OB_ARMATURE: return BKE_armature_add("Armature");
- case OB_SPEAKER: return BKE_speaker_add("Speaker");
+ case OB_MESH: return BKE_mesh_add(G.main, "Mesh");
+ case OB_CURVE: return BKE_curve_add(G.main, "Curve", OB_CURVE);
+ case OB_SURF: return BKE_curve_add(G.main, "Surf", OB_SURF);
+ case OB_FONT: return BKE_curve_add(G.main, "Text", OB_FONT);
+ case OB_MBALL: return BKE_mball_add(G.main, "Meta");
+ case OB_CAMERA: return BKE_camera_add(G.main, "Camera");
+ case OB_LAMP: return BKE_lamp_add(G.main, "Lamp");
+ case OB_LATTICE: return BKE_lattice_add(G.main, "Lattice");
+ case OB_ARMATURE: return BKE_armature_add(G.main, "Armature");
+ case OB_SPEAKER: return BKE_speaker_add(G.main, "Speaker");
case OB_EMPTY: return NULL;
default:
printf("BKE_object_obdata_add_from_type: Internal error, bad type: %d\n", type);
@@ -786,14 +870,14 @@ static const char *get_obdata_defname(int type)
}
/* more general add: creates minimum required data, but without vertices etc. */
-Object *BKE_object_add_only_object(int type, const char *name)
+Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
{
Object *ob;
if (!name)
name = get_obdata_defname(type);
- ob = BKE_libblock_alloc(&G.main->object, ID_OB, name);
+ ob = BKE_libblock_alloc(&bmain->object, ID_OB, name);
/* default object vars */
ob->type = type;
@@ -879,7 +963,7 @@ Object *BKE_object_add(struct Scene *scene, int type)
char name[MAX_ID_NAME];
BLI_strncpy(name, get_obdata_defname(type), sizeof(name));
- ob = BKE_object_add_only_object(type, name);
+ ob = BKE_object_add_only_object(G.main, type, name);
ob->data = BKE_object_obdata_add_from_type(type);
@@ -888,7 +972,7 @@ Object *BKE_object_add(struct Scene *scene, int type)
base = BKE_scene_base_add(scene, ob);
BKE_scene_base_deselect_all(scene);
BKE_scene_base_select(scene, base);
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
@@ -1085,7 +1169,7 @@ static void copy_object_pose(Object *obn, Object *ob)
}
for (con = chan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1145,13 +1229,13 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
copy_v3_v3(ob_tar->size, ob_src->size);
}
-static Object *object_copy_do(Object *ob, int copy_caches)
+Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
{
Object *obn;
ModifierData *md;
int a;
- obn = BKE_libblock_copy(&ob->id);
+ obn = BKE_libblock_copy_ex(bmain, &ob->id);
if (ob->totcol) {
obn->mat = MEM_dupallocN(ob->mat);
@@ -1185,7 +1269,7 @@ static Object *object_copy_do(Object *ob, int copy_caches)
BKE_pose_rebuild(obn, obn->data);
}
defgroup_copy_list(&obn->defbase, &ob->defbase);
- copy_constraints(&obn->constraints, &ob->constraints, TRUE);
+ BKE_copy_constraints(&obn->constraints, &ob->constraints, TRUE);
obn->mode = 0;
obn->sculpt = NULL;
@@ -1208,6 +1292,8 @@ static Object *object_copy_do(Object *ob, int copy_caches)
}
obn->soft = copy_softbody(ob->soft, copy_caches);
obn->bsoft = copy_bulletsoftbody(ob->bsoft);
+ obn->rigidbody_object = BKE_rigidbody_copy_object(ob);
+ obn->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob);
BKE_object_copy_particlesystems(obn, ob);
@@ -1225,13 +1311,7 @@ static Object *object_copy_do(Object *ob, int copy_caches)
/* copy objects, will re-initialize cached simulation data */
Object *BKE_object_copy(Object *ob)
{
- return object_copy_do(ob, FALSE);
-}
-
-/* copy objects, will duplicate cached simulation data */
-Object *BKE_object_copy_with_caches(Object *ob)
-{
- return object_copy_do(ob, TRUE);
+ return BKE_object_copy_ex(G.main, ob, FALSE);
}
static void extern_local_object(Object *ob)
@@ -1402,7 +1482,8 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
ob->proxy_group = gob;
id_lib_extern(&target->id);
- ob->recalc = target->recalc = OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DAG_id_tag_update(&target->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* copy transform
* - gob means this proxy comes from a group, just apply the matrix
@@ -1488,14 +1569,14 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
/* *************** CALC ****************** */
-void BKE_object_scale_to_mat3(Object *ob, float mat[][3])
+void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
{
float vec[3];
mul_v3_v3v3(vec, ob->size, ob->dscale);
size_to_mat3(mat, vec);
}
-void BKE_object_rot_to_mat3(Object *ob, float mat[][3])
+void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], short use_drot)
{
float rmat[3][3], dmat[3][3];
@@ -1526,10 +1607,13 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[][3])
}
/* combine these rotations */
- mul_m3_m3m3(mat, dmat, rmat);
+ if (use_drot)
+ mul_m3_m3m3(mat, dmat, rmat);
+ else
+ copy_m3_m3(mat, rmat);
}
-void BKE_object_mat3_to_rot(Object *ob, float mat[][3], short use_compat)
+void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], short use_compat)
{
switch (ob->rotmode) {
case ROT_MODE_QUAT:
@@ -1632,7 +1716,7 @@ void BKE_object_tfm_protected_restore(Object *ob,
}
/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
-void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const short use_parent)
+void BKE_object_apply_mat4(Object *ob, float mat[4][4], const short use_compat, const short use_parent)
{
float rot[3][3];
@@ -1661,7 +1745,7 @@ void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, c
/* BKE_object_mat3_to_rot handles delta rotations */
}
-void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */
+void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
{
float smat[3][3];
float rmat[3][3];
@@ -1671,11 +1755,11 @@ void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */
BKE_object_scale_to_mat3(ob, smat);
/* rot */
- BKE_object_rot_to_mat3(ob, rmat);
+ BKE_object_rot_to_mat3(ob, rmat, TRUE);
mul_m3_m3m3(mat, rmat, smat);
}
-void BKE_object_to_mat4(Object *ob, float mat[][4])
+void BKE_object_to_mat4(Object *ob, float mat[4][4])
{
float tmat[3][3];
@@ -1689,7 +1773,7 @@ void BKE_object_to_mat4(Object *ob, float mat[][4])
/* extern */
int enable_cu_speed = 1;
-static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
+static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4])
{
Curve *cu;
float vec[4], dir[3], quat[4], radius, ctime;
@@ -1722,7 +1806,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
CLAMP(ctime, 0.0f, 1.0f);
}
else {
- ctime = scene->r.cfra;
+ ctime = BKE_scene_frame_get(scene);
if (IS_EQF(cu->pathlen, 0.0f) == 0)
ctime /= cu->pathlen;
@@ -1773,7 +1857,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
}
}
-static void ob_parbone(Object *ob, Object *par, float mat[][4])
+static void ob_parbone(Object *ob, Object *par, float mat[4][4])
{
bPoseChannel *pchan;
float vec[3];
@@ -1792,12 +1876,19 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4])
}
/* get bone transform */
- copy_m4_m4(mat, pchan->pose_mat);
+ if (pchan->bone->flag & BONE_RELATIVE_PARENTING) {
+ /* the new option uses the root - expected bahaviour, but differs from old... */
+ /* XXX check on version patching? */
+ copy_m4_m4(mat, pchan->chan_mat);
+ }
+ else {
+ copy_m4_m4(mat, pchan->pose_mat);
- /* but for backwards compatibility, the child has to move to the tail */
- copy_v3_v3(vec, mat[1]);
- mul_v3_fl(vec, pchan->bone->length);
- add_v3_v3(mat[3], vec);
+ /* but for backwards compatibility, the child has to move to the tail */
+ copy_v3_v3(vec, mat[1]);
+ mul_v3_fl(vec, pchan->bone->length);
+ add_v3_v3(mat[3], vec);
+ }
}
static void give_parvert(Object *par, int nr, float vec[3])
@@ -1875,7 +1966,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
Curve *cu = par->data;
- ListBase *nurb = BKE_curve_nurbs_get(cu);;
+ ListBase *nurb = BKE_curve_nurbs_get(cu);
BKE_nurbList_index_get_co(nurb, nr, vec);
}
@@ -1903,7 +1994,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
}
-static void ob_parvert3(Object *ob, Object *par, float mat[][4])
+static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
{
float cmat[3][3], v1[3], v2[3], v3[3], q[4];
@@ -1926,12 +2017,12 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4])
else {
add_v3_v3v3(mat[3], v1, v2);
add_v3_v3(mat[3], v3);
- mul_v3_fl(mat[3], 0.3333333f);
+ mul_v3_fl(mat[3], 1.0f / 3.0f);
}
}
}
-static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul)
+static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], int simul)
{
float totmat[4][4];
float tmat[4][4];
@@ -2029,7 +2120,9 @@ static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[
return 1;
}
-void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
+/* note, scene is the active scene while actual_scene is the scene the object resides in */
+void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
+ RigidBodyWorld *rbw)
{
if (ob == NULL) return;
@@ -2054,14 +2147,19 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
else {
BKE_object_to_mat4(ob, ob->obmat);
}
+
+ /* try to fall back to the scene rigid body world if none given */
+ rbw = rbw ? rbw : scene->rigidbody_world;
+ /* read values pushed into RBO from sim/cache... */
+ BKE_rigidbody_sync_transforms(rbw, ob, ctime);
/* solve constraints */
if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
bConstraintOb *cob;
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- solve_constraints(&ob->constraints, cob, ctime);
- constraints_clear_evalob(cob);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ BKE_solve_constraints(&ob->constraints, cob, ctime);
+ BKE_constraints_clear_evalob(cob);
}
/* set negative scale flag in object */
@@ -2069,6 +2167,11 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
else ob->transflag &= ~OB_NEG_SCALE;
}
+void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
+{
+ BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL);
+}
+
/* get object transformation matrix without recalculating dependencies and
* constraints -- assume dependencies are already solved by depsgraph.
* no changes to object and it's parent would be done.
@@ -2090,15 +2193,19 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
}
}
-void BKE_object_where_is_calc(struct Scene *scene, Object *ob)
+void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
{
- BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra);
+ BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw);
+}
+void BKE_object_where_is_calc(Scene *scene, Object *ob)
+{
+ BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL);
}
-void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
/* was written for the old game engine (until 2.04) */
/* It seems that this function is only called
* for a lamp that is the child of another object */
+void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
{
Object *par;
float *fp1, *fp2;
@@ -2130,9 +2237,9 @@ void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
if (ob->constraints.first) {
bConstraintOb *cob;
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
- constraints_clear_evalob(cob);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ BKE_solve_constraints(&ob->constraints, cob, BKE_scene_frame_get(scene));
+ BKE_constraints_clear_evalob(cob);
}
}
@@ -2528,7 +2635,9 @@ int BKE_object_parent_loop_check(const Object *par, const Object *ob)
/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
/* requires flags to be set! */
-void BKE_object_handle_update(Scene *scene, Object *ob)
+/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
+void BKE_object_handle_update_ex(Scene *scene, Object *ob,
+ RigidBodyWorld *rbw)
{
if (ob->recalc & OB_RECALC_ALL) {
/* speed optimization for animation lookups */
@@ -2569,13 +2678,13 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
}
else
- BKE_object_where_is_calc(scene, ob);
+ BKE_object_where_is_calc_ex(scene, rbw, ob);
}
if (ob->recalc & OB_RECALC_DATA) {
ID *data_id = (ID *)ob->data;
AnimData *adt = BKE_animdata_from_id(data_id);
- float ctime = (float)scene->r.cfra; /* XXX this is bad... */
+ float ctime = BKE_scene_frame_get(scene);
if (G.debug & G_DEBUG)
printf("recalcdata %s\n", ob->id.name + 2);
@@ -2616,8 +2725,10 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
case OB_ARMATURE:
if (ob->id.lib && ob->proxy_from) {
- // printf("pose proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name);
- BKE_pose_copy_result(ob->pose, ob->proxy_from->pose);
+ if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
+ printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
+ ob->id.name + 2, ob->proxy_from->id.name + 2);
+ }
}
else {
BKE_pose_where_is(scene, ob);
@@ -2721,6 +2832,15 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
// printf("set proxy pointer for later group stuff %s\n", ob->id.name);
}
}
+/* WARNING: "scene" here may not be the scene object actually resides in.
+ * When dealing with background-sets, "scene" is actually the active scene.
+ * e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n
+ * rigid bodies depend on their world so use BKE_object_handle_update_ex() to also pass along the corrent rigid body world
+ */
+void BKE_object_handle_update(Scene *scene, Object *ob)
+{
+ BKE_object_handle_update_ex(scene, ob, NULL);
+}
void BKE_object_sculpt_modifiers_changed(Object *ob)
{
@@ -2731,7 +2851,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
* changing PVBH node organization, we hope topology does not change in
* the meantime .. weak */
if (ss->pbvh) {
- BLI_pbvh_free(ss->pbvh);
+ BKE_pbvh_free(ss->pbvh);
ss->pbvh = NULL;
}
@@ -2741,10 +2861,10 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
PBVHNode **nodes;
int n, totnode;
- BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
for (n = 0; n < totnode; n++)
- BLI_pbvh_node_mark_update(nodes[n]);
+ BKE_pbvh_node_mark_update(nodes[n]);
MEM_freeN(nodes);
}
@@ -2897,12 +3017,13 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
kb->data = data;
- kb->totelem = me->totvert;
+ kb->totelem = totelem;
}
return kb;
@@ -2934,11 +3055,12 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
- kb->totelem = lt->pntsu * lt->pntsv * lt->pntsw;
+ kb->totelem = totelem;
kb->data = data;
}
@@ -2973,11 +3095,12 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
- kb->totelem = BKE_nurbList_verts_count(lb);
+ kb->totelem = totelem;
kb->data = data;
}
@@ -3080,17 +3203,20 @@ void BKE_object_relink(Object *ob)
if (ob->id.lib)
return;
- relink_constraints(&ob->constraints);
+ BKE_relink_constraints(&ob->constraints);
if (ob->pose) {
bPoseChannel *chan;
for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
- relink_constraints(&chan->constraints);
+ BKE_relink_constraints(&chan->constraints);
}
}
modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
if (ob->adt)
BKE_relink_animdata(ob->adt);
+
+ if (ob->rigidbody_constraint)
+ BKE_rigidbody_relink_constraint(ob->rigidbody_constraint);
ID_NEW(ob->parent);
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index e694a7e7eb3..695ac7da792 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -35,18 +35,16 @@
#include "DNA_scene_types.h"
-#include "BKE_image.h"
-#include "BKE_ocean.h"
-#include "BKE_global.h" // XXX TESTING
-
-#include "BLI_math_base.h"
-#include "BLI_math_inline.h"
+#include "BLI_math.h"
+#include "BLI_path_util.h"
#include "BLI_rand.h"
#include "BLI_string.h"
#include "BLI_threads.h"
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
+#include "BKE_image.h"
+#include "BKE_ocean.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -54,7 +52,7 @@
#ifdef WITH_OCEANSIM
-// Ocean code
+/* Ocean code */
#include "fftw3.h"
#define GRAVITY 9.81f
@@ -82,7 +80,7 @@ typedef struct Ocean {
float _Lx;
float _Lz;
- float normalize_factor; // init w
+ float normalize_factor; /* init w */
float time;
short _do_disp_y;
@@ -96,51 +94,52 @@ typedef struct Ocean {
/* ********* sim data arrays ********* */
/* two dimensional arrays of complex */
- fftw_complex *_fft_in; // init w sim w
- fftw_complex *_fft_in_x; // init w sim w
- fftw_complex *_fft_in_z; // init w sim w
- fftw_complex *_fft_in_jxx; // init w sim w
- fftw_complex *_fft_in_jzz; // init w sim w
- fftw_complex *_fft_in_jxz; // init w sim w
- fftw_complex *_fft_in_nx; // init w sim w
- fftw_complex *_fft_in_nz; // init w sim w
- fftw_complex *_htilda; // init w sim w (only once)
+ fftw_complex *_fft_in; /* init w sim w */
+ fftw_complex *_fft_in_x; /* init w sim w */
+ fftw_complex *_fft_in_z; /* init w sim w */
+ fftw_complex *_fft_in_jxx; /* init w sim w */
+ fftw_complex *_fft_in_jzz; /* init w sim w */
+ fftw_complex *_fft_in_jxz; /* init w sim w */
+ fftw_complex *_fft_in_nx; /* init w sim w */
+ fftw_complex *_fft_in_nz; /* init w sim w */
+ fftw_complex *_htilda; /* init w sim w (only once) */
/* fftw "plans" */
- fftw_plan _disp_y_plan; // init w sim r
- fftw_plan _disp_x_plan; // init w sim r
- fftw_plan _disp_z_plan; // init w sim r
- fftw_plan _N_x_plan; // init w sim r
- fftw_plan _N_z_plan; // init w sim r
- fftw_plan _Jxx_plan; // init w sim r
- fftw_plan _Jxz_plan; // init w sim r
- fftw_plan _Jzz_plan; // init w sim r
+ fftw_plan _disp_y_plan; /* init w sim r */
+ fftw_plan _disp_x_plan; /* init w sim r */
+ fftw_plan _disp_z_plan; /* init w sim r */
+ fftw_plan _N_x_plan; /* init w sim r */
+ fftw_plan _N_z_plan; /* init w sim r */
+ fftw_plan _Jxx_plan; /* init w sim r */
+ fftw_plan _Jxz_plan; /* init w sim r */
+ fftw_plan _Jzz_plan; /* init w sim r */
/* two dimensional arrays of float */
- double *_disp_y; // init w sim w via plan?
- double *_N_x; // init w sim w via plan?
- /*float * _N_y; all member of this array has same values, so convert this array to a float to reduce memory usage (MEM01)*/
- double _N_y; // sim w ********* can be rearranged?
- double *_N_z; // init w sim w via plan?
- double *_disp_x; // init w sim w via plan?
- double *_disp_z; // init w sim w via plan?
+ double *_disp_y; /* init w sim w via plan? */
+ double *_N_x; /* init w sim w via plan? */
+ /* all member of this array has same values, so convert this array to a float to reduce memory usage (MEM01)*/
+ /*float * _N_y; */
+ double _N_y; /* sim w ********* can be rearranged? */
+ double *_N_z; /* init w sim w via plan? */
+ double *_disp_x; /* init w sim w via plan? */
+ double *_disp_z; /* init w sim w via plan? */
/* two dimensional arrays of float */
/* Jacobian and minimum eigenvalue */
- double *_Jxx; // init w sim w
- double *_Jzz; // init w sim w
- double *_Jxz; // init w sim w
+ double *_Jxx; /* init w sim w */
+ double *_Jzz; /* init w sim w */
+ double *_Jxz; /* init w sim w */
/* one dimensional float array */
- float *_kx; // init w sim r
- float *_kz; // init w sim r
+ float *_kx; /* init w sim r */
+ float *_kz; /* init w sim r */
/* two dimensional complex array */
- fftw_complex *_h0; // init w sim r
- fftw_complex *_h0_minus; // init w sim r
+ fftw_complex *_h0; /* init w sim r */
+ fftw_complex *_h0_minus; /* init w sim r */
/* two dimensional float array */
- float *_k; // init w sim r
+ float *_k; /* init w sim r */
} Ocean;
@@ -152,10 +151,13 @@ static float nextfr(float min, float max)
static float gaussRand(void)
{
- float x; // Note: to avoid numerical problems with very small
- float y; // numbers, we make these variables singe-precision
- float length2; // floats, but later we call the double-precision log()
- // and sqrt() functions instead of logf() and sqrtf().
+ /* Note: to avoid numerical problems with very small numbers, we make these variables singe-precision floats,
+ * but later we call the double-precision log() and sqrt() functions instead of logf() and sqrtf().
+ */
+ float x;
+ float y;
+ float length2;
+
do {
x = (float) (nextfr(-1, 1));
y = (float)(nextfr(-1, 1));
@@ -167,12 +169,7 @@ static float gaussRand(void)
/**
* Some useful functions
- * */
-MINLINE float lerp(float a, float b, float f)
-{
- return a + (b - a) * f;
-}
-
+ */
MINLINE float catrom(float p0, float p1, float p2, float p3, float f)
{
return 0.5f * ((2.0f * p1) +
@@ -186,23 +183,24 @@ MINLINE float omega(float k, float depth)
return sqrtf(GRAVITY * k * tanhf(k * depth));
}
-// modified Phillips spectrum
+/* modified Phillips spectrum */
static float Ph(struct Ocean *o, float kx, float kz)
{
float tmp;
float k2 = kx * kx + kz * kz;
if (k2 == 0.0f) {
- return 0.0f; // no DC component
+ return 0.0f; /* no DC component */
}
- // damp out the waves going in the direction opposite the wind
+ /* damp out the waves going in the direction opposite the wind */
tmp = (o->_wx * kx + o->_wz * kz) / sqrtf(k2);
if (tmp < 0) {
tmp *= o->_damp_reflections;
}
- return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) * powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
+ return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) *
+ powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
}
static void compute_eigenstuff(struct OceanResult *ocr, float jxx, float jzz, float jxz)
@@ -240,7 +238,7 @@ static void init_complex(fftw_complex cmpl, float real, float image)
cmpl[1] = image;
}
-#if 0 // unused
+#if 0 /* unused */
static void add_complex_f(fftw_complex res, fftw_complex cmpl, float f)
{
res[0] = cmpl[0] + f;
@@ -306,7 +304,7 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
float frac_x, frac_z;
float uu, vv;
- // first wrap the texture so 0 <= (u, v) < 1
+ /* first wrap the texture so 0 <= (u, v) < 1 */
u = fmodf(u, 1.0f);
v = fmodf(v, 1.0f);
@@ -334,7 +332,9 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
j1 = j1 % oc->_N;
-#define BILERP(m) (lerp(lerp(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], frac_x), lerp(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], frac_x), frac_z))
+#define BILERP(m) (interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
+ interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
+ frac_z))
{
if (oc->_do_disp_y) {
ocr->disp[1] = BILERP(oc->_disp_y);
@@ -364,14 +364,14 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
BLI_rw_mutex_unlock(&oc->oceanmutex);
}
-// use catmullrom interpolation rather than linear
+/* use catmullrom interpolation rather than linear */
void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
{
int i0, i1, i2, i3, j0, j1, j2, j3;
float frac_x, frac_z;
float uu, vv;
- // first wrap the texture so 0 <= (u, v) < 1
+ /* first wrap the texture so 0 <= (u, v) < 1 */
u = fmod(u, 1.0f);
v = fmod(v, 1.0f);
@@ -408,11 +408,15 @@ void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u
j0 = j0 < 0 ? j0 + oc->_N : j0;
j3 = j3 >= oc->_N ? j3 - oc->_N : j3;
-#define INTERP(m) catrom(catrom(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], m[i2 * oc->_N + j0], m[i3 * oc->_N + j0], frac_x), \
- catrom(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], m[i2 * oc->_N + j1], m[i3 * oc->_N + j1], frac_x), \
- catrom(m[i0 * oc->_N + j2], m[i1 * oc->_N + j2], m[i2 * oc->_N + j2], m[i3 * oc->_N + j2], frac_x), \
- catrom(m[i0 * oc->_N + j3], m[i1 * oc->_N + j3], m[i2 * oc->_N + j3], m[i3 * oc->_N + j3], frac_x), \
- frac_z)
+#define INTERP(m) catrom(catrom(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], \
+ m[i2 * oc->_N + j0], m[i3 * oc->_N + j0], frac_x), \
+ catrom(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], \
+ m[i2 * oc->_N + j1], m[i3 * oc->_N + j1], frac_x), \
+ catrom(m[i0 * oc->_N + j2], m[i1 * oc->_N + j2], \
+ m[i2 * oc->_N + j2], m[i3 * oc->_N + j2], frac_x), \
+ catrom(m[i0 * oc->_N + j3], m[i1 * oc->_N + j3], \
+ m[i2 * oc->_N + j3], m[i3 * oc->_N + j3], frac_x), \
+ frac_z)
{
if (oc->_do_disp_y) {
@@ -452,9 +456,9 @@ void BKE_ocean_eval_xz_catrom(struct Ocean *oc, struct OceanResult *ocr, float x
BKE_ocean_eval_uv_catrom(oc, ocr, x / oc->_Lx, z / oc->_Lz);
}
-// note that this doesn't wrap properly for i, j < 0, but its
-// not really meant for that being just a way to get the raw data out
-// to save in some image format.
+/* note that this doesn't wrap properly for i, j < 0, but its not really meant for that being just a way to get
+ * the raw data out to save in some image format.
+ */
void BKE_ocean_eval_ij(struct Ocean *oc, struct OceanResult *ocr, int i, int j)
{
BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
@@ -496,11 +500,10 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
- // compute a new htilda
+ /* compute a new htilda */
#pragma omp parallel for private(i, j)
for (i = 0; i < o->_M; ++i) {
- // note the <= _N/2 here, see the fftw doco about
- // the mechanics of the complex->real fft storage
+ /* note the <= _N/2 here, see the fftw doco about the mechanics of the complex->real fft storage */
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex exp_param1;
fftw_complex exp_param2;
@@ -527,15 +530,15 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
#pragma omp section
{
if (o->_do_disp_y) {
- // y displacement
+ /* y displacement */
fftw_execute(o->_disp_y_plan);
}
- } // section 1
+ } /* section 1 */
#pragma omp section
{
if (o->_do_chop) {
- // x displacement
+ /* x displacement */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
@@ -546,18 +549,21 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, minus_i);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_x[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_disp_x_plan);
}
- } //section 2
+ } /* section 2 */
#pragma omp section
{
if (o->_do_chop) {
- // z displacement
+ /* z displacement */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
@@ -568,28 +574,34 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, minus_i);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_z[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_disp_z_plan);
}
- } // section 3
+ } /* section 3 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jxx
+ /* Jxx */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jxx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
@@ -601,22 +613,25 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
}
}
}
- } // section 4
+ } /* section 4 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jzz
+ /* Jzz */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jzz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
@@ -627,32 +642,35 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
}
}
}
- } // section 5
+ } /* section 5 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jxz
+ /* Jxz */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jxz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_Jxz_plan);
}
- } // section 6
+ } /* section 6 */
#pragma omp section
{
- // fft normals
+ /* fft normals */
if (o->_do_normals) {
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
@@ -667,7 +685,7 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
fftw_execute(o->_N_x_plan);
}
- } // section 7
+ } /* section 7 */
#pragma omp section
{
@@ -694,9 +712,9 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
#endif
o->_N_y = 1.0f / scale;
}
- } // section 8
+ } /* section 8 */
- } // omp sections
+ } /* omp sections */
BLI_rw_mutex_unlock(&o->oceanmutex);
}
@@ -726,7 +744,8 @@ static void set_height_normalize_factor(struct Ocean *oc)
BLI_rw_mutex_unlock(&oc->oceanmutex);
- if (max_h == 0.0f) max_h = 0.00001f; // just in case ...
+ if (max_h == 0.0f)
+ max_h = 0.00001f; /* just in case ... */
res = 1.0f / (max_h);
@@ -743,7 +762,8 @@ struct Ocean *BKE_add_ocean(void)
}
void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
- float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals, short do_jacobian, int seed)
+ float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
+ short do_jacobian, int seed)
{
int i, j, ii;
@@ -761,8 +781,8 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_Lx = Lx;
o->_Lz = Lz;
o->_wx = cos(w);
- o->_wz = -sin(w); // wave direction
- o->_L = V * V / GRAVITY; // largest wave for a given velocity V
+ o->_wz = -sin(w); /* wave direction */
+ o->_L = V * V / GRAVITY; /* largest wave for a given velocity V */
o->time = time;
o->_do_disp_y = do_height_field;
@@ -776,30 +796,30 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_kx = (float *) MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
o->_kz = (float *) MEM_mallocN(o->_N * sizeof(float), "ocean_kz");
- // make this robust in the face of erroneous usage
+ /* make this robust in the face of erroneous usage */
if (o->_Lx == 0.0f)
o->_Lx = 0.001f;
if (o->_Lz == 0.0f)
o->_Lz = 0.001f;
- // the +ve components and DC
+ /* the +ve components and DC */
for (i = 0; i <= o->_M / 2; ++i)
o->_kx[i] = 2.0f * (float)M_PI * i / o->_Lx;
- // the -ve components
+ /* the -ve components */
for (i = o->_M - 1, ii = 0; i > o->_M / 2; --i, ++ii)
o->_kx[i] = -2.0f * (float)M_PI * ii / o->_Lx;
- // the +ve components and DC
+ /* the +ve components and DC */
for (i = 0; i <= o->_N / 2; ++i)
o->_kz[i] = 2.0f * (float)M_PI * i / o->_Lz;
- // the -ve components
+ /* the -ve components */
for (i = o->_N - 1, ii = 0; i > o->_N / 2; --i, ++ii)
o->_kz[i] = -2.0f * (float)M_PI * ii / o->_Lz;
- // pre-calculate the k matrix
+ /* pre-calculate the k matrix */
for (i = 0; i < o->_M; ++i)
for (j = 0; j <= o->_N / 2; ++j)
o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
@@ -819,11 +839,11 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
}
}
- o->_fft_in = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
- o->_htilda = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
+ o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
+ o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
if (o->_do_disp_y) {
- o->_disp_y = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
+ o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
}
@@ -831,32 +851,35 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_fft_in_nx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nx");
o->_fft_in_nz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nz");
- o->_N_x = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
+ o->_N_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
/* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */
- o->_N_z = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
+ o->_N_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE);
o->_N_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nz, o->_N_z, FFTW_ESTIMATE);
}
if (o->_do_chop) {
- o->_fft_in_x = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
- o->_fft_in_z = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");
+ o->_fft_in_x = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
+ o->_fft_in_z = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");
- o->_disp_x = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
- o->_disp_z = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
+ o->_disp_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
+ o->_disp_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
o->_disp_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_x, o->_disp_x, FFTW_ESTIMATE);
o->_disp_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_z, o->_disp_z, FFTW_ESTIMATE);
}
if (o->_do_jacobian) {
- o->_fft_in_jxx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jxx");
- o->_fft_in_jzz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jzz");
- o->_fft_in_jxz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jxz");
+ o->_fft_in_jxx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jxx");
+ o->_fft_in_jzz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jzz");
+ o->_fft_in_jxz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jxz");
- o->_Jxx = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
- o->_Jzz = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
- o->_Jxz = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
+ o->_Jxx = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
+ o->_Jzz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
+ o->_Jxz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
o->_Jxx_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxx, o->_Jxx, FFTW_ESTIMATE);
o->_Jzz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jzz, o->_Jzz, FFTW_ESTIMATE);
@@ -967,7 +990,7 @@ static void cache_filename(char *string, const char *path, const char *relbase,
BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
- BKE_makepicstring(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, 1, TRUE);
+ BKE_makepicstring_from_type(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, 1, TRUE);
}
/* silly functions but useful to inline when the args do a lot of indirections */
@@ -1076,8 +1099,7 @@ void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, in
}
}
-struct OceanCache *BKE_init_ocean_cache(const char *bakepath, const char *relbase,
- int start, int end, float wave_scale,
+struct OceanCache *BKE_init_ocean_cache(const char *bakepath, const char *relbase, int start, int end, float wave_scale,
float chop_amount, float foam_coverage, float foam_fade, int resolution)
{
OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
@@ -1112,7 +1134,7 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
/* ibufs array is zero based, but filenames are based on frame numbers */
/* still need to clamp frame numbers to valid range of images on disk though */
CLAMP(frame, och->start, och->end);
- f = frame - och->start; // shift to 0 based
+ f = frame - och->start; /* shift to 0 based */
/* if image is already loaded in mem, return */
if (och->ibufs_disp[f] != NULL) return;
@@ -1121,22 +1143,35 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE);
och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_disp[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_disp[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM);
och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_foam[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_foam[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL);
och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_norm[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_norm[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
}
-void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data)
+void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel),
+ void *update_cb_data)
{
/* note: some of these values remain uninitialized unless certain options
* are enabled, take care that BKE_ocean_eval_ij() initializes a member
@@ -1197,13 +1232,13 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
pr = prev_foam[res_x * y + x];
}
- /* r = BLI_frand(); */ /* UNUSED */ // randomly reduce foam
+ /* r = BLI_frand(); */ /* UNUSED */ /* randomly reduce foam */
- //pr = pr * och->foam_fade; // overall fade
+ /* pr = pr * och->foam_fade; */ /* overall fade */
- // remember ocean coord sys is Y up!
- // break up the foam where height (Y) is low (wave valley),
- // and X and Z displacement is greatest
+ /* remember ocean coord sys is Y up!
+ * break up the foam where height (Y) is low (wave valley), and X and Z displacement is greatest
+ */
#if 0
vec[0] = ocr.disp[0];
@@ -1219,22 +1254,27 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f;
neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus;
- //if (ocr.disp[1] < 0.0 || r > och->foam_fade)
- // pr *= och->foam_fade;
+#if 0
+ if (ocr.disp[1] < 0.0 || r > och->foam_fade)
+ pr *= och->foam_fade;
- //pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
- //pr = pr * neg_disp * neg_eplus;
+ pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
+ pr = pr * neg_disp * neg_eplus;
+#endif
- if (pr < 1.0f) pr *= pr;
+ if (pr < 1.0f)
+ pr *= pr;
pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f);
-
- foam_result = pr + ocr.foam;
+ /* A full clamping should not be needed! */
+ foam_result = min_ff(pr + ocr.foam, 1.0f);
prev_foam[res_x * y + x] = foam_result;
+ /*foam_result = min_ff(foam_result, 1.0f); */
+
value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
}
@@ -1279,7 +1319,7 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
och->baked = 1;
}
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* stub */
typedef struct Ocean {
@@ -1297,8 +1337,9 @@ void BKE_ocean_eval_uv(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr)
{
}
-// use catmullrom interpolation rather than linear
-void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u), float UNUSED(v))
+/* use catmullrom interpolation rather than linear */
+void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u),
+ float UNUSED(v))
{
}
@@ -1306,7 +1347,8 @@ void BKE_ocean_eval_xz(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr)
{
}
-void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x), float UNUSED(z))
+void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x),
+ float UNUSED(z))
{
}
@@ -1325,8 +1367,10 @@ struct Ocean *BKE_add_ocean(void)
return oc;
}
-void BKE_init_ocean(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz), float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp),
- float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), short UNUSED(do_height_field), short UNUSED(do_chop), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
+void BKE_init_ocean(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz),
+ float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp),
+ float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), short UNUSED(do_height_field),
+ short UNUSED(do_chop), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
{
}
@@ -1351,17 +1395,19 @@ void BKE_free_ocean_cache(struct OceanCache *och)
MEM_freeN(och);
}
-void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), float UNUSED(u), float UNUSED(v))
+void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
+ float UNUSED(u), float UNUSED(v))
{
}
-void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), int UNUSED(i), int UNUSED(j))
+void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
+ int UNUSED(i), int UNUSED(j))
{
}
-OceanCache *BKE_init_ocean_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase),
- int UNUSED(start), int UNUSED(end), float UNUSED(wave_scale),
- float UNUSED(chop_amount), float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
+OceanCache *BKE_init_ocean_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase), int UNUSED(start),
+ int UNUSED(end), float UNUSED(wave_scale), float UNUSED(chop_amount),
+ float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
{
OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
@@ -1372,9 +1418,10 @@ void BKE_simulate_ocean_cache(struct OceanCache *UNUSED(och), int UNUSED(frame))
{
}
-void BKE_bake_ocean(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och), void (*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
+void BKE_bake_ocean(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och),
+ void (*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
{
/* unused */
(void)update_cb;
}
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index dec49f417ae..288e4ccde5d 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -43,9 +43,10 @@
#include "MEM_guardedalloc.h"
#include "DNA_image_types.h"
+#include "DNA_ID.h"
+#include "DNA_packedFile_types.h"
#include "DNA_sound_types.h"
#include "DNA_vfont_types.h"
-#include "DNA_packedFile_types.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -226,16 +227,19 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
return (pf);
}
+/* no libraries for now */
void packAll(Main *bmain, ReportList *reports)
{
Image *ima;
VFont *vfont;
bSound *sound;
+ int tot = 0;
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->packedfile == NULL && ima->id.lib == NULL) {
if (ima->source == IMA_SRC_FILE) {
ima->packedfile = newPackedFile(reports, ima->name, ID_BLEND_PATH(bmain, &ima->id));
+ tot ++;
}
else if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported",
@@ -244,13 +248,26 @@ void packAll(Main *bmain, ReportList *reports)
}
}
- for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next)
- if (vfont->packedfile == NULL && vfont->id.lib == NULL && BKE_vfont_is_builtin(vfont) == FALSE)
+ for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) {
+ if (vfont->packedfile == NULL && vfont->id.lib == NULL && BKE_vfont_is_builtin(vfont) == FALSE) {
vfont->packedfile = newPackedFile(reports, vfont->name, bmain->name);
+ tot ++;
+ }
+ }
- for (sound = bmain->sound.first; sound; sound = sound->id.next)
- if (sound->packedfile == NULL && sound->id.lib == NULL)
+ for (sound = bmain->sound.first; sound; sound = sound->id.next) {
+ if (sound->packedfile == NULL && sound->id.lib == NULL) {
sound->packedfile = newPackedFile(reports, sound->name, bmain->name);
+ tot++;
+ }
+ }
+
+ if (tot == 0)
+ BKE_report(reports, RPT_INFO, "No files have been packed");
+ else
+ BKE_reportf(reports, RPT_INFO, "Packed %d files", tot);
+
+
}
@@ -314,6 +331,9 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
BKE_reportf(reports, RPT_ERROR, "Error writing file '%s'", name);
ret_value = RET_ERROR;
}
+ else
+ BKE_reportf(reports, RPT_INFO, "Saved packed file to: %s", name);
+
close(file);
}
else {
@@ -437,6 +457,7 @@ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_na
case PF_USE_ORIGINAL:
/* if file exists use it */
if (BLI_exists(abs_name)) {
+ BKE_reportf(reports, RPT_INFO, "Use existing file (instead of packed): %s", abs_name);
temp = abs_name;
break;
}
@@ -538,6 +559,51 @@ int unpackImage(ReportList *reports, Image *ima, int how)
return(ret_value);
}
+int unpackLibraries(Main *bmain, ReportList *reports)
+{
+ Library *lib;
+ char *newname;
+ int ret_value = RET_ERROR;
+
+ for (lib = bmain->library.first; lib; lib = lib->id.next) {
+ if (lib->packedfile && lib->name[0]) {
+
+ newname = unpackFile(reports, lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
+ if (newname != NULL) {
+ ret_value = RET_OK;
+
+ printf("Unpacked .blend library: %s\n", newname);
+
+ freePackedFile(lib->packedfile);
+ lib->packedfile = NULL;
+
+ MEM_freeN(newname);
+ }
+ }
+ }
+
+ return(ret_value);
+}
+
+void packLibraries(Main *bmain, ReportList *reports)
+{
+ Library *lib;
+
+ /* test for relativenss */
+ for (lib = bmain->library.first; lib; lib = lib->id.next)
+ if (0 == BLI_path_is_rel(lib->name))
+ break;
+
+ if (lib) {
+ BKE_reportf(reports, RPT_ERROR, "Cannot pack absolute file: '%s'", lib->name);
+ return;
+ }
+
+ for (lib = bmain->library.first; lib; lib = lib->id.next)
+ if (lib->packedfile == NULL)
+ lib->packedfile = newPackedFile(reports, lib->name, bmain->name);
+}
+
void unpackAll(Main *bmain, ReportList *reports, int how)
{
Image *ima;
@@ -557,3 +623,48 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
unpackSound(bmain, reports, sound, how);
}
+/* ID should be not NULL, return 1 if there's a packed file */
+int BKE_pack_check(ID *id)
+{
+ if (GS(id->name) == ID_IM) {
+ Image *ima = (Image *)id;
+ return ima->packedfile != NULL;
+ }
+ if (GS(id->name) == ID_VF) {
+ VFont *vf = (VFont *)id;
+ return vf->packedfile != NULL;
+ }
+ if (GS(id->name) == ID_SO) {
+ bSound *snd = (bSound *)id;
+ return snd->packedfile != NULL;
+ }
+ if (GS(id->name) == ID_LI) {
+ Library *li = (Library *)id;
+ return li->packedfile != NULL;
+ }
+ return 0;
+}
+
+/* ID should be not NULL */
+void BKE_unpack_id(Main *bmain, ID *id, ReportList *reports, int how)
+{
+ if (GS(id->name) == ID_IM) {
+ Image *ima = (Image *)id;
+ if (ima->packedfile)
+ unpackImage(reports, ima, how);
+ }
+ if (GS(id->name) == ID_VF) {
+ VFont *vf = (VFont *)id;
+ if (vf->packedfile)
+ unpackVFont(reports, vf, how);
+ }
+ if (GS(id->name) == ID_SO) {
+ bSound *snd = (bSound *)id;
+ if (snd->packedfile)
+ unpackSound(bmain, reports, snd, how);
+ }
+ if (GS(id->name) == ID_LI) {
+ Library *li = (Library *)id;
+ BKE_reportf(reports, RPT_ERROR, "Cannot unpack individual Library file, '%s'", li->name);
+ }
+}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 36f96045ced..d34d5eaa250 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -43,10 +43,13 @@
#include "BKE_brush.h"
#include "BKE_context.h"
+#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_paint.h"
#include "BKE_subsurf.h"
+#include "bmesh.h"
+
#include <stdlib.h>
#include <string.h>
@@ -154,7 +157,7 @@ int paint_facesel_test(Object *ob)
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
(ob->data != NULL) &&
- (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) &&
+ (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
(ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
);
}
@@ -165,7 +168,7 @@ int paint_vertsel_test(Object *ob)
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
(ob->data != NULL) &&
- (((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) &&
+ (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
(ob->mode & OB_MODE_WEIGHT_PAINT)
);
}
@@ -177,7 +180,7 @@ void BKE_paint_init(Paint *p, const char col[3])
/* If there's no brush, create one */
brush = paint_brush(p);
if (brush == NULL)
- brush = BKE_brush_add("Brush");
+ brush = BKE_brush_add(G.main, "Brush");
paint_brush_set(p, brush);
memcpy(p->paint_cursor_col, col, 3);
@@ -212,7 +215,7 @@ int paint_is_face_hidden(const MFace *f, const MVert *mvert)
}
/* returns non-zero if any of the corners of the grid
- * face whose inner corner is at (x,y) are hidden,
+ * face whose inner corner is at (x, y) are hidden,
* zero otherwise */
int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
int gridsize, int x, int y)
@@ -224,6 +227,22 @@ int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
BLI_BITMAP_GET(grid_hidden, (y + 1) * gridsize + x));
}
+/* Return TRUE if all vertices in the face are visible, FALSE otherwise */
+int paint_is_bmesh_face_hidden(BMFace *f)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ return false;
+}
+
float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
unsigned x, unsigned y)
{
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 5f5a713064d..f90fde983aa 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -55,7 +55,6 @@
#include "BLI_rand.h"
#include "BLI_threads.h"
#include "BLI_linklist.h"
-#include "BLI_bpath.h"
#include "BKE_anim.h"
#include "BKE_animsys.h"
@@ -680,13 +679,11 @@ static float psys_render_projected_area(ParticleSystem *psys, const float center
return area;
}
-void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset)
+void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset)
{
ParticleRenderData *data;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- if (G.is_rendering == FALSE)
- return;
if (psys->renderdata)
return;
@@ -1919,7 +1916,7 @@ 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], int smooth_start)
+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];
@@ -2385,7 +2382,7 @@ void psys_find_parents(ParticleSimulationData *sim)
int from = PART_FROM_FACE;
totparent = (int)(totchild * part->parents * 0.3f);
- if (G.is_rendering && part->child_nbr && part->ren_child_nbr)
+ if ((sim->psys->renderdata || G.is_rendering) && part->child_nbr && part->ren_child_nbr)
totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
tree = BLI_kdtree_new(totparent);
@@ -2462,7 +2459,7 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
if (totchild && part->childtype == PART_CHILD_FACES) {
totparent = (int)(totchild * part->parents * 0.3f);
- if (G.is_rendering && part->child_nbr && part->ren_child_nbr)
+ if ((psys->renderdata || G.is_rendering) && part->child_nbr && part->ren_child_nbr)
totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
/* part->parents could still be 0 so we can't test with totparent */
@@ -3351,7 +3348,7 @@ static void key_from_object(Object *ob, ParticleKey *key)
}
#endif
-static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[][4])
+static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[4][4])
{
float det, w1, w2, d1[2], d2[2];
@@ -3392,7 +3389,7 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat
cross_v3_v3v3(mat[0], mat[1], mat[2]);
}
-static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco)
+static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[4][4], int orco)
{
float v[3][3];
MFace *mface;
@@ -3425,7 +3422,7 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m
triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat);
}
-void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
{
float vec[3];
@@ -3440,7 +3437,7 @@ void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, Pa
copy_v3_v3(hairmat[3], vec);
}
-void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
{
float vec[3], orco[3];
@@ -3462,7 +3459,7 @@ void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float vec[3])
mul_mat3_m4_v3(mat, vec);
}
-void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
{
float facemat[4][4];
@@ -3512,12 +3509,12 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
psys->flag = PSYS_ENABLED | PSYS_CURRENT;
psys->cfra = BKE_scene_frame_get_from_ctime(scene, CFRA + 1);
- DAG_scene_sort(G.main, scene);
+ DAG_relations_tag_update(G.main);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
return md;
}
-void object_remove_particle_system(Scene *scene, Object *ob)
+void object_remove_particle_system(Scene *UNUSED(scene), Object *ob)
{
ParticleSystem *psys = psys_get_current(ob);
ParticleSystemModifierData *psmd;
@@ -3555,7 +3552,7 @@ void object_remove_particle_system(Scene *scene, Object *ob)
else
ob->mode &= ~OB_MODE_PARTICLE_EDIT;
- DAG_scene_sort(G.main, scene);
+ DAG_relations_tag_update(G.main);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
static void default_particle_settings(ParticleSettings *part)
@@ -3850,7 +3847,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
break;
}
- externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0);
+ externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL);
if ((event & mtex->mapto) & PAMAP_ROUGH)
ptex->rough1 = ptex->rough2 = ptex->roughe = texture_value_blend(def, ptex->rough1, value, mtex->roughfac, blend);
@@ -3921,7 +3918,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
break;
}
- externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0);
+ externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL);
if ((event & mtex->mapto) & PAMAP_TIME) {
/* the first time has to set the base value for time regardless of blend mode */
@@ -4502,7 +4499,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part,
psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco, 0);
}
-void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
+void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[4][4], float *scale)
{
Object *ob = sim->ob;
ParticleSystem *psys = sim->psys;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 90889d7c09e..3efe25794e1 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -23,7 +23,8 @@
* Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn.
*
* Adaptive time step
- * Copyright 2011 AutoCRC
+ * Classical SPH
+ * Copyright 2011-2012 AutoCRC
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -521,9 +522,9 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
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;
+ 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)) {
@@ -801,7 +802,7 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch
if (mface->v4)
psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
else
- psys_uv_to_w(0.33333f, 0.33333f, mface->v4, pa->fuv);
+ 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);
@@ -1889,7 +1890,6 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
}
-
if (part->type == PART_HAIR) {
pa->lifetime = 100.0f;
}
@@ -2390,33 +2390,37 @@ typedef struct SPHRangeData {
SPHNeighbor neighbors[SPH_NEIGHBORS];
int tot_neighbors;
- float density, near_density;
- float h;
+ float* data;
ParticleSystem *npsys;
ParticleData *pa;
+ float h;
+ float mass;
float massfac;
int use_size;
} SPHRangeData;
-typedef struct SPHData {
- ParticleSystem *psys[10];
- ParticleData *pa;
- float mass;
- EdgeHash *eh;
- float *gravity;
- /* Average distance to neighbors (other particles in the support domain),
- * for calculating the Courant number (adaptive time step). */
- int pass;
- float element_size;
- float flow[3];
-
- /* Integrator callbacks. This allows different SPH implementations. */
- void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
- void (*density_cb) (void *rangedata_v, int index, float squared_dist);
-} SPHData;
+static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], SPHRangeData *pfr, float interaction_radius, BVHTree_RangeQuery callback)
+{
+ int i;
+ pfr->tot_neighbors = 0;
+
+ for (i=0; i < 10 && psys[i]; i++) {
+ pfr->npsys = psys[i];
+ pfr->massfac = psys[i]->part->mass / pfr->mass;
+ pfr->use_size = psys[i]->part->flag & PART_SIZEMASS;
+
+ if (tree) {
+ BLI_bvhtree_range_query(tree, co, interaction_radius, callback, pfr);
+ break;
+ }
+ else {
+ BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr);
+ }
+ }
+}
static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
{
SPHRangeData *pfr = (SPHRangeData *)userdata;
@@ -2446,8 +2450,8 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
if (pfr->use_size)
q *= npa->size;
- pfr->density += q*q;
- pfr->near_density += q*q*q;
+ pfr->data[0] += q*q;
+ pfr->data[1] += q*q*q;
}
/*
@@ -2488,7 +2492,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
ParticleSpring *spring = NULL;
SPHRangeData pfr;
SPHNeighbor *pfn;
- float mass = sphdata->mass;
float *gravity = sphdata->gravity;
EdgeHash *springhash = sphdata->eh;
@@ -2498,10 +2501,12 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
float visc = fluid->viscosity_omega;
float stiff_visc = fluid->viscosity_beta * (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f);
- float inv_mass = 1.0f/mass;
+ float inv_mass = 1.0f / sphdata->mass;
float spring_constant = fluid->spring_k;
-
- float h = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.f*pa->size : 1.f); /* 4.0 seems to be a pretty good value */
+
+ /* 4.0 seems to be a pretty good value */
+ float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f);
+ float h = interaction_radius * sphdata->hfac;
float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f); /* 4.77 is an experimentally determined density factor */
float rest_length = fluid->rest_length * (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f);
@@ -2512,24 +2517,24 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
float vec[3];
float vel[3];
float co[3];
+ float data[2];
+ float density, near_density;
int i, spring_index, index = pa - psys[0]->particles;
- pfr.tot_neighbors = 0;
- pfr.density = pfr.near_density = 0.f;
+ data[0] = data[1] = 0;
+ pfr.data = data;
pfr.h = h;
pfr.pa = pa;
+ pfr.mass = sphdata->mass;
- for (i=0; i<10 && psys[i]; i++) {
- pfr.npsys = psys[i];
- pfr.massfac = psys[i]->part->mass*inv_mass;
- pfr.use_size = psys[i]->part->flag & PART_SIZEMASS;
+ sph_evaluate_func( NULL, psys, state->co, &pfr, interaction_radius, sph_density_accum_cb);
- BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr);
- }
+ density = data[0];
+ near_density = data[1];
- pressure = stiffness * (pfr.density - rest_density);
- near_pressure = stiffness_near_fac * pfr.near_density;
+ pressure = stiffness * (density - rest_density);
+ near_pressure = stiffness_near_fac * near_density;
pfn = pfr.neighbors;
for (i=0; i<pfr.tot_neighbors; i++, pfn++) {
@@ -2593,14 +2598,209 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
/* Artificial buoyancy force in negative gravity direction */
if (fluid->buoyancy > 0.f && gravity)
- madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density));
+ madd_v3_v3fl(force, gravity, fluid->buoyancy * (density-rest_density));
+
+ if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF)
+ sph_particle_courant(sphdata, &pfr);
+ 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;
+ ParticleData *npa = pfr->npsys->particles + index;
+ float q;
+ float qfac = 21.0f / (256.f * (float)M_PI);
+ float rij, rij_h;
+ float vec[3];
+
+ /* Exclude particles that are more than 2h away. Can't use squared_dist here
+ * because it is not accurate enough. Use current state, i.e. the output of
+ * basic_integrate() - z0r */
+ sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co);
+ rij = len_v3(vec);
+ rij_h = rij / pfr->h;
+ if (rij_h > 2.0f)
+ return;
+
+ /* 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 *= pfr->npsys->part->mass;
+
+ if (pfr->use_size)
+ q *= pfr->pa->size;
+
+ pfr->data[0] += q;
+ pfr->data[1] += q / npa->sphdensity;
+}
+
+static void sphclassical_neighbour_accum_cb(void *userdata, int index, float UNUSED(squared_dist))
+{
+ SPHRangeData *pfr = (SPHRangeData *)userdata;
+ ParticleData *npa = pfr->npsys->particles + index;
+ float rij, rij_h;
+ float vec[3];
+
+ if (pfr->tot_neighbors >= SPH_NEIGHBORS)
+ return;
+
+ /* Exclude particles that are more than 2h away. Can't use squared_dist here
+ * because it is not accurate enough. Use current state, i.e. the output of
+ * basic_integrate() - z0r */
+ sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co);
+ rij = len_v3(vec);
+ rij_h = rij / pfr->h;
+ if (rij_h > 2.0f)
+ return;
+
+ pfr->neighbors[pfr->tot_neighbors].index = index;
+ pfr->neighbors[pfr->tot_neighbors].psys = pfr->npsys;
+ pfr->tot_neighbors++;
+}
+static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse))
+{
+ SPHData *sphdata = (SPHData *)sphdata_v;
+ ParticleSystem **psys = sphdata->psys;
+ ParticleData *pa = sphdata->pa;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
+ SPHRangeData pfr;
+ SPHNeighbor *pfn;
+ float *gravity = sphdata->gravity;
+
+ float dq, u, rij, dv[3];
+ float pressure, npressure;
+
+ float visc = fluid->viscosity_omega;
+
+ float interaction_radius;
+ float h, hinv;
+ /* 4.77 is an experimentally determined density factor */
+ 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);
+
+ ParticleData *npa;
+ float vec[3];
+ float co[3];
+ float pressureTerm;
+
+ int i;
+
+ float qfac2 = 42.0f / (256.0f * (float)M_PI);
+ float rij_h;
+
+ /* 4.0 here is to be consistent with previous formulation/interface */
+ interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f);
+ h = interaction_radius * sphdata->hfac;
+ hinv = 1.0f / h;
+
+ pfr.h = h;
+ 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);
+
+ /* multiply by mass so that we return a force, not accel */
+ qfac2 *= sphdata->mass / pow3(pfr.h);
+
+ pfn = pfr.neighbors;
+ for (i = 0; i < pfr.tot_neighbors; i++, pfn++) {
+ npa = pfn->psys->particles + pfn->index;
+ if (npa == pa) {
+ /* we do not contribute to ourselves */
+ continue;
+ }
+
+ /* Find vector to neighbour. Exclude particles that are more than 2h
+ * away. Can't use current state here because it may have changed on
+ * another thread - so do own mini integration. Unlike basic_integrate,
+ * SPH integration depends on neighbouring particles. - z0r */
+ madd_v3_v3v3fl(co, npa->prev_state.co, npa->prev_state.vel, state->time);
+ sub_v3_v3v3(vec, co, state->co);
+ rij = normalize_v3(vec);
+ rij_h = rij / pfr.h;
+ if (rij_h > 2.0f)
+ continue;
+
+ npressure = stiffness * (pow7(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) );
+
+ if (pfn->psys->part->flag & PART_SIZEMASS)
+ dq *= npa->size;
+
+ pressureTerm = pressure / pow2(pa->sphdensity) + npressure / pow2(npa->sphdensity);
+
+ /* Note that 'minus' is removed, because vec = vecBA, not vecAB.
+ * This applies to the viscosity calculation below, too. */
+ madd_v3_v3fl(force, vec, pressureTerm * dq);
+
+ /* Viscosity */
+ if (visc > 0.0f) {
+ sub_v3_v3v3(dv, npa->prev_state.vel, pa->prev_state.vel);
+ u = dot_v3v3(vec, dv);
+ /* Apply parameters */
+ u *= -dq * hinv * visc / (0.5f * npa->sphdensity + 0.5f * pa->sphdensity);
+ madd_v3_v3fl(force, vec, u);
+ }
+ }
+
+ /* Artificial buoyancy force in negative gravity direction */
+ if (fluid->buoyancy > 0.f && gravity)
+ madd_v3_v3fl(force, gravity, fluid->buoyancy * (pa->sphdensity - rest_density));
if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF)
sph_particle_courant(sphdata, &pfr);
sphdata->pass++;
}
-static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata)
+static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData *sphdata)
+{
+ ParticleSystem **psys = sphdata->psys;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
+ /* 4.0 seems to be a pretty good value */
+ float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f);
+ SPHRangeData pfr;
+ float data[2];
+
+ data[0] = 0;
+ data[1] = 0;
+ pfr.data = data;
+ pfr.h = interaction_radius * sphdata->hfac;
+ pfr.pa = pa;
+ pfr.mass = sphdata->mass;
+
+ sph_evaluate_func( NULL, psys, pa->state.co, &pfr, interaction_radius, sphclassical_density_accum_cb);
+ pa->sphdensity = MIN2(MAX2(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f);
+}
+
+void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata)
{
ParticleTarget *pt;
int i;
@@ -2621,17 +2821,47 @@ static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata)
sphdata->pa = NULL;
sphdata->mass = 1.0f;
- sphdata->force_cb = sph_force_cb;
- sphdata->density_cb = sph_density_accum_cb;
+ if (sim->psys->part->fluid->solver == SPH_SOLVER_DDR) {
+ sphdata->force_cb = sph_force_cb;
+ sphdata->density_cb = sph_density_accum_cb;
+ sphdata->hfac = 1.0f;
+ }
+ else {
+ /* SPH_SOLVER_CLASSICAL */
+ sphdata->force_cb = sphclassical_force_cb;
+ sphdata->density_cb = sphclassical_density_accum_cb;
+ sphdata->hfac = 0.5f;
+ }
+
}
-static void sph_solver_finalise(SPHData *sphdata)
+void psys_sph_finalise(SPHData *sphdata)
{
if (sphdata->eh) {
BLI_edgehash_free(sphdata->eh, NULL);
sphdata->eh = NULL;
}
}
+/* Sample the density field at a point in space. */
+void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2])
+{
+ ParticleSystem **psys = sphdata->psys;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
+ /* 4.0 seems to be a pretty good value */
+ float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f);
+ SPHRangeData pfr;
+ float density[2];
+
+ density[0] = density[1] = 0.0f;
+ pfr.data = density;
+ pfr.h = interaction_radius * sphdata->hfac;
+ pfr.mass = sphdata->mass;
+
+ sph_evaluate_func(tree, psys, co, &pfr, interaction_radius, sphdata->density_cb);
+
+ vars[0] = pfr.data[0];
+ vars[1] = pfr.data[1];
+}
static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata)
{
@@ -2798,13 +3028,20 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
normalize_qt(pa->state.rot);
}
-/************************************************/
-/* Collisions */
-/************************************************/
+/************************************************
+ * Collisions
+ *
+ * The algorithm is roughly:
+ * 1. Use a BVH tree to search for faces that a particle may collide with.
+ * 2. Use Newton's method to find the exact time at which the collision occurs.
+ * http://en.wikipedia.org/wiki/Newton's_method
+ *
+ ************************************************/
#define COLLISION_MAX_COLLISIONS 10
#define COLLISION_MIN_RADIUS 0.001f
#define COLLISION_MIN_DISTANCE 0.0001f
#define COLLISION_ZERO 0.00001f
+#define COLLISION_INIT_STEP 0.00008f
typedef float (*NRDistanceFunc)(float *p, float radius, ParticleCollisionElement *pce, float *nor);
static float nr_signed_distance_to_plane(float *p, float radius, ParticleCollisionElement *pce, float *nor)
{
@@ -2959,16 +3196,20 @@ static void collision_point_on_surface(float p[3], ParticleCollisionElement *pce
/* find first root in range [0-1] starting from 0 */
static float collision_newton_rhapson(ParticleCollision *col, float radius, ParticleCollisionElement *pce, NRDistanceFunc distance_func)
{
- float t0, t1, d0, d1, dd, n[3];
+ float t0, t1, dt_init, d0, d1, dd, n[3];
int iter;
pce->inv_nor = -1;
+ /* Initial step size should be small, but not too small or floating point
+ * precision errors will appear. - z0r */
+ dt_init = COLLISION_INIT_STEP * col->inv_total_time;
+
/* start from the beginning */
t0 = 0.f;
collision_interpolate_element(pce, t0, col->f, col);
d0 = distance_func(col->co1, radius, pce, n);
- t1 = 0.001f;
+ t1 = dt_init;
d1 = 0.f;
for (iter=0; iter<10; iter++) {//, itersum++) {
@@ -2978,11 +3219,6 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part
d1 = distance_func(pce->p, radius, pce, n);
- /* no movement, so no collision */
- if (d1 == d0) {
- return -1.f;
- }
-
/* particle already inside face, so report collision */
if (iter == 0 && d0 < 0.f && d0 > -radius) {
copy_v3_v3(pce->p, col->co1);
@@ -2990,7 +3226,24 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part
pce->inside = 1;
return 0.f;
}
-
+
+ /* Zero gradient (no movement relative to element). Can't step from
+ * here. */
+ if (d1 == d0) {
+ /* If first iteration, try from other end where the gradient may be
+ * greater. Note: code duplicated below. */
+ if (iter == 0) {
+ t0 = 1.f;
+ collision_interpolate_element(pce, t0, col->f, col);
+ d0 = distance_func(col->co2, radius, pce, n);
+ t1 = 1.0f - dt_init;
+ d1 = 0.f;
+ continue;
+ }
+ else
+ return -1.f;
+ }
+
dd = (t1-t0)/(d1-d0);
t0 = t1;
@@ -2998,14 +3251,14 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part
t1 -= d1*dd;
- /* particle movin away from plane could also mean a strangely rotating face, so check from end */
+ /* Particle moving away from plane could also mean a strangely rotating
+ * face, so check from end. Note: code duplicated above. */
if (iter == 0 && t1 < 0.f) {
t0 = 1.f;
collision_interpolate_element(pce, t0, col->f, col);
d0 = distance_func(col->co2, radius, pce, n);
- t1 = 0.999f;
+ t1 = 1.0f - dt_init;
d1 = 0.f;
-
continue;
}
else if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f))
@@ -3453,6 +3706,7 @@ static void collision_check(ParticleSimulationData *sim, int p, float dfra, floa
memset(&col, 0, sizeof(ParticleCollision));
col.total_time = timestep * dfra;
+ col.inv_total_time = 1.0f/col.total_time;
col.inv_timestep = 1.0f/timestep;
col.cfra = cfra;
@@ -3781,18 +4035,19 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
/* Code for an adaptive time step based on the Courant-Friedrichs-Lewy
* condition. */
-#define MIN_TIMESTEP 1.0f / 101.0f
+static const float MIN_TIMESTEP = 1.0f / 101.0f;
/* Tolerance of 1.5 means the last subframe neither favors growing nor
* shrinking (e.g if it were 1.3, the last subframe would tend to be too
* small). */
-#define TIMESTEP_EXPANSION_TOLERANCE 1.5f
+static const float TIMESTEP_EXPANSION_FACTOR = 0.1f;
+static const float TIMESTEP_EXPANSION_TOLERANCE = 1.5f;
/* Calculate the speed of the particle relative to the local scale of the
* simulation. This should be called once per particle during a simulation
* step, after the velocity has been updated. element_size defines the scale of
* the simulation, and is typically the distance to neighboring particles. */
static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
- float dtime, SPHData *sphdata)
+ float dtime, SPHData *sphdata)
{
float relative_vel[3];
float speed;
@@ -3802,14 +4057,31 @@ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
if (sim->courant_num < speed * dtime / sphdata->element_size)
sim->courant_num = speed * dtime / sphdata->element_size;
}
+static float get_base_time_step(ParticleSettings *part)
+{
+ return 1.0f / (float) (part->subframes + 1);
+}
/* Update time step size to suit current conditions. */
static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, float t_frac)
{
+ float dt_target;
if (sim->courant_num == 0.0f)
- psys->dt_frac = 1.0f;
+ dt_target = 1.0f;
+ else
+ dt_target = psys->dt_frac * (psys->part->courant_target / sim->courant_num);
+
+ /* Make sure the time step is reasonable. For some reason, the CLAMP macro
+ * doesn't work here. The time step becomes too large. - z0r */
+ if (dt_target < MIN_TIMESTEP)
+ dt_target = MIN_TIMESTEP;
+ else if (dt_target > get_base_time_step(psys->part))
+ dt_target = get_base_time_step(psys->part);
+
+ /* Decrease time step instantly, but increase slowly. */
+ if (dt_target > psys->dt_frac)
+ psys->dt_frac = interpf(dt_target, psys->dt_frac, TIMESTEP_EXPANSION_FACTOR);
else
- psys->dt_frac *= (psys->part->courant_target / sim->courant_num);
- CLAMP(psys->dt_frac, MIN_TIMESTEP, 1.0f);
+ psys->dt_frac = dt_target;
/* Sync with frame end if it's close. */
if (t_frac == 1.0f)
@@ -3973,31 +4245,72 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
case PART_PHYS_FLUID:
{
SPHData sphdata;
- sph_solver_init(sim, &sphdata);
+ ParticleSettings *part = sim->psys->part;
+ psys_sph_init(sim, &sphdata);
- #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
- LOOP_DYNAMIC_PARTICLES {
- /* do global forces & effectors */
- basic_integrate(sim, p, pa->state.time, cfra);
+ if (part->fluid->solver == SPH_SOLVER_DDR) {
+ /* Apply SPH forces using double-density relaxation algorithm
+ * (Clavat et. al.) */
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ /* do global forces & effectors */
+ basic_integrate(sim, p, pa->state.time, cfra);
- /* actual fluids calculations */
- sph_integrate(sim, pa, pa->state.time, &sphdata);
+ /* actual fluids calculations */
+ sph_integrate(sim, pa, pa->state.time, &sphdata);
- if (sim->colliders)
- collision_check(sim, p, pa->state.time, cfra);
-
- /* SPH particles are not physical particles, just interpolation
- * particles, thus rotation has not a direct sense for them */
- basic_rotate(part, pa, pa->state.time, timestep);
+ if (sim->colliders)
+ collision_check(sim, p, pa->state.time, cfra);
+
+ /* SPH particles are not physical particles, just interpolation
+ * particles, thus rotation has not a direct sense for them */
+ basic_rotate(part, pa, pa->state.time, timestep);
+
+ #pragma omp critical
+ if (part->time_flag & PART_TIME_AUTOSF)
+ update_courant_num(sim, pa, dtime, &sphdata);
+ }
+
+ sph_springs_modify(psys, timestep);
- #pragma omp critical
- if (part->time_flag & PART_TIME_AUTOSF)
- update_courant_num(sim, pa, dtime, &sphdata);
}
+ else {
+ /* SPH_SOLVER_CLASSICAL */
+ /* Apply SPH forces using classical algorithm (due to Gingold
+ * and Monaghan). Note that, unlike double-density relaxation,
+ * this algorthim is separated into distinct loops. */
+
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ basic_integrate(sim, p, pa->state.time, cfra);
+ }
- sph_springs_modify(psys, timestep);
+ /* calculate summation density */
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ sphclassical_calc_dens(pa, pa->state.time, &sphdata);
+ }
- sph_solver_finalise(&sphdata);
+ /* do global forces & effectors */
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ /* actual fluids calculations */
+ sph_integrate(sim, pa, pa->state.time, &sphdata);
+
+ if (sim->colliders)
+ collision_check(sim, p, pa->state.time, cfra);
+
+ /* SPH particles are not physical particles, just interpolation
+ * particles, thus rotation has not a direct sense for them */
+ basic_rotate(part, pa, pa->state.time, timestep);
+
+ #pragma omp critical
+ if (part->time_flag & PART_TIME_AUTOSF)
+ update_courant_num(sim, pa, dtime, &sphdata);
+ }
+ }
+
+ psys_sph_finalise(&sphdata);
break;
}
}
@@ -4211,7 +4524,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
int startframe = 0, endframe = 100, oldtotpart = 0;
/* cache shouldn't be used for hair or "continue physics" */
- if (part->type != PART_HAIR && BKE_ptcache_get_continue_physics() == 0) {
+ if (part->type != PART_HAIR) {
psys_clear_temp_pointcache(psys);
/* set suitable cache range automatically */
@@ -4309,14 +4622,14 @@ static void system_step(ParticleSimulationData *sim, float cfra)
if (!(part->time_flag & PART_TIME_AUTOSF)) {
/* Constant time step */
- psys->dt_frac = 1.0f / (float) (part->subframes + 1);
+ psys->dt_frac = get_base_time_step(part);
}
else if ((int)cfra == startframe) {
- /* Variable time step; use a very conservative value at the start.
- * If it doesn't need to be so small, it will quickly grow. */
- psys->dt_frac = 1.0;
+ /* Variable time step; initialise to subframes */
+ psys->dt_frac = get_base_time_step(part);
}
else if (psys->dt_frac < MIN_TIMESTEP) {
+ /* Variable time step; subsequent frames */
psys->dt_frac = MIN_TIMESTEP;
}
diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 6fa6d86589f..483dd2570e2 100644
--- a/source/blender/blenlib/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -18,12 +18,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/blenlib/intern/pbvh.c
+/** \file blender/blenkernel/intern/pbvh.c
* \ingroup bli
*/
-
-
#include "DNA_meshdata_types.h"
#include "MEM_guardedalloc.h"
@@ -32,8 +30,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_DerivedMesh.h"
#include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
@@ -43,124 +41,12 @@
#include "GPU_buffers.h"
+#include "pbvh_intern.h"
+
#define LEAF_LIMIT 10000
//#define PERFCNTRS
-/* Axis-aligned bounding box */
-typedef struct {
- float bmin[3], bmax[3];
-} BB;
-
-/* Axis-aligned bounding box with centroid */
-typedef struct {
- float bmin[3], bmax[3], bcentroid[3];
-} BBC;
-
-struct PBVHNode {
- /* Opaque handle for drawing code */
- GPU_Buffers *draw_buffers;
-
- /* Voxel bounds */
- BB vb;
- BB orig_vb;
-
- /* For internal nodes, the offset of the children in the PBVH
- * 'nodes' array. */
- int children_offset;
-
- /* Pointer into the PBVH prim_indices array and the number of
- * primitives used by this leaf node.
- *
- * Used for leaf nodes in both mesh- and multires-based PBVHs.
- */
- int *prim_indices;
- unsigned int totprim;
-
- /* Array of indices into the mesh's MVert array. Contains the
- * indices of all vertices used by faces that are within this
- * node's bounding box.
- *
- * Note that a vertex might be used by a multiple faces, and
- * these faces might be in different leaf nodes. Such a vertex
- * will appear in the vert_indices array of each of those leaf
- * nodes.
- *
- * In order to support cases where you want access to multiple
- * nodes' vertices without duplication, the vert_indices array
- * is ordered such that the first part of the array, up to
- * index 'uniq_verts', contains "unique" vertex indices. These
- * vertices might not be truly unique to this node, but if
- * they appear in another node's vert_indices array, they will
- * be above that node's 'uniq_verts' value.
- *
- * Used for leaf nodes in a mesh-based PBVH (not multires.)
- */
- int *vert_indices;
- unsigned int uniq_verts, face_verts;
-
- /* An array mapping face corners into the vert_indices
- * array. The array is sized to match 'totprim', and each of
- * the face's corners gets an index into the vert_indices
- * array, in the same order as the corners in the original
- * MFace. The fourth value should not be used if the original
- * face is a triangle.
- *
- * Used for leaf nodes in a mesh-based PBVH (not multires.)
- */
- int (*face_vert_indices)[4];
-
- /* Indicates whether this node is a leaf or not; also used for
- * marking various updates that need to be applied. */
- PBVHNodeFlags flag : 8;
-
- /* Used for raycasting: how close bb is to the ray point. */
- float tmin;
-
- int proxy_count;
- PBVHProxyNode *proxies;
-};
-
-struct PBVH {
- PBVHType type;
-
- PBVHNode *nodes;
- int node_mem_count, totnode;
-
- int *prim_indices;
- int totprim;
- int totvert;
-
- int leaf_limit;
-
- /* Mesh data */
- MVert *verts;
- MFace *faces;
- CustomData *vdata;
-
- /* Grid Data */
- CCGKey gridkey;
- CCGElem **grids;
- DMGridAdjacency *gridadj;
- void **gridfaces;
- const DMFlagMat *grid_flag_mats;
- int totgrid;
- BLI_bitmap *grid_hidden;
-
- /* Only used during BVH build and update,
- * don't need to remain valid after */
- BLI_bitmap vert_bitmap;
-
-#ifdef PERFCNTRS
- int perf_modified;
-#endif
-
- /* flag are verts/faces deformed */
- int deformed;
-
- int show_diffuse_color;
-};
-
#define STACK_FIXED_DEPTH 100
typedef struct PBVHStack {
@@ -170,7 +56,7 @@ typedef struct PBVHStack {
typedef struct PBVHIter {
PBVH *bvh;
- BLI_pbvh_SearchCallback scb;
+ BKE_pbvh_SearchCallback scb;
void *search_data;
PBVHStack *stack;
@@ -180,14 +66,14 @@ typedef struct PBVHIter {
int stackspace;
} PBVHIter;
-static void BB_reset(BB *bb)
+void BB_reset(BB *bb)
{
bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
}
/* Expand the bounding box to include a new coordinate */
-static void BB_expand(BB *bb, float co[3])
+void BB_expand(BB *bb, const float co[3])
{
int i;
for (i = 0; i < 3; ++i) {
@@ -197,7 +83,7 @@ static void BB_expand(BB *bb, float co[3])
}
/* Expand the bounding box to include another bounding box */
-static void BB_expand_with_bb(BB *bb, BB *bb2)
+void BB_expand_with_bb(BB *bb, BB *bb2)
{
int i;
for (i = 0; i < 3; ++i) {
@@ -207,7 +93,7 @@ static void BB_expand_with_bb(BB *bb, BB *bb2)
}
/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
-static int BB_widest_axis(BB *bb)
+int BB_widest_axis(const BB *bb)
{
float dim[3];
int i;
@@ -229,7 +115,7 @@ static int BB_widest_axis(BB *bb)
}
}
-static void BBC_update_centroid(BBC *bbc)
+void BBC_update_centroid(BBC *bbc)
{
int i;
for (i = 0; i < 3; ++i)
@@ -246,11 +132,11 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
if (node->flag & PBVH_Leaf) {
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL)
+ BKE_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL)
{
BB_expand(&vb, vd.co);
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
BB_expand_with_bb(&vb,
@@ -262,12 +148,12 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
node->vb = vb;
}
-//void BLI_pbvh_node_BB_reset(PBVHNode *node)
+//void BKE_pbvh_node_BB_reset(PBVHNode *node)
//{
// BB_reset(&node->vb);
//}
//
-//void BLI_pbvh_node_BB_expand(PBVHNode *node, float co[3])
+//void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3])
//{
// BB_expand(&node->vb, co);
//}
@@ -334,7 +220,7 @@ static int partition_indices_material(PBVH *bvh, int lo, int hi)
}
}
-static void grow_nodes(PBVH *bvh, int totnode)
+void pbvh_grow_nodes(PBVH *bvh, int totnode)
{
if (totnode > bvh->node_mem_count) {
PBVHNode *prev = bvh->nodes;
@@ -547,7 +433,7 @@ static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
/* Add two child nodes */
bvh->nodes[node_index].children_offset = bvh->totnode;
- grow_nodes(bvh, bvh->totnode + 2);
+ pbvh_grow_nodes(bvh, bvh->totnode + 2);
/* Update parent node bounding box */
update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
@@ -607,7 +493,7 @@ static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
}
/* Do a full rebuild with on Mesh data structure */
-void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata)
+void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata)
{
BBC *prim_bbc = NULL;
BB cb;
@@ -649,7 +535,7 @@ void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int
}
/* Do a full rebuild with on Grids data structure */
-void BLI_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
+void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
{
BBC *prim_bbc = NULL;
@@ -692,14 +578,14 @@ void BLI_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
MEM_freeN(prim_bbc);
}
-PBVH *BLI_pbvh_new(void)
+PBVH *BKE_pbvh_new(void)
{
PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
return bvh;
}
-void BLI_pbvh_free(PBVH *bvh)
+void BKE_pbvh_free(PBVH *bvh)
{
PBVHNode *node;
int i;
@@ -714,6 +600,14 @@ void BLI_pbvh_free(PBVH *bvh)
MEM_freeN(node->vert_indices);
if (node->face_vert_indices)
MEM_freeN(node->face_vert_indices);
+ BKE_pbvh_node_layer_disp_free(node);
+
+ if (node->bm_faces)
+ BLI_ghash_free(node->bm_faces, NULL, NULL);
+ if (node->bm_unique_verts)
+ BLI_ghash_free(node->bm_unique_verts, NULL, NULL);
+ if (node->bm_other_verts)
+ BLI_ghash_free(node->bm_other_verts, NULL, NULL);
}
}
@@ -733,10 +627,15 @@ void BLI_pbvh_free(PBVH *bvh)
if (bvh->prim_indices)
MEM_freeN(bvh->prim_indices);
+ if (bvh->bm_vert_to_node)
+ BLI_ghash_free(bvh->bm_vert_to_node, NULL, NULL);
+ if (bvh->bm_face_to_node)
+ BLI_ghash_free(bvh->bm_face_to_node, NULL, NULL);
+
MEM_freeN(bvh);
}
-static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BLI_pbvh_SearchCallback scb, void *search_data)
+static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BKE_pbvh_SearchCallback scb, void *search_data)
{
iter->bvh = bvh;
iter->scb = scb;
@@ -847,8 +746,8 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
return NULL;
}
-void BLI_pbvh_search_gather(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
+void BKE_pbvh_search_gather(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
PBVHNode ***r_array, int *r_tot)
{
PBVHIter iter;
@@ -888,9 +787,9 @@ void BLI_pbvh_search_gather(PBVH *bvh,
*r_tot = tot;
}
-void BLI_pbvh_search_callback(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitCallback hcb, void *hit_data)
+void BKE_pbvh_search_callback(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitCallback hcb, void *hit_data)
{
PBVHIter iter;
PBVHNode *node;
@@ -931,7 +830,7 @@ static void node_tree_insert(node_tree *tree, node_tree *new_node)
}
}
-static void traverse_tree(node_tree *tree, BLI_pbvh_HitOccludedCallback hcb, void *hit_data, float *tmin)
+static void traverse_tree(node_tree *tree, BKE_pbvh_HitOccludedCallback hcb, void *hit_data, float *tmin)
{
if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
@@ -955,14 +854,14 @@ static void free_tree(node_tree *tree)
free(tree);
}
-float BLI_pbvh_node_get_tmin(PBVHNode *node)
+float BKE_pbvh_node_get_tmin(PBVHNode *node)
{
return node->tmin;
}
-static void BLI_pbvh_search_callback_occluded(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitOccludedCallback hcb, void *hit_data)
+static void BKE_pbvh_search_callback_occluded(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitOccludedCallback hcb, void *hit_data)
{
PBVHIter iter;
PBVHNode *node;
@@ -1013,6 +912,11 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
float (*vnor)[3];
int n;
+ if (bvh->type == PBVH_BMESH) {
+ pbvh_bmesh_normals_update(nodes, totnode);
+ return;
+ }
+
if (bvh->type != PBVH_FACES)
return;
@@ -1106,8 +1010,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
MEM_freeN(vnor);
}
-static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
- int totnode, int flag)
+void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
{
int n;
@@ -1154,6 +1057,11 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
node->prim_indices,
node->totprim);
break;
+ case PBVH_BMESH:
+ node->draw_buffers =
+ GPU_build_bmesh_buffers(bvh->flags &
+ PBVH_DYNTOPO_SMOOTH_SHADING);
+ break;
}
node->flag &= ~PBVH_RebuildDrawBuffers;
@@ -1181,6 +1089,13 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
node->face_vert_indices,
bvh->show_diffuse_color);
break;
+ case PBVH_BMESH:
+ GPU_update_bmesh_buffers(node->draw_buffers,
+ bvh->bm,
+ node->bm_faces,
+ node->bm_unique_verts,
+ node->bm_other_verts);
+ break;
}
node->flag &= ~PBVH_UpdateDrawBuffers;
@@ -1219,7 +1134,7 @@ static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
return update;
}
-void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
+void BKE_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
{
PBVHNode **nodes;
int totnode;
@@ -1227,7 +1142,7 @@ void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
if (!bvh->nodes)
return;
- BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
&nodes, &totnode);
if (flag & PBVH_UpdateNormals)
@@ -1242,7 +1157,7 @@ void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
if (nodes) MEM_freeN(nodes);
}
-void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
+void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
{
PBVHIter iter;
PBVHNode *node;
@@ -1262,7 +1177,7 @@ void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
copy_v3_v3(bb_max, bb.bmax);
}
-void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
{
PBVHIter iter;
PBVHNode *node;
@@ -1318,36 +1233,55 @@ void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
/***************************** PBVH Access ***********************************/
-PBVHType BLI_pbvh_type(const PBVH *bvh)
+PBVHType BKE_pbvh_type(const PBVH *bvh)
{
return bvh->type;
}
-BLI_bitmap *BLI_pbvh_grid_hidden(const PBVH *bvh)
+void BKE_pbvh_bounding_box(const PBVH *bvh, float min[3], float max[3])
+{
+ if (bvh->totnode) {
+ const BB *bb = &bvh->nodes[0].vb;
+ copy_v3_v3(min, bb->bmin);
+ copy_v3_v3(max, bb->bmax);
+ }
+ else {
+ zero_v3(min);
+ zero_v3(max);
+ }
+}
+
+BLI_bitmap *BKE_pbvh_grid_hidden(const PBVH *bvh)
{
BLI_assert(bvh->type == PBVH_GRIDS);
return bvh->grid_hidden;
}
-void BLI_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
+void BKE_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
{
BLI_assert(bvh->type == PBVH_GRIDS);
*key = bvh->gridkey;
}
+BMesh *BKE_pbvh_get_bmesh(PBVH *bvh)
+{
+ BLI_assert(bvh->type == PBVH_BMESH);
+ return bvh->bm;
+}
+
/***************************** Node Access ***********************************/
-void BLI_pbvh_node_mark_update(PBVHNode *node)
+void BKE_pbvh_node_mark_update(PBVHNode *node)
{
node->flag |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
-void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node)
+void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node)
{
node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
-void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
+void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
{
BLI_assert(node->flag & PBVH_Leaf);
@@ -1357,13 +1291,13 @@ void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
node->flag &= ~PBVH_FullyHidden;
}
-void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
+void BKE_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
{
if (vert_indices) *vert_indices = node->vert_indices;
if (verts) *verts = bvh->verts;
}
-void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
+void BKE_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
{
int tot;
@@ -1377,10 +1311,15 @@ void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *to
if (totvert) *totvert = node->uniq_verts + node->face_verts;
if (uniquevert) *uniquevert = node->uniq_verts;
break;
+ case PBVH_BMESH:
+ tot = BLI_ghash_size(node->bm_unique_verts);
+ if (totvert) *totvert = tot + BLI_ghash_size(node->bm_other_verts);
+ if (uniquevert) *uniquevert = tot;
+ break;
}
}
-void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, CCGElem ***griddata, DMGridAdjacency **gridadj)
+void BKE_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, CCGElem ***griddata, DMGridAdjacency **gridadj)
{
switch (bvh->type) {
case PBVH_GRIDS:
@@ -1392,6 +1331,7 @@ void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int
if (gridadj) *gridadj = bvh->gridadj;
break;
case PBVH_FACES:
+ case PBVH_BMESH:
if (grid_indices) *grid_indices = NULL;
if (totgrid) *totgrid = 0;
if (maxgrid) *maxgrid = 0;
@@ -1402,19 +1342,19 @@ void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int
}
}
-void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
+void BKE_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
{
copy_v3_v3(bb_min, node->vb.bmin);
copy_v3_v3(bb_max, node->vb.bmax);
}
-void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
+void BKE_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
{
copy_v3_v3(bb_min, node->orig_vb.bmin);
copy_v3_v3(bb_max, node->orig_vb.bmax);
}
-void BLI_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count)
+void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count)
{
if (node->proxy_count > 0) {
if (proxies) *proxies = node->proxies;
@@ -1439,14 +1379,14 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v)
float bb_min[3], bb_max[3];
if (rcd->original)
- BLI_pbvh_node_get_original_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
else
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
return isect_ray_aabb(&rcd->ray, bb_min, bb_max, &node->tmin);
}
-void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
+void BKE_pbvh_raycast(PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data,
const float ray_start[3], const float ray_normal[3],
int original)
{
@@ -1455,14 +1395,14 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
isect_ray_aabb_initialize(&rcd.ray, ray_start, ray_normal);
rcd.original = original;
- BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
+ BKE_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
}
-static int ray_face_intersection(const float ray_start[3],
- const float ray_normal[3],
- const float *t0, const float *t1,
- const float *t2, const float *t3,
- float *fdist)
+int ray_face_intersection(const float ray_start[3],
+ const float ray_normal[3],
+ const float *t0, const float *t1,
+ const float *t2, const float *t3,
+ float *fdist)
{
float dist;
@@ -1568,7 +1508,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
return hit;
}
-int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
+int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
const float ray_start[3], const float ray_normal[3],
float *dist)
{
@@ -1586,6 +1526,9 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
hit |= pbvh_grids_node_raycast(bvh, node, origco,
ray_start, ray_normal, dist);
break;
+ case PBVH_BMESH:
+ hit = pbvh_bmesh_node_raycast(node, ray_start, ray_normal, dist, use_origco);
+ break;
}
return hit;
@@ -1593,8 +1536,15 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
//#include <GL/glew.h>
-void BLI_pbvh_node_draw(PBVHNode *node, void *setMaterial)
+typedef struct {
+ DMSetMaterial setMaterial;
+ int wireframe;
+} PBVHNodeDrawData;
+
+void BKE_pbvh_node_draw(PBVHNode *node, void *data_v)
{
+ PBVHNodeDrawData *data = data_v;
+
#if 0
/* XXX: Just some quick code to show leaf nodes in different colors */
float col[3]; int i;
@@ -1613,7 +1563,9 @@ void BLI_pbvh_node_draw(PBVHNode *node, void *setMaterial)
#endif
if (!(node->flag & PBVH_FullyHidden))
- GPU_draw_buffers(node->draw_buffers, setMaterial);
+ GPU_draw_buffers(node->draw_buffers,
+ data->setMaterial,
+ data->wireframe);
}
typedef enum {
@@ -1656,19 +1608,19 @@ static PlaneAABBIsect test_planes_aabb(const float bb_min[3],
return ret;
}
-int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
+int BKE_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
{
float bb_min[3], bb_max[3];
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
return test_planes_aabb(bb_min, bb_max, data) != ISECT_OUTSIDE;
}
-int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data)
+int BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data)
{
float bb_min[3], bb_max[3];
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
return test_planes_aabb(bb_min, bb_max, data) != ISECT_INSIDE;
}
@@ -1681,16 +1633,17 @@ static void pbvh_node_check_diffuse_changed(PBVH *bvh, PBVHNode *node)
node->flag |= PBVH_UpdateDrawBuffers;
}
-void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
- DMSetMaterial setMaterial)
+void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
+ DMSetMaterial setMaterial, int wireframe)
{
+ PBVHNodeDrawData draw_data = {setMaterial, wireframe};
PBVHNode **nodes;
int a, totnode;
for (a = 0; a < bvh->totnode; a++)
pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]);
- BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
&nodes, &totnode);
pbvh_update_normals(bvh, nodes, totnode, face_nors);
@@ -1699,15 +1652,15 @@ void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
if (nodes) MEM_freeN(nodes);
if (planes) {
- BLI_pbvh_search_callback(bvh, BLI_pbvh_node_planes_contain_AABB,
- planes, BLI_pbvh_node_draw, setMaterial);
+ BKE_pbvh_search_callback(bvh, BKE_pbvh_node_planes_contain_AABB,
+ planes, BKE_pbvh_node_draw, &draw_data);
}
else {
- BLI_pbvh_search_callback(bvh, NULL, NULL, BLI_pbvh_node_draw, setMaterial);
+ BKE_pbvh_search_callback(bvh, NULL, NULL, BKE_pbvh_node_draw, &draw_data);
}
}
-void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
+void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
{
int a;
@@ -1721,11 +1674,31 @@ void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
bvh->grid_hidden = grid_hidden;
for (a = 0; a < bvh->totnode; ++a)
- BLI_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
+ BKE_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
}
}
-float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
+/* Get the node's displacement layer, creating it if necessary */
+float *BKE_pbvh_node_layer_disp_get(PBVH *bvh, PBVHNode *node)
+{
+ if (!node->layer_disp) {
+ int totvert = 0;
+ BKE_pbvh_node_num_verts(bvh, node, &totvert, NULL);
+ node->layer_disp = MEM_callocN(sizeof(float) * totvert, "layer disp");
+ }
+ return node->layer_disp;
+}
+
+/* If the node has a displacement layer, free it and set to null */
+void BKE_pbvh_node_layer_disp_free(PBVHNode *node)
+{
+ if (node->layer_disp) {
+ MEM_freeN(node->layer_disp);
+ node->layer_disp = NULL;
+ }
+}
+
+float (*BKE_pbvh_get_vertCos(PBVH * pbvh))[3]
{
int a;
float (*vertCos)[3] = NULL;
@@ -1734,7 +1707,7 @@ float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
float *co;
MVert *mvert = pbvh->verts;
- vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BLI_pbvh_get_vertCoords");
+ vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords");
co = (float *)vertCos;
for (a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
@@ -1745,7 +1718,7 @@ float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
return vertCos;
}
-void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
+void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
{
int a;
@@ -1774,21 +1747,21 @@ void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
BKE_mesh_calc_normals_tessface(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
for (a = 0; a < pbvh->totnode; ++a)
- BLI_pbvh_node_mark_update(&pbvh->nodes[a]);
+ BKE_pbvh_node_mark_update(&pbvh->nodes[a]);
- BLI_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
- BLI_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
+ BKE_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
+ BKE_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
}
}
-int BLI_pbvh_isDeformed(PBVH *pbvh)
+int BKE_pbvh_isDeformed(PBVH *pbvh)
{
return pbvh->deformed;
}
/* Proxies */
-PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
+PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
{
int index, totverts;
@@ -1804,14 +1777,14 @@ PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
else
node->proxies = MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
- BLI_pbvh_node_num_verts(bvh, node, &totverts, NULL);
+ BKE_pbvh_node_num_verts(bvh, node, &totverts, NULL);
node->proxies[index].co = MEM_callocN(sizeof(float[3]) * totverts, "PBVHNodeProxy.co");
}
return node->proxies + index;
}
-void BLI_pbvh_node_free_proxies(PBVHNode *node)
+void BKE_pbvh_node_free_proxies(PBVHNode *node)
{
#pragma omp critical
{
@@ -1829,7 +1802,7 @@ void BLI_pbvh_node_free_proxies(PBVHNode *node)
}
}
-void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
+void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
{
PBVHNode **array = NULL, **newarray, *node;
int tot = 0, space = 0;
@@ -1842,7 +1815,7 @@ void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
if (tot == space) {
/* resize array if needed */
space = (tot == 0) ? 32 : space * 2;
- newarray = MEM_callocN(sizeof(PBVHNode) * space, "BLI_pbvh_gather_proxies");
+ newarray = MEM_callocN(sizeof(PBVHNode) * space, "BKE_pbvh_gather_proxies");
if (array) {
memcpy(newarray, array, sizeof(PBVHNode) * tot);
@@ -1879,9 +1852,9 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi->fno = 0;
vi->mvert = 0;
- BLI_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL);
- BLI_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
- BLI_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
+ BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL);
+ BKE_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
+ BKE_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
vi->key = &bvh->gridkey;
vi->grids = grids;
@@ -1896,12 +1869,18 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi->vert_indices = vert_indices;
vi->mverts = verts;
+ if (bvh->type == PBVH_BMESH) {
+ BLI_ghashIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
+ BLI_ghashIterator_init(&vi->bm_other_verts, node->bm_other_verts);
+ vi->bm_vdata = &bvh->bm->vdata;
+ }
+
vi->gh = NULL;
if (vi->grids && mode == PBVH_ITER_UNIQUE)
vi->grid_hidden = bvh->grid_hidden;
vi->mask = NULL;
- if (!vi->grids)
+ if (bvh->type == PBVH_FACES)
vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
new file mode 100644
index 00000000000..e46e95617ed
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -0,0 +1,1423 @@
+/*
+ * ***** 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 *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_buffer.h"
+#include "BLI_ghash.h"
+#include "BLI_heap.h"
+#include "BLI_math.h"
+
+#include "BKE_ccg.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_paint.h"
+#include "BKE_pbvh.h"
+
+#include "GPU_buffers.h"
+
+#include "bmesh.h"
+#include "pbvh_intern.h"
+
+#include <assert.h>
+
+/****************************** Building ******************************/
+
+/* Update node data after splitting */
+static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
+{
+ GHashIterator gh_iter;
+ PBVHNode *n = &bvh->nodes[node_index];
+
+ /* Create vert hash sets */
+ n->bm_unique_verts = BLI_ghash_ptr_new("bm_unique_verts");
+ n->bm_other_verts = BLI_ghash_ptr_new("bm_other_verts");
+
+ BB_reset(&n->vb);
+
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ BMVert *v;
+ void *node_val = SET_INT_IN_POINTER(node_index);
+
+ /* Update ownership of faces */
+ BLI_ghash_insert(bvh->bm_face_to_node, f, node_val);
+
+ /* Update vertices */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ v = l_iter->v;
+ if (!BLI_ghash_haskey(n->bm_unique_verts, v)) {
+ if (BLI_ghash_haskey(bvh->bm_vert_to_node, v)) {
+ if (!BLI_ghash_haskey(n->bm_other_verts, v))
+ BLI_ghash_insert(n->bm_other_verts, v, NULL);
+ }
+ else {
+ BLI_ghash_insert(n->bm_unique_verts, v, NULL);
+ BLI_ghash_insert(bvh->bm_vert_to_node, v, node_val);
+ }
+ }
+ /* Update node bounding box */
+ BB_expand(&n->vb, v->co);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
+ n->vb.bmin[1] <= n->vb.bmax[1] &&
+ n->vb.bmin[2] <= n->vb.bmax[2]);
+
+ n->orig_vb = n->vb;
+
+ /* Build GPU buffers */
+ if (!G.background) {
+ int smooth = bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING;
+ n->draw_buffers = GPU_build_bmesh_buffers(smooth);
+ n->flag |= PBVH_UpdateDrawBuffers;
+ }
+}
+
+/* Recursively split the node if it exceeds the leaf_limit */
+static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
+{
+ GHash *empty, *other;
+ GHashIterator gh_iter;
+ PBVHNode *n, *c1, *c2;
+ BB cb;
+ float mid;
+ int axis, children;
+
+ n = &bvh->nodes[node_index];
+
+ if (BLI_ghash_size(n->bm_faces) <= bvh->leaf_limit) {
+ /* Node limit not exceeded */
+ pbvh_bmesh_node_finalize(bvh, node_index);
+ return;
+ }
+
+ /* Calculate bounding box around primitive centroids */
+ BB_reset(&cb);
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ const BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
+
+ BB_expand(&cb, bbc->bcentroid);
+ }
+
+ /* Find widest axis and its midpoint */
+ axis = BB_widest_axis(&cb);
+ mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
+
+ /* Add two new child nodes */
+ children = bvh->totnode;
+ n->children_offset = children;
+ pbvh_grow_nodes(bvh, bvh->totnode + 2);
+
+ /* Array reallocated, update current node pointer */
+ n = &bvh->nodes[node_index];
+
+ /* Initialize children */
+ c1 = &bvh->nodes[children];
+ c2 = &bvh->nodes[children + 1];
+ c1->flag |= PBVH_Leaf;
+ c2->flag |= PBVH_Leaf;
+ c1->bm_faces = BLI_ghash_ptr_new("bm_faces");
+ c2->bm_faces = BLI_ghash_ptr_new("bm_faces");
+
+ /* Partition the parent node's faces between the two children */
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
+
+ if (bbc->bcentroid[axis] < mid)
+ BLI_ghash_insert(c1->bm_faces, f, NULL);
+ else
+ BLI_ghash_insert(c2->bm_faces, f, NULL);
+ }
+
+ /* Enforce at least one primitive in each node */
+ empty = NULL;
+ if (BLI_ghash_size(c1->bm_faces) == 0) {
+ empty = c1->bm_faces;
+ other = c2->bm_faces;
+ }
+ else if (BLI_ghash_size(c2->bm_faces) == 0) {
+ empty = c2->bm_faces;
+ other = c1->bm_faces;
+ }
+ if (empty) {
+ GHASH_ITER (gh_iter, other) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_insert(empty, key, NULL);
+ BLI_ghash_remove(other, key, NULL, NULL);
+ break;
+ }
+ }
+
+ /* Clear this node */
+
+ /* Mark this node's unique verts as unclaimed */
+ if (n->bm_unique_verts) {
+ GHASH_ITER (gh_iter, n->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ }
+ BLI_ghash_free(n->bm_unique_verts, NULL, NULL);
+ }
+
+ /* Unclaim faces */
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+ }
+ BLI_ghash_free(n->bm_faces, NULL, NULL);
+
+ if (n->bm_other_verts)
+ BLI_ghash_free(n->bm_other_verts, NULL, NULL);
+
+ if (n->layer_disp)
+ MEM_freeN(n->layer_disp);
+
+ n->bm_faces = NULL;
+ n->bm_unique_verts = NULL;
+ n->bm_other_verts = NULL;
+ n->layer_disp = NULL;
+
+ if (n->draw_buffers) {
+ GPU_free_buffers(n->draw_buffers);
+ n->draw_buffers = NULL;
+ }
+ n->flag &= ~PBVH_Leaf;
+
+ /* Recurse */
+ c1 = c2 = NULL;
+ pbvh_bmesh_node_split(bvh, prim_bbc, children);
+ pbvh_bmesh_node_split(bvh, prim_bbc, children + 1);
+
+ /* Array maybe reallocated, update current node pointer */
+ n = &bvh->nodes[node_index];
+
+ /* Update bounding box */
+ BB_reset(&n->vb);
+ BB_expand_with_bb(&n->vb, &bvh->nodes[n->children_offset].vb);
+ BB_expand_with_bb(&n->vb, &bvh->nodes[n->children_offset + 1].vb);
+ n->orig_vb = n->vb;
+}
+
+/* Recursively split the node if it exceeds the leaf_limit */
+static int pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
+{
+ GHash *prim_bbc;
+ GHashIterator gh_iter;
+
+ if (BLI_ghash_size(bvh->nodes[node_index].bm_faces) <= bvh->leaf_limit) {
+ /* Node limit not exceeded */
+ return FALSE;
+ }
+
+ /* For each BMFace, store the AABB and AABB centroid */
+ prim_bbc = BLI_ghash_ptr_new("prim_bbc");
+
+ GHASH_ITER (gh_iter, bvh->nodes[node_index].bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BBC *bbc = MEM_callocN(sizeof(BBC), "BBC");
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ BB_reset((BB *)bbc);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BB_expand((BB *)bbc, l_iter->v->co);
+ } while ((l_iter = l_iter->next) != l_first);
+ BBC_update_centroid(bbc);
+
+ BLI_ghash_insert(prim_bbc, f, bbc);
+ }
+
+ pbvh_bmesh_node_split(bvh, prim_bbc, node_index);
+
+ BLI_ghash_free(prim_bbc, NULL, (void *)MEM_freeN);
+
+ return TRUE;
+}
+
+/**********************************************************************/
+
+static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, GHash *map, void *key)
+{
+ int node_index;
+
+ BLI_assert(BLI_ghash_haskey(map, key));
+
+ node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
+ BLI_assert(node_index < bvh->totnode);
+
+ return &bvh->nodes[node_index];
+}
+
+static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index,
+ const float co[3],
+ const BMVert *example)
+{
+ BMVert *v = BM_vert_create(bvh->bm, co, example, 0);
+ void *val = SET_INT_IN_POINTER(node_index);
+
+ BLI_assert((bvh->totnode == 1 || node_index) && node_index <= bvh->totnode);
+
+ BLI_ghash_insert(bvh->nodes[node_index].bm_unique_verts, v, NULL);
+ BLI_ghash_insert(bvh->bm_vert_to_node, v, val);
+
+ /* Log the new vertex */
+ BM_log_vert_added(bvh->bm, bvh->bm_log, v);
+
+ return v;
+}
+
+static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index,
+ BMVert *v1, BMVert *v2, BMVert *v3,
+ const BMFace *UNUSED(example))
+{
+ BMFace *f;
+ void *val = SET_INT_IN_POINTER(node_index);
+
+ /* Note: passing NULL for the 'example' parameter, profiling shows
+ * a small performance bump */
+ f = BM_face_create_quad_tri(bvh->bm, v1, v2, v3, NULL, NULL, true);
+ if (!BLI_ghash_haskey(bvh->bm_face_to_node, f)) {
+
+ BLI_ghash_insert(bvh->nodes[node_index].bm_faces, f, NULL);
+ BLI_ghash_insert(bvh->bm_face_to_node, f, val);
+
+ /* Log the new face */
+ BM_log_face_added(bvh->bm_log, f);
+ }
+
+ return f;
+}
+
+/* Return the number of faces in 'node' that use vertex 'v' */
+static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ int count = 0;
+
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ if (f_node == node)
+ count++;
+ }
+
+ return count;
+}
+
+/* Return a node that uses vertex 'v' other than its current owner */
+static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ PBVHNode *current_node;
+
+ current_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ if (f_node != current_node)
+ return f_node;
+ }
+
+ return NULL;
+}
+
+static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
+ BMVert *v)
+{
+ PBVHNode *current_owner;
+
+ current_owner = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ BLI_assert(current_owner != new_owner);
+
+ /* Remove current ownership */
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ BLI_ghash_remove(current_owner->bm_unique_verts, v, NULL, NULL);
+
+ /* Set new ownership */
+ BLI_ghash_insert(bvh->bm_vert_to_node, v,
+ SET_INT_IN_POINTER(new_owner - bvh->nodes));
+ BLI_ghash_insert(new_owner->bm_unique_verts, v, NULL);
+ BLI_ghash_remove(new_owner->bm_other_verts, v, NULL, NULL);
+ BLI_assert(!BLI_ghash_haskey(new_owner->bm_other_verts, v));
+}
+
+static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
+{
+ PBVHNode *v_node;
+ BMIter bm_iter;
+ BMFace *f;
+
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ v_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ BLI_ghash_remove(v_node->bm_unique_verts, v, NULL, NULL);
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+
+ /* Have to check each neighboring face's node */
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ BLI_ghash_remove(f_node->bm_unique_verts, v, NULL, NULL);
+ BLI_ghash_remove(f_node->bm_other_verts, v, NULL, NULL);
+
+ BLI_assert(!BLI_ghash_haskey(f_node->bm_unique_verts, v));
+ BLI_assert(!BLI_ghash_haskey(f_node->bm_other_verts, v));
+ }
+}
+
+static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
+{
+ PBVHNode *f_node;
+ BMVert *v;
+
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ /* Check if any of this face's vertices need to be removed
+ * from the node */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ v = l_iter->v;
+ if (pbvh_bmesh_node_vert_use_count(bvh, f_node, v) == 1) {
+ if (BLI_ghash_haskey(f_node->bm_unique_verts, v)) {
+ /* Find a different node that uses 'v' */
+ PBVHNode *new_node;
+
+ new_node = pbvh_bmesh_vert_other_node_find(bvh, v);
+ BLI_assert(new_node || BM_vert_face_count(v) == 1);
+
+ if (new_node) {
+ pbvh_bmesh_vert_ownership_transfer(bvh, new_node, v);
+ }
+ }
+ else {
+ /* Remove from other verts */
+ BLI_ghash_remove(f_node->bm_other_verts, v, NULL, NULL);
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* Remove face from node and top level */
+ BLI_ghash_remove(f_node->bm_faces, f, NULL, NULL);
+ BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+
+ /* Log removed face */
+ BM_log_face_removed(bvh->bm_log, f);
+}
+
+static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
+{
+ /* fast-path for most common case where an edge has 2 faces,
+ * no need to iterate twice.
+ * This assumes that the buffer */
+ BMLoop **data = buf->data;
+ BLI_assert(buf->alloc_count >= 2);
+ if (LIKELY(BM_edge_loop_pair(e, &data[0], &data[1]))) {
+ buf->count = 2;
+ }
+ else {
+ BLI_buffer_resize(buf, BM_edge_face_count(e));
+ BM_iter_as_array(NULL, BM_LOOPS_OF_EDGE, e, buf->data, buf->count);
+ }
+}
+
+static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
+{
+ if (node->bm_orco)
+ MEM_freeN(node->bm_orco);
+ if (node->bm_ortri)
+ MEM_freeN(node->bm_ortri);
+ node->bm_orco = NULL;
+ node->bm_ortri = NULL;
+ node->bm_tot_ortri = 0;
+}
+
+/****************************** EdgeQueue *****************************/
+
+typedef struct {
+ Heap *heap;
+ const float *center;
+ float radius_squared;
+ float limit_len_squared;
+} EdgeQueue;
+
+static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
+{
+ BMVert *v_tri[3];
+ float c[3];
+
+ /* Get closest point in triangle to sphere center */
+ // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3);
+ BM_face_as_array_vert_tri(f, v_tri);
+
+ closest_on_tri_to_point_v3(c, q->center, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
+
+ /* Check if triangle intersects the sphere */
+ return ((len_squared_v3v3(q->center, c) <= q->radius_squared));
+}
+
+static void edge_queue_insert(EdgeQueue *q, BLI_mempool *pool, BMEdge *e,
+ float priority)
+{
+ BMVert **pair;
+
+ pair = BLI_mempool_alloc(pool);
+ pair[0] = e->v1;
+ pair[1] = e->v2;
+ BLI_heap_insert(q->heap, priority, pair);
+}
+
+static void long_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e)
+{
+ const float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq > q->limit_len_squared)
+ edge_queue_insert(q, pool, e, 1.0f / len_sq);
+}
+
+static void short_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e)
+{
+ const float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq < q->limit_len_squared)
+ edge_queue_insert(q, pool, e, len_sq);
+}
+
+static void long_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
+ BMFace *f)
+{
+ if (edge_queue_tri_in_sphere(q, f)) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ /* Check each edge of the face */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ long_edge_queue_edge_add(q, pool, l_iter->e);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+}
+
+static void short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
+ BMFace *f)
+{
+ if (edge_queue_tri_in_sphere(q, f)) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ /* Check each edge of the face */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ short_edge_queue_edge_add(q, pool, l_iter->e);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+}
+
+/* Create a priority queue containing vertex pairs connected by a long
+ * edge as defined by PBVH.bm_max_edge_len.
+ *
+ * Only nodes marked for topology update are checked, and in those
+ * nodes only edges used by a face intersecting the (center, radius)
+ * sphere are checked.
+ *
+ * The highest priority (lowest number) is given to the longest edge.
+ */
+static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
+ PBVH *bvh, const float center[3],
+ float radius)
+{
+ int n;
+
+ q->heap = BLI_heap_new();
+ q->center = center;
+ q->radius_squared = radius * radius;
+ q->limit_len_squared = bvh->bm_max_edge_len * bvh->bm_max_edge_len;
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ /* Check leaf nodes marked for topology update */
+ if ((node->flag & PBVH_Leaf) &&
+ (node->flag & PBVH_UpdateTopology))
+ {
+ GHashIterator gh_iter;
+
+ /* Check each face */
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ long_edge_queue_face_add(q, pool, f);
+ }
+ }
+ }
+}
+
+/* Create a priority queue containing vertex pairs connected by a
+ * short edge as defined by PBVH.bm_min_edge_len.
+ *
+ * Only nodes marked for topology update are checked, and in those
+ * nodes only edges used by a face intersecting the (center, radius)
+ * sphere are checked.
+ *
+ * The highest priority (lowest number) is given to the shortest edge.
+ */
+static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
+ PBVH *bvh, const float center[3],
+ float radius)
+{
+ int n;
+
+ q->heap = BLI_heap_new();
+ q->center = center;
+ q->radius_squared = radius * radius;
+ q->limit_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ /* Check leaf nodes marked for topology update */
+ if ((node->flag & PBVH_Leaf) &&
+ (node->flag & PBVH_UpdateTopology))
+ {
+ GHashIterator gh_iter;
+
+ /* Check each face */
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ short_edge_queue_face_add(q, pool, f);
+ }
+ }
+ }
+}
+
+/*************************** Topology update **************************/
+
+static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e, BLI_Buffer *edge_loops)
+{
+ BMVert *v_new;
+ float mid[3];
+ int i, node_index;
+
+ /* Get all faces adjacent to the edge */
+ pbvh_bmesh_edge_loops(edge_loops, e);
+
+ /* Create a new vertex in current node at the edge's midpoint */
+ mid_v3_v3v3(mid, e->v1->co, e->v2->co);
+
+ node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(bvh->bm_vert_to_node,
+ e->v1));
+ v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1);
+
+ /* For each face, add two new triangles and delete the original */
+ for (i = 0; i < edge_loops->count; i++) {
+ BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
+ BMFace *f_adj = l_adj->f;
+ BMFace *f_new;
+ BMVert *opp, *v1, *v2;
+ void *nip;
+ int ni;
+
+ BLI_assert(f_adj->len == 3);
+ nip = BLI_ghash_lookup(bvh->bm_face_to_node, f_adj);
+ ni = GET_INT_FROM_POINTER(nip);
+
+ /* Ensure node gets redrawn */
+ bvh->nodes[ni].flag |= PBVH_UpdateDrawBuffers;
+
+ /* Find the vertex not in the edge */
+ opp = l_adj->prev->v;
+
+ /* Get e->v1 and e->v2 in the order they appear in the
+ * existing face so that the new faces' winding orders
+ * match */
+ v1 = l_adj->v;
+ v2 = l_adj->next->v;
+
+ if (ni != node_index && i == 0)
+ pbvh_bmesh_vert_ownership_transfer(bvh, &bvh->nodes[ni], v_new);
+
+ /* Create two new faces */
+ f_new = pbvh_bmesh_face_create(bvh, ni, v1, v_new, opp, f_adj);
+ long_edge_queue_face_add(q, pool, f_new);
+ f_new = pbvh_bmesh_face_create(bvh, ni, v_new, v2, opp, f_adj);
+ long_edge_queue_face_add(q, pool, f_new);
+
+ /* Delete original */
+ pbvh_bmesh_face_remove(bvh, f_adj);
+ BM_face_kill(bvh->bm, f_adj);
+
+ /* Ensure new vertex is in the node */
+ if (!BLI_ghash_haskey(bvh->nodes[ni].bm_unique_verts, v_new) &&
+ !BLI_ghash_haskey(bvh->nodes[ni].bm_other_verts, v_new))
+ {
+ BLI_ghash_insert(bvh->nodes[ni].bm_other_verts, v_new, NULL);
+ }
+
+ if (BM_vert_edge_count(opp) >= 9) {
+ BMIter bm_iter;
+ BMEdge *e2;
+
+ BM_ITER_ELEM (e2, &bm_iter, opp, BM_EDGES_OF_VERT) {
+ long_edge_queue_edge_add(q, pool, e2);
+ }
+ }
+ }
+
+ BM_edge_kill(bvh->bm, e);
+}
+
+static int pbvh_bmesh_subdivide_long_edges(PBVH *bvh, EdgeQueue *q,
+ BLI_mempool *pool,
+ BLI_Buffer *edge_loops)
+{
+ int any_subdivided = FALSE;
+
+ while (!BLI_heap_is_empty(q->heap)) {
+ BMVert **pair = BLI_heap_popmin(q->heap);
+ BMEdge *e;
+
+ /* Check that the edge still exists */
+ if (!(e = BM_edge_exists(pair[0], pair[1]))) {
+ BLI_mempool_free(pool, pair);
+ continue;
+ }
+
+ BLI_mempool_free(pool, pair);
+ pair = NULL;
+
+ /* Check that the edge's vertices are still in the PBVH. It's
+ * possible that an edge collapse has deleted adjacent faces
+ * and the node has been split, thus leaving wire edges and
+ * associated vertices. */
+ if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
+ !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ {
+ continue;
+ }
+
+ if (BM_edge_calc_length_squared(e) <= q->limit_len_squared)
+ continue;
+
+ any_subdivided = TRUE;
+
+ pbvh_bmesh_split_edge(bvh, q, pool, e, edge_loops);
+ }
+
+ return any_subdivided;
+}
+
+static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
+ BMVert *v2, GHash *deleted_verts,
+ BLI_Buffer *edge_loops,
+ BLI_Buffer *deleted_faces)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ int i;
+
+ /* Get all faces adjacent to the edge */
+ pbvh_bmesh_edge_loops(edge_loops, e);
+
+ /* Remove the merge vertex from the PBVH */
+ pbvh_bmesh_vert_remove(bvh, v2);
+
+ /* Remove all faces adjacent to the edge */
+ for (i = 0; i < edge_loops->count; i++) {
+ BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
+ BMFace *f_adj = l_adj->f;
+
+ pbvh_bmesh_face_remove(bvh, f_adj);
+ BM_face_kill(bvh->bm, f_adj);
+ }
+
+ /* Kill the edge */
+ BLI_assert(BM_edge_face_count(e) == 0);
+ BM_edge_kill(bvh->bm, e);
+
+ /* For all remaining faces of v2, create a new face that is the
+ * same except it uses v1 instead of v2 */
+ /* Note: this could be done with BM_vert_splice(), but that
+ * requires handling other issues like duplicate edges, so doesn't
+ * really buy anything. */
+ deleted_faces->count = 0;
+ BM_ITER_ELEM (f, &bm_iter, v2, BM_FACES_OF_VERT) {
+ BMVert *v_tri[3];
+ BMFace *existing_face;
+ PBVHNode *n;
+ int ni;
+
+ /* Get vertices, replace use of v2 with v1 */
+ // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3);
+ BM_face_as_array_vert_tri(f, v_tri);
+ for (i = 0; i < 3; i++) {
+ if (v_tri[i] == v2) {
+ v_tri[i] = v1;
+ }
+ }
+
+ /* Check if a face using these vertices already exists. If so,
+ * skip adding this face and mark the existing one for
+ * deletion as well. Prevents extraneous "flaps" from being
+ * created. */
+ if (BM_face_exists(v_tri, 3, &existing_face)) {
+ BLI_assert(existing_face);
+ BLI_buffer_append(deleted_faces, BMFace *, existing_face);
+ }
+ else {
+ n = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ ni = n - bvh->nodes;
+ pbvh_bmesh_face_create(bvh, ni, v_tri[0], v_tri[1], v_tri[2], f);
+
+ /* Ensure that v1 is in the new face's node */
+ if (!BLI_ghash_haskey(n->bm_unique_verts, v1) &&
+ !BLI_ghash_haskey(n->bm_other_verts, v1)) {
+ BLI_ghash_insert(n->bm_other_verts, v1, NULL);
+ }
+ }
+
+ BLI_buffer_append(deleted_faces, BMFace *, f);
+ }
+
+ /* Delete the tagged faces */
+ for (i = 0; i < deleted_faces->count; i++) {
+ BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
+ BMVert *v_tri[3];
+ BMEdge *e_tri[3];
+ int j;
+
+ /* Get vertices and edges of face */
+ BM_face_as_array_vert_tri(f_del, v_tri);
+ for (j = 0; j < 3; j++)
+ e_tri[j] = BM_edge_exists(v_tri[j], v_tri[j == 2 ? 0 : j + 1]);
+
+ /* Check if any of the face's vertices are now unused, if so
+ * remove them from the PBVH */
+ for (j = 0; j < 3; j++) {
+ if (v_tri[j] != v2 && BM_vert_face_count(v_tri[j]) == 1) {
+ BLI_ghash_insert(deleted_verts, v_tri[j], NULL);
+ pbvh_bmesh_vert_remove(bvh, v_tri[j]);
+ }
+ else {
+ v_tri[j] = NULL;
+ }
+ }
+
+ /* Remove the face */
+ pbvh_bmesh_face_remove(bvh, f_del);
+ BM_face_kill(bvh->bm, f_del);
+
+ /* Check if any of the face's edges are now unused by any
+ * face, if so delete them */
+ for (j = 0; j < 3; j++) {
+ if (BM_edge_face_count(e_tri[j]) == 0)
+ BM_edge_kill(bvh->bm, e_tri[j]);
+ }
+
+ /* Delete unused vertices */
+ for (j = 0; j < 3; j++) {
+ if (v_tri[j]) {
+ BM_log_vert_removed(bvh->bm, bvh->bm_log, v_tri[j]);
+ BM_vert_kill(bvh->bm, v_tri[j]);
+ }
+ }
+ }
+
+ /* Move v1 to the midpoint of v1 and v2 (if v1 still exists, it
+ * may have been deleted above) */
+ if (!BLI_ghash_haskey(deleted_verts, v1)) {
+ BM_log_vert_before_modified(bvh->bm, bvh->bm_log, v1);
+ mid_v3_v3v3(v1->co, v1->co, v2->co);
+ }
+
+ /* Delete v2 */
+ BLI_assert(BM_vert_face_count(v2) == 0);
+ BLI_ghash_insert(deleted_verts, v2, NULL);
+ BM_log_vert_removed(bvh->bm, bvh->bm_log, v2);
+ BM_vert_kill(bvh->bm, v2);
+}
+
+static int pbvh_bmesh_collapse_short_edges(PBVH *bvh, EdgeQueue *q,
+ BLI_mempool *pool,
+ BLI_Buffer *edge_loops,
+ BLI_Buffer *deleted_faces)
+{
+ float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
+ GHash *deleted_verts;
+ int any_collapsed = FALSE;
+
+ deleted_verts = BLI_ghash_ptr_new("deleted_verts");
+
+ while (!BLI_heap_is_empty(q->heap)) {
+ BMVert **pair = BLI_heap_popmin(q->heap);
+ BMEdge *e;
+ BMVert *v1, *v2;
+
+ v1 = pair[0];
+ v2 = pair[1];
+ BLI_mempool_free(pool, pair);
+ pair = NULL;
+
+ /* Check that the vertices/edge still exist */
+ if (BLI_ghash_haskey(deleted_verts, v1) ||
+ BLI_ghash_haskey(deleted_verts, v2) ||
+ !(e = BM_edge_exists(v1, v2)))
+ {
+ continue;
+ }
+
+ /* Check that the edge's vertices are still in the PBVH. It's
+ * possible that an edge collapse has deleted adjacent faces
+ * and the node has been split, thus leaving wire edges and
+ * associated vertices. */
+ if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
+ !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ {
+ continue;
+ }
+
+ if (BM_edge_calc_length_squared(e) >= min_len_squared)
+ continue;
+
+ any_collapsed = TRUE;
+
+ pbvh_bmesh_collapse_edge(bvh, e, v1, v2,
+ deleted_verts, edge_loops,
+ deleted_faces);
+ }
+
+ BLI_ghash_free(deleted_verts, NULL, NULL);
+
+ return any_collapsed;
+}
+
+/************************* Called from pbvh.c *************************/
+
+int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
+ const float ray_normal[3], float *dist,
+ int use_original)
+{
+ GHashIterator gh_iter;
+ int hit = 0;
+
+ if (use_original && node->bm_tot_ortri) {
+ int i;
+ for (i = 0; i < node->bm_tot_ortri; i++) {
+ const int *t = node->bm_ortri[i];
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ node->bm_orco[t[0]],
+ node->bm_orco[t[1]],
+ node->bm_orco[t[2]],
+ NULL, dist);
+ }
+ }
+ else {
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ BLI_assert(f->len == 3);
+ if (f->len == 3 && !paint_is_bmesh_face_hidden(f)) {
+ BMVert *v_tri[3];
+
+ BM_face_as_array_vert_tri(f, v_tri);
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ v_tri[0]->co,
+ v_tri[1]->co,
+ v_tri[2]->co,
+ NULL, dist);
+ }
+ }
+ }
+
+ return hit;
+}
+
+void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
+{
+ int n;
+
+ for (n = 0; n < totnode; n++) {
+ PBVHNode *node = nodes[n];
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BM_face_normal_update(BLI_ghashIterator_getKey(&gh_iter));
+ }
+ GHASH_ITER (gh_iter, node->bm_unique_verts) {
+ BM_vert_normal_update(BLI_ghashIterator_getKey(&gh_iter));
+ }
+ }
+}
+
+/***************************** Public API *****************************/
+
+/* Build a PBVH from a BMesh */
+void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
+ BMLog *log)
+{
+ BMIter iter;
+ BMFace *f;
+ PBVHNode *n;
+ int node_index = 0;
+
+ bvh->bm = bm;
+
+ BKE_pbvh_bmesh_detail_size_set(bvh, 0.75);
+
+ bvh->type = PBVH_BMESH;
+ bvh->bm_face_to_node = BLI_ghash_ptr_new("bm_face_to_node");
+ bvh->bm_vert_to_node = BLI_ghash_ptr_new("bm_vert_to_node");
+ bvh->bm_log = log;
+
+ /* TODO: choose leaf limit better */
+ bvh->leaf_limit = 100;
+
+ if (smooth_shading)
+ bvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
+
+ /* Start with all faces in the root node */
+ n = bvh->nodes = MEM_callocN(sizeof(PBVHNode), "PBVHNode");
+ bvh->totnode = 1;
+ n->flag = PBVH_Leaf;
+ n->bm_faces = BLI_ghash_ptr_new("bm_faces");
+ BM_ITER_MESH (f, &iter, bvh->bm, BM_FACES_OF_MESH) {
+ BLI_ghash_insert(n->bm_faces, f, NULL);
+ }
+
+ /* Recursively split the node until it is under the limit; if no
+ * splitting occurs then finalize the existing leaf node */
+ if (!pbvh_bmesh_node_limit_ensure(bvh, node_index))
+ pbvh_bmesh_node_finalize(bvh, 0);
+}
+
+/* Collapse short edges, subdivide long edges */
+int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+ const float center[3], float radius)
+{
+ /* 2 is enough for edge faces - manifold edge */
+ BLI_buffer_declare_static(BMFace *, edge_loops, BLI_BUFFER_NOP, 2);
+ BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
+
+ int modified = FALSE;
+ int n;
+
+ if (mode & PBVH_Collapse) {
+ EdgeQueue q;
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
+ 128, 128, 0);
+ short_edge_queue_create(&q, queue_pool, bvh, center, radius);
+ pbvh_bmesh_collapse_short_edges(bvh, &q, queue_pool, &edge_loops,
+ &deleted_faces);
+ BLI_heap_free(q.heap, NULL);
+ BLI_mempool_destroy(queue_pool);
+ }
+
+ if (mode & PBVH_Subdivide) {
+ EdgeQueue q;
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
+ 128, 128, 0);
+ long_edge_queue_create(&q, queue_pool, bvh, center, radius);
+ pbvh_bmesh_subdivide_long_edges(bvh, &q, queue_pool, &edge_loops);
+ BLI_heap_free(q.heap, NULL);
+ BLI_mempool_destroy(queue_pool);
+ }
+
+ /* Unmark nodes */
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ if (node->flag & PBVH_Leaf &&
+ node->flag & PBVH_UpdateTopology)
+ {
+ node->flag &= ~PBVH_UpdateTopology;
+ }
+ }
+ BLI_buffer_free(&edge_loops);
+ BLI_buffer_free(&deleted_faces);
+
+ return modified;
+}
+
+BLI_INLINE void bm_face_as_array_index_tri(BMFace *f, int r_index[3])
+{
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
+
+ BLI_assert(f->len == 3);
+
+ r_index[0] = BM_elem_index_get(l->v); l = l->next;
+ r_index[1] = BM_elem_index_get(l->v); l = l->next;
+ r_index[2] = BM_elem_index_get(l->v);
+}
+
+/* In order to perform operations on the original node coordinates
+ * (currently just raycast), store the node's triangles and vertices.
+ *
+ * Skips triangles that are hidden. */
+void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
+{
+ GHashIterator gh_iter;
+ int i, totvert, tottri;
+
+ /* Skip if original coords/triangles are already saved */
+ if (node->bm_orco)
+ return;
+
+ totvert = (BLI_ghash_size(node->bm_unique_verts) +
+ BLI_ghash_size(node->bm_other_verts));
+
+ tottri = BLI_ghash_size(node->bm_faces);
+
+ node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, AT);
+ node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, AT);
+
+ /* Copy out the vertices and assign a temporary index */
+ i = 0;
+ GHASH_ITER (gh_iter, node->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ copy_v3_v3(node->bm_orco[i], v->co);
+ BM_elem_index_set(v, i); /* set_dirty! */
+ i++;
+ }
+ GHASH_ITER (gh_iter, node->bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ copy_v3_v3(node->bm_orco[i], v->co);
+ BM_elem_index_set(v, i); /* set_dirty! */
+ i++;
+ }
+
+ /* Copy the triangles */
+ i = 0;
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ if (paint_is_bmesh_face_hidden(f))
+ continue;
+
+#if 0
+ BMIter bm_iter;
+ BMVert *v;
+ int j = 0;
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ node->bm_ortri[i][j] = BM_elem_index_get(v);
+ j++;
+ }
+#else
+ bm_face_as_array_index_tri(f, node->bm_ortri[i]);
+#endif
+ i++;
+ }
+ node->bm_tot_ortri = i;
+}
+
+void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
+{
+ int i;
+ for (i = 0; i < bvh->totnode; i++) {
+ PBVHNode *n = &bvh->nodes[i];
+ if (n->flag & PBVH_Leaf) {
+ /* Free orco/ortri data */
+ pbvh_bmesh_node_drop_orig(n);
+
+ /* Recursively split nodes that have gotten too many
+ * elements */
+ pbvh_bmesh_node_limit_ensure(bvh, i);
+ }
+ }
+}
+
+void BKE_pbvh_bmesh_detail_size_set(PBVH *bvh, float detail_size)
+{
+ bvh->bm_max_edge_len = detail_size;
+ bvh->bm_min_edge_len = bvh->bm_max_edge_len * 0.4f;
+}
+
+void BKE_pbvh_node_mark_topology_update(PBVHNode *node)
+{
+ node->flag |= PBVH_UpdateTopology;
+}
+
+GHash *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node)
+{
+ return node->bm_unique_verts;
+}
+
+GHash *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node)
+{
+ return node->bm_other_verts;
+}
+
+/****************************** Debugging *****************************/
+
+#if 0
+void bli_ghash_duplicate_key_check(GHash *gh)
+{
+ GHashIterator gh_iter1, gh_iter2;
+
+ GHASH_ITER (gh_iter1, gh) {
+ void *key1 = BLI_ghashIterator_getKey(&gh_iter1);
+ int dup = -1;
+
+ GHASH_ITER (gh_iter2, gh) {
+ void *key2 = BLI_ghashIterator_getKey(&gh_iter2);
+
+ if (key1 == key2) {
+ dup++;
+ if (dup > 0) {
+ BLI_assert(!"duplicate in hash");
+ }
+ }
+ }
+ }
+}
+
+void bmesh_print(BMesh *bm)
+{
+ BMIter iter, siter;
+ BMVert *v;
+ BMEdge *e;
+ BMFace *f;
+ BMLoop *l;
+
+ fprintf(stderr, "\nbm=%p, totvert=%d, totedge=%d, "
+ "totloop=%d, totface=%d\n",
+ bm, bm->totvert, bm->totedge,
+ bm->totloop, bm->totface);
+
+ fprintf(stderr, "vertices:\n");
+ BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+ fprintf(stderr, " %d co=(%.3f %.3f %.3f) oflag=%x\n",
+ BM_elem_index_get(v), v->co[0], v->co[1], v->co[2],
+ v->oflags[bm->stackdepth - 1].f);
+ }
+
+ fprintf(stderr, "edges:\n");
+ BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
+ fprintf(stderr, " %d v1=%d, v2=%d, oflag=%x\n",
+ BM_elem_index_get(e),
+ BM_elem_index_get(e->v1),
+ BM_elem_index_get(e->v2),
+ e->oflags[bm->stackdepth - 1].f);
+ }
+
+ fprintf(stderr, "faces:\n");
+ BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
+ fprintf(stderr, " %d len=%d, oflag=%x\n",
+ BM_elem_index_get(f), f->len,
+ f->oflags[bm->stackdepth - 1].f);
+
+ fprintf(stderr, " v: ");
+ BM_ITER_ELEM(v, &siter, f, BM_VERTS_OF_FACE) {
+ fprintf(stderr, "%d ", BM_elem_index_get(v));
+ }
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " e: ");
+ BM_ITER_ELEM(e, &siter, f, BM_EDGES_OF_FACE) {
+ fprintf(stderr, "%d ", BM_elem_index_get(e));
+ }
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " l: ");
+ BM_ITER_ELEM(l, &siter, f, BM_LOOPS_OF_FACE) {
+ fprintf(stderr, "%d(v=%d, e=%d) ",
+ BM_elem_index_get(l),
+ BM_elem_index_get(l->v),
+ BM_elem_index_get(l->e));
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+void pbvh_bmesh_print(PBVH *bvh)
+{
+ GHashIterator gh_iter;
+ int n;
+
+ fprintf(stderr, "\npbvh=%p\n", bvh);
+ fprintf(stderr, "bm_face_to_node:\n");
+ GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
+ fprintf(stderr, " %d -> %d\n",
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ }
+
+ fprintf(stderr, "bm_vert_to_node:\n");
+ GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
+ fprintf(stderr, " %d -> %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ }
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+ if (!(node->flag & PBVH_Leaf))
+ continue;
+
+ fprintf(stderr, "node %d\n faces:\n", n);
+ GHASH_ITER (gh_iter, node->bm_faces)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)));
+ fprintf(stderr, " unique verts:\n");
+ GHASH_ITER (gh_iter, node->bm_unique_verts)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ fprintf(stderr, " other verts:\n");
+ GHASH_ITER (gh_iter, node->bm_other_verts)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ }
+}
+
+void print_flag_factors(int flag)
+{
+ int i;
+ printf("flag=0x%x:\n", flag);
+ for (i = 0; i < 32; i++) {
+ if (flag & (1 << i)) {
+ printf(" %d (1 << %d)\n", 1 << i, i);
+ }
+ }
+}
+
+void pbvh_bmesh_verify(PBVH *bvh)
+{
+ GHashIterator gh_iter;
+ int i;
+
+ /* Check faces */
+ BLI_assert(bvh->bm->totface == BLI_ghash_size(bvh->bm_face_to_node));
+ GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghashIterator_getValue(&gh_iter);
+ int ni = GET_INT_FROM_POINTER(nip);
+ PBVHNode *n = &bvh->nodes[ni];
+
+ /* Check that the face's node is a leaf */
+ BLI_assert(n->flag & PBVH_Leaf);
+
+ /* Check that the face's node knows it owns the face */
+ BLI_assert(BLI_ghash_haskey(n->bm_faces, f));
+
+ /* Check the face's vertices... */
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ PBVHNode *nv;
+
+ /* Check that the vertex is in the node */
+ BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v) ^
+ BLI_ghash_haskey(n->bm_other_verts, v));
+
+ /* Check that the vertex has a node owner */
+ nv = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+
+ /* Check that the vertex's node knows it owns the vert */
+ BLI_assert(BLI_ghash_haskey(nv->bm_unique_verts, v));
+
+ /* Check that the vertex isn't duplicated as an 'other' vert */
+ BLI_assert(!BLI_ghash_haskey(nv->bm_other_verts, v));
+ }
+ }
+
+ /* Check verts */
+ BLI_assert(bvh->bm->totvert == BLI_ghash_size(bvh->bm_vert_to_node));
+ GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
+ BMIter bm_iter;
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BMFace *f;
+ void *nip = BLI_ghashIterator_getValue(&gh_iter);
+ int ni = GET_INT_FROM_POINTER(nip);
+ PBVHNode *n = &bvh->nodes[ni];
+ int found;
+
+ /* Check that the vert's node is a leaf */
+ BLI_assert(n->flag & PBVH_Leaf);
+
+ /* Check that the vert's node knows it owns the vert */
+ BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v));
+
+ /* Check that the vertex isn't duplicated as an 'other' vert */
+ BLI_assert(!BLI_ghash_haskey(n->bm_other_verts, v));
+
+ /* Check that the vert's node also contains one of the vert's
+ * adjacent faces */
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ if (BLI_ghash_lookup(bvh->bm_face_to_node, f) == nip) {
+ found = TRUE;
+ break;
+ }
+ }
+ BLI_assert(found);
+ }
+
+ /* Check that node elements are recorded in the top level */
+ for (i = 0; i < bvh->totnode; i++) {
+ PBVHNode *n = &bvh->nodes[i];
+ if (n->flag & PBVH_Leaf) {
+ /* Check for duplicate entries */
+ /* Slow */
+ #if 0
+ bli_ghash_duplicate_key_check(n->bm_faces);
+ bli_ghash_duplicate_key_check(n->bm_unique_verts);
+ bli_ghash_duplicate_key_check(n->bm_other_verts);
+ #endif
+
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghash_lookup(bvh->bm_face_to_node, f);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_face_to_node, f));
+ BLI_assert(GET_INT_FROM_POINTER(nip) == (n - bvh->nodes));
+ }
+
+ GHASH_ITER (gh_iter, n->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghash_lookup(bvh->bm_vert_to_node, v);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ BLI_assert(!BLI_ghash_haskey(n->bm_other_verts, v));
+ BLI_assert(GET_INT_FROM_POINTER(nip) == (n - bvh->nodes));
+ }
+
+ GHASH_ITER (gh_iter, n->bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ BLI_assert(BM_vert_face_count(v) > 0);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
new file mode 100644
index 00000000000..b3f7bf6e3d1
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh_intern.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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __PBVH_INTERN_H__
+#define __PBVH_INTERN_H__
+
+/* Axis-aligned bounding box */
+typedef struct {
+ float bmin[3], bmax[3];
+} BB;
+
+/* Axis-aligned bounding box with centroid */
+typedef struct {
+ float bmin[3], bmax[3], bcentroid[3];
+} BBC;
+
+/* Note: this structure is getting large, might want to split it into
+ * union'd structs */
+struct PBVHNode {
+ /* Opaque handle for drawing code */
+ struct GPU_Buffers *draw_buffers;
+
+ /* Voxel bounds */
+ BB vb;
+ BB orig_vb;
+
+ /* For internal nodes, the offset of the children in the PBVH
+ * 'nodes' array. */
+ int children_offset;
+
+ /* Pointer into the PBVH prim_indices array and the number of
+ * primitives used by this leaf node.
+ *
+ * Used for leaf nodes in both mesh- and multires-based PBVHs.
+ */
+ int *prim_indices;
+ unsigned int totprim;
+
+ /* Array of indices into the mesh's MVert array. Contains the
+ * indices of all vertices used by faces that are within this
+ * node's bounding box.
+ *
+ * Note that a vertex might be used by a multiple faces, and
+ * these faces might be in different leaf nodes. Such a vertex
+ * will appear in the vert_indices array of each of those leaf
+ * nodes.
+ *
+ * In order to support cases where you want access to multiple
+ * nodes' vertices without duplication, the vert_indices array
+ * is ordered such that the first part of the array, up to
+ * index 'uniq_verts', contains "unique" vertex indices. These
+ * vertices might not be truly unique to this node, but if
+ * they appear in another node's vert_indices array, they will
+ * be above that node's 'uniq_verts' value.
+ *
+ * Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int *vert_indices;
+ unsigned int uniq_verts, face_verts;
+
+ /* An array mapping face corners into the vert_indices
+ * array. The array is sized to match 'totprim', and each of
+ * the face's corners gets an index into the vert_indices
+ * array, in the same order as the corners in the original
+ * MFace. The fourth value should not be used if the original
+ * face is a triangle.
+ *
+ * Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int (*face_vert_indices)[4];
+
+ /* Indicates whether this node is a leaf or not; also used for
+ * marking various updates that need to be applied. */
+ PBVHNodeFlags flag : 16;
+
+ /* Used for raycasting: how close bb is to the ray point. */
+ float tmin;
+
+ /* Scalar displacements for sculpt mode's layer brush. */
+ float *layer_disp;
+
+ int proxy_count;
+ PBVHProxyNode *proxies;
+
+ /* Dyntopo */
+ GHash *bm_faces;
+ GHash *bm_unique_verts;
+ GHash *bm_other_verts;
+ float (*bm_orco)[3];
+ int (*bm_ortri)[3];
+ int bm_tot_ortri;
+};
+
+typedef enum {
+ PBVH_DYNTOPO_SMOOTH_SHADING = 1
+} PBVHFlags;
+
+typedef struct PBVHBMeshLog PBVHBMeshLog;
+
+struct PBVH {
+ PBVHType type;
+ PBVHFlags flags;
+
+ PBVHNode *nodes;
+ int node_mem_count, totnode;
+
+ int *prim_indices;
+ int totprim;
+ int totvert;
+
+ int leaf_limit;
+
+ /* Mesh data */
+ MVert *verts;
+ MFace *faces;
+ CustomData *vdata;
+
+ /* Grid Data */
+ CCGKey gridkey;
+ CCGElem **grids;
+ DMGridAdjacency *gridadj;
+ void **gridfaces;
+ const DMFlagMat *grid_flag_mats;
+ int totgrid;
+ BLI_bitmap *grid_hidden;
+
+ /* Only used during BVH build and update,
+ * don't need to remain valid after */
+ BLI_bitmap vert_bitmap;
+
+#ifdef PERFCNTRS
+ int perf_modified;
+#endif
+
+ /* flag are verts/faces deformed */
+ int deformed;
+
+ int show_diffuse_color;
+
+ /* Dynamic topology */
+ BMesh *bm;
+ GHash *bm_face_to_node;
+ GHash *bm_vert_to_node;
+ float bm_max_edge_len;
+ float bm_min_edge_len;
+
+ struct BMLog *bm_log;
+};
+
+/* pbvh.c */
+void BB_reset(BB *bb);
+void BB_expand(BB *bb, const float co[3]);
+void BB_expand_with_bb(BB *bb, BB *bb2);
+void BBC_update_centroid(BBC *bbc);
+int BB_widest_axis(const BB *bb);
+void pbvh_grow_nodes(PBVH *bvh, int totnode);
+int ray_face_intersection(const float ray_start[3], const float ray_normal[3],
+ const float *t0, const float *t1, const float *t2,
+ const float *t3, float *fdist);
+void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag);
+
+/* pbvh_bmesh.c */
+int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
+ const float ray_normal[3], float *dist,
+ int use_original);
+
+void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
+
+#endif
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 965a1e2b4a6..27c5e03132e 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -43,6 +43,7 @@
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_particle_types.h"
+#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
@@ -51,6 +52,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "PIL_time.h"
#include "WM_api.h"
@@ -72,6 +75,10 @@
#include "BIK_api.h"
+#ifdef WITH_BULLET
+# include "RBI_api.h"
+#endif
+
/* both in intern */
#ifdef WITH_SMOKE
#include "smoke_API.h"
@@ -272,7 +279,7 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
ParticleSystem *psys= psys_v;
ParticleData *pa;
BoidParticle *boid;
- float timestep = 0.04f*psys->part->timetweak;
+ float timestep = 0.04f * psys->part->timetweak;
if (index >= psys->totpart)
return;
@@ -308,8 +315,9 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
pa->lifetime = times[2];
}
- if (boid)
+ if (boid) {
PTCACHE_DATA_TO(data, BPHYS_DATA_BOIDS, 0, &boid->data);
+ }
/* determine velocity from previous location */
if (data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
@@ -333,7 +341,7 @@ static void ptcache_particle_interpolate(int index, void *psys_v, void **data, f
ParticleSystem *psys= psys_v;
ParticleData *pa;
ParticleKey keys[4];
- float dfra, timestep = 0.04f*psys->part->timetweak;
+ float dfra, timestep = 0.04f * psys->part->timetweak;
if (index >= psys->totpart)
return;
@@ -559,7 +567,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b;
unsigned char *obstacles;
unsigned int in_len = sizeof(float)*(unsigned int)res;
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
//int mode = res >= 1000000 ? 2 : 1;
int mode=1; // light
if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy
@@ -792,7 +800,7 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
int cache_compress = 1;
/* version header */
- ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char)*4);
+ ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char) * 4);
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
int total_points=surface->data->total_points;
@@ -831,7 +839,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
char version[4];
/* version header */
- ptcache_file_read(pf, version, 1, sizeof(char)*4);
+ ptcache_file_read(pf, version, 1, sizeof(char) * 4);
if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {printf("Dynamic Paint: Invalid cache version: %s!\n", version); return 0;}
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
@@ -866,6 +874,97 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
return 1;
}
+/* Rigid Body functions */
+static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSED(cfra))
+{
+ RigidBodyWorld *rbw = rb_v;
+ Object *ob = NULL;
+
+ if (rbw->objects)
+ ob = rbw->objects[index];
+
+ if (ob && ob->rigidbody_object) {
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ if (rbo->type == RBO_TYPE_ACTIVE) {
+#ifdef WITH_BULLET
+ RB_body_get_position(rbo->physics_object, rbo->pos);
+ RB_body_get_orientation(rbo->physics_object, rbo->orn);
+#endif
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, rbo->pos);
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, rbo->orn);
+ }
+ }
+
+ return 1;
+}
+static void ptcache_rigidbody_read(int index, void *rb_v, void **data, float UNUSED(cfra), float *old_data)
+{
+ RigidBodyWorld *rbw = rb_v;
+ Object *ob = NULL;
+
+ if (rbw->objects)
+ ob = rbw->objects[index];
+
+ if (ob && ob->rigidbody_object) {
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ if (rbo->type == RBO_TYPE_ACTIVE) {
+
+ if (old_data) {
+ memcpy(rbo->pos, data, 3 * sizeof(float));
+ memcpy(rbo->orn, data + 3, 4 * sizeof(float));
+ }
+ else {
+ PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, rbo->pos);
+ PTCACHE_DATA_TO(data, BPHYS_DATA_ROTATION, 0, rbo->orn);
+ }
+ }
+ }
+}
+static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+{
+ RigidBodyWorld *rbw = rb_v;
+ Object *ob = NULL;
+ ParticleKey keys[4];
+ float dfra;
+
+ if (rbw->objects)
+ ob = rbw->objects[index];
+
+ if (ob && ob->rigidbody_object) {
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ if (rbo->type == RBO_TYPE_ACTIVE) {
+
+ copy_v3_v3(keys[1].co, rbo->pos);
+ copy_v3_v3(keys[1].rot, rbo->orn);
+
+ if (old_data) {
+ memcpy(keys[2].co, data, 3 * sizeof(float));
+ memcpy(keys[2].rot, data + 3, 4 * sizeof(float));
+ }
+ else {
+ 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);
+
+ copy_v3_v3(rbo->pos, keys->co);
+ copy_v3_v3(rbo->orn, keys->rot);
+ }
+ }
+}
+static int ptcache_rigidbody_totpoint(void *rb_v, int UNUSED(cfra))
+{
+ RigidBodyWorld *rbw = rb_v;
+
+ return rbw->numbodies;
+}
+
/* Creating ID's */
void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
{
@@ -1071,6 +1170,42 @@ void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, Object *ob, DynamicPaintSu
pid->max_step = 1;
}
+void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *rbw)
+{
+
+ memset(pid, 0, sizeof(PTCacheID));
+
+ pid->ob= ob;
+ pid->calldata= rbw;
+ pid->type= PTCACHE_TYPE_RIGIDBODY;
+ pid->cache= rbw->pointcache;
+ pid->cache_ptr= &rbw->pointcache;
+ pid->ptcaches= &rbw->ptcaches;
+ pid->totpoint= pid->totwrite= ptcache_rigidbody_totpoint;
+
+ pid->write_point = ptcache_rigidbody_write;
+ pid->read_point = ptcache_rigidbody_read;
+ pid->interpolate_point = ptcache_rigidbody_interpolate;
+
+ pid->write_stream = NULL;
+ pid->read_stream = NULL;
+
+ pid->write_extra_data = NULL;
+ pid->read_extra_data = NULL;
+ pid->interpolate_extra_data = NULL;
+
+ pid->write_header = ptcache_basic_header_write;
+ pid->read_header = ptcache_basic_header_read;
+
+ pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_ROTATION);
+ pid->info_types= 0;
+
+ pid->stack_index = pid->cache->index;
+
+ pid->default_step = 1;
+ pid->max_step = 1;
+}
+
void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
{
PTCacheID *pid;
@@ -1132,11 +1267,17 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
}
}
}
+
+ if (scene && ob->rigidbody_object && scene->rigidbody_world) {
+ pid = MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_rigidbody(pid, ob, scene->rigidbody_world);
+ BLI_addtail(lb, pid);
+ }
if (scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) {
ListBase *lb_dupli_ob;
- /* don't update the dupli groups, we only wan't their pid's */
+ /* don't update the dupli groups, we only want their pid's */
if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE, FALSE))) {
DupliObject *dob;
for (dob= lb_dupli_ob->first; dob; dob= dob->next) {
@@ -1163,7 +1304,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
*/
#define MAX_PTCACHE_PATH FILE_MAX
-#define MAX_PTCACHE_FILE ((FILE_MAX)*2)
+#define MAX_PTCACHE_FILE (FILE_MAX * 2)
static int ptcache_path(PTCacheID *pid, char *filename)
{
@@ -1258,7 +1399,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
{
PTCacheFile *pf;
FILE *fp = NULL;
- char filename[(FILE_MAX)*2];
+ char filename[FILE_MAX * 2];
#ifndef DURIAN_POINTCACHE_LIB_OK
/* don't allow writing for linked objects */
@@ -1311,7 +1452,7 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result,
size_t out_len = len;
#endif
unsigned char *in;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp");
ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
if (compressed) {
@@ -1354,7 +1495,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns
int r = 0;
unsigned char compressed = 0;
size_t out_len= 0;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp");
size_t sizeOfIt = 5;
(void)mode; /* unused when building w/o compression */
@@ -1540,7 +1681,7 @@ void BKE_ptcache_mem_pointers_incr(PTCacheMem *pm)
for (i=0; i<BPHYS_TOT_DATA; i++) {
if (pm->cur[i])
- pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
+ pm->cur[i] = (char *)pm->cur[i] + ptcache_data_size[i];
}
}
int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
@@ -1558,7 +1699,7 @@ int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
}
for (i=0; i<BPHYS_TOT_DATA; i++)
- pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+ pm->cur[i] = data_types & (1<<i) ? (char *)pm->data[i] + index * ptcache_data_size[i] : NULL;
return 1;
}
@@ -1787,7 +1928,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
for (i=0; i<BPHYS_TOT_DATA; i++) {
if (pm->data[i]) {
unsigned int in_len = pm->totpoint*ptcache_data_size[i];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(pf, (unsigned char *)(pm->data[i]), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
@@ -1820,7 +1961,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
if (pid->cache->compression) {
unsigned int in_len = extra->totdata * ptcache_extra_datasize[extra->type];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(pf, (unsigned char *)(extra->data), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
@@ -2535,7 +2676,7 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
after= 0;
if (mode == PTCACHE_RESET_DEPSGRAPH) {
- if (!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
+ if (!(cache->flag & PTCACHE_BAKED)) {
after= 1;
}
@@ -2543,12 +2684,7 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
cache->flag |= PTCACHE_OUTDATED;
}
else if (mode == PTCACHE_RESET_BAKED) {
- if (!BKE_ptcache_get_continue_physics()) {
- reset= 1;
- clear= 1;
- }
- else
- cache->flag |= PTCACHE_OUTDATED;
+ cache->flag |= PTCACHE_OUTDATED;
}
else if (mode == PTCACHE_RESET_OUTDATED) {
reset = 1;
@@ -2645,6 +2781,14 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
}
}
+ if (scene->rigidbody_world && (ob->rigidbody_object || ob->rigidbody_constraint)) {
+ if (ob->rigidbody_object)
+ ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_RESHAPE;
+ BKE_ptcache_id_from_rigidbody(&pid, ob, scene->rigidbody_world);
+ /* only flag as outdated, resetting should happen on start frame */
+ pid.cache->flag |= PTCACHE_OUTDATED;
+ }
+
if (ob->type == OB_ARMATURE)
BIK_clear_cache(ob->pose);
@@ -2694,30 +2838,6 @@ void BKE_ptcache_remove(void)
}
}
-/* Continuous Interaction */
-
-static int CONTINUE_PHYSICS = 0;
-
-void BKE_ptcache_set_continue_physics(Main *bmain, Scene *scene, int enable)
-{
- Object *ob;
-
- if (CONTINUE_PHYSICS != enable) {
- CONTINUE_PHYSICS = enable;
-
- if (CONTINUE_PHYSICS == 0) {
- for (ob=bmain->object.first; ob; ob=ob->id.next)
- if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- }
- }
-}
-
-int BKE_ptcache_get_continue_physics(void)
-{
- return CONTINUE_PHYSICS;
-}
-
/* Point Cache handling */
PointCache *BKE_ptcache_add(ListBase *ptcaches)
@@ -2782,7 +2902,8 @@ static PointCache *ptcache_copy(PointCache *cache, int copy_data)
ncache->mem_cache.last = NULL;
ncache->cached_frames = NULL;
- ncache->flag= 0;
+ /* flag is a mix of user settings and simulator/baking state */
+ ncache->flag= ncache->flag & (PTCACHE_DISK_CACHE|PTCACHE_EXTERNAL|PTCACHE_IGNORE_LIBPATH);
ncache->simframe= 0;
}
else {
@@ -3386,11 +3507,11 @@ void BKE_ptcache_update_info(PTCacheID *pid)
/* smoke doesn't use frame 0 as info frame so can't check based on totpoint */
if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN && totframes)
- BLI_snprintf(cache->info, sizeof(cache->info), "%i frames found!", totframes);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%i frames found!"), totframes);
else if (totframes && cache->totpoint)
- BLI_snprintf(cache->info, sizeof(cache->info), "%i points found!", cache->totpoint);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%i points found!"), cache->totpoint);
else
- BLI_snprintf(cache->info, sizeof(cache->info), "No valid data to read!");
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("No valid data to read!"));
return;
}
@@ -3399,9 +3520,9 @@ void BKE_ptcache_update_info(PTCacheID *pid)
int totpoint = pid->totpoint(pid->calldata, 0);
if (cache->totpoint > totpoint)
- BLI_snprintf(mem_info, sizeof(mem_info), "%i cells + High Resolution cached", totpoint);
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i cells + High Resolution cached"), totpoint);
else
- BLI_snprintf(mem_info, sizeof(mem_info), "%i cells cached", totpoint);
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i cells cached"), totpoint);
}
else {
int cfra = cache->startframe;
@@ -3411,7 +3532,7 @@ void BKE_ptcache_update_info(PTCacheID *pid)
totframes++;
}
- BLI_snprintf(mem_info, sizeof(mem_info), "%i frames on disk", totframes);
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i frames on disk"), totframes);
}
}
else {
@@ -3435,17 +3556,18 @@ void BKE_ptcache_update_info(PTCacheID *pid)
mb = (bytes > 1024.0f * 1024.0f);
- BLI_snprintf(mem_info, sizeof(mem_info), "%i frames in memory (%.1f %s)",
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i frames in memory (%.1f %s)"),
totframes,
bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
- mb ? "Mb" : "kb");
+ mb ? IFACE_("Mb") : IFACE_("kb"));
}
if (cache->flag & PTCACHE_OUTDATED) {
- BLI_snprintf(cache->info, sizeof(cache->info), "%s, cache is outdated!", mem_info);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%s, cache is outdated!"), mem_info);
}
else if (cache->flag & PTCACHE_FRAMES_SKIPPED) {
- BLI_snprintf(cache->info, sizeof(cache->info), "%s, not exact since frame %i.", mem_info, cache->last_exact);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%s, not exact since frame %i."),
+ mem_info, cache->last_exact);
}
else {
BLI_snprintf(cache->info, sizeof(cache->info), "%s.", mem_info);
@@ -3467,4 +3589,3 @@ void BKE_ptcache_invalidate(PointCache *cache)
cache->last_exact = MIN2(cache->startframe, 0);
}
}
-
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index 8da4f11fed3..c4658712ecb 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -287,7 +287,7 @@ void BKE_bproperty_add(bProperty *prop, const char *str)
}
/* reads value of property, sets it in chars in str */
-void BKE_bproperty_set_valstr(bProperty *prop, char *str)
+void BKE_bproperty_set_valstr(bProperty *prop, char str[MAX_PROPSTRING])
{
// extern int Gdfra; /* sector.c */
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index d925d736358..1fd7dc14c23 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -27,6 +27,10 @@
* \ingroup bke
*/
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
#include "MEM_guardedalloc.h"
@@ -39,10 +43,6 @@
#include "BKE_report.h"
#include "BKE_global.h" /* G.background only */
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
static const char *report_type_str(int type)
{
switch (type) {
@@ -52,6 +52,8 @@ static const char *report_type_str(int type)
return TIP_("Info");
case RPT_OPERATOR:
return TIP_("Operator");
+ case RPT_PROPERTY:
+ return TIP_("Property");
case RPT_WARNING:
return TIP_("Warning");
case RPT_ERROR:
@@ -300,3 +302,36 @@ int BKE_reports_contain(ReportList *reports, ReportType level)
return FALSE;
}
+bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
+{
+ Report *report;
+
+ if (header) {
+ fputs(header, fp);
+ }
+
+ for (report = reports->list.first; report; report = report->next) {
+ fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr);
+ }
+
+ return true;
+}
+
+bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
+{
+ FILE *fp;
+
+ errno = 0;
+ fp = BLI_fopen(filepath, "wb");
+ if (fp == NULL) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ filepath, errno ? strerror(errno) : "Unknown error opening file");
+ return false;
+ }
+
+ BKE_report_write_file_fp(fp, reports, header);
+
+ fclose(fp);
+
+ return true;
+}
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
new file mode 100644
index 00000000000..4c6bae122cd
--- /dev/null
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -0,0 +1,1335 @@
+/*
+ * ***** 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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file rigidbody.c
+ * \ingroup blenkernel
+ * \brief Blender-side interface and methods for dealing with Rigid Body simulations
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <float.h>
+#include <math.h>
+#include <limits.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+
+#ifdef WITH_BULLET
+# include "RBI_api.h"
+#endif
+
+#include "DNA_anim_types.h"
+#include "DNA_group_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_rigidbody_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_animsys.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_effect.h"
+#include "BKE_group.h"
+#include "BKE_object.h"
+#include "BKE_mesh.h"
+#include "BKE_pointcache.h"
+#include "BKE_rigidbody.h"
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+
+#ifdef WITH_BULLET
+
+/* ************************************** */
+/* Memory Management */
+
+/* Freeing Methods --------------------- */
+
+/* Free rigidbody world */
+void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
+{
+ /* sanity check */
+ if (!rbw)
+ return;
+
+ if (rbw->physics_world) {
+ /* free physics references, we assume that all physics objects in will have been added to the world */
+ GroupObject *go;
+ if (rbw->constraints) {
+ for (go = rbw->constraints->gobject.first; go; go = go->next) {
+ if (go->ob && go->ob->rigidbody_constraint) {
+ RigidBodyCon *rbc = go->ob->rigidbody_constraint;
+
+ if (rbc->physics_constraint)
+ RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ }
+ }
+ }
+ if (rbw->group) {
+ for (go = rbw->group->gobject.first; go; go = go->next) {
+ if (go->ob && go->ob->rigidbody_object) {
+ RigidBodyOb *rbo = go->ob->rigidbody_object;
+
+ if (rbo->physics_object)
+ RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
+ }
+ }
+ }
+ /* free dynamics world */
+ RB_dworld_delete(rbw->physics_world);
+ }
+ if (rbw->objects)
+ free(rbw->objects);
+
+ /* free cache */
+ BKE_ptcache_free_list(&(rbw->ptcaches));
+ rbw->pointcache = NULL;
+
+ /* free effector weights */
+ if (rbw->effector_weights)
+ MEM_freeN(rbw->effector_weights);
+
+ /* free rigidbody world itself */
+ MEM_freeN(rbw);
+}
+
+/* Free RigidBody settings and sim instances */
+void BKE_rigidbody_free_object(Object *ob)
+{
+ RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
+
+ /* sanity check */
+ if (rbo == NULL)
+ return;
+
+ /* free physics references */
+ if (rbo->physics_object) {
+ RB_body_delete(rbo->physics_object);
+ rbo->physics_object = NULL;
+ }
+
+ if (rbo->physics_shape) {
+ RB_shape_delete(rbo->physics_shape);
+ rbo->physics_shape = NULL;
+ }
+
+ /* free data itself */
+ MEM_freeN(rbo);
+ ob->rigidbody_object = NULL;
+}
+
+/* Free RigidBody constraint and sim instance */
+void BKE_rigidbody_free_constraint(Object *ob)
+{
+ RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
+
+ /* sanity check */
+ if (rbc == NULL)
+ return;
+
+ /* free physics reference */
+ if (rbc->physics_constraint) {
+ RB_constraint_delete(rbc->physics_constraint);
+ rbc->physics_constraint = NULL;
+ }
+
+ /* free data itself */
+ MEM_freeN(rbc);
+ ob->rigidbody_constraint = NULL;
+}
+
+/* Copying Methods --------------------- */
+
+/* These just copy the data, clearing out references to physics objects.
+ * Anything that uses them MUST verify that the copied object will
+ * be added to relevant groups later...
+ */
+
+RigidBodyOb *BKE_rigidbody_copy_object(Object *ob)
+{
+ RigidBodyOb *rboN = NULL;
+
+ if (ob->rigidbody_object) {
+ /* just duplicate the whole struct first (to catch all the settings) */
+ rboN = MEM_dupallocN(ob->rigidbody_object);
+
+ /* tag object as needing to be verified */
+ rboN->flag |= RBO_FLAG_NEEDS_VALIDATE;
+
+ /* clear out all the fields which need to be revalidated later */
+ rboN->physics_object = NULL;
+ rboN->physics_shape = NULL;
+ }
+
+ /* return new copy of settings */
+ return rboN;
+}
+
+RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob)
+{
+ RigidBodyCon *rbcN = NULL;
+
+ if (ob->rigidbody_constraint) {
+ /* just duplicate the whole struct first (to catch all the settings) */
+ rbcN = MEM_dupallocN(ob->rigidbody_constraint);
+
+ /* tag object as needing to be verified */
+ rbcN->flag |= RBC_FLAG_NEEDS_VALIDATE;
+
+ /* clear out all the fields which need to be revalidated later */
+ rbcN->physics_constraint = NULL;
+ }
+
+ /* return new copy of settings */
+ return rbcN;
+}
+
+/* preserve relationships between constraints and rigid bodies after duplication */
+void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc)
+{
+ ID_NEW(rbc->ob1);
+ ID_NEW(rbc->ob2);
+}
+
+/* ************************************** */
+/* Setup Utilities - Validate Sim Instances */
+
+/* create collision shape of mesh - convex hull */
+static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, float margin, bool *can_embed)
+{
+ rbCollisionShape *shape = NULL;
+ Mesh *me = NULL;
+
+ if (ob->type == OB_MESH && ob->data) {
+ me = ob->data;
+ }
+ else {
+ printf("ERROR: cannot make Convex Hull collision shape for non-Mesh object\n");
+ }
+
+ if (me && me->totvert) {
+ shape = RB_shape_new_convex_hull((float *)me->mvert, sizeof(MVert), me->totvert, margin, can_embed);
+ }
+ else {
+ printf("ERROR: no vertices to define Convex Hull collision shape with\n");
+ }
+
+ return shape;
+}
+
+/* create collision shape of mesh - triangulated mesh
+ * returns NULL if creation fails.
+ */
+static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
+{
+ rbCollisionShape *shape = NULL;
+
+ if (ob->type == OB_MESH) {
+ DerivedMesh *dm = CDDM_from_mesh(ob->data, ob);
+
+ MVert *mvert;
+ MFace *mface;
+ int totvert;
+ int totface;
+
+ /* ensure mesh validity, then grab data */
+ DM_ensure_tessface(dm);
+
+ mvert = (dm) ? dm->getVertArray(dm) : NULL;
+ totvert = (dm) ? dm->getNumVerts(dm) : 0;
+ mface = (dm) ? dm->getTessFaceArray(dm) : NULL;
+ totface = (dm) ? dm->getNumTessFaces(dm) : 0;
+
+ /* sanity checking - potential case when no data will be present */
+ if ((totvert == 0) || (totface == 0)) {
+ printf("WARNING: no geometry data converted for Mesh Collision Shape (ob = %s)\n", ob->id.name + 2);
+ }
+ else {
+ rbMeshData *mdata;
+ int i;
+
+ /* init mesh data for collision shape */
+ mdata = RB_trimesh_data_new();
+
+ /* loop over all faces, adding them as triangles to the collision shape
+ * (so for some faces, more than triangle will get added)
+ */
+ for (i = 0; (i < totface) && (mface) && (mvert); i++, mface++) {
+ /* add first triangle - verts 1,2,3 */
+ {
+ MVert *va = (IN_RANGE(mface->v1, 0, totvert)) ? (mvert + mface->v1) : (mvert);
+ MVert *vb = (IN_RANGE(mface->v2, 0, totvert)) ? (mvert + mface->v2) : (mvert);
+ MVert *vc = (IN_RANGE(mface->v3, 0, totvert)) ? (mvert + mface->v3) : (mvert);
+
+ RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co);
+ }
+
+ /* add second triangle if needed - verts 1,3,4 */
+ if (mface->v4) {
+ MVert *va = (IN_RANGE(mface->v1, 0, totvert)) ? (mvert + mface->v1) : (mvert);
+ MVert *vb = (IN_RANGE(mface->v3, 0, totvert)) ? (mvert + mface->v3) : (mvert);
+ MVert *vc = (IN_RANGE(mface->v4, 0, totvert)) ? (mvert + mface->v4) : (mvert);
+
+ RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co);
+ }
+ }
+
+ /* construct collision shape
+ *
+ * These have been chosen to get better speed/accuracy tradeoffs with regards
+ * to limitations of each:
+ * - BVH-Triangle Mesh: for passive objects only. Despite having greater
+ * speed/accuracy, they cannot be used for moving objects.
+ * - GImpact Mesh: for active objects. These are slower and less stable,
+ * but are more flexible for general usage.
+ */
+ if (ob->rigidbody_object->type == RBO_TYPE_PASSIVE) {
+ shape = RB_shape_new_trimesh(mdata);
+ }
+ else {
+ shape = RB_shape_new_gimpact_mesh(mdata);
+ }
+ }
+
+ /* cleanup temp data */
+ if (dm) {
+ dm->release(dm);
+ }
+ }
+ else {
+ printf("ERROR: cannot make Triangular Mesh collision shape for non-Mesh object\n");
+ }
+
+ return shape;
+}
+
+/* Create new physics sim collision shape for object and store it,
+ * or remove the existing one first and replace...
+ */
+void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ rbCollisionShape *new_shape = NULL;
+ BoundBox *bb = NULL;
+ float size[3] = {1.0f, 1.0f, 1.0f};
+ float radius = 1.0f;
+ float height = 1.0f;
+ float capsule_height;
+ float hull_margin = 0.0f;
+ bool can_embed = true;
+
+ /* sanity check */
+ if (rbo == NULL)
+ return;
+
+ /* don't create a new shape if we already have one and don't want to rebuild it */
+ if (rbo->physics_shape && !rebuild)
+ return;
+
+ /* if automatically determining dimensions, use the Object's boundbox
+ * - assume that all quadrics are standing upright on local z-axis
+ * - assume even distribution of mass around the Object's pivot
+ * (i.e. Object pivot is centralized in boundbox)
+ */
+ // XXX: all dimensions are auto-determined now... later can add stored settings for this
+ /* get object dimensions without scaling */
+ bb = BKE_object_boundbox_get(ob);
+ if (bb) {
+ size[0] = (bb->vec[4][0] - bb->vec[0][0]);
+ size[1] = (bb->vec[2][1] - bb->vec[0][1]);
+ size[2] = (bb->vec[1][2] - bb->vec[0][2]);
+ }
+ mul_v3_fl(size, 0.5f);
+
+ if (ELEM3(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
+ /* take radius as largest x/y dimension, and height as z-dimension */
+ radius = MAX2(size[0], size[1]);
+ height = size[2];
+ }
+ else if (rbo->shape == RB_SHAPE_SPHERE) {
+ /* take radius to the the largest dimension to try and encompass everything */
+ radius = MAX3(size[0], size[1], size[2]);
+ }
+
+ /* create new shape */
+ switch (rbo->shape) {
+ case RB_SHAPE_BOX:
+ new_shape = RB_shape_new_box(size[0], size[1], size[2]);
+ break;
+
+ case RB_SHAPE_SPHERE:
+ new_shape = RB_shape_new_sphere(radius);
+ break;
+
+ case RB_SHAPE_CAPSULE:
+ capsule_height = (height - radius) * 2.0f;
+ new_shape = RB_shape_new_capsule(radius, (capsule_height > 0.0f) ? capsule_height : 0.0f);
+ break;
+ case RB_SHAPE_CYLINDER:
+ new_shape = RB_shape_new_cylinder(radius, height);
+ break;
+ case RB_SHAPE_CONE:
+ new_shape = RB_shape_new_cone(radius, height * 2.0f);
+ break;
+
+ case RB_SHAPE_CONVEXH:
+ /* try to emged collision margin */
+ if (!(rbo->flag & RBO_FLAG_USE_MARGIN))
+ hull_margin = 0.04f;
+ new_shape = rigidbody_get_shape_convexhull_from_mesh(ob, hull_margin, &can_embed);
+ if (!(rbo->flag & RBO_FLAG_USE_MARGIN))
+ rbo->margin = (can_embed) ? 0.04f : 0.0f; /* RB_TODO ideally we shouldn't directly change the margin here */
+ break;
+ case RB_SHAPE_TRIMESH:
+ new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
+ break;
+ }
+ /* assign new collision shape if creation was successful */
+ if (new_shape) {
+ if (rbo->physics_shape)
+ RB_shape_delete(rbo->physics_shape);
+ rbo->physics_shape = new_shape;
+ RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo));
+ }
+ else { /* otherwise fall back to box shape */
+ rbo->shape = RB_SHAPE_BOX;
+ BKE_rigidbody_validate_sim_shape(ob, true);
+ }
+}
+
+/* --------------------- */
+
+/* Create physics sim representation of object given RigidBody settings
+ * < rebuild: even if an instance already exists, replace it
+ */
+void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short rebuild)
+{
+ RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
+ float loc[3];
+ float rot[4];
+
+ /* sanity checks:
+ * - object doesn't have RigidBody info already: then why is it here?
+ */
+ if (rbo == NULL)
+ return;
+
+ /* make sure collision shape exists */
+ /* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, but it's needed for constraints to update correctly */
+ if (rbo->physics_shape == NULL || rebuild)
+ BKE_rigidbody_validate_sim_shape(ob, true);
+
+ if (rbo->physics_object) {
+ if (rebuild == false)
+ RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
+ }
+ if (!rbo->physics_object || rebuild) {
+ /* remove rigid body if it already exists before creating a new one */
+ if (rbo->physics_object) {
+ RB_body_delete(rbo->physics_object);
+ }
+
+ mat4_to_loc_quat(loc, rot, ob->obmat);
+
+ rbo->physics_object = RB_body_new(rbo->physics_shape, loc, rot);
+
+ RB_body_set_friction(rbo->physics_object, rbo->friction);
+ RB_body_set_restitution(rbo->physics_object, rbo->restitution);
+
+ RB_body_set_damping(rbo->physics_object, rbo->lin_damping, rbo->ang_damping);
+ RB_body_set_sleep_thresh(rbo->physics_object, rbo->lin_sleep_thresh, rbo->ang_sleep_thresh);
+ RB_body_set_activation_state(rbo->physics_object, rbo->flag & RBO_FLAG_USE_DEACTIVATION);
+
+ if (rbo->type == RBO_TYPE_PASSIVE || rbo->flag & RBO_FLAG_START_DEACTIVATED)
+ RB_body_deactivate(rbo->physics_object);
+
+
+ RB_body_set_linear_factor(rbo->physics_object,
+ (ob->protectflag & OB_LOCK_LOCX) == 0,
+ (ob->protectflag & OB_LOCK_LOCY) == 0,
+ (ob->protectflag & OB_LOCK_LOCZ) == 0);
+ RB_body_set_angular_factor(rbo->physics_object,
+ (ob->protectflag & OB_LOCK_ROTX) == 0,
+ (ob->protectflag & OB_LOCK_ROTY) == 0,
+ (ob->protectflag & OB_LOCK_ROTZ) == 0);
+
+ RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+ }
+
+ if (rbw && rbw->physics_world)
+ RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups);
+}
+
+/* --------------------- */
+
+/* Create physics sim representation of constraint given rigid body constraint settings
+ * < rebuild: even if an instance already exists, replace it
+ */
+void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, short rebuild)
+{
+ RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
+ float loc[3];
+ float rot[4];
+ float lin_lower;
+ float lin_upper;
+ float ang_lower;
+ float ang_upper;
+
+ /* sanity checks:
+ * - object should have a rigid body constraint
+ * - rigid body constraint should have at least one constrained object
+ */
+ if (rbc == NULL) {
+ return;
+ }
+
+ if (ELEM4(NULL, rbc->ob1, rbc->ob1->rigidbody_object, rbc->ob2, rbc->ob2->rigidbody_object)) {
+ if (rbc->physics_constraint) {
+ RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ RB_constraint_delete(rbc->physics_constraint);
+ rbc->physics_constraint = NULL;
+ }
+ return;
+ }
+
+ if (rbc->physics_constraint) {
+ if (rebuild == false)
+ RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ }
+ if (rbc->physics_constraint == NULL || rebuild) {
+ rbRigidBody *rb1 = rbc->ob1->rigidbody_object->physics_object;
+ rbRigidBody *rb2 = rbc->ob2->rigidbody_object->physics_object;
+
+ /* remove constraint if it already exists before creating a new one */
+ if (rbc->physics_constraint) {
+ RB_constraint_delete(rbc->physics_constraint);
+ rbc->physics_constraint = NULL;
+ }
+
+ mat4_to_loc_quat(loc, rot, ob->obmat);
+
+ if (rb1 && rb2) {
+ switch (rbc->type) {
+ case RBC_TYPE_POINT:
+ rbc->physics_constraint = RB_constraint_new_point(loc, rb1, rb2);
+ break;
+ case RBC_TYPE_FIXED:
+ rbc->physics_constraint = RB_constraint_new_fixed(loc, rot, rb1, rb2);
+ break;
+ case RBC_TYPE_HINGE:
+ rbc->physics_constraint = RB_constraint_new_hinge(loc, rot, rb1, rb2);
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z) {
+ RB_constraint_set_limits_hinge(rbc->physics_constraint, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
+ }
+ else
+ RB_constraint_set_limits_hinge(rbc->physics_constraint, 0.0f, -1.0f);
+ break;
+ case RBC_TYPE_SLIDER:
+ rbc->physics_constraint = RB_constraint_new_slider(loc, rot, rb1, rb2);
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
+ RB_constraint_set_limits_slider(rbc->physics_constraint, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
+ else
+ RB_constraint_set_limits_slider(rbc->physics_constraint, 0.0f, -1.0f);
+ break;
+ case RBC_TYPE_PISTON:
+ rbc->physics_constraint = RB_constraint_new_piston(loc, rot, rb1, rb2);
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) {
+ lin_lower = rbc->limit_lin_x_lower;
+ lin_upper = rbc->limit_lin_x_upper;
+ }
+ else {
+ lin_lower = 0.0f;
+ lin_upper = -1.0f;
+ }
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X) {
+ ang_lower = rbc->limit_ang_x_lower;
+ ang_upper = rbc->limit_ang_x_upper;
+ }
+ else {
+ ang_lower = 0.0f;
+ ang_upper = -1.0f;
+ }
+ RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
+ break;
+ case RBC_TYPE_6DOF_SPRING:
+ rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
+
+ RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
+ RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
+ RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
+
+ RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
+ RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
+ RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
+
+ RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
+ RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
+ RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
+
+ RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
+ /* fall through */
+ case RBC_TYPE_6DOF:
+ if (rbc->type == RBC_TYPE_6DOF) /* a litte awkward but avoids duplicate code for limits */
+ rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
+ else
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_X, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Y)
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->limit_lin_y_lower, rbc->limit_lin_y_upper);
+ else
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Y, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Z)
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->limit_lin_z_lower, rbc->limit_lin_z_upper);
+ else
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_LIN_Z, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X)
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->limit_ang_x_lower, rbc->limit_ang_x_upper);
+ else
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_X, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Y)
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->limit_ang_y_lower, rbc->limit_ang_y_upper);
+ else
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Y, 0.0f, -1.0f);
+
+ if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z)
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
+ else
+ RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
+ break;
+ case RBC_TYPE_MOTOR:
+ rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
+
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
+ RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
+ break;
+ }
+ }
+ else { /* can't create constraint without both rigid bodies */
+ return;
+ }
+
+ RB_constraint_set_enabled(rbc->physics_constraint, rbc->flag & RBC_FLAG_ENABLED);
+
+ if (rbc->flag & RBC_FLAG_USE_BREAKING)
+ RB_constraint_set_breaking_threshold(rbc->physics_constraint, rbc->breaking_threshold);
+ else
+ RB_constraint_set_breaking_threshold(rbc->physics_constraint, FLT_MAX);
+
+ if (rbc->flag & RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS)
+ RB_constraint_set_solver_iterations(rbc->physics_constraint, rbc->num_solver_iterations);
+ else
+ RB_constraint_set_solver_iterations(rbc->physics_constraint, -1);
+ }
+
+ if (rbw && rbw->physics_world && rbc->physics_constraint) {
+ RB_dworld_add_constraint(rbw->physics_world, rbc->physics_constraint, rbc->flag & RBC_FLAG_DISABLE_COLLISIONS);
+ }
+}
+
+/* --------------------- */
+
+/* Create physics sim world given RigidBody world settings */
+// NOTE: this does NOT update object references that the scene uses, in case those aren't ready yet!
+void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, short rebuild)
+{
+ /* sanity checks */
+ if (rbw == NULL)
+ return;
+
+ /* create new sim world */
+ if (rebuild || rbw->physics_world == NULL) {
+ if (rbw->physics_world)
+ RB_dworld_delete(rbw->physics_world);
+ rbw->physics_world = RB_dworld_new(scene->physics_settings.gravity);
+ }
+
+ RB_dworld_set_solver_iterations(rbw->physics_world, rbw->num_solver_iterations);
+ RB_dworld_set_split_impulse(rbw->physics_world, rbw->flag & RBW_FLAG_USE_SPLIT_IMPULSE);
+}
+
+/* ************************************** */
+/* Setup Utilities - Create Settings Blocks */
+
+/* Set up RigidBody world */
+RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
+{
+ /* try to get whatever RigidBody world that might be representing this already */
+ RigidBodyWorld *rbw;
+
+ /* sanity checks
+ * - there must be a valid scene to add world to
+ * - there mustn't be a sim world using this group already
+ */
+ if (scene == NULL)
+ return NULL;
+
+ /* create a new sim world */
+ rbw = MEM_callocN(sizeof(RigidBodyWorld), "RigidBodyWorld");
+
+ /* set default settings */
+ rbw->effector_weights = BKE_add_effector_weights(NULL);
+
+ rbw->ltime = PSFRA;
+
+ rbw->time_scale = 1.0f;
+
+ rbw->steps_per_second = 60; /* Bullet default (60 Hz) */
+ rbw->num_solver_iterations = 10; /* 10 is bullet default */
+
+ rbw->pointcache = BKE_ptcache_add(&(rbw->ptcaches));
+ rbw->pointcache->step = 1;
+
+ /* return this sim world */
+ return rbw;
+}
+
+/* Add rigid body settings to the specified object */
+RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
+{
+ RigidBodyOb *rbo;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+
+ /* sanity checks
+ * - rigidbody world must exist
+ * - object must exist
+ * - cannot add rigid body if it already exists
+ */
+ if (ob == NULL || (ob->rigidbody_object != NULL))
+ return NULL;
+
+ /* create new settings data, and link it up */
+ rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
+
+ /* set default settings */
+ rbo->type = type;
+
+ rbo->mass = 1.0f;
+
+ rbo->friction = 0.5f; /* best when non-zero. 0.5 is Bullet default */
+ rbo->restitution = 0.0f; /* best when zero. 0.0 is Bullet default */
+
+ rbo->margin = 0.04f; /* 0.04 (in meters) is Bullet default */
+
+ rbo->lin_sleep_thresh = 0.4f; /* 0.4 is half of Bullet default */
+ rbo->ang_sleep_thresh = 0.5f; /* 0.5 is half of Bullet default */
+
+ rbo->lin_damping = 0.04f; /* 0.04 is game engine default */
+ rbo->ang_damping = 0.1f; /* 0.1 is game engine default */
+
+ rbo->col_groups = 1;
+
+ /* use triangle meshes for passive objects
+ * use convex hulls for active objects since dynamic triangle meshes are very unstable
+ */
+ if (type == RBO_TYPE_ACTIVE)
+ rbo->shape = RB_SHAPE_CONVEXH;
+ else
+ rbo->shape = RB_SHAPE_TRIMESH;
+
+ /* set initial transform */
+ mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
+
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
+
+ /* return this object */
+ return rbo;
+}
+
+/* Add rigid body constraint to the specified object */
+RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
+{
+ RigidBodyCon *rbc;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+
+ /* sanity checks
+ * - rigidbody world must exist
+ * - object must exist
+ * - cannot add constraint if it already exists
+ */
+ if (ob == NULL || (ob->rigidbody_constraint != NULL))
+ return NULL;
+
+ /* create new settings data, and link it up */
+ rbc = MEM_callocN(sizeof(RigidBodyCon), "RigidBodyCon");
+
+ /* set default settings */
+ rbc->type = type;
+
+ rbc->ob1 = NULL;
+ rbc->ob2 = NULL;
+
+ rbc->flag |= RBC_FLAG_ENABLED;
+ rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS;
+
+ rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */
+ rbc->num_solver_iterations = 10; /* 10 is Bullet default */
+
+ rbc->limit_lin_x_lower = -1.0f;
+ rbc->limit_lin_x_upper = 1.0f;
+ rbc->limit_lin_y_lower = -1.0f;
+ rbc->limit_lin_y_upper = 1.0f;
+ rbc->limit_lin_z_lower = -1.0f;
+ rbc->limit_lin_z_upper = 1.0f;
+ rbc->limit_ang_x_lower = -M_PI_4;
+ rbc->limit_ang_x_upper = M_PI_4;
+ rbc->limit_ang_y_lower = -M_PI_4;
+ rbc->limit_ang_y_upper = M_PI_4;
+ rbc->limit_ang_z_lower = -M_PI_4;
+ rbc->limit_ang_z_upper = M_PI_4;
+
+ rbc->spring_damping_x = 0.5f;
+ rbc->spring_damping_y = 0.5f;
+ rbc->spring_damping_z = 0.5f;
+ rbc->spring_stiffness_x = 10.0f;
+ rbc->spring_stiffness_y = 10.0f;
+ rbc->spring_stiffness_z = 10.0f;
+
+ rbc->motor_lin_max_impulse = 1.0f;
+ rbc->motor_lin_target_velocity = 1.0f;
+ rbc->motor_ang_max_impulse = 1.0f;
+ rbc->motor_ang_target_velocity = 1.0f;
+
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
+
+ /* return this object */
+ return rbc;
+}
+
+/* ************************************** */
+/* Utilities API */
+
+/* Get RigidBody world for the given scene, creating one if needed
+ * < scene: Scene to find active Rigid Body world for
+ */
+RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
+{
+ /* sanity check */
+ if (scene == NULL)
+ return NULL;
+
+ return scene->rigidbody_world;
+}
+
+void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
+{
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ RigidBodyCon *rbc;
+ GroupObject *go;
+ int i;
+
+ if (rbw) {
+ /* remove from rigidbody world, free object won't do this */
+ if (rbw->physics_world && rbo->physics_object)
+ RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
+
+ /* remove object from array */
+ if (rbw && rbw->objects) {
+ for (i = 0; i < rbw->numbodies; i++) {
+ if (rbw->objects[i] == ob) {
+ rbw->objects[i] = NULL;
+ break;
+ }
+ }
+ }
+
+ /* remove object from rigid body constraints */
+ if (rbw->constraints) {
+ for (go = rbw->constraints->gobject.first; go; go = go->next) {
+ Object *obt = go->ob;
+ if (obt && obt->rigidbody_constraint) {
+ rbc = obt->rigidbody_constraint;
+ if (rbc->ob1 == ob) {
+ rbc->ob1 = NULL;
+ rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
+ }
+ if (rbc->ob2 == ob) {
+ rbc->ob2 = NULL;
+ rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
+ }
+ }
+ }
+ }
+ }
+
+ /* remove object's settings */
+ BKE_rigidbody_free_object(ob);
+
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
+}
+
+void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
+{
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ RigidBodyCon *rbc = ob->rigidbody_constraint;
+
+ if (rbw) {
+ /* remove from rigidbody world, free object won't do this */
+ if (rbw && rbw->physics_world && rbc->physics_constraint)
+ RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ }
+ /* remove object's settings */
+ BKE_rigidbody_free_constraint(ob);
+
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
+}
+
+
+/* ************************************** */
+/* Simulation Interface - Bullet */
+
+/* Update object array and rigid body count so they're in sync with the rigid body group */
+static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
+{
+ GroupObject *go;
+ int i, n;
+
+ n = BLI_countlist(&rbw->group->gobject);
+
+ if (rbw->numbodies != n) {
+ rbw->numbodies = n;
+ rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies);
+ }
+
+ for (go = rbw->group->gobject.first, i = 0; go; go = go->next, i++) {
+ Object *ob = go->ob;
+ rbw->objects[i] = ob;
+ }
+}
+
+static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
+{
+ float adj_gravity[3];
+
+ /* adjust gravity to take effector weights into account */
+ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+ copy_v3_v3(adj_gravity, scene->physics_settings.gravity);
+ mul_v3_fl(adj_gravity, rbw->effector_weights->global_gravity * rbw->effector_weights->weight[0]);
+ }
+ else {
+ zero_v3(adj_gravity);
+ }
+
+ /* update gravity, since this RNA setting is not part of RigidBody settings */
+ RB_dworld_set_gravity(rbw->physics_world, adj_gravity);
+
+ /* update object array in case there are changes */
+ rigidbody_update_ob_array(rbw);
+}
+
+static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
+{
+ float loc[3];
+ float rot[4];
+ float scale[3];
+
+ /* only update if rigid body exists */
+ if (rbo->physics_object == NULL)
+ return;
+
+ mat4_decompose(loc, rot, scale, ob->obmat);
+
+ /* update scale for all objects */
+ RB_body_set_scale(rbo->physics_object, scale);
+ /* compensate for embedded convex hull collision margin */
+ if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH)
+ RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2]));
+
+ /* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */
+ if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
+ RB_body_set_kinematic_state(rbo->physics_object, TRUE);
+ RB_body_set_mass(rbo->physics_object, 0.0f);
+ }
+
+ /* update rigid body location and rotation for kinematic bodies */
+ if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
+ RB_body_activate(rbo->physics_object);
+ RB_body_set_loc_rot(rbo->physics_object, loc, rot);
+ }
+ /* update influence of effectors - but don't do it on an effector */
+ /* only dynamic bodies need effector update */
+ else if (rbo->type == RBO_TYPE_ACTIVE && ((ob->pd == NULL) || (ob->pd->forcefield == PFIELD_NULL))) {
+ EffectorWeights *effector_weights = rbw->effector_weights;
+ EffectedPoint epoint;
+ ListBase *effectors;
+
+ /* get effectors present in the group specified by effector_weights */
+ effectors = pdInitEffectors(scene, ob, NULL, effector_weights);
+ if (effectors) {
+ float force[3] = {0.0f, 0.0f, 0.0f};
+ float loc[3], vel[3];
+
+ /* create dummy 'point' which represents last known position of object as result of sim */
+ // XXX: this can create some inaccuracies with sim position, but is probably better than using unsimulated vals?
+ RB_body_get_position(rbo->physics_object, loc);
+ RB_body_get_linear_velocity(rbo->physics_object, vel);
+
+ pd_point_from_loc(scene, loc, vel, 0, &epoint);
+
+ /* calculate net force of effectors, and apply to sim object
+ * - we use 'central force' since apply force requires a "relative position" which we don't have...
+ */
+ pdDoEffectors(effectors, NULL, effector_weights, &epoint, force, NULL);
+ if (G.f & G_DEBUG)
+ printf("\tapplying force (%f,%f,%f) to '%s'\n", force[0], force[1], force[2], ob->id.name + 2);
+ /* activate object in case it is deactivated */
+ if (!is_zero_v3(force))
+ RB_body_activate(rbo->physics_object);
+ RB_body_apply_central_force(rbo->physics_object, force);
+ }
+ else if (G.f & G_DEBUG)
+ printf("\tno forces to apply to '%s'\n", ob->id.name + 2);
+
+ /* cleanup */
+ pdEndEffectors(&effectors);
+ }
+ /* NOTE: passive objects don't need to be updated since they don't move */
+
+ /* NOTE: no other settings need to be explicitly updated here,
+ * since RNA setters take care of the rest :)
+ */
+}
+
+/* Updates and validates world, bodies and shapes.
+ * < rebuild: rebuild entire simulation
+ */
+static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, int rebuild)
+{
+ GroupObject *go;
+
+ /* update world */
+ if (rebuild)
+ BKE_rigidbody_validate_sim_world(scene, rbw, true);
+ rigidbody_update_sim_world(scene, rbw);
+
+ /* update objects */
+ for (go = rbw->group->gobject.first; go; go = go->next) {
+ Object *ob = go->ob;
+
+ if (ob && ob->type == OB_MESH) {
+ /* validate that we've got valid object set up here... */
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
+ BKE_object_where_is_calc(scene, ob);
+
+ if (rbo == NULL) {
+ /* Since this object is included in the sim group but doesn't have
+ * rigid body settings (perhaps it was added manually), add!
+ * - assume object to be active? That is the default for newly added settings...
+ */
+ ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE);
+ BKE_rigidbody_validate_sim_object(rbw, ob, true);
+
+ rbo = ob->rigidbody_object;
+ }
+ else {
+ /* perform simulation data updates as tagged */
+ /* refresh object... */
+ if (rebuild) {
+ /* World has been rebuilt so rebuild object */
+ BKE_rigidbody_validate_sim_object(rbw, ob, true);
+ }
+ else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) {
+ BKE_rigidbody_validate_sim_object(rbw, ob, false);
+ }
+ /* refresh shape... */
+ if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
+ /* mesh/shape data changed, so force shape refresh */
+ BKE_rigidbody_validate_sim_shape(ob, true);
+ /* now tell RB sim about it */
+ // XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies
+ RB_body_set_collision_shape(rbo->physics_object, rbo->physics_shape);
+ }
+ rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
+ }
+
+ /* update simulation object... */
+ rigidbody_update_sim_ob(scene, rbw, ob, rbo);
+ }
+ }
+ /* update constraints */
+ if (rbw->constraints == NULL) /* no constraints, move on */
+ return;
+ for (go = rbw->constraints->gobject.first; go; go = go->next) {
+ Object *ob = go->ob;
+
+ if (ob) {
+ /* validate that we've got valid object set up here... */
+ RigidBodyCon *rbc = ob->rigidbody_constraint;
+ /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
+ BKE_object_where_is_calc(scene, ob);
+
+ if (rbc == NULL) {
+ /* Since this object is included in the group but doesn't have
+ * constraint settings (perhaps it was added manually), add!
+ */
+ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
+ BKE_rigidbody_validate_sim_constraint(rbw, ob, true);
+
+ rbc = ob->rigidbody_constraint;
+ }
+ else {
+ /* perform simulation data updates as tagged */
+ if (rebuild) {
+ /* World has been rebuilt so rebuild constraint */
+ BKE_rigidbody_validate_sim_constraint(rbw, ob, true);
+ }
+ else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
+ BKE_rigidbody_validate_sim_constraint(rbw, ob, false);
+ }
+ rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
+ }
+ }
+ }
+}
+
+static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
+{
+ GroupObject *go;
+
+ for (go = rbw->group->gobject.first; go; go = go->next) {
+ Object *ob = go->ob;
+
+ if (ob) {
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ /* reset kinematic state for transformed objects */
+ if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
+ RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+ RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ /* deactivate passive objects so they don't interfere with deactivation of active objects */
+ if (rbo->type == RBO_TYPE_PASSIVE)
+ RB_body_deactivate(rbo->physics_object);
+ }
+ }
+ }
+}
+/* Sync rigid body and object transformations */
+void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ /* keep original transform for kinematic and passive objects */
+ if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
+ return;
+
+ /* use rigid body transform after cache start frame if objects is not being transformed */
+ if (ctime > rbw->pointcache->startframe && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
+ float mat[4][4], size_mat[4][4], size[3];
+
+ /* keep original transform when the simulation is muted */
+ if (rbw->flag & RBW_FLAG_MUTED)
+ return;
+
+ normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point
+ quat_to_mat4(mat, rbo->orn);
+ copy_v3_v3(mat[3], rbo->pos);
+
+ mat4_to_size(size, ob->obmat);
+ size_to_mat4(size_mat, size);
+ mult_m4_m4m4(mat, mat, size_mat);
+
+ copy_m4_m4(ob->obmat, mat);
+ }
+ /* otherwise set rigid body transform to current obmat */
+ else {
+ mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
+ }
+}
+
+/* Used when cancelling transforms - return rigidbody and object to initial states */
+void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ /* return rigid body and object to their initial states */
+ copy_v3_v3(rbo->pos, ob->loc);
+ copy_v3_v3(ob->loc, loc);
+
+ if (ob->rotmode > 0) {
+ eulO_to_quat(rbo->orn, ob->rot, ob->rotmode);
+ copy_v3_v3(ob->rot, rot);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ axis_angle_to_quat(rbo->orn, ob->rotAxis, ob->rotAngle);
+ copy_v3_v3(ob->rotAxis, rotAxis);
+ ob->rotAngle = rotAngle;
+ }
+ else {
+ copy_qt_qt(rbo->orn, ob->quat);
+ copy_qt_qt(ob->quat, quat);
+ }
+ if (rbo->physics_object) {
+ /* allow passive objects to return to original transform */
+ if (rbo->type == RBO_TYPE_PASSIVE)
+ RB_body_set_kinematic_state(rbo->physics_object, TRUE);
+ RB_body_set_loc_rot(rbo->physics_object, rbo->pos, rbo->orn);
+ }
+ // RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well (needs to be done outside bullet's update loop)
+}
+
+void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
+{
+ if (rbw)
+ rbw->pointcache->flag |= PTCACHE_OUTDATED;
+}
+
+/* ------------------ */
+
+/* Run RigidBody simulation for the specified physics world */
+void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
+{
+ float timestep;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ PointCache *cache;
+ PTCacheID pid;
+ int startframe, endframe;
+
+ BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
+ BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
+ cache = rbw->pointcache;
+
+ rbw->flag &= ~RBW_FLAG_FRAME_UPDATE;
+
+ /* 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)) {
+ cache->flag |= PTCACHE_OUTDATED;
+ }
+
+ if (ctime <= startframe) {
+ rbw->ltime = startframe;
+ /* reset and rebuild simulation if necessary */
+ if (cache->flag & PTCACHE_OUTDATED) {
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ rigidbody_update_simulation(scene, rbw, true);
+ BKE_ptcache_validate(cache, (int)ctime);
+ cache->last_exact = 0;
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+ }
+ return;
+ }
+ /* rebuild world if it's outdated on second frame */
+ else if (ctime == startframe + 1 && rbw->ltime == startframe && cache->flag & PTCACHE_OUTDATED) {
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ rigidbody_update_simulation(scene, rbw, true);
+ }
+ /* make sure we don't go out of cache frame range */
+ else if (ctime > endframe) {
+ ctime = endframe;
+ }
+
+ /* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
+ if (rbw->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
+ return;
+ else if (rbw->objects == NULL)
+ rigidbody_update_ob_array(rbw);
+
+ /* try to read from cache */
+ // RB_TODO deal with interpolated, old and baked results
+ if (BKE_ptcache_read(&pid, ctime)) {
+ BKE_ptcache_validate(cache, (int)ctime);
+ rbw->ltime = ctime;
+ return;
+ }
+
+ /* advance simulation, we can only step one frame forward */
+ if (ctime == rbw->ltime + 1 && !(cache->flag & PTCACHE_BAKED)) {
+ /* write cache for first frame when on second frame */
+ if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
+ BKE_ptcache_write(&pid, startframe);
+ }
+
+ /* update and validate simulation */
+ rigidbody_update_simulation(scene, rbw, false);
+
+ /* calculate how much time elapsed since last step in seconds */
+ timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale;
+ /* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
+ RB_dworld_step_simulation(rbw->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f));
+
+ rigidbody_update_simulation_post_step(rbw);
+
+ /* write cache for current frame */
+ BKE_ptcache_validate(cache, (int)ctime);
+ BKE_ptcache_write(&pid, (unsigned int)ctime);
+
+ rbw->ltime = ctime;
+ }
+}
+/* ************************************** */
+
+#else /* WITH_BULLET */
+
+/* stubs */
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+void BKE_rigidbody_free_world(RigidBodyWorld *rbw) {}
+void BKE_rigidbody_free_object(Object *ob) {}
+void BKE_rigidbody_free_constraint(Object *ob) {}
+struct RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) { return NULL; }
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob) { return NULL; }
+void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc) {}
+void BKE_rigidbody_validate_sim_shape(Object *ob, short rebuild) {}
+void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short rebuild) {}
+void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, short rebuild) {}
+void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, short rebuild) {}
+struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
+struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) { return NULL; }
+struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type) { return NULL; }
+struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene) { return NULL; }
+void BKE_rigidbody_remove_object(Scene *scene, Object *ob) {}
+void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
+void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
+void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
+void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
+void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
+
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+#endif /* WITH_BULLET */
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index eb4e0d9c679..6433b73fda0 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -734,7 +734,7 @@ void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up)
}
if (tmp) {
BLI_remlink(&ob->sensors, sens);
- BLI_insertlink(&ob->sensors, tmp, sens);
+ BLI_insertlinkafter(&ob->sensors, tmp, sens);
}
}
}
@@ -778,7 +778,7 @@ void sca_move_controller(bController *cont_to_move, Object *ob, int move_up)
tmp = tmp->next;
}
BLI_remlink(&ob->controllers, cont);
- BLI_insertlink(&ob->controllers, tmp, cont);
+ BLI_insertlinkafter(&ob->controllers, tmp, cont);
}
}
@@ -818,7 +818,7 @@ void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up)
}
if (tmp) {
BLI_remlink(&ob->actuators, act);
- BLI_insertlink(&ob->actuators, tmp, act);
+ BLI_insertlinkafter(&ob->actuators, tmp, act);
}
}
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 9bb2fb2de52..9a1a146c271 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -46,6 +46,7 @@
#include "DNA_group_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
+#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
@@ -72,6 +73,7 @@
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pointcache.h"
+#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_world.h"
@@ -143,7 +145,8 @@ Scene *BKE_scene_copy(Scene *sce, int type)
if (type == SCE_COPY_EMPTY) {
ListBase lb;
- scen = BKE_scene_add(sce->id.name + 2);
+ /* XXX. main should become an arg */
+ scen = BKE_scene_add(G.main, sce->id.name + 2);
lb = scen->r.layers;
scen->r = sce->r;
@@ -170,6 +173,7 @@ Scene *BKE_scene_copy(Scene *sce, int type)
scen->obedit = NULL;
scen->stats = NULL;
scen->fps_info = NULL;
+ scen->rigidbody_world = NULL; /* RB_TODO figure out a way of copying the rigid body world */
BLI_duplicatelist(&(scen->markers), &(sce->markers));
BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
@@ -309,6 +313,9 @@ void BKE_scene_free(Scene *sce)
BKE_free_animdata((ID *)sce);
BKE_keyingsets_free(&sce->keyingsets);
+ if (sce->rigidbody_world)
+ BKE_rigidbody_free_world(sce->rigidbody_world);
+
if (sce->r.avicodecdata) {
free_avicodecdata(sce->r.avicodecdata);
MEM_freeN(sce->r.avicodecdata);
@@ -372,9 +379,8 @@ void BKE_scene_free(Scene *sce)
BKE_color_managed_view_settings_free(&sce->view_settings);
}
-Scene *BKE_scene_add(const char *name)
+Scene *BKE_scene_add(Main *bmain, const char *name)
{
- Main *bmain = G.main;
Scene *sce;
ParticleEditSettings *pset;
int a;
@@ -400,6 +406,7 @@ Scene *BKE_scene_add(const char *name)
sce->r.im_format.planes = R_IMF_PLANES_RGB;
sce->r.im_format.imtype = R_IMF_IMTYPE_PNG;
+ sce->r.im_format.depth = R_IMF_CHAN_DEPTH_8;
sce->r.im_format.quality = 90;
sce->r.im_format.compress = 90;
@@ -432,6 +439,8 @@ Scene *BKE_scene_add(const char *name)
sce->r.bake_osa = 5;
sce->r.bake_flag = R_BAKE_CLEAR;
sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT;
+ sce->r.bake_samples = 256;
+ sce->r.bake_biasdist = 0.001;
sce->r.scemode = R_DOCOMP | R_DOSEQ | R_EXTENSION;
sce->r.stamp = R_STAMP_TIME | R_STAMP_FRAME | R_STAMP_DATE | R_STAMP_CAMERA | R_STAMP_SCENE | R_STAMP_FILENAME | R_STAMP_RENDERTIME;
sce->r.stamp_font_id = 12;
@@ -640,12 +649,11 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
}
/* sort baselist */
- DAG_scene_sort(bmain, scene);
+ DAG_scene_relations_rebuild(bmain, scene);
/* ensure dags are built for sets */
- for (sce = scene->set; sce; sce = sce->set)
- if (sce->theDag == NULL)
- DAG_scene_sort(bmain, sce);
+ for (sce = scene; sce; sce = sce->set)
+ DAG_scene_relations_update(bmain, sce);
/* copy layers and flags from bases to objects */
for (base = scene->base.first; base; base = base->next) {
@@ -703,7 +711,7 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
}
/* used by metaballs
- * doesnt return the original duplicated object, only dupli's
+ * doesn't return the original duplicated object, only dupli's
*/
int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
{
@@ -928,6 +936,18 @@ Base *BKE_scene_base_add(Scene *sce, Object *ob)
return b;
}
+void BKE_scene_base_unlink(Scene *sce, Base *base)
+{
+ /* remove rigid body constraint from world before removing object */
+ if (base->object->rigidbody_constraint)
+ BKE_rigidbody_remove_constraint(sce, base->object);
+ /* remove rigid body object from world before removing object */
+ if (base->object->rigidbody_object)
+ BKE_rigidbody_remove_object(sce, base->object);
+
+ BLI_remlink(&sce->base, base);
+}
+
void BKE_scene_base_deselect_all(Scene *sce)
{
Base *b;
@@ -1023,10 +1043,59 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
}
}
-static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
+/* deps hack - do extra recalcs at end */
+static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent)
{
Base *base;
+
+ scene->customdata_mask = scene_parent->customdata_mask;
+ /* sets first, we allow per definition current scene to have
+ * dependencies on sets, but not the other way around. */
+ if (scene->set)
+ scene_depsgraph_hack(scene->set, scene_parent);
+
+ for (base = scene->base.first; base; base = base->next) {
+ Object *ob = base->object;
+
+ if (ob->depsflag) {
+ int recalc = 0;
+ // printf("depshack %s\n", ob->id.name + 2);
+
+ if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC)
+ recalc |= OB_RECALC_OB;
+ if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC)
+ recalc |= OB_RECALC_DATA;
+
+ ob->recalc |= recalc;
+ BKE_object_handle_update(scene_parent, ob);
+
+ if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) {
+ GroupObject *go;
+
+ for (go = ob->dup_group->gobject.first; go; go = go->next) {
+ if (go->ob)
+ go->ob->recalc |= recalc;
+ }
+ group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
+ }
+ }
+ }
+
+}
+
+static void scene_flag_rbw_recursive(Scene *scene)
+{
+ if (scene->set)
+ scene_flag_rbw_recursive(scene->set);
+
+ if (BKE_scene_check_rigidbody_active(scene))
+ scene->rigidbody_world->flag |= RBW_FLAG_FRAME_UPDATE;
+}
+
+static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
+{
+ Base *base;
scene->customdata_mask = scene_parent->customdata_mask;
@@ -1035,11 +1104,27 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
if (scene->set)
scene_update_tagged_recursive(bmain, scene->set, scene_parent);
+ /* run rigidbody sim
+ * - calculate/read values from cache into RBO's, to get flushed
+ * later when objects are evaluated (if they're tagged for eval)
+ */
+ // XXX: this position may still change, objects not being updated correctly before simulation is run
+ // NOTE: current position is so that rigidbody sim affects other objects
+ if (BKE_scene_check_rigidbody_active(scene) && scene->rigidbody_world->flag & RBW_FLAG_FRAME_UPDATE) {
+ /* we use frame time of parent (this is "scene" itself for top-level of sets recursion),
+ * as that is the active scene controlling all timing in file at the moment
+ */
+ float ctime = BKE_scene_frame_get(scene_parent);
+
+ /* however, "scene" contains the rigidbody world needed for eval... */
+ BKE_rigidbody_do_simulation(scene, ctime);
+ }
+
/* scene objects */
for (base = scene->base.first; base; base = base->next) {
Object *ob = base->object;
- BKE_object_handle_update(scene_parent, ob);
+ BKE_object_handle_update_ex(scene_parent, ob, scene->rigidbody_world);
if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP))
group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
@@ -1058,14 +1143,21 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* update masking curves */
BKE_mask_update_scene(bmain, scene, FALSE);
+
}
/* this is called in main loop, doing tagged updates before redraw */
void BKE_scene_update_tagged(Main *bmain, Scene *scene)
{
+ Scene *sce_iter;
+
/* keep this first */
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
+ /* (re-)build dependency graph if needed */
+ for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
+ DAG_scene_relations_update(bmain, sce_iter);
+
/* flush recalc flags to dependencies */
DAG_ids_flush_tagged(bmain);
@@ -1116,10 +1208,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
/* clear animation overrides */
/* XXX TODO... */
- for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set) {
- if (sce_iter->theDag == NULL)
- DAG_scene_sort(bmain, sce_iter);
- }
+ for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set)
+ DAG_scene_relations_update(bmain, sce_iter);
/* flush recalc flags to dependencies, if we were only changing a frame
* this would not be necessary, but if a user or a script has modified
@@ -1139,7 +1229,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
* such as Scene->World->MTex/Texture) can still get correctly overridden.
*/
BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
- /*...done with recusrive funcs */
+ /*...done with recursive funcs */
/* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later
* when trying to find materials with drivers that need evaluating [#32017]
@@ -1147,9 +1237,14 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
tag_main_idcode(bmain, ID_MA, FALSE);
tag_main_idcode(bmain, ID_LA, FALSE);
+ /* flag rigid body worlds for update */
+ scene_flag_rbw_recursive(sce);
+
/* BKE_object_handle_update() on all objects, groups and sets */
scene_update_tagged_recursive(bmain, sce, sce);
+ scene_depsgraph_hack(sce, sce);
+
/* notify editors and python about recalc */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
@@ -1324,3 +1419,8 @@ int BKE_scene_check_color_management_enabled(const Scene *scene)
{
return strcmp(scene->display_settings.display_device, "None") != 0;
}
+
+int BKE_scene_check_rigidbody_active(const Scene *scene)
+{
+ return scene && scene->rigidbody_world && scene->rigidbody_world->group && !(scene->rigidbody_world->flag & RBW_FLAG_MUTED);
+}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 56fddfdaa2b..01f57b95378 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -167,6 +167,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
newar->prev = newar->next = NULL;
newar->handlers.first = newar->handlers.last = NULL;
newar->uiblocks.first = newar->uiblocks.last = NULL;
+ newar->ui_lists.first = newar->ui_lists.last = NULL;
newar->swinid = 0;
/* use optional regiondata callback */
@@ -279,6 +280,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
}
BLI_freelistN(&ar->panels);
+ BLI_freelistN(&ar->ui_lists);
}
/* not area itself */
@@ -353,6 +355,20 @@ ARegion *BKE_area_find_region_type(ScrArea *sa, int type)
return NULL;
}
+ARegion *BKE_area_find_region_active_win(ScrArea *sa)
+{
+ if (sa) {
+ ARegion *ar = BLI_findlink(&sa->regionbase, sa->region_active_win);
+ if (ar && (ar->regiontype == RGN_TYPE_WINDOW)) {
+ return ar;
+ }
+
+ /* fallback to any */
+ return BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ }
+ return NULL;
+}
+
/* 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 */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 0b7fdaa7c1d..c0e85352217 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -156,42 +156,43 @@ static void init_alpha_over_or_under(Sequence *seq)
seq->seq1 = seq2;
}
-static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
- int fac2, mfac, fac, fac4;
- int xo, tempc;
- char *rt1, *rt2, *rt;
+ float fac2, mfac, fac, fac4;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *) rect1;
- rt2 = (char *) rect2;
- rt = (char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac2 = (int) (256.0f * facf0);
- fac4 = (int) (256.0f * facf1);
+ fac2 = facf0;
+ fac4 = facf1;
while (y--) {
x = xo;
while (x--) {
-
/* rt = rt1 over rt2 (alpha from rt1) */
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
fac = fac2;
- mfac = 256 - ( (fac2 * rt1[3]) >> 8);
+ mfac = 1.0f - fac2 * rt1[3];
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
- else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+ if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+ else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
else {
- tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
- if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
- tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
- if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
- tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
- if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
- tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
- if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
+ tempc[0] = fac * rt1[0] + mfac * rt2[0];
+ tempc[1] = fac * rt1[1] + mfac * rt2[1];
+ tempc[2] = fac * rt1[2] + mfac * rt2[2];
+ tempc[3] = fac * rt1[3] + mfac * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
}
- rt1 += 4; rt2 += 4; rt += 4;
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0) break;
@@ -199,22 +200,23 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, ch
x = xo;
while (x--) {
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
fac = fac4;
- mfac = 256 - ( (fac4 * rt1[3]) >> 8);
+ mfac = 1.0f - (fac4 * rt1[3]);
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
- else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+ if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+ else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
else {
- tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
- if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
- tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
- if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
- tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
- if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
- tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
- if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
+ tempc[0] = fac * rt1[0] + mfac * rt2[0];
+ tempc[1] = fac * rt1[1] + mfac * rt2[1];
+ tempc[2] = fac * rt1[2] + mfac * rt2[2];
+ tempc[3] = fac * rt1[3] + mfac * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
}
- rt1 += 4; rt2 += 4; rt += 4;
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -298,17 +300,17 @@ static void do_alphaover_effect(SeqRenderData context, Sequence *UNUSED(seq), fl
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
/*********************** Alpha Under *************************/
-static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
int fac2, mfac, fac, fac4;
int xo;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
rt1 = rect1;
@@ -460,17 +462,17 @@ static void do_alphaunder_effect(SeqRenderData context, Sequence *UNUSED(seq), f
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
/*********************** Cross *************************/
-static void do_cross_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_cross_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
int fac1, fac2, fac3, fac4;
int xo;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
rt1 = rect1;
@@ -570,7 +572,7 @@ static void do_cross_effect(SeqRenderData context, Sequence *UNUSED(seq), float
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
@@ -713,31 +715,32 @@ static void free_gammacross(Sequence *UNUSED(seq))
static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1,
unsigned char *rect2, unsigned char *out)
{
- int fac1, fac2, col;
+ float fac1, fac2;
int xo;
- unsigned char *rt1, *rt2, *rt;
-
+ unsigned char *cp1, *cp2, *rt;
+ float rt1[4], rt2[4], tempc[4];
+
xo = x;
- rt1 = (unsigned char *) rect1;
- rt2 = (unsigned char *) rect2;
- rt = (unsigned char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac2 = (int)(256.0f * facf0);
- fac1 = 256 - fac2;
+ fac2 = facf0;
+ fac1 = 1.0f - fac2;
while (y--) {
x = xo;
while (x--) {
- col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
- if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
- if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
- if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
- if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
+ tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
+ tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
+ tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
+
+ premul_float_to_straight_uchar(rt, tempc);
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -746,16 +749,16 @@ static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x,
x = xo;
while (x--) {
- col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
- if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
- if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
- if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
- if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
+ tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
+ tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
+ tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
+
+ premul_float_to_straight_uchar(rt, tempc);
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -828,31 +831,34 @@ static void do_gammacross_effect(SeqRenderData context, Sequence *UNUSED(seq), f
static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2,
unsigned char *out)
{
- int col, xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float fac1, fac3;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac1 = (int)(256.0f * facf0);
- fac3 = (int)(256.0f * facf1);
+ fac1 = facf0;
+ fac3 = facf1;
while (y--) {
x = xo;
while (x--) {
- col = rt1[0] + ((fac1 * rt2[0]) >> 8);
- if (col > 255) rt[0] = 255; else rt[0] = col;
- col = rt1[1] + ((fac1 * rt2[1]) >> 8);
- if (col > 255) rt[1] = 255; else rt[1] = col;
- col = rt1[2] + ((fac1 * rt2[2]) >> 8);
- if (col > 255) rt[2] = 255; else rt[2] = col;
- col = rt1[3] + ((fac1 * rt2[3]) >> 8);
- if (col > 255) rt[3] = 255; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] + fac1 * rt2[0];
+ tempc[1] = rt1[1] + fac1 * rt2[1];
+ tempc[2] = rt1[2] + fac1 * rt2[2];
+ tempc[3] = min_ff(1.0f, rt1[3] + fac1 * rt2[3]);
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -861,16 +867,17 @@ static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned
x = xo;
while (x--) {
- col = rt1[0] + ((fac3 * rt2[0]) >> 8);
- if (col > 255) rt[0] = 255; else rt[0] = col;
- col = rt1[1] + ((fac3 * rt2[1]) >> 8);
- if (col > 255) rt[1] = 255; else rt[1] = col;
- col = rt1[2] + ((fac3 * rt2[2]) >> 8);
- if (col > 255) rt[2] = 255; else rt[2] = col;
- col = rt1[3] + ((fac3 * rt2[3]) >> 8);
- if (col > 255) rt[3] = 255; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] + fac3 * rt2[0];
+ tempc[1] = rt1[1] + fac3 * rt2[1];
+ tempc[2] = rt1[2] + fac3 * rt2[2];
+ tempc[3] = min_ff(1.0f, rt1[3] + fac3 * rt2[3]);
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -890,22 +897,28 @@ static void do_add_effect_float(float facf0, float facf1, int x, int y, float *r
fac3 = facf1;
while (y--) {
- x = xo * 4;
+ x = xo;
while (x--) {
- *rt = *rt1 + fac1 * (*rt2);
+ rt[0] = rt1[0] + fac1 * rt2[0];
+ rt[1] = rt1[1] + fac1 * rt2[1];
+ rt[2] = rt1[2] + fac1 * rt2[2];
+ rt[3] = min_ff(1.0f, rt1[3] + fac1 * rt2[3]);
- rt1++; rt2++; rt++;
+ rt1 += 4; rt2 += 4; rt += 4;
}
if (y == 0)
break;
y--;
- x = xo * 4;
+ x = xo;
while (x--) {
- *rt = *rt1 + fac3 * (*rt2);
+ rt[0] = rt1[0] + fac1 * rt2[0];
+ rt[1] = rt1[1] + fac1 * rt2[1];
+ rt[2] = rt1[2] + fac1 * rt2[2];
+ rt[3] = min_ff(1.0f, rt1[3] + fac3 * rt2[3]);
- rt1++; rt2++; rt++;
+ rt1 += 4; rt2 += 4; rt += 4;
}
}
}
@@ -931,32 +944,35 @@ static void do_add_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
/*********************** Sub *************************/
-static void do_sub_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
- int col, xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float fac1, fac3;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *) rect1;
- rt2 = (char *) rect2;
- rt = (char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac1 = (int) (256.0f * facf0);
- fac3 = (int) (256.0f * facf1);
+ fac1 = facf0;
+ fac3 = facf1;
while (y--) {
x = xo;
while (x--) {
- col = rt1[0] - ((fac1 * rt2[0]) >> 8);
- if (col < 0) rt[0] = 0; else rt[0] = col;
- col = rt1[1] - ((fac1 * rt2[1]) >> 8);
- if (col < 0) rt[1] = 0; else rt[1] = col;
- col = rt1[2] - ((fac1 * rt2[2]) >> 8);
- if (col < 0) rt[2] = 0; else rt[2] = col;
- col = rt1[3] - ((fac1 * rt2[3]) >> 8);
- if (col < 0) rt[3] = 0; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] - fac1 * rt2[0];
+ tempc[1] = rt1[1] - fac1 * rt2[1];
+ tempc[2] = rt1[2] - fac1 * rt2[2];
+ tempc[3] = rt1[3] - fac1 * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -965,16 +981,17 @@ static void do_sub_effect_byte(float facf0, float facf1, int x, int y, char *rec
x = xo;
while (x--) {
- col = rt1[0] - ((fac3 * rt2[0]) >> 8);
- if (col < 0) rt[0] = 0; else rt[0] = col;
- col = rt1[1] - ((fac3 * rt2[1]) >> 8);
- if (col < 0) rt[1] = 0; else rt[1] = col;
- col = rt1[2] - ((fac3 * rt2[2]) >> 8);
- if (col < 0) rt[2] = 0; else rt[2] = col;
- col = rt1[3] - ((fac3 * rt2[3]) >> 8);
- if (col < 0) rt[3] = 0; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] - fac3 * rt2[0];
+ tempc[1] = rt1[1] - fac3 * rt2[1];
+ tempc[2] = rt1[2] - fac3 * rt2[2];
+ tempc[3] = rt1[3] - fac3 * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -1029,7 +1046,7 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
@@ -1039,10 +1056,10 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
#define XOFF 8
#define YOFF 8
-static void do_drop_effect_byte(float facf0, float facf1, int x, int y, char *rect2i, char *rect1i, char *outi)
+static void do_drop_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
{
int height, width, temp, fac, fac1, fac2;
- char *rt1, *rt2, *out;
+ unsigned char *rt1, *rt2, *out;
int field = 1;
width = x;
@@ -1051,9 +1068,9 @@ static void do_drop_effect_byte(float facf0, float facf1, int x, int y, char *re
fac1 = (int) (70.0f * facf0);
fac2 = (int) (70.0f * facf1);
- rt2 = (char *) (rect2i + YOFF * width);
- rt1 = (char *) rect1i;
- out = (char *) outi;
+ rt2 = (unsigned char *) (rect2i + YOFF * width);
+ rt1 = (unsigned char *) rect1i;
+ out = (unsigned char *) outi;
for (y = 0; y < height - YOFF; y++) {
if (field) fac = fac1;
else fac = fac2;
@@ -1122,18 +1139,18 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned
unsigned char *out)
{
int xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ rt1 = rect1;
+ rt2 = rect2;
+ rt = out;
fac1 = (int)(256.0f * facf0);
fac3 = (int)(256.0f * facf1);
/* formula:
- * fac * (a * b) + (1-fac)*a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
+ * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
* yaux = -s * px + c * py; //+centy
*/
@@ -1300,7 +1317,8 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f
switch (wipe->wipetype) {
case DO_SINGLE_WIPE:
- width = wipezone->width;
+ width = min_ii(wipezone->width, facf0 * yo);
+ width = min_ii(width, yo - facf0 * yo);
if (angle == 0.0f) {
b1 = posy;
@@ -1539,13 +1557,13 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
WipeZone wipezone;
WipeVars *wipe = (WipeVars *)seq->effectdata;
int xo, yo;
- char *rt1, *rt2, *rt;
+ unsigned char *cp1, *cp2, *rt;
precalc_wipe_zone(&wipezone, wipe, x, y);
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
xo = x;
yo = y;
@@ -1553,11 +1571,18 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
for (x = 0; x < xo; x++) {
float check = check_zone(&wipezone, x, y, seq, facf0);
if (check) {
- if (rt1) {
- rt[0] = (int)(rt1[0] * check) + (int)(rt2[0] * (1 - check));
- rt[1] = (int)(rt1[1] * check) + (int)(rt2[1] * (1 - check));
- rt[2] = (int)(rt1[2] * check) + (int)(rt2[2] * (1 - check));
- rt[3] = (int)(rt1[3] * check) + (int)(rt2[3] * (1 - check));
+ if (cp1) {
+ float rt1[4], rt2[4], tempc[4];
+
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
+ tempc[0] = rt1[0] * check + rt2[0] * (1 - check);
+ tempc[1] = rt1[1] * check + rt2[1] * (1 - check);
+ tempc[2] = rt1[2] * check + rt2[2] * (1 - check);
+ tempc[3] = rt1[3] * check + rt2[3] * (1 - check);
+
+ premul_float_to_straight_uchar(rt, tempc);
}
else {
rt[0] = 0;
@@ -1567,11 +1592,11 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
}
}
else {
- if (rt2) {
- rt[0] = rt2[0];
- rt[1] = rt2[1];
- rt[2] = rt2[2];
- rt[3] = rt2[3];
+ if (cp2) {
+ rt[0] = cp2[0];
+ rt[1] = cp2[1];
+ rt[2] = cp2[2];
+ rt[3] = cp2[3];
}
else {
rt[0] = 0;
@@ -1582,11 +1607,11 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
}
rt += 4;
- if (rt1 != NULL) {
- rt1 += 4;
+ if (cp1 != NULL) {
+ cp1 += 4;
}
- if (rt2 != NULL) {
- rt2 += 4;
+ if (cp2 != NULL) {
+ cp2 += 4;
}
}
}
@@ -1745,7 +1770,7 @@ static void transform_image(int x, int y, ImBuf *ibuf1, ImBuf *out, float scale
/* interpolate */
switch (interpolation) {
case 0:
- neareast_interpolation(ibuf1, out, xt, yt, xi, yi);
+ nearest_interpolation(ibuf1, out, xt, yt, xi, yi);
break;
case 1:
bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
@@ -1803,166 +1828,6 @@ static ImBuf *do_transform_effect(SeqRenderData context, Sequence *seq, float UN
/*********************** Glow *************************/
-static void RVBlurBitmap2_byte(unsigned char *map, int width, int height, float blur, int quality)
-/* MUUUCCH better than the previous blur. */
-/* We do the blurring in two passes which is a whole lot faster. */
-/* I changed the math arount to implement an actual Gaussian */
-/* distribution. */
-/* */
-/* Watch out though, it tends to misbehaven with large blur values on */
-/* a small bitmap. Avoid avoid avoid. */
-/*=============================== */
-{
- unsigned char *temp = NULL, *swap;
- float *filter = NULL;
- int x, y, i, fx, fy;
- int index, ix, halfWidth;
- float fval, k, curColor[3], curColor2[3], weight = 0;
-
- /* If we're not really blurring, bail out */
- if (blur <= 0)
- return;
-
- /*Allocate memory for the tempmap and the blur filter matrix */
- temp = MEM_mallocN((width * height * 4), "blurbitmaptemp");
- if (!temp)
- return;
-
- /*Allocate memory for the filter elements */
- halfWidth = ((quality + 1) * blur);
- filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
- if (!filter) {
- MEM_freeN(temp);
- return;
- }
-
- /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
- * This code is based on an example posted to comp.graphics.algorithms by
- * Blancmange (bmange@airdmhor.gen.nz)
- */
-
- k = -1.0f / (2.0f * (float)M_PI * blur * blur);
- for (ix = 0; ix < halfWidth; ix++) {
- weight = (float)exp(k * (ix * ix));
- filter[halfWidth - ix] = weight;
- filter[halfWidth + ix] = weight;
- }
- filter[0] = weight;
-
- /* Normalize the array */
- fval = 0;
- for (ix = 0; ix < halfWidth * 2; ix++)
- fval += filter[ix];
-
- for (ix = 0; ix < halfWidth * 2; ix++)
- filter[ix] /= fval;
-
- /* Blur the rows */
- for (y = 0; y < height; y++) {
- /* Do the left & right strips */
- for (x = 0; x < halfWidth; x++) {
- index = (x + y * width) * 4;
- fx = 0;
- zero_v3(curColor);
- zero_v3(curColor2);
-
- for (i = x - halfWidth; i < x + halfWidth; i++) {
- if ((i >= 0) && (i < width)) {
- curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
- curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
- curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
-
- curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] * filter[fx];
- curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] * filter[fx];
- curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] * filter[fx];
- }
- fx++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
-
- temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
- temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
- temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
-
- }
-
- /* Do the main body */
- for (x = halfWidth; x < width - halfWidth; x++) {
- index = (x + y * width) * 4;
- fx = 0;
- zero_v3(curColor);
- for (i = x - halfWidth; i < x + halfWidth; i++) {
- curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
- curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
- curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
- fx++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- }
- }
-
- /* Swap buffers */
- swap = temp; temp = map; map = swap;
-
- /* Blur the columns */
- for (x = 0; x < width; x++) {
- /* Do the top & bottom strips */
- for (y = 0; y < halfWidth; y++) {
- index = (x + y * width) * 4;
- fy = 0;
- zero_v3(curColor);
- zero_v3(curColor2);
- for (i = y - halfWidth; i < y + halfWidth; i++) {
- if ((i >= 0) && (i < height)) {
- /* Bottom */
- curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
- curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
- curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
-
- /* Top */
- curColor2[0] += map[(x + (height - 1 - i) * width) * 4 + GlowR] * filter[fy];
- curColor2[1] += map[(x + (height - 1 - i) * width) * 4 + GlowG] * filter[fy];
- curColor2[2] += map[(x + (height - 1 - i) * width) * 4 + GlowB] * filter[fy];
- }
- fy++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
- temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
- temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
- }
-
- /* Do the main body */
- for (y = halfWidth; y < height - halfWidth; y++) {
- index = (x + y * width) * 4;
- fy = 0;
- zero_v3(curColor);
- for (i = y - halfWidth; i < y + halfWidth; i++) {
- curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
- curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
- curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
- fy++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- }
- }
-
- /* Swap buffers */
- swap = temp; temp = map; /* map = swap; */ /* UNUSED */
-
- /* Tidy up */
- MEM_freeN(filter);
- MEM_freeN(temp);
-}
-
static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
/* MUUUCCH better than the previous blur. */
/* We do the blurring in two passes which is a whole lot faster. */
@@ -2124,26 +1989,6 @@ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, i
MEM_freeN(temp);
}
-
-/* Adds two bitmaps and puts the results into a third map. */
-/* C must have been previously allocated but it may be A or B. */
-/* We clamp values to 255 to prevent weirdness */
-/*=============================== */
-static void RVAddBitmaps_byte(unsigned char *a, unsigned char *b, unsigned char *c, int width, int height)
-{
- int x, y, index;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- index = (x + y * width) * 4;
- c[index + GlowR] = MIN2(255, a[index + GlowR] + b[index + GlowR]);
- c[index + GlowG] = MIN2(255, a[index + GlowG] + b[index + GlowG]);
- c[index + GlowB] = MIN2(255, a[index + GlowB] + b[index + GlowB]);
- c[index + GlowA] = MIN2(255, a[index + GlowA] + b[index + GlowA]);
- }
- }
-}
-
static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
{
int x, y, index;
@@ -2159,37 +2004,6 @@ static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int heig
}
}
-/* For each pixel whose total luminance exceeds the threshold,
- * Multiply it's value by BOOST and add it to the output map
- */
-static void RVIsolateHighlights_byte(unsigned char *in, unsigned char *out, int width, int height, int threshold,
- float boost, float clamp)
-{
- int x, y, index;
- int intensity;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- index = (x + y * width) * 4;
-
- /* Isolate the intensity */
- intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
- if (intensity > 0) {
- out[index + GlowR] = MIN2(255 * clamp, (in[index + GlowR] * boost * intensity) / 255);
- out[index + GlowG] = MIN2(255 * clamp, (in[index + GlowG] * boost * intensity) / 255);
- out[index + GlowB] = MIN2(255 * clamp, (in[index + GlowB] * boost * intensity) / 255);
- out[index + GlowA] = MIN2(255 * clamp, (in[index + GlowA] * boost * intensity) / 255);
- }
- else {
- out[index + GlowR] = 0;
- out[index + GlowG] = 0;
- out[index + GlowB] = 0;
- out[index + GlowA] = 0;
- }
- }
- }
-}
-
static void RVIsolateHighlights_float(float *in, float *out, int width, int height, float threshold, float boost, float clamp)
{
int x, y, index;
@@ -2254,16 +2068,27 @@ static void copy_glow_effect(Sequence *dst, Sequence *src)
}
static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
- char *rect1, char *UNUSED(rect2), char *out)
+ unsigned char *rect1, unsigned char *UNUSED(rect2), unsigned char *out)
{
- unsigned char *outbuf = (unsigned char *)out;
- unsigned char *inbuf = (unsigned char *)rect1;
+ float *outbuf, *inbuf;
GlowVars *glow = (GlowVars *)seq->effectdata;
-
- RVIsolateHighlights_byte(inbuf, outbuf, x, y, glow->fMini * 765, glow->fBoost * facf0, glow->fClamp);
- RVBlurBitmap2_byte(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
+
+ inbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect input");
+ outbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect output");
+
+ IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+ IMB_buffer_float_premultiply(inbuf, x, y);
+
+ RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
+ RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
if (!glow->bNoComp)
- RVAddBitmaps_byte(inbuf, outbuf, outbuf, x, y);
+ RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
+
+ IMB_buffer_float_unpremultiply(outbuf, x, y);
+ IMB_buffer_byte_from_float(out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+
+ MEM_freeN(inbuf);
+ MEM_freeN(outbuf);
}
static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
@@ -2292,7 +2117,7 @@ static ImBuf *do_glow_effect(SeqRenderData context, Sequence *seq, float UNUSED(
}
else {
do_glow_effect_byte(seq, render_size, facf0, facf1, context.rectx, context.recty,
- (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
+ (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
}
return out;
@@ -2735,7 +2560,7 @@ static ImBuf *do_speed_effect(SeqRenderData context, Sequence *UNUSED(seq), floa
}
else {
do_cross_effect_byte(facf0, facf1, context.rectx, context.recty,
- (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
+ (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
}
return out;
}
@@ -2761,8 +2586,8 @@ static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), flo
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_drop_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
- do_alphaover_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_drop_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
+ do_alphaover_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
}
}
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 5b2e9f2bf23..9ea405ef636 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -135,7 +135,7 @@ static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_thr
init_data.apply_callback = apply_callback;
IMB_processor_apply_threaded(ibuf->y, sizeof(ModifierThread), &init_data,
- modifier_init_handle, modifier_do_thread);
+ modifier_init_handle, modifier_do_thread);
}
/* **** Color Balance Modifier **** */
@@ -226,24 +226,28 @@ static void curves_apply_threaded(int width, int height, unsigned char *rect, fl
}
if (rect) {
unsigned char *pixel = rect + pixel_index;
- unsigned char result[3];
+ float result[3], tempc[4];
- curvemapping_evaluate_premulRGB(curve_mapping, result, pixel);
+ straight_uchar_to_premul_float(tempc, pixel);
+
+ curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc);
if (mask_rect) {
float t[3];
rgb_uchar_to_float(t, mask_rect + pixel_index);
- pixel[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
- pixel[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
- pixel[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
+ tempc[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
+ tempc[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
+ tempc[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
}
else {
- pixel[0] = result[0];
- pixel[1] = result[1];
- pixel[2] = result[2];
+ tempc[0] = result[0];
+ tempc[1] = result[1];
+ tempc[2] = result[2];
}
+
+ premul_float_to_straight_uchar(pixel, tempc);
}
}
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index acce3740c98..68618287546 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -191,7 +191,9 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const int do_cache
((ID *)seq->sound)->us--;
}
- /* clipboard has no scene and will never have a sound handle or be active */
+ /* clipboard has no scene and will never have a sound handle or be active
+ * same goes to sequences copy for proxy rebuild job
+ */
if (scene) {
Editing *ed = scene->ed;
@@ -322,7 +324,6 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_
{
const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
const char *to_colorspace = scene->sequencer_colorspace_settings.name;
- int predivide = ibuf->flags & IB_cm_predivide;
if (!ibuf->rect_float) {
if (make_float && ibuf->rect) {
@@ -352,7 +353,7 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_
imb_freerectImBuf(ibuf);
IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -365,10 +366,8 @@ void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
return;
if (to_colorspace && to_colorspace[0] != '\0') {
- int predivide = ibuf->flags & IB_cm_predivide;
-
IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -591,8 +590,8 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq)
/* XXX These resets should not be necessary, but users used to be able to
* edit effect's length, leading to strange results. See [#29190] */
seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
- seq->start = seq->startdisp = MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
- seq->enddisp = MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
+ seq->start = seq->startdisp = max_iii(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
+ seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
/* we cant help if strips don't overlap, it wont give useful results.
* but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
if (seq->enddisp < seq->startdisp) {
@@ -634,7 +633,7 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq)
}
}
-/* note: caller should run calc_sequence(scene, seq) after */
+/* note: caller should run BKE_sequence_calc(scene, seq) after */
void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range)
{
char str[FILE_MAX];
@@ -1435,7 +1434,7 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
seq_proxy_build_frame(render_context, seq, cfra, 100);
}
- *progress = (float) cfra / (seq->enddisp - seq->endstill - seq->startdisp + seq->startstill);
+ *progress = (float) (cfra - seq->startdisp - seq->startstill) / (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill);
*do_update = TRUE;
if (*stop || G.is_break)
@@ -1451,7 +1450,7 @@ void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, short sto
IMB_anim_index_rebuild_finish(context->index_context, stop);
}
- seq_free_sequence_recurse(context->scene, context->seq);
+ seq_free_sequence_recurse(NULL, context->seq);
MEM_freeN(context);
}
@@ -1515,18 +1514,6 @@ MINLINE float color_balance_fl(float in, const float lift, const float gain, con
return powf(x, gamma) * mul;
}
-static void make_cb_table_byte(float lift, float gain, float gamma,
- unsigned char *table, float mul)
-{
- int y;
-
- for (y = 0; y < 256; y++) {
- float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
-
- table[y] = FTOCHAR(v);
- }
-}
-
static void make_cb_table_float(float lift, float gain, float gamma,
float *table, float mul)
{
@@ -1541,35 +1528,33 @@ static void make_cb_table_float(float lift, float gain, float gamma,
static void color_balance_byte_byte(StripColorBalance *cb_, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
{
- unsigned char cb_tab[3][256];
- int c;
- unsigned char *p = rect;
- unsigned char *e = p + width * 4 * height;
+ //unsigned char cb_tab[3][256];
+ unsigned char *cp = rect;
+ unsigned char *e = cp + width * 4 * height;
unsigned char *m = mask_rect;
StripColorBalance cb = calc_cb(cb_);
- for (c = 0; c < 3; c++) {
- make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
- }
+ while (cp < e) {
+ float p[4];
+ int c;
- while (p < e) {
- if (m) {
- float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+ straight_uchar_to_premul_float(p, cp);
- p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
- p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
- p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
+ for (c = 0; c < 3; c++) {
+ float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
- m += 4;
- }
- else {
- p[0] = cb_tab[0][p[0]];
- p[1] = cb_tab[1][p[1]];
- p[2] = cb_tab[2][p[2]];
+ if (m)
+ p[c] = p[c] * (1.0f - (float)m[c] / 255.0f) + t * m[c];
+ else
+ p[c] = t;
}
- p += 4;
+ premul_float_to_straight_uchar(cp, p);
+
+ cp += 4;
+ if (m)
+ m += 4;
}
}
@@ -1761,7 +1746,7 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float
init_data.mask = mask_input;
IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
- color_balance_init_handle, color_balance_do_thread);
+ color_balance_init_handle, color_balance_do_thread);
/* color balance either happens on float buffer or byte buffer, but never on both,
* free byte buffer if there's float buffer since float buffer would be used for
@@ -1793,7 +1778,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
{
float mul;
- if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_PREMUL | SEQ_MAKE_FLOAT)) {
+ if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
return TRUE;
}
@@ -1835,8 +1820,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
StripCrop c = {0};
StripTransform t = {0};
int sx, sy, dx, dy;
- double xscale = 1.0;
- double yscale = 1.0;
if (is_proxy_image) {
double f = seq_rendersize_to_scale_factor(context.preview_render_size);
@@ -1853,21 +1836,23 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
t = *seq->strip->transform;
}
- xscale = context.scene->r.xsch ? ((double)context.rectx / (double)context.scene->r.xsch) : 1.0;
- yscale = context.scene->r.ysch ? ((double)context.recty / (double)context.scene->r.ysch) : 1.0;
-
- xscale /= (double)context.rectx / (double)ibuf->x;
- yscale /= (double)context.recty / (double)ibuf->y;
-
- c.left *= xscale; c.right *= xscale;
- c.top *= yscale; c.bottom *= yscale;
-
- t.xofs *= xscale; t.yofs *= yscale;
+ if (is_preprocessed) {
+ double xscale = context.scene->r.xsch ? ((double)context.rectx / (double)context.scene->r.xsch) : 1.0;
+ double yscale = context.scene->r.ysch ? ((double)context.recty / (double)context.scene->r.ysch) : 1.0;
+ if (seq->flag & SEQ_USE_TRANSFORM) {
+ t.xofs *= xscale;
+ t.yofs *= yscale;
+ }
+ if (seq->flag & SEQ_USE_CROP) {
+ c.left *= xscale;
+ c.right *= xscale;
+ c.top *= yscale;
+ c.bottom *= yscale;
+ }
+ }
sx = ibuf->x - c.left - c.right;
sy = ibuf->y - c.top - c.bottom;
- dx = sx;
- dy = sy;
if (seq->flag & SEQ_USE_TRANSFORM) {
if (is_preprocessed) {
@@ -1879,6 +1864,10 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
dy = context.scene->r.ysch;
}
}
+ else {
+ dx = sx;
+ dy = sy;
+ }
if (c.top + c.bottom >= ibuf->y ||
c.left + c.right >= ibuf->x ||
@@ -1890,7 +1879,8 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
-
+ sequencer_imbuf_assign_spaces(context.scene, i);
+
IMB_freeImBuf(ibuf);
ibuf = i;
@@ -1929,12 +1919,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
multibuf(ibuf, mul);
}
- if (seq->flag & SEQ_MAKE_PREMUL) {
- if (ibuf->planes == 32 && ibuf->zbuf == NULL) {
- IMB_premultiply_alpha(ibuf);
- }
- }
-
if (ibuf->x != context.rectx || ibuf->y != context.recty) {
if (context.scene->r.mode & R_OSA) {
IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
@@ -2409,8 +2393,9 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
/* opengl offscreen render */
BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
- ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty,
- IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out);
+ ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect,
+ context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX,
+ TRUE, scene->r.alphamode, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
@@ -2543,13 +2528,18 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
case SEQ_TYPE_IMAGE:
{
StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
+ int flag;
if (s_elem) {
BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
BLI_path_abs(name, G.main->name);
}
- if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name))) {
+ flag = IB_rect;
+ if (seq->alpha_mode == SEQ_ALPHA_PREMUL)
+ flag |= IB_alphamode_premul;
+
+ if (s_elem && (ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name))) {
/* we don't need both (speed reasons)! */
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
@@ -2638,7 +2628,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
{
ImBuf *ibuf = NULL;
- int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ int use_preprocess = FALSE;
int is_proxy_image = FALSE;
float nr = give_stripelem_index(seq, cfra);
/* all effects are handled similarly with the exception of speed effect */
@@ -2647,30 +2637,36 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
- /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
- * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
- if (ibuf)
- use_preprocess = FALSE;
-
- if (ibuf == NULL)
- ibuf = copy_from_ibuf_still(context, seq, nr);
-
if (ibuf == NULL) {
- ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+ if (ibuf == NULL)
+ ibuf = copy_from_ibuf_still(context, seq, nr);
if (ibuf == NULL) {
- /* MOVIECLIPs have their own proxy management */
- if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
- ibuf = seq_proxy_fetch(context, seq, cfra);
- is_proxy_image = (ibuf != NULL);
- }
+ ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+
+ if (ibuf == NULL) {
+ /* MOVIECLIPs have their own proxy management */
+ if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
+ ibuf = seq_proxy_fetch(context, seq, cfra);
+ is_proxy_image = (ibuf != NULL);
+ }
- if (ibuf == NULL)
- ibuf = do_render_strip_uncached(context, seq, cfra);
+ if (ibuf == NULL)
+ ibuf = do_render_strip_uncached(context, seq, cfra);
- if (ibuf)
- BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ if (ibuf)
+ BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ }
}
+
+ if (ibuf)
+ use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ }
+ else {
+ /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
+ * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL
+ * so, no need in check for preprocess here
+ */
}
if (ibuf == NULL) {
@@ -3959,6 +3955,24 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine)
return seq;
}
+void BKE_sequence_alpha_mode_from_extension(Sequence *seq)
+{
+ if (seq->strip && seq->strip->stripdata) {
+ char *name = seq->strip->stripdata->name;
+
+ if (BLI_testextensie(name, ".exr") ||
+ BLI_testextensie(name, ".cin") ||
+ BLI_testextensie(name, ".dpx") ||
+ BLI_testextensie(name, ".hdr"))
+ {
+ seq->alpha_mode = IMA_ALPHA_PREMUL;
+ }
+ else {
+ seq->alpha_mode = IMA_ALPHA_STRAIGHT;
+ }
+ }
+}
+
void BKE_sequence_init_colorspace(Sequence *seq)
{
if (seq->strip && seq->strip->stripdata) {
@@ -3970,10 +3984,18 @@ void BKE_sequence_init_colorspace(Sequence *seq)
/* initialize input color space */
if (seq->type == SEQ_TYPE_IMAGE) {
- ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name);
+ ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, seq->strip->colorspace_settings.name);
+
+ /* byte images are default to straight alpha, however sequencer
+ * works in premul space, so mark strip to be premultiplied first
+ */
+ seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
+ if (ibuf) {
+ if (ibuf->flags & IB_alphamode_premul)
+ seq->alpha_mode = IMA_ALPHA_PREMUL;
- if (ibuf)
IMB_freeImBuf(ibuf);
+ }
}
}
}
@@ -4173,7 +4195,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->seqbase.first = seqn->seqbase.last = NULL;
/* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
- /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/
+ /* - seq_dupli_recursive(&seq->seqbase, &seqn->seqbase);*/
}
else if (seq->type == SEQ_TYPE_SCENE) {
seqn->strip->stripdata = NULL;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 53dfbdcfb85..248cd689258 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -170,7 +170,7 @@ void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int
if (free_old && sds->fluid)
smoke_free(sds->fluid);
- if (!MIN3(res[0], res[1], res[2])) {
+ if (!min_iii(res[0], res[1], res[2])) {
sds->fluid = NULL;
return;
}
@@ -191,7 +191,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
if (free_old && sds->wt)
smoke_turbulence_free(sds->wt);
- if (!MIN3(res[0], res[1], res[2])) {
+ if (!min_iii(res[0], res[1], res[2])) {
sds->wt = NULL;
return;
}
@@ -213,8 +213,8 @@ static void smoke_pos_to_cell(SmokeDomainSettings *sds, float pos[3])
pos[2] *= 1.0f / sds->cell_size[2];
}
-/* set domain resolution and dimensions from object derivedmesh */
-static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm)
+/* set domain transformations and base resolution from object derivedmesh */
+static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm, int init_resolution)
{
size_t i;
float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
@@ -246,7 +246,10 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *
/* calculate domain dimensions */
sub_v3_v3v3(size, max, min);
- copy_v3_v3(sds->cell_size, size);
+ if (init_resolution) {
+ zero_v3_int(sds->base_res);
+ copy_v3_v3(sds->cell_size, size);
+ }
mul_v3_v3(size, ob->size);
copy_v3_v3(sds->global_size, size);
copy_v3_v3(sds->dp0, min);
@@ -254,18 +257,18 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *
invert_m4_m4(sds->imat, ob->obmat);
// prevent crash when initializing a plane as domain
- if ((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
+ if (!init_resolution || (size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
return;
/* define grid resolutions from longest domain side */
- if (size[0] > MAX2(size[1], size[2])) {
+ if (size[0] >= MAX2(size[1], size[2])) {
scale = res / size[0];
sds->scale = size[0] / ob->size[0];
sds->base_res[0] = res;
sds->base_res[1] = (int)(size[1] * scale + 0.5f);
sds->base_res[2] = (int)(size[2] * scale + 0.5f);
}
- else if (size[1] > MAX2(size[0], size[2])) {
+ else if (size[1] >= MAX2(size[0], size[2])) {
scale = res / size[1];
sds->scale = size[1] / ob->size[1];
sds->base_res[0] = (int)(size[0] * scale + 0.5f);
@@ -293,7 +296,7 @@ static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene,
SmokeDomainSettings *sds = smd->domain;
int res[3];
/* set domain dimensions from derivedmesh */
- smoke_set_domain_from_derivedmesh(sds, ob, dm);
+ smoke_set_domain_from_derivedmesh(sds, ob, dm, TRUE);
/* reset domain values */
zero_v3_int(sds->shift);
zero_v3(sds->shift_f);
@@ -924,7 +927,8 @@ static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3]
}
}
-static void em_allocateData(EmissionMap *em, int use_velocity) {
+static void em_allocateData(EmissionMap *em, int use_velocity)
+{
int i, res[3];
for (i = 0; i < 3; i++) {
@@ -941,7 +945,8 @@ static void em_allocateData(EmissionMap *em, int use_velocity) {
em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity");
}
-static void em_freeData(EmissionMap *em) {
+static void em_freeData(EmissionMap *em)
+{
if (em->influence)
MEM_freeN(em->influence);
if (em->velocity)
@@ -1058,7 +1063,7 @@ static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres)
int result_type;
/* no node textures for now */
- result_type = multitex_ext_safe(texture, tex_co, texres);
+ result_type = multitex_ext_safe(texture, tex_co, texres, NULL);
/* 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.
@@ -1578,7 +1583,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
}
/* set fire reaction coordinate */
- if (fuel && fuel[index]) {
+ 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);
@@ -1586,6 +1591,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
if (value > react[index]) {
float f = fuel_flow / fuel[index];
react[index] = value * f + (1.0f - f) * react[index];
+ CLAMP(react[index], 0.0f, value);
}
}
}
@@ -1982,7 +1988,7 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *
/* update object state */
invert_m4_m4(sds->imat, ob->obmat);
copy_m4_m4(sds->obmat, ob->obmat);
- smoke_set_domain_from_derivedmesh(sds, ob, domain_dm);
+ smoke_set_domain_from_derivedmesh(sds, ob, domain_dm, (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN));
/* use global gravity if enabled */
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
@@ -2405,7 +2411,7 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene)
bv[3] = (float)sds->res[1]; // y
bv[5] = (float)sds->res[2]; // z
-// #pragma omp parallel for schedule(static,1)
+// #pragma omp parallel for schedule(static, 1)
for (z = 0; z < sds->res[2]; z++)
{
size_t index = z * slabsize;
@@ -2509,7 +2515,8 @@ float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity
return -1.0f;
}
-int smoke_get_data_flags(SmokeDomainSettings *sds) {
+int smoke_get_data_flags(SmokeDomainSettings *sds)
+{
int flags = 0;
if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT;
if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE;
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index bb0cfe1a5c6..e2c6df5e528 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1097,12 +1097,12 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
float facedist, outerfacethickness, tune = 10.f;
int a, deflected=0;
- aabbmin[0] = MIN3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmin[1] = MIN3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmin[2] = MIN3(face_v1[2], face_v2[2], face_v3[2]);
- aabbmax[0] = MAX3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmax[1] = MAX3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmax[2] = MAX3(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
/* calculate face normal once again SIGH */
sub_v3_v3v3(edge1, face_v1, face_v2);
@@ -1196,12 +1196,12 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
float t, tune = 10.0f;
int a, deflected=0;
- aabbmin[0] = MIN3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmin[1] = MIN3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmin[2] = MIN3(face_v1[2], face_v2[2], face_v3[2]);
- aabbmax[0] = MAX3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmax[1] = MAX3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmax[2] = MAX3(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
@@ -1957,7 +1957,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
closest_to_line_segment_v3(ve, opco, nv2, nv3);
- 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);
@@ -1966,7 +1966,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
closest_to_line_segment_v3(ve, opco, nv3, nv1);
- 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);
@@ -4108,18 +4108,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
softbody_reset(ob, sb, vertexCos, numVerts);
}
- /* continue physics special case */
- if (BKE_ptcache_get_continue_physics()) {
- BKE_ptcache_invalidate(cache);
- /* do simulation */
- dtime = timescale;
- softbody_update_positions(ob, sb, vertexCos, numVerts);
- softbody_step(scene, ob, sb, dtime);
- softbody_to_object(ob, vertexCos, numVerts, 0);
- sb->last_frame = framenr;
- return;
- }
-
/* still no points? go away */
if (sb->totpoint==0) {
return;
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index 09440591826..f3391803294 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -35,7 +35,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BKE_animsys.h"
#include "BKE_global.h"
@@ -43,11 +42,11 @@
#include "BKE_main.h"
#include "BKE_speaker.h"
-void *BKE_speaker_add(const char *name)
+void *BKE_speaker_add(Main *bmain, const char *name)
{
Speaker *spk;
- spk = BKE_libblock_alloc(&G.main->speaker, ID_SPK, name);
+ spk = BKE_libblock_alloc(&bmain->speaker, ID_SPK, name);
spk->attenuation = 1.0f;
spk->cone_angle_inner = 360.0f;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index be8b572417e..e03100280d6 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -50,8 +50,8 @@
#include "BLI_edgehash.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
@@ -1013,7 +1013,11 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
mf->flag = faceFlags[i].flag;
mf->mat_nr = faceFlags[i].mat_nr;
}
- else mf->flag = ME_SMOOTH;
+ else {
+ mf->flag = ME_SMOOTH;
+ }
+
+ mf->edcode = 0;
}
/* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes
@@ -1093,6 +1097,14 @@ void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly,
}
}
+/* utility functon */
+BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
+{
+ copy_v3_v3(mv->co, CCG_elem_co(key, elem));
+ normal_float_to_short_v3(mv->no, CCG_elem_no(key, elem));
+ mv->flag = mv->bweight = 0;
+}
+
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
@@ -1103,7 +1115,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
int totvert, totedge, totface;
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int i = 0;
+ unsigned int i = 0;
CCG_key_top_level(&key, ss);
@@ -1113,24 +1125,20 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
vd = ccgSubSurf_getFaceCenterData(f);
- copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
- i++;
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
for (S = 0; S < numVerts; S++) {
- for (x = 1; x < gridSize - 1; x++, i++) {
+ for (x = 1; x < gridSize - 1; x++) {
vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
- copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
}
}
for (S = 0; S < numVerts; S++) {
for (y = 1; y < gridSize - 1; y++) {
- for (x = 1; x < gridSize - 1; x++, i++) {
+ for (x = 1; x < gridSize - 1; x++) {
vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
- copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
}
}
}
@@ -1141,15 +1149,14 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
CCGEdge *e = ccgdm->edgeMap[index].edge;
int x;
- for (x = 1; x < edgeSize - 1; x++, i++) {
- vd = ccgSubSurf_getEdgeData(ss, e, x);
- copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
+ for (x = 1; x < edgeSize - 1; x++) {
/* This gives errors with -debug-fpe
* the normals don't seem to be unit length.
* this is most likely caused by edges with no
* faces which are now zerod out, see comment in:
* ccgSubSurf__calcVertNormals(), - campbell */
- normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
+ vd = ccgSubSurf_getEdgeData(ss, e, x);
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
}
}
@@ -1158,12 +1165,20 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
CCGVert *v = ccgdm->vertMap[index].vert;
vd = ccgSubSurf_getVertData(ss, v);
- copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd));
- normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd));
- i++;
+ ccgDM_to_MVert(&mvert[i++], &key, vd);
}
}
+
+/* utility functon */
+BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
+{
+ med->v1 = v1;
+ med->v2 = v2;
+ med->crease = med->bweight = 0;
+ med->flag = flag;
+}
+
static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
@@ -1172,8 +1187,9 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
int totedge, totface;
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int i = 0;
+ unsigned int i = 0;
short *edgeFlags = ccgdm->edgeFlags;
+ const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
totface = ccgSubSurf_getNumFaces(ss);
for (index = 0; index < totface; index++) {
@@ -1182,36 +1198,22 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
for (S = 0; S < numVerts; S++) {
for (x = 0; x < gridSize - 1; x++) {
- MEdge *med = &medge[i];
-
- if (ccgdm->drawInteriorEdges)
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
- med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
- med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
- i++;
+ ccgDM_to_MEdge(&medge[i++],
+ getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
+ getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
+ ed_interior_flag);
}
for (x = 1; x < gridSize - 1; x++) {
for (y = 0; y < gridSize - 1; y++) {
- MEdge *med;
-
- med = &medge[i];
- if (ccgdm->drawInteriorEdges)
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
- med->v1 = getFaceIndex(ss, f, S, x, y,
- edgeSize, gridSize);
- med->v2 = getFaceIndex(ss, f, S, x, y + 1,
- edgeSize, gridSize);
- i++;
-
- med = &medge[i];
- if (ccgdm->drawInteriorEdges)
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
- med->v1 = getFaceIndex(ss, f, S, y, x,
- edgeSize, gridSize);
- med->v2 = getFaceIndex(ss, f, S, y + 1, x,
- edgeSize, gridSize);
- i++;
+ ccgDM_to_MEdge(&medge[i++],
+ getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
+ getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
+ ed_interior_flag);
+ ccgDM_to_MEdge(&medge[i++],
+ getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
+ getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
+ ed_interior_flag);
}
}
}
@@ -1220,27 +1222,28 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
totedge = ccgSubSurf_getNumEdges(ss);
for (index = 0; index < totedge; index++) {
CCGEdge *e = ccgdm->edgeMap[index].edge;
- unsigned int flags = 0;
+ short ed_flag = 0;
int x;
int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
- if (!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
+ if (!ccgSubSurf_getEdgeNumFaces(e)) {
+ ed_flag |= ME_LOOSEEDGE;
+ }
if (edgeFlags) {
if (edgeIdx != -1) {
- flags |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
+ ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
}
}
else {
- flags |= ME_EDGEDRAW | ME_EDGERENDER;
+ ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
}
for (x = 0; x < edgeSize - 1; x++) {
- MEdge *med = &medge[i];
- med->v1 = getEdgeIndex(ss, e, x, edgeSize);
- med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
- med->flag = flags;
- i++;
+ ccgDM_to_MEdge(&medge[i++],
+ getEdgeIndex(ss, e, x, edgeSize),
+ getEdgeIndex(ss, e, x + 1, edgeSize),
+ ed_flag);
}
}
}
@@ -1278,6 +1281,7 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
edgeSize, gridSize);
mf->mat_nr = mat_nr;
mf->flag = flag;
+ mf->edcode = 0;
i++;
}
@@ -1314,8 +1318,8 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
for (index = 0; index < totface; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
- /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
- /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
+ /* int flag = (faceFlags) ? faceFlags[index * 2]: ME_SMOOTH; */ /* UNUSED */
+ /* int mat_nr = (faceFlags) ? faceFlags[index * 2 + 1]: 0; */ /* UNUSED */
for (S = 0; S < numVerts; S++) {
for (y = 0; y < gridSize - 1; y++) {
@@ -1569,7 +1573,7 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
CCGFace **faces;
int totface;
- BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
+ BKE_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
if (totface) {
ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
@@ -1707,7 +1711,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
if (dm->numTessFaceData) {
- BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, setMaterial);
+ BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
+ setMaterial, FALSE);
glShadeModel(GL_FLAT);
}
@@ -3025,7 +3030,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
* when the ccgdm gets remade, the assumption is that the topology
* does not change. */
ccgdm_create_grids(dm);
- BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
+ BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
ccgdm->gridFlagMats, ccgdm->gridHidden);
}
@@ -3043,15 +3048,15 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
numGrids = ccgDM_getNumGrids(dm);
- ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
- BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
+ BKE_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
}
else if (ob->type == OB_MESH) {
Mesh *me = ob->data;
- ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */
- BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
+ BKE_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
me->totface, me->totvert, &me->vdata);
}
@@ -3319,7 +3324,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
/*I think this is for interpolating the center vert?*/
- w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
+ w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
numVerts, vertNum);
if (vertOrigIndex) {
diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c
index ff9774f85af..6f9736df683 100644
--- a/source/blender/blenkernel/intern/suggestions.c
+++ b/source/blender/blenkernel/intern/suggestions.c
@@ -163,13 +163,13 @@ void texttool_suggest_add(const char *name, char type)
suggestions.top = 0;
}
-void texttool_suggest_prefix(const char *prefix)
+void texttool_suggest_prefix(const char *prefix, const int prefix_len)
{
SuggItem *match, *first, *last;
- int cmp, len = strlen(prefix), top = 0;
+ int cmp, top = 0;
if (!suggestions.first) return;
- if (len == 0) {
+ if (prefix_len == 0) {
suggestions.selected = suggestions.firstmatch = suggestions.first;
suggestions.lastmatch = suggestions.last;
return;
@@ -177,7 +177,7 @@ void texttool_suggest_prefix(const char *prefix)
first = last = NULL;
for (match = suggestions.first; match; match = match->next) {
- cmp = txttl_cmp(prefix, match->name, len);
+ cmp = txttl_cmp(prefix, match->name, prefix_len);
if (cmp == 0) {
if (!first) {
first = match;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 322b77e0462..74c0a76f82d 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -38,12 +38,12 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_string_cursor_utf8.h"
#include "BLI_string_utf8.h"
#include "BLI_listbase.h"
-#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "DNA_constraint_types.h"
@@ -171,9 +171,8 @@ void BKE_text_free(Text *text)
#endif
}
-Text *BKE_text_add(const char *name)
+Text *BKE_text_add(Main *bmain, const char *name)
{
- Main *bmain = G.main;
Text *ta;
TextLine *tmp;
@@ -363,9 +362,8 @@ int BKE_text_reload(Text *text)
return 1;
}
-Text *BKE_text_load(const char *file, const char *relpath)
+Text *BKE_text_load(Main *bmain, const char *file, const char *relpath)
{
- Main *bmain = G.main;
FILE *fp;
int i, llen, len;
unsigned char *buffer;
@@ -938,7 +936,7 @@ void txt_move_right(Text *text, short sel)
if (!sel) txt_pop_sel(text);
}
-void txt_jump_left(Text *text, short sel)
+void txt_jump_left(Text *text, bool sel, bool use_init_step)
{
TextLine **linep;
int *charp;
@@ -950,12 +948,12 @@ void txt_jump_left(Text *text, short sel)
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_PREV,
- STRCUR_JUMP_DELIM);
+ STRCUR_JUMP_DELIM, use_init_step);
if (!sel) txt_pop_sel(text);
}
-void txt_jump_right(Text *text, short sel)
+void txt_jump_right(Text *text, bool sel, bool use_init_step)
{
TextLine **linep;
int *charp;
@@ -967,7 +965,7 @@ void txt_jump_right(Text *text, short sel)
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_NEXT,
- STRCUR_JUMP_DELIM);
+ STRCUR_JUMP_DELIM, use_init_step);
if (!sel) txt_pop_sel(text);
}
@@ -2404,7 +2402,7 @@ void txt_delete_char(Text *text)
void txt_delete_word(Text *text)
{
- txt_jump_right(text, 1);
+ txt_jump_right(text, true, true);
txt_delete_sel(text);
}
@@ -2453,7 +2451,7 @@ void txt_backspace_char(Text *text)
void txt_backspace_word(Text *text)
{
- txt_jump_left(text, 1);
+ txt_jump_left(text, true, true);
txt_delete_sel(text);
}
@@ -2930,9 +2928,46 @@ int text_check_identifier(const char ch)
return 0;
}
+int 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;
+}
+
+#ifndef WITH_PYTHON
+int text_check_identifier_unicode(const unsigned int ch)
+{
+ return (ch < 255 && text_check_identifier((char)ch));
+}
+
+int text_check_identifier_nodigit_unicode(const unsigned int ch)
+{
+ return (ch < 255 && text_check_identifier_nodigit((char)ch));
+}
+#endif /* WITH_PYTHON */
+
int text_check_whitespace(const char ch)
{
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
return 1;
return 0;
}
+
+int text_find_identifier_start(const char *str, int i)
+{
+ if (UNLIKELY(i <= 0)) {
+ return 0;
+ }
+
+ while (i--) {
+ if (!text_check_identifier(str[i])) {
+ break;
+ }
+ }
+ i++;
+ return i;
+}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 6d0313f6334..55a0f3752a1 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -42,7 +42,6 @@
#include "BLI_math.h"
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "DNA_key_types.h"
#include "DNA_object_types.h"
@@ -441,7 +440,7 @@ void default_tex(Tex *tex)
tex->type = TEX_CLOUDS;
tex->stype = 0;
tex->flag = TEX_CHECKER_ODD;
- tex->imaflag = TEX_INTERPOL | TEX_MIPMAP | TEX_USEALPHA;
+ tex->imaflag = TEX_INTERPOL | TEX_MIPMAP;
tex->extend = TEX_REPEAT;
tex->cropxmin = tex->cropymin = 0.0;
tex->cropxmax = tex->cropymax = 1.0;
@@ -541,9 +540,8 @@ void tex_set_type(Tex *tex, int type)
/* ------------------------------------------------------------------------- */
-Tex *add_texture(const char *name)
+Tex *add_texture(Main *bmain, const char *name)
{
- Main *bmain = G.main;
Tex *tex;
tex = BKE_libblock_alloc(&bmain->tex, ID_TE, name);
@@ -616,6 +614,7 @@ void default_mtex(MTex *mtex)
mtex->gravityfac = 1.0f;
mtex->fieldfac = 1.0f;
mtex->normapspace = MTEX_NSPACE_TANGENT;
+ mtex->brush_map_mode = MTEX_MAP_MODE_TILED;
}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 5e8ef23e000..f625f5c8526 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -141,8 +141,10 @@ static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
}
BLI_freelistN(&dopesheet->channels);
+ BLI_freelistN(&dopesheet->coverage_segments);
dopesheet->channels.first = dopesheet->channels.last = NULL;
+ dopesheet->coverage_segments.first = dopesheet->coverage_segments.last = NULL;
dopesheet->tot_channel = 0;
}
@@ -169,8 +171,9 @@ void BKE_tracking_settings_init(MovieTracking *tracking)
tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION;
tracking->settings.default_minimum_correlation = 0.75;
- tracking->settings.default_pattern_size = 11;
+ tracking->settings.default_pattern_size = 15;
tracking->settings.default_search_size = 61;
+ tracking->settings.default_algorithm_flag |= TRACK_ALGORITHM_FLAG_USE_BRUTE;
tracking->settings.dist = 1;
tracking->settings.object_distance = 1;
tracking->settings.reconstruction_success_threshold = 1e-3;
@@ -1625,6 +1628,67 @@ ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int cali
calibration_height, overscan, FALSE);
}
+void BKE_tracking_max_undistortion_delta_across_bound(MovieTracking *tracking, rcti *rect, float delta[2])
+{
+ int a;
+ float pos[2], warped_pos[2];
+ const int coord_delta = 5;
+
+ delta[0] = delta[1] = -FLT_MAX;
+
+ for (a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) {
+ if (a > rect->xmax)
+ a = rect->xmax;
+
+ /* bottom edge */
+ pos[0] = a;
+ pos[1] = rect->ymin;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ /* top edge */
+ pos[0] = a;
+ pos[1] = rect->ymax;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ if (a >= rect->xmax)
+ break;
+ }
+
+ for (a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) {
+ if (a > rect->ymax)
+ a = rect->ymax;
+
+ /* left edge */
+ pos[0] = rect->xmin;
+ pos[1] = a;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ /* right edge */
+ pos[0] = rect->xmax;
+ pos[1] = a;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ if (a >= rect->ymax)
+ break;
+ }
+}
+
/*********************** Image sampling *************************/
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
@@ -1681,7 +1745,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
/* real sampling requires libmv, but areas are supposing pattern would be
* sampled if search area does exists, so we'll need to create empty
* pattern area here to prevent adding NULL-checks all over just to deal
- * with situation when lubmv is disabled
+ * with situation when libmv is disabled
*/
(void) frame_width;
@@ -3506,15 +3570,15 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf
BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat);
invert_m4(mat);
- if (filter == TRACKING_FILTER_NEAREAST)
- interpolation = neareast_interpolation;
+ if (filter == TRACKING_FILTER_NEAREST)
+ interpolation = nearest_interpolation;
else if (filter == TRACKING_FILTER_BILINEAR)
interpolation = bilinear_interpolation;
else if (filter == TRACKING_FILTER_BICUBIC)
interpolation = bicubic_interpolation;
else
/* fallback to default interpolation method */
- interpolation = neareast_interpolation;
+ interpolation = nearest_interpolation;
for (j = 0; j < tmpibuf->y; j++) {
for (i = 0; i < tmpibuf->x; i++) {
@@ -3766,6 +3830,88 @@ static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, in
}
}
+static int coverage_from_count(int count)
+{
+ if (count < 8)
+ return TRACKING_COVERAGE_BAD;
+ else if (count < 16)
+ return TRACKING_COVERAGE_ACCEPTABLE;
+ return TRACKING_COVERAGE_OK;
+}
+
+static void tracking_dopesheet_calc_coverage(MovieTracking *tracking)
+{
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+ ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+ MovieTrackingTrack *track;
+ int frames, start_frame = INT_MAX, end_frame = -INT_MAX;
+ int *per_frame_counter;
+ int prev_coverage, last_segment_frame;
+ int i;
+
+ /* find frame boundaries */
+ for (track = tracksbase->first; track; track = track->next) {
+ start_frame = min_ii(start_frame, track->markers[0].framenr);
+ end_frame = max_ii(end_frame, track->markers[track->markersnr - 1].framenr);
+ }
+
+ frames = end_frame - start_frame + 1;
+
+ /* this is a per-frame counter of markers (how many markers belongs to the same frame) */
+ per_frame_counter = MEM_callocN(sizeof(int) * frames, "per frame track counter");
+
+ /* find per-frame markers count */
+ for (track = tracksbase->first; track; track = track->next) {
+ int i;
+
+ for (i = 0; i < track->markersnr; i++) {
+ MovieTrackingMarker *marker = &track->markers[i];
+
+ /* TODO: perhaps we need to add check for non-single-frame track here */
+ if ((marker->flag & MARKER_DISABLED) == 0)
+ per_frame_counter[marker->framenr - start_frame]++;
+ }
+ }
+
+ /* convert markers count to coverage and detect segments with the same coverage */
+ prev_coverage = coverage_from_count(per_frame_counter[0]);
+ last_segment_frame = start_frame;
+
+ /* means only disabled tracks in the beginning, could be ignored */
+ if (!per_frame_counter[0])
+ prev_coverage = TRACKING_COVERAGE_OK;
+
+ for (i = 1; i < frames; i++) {
+ int coverage = coverage_from_count(per_frame_counter[i]);
+
+ /* means only disabled tracks in the end, could be ignored */
+ if (i == frames - 1 && !per_frame_counter[i])
+ coverage = TRACKING_COVERAGE_OK;
+
+ if (coverage != prev_coverage || i == frames - 1) {
+ MovieTrackingDopesheetCoverageSegment *coverage_segment;
+ int end_segment_frame = i - 1 + start_frame;
+
+ if (end_segment_frame == last_segment_frame)
+ end_segment_frame++;
+
+ coverage_segment = MEM_callocN(sizeof(MovieTrackingDopesheetCoverageSegment), "tracking coverage segment");
+ coverage_segment->coverage = prev_coverage;
+ coverage_segment->start_frame = last_segment_frame;
+ coverage_segment->end_frame = end_segment_frame;
+
+ BLI_addtail(&dopesheet->coverage_segments, coverage_segment);
+
+ last_segment_frame = end_segment_frame;
+ }
+
+ prev_coverage = coverage;
+ }
+
+ MEM_freeN(per_frame_counter);
+}
+
void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
{
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
@@ -3793,6 +3939,7 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking)
reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
+ /* channels */
for (track = tracksbase->first; track; track = track->next) {
MovieTrackingDopesheetChannel *channel;
@@ -3820,5 +3967,8 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking)
tracking_dopesheet_sort(tracking, sort_method, inverse);
+ /* frame coverage */
+ tracking_dopesheet_calc_coverage(tracking);
+
dopesheet->ok = TRUE;
}
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 84e1f29f6c0..dd6ed42bd92 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -142,7 +142,7 @@ static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0,
/* Areas */
static struct bUnitDef buMetricAreaDef[] = {
{"square kilometer", "square kilometers", "km²", "km2", "Square Kilometers", UN_SC_KM * UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
- {"square hectometer", "square hectometers", "hm²", "hm2", "Square Hectometers", UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_NONE}, /* hectare */
+ {"square hectometer", "square hectometers", "hm²", "hm2", "Square Hectometers", UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS}, /* hectare */
{"square dekameter", "square dekameters", "dam²", "dam2", "Square Dekameters", UN_SC_DAM * UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS}, /* are */
{"square meter", "square meters", "m²", "m2", "Square Meters", UN_SC_M * UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"square decimeter", "square decimetees", "dm²", "dm2", "Square Decimeters", UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
@@ -168,7 +168,7 @@ static struct bUnitCollection buImperialAreaCollecton = {buImperialAreaDef, 4, 0
/* Volumes */
static struct bUnitDef buMetricVolDef[] = {
{"cubic kilometer", "cubic kilometers", "km³", "km3", "Cubic Kilometers", UN_SC_KM * UN_SC_KM * UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
- {"cubic hectometer", "cubic hectometers", "hm³", "hm3", "Cubic Hectometers", UN_SC_HM * UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_NONE},
+ {"cubic hectometer", "cubic hectometers", "hm³", "hm3", "Cubic Hectometers", UN_SC_HM * UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
{"cubic dekameter", "cubic dekameters", "dam³", "dam3", "Cubic Dekameters", UN_SC_DAM * UN_SC_DAM * UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS},
{"cubic meter", "cubic meters", "m³", "m3", "Cubic Meters", UN_SC_M * UN_SC_M * UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"cubic decimeter", "cubic decimeters", "dm³", "dm3", "Cubic Decimeters", UN_SC_DM * UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
@@ -194,9 +194,9 @@ static struct bUnitCollection buImperialVolCollecton = {buImperialVolDef, 4, 0,
/* Mass */
static struct bUnitDef buMetricMassDef[] = {
{"ton", "tonnes", "ton", "t", "1000 Kilograms", UN_SC_MTON, 0.0, B_UNIT_DEF_NONE},
- {"quintal", "quintals", "ql", "q", "100 Kilograms", UN_SC_QL, 0.0, B_UNIT_DEF_NONE},
+ {"quintal", "quintals", "ql", "q", "100 Kilograms", UN_SC_QL, 0.0, B_UNIT_DEF_SUPPRESS},
{"kilogram", "kilograms", "kg", NULL, "Kilograms", UN_SC_KG, 0.0, B_UNIT_DEF_NONE}, /* base unit */
- {"hectogram", "hectograms", "hg", NULL, "Hectograms", UN_SC_HG, 0.0, B_UNIT_DEF_NONE},
+ {"hectogram", "hectograms", "hg", NULL, "Hectograms", UN_SC_HG, 0.0, B_UNIT_DEF_SUPPRESS},
{"dekagram", "dekagrams", "dag", NULL, "10 Grams", UN_SC_DAG, 0.0, B_UNIT_DEF_SUPPRESS},
{"gram", "grams", "g", NULL, "Grams", UN_SC_G, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 4bde895cf7d..206f829eaa8 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -40,7 +40,6 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BKE_animsys.h"
#include "BKE_global.h"
@@ -80,9 +79,8 @@ void BKE_world_free(World *wrld)
BKE_world_free_ex(wrld, TRUE);
}
-World *add_world(const char *name)
+World *add_world(Main *bmain, const char *name)
{
- Main *bmain = G.main;
World *wrld;
wrld = BKE_libblock_alloc(&bmain->world, ID_WO, name);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 0f861a7ed37..7e51025883d 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -373,7 +373,7 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
{
char name[128];
char *param;
- const AVOption *rv = NULL;
+ int fail = TRUE;
PRINT("FFMPEG expert option: %s: ", prop->name);
@@ -388,30 +388,30 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
switch (prop->type) {
case IDP_STRING:
PRINT("%s.\n", IDP_String(prop));
- av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
+ fail = av_opt_set(c, prop->name, IDP_String(prop), 0);
break;
case IDP_FLOAT:
PRINT("%g.\n", IDP_Float(prop));
- rv = av_set_double(c, prop->name, IDP_Float(prop));
+ fail = av_opt_set_double(c, prop->name, IDP_Float(prop), 0);
break;
case IDP_INT:
PRINT("%d.\n", IDP_Int(prop));
if (param) {
if (IDP_Int(prop)) {
- av_set_string3(c, name, param, 1, &rv);
+ fail = av_opt_set(c, name, param, 0);
}
else {
return;
}
}
else {
- rv = av_set_int(c, prop->name, IDP_Int(prop));
+ fail = av_opt_set_int(c, prop->name, IDP_Int(prop), 0);
}
break;
}
- if (!rv) {
+ if (fail) {
PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name);
}
}
@@ -464,8 +464,9 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
error[0] = '\0';
- st = av_new_stream(of, 0);
+ st = avformat_new_stream(of, NULL);
if (!st) return NULL;
+ st->id = 0;
/* Set up the codec context */
@@ -497,8 +498,15 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->rc_max_rate = rd->ffcodecdata.rc_max_rate * 1000;
c->rc_min_rate = rd->ffcodecdata.rc_min_rate * 1000;
c->rc_buffer_size = rd->ffcodecdata.rc_buffer_size * 1024;
+
+#if 0
+ /* this options are not set in ffmpeg.c and leads to artifacts with MPEG-4
+ * see #33586: Encoding to mpeg4 makes first frame(s) blocky
+ */
c->rc_initial_buffer_occupancy = rd->ffcodecdata.rc_buffer_size * 3 / 4;
c->rc_buffer_aggressivity = 1.0;
+#endif
+
c->me_method = ME_EPZS;
codec = avcodec_find_encoder(c->codec_id);
@@ -534,16 +542,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
}
if (codec_id == CODEC_ID_FFV1) {
-#ifdef FFMPEG_FFV1_ALPHA_SUPPORTED
- if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
- c->pix_fmt = PIX_FMT_RGB32;
- }
- else {
- c->pix_fmt = PIX_FMT_BGR0;
- }
-#else
c->pix_fmt = PIX_FMT_RGB32;
-#endif
}
if (codec_id == CODEC_ID_QTRLE) {
@@ -575,7 +574,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
set_ffmpeg_properties(rd, c, "video");
- if (avcodec_open(c, codec) < 0) {
+ if (avcodec_open2(c, codec, NULL) < 0) {
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
return NULL;
}
@@ -612,8 +611,9 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
error[0] = '\0';
- st = av_new_stream(of, 1);
+ st = avformat_new_stream(of, NULL);
if (!st) return NULL;
+ st->id = 1;
c = st->codec;
c->codec_id = codec_id;
@@ -635,7 +635,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
set_ffmpeg_properties(rd, c, "audio");
- if (avcodec_open(c, codec) < 0) {
+ if (avcodec_open2(c, codec, NULL) < 0) {
//XXX error("Couldn't initialize audio codec");
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
return NULL;
@@ -1144,7 +1144,7 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
val.i = 0;
- avcodec_get_context_defaults(&c);
+ avcodec_get_context_defaults3(&c, NULL);
o = c.av_class->option + opt_index;
parent = c.av_class->option + parent_index;
@@ -1175,23 +1175,23 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
}
switch (o->type) {
- case FF_OPT_TYPE_INT:
- case FF_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_INT:
+ case AV_OPT_TYPE_INT64:
val.i = FFMPEG_DEF_OPT_VAL_INT(o);
idp_type = IDP_INT;
break;
- case FF_OPT_TYPE_DOUBLE:
- case FF_OPT_TYPE_FLOAT:
+ case AV_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_FLOAT:
val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o);
idp_type = IDP_FLOAT;
break;
- case FF_OPT_TYPE_STRING:
+ case AV_OPT_TYPE_STRING:
val.string.str = (char *)" ";
val.string.len = 80;
/* val.str = (char *)" ";*/
idp_type = IDP_STRING;
break;
- case FF_OPT_TYPE_CONST:
+ case AV_OPT_TYPE_CONST:
val.i = 1;
idp_type = IDP_INT;
break;
@@ -1231,7 +1231,7 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
char *param;
IDProperty *prop = NULL;
- avcodec_get_context_defaults(&c);
+ avcodec_get_context_defaults3(&c, NULL);
strncpy(name_, str, sizeof(name_));
@@ -1252,10 +1252,10 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
if (!o) {
return 0;
}
- if (param && o->type == FF_OPT_TYPE_CONST) {
+ if (param && o->type == AV_OPT_TYPE_CONST) {
return 0;
}
- if (param && o->type != FF_OPT_TYPE_CONST && o->unit) {
+ if (param && o->type != AV_OPT_TYPE_CONST && o->unit) {
p = my_av_find_opt(&c, param, o->unit, 0, 0);
if (p) {
prop = BKE_ffmpeg_property_add(rd, (char *) type, p - c.av_class->option, o - c.av_class->option);
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index a21778307c1..0ba0f138c28 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -25,53 +25,19 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#ifndef __BLI_ARRAY_H__
+#define __BLI_ARRAY_H__
+
/** \file BLI_array.h
* \ingroup bli
- * \brief A macro array library.
- *
- * this library needs to be changed to not use macros quite so heavily,
- * and to be more of a complete array API. The way arrays are
- * exposed to client code as normal C arrays is very useful though, imho.
- * it does require some use of macros, however.
- *
- * anyway, it's used a bit too heavily to simply rewrite as a
- * more "correct" solution without macros entirely. I originally wrote this
- * to be very easy to use, without the normal pain of most array libraries.
- * This was especially helpful when it came to the massive refactors necessary
- * for bmesh, and really helped to speed the process up. - joeedh
- *
- * little array macro library. example of usage:
- *
- * int *arr = NULL;
- * BLI_array_declare(arr);
- * int i;
- *
- * for (i = 0; i < 10; i++) {
- * BLI_array_grow_one(arr);
- * arr[i] = something;
- * }
- * BLI_array_free(arr);
- *
- * arrays are buffered, using double-buffering (so on each reallocation,
- * the array size is doubled). supposedly this should give good Big Oh
- * behavior, though it may not be the best in practice.
+ * \brief A (mainly) macro array library.
*/
-#define BLI_array_declare(arr) \
- int _##arr##_count = 0; \
- void *_##arr##_tmp; \
- void *_##arr##_static = NULL
-
-/* 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; \
- void *_##arr##_tmp; \
- char _##arr##_static[maxstatic * sizeof(arr)]
-
+/* -------------------------------------------------------------------- */
+/* internal defines */
/* this returns the entire size of the array, including any buffering. */
-#define BLI_array_totalsize_dyn(arr) ( \
+#define _bli_array_totalsize_dynamic(arr) ( \
((arr) == NULL) ? \
0 : \
MEM_allocN_len(arr) / sizeof(*arr) \
@@ -80,55 +46,61 @@
#define _bli_array_totalsize_static(arr) \
(sizeof(_##arr##_static) / sizeof(*arr))
-#define BLI_array_totalsize(arr) ( \
+#define _bli_array_totalsize(arr) ( \
(size_t) \
(((void *)(arr) == (void *)_##arr##_static && (void *)(arr) != NULL) ? \
_bli_array_totalsize_static(arr) : \
- BLI_array_totalsize_dyn(arr)) \
+ _bli_array_totalsize_dynamic(arr)) \
)
+/* BLI_array.c
+ *
+ * Doing the realloc in a macro isn't so simple,
+ * so use a function the macros can use.
+ */
+void _bli_array_grow_func(void **arr_p, const void *arr_static,
+ const int sizeof_arr_p, const int arr_count, const int num,
+ const char *alloc_str);
+
+
+/* -------------------------------------------------------------------- */
+/* public defines */
+
+#define BLI_array_declare(arr) \
+ int _##arr##_count = 0; \
+ void *_##arr##_static = NULL
+
+/* 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. */
#define BLI_array_count(arr) _##arr##_count
-/* Grow the array by a fixed number of items. zeroes the new elements.
+/* Grow the array by a fixed number of items.
*
* Allow for a large 'num' value when the new size is more then double
* to allocate the exact sized array. */
-
-/* grow an array by a specified number of items */
-#define BLI_array_grow_items(arr, num) ( \
+#define BLI_array_grow_items(arr, num) (( \
(((void *)(arr) == NULL) && \
((void *)(_##arr##_static) != NULL) && \
- /* dont add _##arr##_count below because it must be zero */ \
+ /* don't add _##arr##_count below because it must be zero */ \
(_bli_array_totalsize_static(arr) >= _##arr##_count + num)) ? \
/* we have an empty array and a static var big enough */ \
- ((arr = (void *)_##arr##_static), (_##arr##_count += (num))) \
+ (arr = (void *)_##arr##_static) \
: \
/* use existing static array or allocate */ \
- ((BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
- (_##arr##_count += num) : \
- ( \
- (void) (_##arr##_tmp = MEM_callocN( \
- sizeof(*arr) * (num < _##arr##_count ? \
- (_##arr##_count * 2 + 2) : \
- (_##arr##_count + num)), \
- #arr " " __FILE__ ":" STRINGIFY(__LINE__) \
- ) \
- ), \
- (void) (arr && memcpy(_##arr##_tmp, \
- arr, \
- sizeof(*arr) * _##arr##_count) \
- ), \
- (void) (arr && ((void *)(arr) != (void *)_##arr##_static ? \
- (MEM_freeN(arr), arr) : \
- arr) \
- ), \
- (void) (arr = _##arr##_tmp \
- ), \
- (_##arr##_count += num) \
- )) \
-)
+ (LIKELY(_bli_array_totalsize(arr) >= _##arr##_count + num) ? \
+ (void)0 /* do nothing */ : \
+ _bli_array_grow_func((void **)&(arr), _##arr##_static, \
+ sizeof(*arr), _##arr##_count, num, \
+ "BLI_array." #arr), \
+ (void)0) /* msvc2008 needs this */ \
+ ), \
+ /* increment the array count, all conditions above are accounted for. */ \
+ (_##arr##_count += num))
/* returns length of array */
#define BLI_array_grow_one(arr) BLI_array_grow_items(arr, 1)
@@ -167,20 +139,23 @@
/* 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
+ { _##arr##_count = 0; } (void)0
/* 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_length_set(arr, count) \
- _##arr##_count = (count); (void)0
+ { _##arr##_count = (count); }(void)0
/* only to prevent unused warnings */
#define BLI_array_fake_user(arr) \
(void)_##arr##_count, \
- (void)_##arr##_tmp, \
(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()
* but use when the max size is known ahead of time */
@@ -196,3 +171,32 @@
if (_##arr##_is_static) { \
MEM_freeN(arr); \
} (void)0
+
+
+/* alloca */
+#ifdef _MSC_VER
+# define alloca _alloca
+#endif
+
+#if defined(__MINGW32__)
+# include <malloc.h> /* mingw needs for alloca() */
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define BLI_array_alloca(arr, realsize) \
+ (typeof(arr))alloca(sizeof(*arr) * (realsize))
+
+#define BLI_array_alloca_and_count(arr, realsize) \
+ (typeof(arr))alloca(sizeof(*arr) * (realsize)); \
+ const int _##arr##_count = (realsize)
+
+#else
+#define BLI_array_alloca(arr, realsize) \
+ alloca(sizeof(*arr) * (realsize))
+
+#define BLI_array_alloca_and_count(arr, realsize) \
+ alloca(sizeof(*arr) * (realsize)); \
+ const int _##arr##_count = (realsize)
+#endif
+
+#endif /* __BLI_ARRAY_H__ */
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
new file mode 100644
index 00000000000..880a97acb80
--- /dev/null
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -0,0 +1,90 @@
+/*
+ * ***** 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_BUFFER_H__
+#define __BLI_BUFFER_H__
+
+/* Note: this more or less fills same purpose as BLI_array, but makes
+ * it much easier to resize the array outside of the function it was
+ * declared in since */
+
+/* Usage examples:
+ *
+ * {
+ * BLI_buffer_declare_static(int, my_int_array, BLI_BUFFER_NOP, 32);
+ *
+ * BLI_buffer_append(my_int_array, int, 42);
+ * assert(my_int_array.count == 1);
+ * assert(BLI_buffer_at(my_int_array, int, 0) == 42);
+ *
+ * BLI_buffer_free(&my_int_array);
+ * }
+ */
+
+typedef struct {
+ void *data;
+ const int elem_size;
+ int count, alloc_count;
+ int flag;
+} BLI_Buffer;
+
+enum {
+ BLI_BUFFER_NOP = 0,
+ BLI_BUFFER_USE_STATIC = (1 << 0),
+ BLI_BUFFER_USE_CALLOC = (1 << 1), /* ensure the array is always calloc'd */
+};
+
+#define BLI_buffer_declare_static(type_, name_, flag_, static_count_) \
+ type_ *name_ ## _static_[static_count_]; \
+ BLI_Buffer name_ = { \
+ /* clear the static memory if this is a calloc'd array */ \
+ ((void)((flag_ & BLI_BUFFER_USE_CALLOC) ? \
+ memset(name_ ## _static_, 0, sizeof(name_ ## _static_)) : 0\
+ ), /* memset-end */ \
+ name_ ## _static_), \
+ sizeof(type_), \
+ 0, \
+ static_count_, \
+ BLI_BUFFER_USE_STATIC | flag_}
+
+/* never use static*/
+#define BLI_buffer_declare(type_, name_, flag_) \
+ BLI_Buffer name_ = {NULL, \
+ sizeof(type_), \
+ 0, \
+ 0, \
+ flag_}
+
+
+#define BLI_buffer_at(buffer_, type_, index_) ( \
+ (((type_ *)(buffer_)->data)[(BLI_assert(sizeof(type_) == (buffer_)->elem_size)), index_]))
+
+#define BLI_buffer_append(buffer_, type_, val_) ( \
+ BLI_buffer_resize(buffer_, (buffer_)->count + 1), \
+ (BLI_buffer_at(buffer_, type_, (buffer_)->count - 1) = val_) \
+)
+
+/* Never decreases the amount of memory allocated */
+void BLI_buffer_resize(BLI_Buffer *buffer, int new_count);
+
+/* Does not free the buffer structure itself */
+void BLI_buffer_free(BLI_Buffer *buffer);
+
+#endif /* __BLI_BUFFER_H__ */
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 1330a74bea3..54cd687eeac 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -32,6 +32,7 @@
* \ingroup bli
*/
+#include "BLI_utildefines.h"
#include "DNA_listBase.h"
//struct ListBase;
//struct LinkData;
@@ -40,8 +41,7 @@
extern "C" {
#endif
-void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);
-int BLI_findindex(const struct ListBase *listbase, void *vlink);
+int BLI_findindex(const struct ListBase *listbase, const void *vlink);
int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset);
/* find forwards */
@@ -59,7 +59,7 @@ void *BLI_rfindptr(const struct ListBase *listbase, const void *ptr, const int o
void BLI_freelistN(struct ListBase *listbase);
void BLI_addtail(struct ListBase *listbase, void *vlink);
void BLI_remlink(struct ListBase *listbase, void *vlink);
-int BLI_remlink_safe(struct ListBase *listbase, void *vlink);
+bool BLI_remlink_safe(struct ListBase *listbase, void *vlink);
void BLI_addhead(struct ListBase *listbase, void *vlink);
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink);
@@ -79,4 +79,4 @@ struct LinkData *BLI_genericNodeN(void *data);
}
#endif
-#endif
+#endif /* __BLI_LISTBASE_H__ */
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 69d6478e0e2..aa4e697b48b 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -80,6 +80,9 @@
#define MAXFLOAT ((float)3.40282347e+38)
#endif
+/* do not redefine functions from C99 or POSIX.1-2001 */
+#if !(defined(_ISOC99_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L))
+
#ifndef sqrtf
#define sqrtf(a) ((float)sqrt(a))
#endif
@@ -129,6 +132,8 @@
#define hypotf(a, b) ((float)hypot(a, b))
#endif
+#endif /* C99 or POSIX.1-2001 */
+
#ifdef WIN32
# ifndef FREE_WINDOWS
# define isnan(n) _isnan(n)
@@ -212,5 +217,26 @@ extern double round(double x);
double double_round(double x, int ndigits);
-#endif /* __BLI_MATH_BASE_H__ */
+/* asserts, some math functions expect normalized inputs
+ * check the vector is unit length, or zero length (which can't be helped in some cases).
+ */
+#ifdef DEBUG
+/* note: 0.0001 is too small becaues normals may be converted from short's: see [#34322] */
+# define BLI_ASSERT_UNIT_EPSILON 0.0002f
+# define BLI_ASSERT_UNIT_V3(v) { \
+ const float _test_unit = len_squared_v3(v); \
+ BLI_assert((fabsf(_test_unit - 1.0f) < BLI_ASSERT_UNIT_EPSILON) || \
+ (fabsf(_test_unit) < BLI_ASSERT_UNIT_EPSILON)); \
+} (void)0
+# define BLI_ASSERT_UNIT_V2(v) { \
+ const float _test_unit = len_squared_v2(v); \
+ BLI_assert((fabsf(_test_unit - 1.0f) < BLI_ASSERT_UNIT_EPSILON) || \
+ (fabsf(_test_unit) < BLI_ASSERT_UNIT_EPSILON)); \
+} (void)0
+#else
+# define BLI_ASSERT_UNIT_V2(v) (void)0
+# define BLI_ASSERT_UNIT_V3(v) (void)0
+#endif
+
+#endif /* __BLI_MATH_BASE_H__ */
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index c71463da61d..145427ea529 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -100,6 +100,15 @@ MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[
void BLI_init_srgb_conversion(void);
+/**************** Alpha Transformations *****************/
+
+MINLINE void premul_to_straight_v4_v4(float straight[4], const float premul[4]);
+MINLINE void premul_to_straight_v4(float color[4]);
+MINLINE void straight_to_premul_v4_v4(float straight[4], const float premul[4]);
+MINLINE void straight_to_premul_v4(float color[4]);
+MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4]);
+MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4]);
+
/************************** Other *************************/
int constrain_rgb(float *r, float *g, float *b);
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index cfd163d4e57..c4e17b1ed48 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -51,8 +51,10 @@ float normal_quad_v3(float r[3], const float a[3], const float b[3], const float
float area_tri_v2(const float a[2], const float b[2], const float c[2]);
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_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_poly_v3(int nr, float verts[][3], const float normal[3]);
+float area_poly_v2(int nr, float verts[][2]);
int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
@@ -67,11 +69,15 @@ void closest_to_line_segment_v2(float closest[2], const float p[2], const float
float dist_to_plane_normalized_v3(const float p[3], const float plane_co[3], const float plane_no_unit[3]);
float dist_to_plane_v3(const float p[3], const float plane_co[3], const float plane_no[3]);
float dist_to_line_segment_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 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[3], const float p[3], const float l1[3], const float l2[3]);
void closest_to_plane_v3(float r[3], const float plane_co[3], const float plane_no_unit[3], const float pt[3]);
+/* Set 'r' to the point in triangle (t1, t2, t3) closest to point 'p' */
+void closest_on_tri_to_point_v3(float r[3], const float p[3], const float t1[3], const float t2[3], const float t3[3]);
+
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3]);
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]);
@@ -126,7 +132,7 @@ int isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
/* point in polygon */
int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
-int isect_point_tri_v2(const float v1[2], const float v2[2], const float v3[2], const float pt[2]);
+int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
int isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
@@ -202,7 +208,7 @@ void perspective_m4(float mat[4][4], const float left, const float right,
const float bottom, const float top, const float nearClip, const float farClip);
void orthographic_m4(float mat[4][4], const float left, const float right,
const float bottom, const float top, const float nearClip, const float farClip);
-void window_translate_m4(float winmat[][4], float perspmat[][4],
+void window_translate_m4(float winmat[4][4], float perspmat[4][4],
const float x, const float y);
int box_clip_bounds_m4(float boundbox[2][3],
@@ -257,11 +263,19 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f);
float form_factor_hemi_poly(float p[3], float n[3],
float v1[3], float v2[3], float v3[3], float v4[3]);
-void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]);
+bool axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]);
+void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]);
+float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+#endif
+;
MINLINE int max_axis_v3(const float vec[3]);
MINLINE int min_axis_v3(const float vec[3]);
+MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index f51bd1cf840..97cd6a60862 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -88,13 +88,15 @@ void mul_serie_m4(float R[4][4],
void mul_m4_v3(float M[4][4], float r[3]);
void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]);
+void mul_v2_m2v2(float r[2], float M[2][2], const float v[2]);
void mul_mat3_m4_v3(float M[4][4], float r[3]);
void mul_m4_v4(float M[4][4], float r[4]);
-void mul_v4_m4v4(float r[4], float M[4][4], float v[4]);
+void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
void mul_project_m4_v3(float M[4][4], float vec[3]);
void mul_m3_v3(float M[3][3], float r[3]);
-void mul_v3_m3v3(float r[3], float M[3][3], float a[3]);
+void mul_v3_m3v3(float r[3], float M[3][3], const float a[3]);
+void mul_v2_m3v3(float r[2], float M[3][3], const float a[3]);
void mul_transposed_m3_v3(float M[3][3], float r[3]);
void mul_m3_v3_double(float M[3][3], double r[3]);
@@ -144,10 +146,14 @@ float determinant_m2(float a, float b,
float determinant_m3(float a, float b, float c,
float d, float e, float f,
float g, float h, float i);
+float determinant_m3_array(float m[3][3]);
float determinant_m4(float A[4][4]);
+#define PSEUDOINVERSE_EPSILON 1e-8f
+
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_m3_m3(float Ainv[3][3], float A[3][3], float epsilon);
/****************************** Transformations ******************************/
@@ -165,10 +171,13 @@ void mat4_to_size(float r[3], float M[4][4]);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], const char axis, const float angle);
+void rotate_m2(float mat[2][2], const float angle);
-void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[][3]);
-void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]);
+void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
+void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]);
+void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4]);
void loc_eul_size_to_mat4(float R[4][4],
const float loc[3], const float eul[3], const float size[3]);
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index 652925fbe49..5ba37d70ca5 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -186,6 +186,11 @@ float fov_to_focallength(float fov, float sensor);
float angle_wrap_rad(float angle);
float angle_wrap_deg(float angle);
+float angle_compat_rad(float angle, float angle_compat);
+
+int mat3_from_axis_conversion(int from_forward, int from_up, int to_forward, int to_up,
+ float r_mat[3][3]);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index f4572afec84..42a6b90f738 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -171,6 +171,10 @@ 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 flip_v4_v4v4(float v[4], const float v1[4], const float v2[4]);
+void flip_v3_v3v3(float v[3], const float v1[3], const float v2[3]);
+void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]);
+
/********************************* Comparison ********************************/
MINLINE int is_zero_v3(const float a[3]);
@@ -251,6 +255,7 @@ void sub_vn_vn(float *array_tar, const float *array_src, const int size);
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size);
void msub_vn_vn(float *array_tar, const float *array_src, const float f, const int size);
void msub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const float f, const int size);
+void interp_vn_vn(float *array_tar, const float *array_src, const float t, const int size);
void fill_vn_i(int *array_tar, const int size, const int val);
void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val);
void fill_vn_fl(float *array_tar, const int size, const float val);
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index 8fd2166e6f8..a1cbad73239 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -86,6 +86,18 @@ __attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
;
+void BLI_mempool_as_array(BLI_mempool *pool, void **data)
+#ifdef __GNUC__
+__attribute__((nonnull(1)))
+#endif
+;
+
+void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+__attribute__((nonnull(1, 2)))
+#endif
+;
/** iteration stuff. note: this may easy to produce bugs with **/
/* private structure */
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 5e47adf25ef..8c51c925d97 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -67,6 +67,8 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check);
#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"
@@ -118,7 +120,11 @@ int BLI_split_name_num(char *left, int *nr, const char *name, const char delim);
void BLI_splitdirstring(char *di, char *fi);
/* make sure path separators conform to system one */
-void BLI_clean(char *path);
+void BLI_clean(char *path)
+#ifdef __GNUC__
+__attribute__((nonnull(1)))
+#endif
+;
/**
* dir can be any input, like from buttons, and this function
@@ -171,7 +177,11 @@ int BLI_path_is_rel(const char *path);
* \a from The character to replace
* \a to The character to replace with
*/
-void BLI_char_switch(char *string, char from, char to);
+void BLI_char_switch(char *string, char from, char to)
+#ifdef __GNUC__
+__attribute__((nonnull(1)))
+#endif
+;
/* Initialize path to program executable */
void BLI_init_program_path(const char *argv0);
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index f2e26093711..3c9363039b2 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -56,6 +56,8 @@ void BLI_rctf_translate(struct rctf *rect, float x, float y);
void BLI_rcti_translate(struct rcti *rect, int x, int y);
void BLI_rcti_resize(struct rcti *rect, int x, int y);
void BLI_rctf_resize(struct rctf *rect, float x, float y);
+void BLI_rcti_scale(rcti *rect, const float scale);
+void BLI_rctf_scale(rctf *rect, const float scale);
void BLI_rctf_interp(struct rctf *rect, const struct rctf *rect_a, const struct rctf *rect_b, const float fac);
//void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac);
int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]);
diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h
index c8fd72bbbd2..ce2c6a4252f 100644
--- a/source/blender/blenlib/BLI_scanfill.h
+++ b/source/blender/blenlib/BLI_scanfill.h
@@ -72,7 +72,8 @@ typedef struct ScanFillVert {
float xy[2]; /* 2D copy of vertex location (using dominant axis) */
unsigned int keyindex; /* original index #, for restoring key information */
short poly_nr;
- unsigned char f, h;
+ unsigned char edge_tot; /* number of edges using this vertex */
+ unsigned char f;
} ScanFillVert;
typedef struct ScanFillEdge {
@@ -101,6 +102,10 @@ enum {
* Assumes ordered edges, otherwise we risk an eternal loop
* removing double verts. - campbell */
BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1),
+
+ /* note: This flag removes checks for overlapping polygons.
+ * when this flag is set, we'll never get back more faces then (totvert - 2) */
+ BLI_SCANFILL_CALC_HOLES = (1 << 2)
};
int BLI_scanfill_begin(ScanFillContext *sf_ctx);
diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h
index 3c38c0380e0..04d9df2abda 100644
--- a/source/blender/blenlib/BLI_string_cursor_utf8.h
+++ b/source/blender/blenlib/BLI_string_cursor_utf8.h
@@ -46,6 +46,6 @@ int BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, int *pos);
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
int *pos, strCursorJumpDirection direction,
- strCursorJumpType jump);
+ strCursorJumpType jump, bool use_init_step);
#endif /* __BLI_STRING_CURSOR_UTF8_H__ */
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index ecbc4cb1cd4..30d5c28bf98 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -41,6 +41,7 @@ int BLI_str_utf8_size_safe(const char *p);
/* copied from glib */
unsigned int BLI_str_utf8_as_unicode(const char *p);
unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index);
+unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index);
unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index);
size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf);
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 7c3b70545d6..95ad786c7c2 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -32,12 +32,45 @@
* \ingroup bli
*/
-#ifndef FALSE
-# define FALSE 0
+#ifndef NDEBUG /* for BLI_assert */
+#include <stdio.h>
#endif
-#ifndef TRUE
-# define TRUE 1
+/* note: use of (int, TRUE / FALSE) is deprecated,
+ * use (bool, true / false) instead */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# ifndef HAVE__BOOL
+# ifdef __cplusplus
+typedef bool _BLI_Bool;
+# else
+/* using char here may cause nasty tricky bugs, e.g.
+ * bool is_bit_flag = RNA_property_flag(prop) & PROP_ENUM_FLAG;
+ * as PROP_ENUM_FLAG is farther than 8th bit, do_translate would be always false!
+ */
+# define _BLI_Bool unsigned int
+# endif
+# else
+# define _BLI_Bool _Bool
+# endif
+# define bool _BLI_Bool
+# define false 0
+# define true 1
+# define __bool_true_false_are_defined 1
+#endif
+
+/* remove this when we're ready to remove TRUE/FALSE completely */
+#ifdef WITH_BOOL_COMPAT
+/* interim until all occurrences of these can be updated to stdbool */
+/* XXX Why not use the true/false velues here? */
+# ifndef FALSE
+# define FALSE 0
+# endif
+
+# ifndef TRUE
+# define TRUE 1
+# endif
#endif
/* useful for finding bad use of min/max */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 8a3b1c9675b..e5851109d87 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -25,9 +25,7 @@
set(INC
.
- ../blenkernel
- ../blenloader
- ../gpu
+ # ../blenkernel # dont add this back!
../makesdna
../../../intern/ghost
../../../intern/guardedalloc
@@ -40,6 +38,7 @@ set(INC_SYS
set(SRC
intern/BLI_args.c
+ intern/BLI_array.c
intern/BLI_dynstr.c
intern/BLI_ghash.c
intern/BLI_heap.c
@@ -50,7 +49,7 @@ set(SRC
intern/BLI_mempool.c
intern/DLRB_tree.c
intern/boxpack2d.c
- intern/bpath.c
+ intern/buffer.c
intern/callbacks.c
intern/cpu.c
intern/dynlib.c
@@ -78,7 +77,6 @@ set(SRC
intern/md5.c
intern/noise.c
intern/path_util.c
- intern/pbvh.c
intern/quadric.c
intern/rand.c
intern/rct.c
@@ -100,8 +98,8 @@ set(SRC
BLI_array.h
BLI_bitmap.h
BLI_blenlib.h
+ BLI_buffer.h
BLI_boxpack2d.h
- BLI_bpath.h
BLI_callbacks.h
BLI_cpu.h
BLI_dlrbTree.h
@@ -137,7 +135,6 @@ set(SRC
BLI_mempool.h
BLI_noise.h
BLI_path_util.h
- BLI_pbvh.h
BLI_quadric.h
BLI_rand.h
BLI_rect.h
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index e53f622a5c4..2be06f7311d 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -1,11 +1,37 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
cflags=''
-incs = '. ../makesdna ../blenkernel #/intern/guardedalloc #/intern/ghost ../editors/include ../gpu ../blenloader'
-incs += ' ../windowmanager ../bmesh #/extern/glew/include'
+# don't add ../blenkernel back!
+incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost'
incs += ' ' + env['BF_FREETYPE_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/source/blender/blenlib/intern/BLI_array.c b/source/blender/blenlib/intern/BLI_array.c
new file mode 100644
index 00000000000..5823b7db3f1
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_array.c
@@ -0,0 +1,97 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joseph Eagar,
+ * Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenlib/intern/BLI_array.c
+ * \ingroup bli
+ * \brief A (mainly) macro array library.
+ *
+ * This library needs to be changed to not use macros quite so heavily,
+ * and to be more of a complete array API. The way arrays are
+ * exposed to client code as normal C arrays is very useful though, imho.
+ * it does require some use of macros, however.
+ *
+ * anyway, it's used a bit too heavily to simply rewrite as a
+ * more "correct" solution without macros entirely. I originally wrote this
+ * to be very easy to use, without the normal pain of most array libraries.
+ * This was especially helpful when it came to the massive refactors necessary
+ * for bmesh, and really helped to speed the process up. - joeedh
+ *
+ * little array macro library. example of usage:
+ *
+ * int *arr = NULL;
+ * BLI_array_declare(arr);
+ * int i;
+ *
+ * for (i = 0; i < 10; i++) {
+ * BLI_array_grow_one(arr);
+ * arr[i] = something;
+ * }
+ * BLI_array_free(arr);
+ *
+ * arrays are buffered, using double-buffering (so on each reallocation,
+ * the array size is doubled). supposedly this should give good Big Oh
+ * behavior, though it may not be the best in practice.
+ */
+
+#include <string.h>
+
+#include "BLI_array.h"
+
+#include "MEM_guardedalloc.h"
+
+/**
+ * This function is only to be called via macros.
+ *
+ * \note The caller must adjust \a arr_count
+ */
+void _bli_array_grow_func(void **arr_p, const void *arr_static,
+ const int sizeof_arr_p, const int arr_count, const int num,
+ const char *alloc_str)
+{
+ void *arr = *arr_p;
+ void *arr_tmp;
+
+ arr_tmp = MEM_mallocN(sizeof_arr_p *
+ ((num < arr_count) ?
+ (arr_count * 2 + 2) : (arr_count + num)), alloc_str);
+
+ if (arr) {
+ memcpy(arr_tmp, arr, sizeof_arr_p * arr_count);
+
+ if (arr != arr_static) {
+ MEM_freeN(arr);
+ }
+ }
+
+ *arr_p = arr_tmp;
+
+ /* caller must do */
+#if 0
+ arr_count += num;
+#endif
+}
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index c4094920c2a..7ebe4430e20 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -39,7 +39,7 @@
#include "BLI_mempool.h"
#include "BLI_ghash.h"
-#include "BLO_sys_types.h" // for intptr_t support
+#include "MEM_sys_types.h" /* for intptr_t support */
/***/
unsigned int hashsizes[] = {
@@ -78,9 +78,9 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val)
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
Entry *e = (Entry *)BLI_mempool_alloc(gh->entrypool);
+ e->next = gh->buckets[hash];
e->key = key;
e->val = val;
- e->next = gh->buckets[hash];
gh->buckets[hash] = e;
if (++gh->nentries > (float)gh->nbuckets / 2) {
@@ -109,13 +109,13 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val)
void *BLI_ghash_lookup(GHash *gh, const void *key)
{
- if (gh) {
- unsigned int hash = gh->hashfp(key) % gh->nbuckets;
- Entry *e;
+ const unsigned int hash = gh->hashfp(key) % gh->nbuckets;
+ Entry *e;
- for (e = gh->buckets[hash]; e; e = e->next)
- if (gh->cmpfp(key, e->key) == 0)
- return e->val;
+ for (e = gh->buckets[hash]; e; e = e->next) {
+ if (gh->cmpfp(key, e->key) == 0) {
+ return e->val;
+ }
}
return NULL;
}
@@ -312,17 +312,25 @@ int BLI_ghashutil_intcmp(const void *a, const void *b)
return (a < b) ? -1 : 1;
}
+/**
+ * This function implements the widely used "djb" hash apparently posted
+ * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit
+ * unsigned hash value starts at 5381 and for each byte 'c' in the
+ * string, is updated: <literal>hash = hash * 33 + c</literal>. This
+ * function uses the signed value of each byte.
+ *
+ * note: this is the same hash method that glib 2.34.0 uses.
+ */
unsigned int BLI_ghashutil_strhash(const void *ptr)
{
- const char *s = ptr;
- unsigned int i = 0;
- unsigned char c;
+ const signed char *p;
+ unsigned int h = 5381;
- while ((c = *s++)) {
- i = i * 37 + c;
+ for (p = ptr; *p != '\0'; p++) {
+ h = (h << 5) + h + *p;
}
- return i;
+ return h;
}
int BLI_ghashutil_strcmp(const void *a, const void *b)
{
@@ -376,4 +384,3 @@ void BLI_ghashutil_pairfree(void *ptr)
{
MEM_freeN((void *)ptr);
}
-
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index dcc028630e2..aa54969b6f8 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -167,7 +167,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
heap->freenodes = (HeapNode *)(((HeapNode *)heap->freenodes)->ptr);
}
else {
- node = (HeapNode *)BLI_memarena_alloc(heap->arena, sizeof *node);
+ node = (HeapNode *)BLI_memarena_alloc(heap->arena, sizeof(*node));
}
node->value = value;
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 6cf167b8823..b2d07b9ee4d 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -1237,7 +1237,7 @@ static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node)
#define DEFAULT_FIND_NEAREST_HEAP_SIZE 1024
-#define NodeDistance_priority(a, b) ( (a).dist < (b).dist)
+#define NodeDistance_priority(a, b) ((a).dist < (b).dist)
static void NodeDistance_push_heap(NodeDistance *heap, int heap_size)
PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size)
@@ -1554,7 +1554,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], f
float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3])
{
BVHRayCastData data;
- float dist = 0.0;
+ float dist;
data.hit.dist = FLT_MAX;
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index d98e63d88dd..5f0c90f234d 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -27,9 +27,7 @@
/** \file blender/blenlib/intern/BLI_mempool.c
* \ingroup bli
- */
-
-/*
+ *
* Simple, fast memory allocator for allocating many elements of the same size.
*/
@@ -56,6 +54,9 @@
#define FREEWORD MAKE_ID('f', 'r', 'e', 'e')
+/* currently totalloc isnt used */
+// #define USE_TOTALLOC
+
typedef struct BLI_freenode {
struct BLI_freenode *next;
int freeword; /* used to identify this as a freed node */
@@ -112,6 +113,7 @@ BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag)
pool->pchunk = pchunk;
pool->csize = esize * pchunk;
pool->chunks.first = pool->chunks.last = NULL;
+ pool->totalloc = 0;
pool->totused = 0;
maxchunks = totelem / pchunk + 1;
@@ -161,10 +163,11 @@ BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag)
}
}
- /* set the end of this chunks memoryy to the new tail for next iteration */
+ /* set the end of this chunks memory to the new tail for next iteration */
lasttail = curnode;
-
+#ifdef USE_TOTALLOC
pool->totalloc += pool->pchunk;
+#endif
}
/* terminate the list */
curnode->next = NULL;
@@ -215,8 +218,9 @@ void *BLI_mempool_alloc(BLI_mempool *pool)
}
}
curnode->next = NULL; /* terminate the list */
-
+#ifdef USE_TOTALLOC
pool->totalloc += pool->pchunk;
+#endif
}
retval = pool->free;
@@ -237,12 +241,20 @@ void *BLI_mempool_calloc(BLI_mempool *pool)
return retval;
}
-/* doesnt protect against double frees, don't be stupid! */
+/**
+ * Free an element from the mempool.
+ *
+ * \note doesnt protect against double frees, don't be stupid!
+ */
void BLI_mempool_free(BLI_mempool *pool, void *addr)
{
BLI_freenode *newhead = addr;
if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
+#ifndef NDEBUG
+ /* this will detect double free's */
+ BLI_assert(newhead->freeword != FREEWORD);
+#endif
newhead->freeword = FREEWORD;
}
@@ -276,7 +288,9 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
}
BLI_addtail(&pool->chunks, first);
+#ifdef USE_TOTALLOC
pool->totalloc = pool->pchunk;
+#endif
pool->free = first->data; /* start of the list */
for (tmpaddr = first->data, i = 0; i < pool->pchunk; i++) {
@@ -295,33 +309,51 @@ int BLI_mempool_count(BLI_mempool *pool)
void *BLI_mempool_findelem(BLI_mempool *pool, int index)
{
- if (!(pool->flag & BLI_MEMPOOL_ALLOW_ITER)) {
- fprintf(stderr, "%s: Error! you can't iterate over this mempool!\n", __func__);
- return NULL;
- }
- else if ((index >= 0) && (index < pool->totused)) {
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+
+ if ((index >= 0) && (index < pool->totused)) {
/* we could have some faster mem chunk stepping code inline */
BLI_mempool_iter iter;
void *elem;
BLI_mempool_iternew(pool, &iter);
for (elem = BLI_mempool_iterstep(&iter); index-- != 0; elem = BLI_mempool_iterstep(&iter)) {
/* do nothing */
- };
+ }
return elem;
}
return NULL;
}
-void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
+/**
+ * \param data array of pointers at least the size of 'pool->totused'
+ */
+void BLI_mempool_as_array(BLI_mempool *pool, void **data)
{
- if (!(pool->flag & BLI_MEMPOOL_ALLOW_ITER)) {
- fprintf(stderr, "%s: Error! you can't iterate over this mempool!\n", __func__);
- iter->curchunk = NULL;
- iter->curindex = 0;
-
- return;
+ BLI_mempool_iter iter;
+ void *elem;
+ void **p = data;
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+ BLI_mempool_iternew(pool, &iter);
+ for (elem = BLI_mempool_iterstep(&iter); elem; elem = BLI_mempool_iterstep(&iter)) {
+ *p++ = elem;
}
+ BLI_assert((p - data) == pool->totused);
+}
+
+/**
+ * Allocate an array from the mempool.
+ */
+void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
+{
+ void *data = MEM_mallocN(BLI_mempool_count(pool) * pool->esize, allocstr);
+ BLI_mempool_as_array(pool, data);
+ return data;
+}
+
+void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
+{
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
iter->pool = pool;
iter->curchunk = pool->chunks.first;
@@ -391,6 +423,9 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
#endif
+/**
+ * Free the mempool its self (and all elements).
+ */
void BLI_mempool_destroy(BLI_mempool *pool)
{
BLI_mempool_chunk *mpchunk = NULL;
diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c
new file mode 100644
index 00000000000..b2280b9a0d1
--- /dev/null
+++ b/source/blender/blenlib/intern/buffer.c
@@ -0,0 +1,81 @@
+/*
+ * ***** 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 *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_buffer.h"
+#include "BLI_utildefines.h"
+
+#include <string.h>
+
+static void *buffer_alloc(BLI_Buffer *buffer, int len)
+{
+ return ((buffer->flag & BLI_BUFFER_USE_CALLOC) ?
+ MEM_callocN : MEM_mallocN)
+ (buffer->elem_size * len, "BLI_Buffer.data");
+}
+
+static void *buffer_realloc(BLI_Buffer *buffer, int len)
+{
+ return ((buffer->flag & BLI_BUFFER_USE_CALLOC) ?
+ MEM_recallocN : MEM_reallocN)
+ (buffer->data, (buffer->elem_size * len));
+}
+
+void BLI_buffer_resize(BLI_Buffer *buffer, int new_count)
+{
+ if (new_count > buffer->alloc_count) {
+ if (buffer->flag & BLI_BUFFER_USE_STATIC) {
+ void *orig = buffer->data;
+
+ buffer->data = buffer_alloc(buffer, new_count);
+ memcpy(buffer->data, orig, buffer->elem_size * buffer->count);
+ buffer->alloc_count = new_count;
+ buffer->flag &= ~BLI_BUFFER_USE_STATIC;
+ }
+ else {
+ if (buffer->alloc_count && (new_count < buffer->alloc_count * 2)) {
+ buffer->alloc_count *= 2;
+ }
+ else {
+ buffer->alloc_count = new_count;
+ }
+
+ if (buffer->data) {
+ buffer->data = buffer_realloc(buffer, buffer->alloc_count);
+ }
+ else {
+ buffer->data = buffer_alloc(buffer, buffer->alloc_count);
+ }
+ }
+ }
+
+ buffer->count = new_count;
+}
+
+void BLI_buffer_free(BLI_Buffer *buffer)
+{
+ if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
+ if (buffer->data) {
+ MEM_freeN(buffer->data);
+ }
+ }
+ memset(buffer, 0, sizeof(*buffer));
+}
diff --git a/source/blender/blenlib/intern/endian_switch.c b/source/blender/blenlib/intern/endian_switch.c
index b9b18136863..e3ed88b6f8d 100644
--- a/source/blender/blenlib/intern/endian_switch.c
+++ b/source/blender/blenlib/intern/endian_switch.c
@@ -24,7 +24,7 @@
* \ingroup bli
*/
-#include "BLO_sys_types.h"
+#include "MEM_sys_types.h"
#include "BLI_utildefines.h"
#include "BLI_endian_switch.h"
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 883cdfde426..24b3c36a329 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -63,7 +63,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLO_sys_types.h" // for intptr_t support
+#include "MEM_sys_types.h" // for intptr_t support
/* gzip the file in from and write it to "to".
@@ -111,7 +111,7 @@ int BLI_file_gzip(const char *from, const char *to)
return rval;
}
-/* gzip the file in from_file and write it to memery to_mem, at most size bytes.
+/* gzip the file in from_file and write it to memory to_mem, at most size bytes.
* return the unziped size
*/
char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r)
@@ -283,7 +283,7 @@ int BLI_move(const char *file, const char *to)
{
int err;
- /* windows doesn't support moveing to a directory
+ /* windows doesn't support moving to a directory
* it has to be 'mv filename filename' and not
* 'mv filename destdir' */
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 0a87316aa81..353b73a6403 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -52,8 +52,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BKE_font.h"
-
#include "DNA_vfont_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_curve_types.h"
diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter.c
index 6203a98828b..3fe0ef158df 100644
--- a/source/blender/blenlib/intern/jitter.c
+++ b/source/blender/blenlib/intern/jitter.c
@@ -165,7 +165,7 @@ void BLI_jitter_init(float *jitarr, int num)
MEM_freeN(jit2);
- /* finally, move jittertab to be centered around (0,0) */
+ /* finally, move jittertab to be centered around (0, 0) */
for (i = 0; i < 2 * num; i += 2) {
jitarr[i] -= 0.5f;
jitarr[i + 1] -= 0.5f;
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 9f6f409c473..348efaf40a9 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -28,9 +28,10 @@
/** \file blender/blenlib/intern/listbase.c
* \ingroup bli
+ *
+ * Manipulations on ListBase structs
*/
-
#include <string.h>
#include <stdlib.h>
@@ -41,10 +42,11 @@
#include "BLI_listbase.h"
-
/* implementation */
-/* Ripped this from blender.c */
+/**
+ * moves the entire contents of \a src onto the end of \a dst.
+ */
void BLI_movelisttolist(ListBase *dst, ListBase *src)
{
if (src->first == NULL) return;
@@ -61,6 +63,9 @@ void BLI_movelisttolist(ListBase *dst, ListBase *src)
src->first = src->last = NULL;
}
+/**
+ * Prepends \a vlink (assumed to begin with a Link) onto listbase.
+ */
void BLI_addhead(ListBase *listbase, void *vlink)
{
Link *link = vlink;
@@ -77,6 +82,9 @@ void BLI_addhead(ListBase *listbase, void *vlink)
}
+/**
+ * Appends \a vlink (assumed to begin with a Link) onto listbase.
+ */
void BLI_addtail(ListBase *listbase, void *vlink)
{
Link *link = vlink;
@@ -93,6 +101,9 @@ void BLI_addtail(ListBase *listbase, void *vlink)
}
+/**
+ * Removes \a vlink from \a listbase. Assumes it is linked into there!
+ */
void BLI_remlink(ListBase *listbase, void *vlink)
{
Link *link = vlink;
@@ -107,18 +118,24 @@ void BLI_remlink(ListBase *listbase, void *vlink)
if (listbase->first == link) listbase->first = link->next;
}
-int BLI_remlink_safe(ListBase *listbase, void *vlink)
+/**
+ * Checks that \a vlink is linked into listbase, removing it from there if so.
+ */
+bool BLI_remlink_safe(ListBase *listbase, void *vlink)
{
if (BLI_findindex(listbase, vlink) != -1) {
BLI_remlink(listbase, vlink);
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
+/**
+ * Removes \a vlink from listbase and disposes of it. Assumes it is linked into there!
+ */
void BLI_freelinkN(ListBase *listbase, void *vlink)
{
Link *link = vlink;
@@ -131,43 +148,11 @@ void BLI_freelinkN(ListBase *listbase, void *vlink)
}
-void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink)
-{
- Link *prevlink = vprevlink;
- Link *newlink = vnewlink;
-
- /* newlink comes after prevlink */
- if (newlink == NULL) return;
- if (listbase == NULL) return;
-
- /* empty list */
- if (listbase->first == NULL) {
-
- listbase->first = newlink;
- listbase->last = newlink;
- return;
- }
-
- /* insert before first element */
- if (prevlink == NULL) {
- newlink->next = listbase->first;
- newlink->prev = NULL;
- newlink->next->prev = newlink;
- listbase->first = newlink;
- return;
- }
-
- /* at end of list */
- if (listbase->last == prevlink)
- listbase->last = newlink;
-
- newlink->next = prevlink->next;
- prevlink->next = newlink;
- if (newlink->next) newlink->next->prev = newlink;
- newlink->prev = prevlink;
-}
-
-/* This uses insertion sort, so NOT ok for large list */
+/**
+ * Sorts the elements of listbase into the order defined by cmp
+ * (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)(void *, void *))
{
Link *current = NULL;
@@ -193,6 +178,10 @@ void BLI_sortlist(ListBase *listbase, int (*cmp)(void *, void *))
}
}
+/**
+ * Inserts \a vnewlink immediately following \a vprevlink in \a listbase.
+ * Or, if \a vprevlink is NULL, puts \a vnewlink at the front of the list.
+ */
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
{
Link *prevlink = vprevlink;
@@ -213,21 +202,28 @@ void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
if (prevlink == NULL) {
newlink->prev = NULL;
newlink->next = listbase->first;
- ((Link *)listbase->first)->prev = newlink;
+ newlink->next->prev = newlink;
listbase->first = newlink;
return;
}
/* at end of list */
- if (listbase->last == prevlink)
+ if (listbase->last == prevlink) {
listbase->last = newlink;
+ }
newlink->next = prevlink->next;
newlink->prev = prevlink;
prevlink->next = newlink;
- if (newlink->next) newlink->next->prev = newlink;
+ if (newlink->next) {
+ newlink->next->prev = newlink;
+ }
}
+/**
+ * Inserts \a vnewlink immediately preceding \a vnextlink in listbase.
+ * Or, if \a vnextlink is NULL, puts \a vnewlink at the end of the list.
+ */
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
{
Link *nextlink = vnextlink;
@@ -254,16 +250,22 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
}
/* at beginning of list */
- if (listbase->first == nextlink)
+ if (listbase->first == nextlink) {
listbase->first = newlink;
+ }
newlink->next = nextlink;
newlink->prev = nextlink->prev;
nextlink->prev = newlink;
- if (newlink->prev) newlink->prev->next = newlink;
+ if (newlink->prev) {
+ newlink->prev->next = newlink;
+ }
}
+/**
+ * Removes and disposes of the entire contents of listbase using direct free(3).
+ */
void BLI_freelist(ListBase *listbase)
{
Link *link, *next;
@@ -282,6 +284,9 @@ void BLI_freelist(ListBase *listbase)
listbase->last = NULL;
}
+/**
+ * Removes and disposes of the entire contents of \a listbase using guardedalloc.
+ */
void BLI_freelistN(ListBase *listbase)
{
Link *link, *next;
@@ -300,6 +305,9 @@ void BLI_freelistN(ListBase *listbase)
}
+/**
+ * Returns the number of elements in \a listbase.
+ */
int BLI_countlist(const ListBase *listbase)
{
Link *link;
@@ -315,6 +323,9 @@ int BLI_countlist(const ListBase *listbase)
return count;
}
+/**
+ * Returns the nth element of \a listbase, numbering from 1.
+ */
void *BLI_findlink(const ListBase *listbase, int number)
{
Link *link = NULL;
@@ -330,6 +341,9 @@ void *BLI_findlink(const ListBase *listbase, int number)
return link;
}
+/**
+ * Returns the nth-last element of \a listbase, numbering from 1.
+ */
void *BLI_rfindlink(const ListBase *listbase, int number)
{
Link *link = NULL;
@@ -345,7 +359,10 @@ void *BLI_rfindlink(const ListBase *listbase, int number)
return link;
}
-int BLI_findindex(const ListBase *listbase, void *vlink)
+/**
+ * Returns the position of \a vlink within \a listbase, numbering from 1, or -1 if not found.
+ */
+int BLI_findindex(const ListBase *listbase, const void *vlink)
{
Link *link = NULL;
int number = 0;
@@ -365,6 +382,10 @@ int BLI_findindex(const ListBase *listbase, void *vlink)
return -1;
}
+/**
+ * Finds the first element of \a listbase which contains the null-terminated
+ * string \a id at the specified offset, returning NULL if not found.
+ */
void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
{
Link *link = NULL;
@@ -383,6 +404,10 @@ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
return NULL;
}
/* same as above but find reverse */
+/**
+ * Finds the last element of \a listbase which contains the
+ * null-terminated string \a id at the specified offset, returning NULL if not found.
+ */
void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset)
{
Link *link = NULL;
@@ -401,6 +426,10 @@ void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset
return NULL;
}
+/**
+ * Finds the first element of \a listbase which contains a pointer to the
+ * null-terminated string \a id at the specified offset, returning NULL if not found.
+ */
void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset)
{
Link *link = NULL;
@@ -420,6 +449,10 @@ void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int off
return NULL;
}
/* same as above but find reverse */
+/**
+ * Finds the last element of \a listbase which contains a pointer to the
+ * null-terminated string \a id at the specified offset, returning NULL if not found.
+ */
void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset)
{
Link *link = NULL;
@@ -440,6 +473,8 @@ void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int of
}
void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
+/* finds the first element of listbase which contains the specified pointer value
+at the specified offset, returning NULL if not found. */
{
Link *link = NULL;
const void *ptr_iter;
@@ -448,7 +483,7 @@ void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
for (link = listbase->first; link; link = link->next) {
/* exact copy of BLI_findstring(), except for this line */
- ptr_iter = *((const char **)(((const char *)link) + offset));
+ ptr_iter = *((const void **)(((const char *)link) + offset));
if (ptr == ptr_iter) {
return link;
@@ -459,6 +494,8 @@ void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
}
/* same as above but find reverse */
void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
+/* finds the last element of listbase which contains the specified pointer value
+at the specified offset, returning NULL if not found. */
{
Link *link = NULL;
const void *ptr_iter;
@@ -467,7 +504,7 @@ void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
for (link = listbase->last; link; link = link->prev) {
/* exact copy of BLI_rfindstring(), except for this line */
- ptr_iter = *((const char **)(((const char *)link) + offset));
+ ptr_iter = *((const void **)(((const char *)link) + offset));
if (ptr == ptr_iter) {
return link;
@@ -478,6 +515,8 @@ void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
}
int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset)
+/* returns the 1-based index of the first element of listbase which contains the specified
+null-terminated string at the specified offset, or -1 if not found. */
{
Link *link = NULL;
const char *id_iter;
@@ -499,6 +538,7 @@ int BLI_findstringindex(const ListBase *listbase, const char *id, const int offs
}
void BLI_duplicatelist(ListBase *dst, const ListBase *src)
+/* sets dst to a duplicate of the entire contents of src. dst may be the same as src. */
{
struct Link *dst_link, *src_link;
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index b9866f9c6e6..8eb6561003b 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -175,6 +175,42 @@ MINLINE int max_ii(int a, int b)
return (b < a) ? a : b;
}
+MINLINE float min_fff(float a, float b, float c)
+{
+ return min_ff(min_ff(a, b), c);
+}
+MINLINE float max_fff(float a, float b, float c)
+{
+ return max_ff(max_ff(a, b), c);
+}
+
+MINLINE int min_iii(int a, int b, int c)
+{
+ return min_ii(min_ii(a, b), c);
+}
+MINLINE int max_iii(int a, int b, int c)
+{
+ return max_ii(max_ii(a, b), c);
+}
+
+MINLINE float min_ffff(float a, float b, float c, float d)
+{
+ return min_ff(min_fff(a, b, c), d);
+}
+MINLINE float max_ffff(float a, float b, float c, float d)
+{
+ return max_ff(max_fff(a, b, c), d);
+}
+
+MINLINE int min_iiii(int a, int b, int c, int d)
+{
+ return min_ii(min_iii(a, b, c), d);
+}
+MINLINE int max_iiii(int a, int b, int c, int d)
+{
+ return max_ii(max_iii(a, b, c), d);
+}
+
MINLINE float signf(float f)
{
return (f < 0.f) ? -1.f : 1.f;
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 64851dbf12c..07cd85c4107 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -266,8 +266,8 @@ void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
{
- float cmax = MAX3(r, g, b);
- float cmin = MIN3(r, g, b);
+ const float cmax = max_fff(r, g, b);
+ const float cmin = min_fff(r, g, b);
float h, s, l = (cmax + cmin) / 2.0f;
if (cmax == cmin) {
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index 4c8bd43ef73..e9a1c0abc38 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -149,31 +149,6 @@ MINLINE void linearrgb_to_srgb_ushort4(unsigned short srgb[4], const float linea
srgb[3] = FTOUSHORT(linear[3]);
}
-MINLINE void linearrgb_to_srgb_ushort4_predivide(unsigned short srgb[4], const float linear[4])
-{
- float alpha, inv_alpha, t;
- int i;
-
- if (linear[3] == 1.0f || linear[3] == 0.0f) {
- linearrgb_to_srgb_ushort4(srgb, linear);
- return;
- }
-
- alpha = linear[3];
- inv_alpha = 1.0f / alpha;
-
- for (i = 0; i < 3; ++i) {
- t = linear[i] * inv_alpha;
- srgb[i] = (t <= 1.0f) ?
- /* warning - converts: float -> short -> float -> short */
- (unsigned short) (to_srgb_table_lookup(t) * alpha) :
- /* if FTOUSHORT was an inline function this could be done less confusingly */
- ((t = linearrgb_to_srgb(t) * alpha), FTOUSHORT(t));
- }
-
- srgb[3] = FTOUSHORT(linear[3]);
-}
-
MINLINE void srgb_to_linearrgb_uchar4(float linear[4], const unsigned char srgb[4])
{
linear[0] = BLI_color_from_srgb_table[srgb[0]];
@@ -199,7 +174,8 @@ MINLINE void srgb_to_linearrgb_uchar4_predivide(float linear[4], const unsigned
}
/* color macros for themes */
-#define rgba_char_args_set_fl(col, r, g, b, a) rgba_char_args_set(col, r * 255, g * 255, b * 255, a * 255)
+#define rgba_char_args_set_fl(col, r, g, b, a) \
+ rgba_char_args_set(col, (r) * 255, (g) * 255, (b) * 255, (a) * 255)
MINLINE void rgba_char_args_set(char col[4], const char r, const char g, const char b, const char a)
{
@@ -293,4 +269,72 @@ MINLINE int compare_rgb_uchar(const unsigned char col_a[3], const unsigned char
return 0;
}
+/**************** Alpha Transformations *****************/
+
+MINLINE void premul_to_straight_v4_v4(float straight[4], const float premul[4])
+{
+ if (premul[3] == 0.0f || premul[3] == 1.0f) {
+ straight[0] = premul[0];
+ straight[1] = premul[1];
+ straight[2] = premul[2];
+ straight[3] = premul[3];
+ }
+ else {
+ float alpha_inv = 1.0f / premul[3];
+ straight[0] = premul[0] * alpha_inv;
+ straight[1] = premul[1] * alpha_inv;
+ straight[2] = premul[2] * alpha_inv;
+ straight[3] = premul[3];
+ }
+}
+
+MINLINE void premul_to_straight_v4(float color[4])
+{
+ premul_to_straight_v4_v4(color, color);
+}
+
+MINLINE void straight_to_premul_v4_v4(float premul[4], const float straight[4])
+{
+ float alpha = straight[3];
+ premul[0] = straight[0] * alpha;
+ premul[1] = straight[1] * alpha;
+ premul[2] = straight[2] * alpha;
+ premul[3] = straight[3];
+}
+
+MINLINE void straight_to_premul_v4(float color[4])
+{
+ straight_to_premul_v4_v4(color, color);
+}
+
+MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4])
+{
+ float alpha = color[3] / 255.0f;
+ float fac = alpha / 255.0f;
+
+ result[0] = color[0] * fac;
+ result[1] = color[1] * fac;
+ result[2] = color[2] * fac;
+ result[3] = alpha;
+}
+
+MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4])
+{
+ if (color[3] == 0.0f || color[3] == 1.0f) {
+ result[0] = FTOCHAR(color[0]);
+ result[1] = FTOCHAR(color[1]);
+ result[2] = FTOCHAR(color[2]);
+ result[3] = FTOCHAR(color[3]);
+ }
+ else {
+ float alpha_inv = 1.0f / color[3];
+
+ /* hopefully this would be optimized */
+ result[0] = FTOCHAR(color[0] * alpha_inv);
+ result[1] = FTOCHAR(color[1] * alpha_inv);
+ result[2] = FTOCHAR(color[2] * alpha_inv);
+ result[3] = FTOCHAR(color[3]);
+ }
+}
+
#endif /* __MATH_COLOR_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 74abd7e8c7e..baca7bb8f8a 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -39,9 +39,9 @@
void cent_tri_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3])
{
- cent[0] = 0.33333f * (v1[0] + v2[0] + v3[0]);
- cent[1] = 0.33333f * (v1[1] + v2[1] + v3[1]);
- cent[2] = 0.33333f * (v1[2] + v2[2] + v3[2]);
+ cent[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
+ cent[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
+ cent[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
}
void cent_quad_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
@@ -129,35 +129,59 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
return (len / 2.0f);
}
+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];
+
+ sub_v3_v3v3(vec1, v3, v2);
+ sub_v3_v3v3(vec2, v1, v2);
+ cross_v3_v3v3(n, vec1, vec2);
+ area = len_v3(n) / 2.0f;
+
+ /* negate area for flipped triangles */
+ if (dot_v3v3(n, normal) < 0.0f)
+ area = -area;
+
+ return area;
+}
+
float area_poly_v3(int nr, float verts[][3], const float normal[3])
{
- float x, y, z, area, max;
- float *cur, *prev;
- int a, px = 0, py = 1;
+ int a, px, py;
+ const float max = axis_dominant_v3_max(&px, &py, normal);
+ float area;
+ float *co_curr, *co_prev;
- /* first: find dominant axis: 0==X, 1==Y, 2==Z
- * don't use 'axis_dominant_v3()' because we need max axis too */
- x = fabsf(normal[0]);
- y = fabsf(normal[1]);
- z = fabsf(normal[2]);
- max = MAX3(x, y, z);
- if (max == y) py = 2;
- else if (max == x) {
- px = 1;
- py = 2;
+ /* The Trapezium Area Rule */
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+ area = 0.0f;
+ for (a = 0; a < nr; a++) {
+ area += (co_curr[px] - co_prev[px]) * (co_curr[py] + co_prev[py]);
+ co_prev = verts[a];
+ co_curr = verts[a + 1];
}
+ return fabsf(0.5f * area / max);
+}
+
+float area_poly_v2(int nr, float verts[][2])
+{
+ int a;
+ float area;
+ float *co_curr, *co_prev;
+
/* The Trapezium Area Rule */
- prev = verts[nr - 1];
- cur = verts[0];
- area = 0;
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+ area = 0.0f;
for (a = 0; a < nr; a++) {
- area += (cur[px] - prev[px]) * (cur[py] + prev[py]);
- prev = verts[a];
- cur = verts[a + 1];
+ area += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]);
+ co_prev = verts[a];
+ co_curr = verts[a + 1];
}
- return fabsf(0.5f * area / max);
+ return fabsf(0.5f * area);
}
/********************************* Distance **********************************/
@@ -180,7 +204,7 @@ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2])
/* distance p to line-piece v1-v2 */
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
{
- float labda, rc[2], pt[2], len;
+ float lambda, rc[2], pt[2], len;
rc[0] = l2[0] - l1[0];
rc[1] = l2[1] - l1[1];
@@ -191,18 +215,18 @@ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const
return (rc[0] * rc[0] + rc[1] * rc[1]);
}
- labda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len;
- if (labda <= 0.0f) {
+ lambda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len;
+ if (lambda <= 0.0f) {
pt[0] = l1[0];
pt[1] = l1[1];
}
- else if (labda >= 1.0f) {
+ else if (lambda >= 1.0f) {
pt[0] = l2[0];
pt[1] = l2[1];
}
else {
- pt[0] = labda * rc[0] + l1[0];
- pt[1] = labda * rc[1] + l1[1];
+ pt[0] = lambda * rc[0] + l1[0];
+ pt[1] = lambda * rc[1] + l1[1];
}
rc[0] = pt[0] - p[0];
@@ -296,22 +320,113 @@ float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float
return len_v3v3(closest, v1);
}
+float dist_to_line_v3(const float v1[3], const float v2[3], const float v3[3])
+{
+ float closest[3];
+
+ closest_to_line_v3(closest, v1, v2, v3);
+
+ return len_v3v3(closest, v1);
+}
+
+/* Adapted from "Real-Time Collision Detection" by Christer Ericson,
+ * published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc.
+ *
+ * Set 'r' to the point in triangle (a, b, c) closest to point 'p' */
+void closest_on_tri_to_point_v3(float r[3], const float p[3],
+ const float a[3], const float b[3], const float c[3])
+{
+ float ab[3], ac[3], ap[3], d1, d2;
+ float bp[3], d3, d4, vc, cp[3], d5, d6, vb, va;
+ float denom, v, w;
+
+ /* Check if P in vertex region outside A */
+ sub_v3_v3v3(ab, b, a);
+ sub_v3_v3v3(ac, c, a);
+ sub_v3_v3v3(ap, p, a);
+ d1 = dot_v3v3(ab, ap);
+ d2 = dot_v3v3(ac, ap);
+ if (d1 <= 0.0f && d2 <= 0.0f) {
+ /* barycentric coordinates (1,0,0) */
+ copy_v3_v3(r, a);
+ return;
+ }
+
+ /* Check if P in vertex region outside B */
+ sub_v3_v3v3(bp, p, b);
+ d3 = dot_v3v3(ab, bp);
+ d4 = dot_v3v3(ac, bp);
+ if (d3 >= 0.0f && d4 <= d3) {
+ /* barycentric coordinates (0,1,0) */
+ copy_v3_v3(r, b);
+ return;
+ }
+ /* Check if P in edge region of AB, if so return projection of P onto AB */
+ vc = d1 * d4 - d3 * d2;
+ if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
+ float v = d1 / (d1 - d3);
+ /* barycentric coordinates (1-v,v,0) */
+ madd_v3_v3v3fl(r, a, ab, v);
+ return;
+ }
+ /* Check if P in vertex region outside C */
+ sub_v3_v3v3(cp, p, c);
+ d5 = dot_v3v3(ab, cp);
+ d6 = dot_v3v3(ac, cp);
+ if (d6 >= 0.0f && d5 <= d6) {
+ /* barycentric coordinates (0,0,1) */
+ copy_v3_v3(r, c);
+ return;
+ }
+ /* Check if P in edge region of AC, if so return projection of P onto AC */
+ vb = d5 * d2 - d1 * d6;
+ if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
+ float w = d2 / (d2 - d6);
+ /* barycentric coordinates (1-w,0,w) */
+ madd_v3_v3v3fl(r, a, ac, w);
+ return;
+ }
+ /* Check if P in edge region of BC, if so return projection of P onto BC */
+ va = d3 * d6 - d5 * d4;
+ if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
+ float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
+ /* barycentric coordinates (0,1-w,w) */
+ sub_v3_v3v3(r, c, b);
+ mul_v3_fl(r, w);
+ add_v3_v3(r, b);
+ return;
+ }
+
+ /* P inside face region. Compute Q through its barycentric coordinates (u,v,w) */
+ denom = 1.0f / (va + vb + vc);
+ v = vb * denom;
+ w = vc * denom;
+
+ /* = u*a + v*b + w*c, u = va * denom = 1.0f - v - w */
+ /* ac * w */
+ mul_v3_fl(ac, w);
+ /* a + ab * v */
+ madd_v3_v3v3fl(r, a, ab, v);
+ /* a + ab * v + ac * w */
+ add_v3_v3(r, ac);
+}
+
/******************************* Intersection ********************************/
/* intersect Line-Line, shorts */
int isect_line_line_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
{
- float div, labda, mu;
+ float div, lambda, mu;
div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]));
if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR;
- labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
- if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
+ if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
+ if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
return ISECT_LINE_LINE_CROSS;
}
return ISECT_LINE_LINE_NONE;
@@ -335,17 +450,17 @@ int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v
/* intersect Line-Line, floats */
int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
- float div, labda, mu;
+ float div, lambda, mu;
div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR;
- labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
- if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
+ if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
+ if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
return ISECT_LINE_LINE_CROSS;
}
return ISECT_LINE_LINE_NONE;
@@ -1037,7 +1152,7 @@ int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const flo
if (t0 > 1.0f || t1 < 0.0f) return 0;
- /* clamp to [0,1] */
+ /* clamp to [0, 1] */
CLAMP(t0, 0.0f, 1.0f);
CLAMP(t1, 0.0f, 1.0f);
@@ -1157,10 +1272,10 @@ int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const flo
}
/*e3*/
- /* sub_v3_v3v3(bv,v0,p1); */ /* UNUSED */
- /* elen2 = dot_v3v3(e1,e1); */ /* UNUSED */
- /* edotv = dot_v3v3(e1,vel); */ /* UNUSED */
- /* edotbv = dot_v3v3(e1,bv); */ /* UNUSED */
+ /* sub_v3_v3v3(bv, v0, p1); */ /* UNUSED */
+ /* elen2 = dot_v3v3(e1, e1); */ /* UNUSED */
+ /* edotv = dot_v3v3(e1, vel); */ /* UNUSED */
+ /* edotbv = dot_v3v3(e1, bv); */ /* UNUSED */
sub_v3_v3v3(bv, v1, p1);
elen2 = dot_v3v3(e3, e3);
@@ -1195,13 +1310,13 @@ int isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3]
int a0 = axis, a1 = (axis + 1) % 3, a2 = (axis + 2) % 3;
#if 0
- return isect_line_tri_v3(p1,p2,v0,v1,v2,lambda);
+ return isect_line_tri_v3(p1, p2, v0, v1, v2, lambda);
/* first a simple bounding box test */
- if (MIN3(v0[a1],v1[a1],v2[a1]) > p1[a1]) return 0;
- if (MIN3(v0[a2],v1[a2],v2[a2]) > p1[a2]) return 0;
- if (MAX3(v0[a1],v1[a1],v2[a1]) < p1[a1]) return 0;
- if (MAX3(v0[a2],v1[a2],v2[a2]) < p1[a2]) return 0;
+ if (min_fff(v0[a1], v1[a1], v2[a1]) > p1[a1]) return 0;
+ if (min_fff(v0[a2], v1[a2], v2[a2]) > p1[a2]) return 0;
+ if (max_fff(v0[a1], v1[a1], v2[a1]) < p1[a1]) return 0;
+ if (max_fff(v0[a2], v1[a2], v2[a2]) < p1[a2]) return 0;
/* then a full intersection test */
#endif
@@ -1415,8 +1530,8 @@ int isect_ray_aabb(const IsectRayAABBData *data, const float bb_min[3],
return TRUE;
}
-/* find closest point to p on line through l1,l2 and return lambda,
- * where (0 <= lambda <= 1) when cp is in the line segment l1,l2
+/* find closest point to p on line through (l1, l2) and return lambda,
+ * where (0 <= lambda <= 1) when cp is in the line segment (l1, l2)
*/
float closest_to_line_v3(float cp[3], const float p[3], const float l1[3], const float l2[3])
{
@@ -1702,9 +1817,9 @@ static int point_in_slice(const float p[3], const float v1[3], const float l1[3]
/*
* what is a slice ?
* some maths:
- * a line including l1,l2 and a point not on the line
+ * a line including (l1, l2) and a point not on the line
* define a subset of R3 delimited by planes parallel to the line and orthogonal
- * to the (point --> line) distance vector,one plane on the line one on the point,
+ * to the (point --> line) distance vector, one plane on the line one on the point,
* the room inside usually is rather small compared to R3 though still infinite
* useful for restricting (speeding up) searches
* e.g. all points of triangular prism are within the intersection of 3 'slices'
@@ -1735,7 +1850,7 @@ static int point_in_slice_as(float p[3], float origin[3], float normal[3])
return 1;
}
-/*mama (knowing the squared length of the normal)*/
+/*mama (knowing the squared length of the normal) */
static int point_in_slice_m(float p[3], float origin[3], float normal[3], float lns)
{
float h, rp[3];
@@ -1867,20 +1982,73 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int,
}
}
-/****************************** Interpolation ********************************/
+/****************************** Axis Utils ********************************/
+
+/**
+ * \brief Normal to x,y matrix
+ *
+ * Creates a 3x3 matrix from a normal.
+ * This matrix can be applied to vectors so their 'z' axis runs along \a normal.
+ * In practice it means you can use x,y as 2d coords. \see
+ *
+ * \param r_mat The matrix to return.
+ * \param normal A unit length vector.
+ */
+bool axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
+{
+ float up[3] = {0.0f, 0.0f, 1.0f};
+ float axis[3];
+ float angle;
+
+ /* double check they are normalized */
+ BLI_ASSERT_UNIT_V3(normal);
+
+ cross_v3_v3v3(axis, normal, up);
+ angle = saacos(dot_v3v3(normal, up));
+
+ if (angle >= FLT_EPSILON) {
+ if (len_squared_v3(axis) < FLT_EPSILON) {
+ axis[0] = 0.0f;
+ axis[1] = 1.0f;
+ axis[2] = 0.0f;
+ }
+
+ axis_angle_to_mat3(r_mat, axis, angle);
+ return true;
+ }
+ else {
+ unit_m3(r_mat);
+ return false;
+ }
+}
/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */
-void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3])
+void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
+{
+ const float xn = fabsf(axis[0]);
+ const float yn = fabsf(axis[1]);
+ const float zn = fabsf(axis[2]);
+
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; }
+ else { *r_axis_a = 1; *r_axis_b = 2; }
+}
+
+/* same as axis_dominant_v3 but return the max value */
+float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
{
const float xn = fabsf(axis[0]);
const float yn = fabsf(axis[1]);
const float zn = fabsf(axis[2]);
- if (zn >= xn && zn >= yn) { *axis_a = 0; *axis_b = 1; }
- else if (yn >= xn && yn >= zn) { *axis_a = 0; *axis_b = 2; }
- else { *axis_a = 1; *axis_b = 2; }
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; }
+ else { *r_axis_a = 1; *r_axis_b = 2; return xn; }
}
+
+/****************************** Interpolation ********************************/
+
static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j)
{
return 0.5f * ((v1[i] - v2[i]) * (v2[j] - v3[j]) + (v1[j] - v2[j]) * (v3[i] - v2[i]));
@@ -2252,59 +2420,106 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i;
+ int i, i_next, i_curr;
+ bool edge_interp = false;
totweight = 0.0f;
for (i = 0; i < n; i++) {
+ i_curr = i;
+ i_next = (i == n - 1) ? 0 : i + 1;
+
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = (i == n - 1) ? v[0] : v[i + 1];
+ vnext = v[i_next];
+
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
+ if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ edge_interp = true;
+ break;
+ }
t1 = mean_value_half_tan_v3(co, vprev, vmid);
t2 = mean_value_half_tan_v3(co, vmid, vnext);
len = len_v3v3(co, vmid);
- w[i] = (len != 0.0f)? (t1 + t2) / len: 0.0f;
+ w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
totweight += w[i];
}
- if (totweight != 0.0f) {
- for (i = 0; i < n; i++) {
- w[i] /= totweight;
+ if (edge_interp) {
+ float len_curr = len_v3v3(co, vmid);
+ float len_next = len_v3v3(co, vnext);
+ float edge_len = len_curr + len_next;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+
+ w[i_curr] = len_next / edge_len;
+ w[i_next] = len_curr / edge_len;
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i = 0; i < n; i++) {
+ w[i] /= totweight;
+ }
}
}
}
+
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i;
+ int i, i_next, i_curr;
+ bool edge_interp = false;
totweight = 0.0f;
for (i = 0; i < n; i++) {
+ i_curr = i;
+ i_next = (i == n - 1) ? 0 : i + 1;
+
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = (i == n - 1) ? v[0] : v[i + 1];
+ vnext = v[i_next];
+
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
+ if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ edge_interp = true;
+ break;
+ }
t1 = mean_value_half_tan_v2(co, vprev, vmid);
t2 = mean_value_half_tan_v2(co, vmid, vnext);
len = len_v2v2(co, vmid);
- w[i] = (len != 0.0f)? (t1 + t2) / len: 0.0f;
+ w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
totweight += w[i];
}
- if (totweight != 0.0f) {
- for (i = 0; i < n; i++) {
- w[i] /= totweight;
+ if (edge_interp) {
+ float len_curr = len_v2v2(co, vmid);
+ float len_next = len_v2v2(co, vnext);
+ float edge_len = len_curr + len_next;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+
+ w[i_curr] = len_next / edge_len;
+ w[i_next] = len_curr / edge_len;
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i = 0; i < n; i++) {
+ w[i] /= totweight;
+ }
}
}
}
-/* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
+/* (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)
{
float a[3], b[3];
@@ -2435,7 +2650,7 @@ void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
/***************************** View & Projection *****************************/
-void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top,
+void orthographic_m4(float matrix[4][4], const float left, const float right, const float bottom, const float top,
const float nearClip, const float farClip)
{
float Xdelta, Ydelta, Zdelta;
@@ -2481,7 +2696,7 @@ void perspective_m4(float mat[4][4], const float left, const float right, const
}
/* translate a matrix created by orthographic_m4 or perspective_m4 in XY coords (used to jitter the view) */
-void window_translate_m4(float winmat[][4], float perspmat[][4], const float x, const float y)
+void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y)
{
if (winmat[2][3] == -1.0f) {
/* in the case of a win-matrix, this means perspective always */
@@ -2509,7 +2724,7 @@ void window_translate_m4(float winmat[][4], float perspmat[][4], const float x,
}
}
-static void i_multmatrix(float icand[][4], float Vm[][4])
+static void i_multmatrix(float icand[4][4], float Vm[4][4])
{
int row, col;
float temp[4][4];
@@ -2523,7 +2738,7 @@ static void i_multmatrix(float icand[][4], float Vm[][4])
copy_m4_m4(Vm, temp);
}
-void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, float twist)
+void polarview_m4(float Vm[4][4], float dist, float azimuth, float incidence, float twist)
{
unit_m4(Vm);
@@ -2534,7 +2749,7 @@ void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, flo
rotate_m4(Vm, 'Z', -azimuth);
}
-void lookat_m4(float mat[][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
+void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
{
float sine, cosine, hyp, hyp1, dx, dy, dz;
float mat1[4][4] = MAT4_UNITY;
@@ -2791,8 +3006,8 @@ void tangent_from_uv(float uv1[2], float uv2[2], float uv3[3], float co1[3], flo
/****************************** Vector Clouds ********************************/
/* vector clouds */
-/* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight,
- * float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3])
+/* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, float (*rpos)[3], float *rweight,
+ * float lloc[3], float rloc[3], float lrot[3][3], float lscale[3][3])
*
* input
* (
@@ -2881,9 +3096,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl
/* build 'projection' matrix */
for (a = 0; a < list_size; a++) {
sub_v3_v3v3(va, rpos[a], accu_rcom);
- /* mul_v3_fl(va,bp->mass); mass needs renormalzation here ?? */
+ /* mul_v3_fl(va, bp->mass); mass needs renormalzation here ?? */
sub_v3_v3v3(vb, pos[a], accu_com);
- /* mul_v3_fl(va,rp->mass); */
+ /* mul_v3_fl(va, rp->mass); */
m[0][0] += va[0] * vb[0];
m[0][1] += va[0] * vb[1];
m[0][2] += va[0] * vb[2];
@@ -3376,44 +3591,57 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl
/* evaluate if entire quad is a proper convex quad */
int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
- float nor[3], nor1[3], nor2[3], vec[4][2];
- int axis_a, axis_b;
+ float nor[3], nor_a[3], nor_b[3], vec[4][2];
+ float mat[3][3];
+ const bool is_ok_a = (normal_tri_v3(nor_a, v1, v2, v3) > FLT_EPSILON);
+ const bool is_ok_b = (normal_tri_v3(nor_b, v1, v3, v4) > FLT_EPSILON);
/* define projection, do both trias apart, quad is undefined! */
- normal_tri_v3(nor1, v1, v2, v3);
- normal_tri_v3(nor2, v1, v3, v4);
+ /* check normal length incase one size is zero area */
+ if (is_ok_a) {
+ if (is_ok_b) {
+ /* use both, most common outcome */
+
+ /* when the face is folded over as 2 tris we probably don't want to create
+ * a quad from it, but go ahead with the intersection test since this
+ * isn't a function for degenerate faces */
+ if (UNLIKELY(dot_v3v3(nor_a, nor_b) < 0.0f)) {
+ /* flip so adding normals in the opposite direction
+ * doesn't give a zero length vector */
+ negate_v3(nor_b);
+ }
- /* when the face is folded over as 2 tris we probably don't want to create
- * a quad from it, but go ahead with the intersection test since this
- * isn't a function for degenerate faces */
- if (UNLIKELY(dot_v3v3(nor1, nor2) < 0.0f)) {
- /* flip so adding normals in the opposite direction
- * doesnt give a zero length vector */
- negate_v3(nor2);
+ add_v3_v3v3(nor, nor_a, nor_b);
+ normalize_v3(nor);
+ }
+ else {
+ copy_v3_v3(nor, nor_a); /* only 'a' */
+ }
+ }
+ else {
+ if (is_ok_b) {
+ copy_v3_v3(nor, nor_b); /* only 'b' */
+ }
+ else {
+ return false; /* both zero, we can't do anything useful here */
+ }
}
- add_v3_v3v3(nor, nor1, nor2);
-
- axis_dominant_v3(&axis_a, &axis_b, nor);
-
- vec[0][0] = v1[axis_a];
- vec[0][1] = v1[axis_b];
- vec[1][0] = v2[axis_a];
- vec[1][1] = v2[axis_b];
+ axis_dominant_v3_to_m3(mat, nor);
- vec[2][0] = v3[axis_a];
- vec[2][1] = v3[axis_b];
- vec[3][0] = v4[axis_a];
- vec[3][1] = v4[axis_b];
+ mul_v2_m3v3(vec[0], mat, v1);
+ mul_v2_m3v3(vec[1], mat, v2);
+ mul_v2_m3v3(vec[2], mat, v3);
+ mul_v2_m3v3(vec[3], mat, v4);
/* linetests, the 2 diagonals have to instersect to be convex */
- return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0) ? TRUE : FALSE;
+ return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0);
}
int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
/* linetests, the 2 diagonals have to instersect to be convex */
- return (isect_line_line_v2(v1, v3, v2, v4) > 0) ? TRUE : FALSE;
+ return (isect_line_line_v2(v1, v3, v2, v4) > 0);
}
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index ba9770e1bd1..f32b477787b 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -158,4 +158,31 @@ MINLINE int min_axis_v3(const float vec[3])
((y < z) ? 1 : 2));
}
+/**
+ * Simple method to find how many tri's we need when we already know the corner+poly count.
+ *
+ * Formula is:
+ *
+ * tri = ((corner_count / poly_count) - 2) * poly_count;
+ *
+ * Use doubles since this is used for allocating and we
+ * don't want float precision to give incorrect results.
+ *
+ * \param poly_count The number of ngon's/tris (1-2 sided faces will give incorrect results)
+ * \param corner_count - also known as loops in BMesh/DNA
+ */
+MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
+{
+ if (poly_count != 0) {
+ const double poly_count_d = (double)poly_count;
+ const double corner_count_d = (double)corner_count;
+ BLI_assert(poly_count > 0);
+ BLI_assert(corner_count > 0);
+ return (int)((((corner_count_d / poly_count_d) - 2.0) * poly_count_d) + 0.5);
+ }
+ else {
+ return 0;
+ }
+}
+
#endif /* __MATH_GEOM_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 38214f9c6b0..9d9e3e611e1 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -43,7 +43,7 @@ void zero_m4(float m[4][4])
memset(m, 0, 4 * 4 * sizeof(float));
}
-void unit_m3(float m[][3])
+void unit_m3(float m[3][3])
{
m[0][0] = m[1][1] = m[2][2] = 1.0;
m[0][1] = m[0][2] = 0.0;
@@ -51,7 +51,7 @@ void unit_m3(float m[][3])
m[2][0] = m[2][1] = 0.0;
}
-void unit_m4(float m[][4])
+void unit_m4(float m[4][4])
{
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0;
m[0][1] = m[0][2] = m[0][3] = 0.0;
@@ -60,18 +60,18 @@ void unit_m4(float m[][4])
m[3][0] = m[3][1] = m[3][2] = 0.0;
}
-void copy_m3_m3(float m1[][3], float m2[][3])
+void copy_m3_m3(float m1[3][3], float m2[3][3])
{
/* destination comes first: */
memcpy(&m1[0], &m2[0], 9 * sizeof(float));
}
-void copy_m4_m4(float m1[][4], float m2[][4])
+void copy_m4_m4(float m1[4][4], float m2[4][4])
{
memcpy(m1, m2, 4 * 4 * sizeof(float));
}
-void copy_m3_m4(float m1[][3], float m2[][4])
+void copy_m3_m4(float m1[3][3], float m2[4][4])
{
m1[0][0] = m2[0][0];
m1[0][1] = m2[0][1];
@@ -86,7 +86,7 @@ void copy_m3_m4(float m1[][3], float m2[][4])
m1[2][2] = m2[2][2];
}
-void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */
+void copy_m4_m3(float m1[4][4], float m2[3][3]) /* no clear */
{
m1[0][0] = m2[0][0];
m1[0][1] = m2[0][1];
@@ -112,7 +112,7 @@ void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */
}
-void swap_m3m3(float m1[][3], float m2[][3])
+void swap_m3m3(float m1[3][3], float m2[3][3])
{
float t;
int i, j;
@@ -126,7 +126,7 @@ void swap_m3m3(float m1[][3], float m2[][3])
}
}
-void swap_m4m4(float m1[][4], float m2[][4])
+void swap_m4m4(float m1[4][4], float m2[4][4])
{
float t;
int i, j;
@@ -142,7 +142,7 @@ void swap_m4m4(float m1[][4], float m2[][4])
/******************************** Arithmetic *********************************/
-void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4])
+void mult_m4_m4m4(float m1[4][4], float m3_[4][4], float m2_[4][4])
{
float m2[4][4], m3[4][4];
@@ -173,7 +173,7 @@ void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4])
}
-void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3])
+void mul_m3_m3m3(float m1[3][3], float m3_[3][3], float m2_[3][3])
{
float m2[3][3], m3[3][3];
@@ -195,7 +195,7 @@ void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
-void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3])
+void mul_m4_m4m3(float m1[4][4], float m3_[4][4], float m2_[3][3])
{
float m2[3][3], m3[4][4];
@@ -215,7 +215,7 @@ void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3])
}
/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */
-void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3])
+void mult_m3_m3m4(float m1[3][3], float m3_[4][4], float m2_[3][3])
{
float m2[3][3], m3[4][4];
@@ -237,7 +237,7 @@ void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
-void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4])
+void mul_m4_m3m4(float m1[4][4], float m3_[3][3], float m2_[4][4])
{
float m2[4][4], m3[3][3];
@@ -256,10 +256,10 @@ void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
-void mul_serie_m3(float answ[][3],
- float m1[][3], float m2[][3], float m3[][3],
- float m4[][3], float m5[][3], float m6[][3],
- float m7[][3], float m8[][3])
+void mul_serie_m3(float answ[3][3],
+ float m1[3][3], float m2[3][3], float m3[3][3],
+ float m4[3][3], float m5[3][3], float m6[3][3],
+ float m7[3][3], float m8[3][3])
{
float temp[3][3];
@@ -289,10 +289,10 @@ void mul_serie_m3(float answ[][3],
}
}
-void mul_serie_m4(float answ[][4], float m1[][4],
- float m2[][4], float m3[][4], float m4[][4],
- float m5[][4], float m6[][4], float m7[][4],
- float m8[][4])
+void mul_serie_m4(float answ[4][4], float m1[4][4],
+ float m2[4][4], float m3[4][4], float m4[4][4],
+ float m5[4][4], float m6[4][4], float m7[4][4],
+ float m8[4][4])
{
float temp[4][4];
@@ -322,7 +322,7 @@ void mul_serie_m4(float answ[][4], float m1[][4],
}
}
-void mul_m4_v3(float mat[][4], float vec[3])
+void mul_m4_v3(float mat[4][4], float vec[3])
{
float x, y;
@@ -333,7 +333,7 @@ void mul_m4_v3(float mat[][4], float vec[3])
vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
-void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3])
+void mul_v3_m4v3(float in[3], float mat[4][4], const float vec[3])
{
float x, y;
@@ -344,8 +344,17 @@ void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3])
in[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
+void mul_v2_m2v2(float r[2], float mat[2][2], const float vec[2])
+{
+ float x;
+
+ x = vec[0];
+ r[0] = mat[0][0] * x + mat[1][0] * vec[1];
+ r[1] = mat[0][1] * x + mat[1][1] * vec[1];
+}
+
/* same as mul_m4_v3() but doesnt apply translation component */
-void mul_mat3_m4_v3(float mat[][4], float vec[3])
+void mul_mat3_m4_v3(float mat[4][4], float vec[3])
{
float x, y;
@@ -356,7 +365,7 @@ void mul_mat3_m4_v3(float mat[][4], float vec[3])
vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
}
-void mul_project_m4_v3(float mat[][4], float vec[3])
+void mul_project_m4_v3(float mat[4][4], float vec[3])
{
const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3];
mul_m4_v3(mat, vec);
@@ -366,7 +375,7 @@ void mul_project_m4_v3(float mat[][4], float vec[3])
vec[2] /= w;
}
-void mul_v4_m4v4(float r[4], float mat[4][4], float v[4])
+void mul_v4_m4v4(float r[4], float mat[4][4], const float v[4])
{
float x, y, z;
@@ -404,13 +413,19 @@ void mul_m4_v4d(float mat[4][4], double r[4])
mul_v4d_m4v4d(r, mat, r);
}
-void mul_v3_m3v3(float r[3], float M[3][3], float a[3])
+void mul_v3_m3v3(float r[3], float M[3][3], const float a[3])
{
r[0] = M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
r[2] = M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
}
+void mul_v2_m3v3(float r[2], float M[3][3], const float a[3])
+{
+ r[0] = M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
+ r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
+}
+
void mul_m3_v3(float M[3][3], float r[3])
{
float tmp[3];
@@ -419,7 +434,7 @@ void mul_m3_v3(float M[3][3], float r[3])
copy_v3_v3(r, tmp);
}
-void mul_transposed_m3_v3(float mat[][3], float vec[3])
+void mul_transposed_m3_v3(float mat[3][3], float vec[3])
{
float x, y;
@@ -457,7 +472,7 @@ void mul_mat3_m4_fl(float m[4][4], float f)
m[i][j] *= f;
}
-void mul_m3_v3_double(float mat[][3], double vec[3])
+void mul_m3_v3_double(float mat[3][3], double vec[3])
{
double x, y;
@@ -468,7 +483,7 @@ void mul_m3_v3_double(float mat[][3], double vec[3])
vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2];
}
-void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
+void add_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
{
int i, j;
@@ -477,7 +492,7 @@ void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
m1[i][j] = m2[i][j] + m3[i][j];
}
-void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
+void add_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
{
int i, j;
@@ -486,7 +501,7 @@ void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
m1[i][j] = m2[i][j] + m3[i][j];
}
-void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
+void sub_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
{
int i, j;
@@ -495,7 +510,7 @@ void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
m1[i][j] = m2[i][j] - m3[i][j];
}
-void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
+void sub_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
{
int i, j;
@@ -504,8 +519,7 @@ void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
m1[i][j] = m2[i][j] - m3[i][j];
}
-/* why not make this a standard part of the API? */
-static float determinant_m3_local(float m[3][3])
+float determinant_m3_array(float m[3][3])
{
return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
@@ -534,7 +548,7 @@ int invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon)
adjoint_m3_m3(m1, m2);
/* then determinant old matrix! */
- det = determinant_m3_local(m2);
+ det = determinant_m3_array(m2);
success = (fabsf(det) > epsilon);
@@ -569,7 +583,7 @@ int invert_m3_m3(float m1[3][3], float m2[3][3])
adjoint_m3_m3(m1, m2);
/* then determinant old matrix! */
- det = determinant_m3_local(m2);
+ det = determinant_m3_array(m2);
success = (det != 0.0f);
@@ -613,6 +627,8 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4])
float max;
int maxj;
+ BLI_assert(inverse != mat);
+
/* Set inverse to identity */
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
@@ -665,7 +681,7 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4])
/****************************** Linear Algebra *******************************/
-void transpose_m3(float mat[][3])
+void transpose_m3(float mat[3][3])
{
float t;
@@ -680,7 +696,7 @@ void transpose_m3(float mat[][3])
mat[2][1] = t;
}
-void transpose_m4(float mat[][4])
+void transpose_m4(float mat[4][4])
{
float t;
@@ -706,7 +722,7 @@ void transpose_m4(float mat[][4])
mat[3][2] = t;
}
-void orthogonalize_m3(float mat[][3], int axis)
+void orthogonalize_m3(float mat[3][3], int axis)
{
float size[3];
mat3_to_size(size, mat);
@@ -784,7 +800,7 @@ void orthogonalize_m3(float mat[][3], int axis)
mul_v3_fl(mat[2], size[2]);
}
-void orthogonalize_m4(float mat[][4], int axis)
+void orthogonalize_m4(float mat[4][4], int axis)
{
float size[3];
mat4_to_size(size, mat);
@@ -863,7 +879,7 @@ void orthogonalize_m4(float mat[][4], int axis)
mul_v3_fl(mat[2], size[2]);
}
-int is_orthogonal_m3(float m[][3])
+int is_orthogonal_m3(float m[3][3])
{
int i, j;
@@ -877,7 +893,7 @@ int is_orthogonal_m3(float m[][3])
return 1;
}
-int is_orthogonal_m4(float m[][4])
+int is_orthogonal_m4(float m[4][4])
{
int i, j;
@@ -892,7 +908,7 @@ int is_orthogonal_m4(float m[][4])
return 1;
}
-int is_orthonormal_m3(float m[][3])
+int is_orthonormal_m3(float m[3][3])
{
if (is_orthogonal_m3(m)) {
int i;
@@ -907,7 +923,7 @@ int is_orthonormal_m3(float m[][3])
return 0;
}
-int is_orthonormal_m4(float m[][4])
+int is_orthonormal_m4(float m[4][4])
{
if (is_orthogonal_m4(m)) {
int i;
@@ -922,7 +938,7 @@ int is_orthonormal_m4(float m[][4])
return 0;
}
-int is_uniform_scaled_m3(float m[][3])
+int is_uniform_scaled_m3(float m[3][3])
{
const float eps = 1e-7;
float t[3][3];
@@ -951,21 +967,21 @@ int is_uniform_scaled_m3(float m[][3])
return 0;
}
-void normalize_m3(float mat[][3])
+void normalize_m3(float mat[3][3])
{
normalize_v3(mat[0]);
normalize_v3(mat[1]);
normalize_v3(mat[2]);
}
-void normalize_m3_m3(float rmat[][3], float mat[][3])
+void normalize_m3_m3(float rmat[3][3], float mat[3][3])
{
normalize_v3_v3(rmat[0], mat[0]);
normalize_v3_v3(rmat[1], mat[1]);
normalize_v3_v3(rmat[2], mat[2]);
}
-void normalize_m4(float mat[][4])
+void normalize_m4(float mat[4][4])
{
float len;
@@ -977,19 +993,13 @@ void normalize_m4(float mat[][4])
if (len != 0.0f) mat[2][3] /= len;
}
-void normalize_m4_m4(float rmat[][4], float mat[][4])
+void normalize_m4_m4(float rmat[4][4], float mat[4][4])
{
- float len;
-
- len = normalize_v3_v3(rmat[0], mat[0]);
- if (len != 0.0f) rmat[0][3] = mat[0][3] / len;
- len = normalize_v3_v3(rmat[1], mat[1]);
- if (len != 0.0f) rmat[1][3] = mat[1][3] / len;
- len = normalize_v3_v3(rmat[2], mat[2]);
- if (len != 0.0f) rmat[2][3] = mat[2][3] / len;
+ copy_m4_m4(rmat, mat);
+ normalize_m4(rmat);
}
-void adjoint_m2_m2(float m1[][2], float m[][2])
+void adjoint_m2_m2(float m1[2][2], float m[2][2])
{
BLI_assert(m1 != m);
m1[0][0] = m[1][1];
@@ -998,7 +1008,7 @@ void adjoint_m2_m2(float m1[][2], float m[][2])
m1[1][1] = m[0][0];
}
-void adjoint_m3_m3(float m1[][3], float m[][3])
+void adjoint_m3_m3(float m1[3][3], float m[3][3])
{
BLI_assert(m1 != m);
m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1];
@@ -1014,7 +1024,7 @@ void adjoint_m3_m3(float m1[][3], float m[][3])
m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
-void adjoint_m4_m4(float out[][4], float in[][4]) /* out = ADJ(in) */
+void adjoint_m4_m4(float out[4][4], float in[4][4]) /* out = ADJ(in) */
{
float a1, a2, a3, a4, b1, b2, b3, b4;
float c1, c2, c3, c4, d1, d2, d3, d4;
@@ -1080,7 +1090,7 @@ float determinant_m3(float a1, float a2, float a3,
return ans;
}
-float determinant_m4(float m[][4])
+float determinant_m4(float m[4][4])
{
float ans;
float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
@@ -1115,7 +1125,7 @@ float determinant_m4(float m[][4])
/****************************** Transformations ******************************/
-void size_to_mat3(float mat[][3], const float size[3])
+void size_to_mat3(float mat[3][3], const float size[3])
{
mat[0][0] = size[0];
mat[0][1] = 0.0f;
@@ -1128,7 +1138,7 @@ void size_to_mat3(float mat[][3], const float size[3])
mat[2][0] = 0.0f;
}
-void size_to_mat4(float mat[][4], const float size[3])
+void size_to_mat4(float mat[4][4], const float size[3])
{
float tmat[3][3];
@@ -1137,14 +1147,14 @@ void size_to_mat4(float mat[][4], const float size[3])
copy_m4_m3(mat, tmat);
}
-void mat3_to_size(float size[3], float mat[][3])
+void mat3_to_size(float size[3], float mat[3][3])
{
size[0] = len_v3(mat[0]);
size[1] = len_v3(mat[1]);
size[2] = len_v3(mat[2]);
}
-void mat4_to_size(float size[3], float mat[][4])
+void mat4_to_size(float size[3], float mat[4][4])
{
size[0] = len_v3(mat[0]);
size[1] = len_v3(mat[1]);
@@ -1154,7 +1164,7 @@ void mat4_to_size(float size[3], float mat[][4])
/* this gets the average scale of a matrix, only use when your scaling
* data that has no idea of scale axis, examples are bone-envelope-radius
* and curve radius */
-float mat3_to_scale(float mat[][3])
+float mat3_to_scale(float mat[3][3])
{
/* unit length vector */
float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f};
@@ -1162,7 +1172,7 @@ float mat3_to_scale(float mat[][3])
return len_v3(unit_vec);
}
-float mat4_to_scale(float mat[][4])
+float mat4_to_scale(float mat[4][4])
{
float tmat[3][3];
copy_m3_m4(tmat, mat);
@@ -1200,7 +1210,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
size[2] = mat3[2][2];
}
-void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4])
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4])
{
float mat3[3][3]; /* wmat -> 3x3 */
@@ -1211,7 +1221,34 @@ void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wm
copy_v3_v3(loc, wmat[3]);
}
-void scale_m3_fl(float m[][3], float scale)
+void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4])
+{
+ float mat3[3][3];
+ float mat3_n[3][3]; /* normalized mat3 */
+
+ copy_m3_m4(mat3, wmat);
+ normalize_m3_m3(mat3_n, mat3);
+
+ /* 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]);
+ }
+
+ mat3_to_quat(quat, mat3_n);
+ copy_v3_v3(loc, wmat[3]);
+}
+
+void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4])
+{
+ float rot[3][3];
+ mat4_to_loc_rot_size(loc, rot, size, wmat);
+ mat3_to_quat(quat, rot);
+}
+
+void scale_m3_fl(float m[3][3], float scale)
{
m[0][0] = m[1][1] = m[2][2] = scale;
m[0][1] = m[0][2] = 0.0;
@@ -1219,7 +1256,7 @@ void scale_m3_fl(float m[][3], float scale)
m[2][0] = m[2][1] = 0.0;
}
-void scale_m4_fl(float m[][4], float scale)
+void scale_m4_fl(float m[4][4], float scale)
{
m[0][0] = m[1][1] = m[2][2] = scale;
m[3][3] = 1.0;
@@ -1229,14 +1266,14 @@ void scale_m4_fl(float m[][4], float scale)
m[3][0] = m[3][1] = m[3][2] = 0.0;
}
-void translate_m4(float mat[][4], float Tx, float Ty, float Tz)
+void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
{
mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
}
-void rotate_m4(float mat[][4], const char axis, const float angle)
+void rotate_m4(float mat[4][4], const char axis, const float angle)
{
int col;
float temp[4] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -1244,8 +1281,8 @@ void rotate_m4(float mat[][4], const char axis, const float angle)
assert(axis >= 'X' && axis <= 'Z');
- cosine = (float)cos(angle);
- sine = (float)sin(angle);
+ cosine = cosf(angle);
+ sine = sinf(angle);
switch (axis) {
case 'X':
for (col = 0; col < 4; col++)
@@ -1276,7 +1313,14 @@ void rotate_m4(float mat[][4], const char axis, const float angle)
}
}
-void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float srcweight)
+void rotate_m2(float mat[2][2], const float angle)
+{
+ mat[0][0] = mat[1][1] = cosf(angle);
+ mat[0][1] = sinf(angle);
+ mat[1][0] = -mat[0][1];
+}
+
+void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
{
float srot[3][3], drot[3][3];
float squat[4], dquat[4], fquat[4];
@@ -1299,7 +1343,7 @@ void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float s
mul_m3_m3m3(out, rmat, smat);
}
-void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float srcweight)
+void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const float srcweight)
{
float sloc[3], dloc[3], floc[3];
float srot[3][3], drot[3][3];
@@ -1321,14 +1365,14 @@ void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float s
loc_quat_size_to_mat4(out, floc, fquat, fsize);
}
-int is_negative_m3(float mat[][3])
+int is_negative_m3(float mat[3][3])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
-int is_negative_m4(float mat[][4])
+int is_negative_m4(float mat[4][4])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
@@ -1418,7 +1462,7 @@ void loc_axisangle_size_to_mat4(float mat[4][4], const float loc[3], const float
/*********************************** Other ***********************************/
-void print_m3(const char *str, float m[][3])
+void print_m3(const char *str, float m[3][3])
{
printf("%s\n", str);
printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]);
@@ -1427,7 +1471,7 @@ void print_m3(const char *str, float m[][3])
printf("\n");
}
-void print_m4(const char *str, float m[][4])
+void print_m4(const char *str, float m[4][4])
{
printf("%s\n", str);
printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
@@ -1901,3 +1945,16 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon)
mul_serie_m4(Ainv, U, Wm, V, NULL, NULL, NULL, NULL, NULL);
}
+
+void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon)
+{
+ /* try regular inverse when possible, otherwise fall back to slow svd */
+ if (!invert_m3_m3(Ainv, A)) {
+ float tmp[4][4], tmpinv[4][4];
+
+ copy_m4_m3(tmp, A);
+ pseudoinverse_m4_m4(tmpinv, tmp, epsilon);
+ copy_m3_m4(Ainv, tmpinv);
+ }
+}
+
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 3069542107e..26576b2dcb2 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -84,6 +84,8 @@ void mul_qt_qtqt(float q[4], const float q1[4], const float q2[4])
* \note:
* Assumes a unit quaternion?
*
+ * \note: multiplying by 3x3 matrix is ~25% faster.
+ *
* in fact not, but you may want to use a unit quat, read on...
*
* Shortcut for 'q v q*' when \a v is actually a quaternion.
@@ -185,7 +187,7 @@ void mul_fac_qt_fl(float q[4], const float fac)
}
/* skip error check, currently only needed by mat3_to_quat_is_ok */
-static void quat_to_mat3_no_error(float m[][3], const float q[4])
+static void quat_to_mat3_no_error(float m[3][3], const float q[4])
{
double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
@@ -217,7 +219,7 @@ static void quat_to_mat3_no_error(float m[][3], const float q[4])
m[2][2] = (float)(1.0 - qaa - qbb);
}
-void quat_to_mat3(float m[][3], const float q[4])
+void quat_to_mat3(float m[3][3], const float q[4])
{
#ifdef DEBUG
float f;
@@ -229,7 +231,7 @@ void quat_to_mat3(float m[][3], const float q[4])
quat_to_mat3_no_error(m, q);
}
-void quat_to_mat4(float m[][4], const float q[4])
+void quat_to_mat4(float m[4][4], const float q[4])
{
double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
@@ -273,7 +275,7 @@ void quat_to_mat4(float m[][4], const float q[4])
m[3][3] = 1.0f;
}
-void mat3_to_quat(float q[4], float wmat[][3])
+void mat3_to_quat(float q[4], float wmat[3][3])
{
double tr, s;
float mat[3][3];
@@ -325,7 +327,7 @@ void mat3_to_quat(float q[4], float wmat[][3])
normalize_qt(q);
}
-void mat4_to_quat(float q[4], float m[][4])
+void mat4_to_quat(float q[4], float m[4][4])
{
float mat[3][3];
@@ -589,10 +591,10 @@ void interp_qt_qtqt(float result[4], const float quat1[4], const float quat2[4],
}
if ((1.0f - cosom) > 0.0001f) {
- omega = (float)acos(cosom);
- sinom = (float)sin(omega);
- sc1 = (float)sin((1 - t) * omega) / sinom;
- sc2 = (float)sin(t * omega) / sinom;
+ omega = acosf(cosom);
+ sinom = sinf(omega);
+ sc1 = sinf((1.0f - t) * omega) / sinom;
+ sc2 = sinf(t * omega) / sinom;
}
else {
sc1 = 1.0f - t;
@@ -861,7 +863,7 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang
/* TODO: the following calls should probably be deprecated sometime */
/* TODO, replace use of this function with axis_angle_to_mat3() */
-void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi)
+void vec_rot_to_mat3(float mat[3][3], const float vec[3], const float phi)
{
/* rotation of phi radials around vec */
float vx, vx2, vy, vy2, vz, vz2, co, si;
@@ -889,7 +891,7 @@ void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi)
/******************************** XYZ Eulers *********************************/
/* XYZ order */
-void eul_to_mat3(float mat[][3], const float eul[3])
+void eul_to_mat3(float mat[3][3], const float eul[3])
{
double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
@@ -917,7 +919,7 @@ void eul_to_mat3(float mat[][3], const float eul[3])
}
/* XYZ order */
-void eul_to_mat4(float mat[][4], const float eul[3])
+void eul_to_mat4(float mat[4][4], const float eul[3])
{
double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
@@ -950,7 +952,7 @@ void eul_to_mat4(float mat[][4], const float eul[3])
/* returns two euler calculation methods, so we can pick the best */
/* XYZ order */
-static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3])
+static void mat3_to_eul2(float tmat[3][3], float eul1[3], float eul2[3])
{
float cy, quat[4], mat[3][3];
@@ -982,7 +984,7 @@ static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3])
}
/* XYZ order */
-void mat3_to_eul(float *eul, float tmat[][3])
+void mat3_to_eul(float *eul, float tmat[3][3])
{
float eul1[3], eul2[3];
@@ -998,7 +1000,7 @@ void mat3_to_eul(float *eul, float tmat[][3])
}
/* XYZ order */
-void mat4_to_eul(float *eul, float tmat[][4])
+void mat4_to_eul(float *eul, float tmat[4][4])
{
float tempMat[3][3];
@@ -1107,7 +1109,7 @@ void compatible_eul(float eul[3], const float oldrot[3])
/* uses 2 methods to retrieve eulers, and picks the closest */
/* XYZ order */
-void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[][3])
+void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3])
{
float eul1[3], eul2[3];
float d1, d2;
@@ -1388,7 +1390,7 @@ void rotate_eulO(float beul[3], const short order, char axis, float ang)
}
/* the matrix is written to as 3 axis vectors */
-void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order)
+void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order)
{
const RotOrderInfo *R = GET_ROTATIONORDER_INFO(order);
@@ -1447,7 +1449,7 @@ void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order)
* - added support for scaling
*/
-void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4])
+void mat4_to_dquat(DualQuat *dq, float basemat[4][4], float mat[4][4])
{
float *t, *q, dscale[3], scale[3], basequat[4];
float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4];
@@ -1502,7 +1504,7 @@ void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4])
dq->trans[3] = 0.5f * ( t[0] * q[2] - t[1] * q[1] + t[2] * q[0]);
}
-void dquat_to_mat4(float mat[][4], DualQuat *dq)
+void dquat_to_mat4(float mat[4][4], DualQuat *dq)
{
float len, *t, q0[4];
@@ -1583,7 +1585,7 @@ void normalize_dq(DualQuat *dq, float totweight)
}
}
-void mul_v3m3_dq(float co[3], float mat[][3], DualQuat *dq)
+void mul_v3m3_dq(float co[3], float mat[3][3], DualQuat *dq)
{
float M[3][3], t[3], scalemat[3][3], len2;
float w = dq->quat[0], x = dq->quat[1], y = dq->quat[2], z = dq->quat[3];
@@ -1660,7 +1662,7 @@ void quat_apply_track(float quat[4], short axis, short upflag)
axis = axis - 3;
/* there are 2 possible up-axis for each axis used, the 'quat_track' applies so the first
- * up axis is used X->Y, Y->X, Z->X, if this first up axis isn used then rotate 90d
+ * up axis is used X->Y, Y->X, Z->X, if this first up axis isn't used then rotate 90d
* the strange bit shift below just find the low axis {X:Y, Y:X, Z:X} */
if (upflag != (2 - axis) >> 1) {
float q[4] = {M_SQRT1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */
@@ -1737,3 +1739,158 @@ float angle_wrap_deg(float angle)
{
return mod_inline(angle + 180.0f, 360.0f) - 180.0f;
}
+
+/* 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;
+}
+
+/* axis conversion */
+static float _axis_convert_matrix[23][3][3] = {
+ {{-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}},
+ {{-1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, -1.0, 0.0}},
+ {{-1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}},
+ {{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}},
+ {{0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}},
+ {{0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, 0.0, -1.0}, {0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {1.0, 0.0, 0.0}},
+ {{0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}, {1.0, 0.0, 0.0}},
+ {{0.0, 0.0, -1.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}},
+ {{0.0, -1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}},
+ {{0.0, 0.0, -1.0}, {1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}},
+ {{0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}},
+ {{1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, 1.0, 0.0}},
+};
+
+static int _axis_convert_lut[23][24] = {
+ {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A,
+ 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C,
+ 0x745, 0x94D, 0x15D, 0x365},
+ {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A,
+ 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC,
+ 0x645, 0xA4D, 0x05D, 0x465},
+ {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A,
+ 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C,
+ 0x705, 0x50D, 0x11D, 0xB25},
+ {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A,
+ 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C,
+ 0x685, 0x28D, 0x09D, 0x8A5},
+ {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A,
+ 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C,
+ 0x885, 0x68D, 0x29D, 0x0A5},
+ {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A,
+ 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC,
+ 0x8C5, 0xACD, 0x2DD, 0x4E5},
+ {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA,
+ 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C,
+ 0x805, 0x40D, 0x21D, 0xA25},
+ {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A,
+ 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC,
+ 0x945, 0x14D, 0x35D, 0x765},
+ {0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A,
+ 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C,
+ 0xB05, 0x70D, 0x51D, 0x125},
+ {0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA,
+ 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C,
+ 0xA05, 0x80D, 0x41D, 0x225},
+ {0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A,
+ 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C,
+ 0xAC5, 0x2CD, 0x4DD, 0x8E5},
+ {0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A,
+ 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC,
+ 0xA45, 0x04D, 0x45D, 0x665},
+ {0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A,
+ 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C,
+ 0x445, 0x64D, 0xA5D, 0x065},
+ {0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A,
+ 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C,
+ 0x4C5, 0x8CD, 0xADD, 0x2E5},
+ {0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA,
+ 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C,
+ 0x405, 0x20D, 0xA1D, 0x825},
+ {0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A,
+ 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC,
+ 0x505, 0x10D, 0xB1D, 0x725},
+ {0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A,
+ 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C,
+ 0x345, 0x74D, 0x95D, 0x165},
+ {0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA,
+ 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC,
+ 0x205, 0xA0D, 0x81D, 0x425},
+ {0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A,
+ 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C,
+ 0x2C5, 0x4CD, 0x8DD, 0xAE5},
+ {0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A,
+ 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC,
+ 0x285, 0x08D, 0x89D, 0x6A5},
+ {0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A,
+ 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C,
+ 0x085, 0x88D, 0x69D, 0x2A5},
+ {0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A,
+ 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC,
+ 0x105, 0xB0D, 0x71D, 0x525},
+ {0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A,
+ 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C,
+ 0x045, 0x44D, 0x65D, 0xA65},
+ };
+
+// _axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
+
+MINLINE int _axis_signed(const int axis)
+{
+ return (axis < 3) ? axis : axis - 3;
+}
+
+/*
+ * Each argument us an axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z']
+ * where the first 2 are a source and the second 2 are the target.
+ */
+int mat3_from_axis_conversion(int from_forward, int from_up, int to_forward, int to_up,
+ float r_mat[3][3])
+{
+ // from functools import reduce
+ int value;
+ int i;
+
+ if (from_forward == to_forward && from_up == to_up) {
+ unit_m3(r_mat);
+ return false;
+ }
+
+ if ((_axis_signed(from_forward) == _axis_signed(from_up)) ||
+ (_axis_signed(to_forward) == _axis_signed(to_up)))
+ {
+ /* we could assert here! */
+ unit_m3(r_mat);
+ return false;
+ }
+
+ value = ((from_forward << (0 * 3)) |
+ (from_up << (1 * 3)) |
+ (to_forward << (2 * 3)) |
+ (to_up << (3 * 3)));
+
+ for (i = 0; i < (sizeof(_axis_convert_matrix) / sizeof(*_axis_convert_matrix)); i++) {
+ int j;
+ for (j = 0; j < sizeof(*_axis_convert_lut) / sizeof(*_axis_convert_lut[0]); j++) {
+ if (_axis_convert_lut[i][j] == value) {
+ copy_m3_m3(r_mat, _axis_convert_matrix[i]);
+ return true;
+ }
+ }
+
+ }
+// BLI_assert(0);
+ return false;
+}
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 812e2b3e63d..58d444f5794 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -122,6 +122,32 @@ 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;
}
+/**
+ * Equivalent to:
+ * interp_v3_v3v3(v, v1, v2, -1.0f);
+ */
+
+void flip_v4_v4v4(float v[4], const float v1[4], const float v2[4])
+{
+ v[0] = v1[0] + (v1[0] - v2[0]);
+ v[1] = v1[1] + (v1[1] - v2[1]);
+ v[2] = v1[2] + (v1[2] - v2[2]);
+ v[3] = v1[3] + (v1[3] - v2[3]);
+}
+
+void flip_v3_v3v3(float v[3], const float v1[3], const float v2[3])
+{
+ v[0] = v1[0] + (v1[0] - v2[0]);
+ v[1] = v1[1] + (v1[1] - v2[1]);
+ v[2] = v1[2] + (v1[2] - v2[2]);
+}
+
+void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2])
+{
+ v[0] = v1[0] + (v1[0] - v2[0]);
+ v[1] = v1[1] + (v1[1] - v2[1]);
+}
+
/********************************** Angles ***********************************/
/* Return the angle in radians between vecs 1-2 and 2-3 in radians
@@ -209,11 +235,8 @@ float angle_signed_v2v2(const float v1[2], const float v2[2])
float angle_normalized_v3v3(const float v1[3], const float v2[3])
{
/* double check they are normalized */
-#ifdef DEBUG
- float test;
- BLI_assert(fabsf((test = len_squared_v3(v1)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
- BLI_assert(fabsf((test = len_squared_v3(v2)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
-#endif
+ BLI_ASSERT_UNIT_V3(v1);
+ BLI_ASSERT_UNIT_V3(v2);
/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
if (dot_v3v3(v1, v2) < 0.0f) {
@@ -232,11 +255,8 @@ float angle_normalized_v3v3(const float v1[3], const float v2[3])
float angle_normalized_v2v2(const float v1[2], const float v2[2])
{
/* double check they are normalized */
-#ifdef DEBUG
- float test;
- BLI_assert(fabsf((test = len_squared_v2(v1)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
- BLI_assert(fabsf((test = len_squared_v2(v2)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
-#endif
+ BLI_ASSERT_UNIT_V2(v1);
+ BLI_ASSERT_UNIT_V2(v2);
/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
if (dot_v2v2(v1, v2) < 0.0f) {
@@ -423,10 +443,7 @@ void rotate_normalized_v3_v3v3fl(float r[3], const float p[3], const float axis[
const float sintheta = sin(angle);
/* double check they are normalized */
-#ifdef DEBUG
- float test;
- BLI_assert(fabsf((test = len_squared_v3(axis)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
-#endif
+ BLI_ASSERT_UNIT_V3(axis);
r[0] = ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) +
(((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) +
@@ -685,6 +702,19 @@ void msub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array
}
}
+void interp_vn_vn(float *array_tar, const float *array_src, const float t, const int size)
+{
+ const float s = 1.0f - t;
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar) = (s * *(tar)) + (t * *(src));
+ tar--;
+ src--;
+ }
+}
+
void fill_vn_i(int *array_tar, const int size, const int val)
{
int *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 3ede8636aa5..48e7de43a86 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -461,7 +461,7 @@ MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
r[2] = v1[2] * v2[2];
}
-MINLINE void negate_v2(float r[3])
+MINLINE void negate_v2(float r[2])
{
r[0] = -r[0];
r[1] = -r[1];
@@ -528,6 +528,7 @@ MINLINE float cross_v2v2(const float a[2], const float b[2])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
{
+ BLI_assert(r != a && r != b);
r[0] = a[1] * b[2] - a[2] * b[1];
r[1] = a[2] * b[0] - a[0] * b[2];
r[2] = a[0] * b[1] - a[1] * b[0];
@@ -544,7 +545,7 @@ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const f
n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
}
-MINLINE void star_m3_v3(float rmat[][3], float a[3])
+MINLINE void star_m3_v3(float rmat[3][3], float a[3])
{
rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0;
rmat[0][1] = -a[2];
@@ -662,7 +663,7 @@ MINLINE float normalize_v3_v3(float r[3], const float a[3])
float d = dot_v3v3(a, a);
/* a larger value causes normalize errors in a
- * scaled down models with camera xtreme close */
+ * scaled down models with camera extreme close */
if (d > 1.0e-35f) {
d = sqrtf(d);
mul_v3_v3fl(r, a, 1.0f / d);
@@ -680,7 +681,7 @@ MINLINE double normalize_v3_d(double n[3])
double d = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
/* a larger value causes normalize errors in a
- * scaled down models with camera xtreme close */
+ * scaled down models with camera extreme close */
if (d > 1.0e-35) {
double mul;
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index f37e1e03f39..c159f707b98 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -1460,7 +1460,8 @@ float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noise
noisefunc = cellNoiseU;
break;
case 0:
- default: {
+ default:
+ {
noisefunc = orgBlenderNoise;
/* add one to make return value same as BLI_hnoise */
x += 1;
@@ -1592,7 +1593,8 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves
noisefunc = cellNoise;
break;
case 0:
- default: {
+ default:
+ {
noisefunc = orgBlenderNoiseS;
}
}
@@ -1662,7 +1664,8 @@ float mg_MultiFractal(float x, float y, float z, float H, float lacunarity, floa
noisefunc = cellNoise;
break;
case 0:
- default: {
+ default:
+ {
noisefunc = orgBlenderNoiseS;
}
}
@@ -1728,7 +1731,8 @@ float mg_HeteroTerrain(float x, float y, float z, float H, float lacunarity, flo
noisefunc = cellNoise;
break;
case 0:
- default: {
+ default:
+ {
noisefunc = orgBlenderNoiseS;
}
}
@@ -1801,7 +1805,8 @@ float mg_HybridMultiFractal(float x, float y, float z, float H, float lacunarity
noisefunc = cellNoise;
break;
case 0:
- default: {
+ default:
+ {
noisefunc = orgBlenderNoiseS;
}
}
@@ -1876,7 +1881,8 @@ float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity
noisefunc = cellNoise;
break;
case 0:
- default: {
+ default:
+ {
noisefunc = orgBlenderNoiseS;
}
}
@@ -1941,7 +1947,8 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba
noisefunc1 = cellNoise;
break;
case 0:
- default: {
+ default:
+ {
noisefunc1 = orgBlenderNoiseS;
}
}
@@ -1975,7 +1982,8 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba
noisefunc2 = cellNoise;
break;
case 0:
- default: {
+ default:
+ {
noisefunc2 = orgBlenderNoiseS;
}
}
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 444daf8817c..5265d862ab8 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -47,7 +47,7 @@
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
-#include "BKE_blender.h" /* BLENDER_VERSION */
+#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */
#include "GHOST_Path-api.h"
@@ -848,7 +848,7 @@ const char *BLI_getDefaultDocumentFolder(void)
/* ************************************************************* */
/* ************************************************************* */
-// #define PATH_DEBUG2
+// #define PATH_DEBUG
static char *blender_version_decimal(const int ver)
{
@@ -871,14 +871,14 @@ static int test_path(char *targetpath, const char *path_base, const char *path_s
BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
if (BLI_is_dir(targetpath)) {
-#ifdef PATH_DEBUG2
- printf("\tpath found: %s\n", targetpath);
+#ifdef PATH_DEBUG
+ printf("\t%s found: %s\n", __func__, targetpath);
#endif
return 1;
}
else {
-#ifdef PATH_DEBUG2
- printf("\tpath missing: %s\n", targetpath);
+#ifdef PATH_DEBUG
+ printf("\t%s missing: %s\n", __func__, targetpath);
#endif
//targetpath[0] = '\0';
return 0;
@@ -892,10 +892,16 @@ static int test_env_path(char *path, const char *envvar)
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 1;
}
else {
path[0] = '\0';
+#ifdef PATH_DEBUG
+ printf("\t%s env %s missing: %s\n", __func__, envvar, env);
+#endif
return 0;
}
}
@@ -904,8 +910,8 @@ static int get_path_local(char *targetpath, const char *folder_name, const char
{
char relfolder[FILE_MAX];
-#ifdef PATH_DEBUG2
- printf("get_path_local...\n");
+#ifdef PATH_DEBUG
+ printf("%s...\n", __func__);
#endif
if (folder_name) {
@@ -964,8 +970,8 @@ static int get_path_user(char *targetpath, const char *folder_name, const char *
if (!user_path[0])
return 0;
-#ifdef PATH_DEBUG2
- printf("get_path_user: %s\n", user_path);
+#ifdef PATH_DEBUG
+ printf("%s: %s\n", __func__, user_path);
#endif
if (subfolder_name) {
@@ -1034,8 +1040,8 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
if (!system_path[0])
return 0;
-#ifdef PATH_DEBUG2
- printf("get_path_system: %s\n", system_path);
+#ifdef PATH_DEBUG
+ printf("%s: %s\n", __func__, system_path);
#endif
if (subfolder_name) {
@@ -1174,7 +1180,7 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check)
#ifdef PATH_DEBUG
-#undef PATH_DEBUG
+# undef PATH_DEBUG
#endif
void BLI_setenv(const char *env, const char *val)
@@ -1212,8 +1218,6 @@ void BLI_setenv_if_new(const char *env, const char *val)
void BLI_clean(char *path)
{
- if (path == NULL) return;
-
#ifdef WIN32
if (path && BLI_strnlen(path, 3) > 2) {
BLI_char_switch(path + 2, '/', '\\');
@@ -1225,7 +1229,6 @@ void BLI_clean(char *path)
void BLI_char_switch(char *string, char from, char to)
{
- if (string == NULL) return;
while (*string != 0) {
if (*string == from) *string = to;
string++;
@@ -1622,7 +1625,7 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
rel_dir[0] = 0;
/* if image is "below" current .blend file directory */
- if (!strncmp(path, blend_dir, len)) {
+ if (!BLI_path_ncmp(path, blend_dir, len)) {
/* if image is _in_ current .blend file directory */
if (BLI_path_cmp(dir, blend_dir) == 0) {
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index ee073d5d309..4bd7715ea7a 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -109,9 +109,9 @@ static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], c
return 1; /* co-linear */
}
else {
- const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0);
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
}
static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
@@ -121,9 +121,9 @@ static int isect_segments_fl(const float v1[2], const float v2[2], const float v
return 1; /* co-linear */
}
else {
- const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0);
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
}
@@ -317,6 +317,30 @@ void BLI_rctf_resize(rctf *rect, float x, float y)
rect->ymax = rect->ymin + y;
}
+void BLI_rcti_scale(rcti *rect, const float scale)
+{
+ const int cent_x = BLI_rcti_cent_x(rect);
+ const int cent_y = BLI_rcti_cent_y(rect);
+ const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f);
+ const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
+}
+
+void BLI_rctf_scale(rctf *rect, const float scale)
+{
+ const float cent_x = BLI_rctf_cent_x(rect);
+ const float cent_y = BLI_rctf_cent_y(rect);
+ const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f);
+ const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
+}
+
void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac)
{
const float ifac = 1.0f - fac;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index defe500cb21..4d42d71f490 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -95,7 +95,7 @@ typedef struct ScanFillVertLink {
#define SF_EPSILON 0.00003f
-#define SF_VERT_UNKNOWN 1 /* TODO, what is this for exactly? - need to document it! */
+#define SF_VERT_AVAILABLE 1 /* available - in an edge */
#define SF_VERT_ZERO_LEN 255
/* Optionally set ScanFillEdge f to this to mark original boundary edges.
@@ -325,7 +325,9 @@ static short addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
fac1 = 1.0e10f * (eed->v2->xy[0] - x);
}
- else fac1 = (x - eed->v2->xy[0]) / fac1;
+ else {
+ fac1 = (x - eed->v2->xy[0]) / fac1;
+ }
for (ed = sc->edge_first; ed; ed = ed->next) {
@@ -422,7 +424,7 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
ScanFillEdge *eed, *ed1;
for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (eve->h == 1) {
+ if (eve->edge_tot == 1) {
/* find the edge which has vertex eve,
* note: we _know_ this will crash if 'ed1' becomes NULL
* but this will never happen. */
@@ -442,14 +444,14 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) {
if (compare_v3v3(eve->co, eed->v1->co, SF_EPSILON)) {
ed1->v2 = eed->v1;
- eed->v1->h++;
- eve->h = 0;
+ eed->v1->edge_tot++;
+ eve->edge_tot = 0;
break;
}
else if (compare_v3v3(eve->co, eed->v2->co, SF_EPSILON)) {
ed1->v2 = eed->v2;
- eed->v2->h++;
- eve->h = 0;
+ eed->v2->edge_tot++;
+ eve->edge_tot = 0;
break;
}
else {
@@ -459,11 +461,11 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
/* new edge */
ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
- /* printf("fill: vertex near edge %x\n",eve); */
+ /* printf("fill: vertex near edge %x\n", eve); */
ed1->f = 0;
ed1->poly_nr = eed->poly_nr;
eed->v1 = eve;
- eve->h = 3;
+ eve->edge_tot = 3;
break;
}
}
@@ -509,7 +511,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
ScanFillVert *eve, *v1, *v2, *v3;
ScanFillEdge *eed, *nexted, *ed1, *ed2, *ed3;
int a, b, verts, maxface, totface;
- short nr, test, twoconnected = 0;
+ short nr, twoconnected = 0;
nr = pf->nr;
@@ -565,6 +567,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
verts++;
eve->f = 0; /* flag for connectedges later on */
sc->vert = eve;
+ /* if (even->tmp.v == NULL) eve->tmp.u = verts; */ /* Note, debug print only will work for curve polyfill, union is in use for mesh */
sc++;
}
}
@@ -630,21 +633,28 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
/* (temporal) security: never much more faces than vertices */
totface = 0;
- maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */
+ if (flag & BLI_SCANFILL_CALC_HOLES) {
+ maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */
+ }
+ else {
+ maxface = verts - 2; /* when we don't calc any holes, we assume face is a non overlapping loop */
+ }
sc = sf_ctx->_scdata;
for (a = 0; a < verts; a++) {
- /* printf("VERTEX %d %x\n",a,sc->v1); */
+ /* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */
ed1 = sc->edge_first;
while (ed1) { /* set connectflags */
nexted = ed1->next;
- if (ed1->v1->h == 1 || ed1->v2->h == 1) {
+ if (ed1->v1->edge_tot == 1 || ed1->v2->edge_tot == 1) {
BLI_remlink((ListBase *)&(sc->edge_first), ed1);
BLI_addtail(&sf_ctx->filledgebase, ed1);
- if (ed1->v1->h > 1) ed1->v1->h--;
- if (ed1->v2->h > 1) ed1->v2->h--;
+ if (ed1->v1->edge_tot > 1) ed1->v1->edge_tot--;
+ if (ed1->v2->edge_tot > 1) ed1->v2->edge_tot--;
+ }
+ else {
+ ed1->v2->f = SF_VERT_AVAILABLE;
}
- else ed1->v2->f = SF_VERT_UNKNOWN;
ed1 = nexted;
}
@@ -654,7 +664,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
/* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */
/* if (callLocalInterruptCallBack()) break; */
- if (totface > maxface) {
+ if (totface >= maxface) {
/* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */
a = verts;
break;
@@ -664,83 +674,112 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
/* printf("just 1 edge to vert\n"); */
BLI_addtail(&sf_ctx->filledgebase, ed1);
ed1->v2->f = 0;
- ed1->v1->h--;
- ed1->v2->h--;
+ ed1->v1->edge_tot--;
+ ed1->v2->edge_tot--;
}
else {
/* test rest of vertices */
+ ScanFillVertLink *best_sc = NULL;
+ float best_angle = 3.14f;
float miny;
+ bool firsttime = false;
+
v1 = ed1->v2;
v2 = ed1->v1;
v3 = ed2->v2;
+
/* this happens with a serial of overlapping edges */
if (v1 == v2 || v2 == v3) break;
- /* printf("test verts %x %x %x\n",v1,v2,v3); */
+
+ /* printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
miny = min_ff(v1->xy[1], v3->xy[1]);
- /* miny = min_ff(v1->xy[1],v3->xy[1]); */
sc1 = sc + 1;
- test = 0;
- for (b = a + 1; b < verts; b++) {
+ for (b = a + 1; b < verts; b++, sc1++) {
if (sc1->vert->f == 0) {
if (sc1->vert->xy[1] <= miny) break;
-
- if (testedgeside(v1->xy, v2->xy, sc1->vert->xy))
- if (testedgeside(v2->xy, v3->xy, sc1->vert->xy))
+ if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) {
+ if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) {
if (testedgeside(v3->xy, v1->xy, sc1->vert->xy)) {
- /* point in triangle */
-
- test = 1;
- break;
+ /* point is in triangle */
+
+ /* because multiple points can be inside triangle (concave holes) */
+ /* we continue searching and pick the one with sharpest corner */
+
+ if (best_sc == NULL) {
+ best_sc = sc1;
+ /* only need to continue checking with holes */
+ if ((flag & BLI_SCANFILL_CALC_HOLES) == 0) {
+ break;
+ }
+ }
+ else {
+ float angle;
+
+ /* prevent angle calc for the simple cases only 1 vertex is found */
+ if (firsttime == false) {
+ best_angle = angle_v2v2v2(v2->co, v1->co, best_sc->vert->co);
+ firsttime = true;
+ }
+
+ angle = angle_v2v2v2(v2->co, v1->co, sc1->vert->co);
+ if (angle < best_angle) {
+ best_sc = sc1;
+ best_angle = angle;
+ }
+ }
+
}
+ }
+ }
}
- sc1++;
}
- if (test) {
+
+ if (best_sc) {
/* make new edge, and start over */
- /* printf("add new edge %x %x and start again\n",v2,sc1->vert); */
+ /* printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u); */
- ed3 = BLI_scanfill_edge_add(sf_ctx, v2, sc1->vert);
+ ed3 = BLI_scanfill_edge_add(sf_ctx, v2, best_sc->vert);
BLI_remlink(&sf_ctx->filledgebase, ed3);
BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed2, ed3);
- ed3->v2->f = SF_VERT_UNKNOWN;
+ ed3->v2->f = SF_VERT_AVAILABLE;
ed3->f = SF_EDGE_UNKNOWN;
- ed3->v1->h++;
- ed3->v2->h++;
+ ed3->v1->edge_tot++;
+ ed3->v2->edge_tot++;
}
else {
/* new triangle */
- /* printf("add face %x %x %x\n",v1,v2,v3); */
+ /* printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
addfillface(sf_ctx, v1, v2, v3);
totface++;
BLI_remlink((ListBase *)&(sc->edge_first), ed1);
BLI_addtail(&sf_ctx->filledgebase, ed1);
ed1->v2->f = 0;
- ed1->v1->h--;
- ed1->v2->h--;
+ ed1->v1->edge_tot--;
+ ed1->v2->edge_tot--;
/* ed2 can be removed when it's a boundary edge */
if ((ed2->f == 0 && twoconnected) || (ed2->f == SF_EDGE_BOUNDARY)) {
BLI_remlink((ListBase *)&(sc->edge_first), ed2);
BLI_addtail(&sf_ctx->filledgebase, ed2);
ed2->v2->f = 0;
- ed2->v1->h--;
- ed2->v2->h--;
+ ed2->v1->edge_tot--;
+ ed2->v2->edge_tot--;
}
/* new edge */
ed3 = BLI_scanfill_edge_add(sf_ctx, v1, v3);
BLI_remlink(&sf_ctx->filledgebase, ed3);
ed3->f = SF_EDGE_UNKNOWN;
- ed3->v1->h++;
- ed3->v2->h++;
+ ed3->v1->edge_tot++;
+ ed3->v2->edge_tot++;
- /* printf("add new edge %x %x\n",v1,v3); */
+ /* printf("add new edge %x %x\n", v1, v3); */
sc1 = addedgetoscanlist(sf_ctx, ed3, verts);
if (sc1) { /* ed3 already exists: remove if a boundary */
/* printf("Edge exists\n"); */
- ed3->v1->h--;
- ed3->v2->h--;
+ ed3->v1->edge_tot--;
+ ed3->v2->edge_tot--;
ed3 = sc1->edge_first;
while (ed3) {
@@ -748,37 +787,41 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
if (twoconnected || ed3->f == SF_EDGE_BOUNDARY) {
BLI_remlink((ListBase *)&(sc1->edge_first), ed3);
BLI_addtail(&sf_ctx->filledgebase, ed3);
- ed3->v1->h--;
- ed3->v2->h--;
+ ed3->v1->edge_tot--;
+ ed3->v2->edge_tot--;
}
break;
}
ed3 = ed3->next;
}
}
-
}
}
+
/* test for loose edges */
ed1 = sc->edge_first;
while (ed1) {
nexted = ed1->next;
- if (ed1->v1->h < 2 || ed1->v2->h < 2) {
+ if (ed1->v1->edge_tot < 2 || ed1->v2->edge_tot < 2) {
BLI_remlink((ListBase *)&(sc->edge_first), ed1);
BLI_addtail(&sf_ctx->filledgebase, ed1);
- if (ed1->v1->h > 1) ed1->v1->h--;
- if (ed1->v2->h > 1) ed1->v2->h--;
+ if (ed1->v1->edge_tot > 1) ed1->v1->edge_tot--;
+ if (ed1->v2->edge_tot > 1) ed1->v2->edge_tot--;
}
ed1 = nexted;
}
+ /* done with loose edges */
}
+
sc++;
}
MEM_freeN(sf_ctx->_scdata);
sf_ctx->_scdata = NULL;
+ BLI_assert(totface <= maxface);
+
return totface;
}
@@ -820,7 +863,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
while (eve) {
eve->f = 0;
eve->poly_nr = 0;
- eve->h = 0;
+ eve->edge_tot = 0;
eve = eve->next;
a += 1;
}
@@ -858,15 +901,15 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
eed = sf_ctx->filledgebase.first;
while (eed) {
eed->poly_nr = 0;
- eed->v1->f = SF_VERT_UNKNOWN;
- eed->v2->f = SF_VERT_UNKNOWN;
+ eed->v1->f = SF_VERT_AVAILABLE;
+ eed->v2->f = SF_VERT_AVAILABLE;
eed = eed->next;
}
eve = sf_ctx->fillvertbase.first;
while (eve) {
- if (eve->f & SF_VERT_UNKNOWN) {
+ if (eve->f & SF_VERT_AVAILABLE) {
ok = 1;
break;
}
@@ -910,56 +953,74 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
/* STEP 1: COUNT POLYS */
- eve = sf_ctx->fillvertbase.first;
- while (eve) {
- eve->xy[0] = eve->co[co_x];
- eve->xy[1] = eve->co[co_y];
+ if (flag & BLI_SCANFILL_CALC_HOLES) {
+ eve = sf_ctx->fillvertbase.first;
+ while (eve) {
+ eve->xy[0] = eve->co[co_x];
+ eve->xy[1] = eve->co[co_y];
+
+ /* get first vertex with no poly number */
+ if (eve->poly_nr == 0) {
+ poly++;
+ /* now a sort of select connected */
+ ok = 1;
+ eve->poly_nr = poly;
- /* get first vertex with no poly number */
- if (eve->poly_nr == 0) {
- poly++;
- /* now a sort of select connected */
- ok = 1;
- eve->poly_nr = poly;
-
- while (ok) {
-
- ok = 0;
- toggle++;
- if (toggle & 1) eed = sf_ctx->filledgebase.first;
- else eed = sf_ctx->filledgebase.last;
-
- while (eed) {
- if (eed->v1->poly_nr == 0 && eed->v2->poly_nr == poly) {
- eed->v1->poly_nr = poly;
- eed->poly_nr = poly;
- ok = 1;
- }
- else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) {
- eed->v2->poly_nr = poly;
- eed->poly_nr = poly;
- ok = 1;
- }
- else if (eed->poly_nr == 0) {
- if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) {
+ while (ok) {
+
+ ok = 0;
+ toggle++;
+ if (toggle & 1) eed = sf_ctx->filledgebase.first;
+ else eed = sf_ctx->filledgebase.last;
+
+ while (eed) {
+ if (eed->v1->poly_nr == 0 && eed->v2->poly_nr == poly) {
+ eed->v1->poly_nr = poly;
eed->poly_nr = poly;
ok = 1;
}
+ else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) {
+ eed->v2->poly_nr = poly;
+ eed->poly_nr = poly;
+ ok = 1;
+ }
+ else if (eed->poly_nr == 0) {
+ if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) {
+ eed->poly_nr = poly;
+ ok = 1;
+ }
+ }
+ if (toggle & 1) eed = eed->next;
+ else eed = eed->prev;
}
- if (toggle & 1) eed = eed->next;
- else eed = eed->prev;
}
}
+ eve = eve->next;
+ }
+ /* printf("amount of poly's: %d\n", poly); */
+ }
+ else {
+ poly = 1;
+
+ eve = sf_ctx->fillvertbase.first;
+ while (eve) {
+ eve->xy[0] = eve->co[co_x];
+ eve->xy[1] = eve->co[co_y];
+ eve->poly_nr = poly;
+ eve = eve->next;
+ }
+ eed = sf_ctx->filledgebase.first;
+ while (eed) {
+ eed->poly_nr = poly;
+ eed = eed->next;
}
- eve = eve->next;
}
- /* printf("amount of poly's: %d\n",poly); */
/* STEP 2: remove loose edges and strings of edges */
eed = sf_ctx->filledgebase.first;
while (eed) {
- if (eed->v1->h++ > 250) break;
- if (eed->v2->h++ > 250) break;
+ if (eed->v1->edge_tot++ > 250) break;
+ if (eed->v2->edge_tot++ > 250) break;
eed = eed->next;
}
if (eed) {
@@ -980,14 +1041,14 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
while (eed) {
if (toggle & 1) nexted = eed->next;
else nexted = eed->prev;
- if (eed->v1->h == 1) {
- eed->v2->h--;
+ if (eed->v1->edge_tot == 1) {
+ eed->v2->edge_tot--;
BLI_remlink(&sf_ctx->fillvertbase, eed->v1);
BLI_remlink(&sf_ctx->filledgebase, eed);
ok = 1;
}
- else if (eed->v2->h == 1) {
- eed->v1->h--;
+ else if (eed->v2->edge_tot == 1) {
+ eed->v1->edge_tot--;
BLI_remlink(&sf_ctx->fillvertbase, eed->v2);
BLI_remlink(&sf_ctx->filledgebase, eed);
ok = 1;
@@ -1002,13 +1063,13 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
/* CURRENT STATUS:
- * - eve->f :1 = available in edges
- * - eve->xs :polynumber
- * - eve->h :amount of edges connected to vertex
- * - eve->tmp.v :store! original vertex number
+ * - eve->f :1 = available in edges
+ * - eve->poly_nr :polynumber
+ * - eve->edge_tot :amount of edges connected to vertex
+ * - eve->tmp.v :store! original vertex number
*
- * - eed->f :1 = boundary edge (optionally set by caller)
- * - eed->poly_nr :poly number
+ * - eed->f :1 = boundary edge (optionally set by caller)
+ * - eed->poly_nr :poly number
*/
@@ -1037,7 +1098,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
min_xy_p[1] = (min_xy_p[1]) < (eve->xy[1]) ? (min_xy_p[1]) : (eve->xy[1]);
max_xy_p[0] = (max_xy_p[0]) > (eve->xy[0]) ? (max_xy_p[0]) : (eve->xy[0]);
max_xy_p[1] = (max_xy_p[1]) > (eve->xy[1]) ? (max_xy_p[1]) : (eve->xy[1]);
- if (eve->h > 2) pflist[eve->poly_nr - 1].f = 1;
+ if (eve->edge_tot > 2) pflist[eve->poly_nr - 1].f = 1;
eve = eve->next;
}
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index f23f75f69d9..3500f3f1805 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -199,12 +199,15 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
/* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */
startMatch = strstr(str, prefix) + prefixLen + 1;
-
- /* get the end point (i.e. where the next occurance of " is after the starting point) */
- endMatch = strchr(startMatch, '"'); /* " NOTE: this comment here is just so that my text editor still shows the functions ok... */
-
- /* return the slice indicated */
- return BLI_strdupn(startMatch, (size_t)(endMatch - startMatch));
+ if (startMatch) {
+ /* get the end point (i.e. where the next occurance of " is after the starting point) */
+ endMatch = strchr(startMatch, '"'); /* " NOTE: this comment here is just so that my text editor still shows the functions ok... */
+
+ if (endMatch)
+ /* return the slice indicated */
+ return BLI_strdupn(startMatch, (size_t)(endMatch - startMatch));
+ }
+ return BLI_strdupn("", 0);
}
/* Replaces all occurrences of oldText with newText in str, returning a new string that doesn't
@@ -412,7 +415,7 @@ int BLI_natstrcmp(const char *s1, const char *s2)
void BLI_timestr(double _time, char *str)
{
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
- int hr = ( (int) _time) / (60*60);
+ int hr = ( (int) _time) / (60 * 60);
int min = (((int) _time) / 60 ) % 60;
int sec = ( (int) (_time)) % 60;
int hun = ( (int) (_time * 100.0)) % 100;
diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c
index 65763f21b0f..674d5ae5c8d 100644
--- a/source/blender/blenlib/intern/string_cursor_utf8.c
+++ b/source/blender/blenlib/intern/string_cursor_utf8.c
@@ -139,12 +139,17 @@ int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *p
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
int *pos, strCursorJumpDirection direction,
- strCursorJumpType jump)
+ strCursorJumpType jump, bool use_init_step)
{
const int pos_prev = *pos;
if (direction == STRCUR_DIR_NEXT) {
- BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+ if (use_init_step) {
+ BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+ }
+ else {
+ BLI_assert(jump == STRCUR_JUMP_DELIM);
+ }
if (jump != STRCUR_JUMP_NONE) {
const strCursorDelimType delim_type = (*pos) < maxlen ? cursor_delim_type(&str[*pos]) : STRCUR_DELIM_NONE;
@@ -163,7 +168,12 @@ void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
}
}
else if (direction == STRCUR_DIR_PREV) {
- BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
+ if (use_init_step) {
+ BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
+ }
+ else {
+ BLI_assert(jump == STRCUR_JUMP_DELIM);
+ }
if (jump != STRCUR_JUMP_NONE) {
const strCursorDelimType delim_type = (*pos) > 1 ? cursor_delim_type(&str[(*pos) - 1]) : STRCUR_DELIM_NONE;
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index bf98f2ae77c..26235de4dd2 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -114,7 +114,7 @@ int BLI_utf8_invalid_byte(const char *str, int length)
/* Check for valid bytes after the 2nd, if any; all must start 10 */
while (--ab > 0) {
- if ((*(p+1) & 0xc0) != 0x80) goto utf8_error;
+ if ((*(p + 1) & 0xc0) != 0x80) goto utf8_error;
p++; /* do this after so we get usable offset - campbell */
}
}
@@ -369,7 +369,7 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__rest
int BLI_str_utf8_size(const char *p)
{
int mask = 0, len;
- unsigned char c = (unsigned char) *p;
+ const unsigned char c = (unsigned char) *p;
UTF8_COMPUTE (c, mask, len, -1);
@@ -382,7 +382,7 @@ int BLI_str_utf8_size(const char *p)
int BLI_str_utf8_size_safe(const char *p)
{
int mask = 0, len;
- unsigned char c = (unsigned char) *p;
+ const unsigned char c = (unsigned char) *p;
UTF8_COMPUTE (c, mask, len, 1);
@@ -408,10 +408,10 @@ unsigned int BLI_str_utf8_as_unicode(const char *p)
{
int i, mask = 0, len;
unsigned int result;
- unsigned char c = (unsigned char) *p;
+ const unsigned char c = (unsigned char) *p;
UTF8_COMPUTE (c, mask, len, -1);
- if (len == -1)
+ if (UNLIKELY(len == -1))
return BLI_UTF8_ERR;
UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
@@ -423,16 +423,32 @@ unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *
{
int i, mask = 0, len;
unsigned int result;
- unsigned char c = (unsigned char) *p;
+ const unsigned char c = (unsigned char) *p;
UTF8_COMPUTE (c, mask, len, -1);
- if (len == -1)
+ if (UNLIKELY(len == -1))
return BLI_UTF8_ERR;
UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
*index += len;
return result;
}
+unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index)
+{
+ int i, mask = 0, len;
+ unsigned int result;
+ const unsigned char c = (unsigned char) *p;
+
+ UTF8_COMPUTE (c, mask, len, -1);
+ if (UNLIKELY(len == -1)) {
+ *index += 1;
+ return c;
+ }
+ UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR);
+ *index += len;
+ return result;
+}
+
/* another variant that steps over the index,
* note, currently this also falls back to latin1 for text drawing. */
unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index)
@@ -445,7 +461,7 @@ unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__re
c = (unsigned char) *p;
UTF8_COMPUTE (c, mask, len, -1);
- if (len == -1) {
+ if (UNLIKELY(len == -1)) {
/* when called with NULL end, result will never be NULL,
* checks for a NULL character */
char *p_next = BLI_str_find_next_char_utf8(p, NULL);
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 146e1d531f1..686484ef1db 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -729,6 +729,9 @@ void BLI_thread_queue_wait_finish(ThreadQueue *queue)
void BLI_begin_threaded_malloc(void)
{
+ /* Used for debug only */
+ /* BLI_assert(thread_levels >= 0); */
+
if (thread_levels == 0) {
MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
}
@@ -737,6 +740,9 @@ void BLI_begin_threaded_malloc(void)
void BLI_end_threaded_malloc(void)
{
+ /* Used for debug only */
+ /* BLI_assert(thread_levels >= 0); */
+
thread_levels--;
if (thread_levels == 0)
MEM_set_lock_callback(NULL, NULL);
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 68d9d74cca4..65fb490b218 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -41,7 +41,7 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BKE_global.h"
+#include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */
#define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
#include "BLI_winstuff.h"
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 16a4d8d46ec..2ee5decdfac 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -240,13 +240,32 @@ struct ID *BLO_library_append_named_part_ex(const struct bContext *C, struct Mai
void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle **bh, int idcode, short flag);
+void BLO_library_append_all(struct Main *mainl, BlendHandle *bh);
+
void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);
BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, struct ReportList *reports);
-
+
/* internal function but we need to expose it */
void blo_lib_link_screen_restore(struct Main *newmain, struct bScreen *curscreen, struct Scene *curscene);
+/**
+ * BLO_expand_main() loops over all ID data in Main to mark relations.
+ * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding.
+ *
+ * \param expand_doit_func() gets called for each ID block it finds
+ */
+void BLO_main_expander(void (*expand_doit_func)(void *, struct Main *, void *));
+
+/**
+ * BLO_expand_main() loops over all ID data in Main to mark relations.
+ * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding.
+ *
+ * \param fdhandle usually filedata, or own handle
+ * \param mainvar the Main database to expand
+ */
+void BLO_expand_main(void *fdhandle, struct Main *mainvar);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index 3c5812fa513..5b929195aea 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -52,7 +52,6 @@ set(SRC
BLO_blend_defs.h
BLO_readfile.h
BLO_runtime.h
- BLO_soundfile.h
BLO_sys_types.h
BLO_undofile.h
BLO_writefile.h
diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript
index 49e8869637e..8950c4f7702 100644
--- a/source/blender/blenloader/SConscript
+++ b/source/blender/blenloader/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index e9caa337129..5111baa06c1 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -311,6 +311,8 @@ 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);
+ /* removed packed data from this trick - it's internal data that needs saves */
+
bfd = blo_read_file_internal(fd, filename);
/* ensures relinked images are not freed */
@@ -318,7 +320,7 @@ 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);
-
+
/* 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 203af1d8316..1ad6f1bf78a 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -41,6 +41,7 @@
#include <math.h> // for fabs
#include <stdarg.h> /* for va_start/end */
+#include "BLI_utildefines.h"
#ifndef WIN32
# include <unistd.h> // for read close
#else
@@ -81,6 +82,7 @@
#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
#include "DNA_property_types.h"
+#include "DNA_rigidbody_types.h"
#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
@@ -116,6 +118,7 @@
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_deform.h"
+#include "BKE_depsgraph.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_global.h" // for G
@@ -210,20 +213,6 @@
* - initialize FileGlobal and copy pointers to Global
*/
-/* also occurs in library.c */
-/* GS reads the memory pointed at in a specific ordering. There are,
- * however two definitions for it. I have jotted them down here, both,
- * but I think the first one is actually used. The thing is that
- * big-endian systems might read this the wrong way round. OTOH, we
- * constructed the IDs that are read out with this macro explicitly as
- * well. I expect we'll sort it out soon... */
-
-/* from blendef: */
-#define GS(a) (*((short *)(a)))
-
-/* from misc_util: flip the bytes from x */
-/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-
/***/
typedef struct OldNew {
@@ -543,7 +532,9 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
BLI_strncpy(name1, filepath, sizeof(name1));
cleanup_path(relabase, name1);
-// printf("blo_find_main: original in %s\n", name);
+
+// printf("blo_find_main: relabase %s\n", relabase);
+// printf("blo_find_main: original in %s\n", filepath);
// printf("blo_find_main: converted to %s\n", name1);
for (m = mainlist->first; m; m = m->next) {
@@ -839,7 +830,7 @@ static int read_file_dna(FileData *fd)
for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
if (bhead->code == DNA1) {
- int do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) ? 1 : 0;
+ const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap);
if (fd->filesdna) {
@@ -962,11 +953,11 @@ static FileData *filedata_new(void)
fd->filedes = -1;
fd->gzfiledes = NULL;
- /* XXX, this doesn't need to be done all the time,
- * but it keeps us re-entrant, remove once we have
- * a lib that provides a nice lock. - zr
- */
- fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, 0);
+ /* XXX, this doesn't need to be done all the time,
+ * but it keeps us re-entrant, remove once we have
+ * a lib that provides a nice lock. - zr
+ */
+ fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false);
fd->datamap = oldnewmap_new();
fd->globmap = oldnewmap_new();
@@ -1020,6 +1011,46 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports)
}
}
+static int fd_read_gzip_from_memory(FileData *filedata, void *buffer, unsigned int size)
+{
+ int err;
+
+ filedata->strm.next_out = (Bytef *) buffer;
+ filedata->strm.avail_out = size;
+
+ // Inflate another chunk.
+ err = inflate (&filedata->strm, Z_SYNC_FLUSH);
+
+ if (err == Z_STREAM_END) {
+ return 0;
+ }
+ else if (err != Z_OK) {
+ printf("fd_read_gzip_from_memory: zlib error\n");
+ return 0;
+ }
+
+ filedata->seek += size;
+
+ return (size);
+}
+
+static int fd_read_gzip_from_memory_init(FileData *fd)
+{
+
+ fd->strm.next_in = (Bytef *) fd->buffer;
+ fd->strm.avail_in = fd->buffersize;
+ fd->strm.total_out = 0;
+ fd->strm.zalloc = Z_NULL;
+ fd->strm.zfree = Z_NULL;
+
+ if (inflateInit2(&fd->strm, (16+MAX_WBITS)) != Z_OK)
+ return 0;
+
+ fd->read = fd_read_gzip_from_memory;
+
+ return 1;
+}
+
FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports)
{
if (!mem || memsize<SIZEOFBLENDERHEADER) {
@@ -1028,11 +1059,23 @@ FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports)
}
else {
FileData *fd = filedata_new();
+ char *cp = mem;
+
fd->buffer = mem;
fd->buffersize = memsize;
- fd->read = fd_read_from_memory;
- fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
+ /* test if gzip */
+ if (cp[0] == 0x1f && cp[1] == 0x8b) {
+ if (0 == fd_read_gzip_from_memory_init(fd)) {
+ blo_freefiledata(fd);
+ return NULL;
+ }
+ }
+ else
+ fd->read = fd_read_from_memory;
+
+ fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
+
return blo_decode_and_check(fd, reports);
}
}
@@ -1066,6 +1109,12 @@ void blo_freefiledata(FileData *fd)
gzclose(fd->gzfiledes);
}
+ if (fd->strm.next_in) {
+ if (inflateEnd (&fd->strm) != Z_OK) {
+ printf("close gzip stream error\n");
+ }
+ }
+
if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
MEM_freeN(fd->buffer);
fd->buffer = NULL;
@@ -1089,6 +1138,8 @@ void blo_freefiledata(FileData *fd)
oldnewmap_free(fd->imamap);
if (fd->movieclipmap)
oldnewmap_free(fd->movieclipmap);
+ if (fd->packedmap)
+ oldnewmap_free(fd->packedmap);
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
oldnewmap_free(fd->libmap);
if (fd->bheadmap)
@@ -1154,25 +1205,33 @@ static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
return oldnewmap_lookup_and_inc(fd->datamap, adr);
}
-static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
+static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
{
return oldnewmap_lookup_and_inc(fd->globmap, adr);
}
-static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
+static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
{
if (fd->imamap && adr)
return oldnewmap_lookup_and_inc(fd->imamap, adr);
return NULL;
}
-static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
+static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
{
if (fd->movieclipmap && adr)
return oldnewmap_lookup_and_inc(fd->movieclipmap, adr);
return NULL;
}
+static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */
+{
+ if (fd->packedmap && adr)
+ return oldnewmap_lookup_and_inc(fd->packedmap, adr);
+
+ return oldnewmap_lookup_and_inc(fd->datamap, adr);
+}
+
static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
{
@@ -1369,6 +1428,71 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
}
}
+/* 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)
+{
+ oldnewmap_insert(fd->packedmap, pf, pf, 0);
+ oldnewmap_insert(fd->packedmap, pf->data, pf->data, 0);
+}
+
+void blo_make_packed_pointer_map(FileData *fd, Main *oldmain)
+{
+ Image *ima;
+ VFont *vfont;
+ bSound *sound;
+ Library *lib;
+
+ fd->packedmap = oldnewmap_new();
+
+ for (ima = oldmain->image.first; ima; ima = ima->id.next)
+ if (ima->packedfile)
+ insert_packedmap(fd, ima->packedfile);
+
+ for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
+ if (vfont->packedfile)
+ insert_packedmap(fd, vfont->packedfile);
+
+ for (sound = oldmain->sound.first; sound; sound = sound->id.next)
+ if (sound->packedfile)
+ insert_packedmap(fd, sound->packedfile);
+
+ for (lib = oldmain->library.first; lib; lib = lib->id.next)
+ if (lib->packedfile)
+ insert_packedmap(fd, lib->packedfile);
+
+}
+
+/* set old main packed data to zero if it has been restored */
+/* this works because freeing old main only happens after this call */
+void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
+{
+ Image *ima;
+ VFont *vfont;
+ bSound *sound;
+ Library *lib;
+ OldNew *entry = fd->packedmap->entries;
+ int i;
+
+ /* used entries were restored, so we put them to zero */
+ for (i=0; i < fd->packedmap->nentries; i++, entry++) {
+ if (entry->nr > 0)
+ entry->newp = NULL;
+ }
+
+ for (ima = oldmain->image.first; ima; ima = ima->id.next)
+ ima->packedfile = newpackedadr(fd, ima->packedfile);
+
+ for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
+ vfont->packedfile = newpackedadr(fd, vfont->packedfile);
+
+ for (sound = oldmain->sound.first; sound; sound = sound->id.next)
+ sound->packedfile = newpackedadr(fd, sound->packedfile);
+
+ for (lib = oldmain->library.first; lib; lib = lib->id.next)
+ lib->packedfile = newpackedadr(fd, lib->packedfile);
+}
+
/* undo file support: add all library pointers in lookup */
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd)
@@ -1708,10 +1832,10 @@ static void direct_link_script(FileData *UNUSED(fd), Script *script)
static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
{
- PackedFile *pf = newdataadr(fd, oldpf);
+ PackedFile *pf = newpackedadr(fd, oldpf);
if (pf) {
- pf->data = newdataadr(fd, pf->data);
+ pf->data = newpackedadr(fd, pf->data);
}
return pf;
@@ -1729,6 +1853,7 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
if (prv->rect[i]) {
prv->rect[i] = newdataadr(fd, prv->rect[i]);
}
+ prv->gputexture[i] = NULL;
}
}
@@ -2535,7 +2660,7 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
cld.fd = fd;
cld.id = id;
- id_loop_constraints(conlist, lib_link_constraint_cb, &cld);
+ BKE_id_loop_constraints(conlist, lib_link_constraint_cb, &cld);
}
static void direct_link_constraints(FileData *fd, ListBase *lb)
@@ -2556,15 +2681,15 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
data->prop = newdataadr(fd, data->prop);
if (data->prop)
IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- }
break;
+ }
case CONSTRAINT_TYPE_SPLINEIK:
{
bSplineIKConstraint *data= con->data;
-
+
data->points= newdataadr(fd, data->points);
- }
break;
+ }
case CONSTRAINT_TYPE_KINEMATIC:
{
bKinematicConstraint *data = con->data;
@@ -2574,30 +2699,32 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
/* version patch for runtime flag, was not cleared in some case */
data->flag &= ~CONSTRAINT_IK_AUTO;
+ break;
}
case CONSTRAINT_TYPE_CHILDOF:
{
/* XXX version patch, in older code this flag wasn't always set, and is inherent to type */
if (con->ownspace == CONSTRAINT_SPACE_POSE)
con->flag |= CONSTRAINT_SPACEONCE;
- }
break;
+ }
}
}
}
-static void lib_link_pose(FileData *fd, Object *ob, bPose *pose)
+static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
{
bPoseChannel *pchan;
bArmature *arm = ob->data;
- int rebuild;
+ int rebuild = 0;
if (!pose || !arm)
return;
-
- /* always rebuild to match proxy or lib changes */
- rebuild = ob->proxy || (ob->id.lib==NULL && arm->id.lib);
+ /* always rebuild to match proxy or lib changes, but on Undo */
+ if (fd->memfile == NULL)
+ if (ob->proxy || (ob->id.lib==NULL && arm->id.lib))
+ rebuild = 1;
if (ob->proxy) {
/* sync proxy layer */
@@ -2629,7 +2756,7 @@ static void lib_link_pose(FileData *fd, Object *ob, bPose *pose)
}
if (rebuild) {
- ob->recalc = (OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
pose->flag |= POSE_RECALC;
}
}
@@ -2981,7 +3108,7 @@ static void direct_link_text(FileData *fd, Text *text)
if (text->flags & TXT_ISEXT) {
BKE_text_reload(text);
}
- else {
+ /* else { */
#endif
link_list(fd, &text->lines);
@@ -3207,7 +3334,7 @@ static void direct_link_texture(FileData *fd, Tex *tex)
tex->env = newdataadr(fd, tex->env);
if (tex->env) {
tex->env->ima = NULL;
- memset(tex->env->cube, 0, 6*sizeof(void *));
+ memset(tex->env->cube, 0, 6 * sizeof(void *));
tex->env->ok= 0;
}
tex->pd = newdataadr(fd, tex->pd);
@@ -4042,8 +4169,6 @@ static void lib_link_object(FileData *fd, Main *main)
else {
/* this triggers object_update to always use a copy */
ob->proxy->proxy_from = ob;
- /* force proxy updates after load/undo, a bit weak */
- ob->recalc = ob->proxy->recalc = (OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
ob->proxy_group = newlibadr(fd, ob->id.lib, ob->proxy_group);
@@ -4096,7 +4221,7 @@ static void lib_link_object(FileData *fd, Main *main)
/* if id.us==0 a new base will be created later on */
/* WARNING! Also check expand_object(), should reflect the stuff below. */
- lib_link_pose(fd, ob, ob->pose);
+ lib_link_pose(fd, main, ob, ob->pose);
lib_link_constraints(fd, &ob->id, &ob->constraints);
// XXX deprecated - old animation system <<<
@@ -4241,6 +4366,11 @@ static void lib_link_object(FileData *fd, Main *main)
lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
lib_link_modifiers(fd, ob);
+
+ if (ob->rigidbody_constraint) {
+ ob->rigidbody_constraint->ob1 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob1);
+ ob->rigidbody_constraint->ob2 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob2);
+ }
}
}
@@ -4664,6 +4794,20 @@ static void direct_link_object(FileData *fd, Object *ob)
}
ob->bsoft = newdataadr(fd, ob->bsoft);
ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
+
+ ob->rigidbody_object = newdataadr(fd, ob->rigidbody_object);
+ if (ob->rigidbody_object) {
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ /* must nullify the references to physics sim objects, since they no-longer exist
+ * (and will need to be recalculated)
+ */
+ rbo->physics_object = NULL;
+ rbo->physics_shape = NULL;
+ }
+ ob->rigidbody_constraint = newdataadr(fd, ob->rigidbody_constraint);
+ if (ob->rigidbody_constraint)
+ ob->rigidbody_constraint->physics_constraint = NULL;
link_list(fd, &ob->particlesystem);
direct_link_particlesystems(fd, &ob->particlesystem);
@@ -4882,6 +5026,18 @@ static void lib_link_scene(FileData *fd, Main *main)
BKE_sequencer_update_muting(sce->ed);
BKE_sequencer_update_sound_bounds_all(sce);
+
+ /* rigidbody world relies on it's linked groups */
+ if (sce->rigidbody_world) {
+ RigidBodyWorld *rbw = sce->rigidbody_world;
+ if (rbw->group)
+ rbw->group = newlibadr(fd, sce->id.lib, rbw->group);
+ if (rbw->constraints)
+ rbw->constraints = newlibadr(fd, sce->id.lib, rbw->constraints);
+ if (rbw->effector_weights)
+ rbw->effector_weights->group = newlibadr(fd, sce->id.lib, rbw->effector_weights->group);
+ }
+
if (sce->nodetree) {
lib_link_ntree(fd, &sce->id, sce->nodetree);
composite_patch(sce->nodetree, sce);
@@ -4958,9 +5114,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
Editing *ed;
Sequence *seq;
MetaStack *ms;
+ RigidBodyWorld *rbw;
sce->theDag = NULL;
- sce->dagisvalid = 0;
sce->obedit = NULL;
sce->stats = NULL;
sce->fps_info = NULL;
@@ -4991,6 +5147,16 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->toolsettings->imapaint.paintcursor = NULL;
sce->toolsettings->particle.paintcursor = NULL;
+
+ /* in rare cases this is needed, see [#33806] */
+ if (sce->toolsettings->vpaint) {
+ sce->toolsettings->vpaint->vpaint_prev = NULL;
+ sce->toolsettings->vpaint->tot = 0;
+ }
+ if (sce->toolsettings->wpaint) {
+ sce->toolsettings->wpaint->wpaint_prev = NULL;
+ sce->toolsettings->wpaint->tot = 0;
+ }
}
if (sce->ed) {
@@ -5134,6 +5300,28 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
direct_link_view_settings(fd, &sce->view_settings);
+
+ sce->rigidbody_world = newdataadr(fd, sce->rigidbody_world);
+ rbw = sce->rigidbody_world;
+ if (rbw) {
+ /* must nullify the reference to physics sim object, since it no-longer exist
+ * (and will need to be recalculated)
+ */
+ rbw->physics_world = NULL;
+ rbw->objects = NULL;
+ rbw->numbodies = 0;
+
+ /* set effector weights */
+ rbw->effector_weights = newdataadr(fd, rbw->effector_weights);
+ if (!rbw->effector_weights)
+ rbw->effector_weights = BKE_add_effector_weights(NULL);
+
+ /* link cache */
+ direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, FALSE);
+ /* make sure simulation starts from the beginning after loading file */
+ if (rbw->pointcache)
+ rbw->ltime = rbw->pointcache->startframe;
+ }
}
/* ************ READ WM ***************** */
@@ -5160,6 +5348,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->drawdata = NULL;
win->drawmethod = -1;
win->drawfail = 0;
+ win->active = 0;
}
wm->timers.first = wm->timers.last = NULL;
@@ -5231,27 +5420,6 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
/* ****************** READ SCREEN ***************** */
-static void butspace_version_132(SpaceButs *buts)
-{
- buts->v2d.tot.xmin = 0.0f;
- buts->v2d.tot.ymin = 0.0f;
- buts->v2d.tot.xmax = 1279.0f;
- buts->v2d.tot.ymax = 228.0f;
-
- buts->v2d.min[0] = 256.0f;
- buts->v2d.min[1] = 42.0f;
-
- buts->v2d.max[0] = 2048.0f;
- buts->v2d.max[1] = 450.0f;
-
- buts->v2d.minzoom = 0.5f;
- buts->v2d.maxzoom = 1.21f;
-
- buts->v2d.scroll = 0;
- buts->v2d.keepzoom = 1;
- buts->v2d.keeptot = 1;
-}
-
/* note: file read without screens option G_FILE_NO_UI;
* check lib pointers in call below */
static void lib_link_screen(FileData *fd, Main *main)
@@ -5305,18 +5473,9 @@ static void lib_link_screen(FileData *fd, Main *main)
else if (sl->spacetype == SPACE_BUTS) {
SpaceButs *sbuts = (SpaceButs *)sl;
sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid);
- sbuts->mainbo = sbuts->mainb;
- sbuts->mainbuser = sbuts->mainb;
- if (main->versionfile < 132)
- butspace_version_132(sbuts);
}
else if (sl->spacetype == SPACE_FILE) {
- SpaceFile *sfile = (SpaceFile *)sl;
- sfile->files = NULL;
- sfile->op = NULL;
- sfile->layout = NULL;
- sfile->folders_prev = NULL;
- sfile->folders_next = NULL;
+ ;
}
else if (sl->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)sl;
@@ -5348,12 +5507,6 @@ static void lib_link_screen(FileData *fd, Main *main)
*/
sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd);
- sseq->scopes.reference_ibuf = NULL;
- sseq->scopes.zebra_ibuf = NULL;
- sseq->scopes.waveform_ibuf = NULL;
- sseq->scopes.sep_waveform_ibuf = NULL;
- sseq->scopes.vector_ibuf = NULL;
- sseq->scopes.histogram_ibuf = NULL;
}
else if (sl->spacetype == SPACE_NLA) {
SpaceNla *snla= (SpaceNla *)sl;
@@ -5368,7 +5521,6 @@ static void lib_link_screen(FileData *fd, Main *main)
SpaceText *st= (SpaceText *)sl;
st->text= newlibadr(fd, sc->id.lib, st->text);
- st->drawcache= NULL;
}
else if (sl->spacetype == SPACE_SCRIPT) {
SpaceScript *scpt = (SpaceScript *)sl;
@@ -5385,7 +5537,6 @@ static void lib_link_screen(FileData *fd, Main *main)
TreeStoreElem *tselem;
int a;
- so->tree.first = so->tree.last= NULL;
so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id);
if (so->treestore) {
@@ -5399,7 +5550,6 @@ static void lib_link_screen(FileData *fd, Main *main)
SpaceNode *snode = (SpaceNode *)sl;
snode->id = newlibadr(fd, sc->id.lib, snode->id);
- snode->edittree = NULL;
if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) {
/* internal data, a bit patchy */
@@ -5420,19 +5570,12 @@ static void lib_link_screen(FileData *fd, Main *main)
else {
snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree);
}
-
- snode->linkdrag.first = snode->linkdrag.last = NULL;
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip);
sclip->mask_info.mask = newlibadr_us(fd, sc->id.lib, sclip->mask_info.mask);
-
- sclip->scopes.track_search = NULL;
- sclip->scopes.track_preview = NULL;
- sclip->draw_context = NULL;
- sclip->scopes.ok = 0;
}
else if (sl->spacetype == SPACE_LOGIC) {
SpaceLogic *slogic = (SpaceLogic *)sl;
@@ -5446,7 +5589,14 @@ static void lib_link_screen(FileData *fd, Main *main)
}
}
-/* Only for undo files, or to restore a screen after reading without UI... */
+/**
+ * Only for undo files, or to restore a screen after reading without UI...
+ *
+ * user
+ * - 0: no usercount change
+ * - 1: ensure a user
+ * - 2: ensure a real user (even if a fake one is set)
+ */
static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
{
if (id) {
@@ -5459,7 +5609,14 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
for (; idn; idn = idn->next) {
if (idn->name[2] == name[0] && strcmp(idn->name+2, name) == 0) {
if (idn->lib == id->lib) {
- if (user && idn->us == 0) idn->us++;
+ if (user == 1) {
+ if (idn->us == 0) {
+ idn->us++;
+ }
+ }
+ else if (user == 2) {
+ id_us_ensure_real(idn);
+ }
break;
}
}
@@ -5625,7 +5782,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
- sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 1);
+ sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 2);
/* this will be freed, not worth attempting to find same scene,
* since it gets initialized later */
@@ -5641,7 +5798,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
* so assume that here we're doing for undo only...
*/
sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1);
- sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 1);
+ sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 2);
}
else if (sl->spacetype == SPACE_SEQ) {
SpaceSeq *sseq = (SpaceSeq *)sl;
@@ -5716,8 +5873,8 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
- sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1);
- sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 1);
+ sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 2);
+ sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 2);
sclip->scopes.ok = 0;
}
@@ -5737,6 +5894,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
{
Panel *pa;
+ uiList *ui_list;
link_list(fd, &ar->panels);
@@ -5746,7 +5904,13 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
pa->activedata = NULL;
pa->type = NULL;
}
-
+
+ link_list(fd, &ar->ui_lists);
+
+ for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) {
+ ui_list->type = NULL;
+ }
+
ar->regiondata = newdataadr(fd, ar->regiondata);
if (ar->regiondata) {
if (spacetype == SPACE_VIEW3D) {
@@ -5774,6 +5938,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
ar->type = NULL;
ar->swap = 0;
ar->do_draw = FALSE;
+ ar->regiontimer = NULL;
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
}
@@ -5842,6 +6007,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sa->handlers.first = sa->handlers.last = NULL;
sa->type = NULL; /* spacetype callbacks */
+ sa->region_active_win = -1;
for (ar = sa->regionbase.first; ar; ar = ar->next)
direct_link_region(fd, ar, sa->spacetype);
@@ -5890,6 +6056,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
v3d->afterdraw_xray.first = v3d->afterdraw_xray.last = NULL;
v3d->afterdraw_xraytransp.first = v3d->afterdraw_xraytransp.last = NULL;
v3d->properties_storage = NULL;
+ v3d->defmaterial = NULL;
/* render can be quite heavy, set to wire on load */
if (v3d->drawtype == OB_RENDER)
@@ -5918,6 +6085,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
soops->treestore->totelem = soops->treestore->usedelem;
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
}
+ soops->tree.first = soops->tree.last= NULL;
}
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
@@ -5950,6 +6118,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
snode->gpd = newdataadr(fd, snode->gpd);
direct_link_gpencil(fd, snode->gpd);
}
+ snode->edittree = NULL;
+ snode->linkdrag.first = snode->linkdrag.last = NULL;
+ }
+ else if (sl->spacetype == SPACE_TEXT) {
+ SpaceText *st= (SpaceText *)sl;
+
+ st->drawcache= NULL;
}
else if (sl->spacetype == SPACE_TIME) {
SpaceTime *stime = (SpaceTime *)sl;
@@ -5965,6 +6140,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
}
}
else if (sl->spacetype == SPACE_SEQ) {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
/* grease pencil data is not a direct data and can't be linked from direct_link*
* functions, it should be linked from lib_link* functions instead
*
@@ -5973,17 +6150,26 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
* simple return NULL here (sergey)
*/
#if 0
- SpaceSeq *sseq = (SpaceSeq *)sl;
if (sseq->gpd) {
sseq->gpd = newdataadr(fd, sseq->gpd);
direct_link_gpencil(fd, sseq->gpd);
}
#endif
+ sseq->scopes.reference_ibuf = NULL;
+ sseq->scopes.zebra_ibuf = NULL;
+ sseq->scopes.waveform_ibuf = NULL;
+ sseq->scopes.sep_waveform_ibuf = NULL;
+ sseq->scopes.vector_ibuf = NULL;
+ sseq->scopes.histogram_ibuf = NULL;
+
}
else if (sl->spacetype == SPACE_BUTS) {
SpaceButs *sbuts = (SpaceButs *)sl;
+
sbuts->path= NULL;
sbuts->texuser= NULL;
+ sbuts->mainbo = sbuts->mainb;
+ sbuts->mainbuser = sbuts->mainb;
}
else if (sl->spacetype == SPACE_CONSOLE) {
SpaceConsole *sconsole = (SpaceConsole *)sl;
@@ -6023,6 +6209,14 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sfile->op = NULL;
sfile->params = newdataadr(fd, sfile->params);
}
+ else if (sl->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ sclip->scopes.track_search = NULL;
+ sclip->scopes.track_preview = NULL;
+ sclip->draw_context = NULL;
+ sclip->scopes.ok = 0;
+ }
}
sa->actionzones.first = sa->actionzones.last = NULL;
@@ -6041,6 +6235,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
{
Main *newmain;
+ /* check if the library was already read */
for (newmain = fd->mainlist->first; newmain; newmain = newmain->next) {
if (newmain->curlib) {
if (BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) {
@@ -6059,14 +6254,14 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
}
}
}
- /* make sure we have full path in lib->filename */
+ /* make sure we have full path in lib->filepath */
BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name));
cleanup_path(fd->relabase, lib->filepath);
-#if 0
- printf("direct_link_library: name %s\n", lib->name);
- printf("direct_link_library: filename %s\n", lib->filename);
-#endif
+// printf("direct_link_library: name %s\n", lib->name);
+// printf("direct_link_library: filepath %s\n", lib->filepath);
+
+ lib->packedfile = direct_link_packedfile(fd, lib->packedfile);
/* new main */
newmain= MEM_callocN(sizeof(Main), "directlink");
@@ -6256,6 +6451,7 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
clip->tracking.dopesheet.ok = 0;
clip->tracking.dopesheet.channels.first = clip->tracking.dopesheet.channels.last = NULL;
+ clip->tracking.dopesheet.coverage_segments.first = clip->tracking.dopesheet.coverage_segments.last = NULL;
link_list(fd, &tracking->objects);
@@ -6625,6 +6821,17 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->globalf = fg->globalf;
BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
+ /* error in 2.65 and older: main->name was not set if you save from startup (not after loading file) */
+ if (bfd->filename[0] == 0) {
+ if (fd->fileversion < 265 || (fd->fileversion == 265 && fg->subversion < 1))
+ if ((G.fileflags & G_FILE_RECOVER)==0)
+ BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename));
+
+ /* early 2.50 version patch - filename not in FileGlobal struct at all */
+ if (fd->fileversion <= 250)
+ BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename));
+ }
+
if (G.fileflags & G_FILE_RECOVER)
BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase));
@@ -6720,7 +6927,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree)
/* Convert degrees to radians. */
NodeDefocus *nqd = node->storage;
/* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */
- nqd->rotation = DEG2RADF(nqd->rotation*255.0f);
+ nqd->rotation = DEG2RADF(nqd->rotation * 255.0f);
}
else if (node->type == CMP_NODE_CHROMA_MATTE) {
/* Convert degrees to radians. */
@@ -6732,7 +6939,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree)
/* Convert degrees to radians. */
NodeGlare *ndg = node->storage;
/* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */
- ndg->angle_ofs = DEG2RADF(ndg->angle_ofs*255.0f);
+ ndg->angle_ofs = DEG2RADF(ndg->angle_ofs * 255.0f);
}
/* XXX TexMapping struct is used by other nodes too (at least node_composite_mapValue),
* but not the rot part...
@@ -7137,6 +7344,17 @@ static void do_version_node_cleanup_dynamic_sockets_264(void *UNUSED(data), ID *
}
}
+static void do_version_node_fix_translate_wrapping(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+ bNode *node;
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_TRANSLATE && node->storage == NULL) {
+ node->storage = MEM_callocN(sizeof(NodeTranslateData), "node translate data");
+ }
+ }
+}
+
static void do_version_node_fix_internal_links_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
{
bNode *node;
@@ -7503,7 +7721,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (ob = main->object.first; ob; ob = ob->id.next) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (!cti)
continue;
@@ -7884,7 +8102,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
- int maxres = MAX3(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
+ int maxres = max_iii(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
smd->domain->scale = smd->domain->dx * maxres;
smd->domain->dx = 1.0f / smd->domain->scale;
}
@@ -8382,6 +8600,226 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 3)) {
+ bScreen *sc;
+ for (sc = main->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ switch (sl->spacetype) {
+ case SPACE_VIEW3D:
+ {
+ View3D *v3d = (View3D *)sl;
+ v3d->flag2 |= V3D_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_SEQ:
+ {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+ sseq->flag |= SEQ_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_IMAGE:
+ {
+ SpaceImage *sima = (SpaceImage *)sl;
+ sima->flag |= SI_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_NODE:
+ {
+ SpaceNode *snode = (SpaceNode *)sl;
+ snode->flag |= SNODE_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_CLIP:
+ {
+ SpaceClip *sclip = (SpaceClip *)sl;
+ sclip->flag |= SC_SHOW_GPENCIL;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) {
+ Scene *scene;
+ Image *image, *nimage;
+ Tex *tex, *otex;
+
+ for (scene = main->scene.first; scene; scene = scene->id.next) {
+ Sequence *seq;
+ bool set_premul = false;
+
+ SEQ_BEGIN (scene->ed, seq)
+ {
+ if (seq->flag & SEQ_MAKE_PREMUL) {
+ seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
+ }
+ else {
+ BKE_sequence_alpha_mode_from_extension(seq);
+ }
+ }
+ SEQ_END
+
+ if (scene->r.bake_samples == 0)
+ scene->r.bake_samples = 256;
+
+ if (scene->world) {
+ World *world = blo_do_versions_newlibadr(fd, scene->id.lib, scene->world);
+
+ if (world && is_zero_v3(&world->horr)) {
+ if ((world->skytype & WO_SKYBLEND) == 0 || is_zero_v3(&world->zenr)) {
+ set_premul = true;
+ }
+ }
+ }
+ else
+ set_premul = true;
+
+ if (set_premul) {
+ printf("2.66 versioning fix: replacing black sky with premultiplied alpha for scene %s\n", scene->id.name + 2);
+ scene->r.alphamode = R_ALPHAPREMUL;
+ }
+ }
+
+ for (image = main->image.first; image; image = image->id.next) {
+ if (image->flag & IMA_DO_PREMUL) {
+ image->alpha_mode = IMA_ALPHA_STRAIGHT;
+ }
+ else {
+ BKE_image_alpha_mode_from_extension(image);
+ }
+
+ image->flag &= ~IMA_DONE_TAG;
+ }
+
+ /* use alpha flag moved from texture to image datablock */
+ for (tex = main->tex.first; tex; tex = tex->id.next) {
+ if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
+ image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
+
+ /* skip if no image or already tested */
+ if (!image || (image->flag & (IMA_DONE_TAG|IMA_IGNORE_ALPHA)))
+ continue;
+
+ image->flag |= IMA_DONE_TAG;
+
+ /* we might have some textures using alpha and others not, so we check if
+ * they exist and duplicate the image datablock if necessary */
+ for (otex = main->tex.first; otex; otex = otex->id.next)
+ if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA))
+ if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima))
+ break;
+
+ /* no duplication if the texture and image datablock are not
+ * from the same .blend file, the image datablock may not have
+ * been loaded from a library file otherwise */
+ if (otex && (tex->id.lib == image->id.lib)) {
+ /* copy image datablock */
+ nimage = BKE_image_copy(main, image);
+ nimage->flag |= IMA_IGNORE_ALPHA|IMA_DONE_TAG;
+ nimage->id.us--;
+
+ /* we need to do some trickery to make file loading think
+ * this new datablock is part of file we're loading */
+ blo_do_versions_oldnewmap_insert(fd->libmap, nimage, nimage, 0);
+ nimage->id.lib = image->id.lib;
+ nimage->id.flag |= (image->id.flag & LIB_NEED_LINK);
+
+ /* assign new image, and update the users counts accordingly */
+ for (otex = main->tex.first; otex; otex = otex->id.next) {
+ if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA) == 0) {
+ if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima)) {
+ if (!(otex->id.flag & LIB_NEED_LINK)) {
+ image->id.us--;
+ nimage->id.us++;
+ }
+ otex->ima = nimage;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ /* no other textures using alpha, just set the flag */
+ image->flag |= IMA_IGNORE_ALPHA;
+ }
+ }
+ }
+
+ for (image = main->image.first; image; image = image->id.next)
+ image->flag &= ~IMA_DONE_TAG;
+ }
+
+ if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
+ Curve *cu;
+
+ for (cu = main->curve.first; cu; cu = cu->id.next) {
+ if (cu->flag & (CU_FRONT | CU_BACK)) {
+ if ( cu->ext1 != 0.0f || cu->ext2 != 0.0f) {
+ Nurb *nu;
+
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
+ int a;
+
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ a = nu->pntsu;
+
+ while (a--) {
+ bezt->radius = 1.0f;
+ bezt++;
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+
+ while (a--) {
+ bp->radius = 1.0f;
+ bp++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 265, 8)) {
+ Mesh *me;
+ for (me = main->mesh.first; me; me = me->id.next) {
+ BKE_mesh_do_versions_cd_flag_init(me);
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 265, 9)) {
+ Brush *br;
+ for (br = main->brush.first; br; br = br->id.next) {
+ if (br->ob_mode & OB_MODE_TEXTURE_PAINT) {
+ br->mtex.brush_map_mode = MTEX_MAP_MODE_TILED;
+ }
+ }
+ }
+
+ // add storage for compositor translate nodes when not existing
+ if (!MAIN_VERSION_ATLEAST(main, 265, 10)) {
+ bNodeTreeType *ntreetype;
+ bNodeTree *ntree;
+
+ ntreetype = ntreeGetType(NTREE_COMPOSIT);
+ if (ntreetype && ntreetype->foreach_nodetree)
+ ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_translate_wrapping);
+
+ for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ do_version_node_fix_translate_wrapping(NULL, NULL, ntree);
+ }
+
+ // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
+
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
@@ -8401,8 +8839,11 @@ static void lib_link_all(FileData *fd, Main *main)
{
oldnewmap_sort(fd);
- lib_link_windowmanager(fd, main);
- lib_link_screen(fd, main);
+ /* No load UI for undo memfiles */
+ if (fd->memfile == NULL) {
+ lib_link_windowmanager(fd, main);
+ lib_link_screen(fd, main);
+ }
lib_link_scene(fd, main);
lib_link_object(fd, main);
lib_link_curve(fd, main);
@@ -8449,9 +8890,14 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
wmKeyMap *keymap;
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
+ bAddon *addon;
bfd->user = user= read_struct(fd, bhead, "user def");
+ /* User struct has separate do-version handling */
+ user->versionfile = bfd->main->versionfile;
+ user->subversionfile = bfd->main->subversionfile;
+
/* read all data into fd->datamap */
bhead = read_data_into_oldnewmap(fd, bhead, "user def");
@@ -8486,7 +8932,14 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
for (kmi=keymap->items.first; kmi; kmi=kmi->next)
direct_link_keymapitem(fd, kmi);
}
-
+
+ for (addon = user->addons.first; addon; addon = addon->next) {
+ addon->prop = newdataadr(fd, addon->prop);
+ if (addon->prop) {
+ IDP_DirectLinkProperty(addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
+ }
+
// XXX
user->uifonts.first = user->uifonts.last= NULL;
@@ -8610,7 +9063,7 @@ static void sort_bhead_old_map(FileData *fd)
fd->tot_bheadmap = tot;
if (tot == 0) return;
- bhs = fd->bheadmap = MEM_mallocN(tot*sizeof(struct BHeadSort), STRINGIFY(BHeadSort));
+ bhs = fd->bheadmap = MEM_mallocN(tot * sizeof(struct BHeadSort), "BHeadSort");
for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead), bhs++) {
bhs->bhead = bhead;
@@ -8675,9 +9128,10 @@ static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
}
-static void expand_doit(FileData *fd, Main *mainvar, void *old)
+static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
{
BHead *bhead;
+ FileData *fd = fdhandle;
ID *id;
bhead = find_bhead(fd, old);
@@ -8690,7 +9144,15 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
Library *lib = read_struct(fd, bheadlib, "Library");
Main *ptr = blo_find_main(fd, lib->name, fd->relabase);
- id = is_yet_read(fd, ptr, bhead);
+ if (ptr->curlib == NULL) {
+ const char *idname= bhead_id_name(fd, bhead);
+
+ BKE_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB ERROR: Data refers to main .blend file: '%s' from %s"),
+ idname, mainvar->curlib->filepath);
+ return;
+ }
+ else
+ id = is_yet_read(fd, ptr, bhead);
if (id == NULL) {
read_libblock(fd, ptr, bhead, LIB_READ+LIB_INDIRECT, NULL);
@@ -8744,7 +9206,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
}
}
-
+static void (*expand_doit)(void *, Main *, void *);
// XXX deprecated - old animation system
static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
@@ -9129,7 +9591,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
ced.fd = fd;
ced.mainvar = mainvar;
- id_loop_constraints(lb, expand_constraint_cb, &ced);
+ BKE_id_loop_constraints(lb, expand_constraint_cb, &ced);
/* deprecated manual expansion stuff */
for (curcon = lb->first; curcon; curcon = curcon->next) {
@@ -9335,7 +9797,12 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
if (ob->pd && ob->pd->tex)
expand_doit(fd, mainvar, ob->pd->tex);
-
+
+ if (ob->rigidbody_constraint) {
+ expand_doit(fd, mainvar, ob->rigidbody_constraint->ob1);
+ expand_doit(fd, mainvar, ob->rigidbody_constraint->ob2);
+ }
+
}
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
@@ -9381,6 +9848,11 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
}
SEQ_END
}
+
+ if (sce->rigidbody_world) {
+ expand_doit(fd, mainvar, sce->rigidbody_world->group);
+ expand_doit(fd, mainvar, sce->rigidbody_world->constraints);
+ }
#ifdef DURIAN_CAMERA_SWITCH
{
@@ -9455,20 +9927,24 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask)
}
}
-static void expand_main(FileData *fd, Main *mainvar)
+void BLO_main_expander(void (*expand_doit_func)(void *, Main *, void *))
+{
+ expand_doit = expand_doit_func;
+}
+
+void BLO_expand_main(void *fdhandle, Main *mainvar)
{
ListBase *lbarray[MAX_LIBARRAY];
+ FileData *fd = fdhandle;
ID *id;
int a, do_it = TRUE;
- if (fd == NULL) return;
-
while (do_it) {
do_it = FALSE;
a = set_listbasepointers(mainvar, lbarray);
while (a--) {
- id= lbarray[a]->first;
+ id = lbarray[a]->first;
while (id) {
if (id->flag & LIB_NEED_EXPAND) {
switch (GS(id->name)) {
@@ -9553,6 +10029,9 @@ static void expand_main(FileData *fd, Main *mainvar)
}
}
+
+/* ***************************** */
+
static int object_in_any_scene(Main *mainvar, Object *ob)
{
Scene *sce;
@@ -9608,7 +10087,7 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
if (do_it) {
base = MEM_callocN(sizeof(Base), "add_ext_base");
- BLI_addtail(&(sce->base), base);
+ BLI_addtail(&sce->base, base);
base->lay = ob->lay;
base->object = ob;
base->flag = ob->flag;
@@ -9632,7 +10111,7 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
Base *base;
/* BKE_object_add(...) messes with the selection */
- Object *ob = BKE_object_add_only_object(OB_EMPTY, group->id.name+2);
+ Object *ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name+2);
ob->type = OB_EMPTY;
ob->lay = scene->lay;
@@ -9640,7 +10119,7 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
base = BKE_scene_base_add(scene, ob);
base->flag |= SELECT;
base->object->flag= base->flag;
- ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
scene->basact = base;
/* assign the group */
@@ -9679,7 +10158,8 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons
}
else {
/* already linked */
- printf("append: already linked\n");
+ 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;
@@ -9701,6 +10181,28 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons
return (found) ? id : NULL;
}
+/* simple reader for copy/paste buffers */
+void BLO_library_append_all(Main *mainl, BlendHandle *bh)
+{
+ FileData *fd = (FileData *)(bh);
+ BHead *bhead;
+ ID *id = NULL;
+
+ for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
+ if (bhead->code == ENDB)
+ break;
+ if (bhead->code == ID_OB)
+ read_libblock(fd, mainl, bhead, LIB_TESTIND, &id);
+
+ if (id) {
+ /* sort by name in list */
+ ListBase *lb = which_libbase(mainl, GS(id->name));
+ id_sort_by_name(lb, id);
+ }
+ }
+}
+
+
static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag)
{
ID *id= append_named_part(mainl, fd, idname, idcode);
@@ -9805,8 +10307,11 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
Main *mainvar;
Library *curlib;
+ /* expander now is callback function */
+ BLO_main_expander(expand_doit_library);
+
/* make main consistent */
- expand_main(*fd, mainl);
+ BLO_expand_main(*fd, mainl);
/* do this when expand found other libs */
read_libraries(*fd, (*fd)->mainlist);
@@ -9901,6 +10406,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
ListBase *lbarray[MAX_LIBARRAY];
int a, do_it = TRUE;
+ /* expander now is callback function */
+ BLO_main_expander(expand_doit_library);
+
while (do_it) {
do_it = FALSE;
@@ -9914,12 +10422,26 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
FileData *fd = mainptr->curlib->filedata;
if (fd == NULL) {
+
/* printf and reports for now... its important users know this */
- BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
- mainptr->curlib->filepath, mainptr->curlib->name);
- fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
-
+ /* if packed file... */
+ if (mainptr->curlib->packedfile) {
+ PackedFile *pf = mainptr->curlib->packedfile;
+
+ BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read packed library: '%s'"),
+ mainptr->curlib->name);
+ fd = blo_openblendermemory(pf->data, pf->size, basefd->reports);
+
+
+ /* needed for library_append and read_libraries */
+ BLI_strncpy(fd->relabase, mainptr->curlib->filepath, sizeof(fd->relabase));
+ }
+ else {
+ BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
+ mainptr->curlib->filepath, mainptr->curlib->name);
+ fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
+ }
/* allow typing in a new lib path */
if (G.debug_value == -666) {
while (fd == NULL) {
@@ -10000,7 +10522,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
}
}
- expand_main(fd, mainptr);
+ BLO_expand_main(fd, mainptr);
}
}
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index a979a16220d..a0895c92b24 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -69,6 +69,9 @@ typedef struct FileData {
char headerdone;
int inbuffer;
+ // gzip stream for memory decompression
+ z_stream strm;
+
// general reading variables
struct SDNA *filesdna;
struct SDNA *memsdna;
@@ -83,6 +86,7 @@ typedef struct FileData {
struct OldNewMap *libmap;
struct OldNewMap *imamap;
struct OldNewMap *movieclipmap;
+ struct OldNewMap *packedmap;
struct BHeadSort *bheadmap;
int tot_bheadmap;
@@ -127,6 +131,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_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);
void blo_freefiledata(FileData *fd);
diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c
index 5d8a865eea8..cbbaf713e84 100644
--- a/source/blender/blenloader/intern/runtime.c
+++ b/source/blender/blenloader/intern/runtime.c
@@ -48,11 +48,12 @@
#include "BLO_readfile.h"
#include "BLO_runtime.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
#include "BKE_blender.h"
#include "BKE_report.h"
-#include "BLI_blenlib.h"
-
/* Runtime reading */
static int handle_read_msb_int(int handle)
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 1521739258e..f4d841fd22a 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -292,7 +292,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
memcpy(&ar->v2d, &soops->v2d, sizeof(View2D));
ar->v2d.scroll &= ~V2D_SCROLL_LEFT;
- ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
ar->v2d.keepzoom |= (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPASPECT);
ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
@@ -415,7 +415,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.tot.ymax = ar->winy;
ar->v2d.cur = ar->v2d.tot;
ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
+ ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
break;
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 8a56e3c2ab8..65a60e11ab3 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -289,11 +289,10 @@ static void ntree_version_245(FileData *fd, Library *lib, bNodeTree *ntree)
iuser = node->storage;
if (iuser->flag & IMA_OLD_PREMUL) {
iuser->flag &= ~IMA_OLD_PREMUL;
- iuser->flag |= IMA_DO_PREMUL;
}
if (iuser->flag & IMA_DO_PREMUL) {
image->flag &= ~IMA_OLD_PREMUL;
- image->flag |= IMA_DO_PREMUL;
+ image->alpha_mode = IMA_ALPHA_STRAIGHT;
}
}
}
@@ -545,7 +544,7 @@ void blo_do_version_old_trackto_to_constraints(Object *ob)
{
/* create new trackto constraint from the relationship */
if (ob->track) {
- bConstraint *con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
+ bConstraint *con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
bTrackToConstraint *data = con->data;
/* copy tracking settings from the object */
@@ -1840,7 +1839,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
SEQ_BEGIN (sce->ed, seq)
{
if (seq->type == SEQ_TYPE_IMAGE || seq->type == SEQ_TYPE_MOVIE)
- seq->flag |= SEQ_MAKE_PREMUL;
+ seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
}
SEQ_END
}
@@ -2901,20 +2900,19 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
for (ima = main->image.first; ima; ima = ima->id.next) {
if (ima->flag & IMA_OLD_PREMUL) {
ima->flag &= ~IMA_OLD_PREMUL;
- ima->flag |= IMA_DO_PREMUL;
+ ima->alpha_mode = IMA_ALPHA_STRAIGHT;
}
}
for (tex = main->tex.first; tex; tex = tex->id.next) {
if (tex->iuser.flag & IMA_OLD_PREMUL) {
tex->iuser.flag &= ~IMA_OLD_PREMUL;
- tex->iuser.flag |= IMA_DO_PREMUL;
}
ima = blo_do_versions_newlibadr(fd, lib, tex->ima);
if (ima && (tex->iuser.flag & IMA_DO_PREMUL)) {
ima->flag &= ~IMA_OLD_PREMUL;
- ima->flag |= IMA_DO_PREMUL;
+ ima->alpha_mode = IMA_ALPHA_STRAIGHT;
}
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index b010cae6893..ca186455224 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -89,6 +89,8 @@
# include "BLI_winstuff.h"
#endif
+#include "BLI_utildefines.h"
+
/* allow writefile to use deprecated functionality (for forward compatibility code) */
#define DNA_DEPRECATED_ALLOW
@@ -118,6 +120,7 @@
#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
#include "DNA_property_types.h"
+#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "DNA_sdna_types.h"
#include "DNA_sequence_types.h"
@@ -139,7 +142,7 @@
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
-#include "BLI_bpath.h"
+#include "BKE_bpath.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -197,7 +200,7 @@ static WriteData *writedata_new(int file)
if (wd == NULL) return NULL;
- wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, 0);
+ wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false);
wd->file= file;
@@ -850,8 +853,12 @@ static void write_userdef(WriteData *wd)
write_keymapitem(wd, kmi);
}
- for (bext= U.addons.first; bext; bext=bext->next)
+ for (bext= U.addons.first; bext; bext=bext->next) {
writestruct(wd, DATA, "bAddon", 1, bext);
+ if (bext->prop) {
+ IDP_WriteProperty(bext->prop, wd);
+ }
+ }
for (style= U.uistyles.first; style; style= style->next) {
writestruct(wd, DATA, "uiStyle", 1, style);
@@ -1228,7 +1235,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
bConstraint *con;
for (con=conlist->first; con; con=con->next) {
- bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti= BKE_constraint_get_typeinfo(con);
/* Write the specific data */
if (cti && con->data) {
@@ -1416,8 +1423,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
int size = mmd->dyngridsize;
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->bindinfluences);
- writedata(wd, DATA, sizeof(int)*(mmd->totvert+1), mmd->bindoffsets);
- writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert,
+ writedata(wd, DATA, sizeof(int) * (mmd->totvert + 1), mmd->bindoffsets);
+ writedata(wd, DATA, sizeof(float) * 3 * mmd->totcagevert,
mmd->bindcagecos);
writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid);
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
@@ -1483,6 +1490,14 @@ static void write_objects(WriteData *wd, ListBase *idbase)
}
writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft);
+ if (ob->rigidbody_object) {
+ // TODO: if any extra data is added to handle duplis, will need separate function then
+ writestruct(wd, DATA, "RigidBodyOb", 1, ob->rigidbody_object);
+ }
+ if (ob->rigidbody_constraint) {
+ writestruct(wd, DATA, "RigidBodyCon", 1, ob->rigidbody_constraint);
+ }
+
write_particlesystems(wd, &ob->particlesystem);
write_modifiers(wd, &ob->modifiers);
}
@@ -1674,7 +1689,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external)
MDisps *md = &mdlist[i];
if (md->disps) {
if (!external)
- writedata(wd, DATA, sizeof(float)*3*md->totdisp, md->disps);
+ writedata(wd, DATA, sizeof(float) * 3 * md->totdisp, md->disps);
}
if (md->hidden)
@@ -2292,7 +2307,14 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
}
write_view_settings(wd, &sce->view_settings);
-
+
+ /* writing RigidBodyWorld data to the blend file */
+ if (sce->rigidbody_world) {
+ writestruct(wd, DATA, "RigidBodyWorld", 1, sce->rigidbody_world);
+ writestruct(wd, DATA, "EffectorWeights", 1, sce->rigidbody_world->effector_weights);
+ write_pointcaches(wd, &(sce->rigidbody_world->ptcaches));
+ }
+
sce= sce->id.next;
}
/* flush helps the compression for undo-save */
@@ -2395,6 +2417,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
for (sa= sc->areabase.first; sa; sa= sa->next) {
SpaceLink *sl;
Panel *pa;
+ uiList *ui_list;
ARegion *ar;
writestruct(wd, DATA, "ScrArea", 1, sa);
@@ -2404,6 +2427,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
for (pa= ar->panels.first; pa; pa= pa->next)
writestruct(wd, DATA, "Panel", 1, pa);
+
+ for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next)
+ writestruct(wd, DATA, "uiList", 1, ui_list);
}
sl= sa->spacedata.first;
@@ -2515,6 +2541,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
sc= sc->id.next;
}
+
+ /* flush helps the compression for undo-save */
+ mywrite(wd, MYWRITE_FLUSH, 0);
}
static void write_libraries(WriteData *wd, Main *main)
@@ -2528,20 +2557,35 @@ static void write_libraries(WriteData *wd, Main *main)
a=tot= set_listbasepointers(main, lbarray);
/* test: is lib being used */
- foundone = FALSE;
- while (tot--) {
- for (id= lbarray[tot]->first; id; id= id->next) {
- if (id->us>0 && (id->flag & LIB_EXTERN)) {
- foundone = TRUE;
- break;
+ if (main->curlib && main->curlib->packedfile)
+ foundone = TRUE;
+ else {
+ foundone = FALSE;
+ while (tot--) {
+ for (id= lbarray[tot]->first; id; id= id->next) {
+ if (id->us>0 && (id->flag & LIB_EXTERN)) {
+ foundone = TRUE;
+ break;
+ }
}
+ if (foundone) break;
}
- if (foundone) break;
}
-
+
+ /* to be able to restore quit.blend and temp saves, the packed blend has to be in undo buffers... */
+ /* XXX needs rethink, just like save UI in undo files now - would be nice to append things only for the]
+ quit.blend and temp saves */
if (foundone) {
writestruct(wd, ID_LI, "Library", 1, main->curlib);
+ if (main->curlib->packedfile) {
+ PackedFile *pf = main->curlib->packedfile;
+ writestruct(wd, DATA, "PackedFile", 1, pf);
+ writedata(wd, DATA, pf->size, pf->data);
+ if (wd->current == NULL)
+ printf("write packed .blend: %s\n", main->curlib->name);
+ }
+
while (a--) {
for (id= lbarray[a]->first; id; id= id->next) {
if (id->us>0 && (id->flag & LIB_EXTERN)) {
@@ -2877,7 +2921,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
/* XXX still remap G */
fg.curscreen= screen;
- fg.curscene= screen->scene;
+ fg.curscene= screen? screen->scene : NULL;
fg.displaymode= G.displaymode;
fg.winpos= G.winpos;
@@ -2886,7 +2930,6 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
fg.globalf= G.f;
BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename));
-
sprintf(subvstr, "%4d", BLENDER_SUBVERSION);
memcpy(fg.subvstr, subvstr, 4);
@@ -2938,11 +2981,8 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
write_thumb(wd, thumb);
write_global(wd, write_flags, mainvar);
- /* no UI save in undo */
- if (current==NULL) {
- write_windowmanagers(wd, &mainvar->wm);
- write_screens (wd, &mainvar->screen);
- }
+ write_windowmanagers(wd, &mainvar->wm);
+ write_screens (wd, &mainvar->screen);
write_movieclips (wd, &mainvar->movieclip);
write_masks (wd, &mainvar->mask);
write_scenes (wd, &mainvar->scene);
@@ -3027,13 +3067,12 @@ static int do_history(const char *name, ReportList *reports)
/* return: success (1) */
int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const int *thumb)
{
- char userfilename[FILE_MAX];
char tempname[FILE_MAX+1];
int file, err, write_user_block;
/* path backup/restore */
void *path_list_backup = NULL;
- const int path_list_flag = (BLI_BPATH_TRAVERSE_SKIP_LIBRARY | BLI_BPATH_TRAVERSE_SKIP_MULTIFILE);
+ const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE);
/* open temporary file, so we preserve the original in case we crash */
BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
@@ -3046,7 +3085,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
/* check if we need to backup and restore paths */
if (UNLIKELY((write_flags & G_FILE_RELATIVE_REMAP) && (G_FILE_SAVE_COPY & write_flags))) {
- path_list_backup = BLI_bpath_list_backup(mainvar, path_list_flag);
+ path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag);
}
/* remapping of relative paths to new file location */
@@ -3069,24 +3108,23 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
* we should not have any relative paths, but if there
* is somehow, an invalid or empty G.main->name it will
* print an error, don't try make the absolute in this case. */
- BLI_bpath_absolute_convert(mainvar, G.main->name, NULL);
+ BKE_bpath_absolute_convert(mainvar, G.main->name, NULL);
}
}
}
- BLI_make_file_string(G.main->name, userfilename, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
- write_user_block= (BLI_path_cmp(filepath, userfilename) == 0);
+ write_user_block= write_flags & G_FILE_USERPREFS;
if (write_flags & G_FILE_RELATIVE_REMAP)
- BLI_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
+ BKE_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
/* actual file writing */
err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb);
close(file);
if (UNLIKELY(path_list_backup)) {
- BLI_bpath_list_restore(mainvar, path_list_flag, path_list_backup);
- BLI_bpath_list_free(path_list_backup);
+ BKE_bpath_list_restore(mainvar, path_list_flag, path_list_backup);
+ BKE_bpath_list_free(path_list_backup);
}
if (err) {
@@ -3151,3 +3189,4 @@ int BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int wr
if (err==0) return 1;
return 0;
}
+
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 2a23658f5d0..aa1fb2dda46 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -30,7 +30,7 @@ set(INC
../blenlib
../makesdna
../../../intern/guardedalloc
- ../../../extern/bullet2/src
+ ../../../extern/rangetree
../../../intern/opennl/extern
)
@@ -41,7 +41,6 @@ set(INC_SYS
set(SRC
operators/bmo_bevel.c
operators/bmo_connect.c
- operators/bmo_slide.c
operators/bmo_create.c
operators/bmo_dissolve.c
operators/bmo_dupe.c
@@ -74,6 +73,8 @@ set(SRC
intern/bmesh_iterators.c
intern/bmesh_iterators.h
intern/bmesh_iterators_inline.h
+ intern/bmesh_log.c
+ intern/bmesh_log.h
intern/bmesh_marking.c
intern/bmesh_marking.h
intern/bmesh_mesh.c
@@ -111,6 +112,10 @@ set(SRC
tools/bmesh_decimate_dissolve.c
tools/bmesh_decimate_unsubdivide.c
tools/bmesh_decimate.h
+ tools/bmesh_edgesplit.c
+ tools/bmesh_edgesplit.h
+ tools/bmesh_triangulate.c
+ tools/bmesh_triangulate.h
bmesh.h
bmesh_class.h
@@ -122,6 +127,9 @@ endif()
if(WITH_BULLET)
add_definitions(-DWITH_BULLET)
+ list(APPEND INC_SYS
+ ${BULLET_INCLUDE_DIRS}
+ )
endif()
if(WITH_INTERNATIONAL)
diff --git a/source/blender/bmesh/SConscript b/source/blender/bmesh/SConscript
index 6765d57cb3e..a8ca514297e 100644
--- a/source/blender/bmesh/SConscript
+++ b/source/blender/bmesh/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
cflags=''
@@ -15,7 +41,9 @@ incs = [
'../blenkernel',
'#/intern/guardedalloc',
'#/extern/bullet2/src',
- '#/intern/opennl/extern', ]
+ '#/extern/rangetree',
+ '#/intern/opennl/extern'
+ ]
defs = []
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 6257aa4bf3e..3b33513b575 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -243,6 +243,7 @@ extern "C" {
#include <stdlib.h>
#include <stdio.h>
+#include <assert.h>
#include "bmesh_class.h"
@@ -254,6 +255,7 @@ extern "C" {
#include "intern/bmesh_core.h"
#include "intern/bmesh_interp.h"
#include "intern/bmesh_iterators.h"
+#include "intern/bmesh_log.h"
#include "intern/bmesh_marking.h"
#include "intern/bmesh_mesh.h"
#include "intern/bmesh_mesh_conv.h"
@@ -266,8 +268,9 @@ extern "C" {
#include "intern/bmesh_inline.h"
-#include "tools/bmesh_decimate.h"
#include "tools/bmesh_bevel.h"
+#include "tools/bmesh_decimate.h"
+#include "tools/bmesh_triangulate.h"
#ifdef __cplusplus
}
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 9d797c1e602..6dc0218da93 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -45,7 +45,7 @@ struct Object;
* pointers. this is a requirement of mempool's method of
* iteration.
*
- * hrm. it doesn't but stull works ok, remove the comment above? - campbell.
+ * hrm. it doesn't but still works ok, remove the comment above? - campbell.
*/
// #pragma GCC diagnostic error "-Wpadded"
@@ -184,11 +184,12 @@ typedef struct BMesh {
* BM_LOOP isn't handled so far. */
char elem_index_dirty;
- /*element pools*/
+ /* element pools */
struct BLI_mempool *vpool, *epool, *lpool, *fpool;
- /*operator api stuff*/
- struct BLI_mempool *toolflagpool;
+ /* operator api stuff (must be all NULL or all alloc'd) */
+ struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
+
int stackdepth;
struct BMOperator *currentop;
@@ -204,7 +205,7 @@ typedef struct BMesh {
* Only use when the edit mesh cant be accessed - campbell */
short selectmode;
- /*ID of the shape key this bmesh came from*/
+ /* ID of the shape key this bmesh came from */
int shapenr;
int walkers, totflags;
@@ -252,6 +253,17 @@ enum {
};
/* defines */
+#define BM_ELEM_CD_GET_VOID_P(ele, offset) \
+ (assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
+
+#define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
+ { assert(offset != -1); *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
+
+#define BM_ELEM_CD_GET_FLOAT(ele, offset) \
+ (assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
+
+#define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
+ (assert(offset != -1), (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
/*forward declarations*/
@@ -276,5 +288,6 @@ enum {
* but should not error on valid cases */
#define BM_LOOP_RADIAL_MAX 10000
#define BM_NGON_MAX 100000
+#define BM_OMP_LIMIT 10000 /* setting zero so we can catch bugs in OpenMP/BMesh */
#endif /* __BMESH_CLASS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 8b7fac1eacd..fddb7b4bf2c 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -53,7 +53,7 @@ static void bm_loop_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
* \brief Make Quad/Triangle
*
* Creates a new quad or triangle from a list of 3 or 4 vertices.
- * If \a nodouble is TRUE, then a check is done to see if a face
+ * If \a no_double is true, then a check is done to see if a face
* with these vertices already exists and returns it instead.
*
* If a pointer to an example face is provided, it's custom data
@@ -65,16 +65,16 @@ static void bm_loop_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
BMFace *BM_face_create_quad_tri(BMesh *bm,
BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
- const BMFace *example, const int nodouble)
+ const BMFace *example, const bool no_double)
{
BMVert *vtar[4] = {v1, v2, v3, v4};
- return BM_face_create_quad_tri_v(bm, vtar, v4 ? 4 : 3, example, nodouble);
+ return BM_face_create_quad_tri_v(bm, vtar, v4 ? 4 : 3, example, no_double);
}
-BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFace *example, const int nodouble)
+BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFace *example, const bool no_double)
{
BMFace *f = NULL;
- int is_overlap = FALSE;
+ bool is_overlap = false;
/* sanity check - debug mode only */
if (len == 3) {
@@ -97,7 +97,7 @@ BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFa
}
- if (nodouble) {
+ if (no_double) {
/* check if face exists or overlaps */
is_overlap = BM_face_exists(verts, len, &f);
}
@@ -173,24 +173,24 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
*/
BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag)
{
- BMEdge **edges2 = NULL;
- BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
- BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
+ BMEdge **edges_sort = BLI_array_alloca(edges_sort, len);
+ BMVert **verts_sort = BLI_array_alloca(verts_sort, len + 1);
+ int esort_index = 0;
+ int vsort_index = 0;
+
BMFace *f = NULL;
BMEdge *e;
BMVert *v, *ev1, *ev2;
- int i, /* j, */ v1found, reverse;
+ int i;
+ bool is_v1_found, is_reverse;
+
/* this code is hideous, yeek. I'll have to think about ways of
* cleaning it up. basically, it now combines the old BM_face_create_ngon
* _and_ the old bmesh_mf functions, so its kindof smashed together
* - joeedh */
- if (!len || !v1 || !v2 || !edges || !bm) {
- BLI_assert(0);
- return NULL;
- }
+ BLI_assert(len && v1 && v2 && edges && bm);
/* put edges in correct order */
for (i = 0; i < len; i++) {
@@ -207,14 +207,19 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
SWAP(BMVert *, ev1, ev2);
}
- BLI_array_append(verts, ev1);
+ verts_sort[vsort_index++] = ev1;
v = ev2;
e = edges[0];
do {
BMEdge *e2 = e;
- BLI_array_append(verts, v);
- BLI_array_append(edges2, e);
+ /* vertex array is (len + 1) */
+ if (UNLIKELY(vsort_index > len)) {
+ goto err; /* vertex in loop twice */
+ }
+
+ verts_sort[vsort_index++] = v;
+ edges_sort[esort_index++] = e;
/* we only flag the verts to check if they are in the face more then once */
BM_ELEM_API_FLAG_ENABLE(v, _FLAG_MV);
@@ -227,84 +232,78 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
}
} while (e2 != e);
- if (e2 == e)
+ if (UNLIKELY(e2 == e)) {
goto err; /* the edges do not form a closed loop */
+ }
e = e2;
} while (e != edges[0]);
- if (BLI_array_count(edges2) != len) {
+ if (UNLIKELY(esort_index != len)) {
goto err; /* we didn't use all edges in forming the boundary loop */
}
/* ok, edges are in correct order, now ensure they are going
* in the correct direction */
- v1found = reverse = FALSE;
+ is_v1_found = is_reverse = false;
for (i = 0; i < len; i++) {
- if (BM_vert_in_edge(edges2[i], v1)) {
+ if (BM_vert_in_edge(edges_sort[i], v1)) {
/* see if v1 and v2 are in the same edge */
- if (BM_vert_in_edge(edges2[i], v2)) {
+ if (BM_vert_in_edge(edges_sort[i], v2)) {
/* if v1 is shared by the *next* edge, then the winding
* is incorrect */
- if (BM_vert_in_edge(edges2[(i + 1) % len], v1)) {
- reverse = TRUE;
+ if (BM_vert_in_edge(edges_sort[(i + 1) % len], v1)) {
+ is_reverse = true;
break;
}
}
- v1found = TRUE;
+ is_v1_found = true;
}
- if ((v1found == FALSE) && BM_vert_in_edge(edges2[i], v2)) {
- reverse = TRUE;
+ if ((is_v1_found == false) && BM_vert_in_edge(edges_sort[i], v2)) {
+ is_reverse = true;
break;
}
}
- if (reverse) {
+ if (is_reverse) {
for (i = 0; i < len / 2; i++) {
- v = verts[i];
- verts[i] = verts[len - i - 1];
- verts[len - i - 1] = v;
+ v = verts_sort[i];
+ verts_sort[i] = verts_sort[len - i - 1];
+ verts_sort[len - i - 1] = v;
}
}
for (i = 0; i < len; i++) {
- edges2[i] = BM_edge_exists(verts[i], verts[(i + 1) % len]);
- if (!edges2[i]) {
+ edges_sort[i] = BM_edge_exists(verts_sort[i], verts_sort[(i + 1) % len]);
+ if (UNLIKELY(edges_sort[i] == NULL)) {
goto err;
}
/* check if vert is in face more then once. if the flag is disabled. we've already visited */
- if (!BM_ELEM_API_FLAG_TEST(verts[i], _FLAG_MV)) {
+ if (UNLIKELY(!BM_ELEM_API_FLAG_TEST(verts_sort[i], _FLAG_MV))) {
goto err;
}
- BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
+ BM_ELEM_API_FLAG_DISABLE(verts_sort[i], _FLAG_MV);
}
- f = BM_face_create(bm, verts, edges2, len, create_flag);
+ f = BM_face_create(bm, verts_sort, edges_sort, len, create_flag);
/* clean up flags */
for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_DISABLE(edges2[i], _FLAG_MF);
+ BM_ELEM_API_FLAG_DISABLE(edges_sort[i], _FLAG_MF);
}
- BLI_array_free(verts);
- BLI_array_free(edges2);
-
return f;
err:
for (i = 0; i < len; i++) {
BM_ELEM_API_FLAG_DISABLE(edges[i], _FLAG_MF);
- /* vert count may != len */
- if (i < BLI_array_count(verts)) {
- BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
- }
}
-
- BLI_array_free(verts);
- BLI_array_free(edges2);
+ for (i = 0; i < vsort_index; i++) {
+ BM_ELEM_API_FLAG_DISABLE(verts_sort[i], _FLAG_MV);
+ }
return NULL;
}
@@ -794,7 +793,7 @@ void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *sour
/* First we copy select */
if (BM_elem_flag_test((BMElem *)sheader, BM_ELEM_SELECT)) {
- BM_elem_select_set(target_mesh, (BMElem *)target, TRUE);
+ BM_elem_select_set(target_mesh, (BMElem *)target, true);
}
/* Now we copy flags */
@@ -821,6 +820,8 @@ void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *sour
BMesh *BM_mesh_copy(BMesh *bm_old)
{
+#define USE_FAST_FACE_COPY
+
BMesh *bm_new;
BMVert *v, *v2, **vtable = NULL;
BMEdge *e, *e2, **edges = NULL, **etable = NULL;
@@ -828,6 +829,10 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
BLI_array_declare(edges);
BMLoop *l, /* *l2, */ **loops = NULL;
BLI_array_declare(loops);
+#ifdef USE_FAST_FACE_COPY
+ BMVert **verts = NULL;
+ BLI_array_declare(verts);
+#endif
BMFace *f, *f2, **ftable = NULL;
BMEditSelection *ese;
BMIter iter, liter;
@@ -895,12 +900,24 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
BLI_array_grow_items(loops, f->len);
BLI_array_grow_items(edges, f->len);
+#ifdef USE_FAST_FACE_COPY
+ BLI_array_empty(verts);
+ BLI_array_grow_items(verts, f->len);
+#endif
+
l = BM_iter_new(&liter, bm_old, BM_LOOPS_OF_FACE, f);
for (j = 0; j < f->len; j++, l = BM_iter_step(&liter)) {
loops[j] = l;
edges[j] = etable[BM_elem_index_get(l->e)];
+
+#ifdef USE_FAST_FACE_COPY
+ verts[j] = vtable[BM_elem_index_get(l->v)];
+#endif
}
+#ifdef USE_FAST_FACE_COPY
+ f2 = BM_face_create(bm_new, verts, edges, f->len, BM_CREATE_SKIP_CD);
+#else
v = vtable[BM_elem_index_get(loops[0]->v)];
v2 = vtable[BM_elem_index_get(loops[1]->v)];
@@ -910,6 +927,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
}
f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, BM_CREATE_SKIP_CD);
+#endif
+
if (UNLIKELY(f2 == NULL)) {
continue;
}
@@ -965,9 +984,12 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
MEM_freeN(vtable);
MEM_freeN(ftable);
+#ifdef USE_FAST_FACE_COPY
+ BLI_array_free(verts);
+#endif
+
BLI_array_free(loops);
BLI_array_free(edges);
-
return bm_new;
}
diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h
index 60c465e5f5a..0f597dbb1d8 100644
--- a/source/blender/bmesh/intern/bmesh_construct.h
+++ b/source/blender/bmesh/intern/bmesh_construct.h
@@ -29,10 +29,10 @@
BMFace *BM_face_create_quad_tri_v(BMesh *bm,
BMVert **verts, int len,
- const BMFace *example, const int nodouble);
+ const BMFace *example, const bool no_double);
BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
- const BMFace *example, const int nodouble);
+ const BMFace *example, const bool no_double);
void BM_face_copy_shared(BMesh *bm, BMFace *f);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 14fab7abdc9..643e73e02b4 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -78,9 +78,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, cons
copy_v3_v3(v->co, co);
}
- /* allocate flag */
- if (bm->toolflagpool) {
- v->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ /* allocate flags */
+ if (bm->vtoolflagpool) {
+ v->oflags = BLI_mempool_calloc(bm->vtoolflagpool);
}
if (!(create_flag & BM_CREATE_SKIP_CD)) {
@@ -109,7 +109,7 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, cons
* \brief Main function for creating a new edge.
*
* \note Duplicate edges are supported by the API however users should _never_ see them.
- * so unless you need a unique edge or know the edge won't exist, you should call with \a nodouble = TRUE
+ * so unless you need a unique edge or know the edge won't exist, you should call with \a no_double = true
*/
BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag)
{
@@ -132,9 +132,9 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example,
e->head.htype = BM_EDGE;
- /* allocate flag */
- if (bm->toolflagpool) {
- e->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ /* allocate flags */
+ if (bm->etoolflagpool) {
+ e->oflags = BLI_mempool_calloc(bm->etoolflagpool);
}
e->v1 = v1;
@@ -209,12 +209,11 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge
return l;
}
-BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges)
+BMFace *BM_face_copy(BMesh *bm, BMFace *f,
+ const bool copy_verts, const bool copy_edges)
{
- BMVert **verts = NULL;
- BMEdge **edges = NULL;
- BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
- BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
+ BMVert **verts = BLI_array_alloca(verts, f->len);
+ BMEdge **edges = BLI_array_alloca(edges, f->len);
BMLoop *l_iter;
BMLoop *l_first;
BMLoop *l_copy;
@@ -224,7 +223,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
i = 0;
do {
- if (copyverts) {
+ if (copy_verts) {
verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0);
}
else {
@@ -236,7 +235,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
i = 0;
do {
- if (copyedges) {
+ if (copy_edges) {
BMVert *v1, *v2;
if (l_iter->e->v1 == verts[i]) {
@@ -267,9 +266,6 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
l_copy = l_copy->next;
} while ((l_iter = l_iter->next) != l_first);
- BLI_array_fixedstack_free(verts);
- BLI_array_fixedstack_free(edges);
-
return f_copy;
}
@@ -295,9 +291,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag creat
f->head.htype = BM_FACE;
- /* allocate flag */
- if (bm->toolflagpool) {
- f->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ /* allocate flags */
+ if (bm->ftoolflagpool) {
+ f->oflags = BLI_mempool_calloc(bm->ftoolflagpool);
}
if (!(create_flag & BM_CREATE_SKIP_CD)) {
@@ -321,7 +317,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
int i, overlap;
if (len == 0) {
- /* just return NULL for no */
+ /* just return NULL for now */
return NULL;
}
@@ -517,8 +513,8 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
if (v->head.data)
CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, v->oflags);
+ if (bm->vtoolflagpool) {
+ BLI_mempool_free(bm->vtoolflagpool, v->oflags);
}
BLI_mempool_free(bm->vpool, v);
}
@@ -537,8 +533,8 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e)
if (e->head.data)
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, e->oflags);
+ if (bm->etoolflagpool) {
+ BLI_mempool_free(bm->etoolflagpool, e->oflags);
}
BLI_mempool_free(bm->epool, e);
}
@@ -560,8 +556,8 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f)
if (f->head.data)
CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, f->oflags);
+ if (bm->ftoolflagpool) {
+ BLI_mempool_free(bm->ftoolflagpool, f->oflags);
}
BLI_mempool_free(bm->fpool, f);
}
@@ -585,22 +581,19 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
*/
void BM_face_edges_kill(BMesh *bm, BMFace *f)
{
- BMEdge **edges = NULL;
- BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
+ BMEdge **edges = BLI_array_alloca_and_count(edges, f->len);
BMLoop *l_iter;
BMLoop *l_first;
- int i;
+ int i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- BLI_array_append(edges, l_iter->e);
+ edges[i++] = l_iter->e;
} while ((l_iter = l_iter->next) != l_first);
for (i = 0; i < BLI_array_count(edges); i++) {
BM_edge_kill(bm, edges[i]);
}
-
- BLI_array_free(edges);
}
/**
@@ -609,22 +602,19 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
*/
void BM_face_verts_kill(BMesh *bm, BMFace *f)
{
- BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
+ BMVert **verts = BLI_array_alloca_and_count(verts, f->len);
BMLoop *l_iter;
BMLoop *l_first;
- int i;
+ int i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- BLI_array_append(verts, l_iter->v);
+ verts[i++] = l_iter->v;
} while ((l_iter = l_iter->next) != l_first);
for (i = 0; i < BLI_array_count(verts); i++) {
BM_vert_kill(bm, verts[i]);
}
-
- BLI_array_free(verts);
}
/**
@@ -745,7 +735,7 @@ static int UNUSED_FUNCTION(bm_loop_length)(BMLoop *l)
*
* \return Success
*/
-static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
+static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f
#ifdef USE_BMESH_HOLES
, BMLoopList *lst
#endif
@@ -759,10 +749,9 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
#endif
const int len = f->len;
- const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
+ const bool do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
BMLoop *l_iter, *oldprev, *oldnext;
- BMEdge **edar = NULL;
- BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
+ BMEdge **edar = BLI_array_alloca(edar, len);
int i, j, edok;
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
@@ -814,11 +803,11 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
}
}
}
- /* rebuild radia */
+ /* rebuild radial */
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next)
bmesh_radial_append(l_iter->e, l_iter);
- /* validate radia */
+ /* validate radial */
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
BM_CHECK_ELEMENT(l_iter);
BM_CHECK_ELEMENT(l_iter->e);
@@ -826,17 +815,15 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
BM_CHECK_ELEMENT(l_iter->f);
}
- BLI_array_fixedstack_free(edar);
-
BM_CHECK_ELEMENT(f);
- return 1;
+ return true;
}
/**
* \brief Flip the faces direction
*/
-int bmesh_loop_reverse(BMesh *bm, BMFace *f)
+bool bmesh_loop_reverse(BMesh *bm, BMFace *f)
{
#ifdef USE_BMESH_HOLES
return bm_loop_reverse_loop(bm, f, f->loops.first);
@@ -907,26 +894,26 @@ static int UNUSED_FUNCTION(count_flagged_disk)(BMVert *v, int flag)
return i;
}
-static int disk_is_flagged(BMVert *v, int flag)
+static bool disk_is_flagged(BMVert *v, int flag)
{
BMEdge *e = v->e;
if (!e)
- return FALSE;
+ return false;
do {
BMLoop *l = e->l;
if (!l) {
- return FALSE;
+ return false;
}
if (bmesh_radial_length(l) == 1)
- return FALSE;
+ return false;
do {
if (!BM_ELEM_API_FLAG_TEST(l->f, flag))
- return FALSE;
+ return false;
l = l->radial_next;
} while (l != e->l);
@@ -934,7 +921,7 @@ static int disk_is_flagged(BMVert *v, int flag)
e = bmesh_disk_edge_next(e, v);
} while (e != v->e);
- return TRUE;
+ return true;
}
/* Mid-level Topology Manipulation Functions */
@@ -953,7 +940,7 @@ static int disk_is_flagged(BMVert *v, int flag)
* \note this is a generic, flexible join faces function,
* almost everything uses this, including #BM_faces_join_pair
*/
-BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del)
+BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
{
BMFace *f, *newf;
#ifdef USE_BMESH_HOLES
@@ -1068,7 +1055,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
} while (l2 != l_iter);
if (l2 != l_iter) {
- /* I think this is correct */
+ /* I think this is correct? */
if (l2->v != l_iter->v) {
l2 = l2->next;
}
@@ -1080,7 +1067,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
BM_elem_attrs_copy(bm, bm, faces[0], newf);
#ifdef USE_BMESH_HOLES
- /* add hole */
+ /* add holes */
BLI_movelisttolist(&newf->loops, &holes);
#endif
@@ -1212,7 +1199,7 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
ListBase *holes,
#endif
BMEdge *example,
- const short nodouble
+ const bool no_double
)
{
#ifdef USE_BMESH_HOLES
@@ -1239,7 +1226,7 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
}
/* allocate new edge between v1 and v2 */
- e = BM_edge_create(bm, v1, v2, example, nodouble ? BM_CREATE_NO_DOUBLE : 0);
+ e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : 0);
f2 = bm_face_create__sfme(bm, f);
f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0);
@@ -1365,9 +1352,10 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BMLoop *nextl;
BMEdge *ne;
BMVert *nv, *ov;
- int i, edok, valence1 = 0, valence2 = 0;
+ int i, valence1 = 0, valence2 = 0;
+ bool edok;
- BLI_assert(bmesh_vert_in_edge(e, tv) != FALSE);
+ BLI_assert(bmesh_vert_in_edge(e, tv) != false);
ov = bmesh_edge_other_vert_get(e, tv);
@@ -1396,13 +1384,13 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
/* add ne to tv's disk cycle */
bmesh_disk_edge_append(ne, tv);
- /* verify disk cycle */
+ /* verify disk cycles */
edok = bmesh_disk_validate(valence1, ov->e, ov);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(valence2, tv->e, tv);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(2, nv->e, nv);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
/* Split the radial cycle if present */
nextl = e->l;
@@ -1468,9 +1456,9 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
/* verify length of radial cycle */
edok = bmesh_radial_validate(radlen, e->l);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
edok = bmesh_radial_validate(radlen, ne->l);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
/* verify loop->v and loop->next->v pointers for e */
for (i = 0, l = e->l; i < radlen; i++, l = l->radial_next) {
@@ -1479,11 +1467,11 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BMESH_ASSERT(!(l->prev->e != ne && l->next->e != ne));
edok = bmesh_verts_in_edge(l->v, l->next->v, e);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
BMESH_ASSERT(l->v != l->next->v);
BMESH_ASSERT(l->e != l->next->e);
- /* verify loop cycle for kloop-> */
+ /* verify loop cycle for kloop->f */
BM_CHECK_ELEMENT(l);
BM_CHECK_ELEMENT(l->v);
BM_CHECK_ELEMENT(l->e);
@@ -1495,7 +1483,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
// BMESH_ASSERT(l->radial_next == l);
BMESH_ASSERT(!(l->prev->e != e && l->next->e != e));
edok = bmesh_verts_in_edge(l->v, l->next->v, ne);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
BMESH_ASSERT(l->v != l->next->v);
BMESH_ASSERT(l->e != l->next->e);
@@ -1547,12 +1535,13 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
* faces with just 2 edges. It is up to the caller to decide what to do with
* these faces.
*/
-BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_double)
+BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_double)
{
BMEdge *oe;
BMVert *ov, *tv;
BMLoop *killoop, *l;
- int len, radlen = 0, halt = 0, i, valence1, valence2, edok;
+ int len, radlen = 0, i, valence1, valence2;
+ bool edok, halt = false;
if (bmesh_vert_in_edge(ke, kv) == 0) {
return NULL;
@@ -1564,7 +1553,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
oe = bmesh_disk_edge_next(ke, kv);
tv = bmesh_edge_other_vert_get(ke, kv);
ov = bmesh_edge_other_vert_get(oe, kv);
- halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edge */
+ halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edges */
if (halt) {
return NULL;
@@ -1572,7 +1561,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
else {
BMEdge *e_splice;
- /* For verification later, count valence of ov and t */
+ /* For verification later, count valence of ov and tv */
valence1 = bmesh_disk_count(ov);
valence2 = bmesh_disk_count(tv);
@@ -1614,8 +1603,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
radlen = bmesh_radial_length(ke->l);
if (LIKELY(radlen)) {
- BMLoop **loops = NULL;
- BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__);
+ BMLoop **loops = BLI_array_alloca(loops, radlen);
killoop = ke->l;
@@ -1628,12 +1616,11 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
bm->totloop--;
BLI_mempool_free(bm->lpool, loops[i]);
}
- BLI_array_fixedstack_free(loops);
}
/* Validate radial cycle of oe */
edok = bmesh_radial_validate(radlen, oe->l);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
}
/* deallocate edge */
@@ -1644,17 +1631,17 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
/* Validate disk cycle lengths of ov, tv are unchanged */
edok = bmesh_disk_validate(valence1, ov->e, ov);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(valence2, tv->e, tv);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
/* Validate loop cycle of all faces attached to 'oe' */
for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) {
BMESH_ASSERT(l->e == oe);
edok = bmesh_verts_in_edge(l->v, l->next->v, oe);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
edok = bmesh_loop_validate(l->f);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
BM_CHECK_ELEMENT(l);
BM_CHECK_ELEMENT(l->v);
@@ -1801,8 +1788,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
/* deallocate edge and its two loops as well as f2 */
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags);
+ if (bm->etoolflagpool) {
+ BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags);
}
BLI_mempool_free(bm->epool, f1loop->e);
bm->totedge--;
@@ -1810,8 +1797,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
bm->totloop--;
BLI_mempool_free(bm->lpool, f2loop);
bm->totloop--;
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, f2->oflags);
+ if (bm->ftoolflagpool) {
+ BLI_mempool_free(bm->ftoolflagpool, f2->oflags);
}
BLI_mempool_free(bm->fpool, f2);
bm->totface--;
@@ -1822,7 +1809,7 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
/* validate the new loop cycle */
edok = bmesh_loop_validate(f1);
- BMESH_ASSERT(edok != FALSE);
+ BMESH_ASSERT(edok != false);
return f1;
}
@@ -1838,7 +1825,7 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
* where \a v and \a vtarget are connected by an edge
* (assert checks for this case).
*/
-int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
+bool BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
{
void *loops_stack[BM_DEFAULT_ITER_STACK_SIZE];
BMLoop **loops;
@@ -1848,7 +1835,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
/* verts already spliced */
if (v == v_target) {
- return FALSE;
+ return false;
}
/* we can't modify the vert while iterating so first allocate an array of loops */
@@ -1878,7 +1865,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
/* v is unused now, and can be killed */
BM_vert_kill(bm, v);
- return TRUE;
+ return true;
}
/**
@@ -1892,10 +1879,10 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
*
* \return Success
*/
-int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
+bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
{
BMEdge **stack = NULL;
- BLI_array_declare(stack);
+ BLI_array_staticdeclare(stack, BM_DEFAULT_ITER_STACK_SIZE);
BMVert **verts = NULL;
GHash *visithash;
BMIter eiter, liter;
@@ -2009,13 +1996,13 @@ int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
MEM_freeN(verts);
}
- return TRUE;
+ return true;
}
/**
* High level function which wraps both #bmesh_vert_separate and #bmesh_edge_separate
*/
-int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
+bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
BMEdge **e_in, int e_in_len)
{
int i;
@@ -2039,7 +2026,7 @@ int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
*
* \note Edges must already have the same vertices.
*/
-int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
+bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
{
BMLoop *l;
@@ -2050,7 +2037,7 @@ int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
* so assert on release builds */
BLI_assert(0);
- return FALSE;
+ return false;
}
while (e->l) {
@@ -2069,7 +2056,7 @@ int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
/* removes from disks too */
BM_edge_kill(bm, e);
- return TRUE;
+ return true;
}
/**
@@ -2083,7 +2070,7 @@ int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
* \note Does nothing if \a l_sep is already the only loop in the
* edge radial.
*/
-int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
+bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
{
BMEdge *ne;
int radlen;
@@ -2094,7 +2081,7 @@ int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
radlen = bmesh_radial_length(e->l);
if (radlen < 2) {
/* no cut required */
- return TRUE;
+ return true;
}
if (l_sep == e->l) {
@@ -2112,11 +2099,11 @@ int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
BM_CHECK_ELEMENT(ne);
BM_CHECK_ELEMENT(e);
- return TRUE;
+ return true;
}
/**
- * \brief Unglue Region Make Vert (URMV)
+ * \brief Un-glue Region Make Vert (URMV)
*
* Disconnects a face from its vertex fan at loop \a sl
*
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 5fd4a6ec7df..d8cfc973394 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -27,7 +27,8 @@
* \ingroup bmesh
*/
-BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges);
+BMFace *BM_face_copy(BMesh *bm, BMFace *f,
+ const bool copy_verts, const bool copy_edges);
typedef enum eBMCreateFlag {
/* faces and edges only */
@@ -49,16 +50,16 @@ void BM_face_kill(BMesh *bm, BMFace *f);
void BM_edge_kill(BMesh *bm, BMEdge *e);
void BM_vert_kill(BMesh *bm, BMVert *v);
-int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep);
-int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target);
-int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target);
+bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep);
+bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target);
+bool BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target);
-int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len);
+bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len);
-int bmesh_loop_reverse(BMesh *bm, BMFace *f);
+bool bmesh_loop_reverse(BMesh *bm, BMFace *f);
-BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del);
-int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
+BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del);
+bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
BMEdge **e_in, int e_in_len);
/* EULER API - For modifying structure */
@@ -68,11 +69,11 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1,
ListBase *holes,
#endif
BMEdge *example,
- const short nodouble
+ const bool no_double
);
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
-BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_splice);
+BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_splice);
BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv);
BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl);
diff --git a/source/blender/bmesh/intern/bmesh_error.h b/source/blender/bmesh/intern/bmesh_error.h
index 2ef146c7b38..0f23f87c143 100644
--- a/source/blender/bmesh/intern/bmesh_error.h
+++ b/source/blender/bmesh/intern/bmesh_error.h
@@ -35,11 +35,11 @@ void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg)
/* gets the topmost error from the stack.
* returns error code or 0 if no error.*/
-int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op);
-int BMO_error_occurred(BMesh *bm);
+int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op);
+bool BMO_error_occurred(BMesh *bm);
/* same as geterror, only pops the error off the stack as well */
-int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op);
+int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op);
void BMO_error_clear(BMesh *bm);
/* this is meant for handling errors, like self-intersection test failures.
diff --git a/source/blender/bmesh/intern/bmesh_inline.h b/source/blender/bmesh/intern/bmesh_inline.h
index 04b214f725a..102e9d47ffd 100644
--- a/source/blender/bmesh/intern/bmesh_inline.h
+++ b/source/blender/bmesh/intern/bmesh_inline.h
@@ -44,7 +44,7 @@ BLI_INLINE char _bm_elem_flag_test(const BMHeader *head, const char hflag)
return head->hflag & hflag;
}
-BLI_INLINE short _bm_elem_flag_test_bool(const BMHeader *head, const char hflag)
+BLI_INLINE bool _bm_elem_flag_test_bool(const BMHeader *head, const char hflag)
{
return (head->hflag & hflag) != 0;
}
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index caf9f3c70d5..44b8baace4c 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -172,11 +172,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks = NULL;
- float (*cos)[3] = NULL, *w = NULL;
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ void **blocks = BLI_array_alloca(blocks, source->len);
+ float (*cos)[3] = BLI_array_alloca(cos, source->len);
+ float *w = BLI_array_alloca(w, source->len);
int i;
BM_elem_attrs_copy(bm, bm, source, target);
@@ -196,10 +194,6 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, l_iter->head.data);
i++;
} while ((l_iter = l_iter->next) != l_first);
-
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(w);
- BLI_array_fixedstack_free(blocks);
}
/**
@@ -605,18 +599,16 @@ void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source)
* 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,
- int do_vertex, int do_multires)
+ const bool do_vertex, const bool do_multires)
{
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks = NULL;
- void **vblocks = NULL;
- float (*cos)[3] = NULL, co[3], *w = NULL;
- float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
+ void **vblocks = do_vertex ? BLI_array_alloca(vblocks, source->len) : NULL;
+ void **blocks = BLI_array_alloca(blocks, source->len);
+ float (*cos)[3] = BLI_array_alloca(cos, source->len);
+ float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
+ float *w = BLI_array_alloca(w, source->len);
+ float co[2];
int i, ax, ay;
BM_elem_attrs_copy(bm, bm, source, target->f);
@@ -625,7 +617,6 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
do {
copy_v3_v3(cos[i], l_iter->v->co);
- add_v3_v3(cent, cos[i]);
w[i] = 0.0f;
blocks[i] = l_iter->head.data;
@@ -642,38 +633,22 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
axis_dominant_v3(&ax, &ay, source->no);
- /* scale source face coordinates a bit, so points sitting directly on an
- * edge will work. */
- mul_v3_fl(cent, 1.0f / (float)source->len);
for (i = 0; i < source->len; i++) {
- float vec[3], tmp[3];
- sub_v3_v3v3(vec, cent, cos[i]);
- mul_v3_fl(vec, 0.001f);
- add_v3_v3(cos[i], vec);
-
- copy_v3_v3(tmp, cos[i]);
- cos[i][0] = tmp[ax];
- cos[i][1] = tmp[ay];
- cos[i][2] = 0.0f;
+ cos_2d[i][0] = cos[i][ax];
+ cos_2d[i][1] = cos[i][ay];
}
/* interpolate */
co[0] = target->v->co[ax];
co[1] = target->v->co[ay];
- co[2] = 0.0f;
- interp_weights_poly_v3(w, cos, source->len, co);
+ interp_weights_poly_v2(w, cos_2d, source->len, co);
CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data);
if (do_vertex) {
CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data);
- BLI_array_fixedstack_free(vblocks);
}
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(w);
- BLI_array_fixedstack_free(blocks);
-
if (do_multires) {
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
bm_loop_interp_mdisps(bm, target, source);
@@ -686,42 +661,24 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
{
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks = NULL;
- float (*cos)[3] = NULL, *w = NULL;
- float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ void **blocks = BLI_array_alloca(blocks, source->len);
+ float (*cos)[3] = BLI_array_alloca(cos, source->len);
+ float *w = BLI_array_alloca(w, source->len);
int i;
i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
do {
copy_v3_v3(cos[i], l_iter->v->co);
- add_v3_v3(cent, cos[i]);
w[i] = 0.0f;
blocks[i] = l_iter->v->head.data;
i++;
} while ((l_iter = l_iter->next) != l_first);
- /* scale source face coordinates a bit, so points sitting directly on an
- * edge will work. */
- mul_v3_fl(cent, 1.0f / (float)source->len);
- for (i = 0; i < source->len; i++) {
- float vec[3];
- sub_v3_v3v3(vec, cent, cos[i]);
- mul_v3_fl(vec, 0.01f);
- add_v3_v3(cos[i], vec);
- }
-
/* interpolate */
interp_weights_poly_v3(w, cos, source->len, v->co);
CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data);
-
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(w);
- BLI_array_fixedstack_free(blocks);
}
static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index 8be963f5798..3563ed1f40e 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -44,7 +44,7 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const floa
void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source);
void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
- int do_vertex, int do_multires);
+ const bool do_vertex, const bool do_multires);
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index c3f33eb95e1..44b76df7432 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -164,14 +164,12 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
*
* Counts how many flagged / unflagged items are found in this element.
*/
-int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const short value)
+int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value)
{
BMIter iter;
BMElem *ele;
int count = 0;
- BLI_assert(ELEM(value, TRUE, FALSE));
-
for (ele = BM_iter_new(&iter, NULL, itype, data); ele; ele = BM_iter_step(&iter)) {
if (BM_elem_flag_test_bool(ele, hflag) == value) {
count++;
@@ -186,14 +184,12 @@ int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, cons
*
* Counts how many flagged / unflagged items are found in this mesh.
*/
-int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const short value)
+int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value)
{
BMIter iter;
BMElem *ele;
int count = 0;
- BLI_assert(ELEM(value, TRUE, FALSE));
-
for (ele = BM_iter_new(&iter, bm, itype, NULL); ele; ele = BM_iter_step(&iter)) {
if (BM_elem_flag_test_bool(ele, hflag) == value) {
count++;
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index 7291bca6356..3b795a253bd 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -131,8 +131,8 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
__attribute__((warn_unused_result))
#endif
;
-int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const short value);
-int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const short value);
+int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value);
+int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value);
/* private for bmesh_iterators_inline.c */
void bmiter__vert_of_mesh_begin(struct BMIter *iter);
diff --git a/source/blender/bmesh/intern/bmesh_iterators_inline.h b/source/blender/bmesh/intern/bmesh_iterators_inline.h
index 96816521493..eef6544be89 100644
--- a/source/blender/bmesh/intern/bmesh_iterators_inline.h
+++ b/source/blender/bmesh/intern/bmesh_iterators_inline.h
@@ -35,7 +35,7 @@
/**
* \brief Iterator Step
*
- * Calls an iterators step fucntion to return the next element.
+ * Calls an iterators step function to return the next element.
*/
BLI_INLINE void *BM_iter_step(BMIter *iter)
{
@@ -50,7 +50,7 @@ BLI_INLINE void *BM_iter_step(BMIter *iter)
* it with the appropriate function pointers based
* upon its type.
*/
-BLI_INLINE int BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
+BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
{
/* int argtype; */
iter->itype = itype;
@@ -77,91 +77,61 @@ BLI_INLINE int BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *dat
iter->step = bmiter__face_of_mesh_step;
break;
case BM_EDGES_OF_VERT:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__edge_of_vert_begin;
iter->step = bmiter__edge_of_vert_step;
iter->vdata = data;
break;
case BM_FACES_OF_VERT:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__face_of_vert_begin;
iter->step = bmiter__face_of_vert_step;
iter->vdata = data;
break;
case BM_LOOPS_OF_VERT:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__loop_of_vert_begin;
iter->step = bmiter__loop_of_vert_step;
iter->vdata = data;
break;
case BM_VERTS_OF_EDGE:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__vert_of_edge_begin;
iter->step = bmiter__vert_of_edge_step;
iter->edata = data;
break;
case BM_FACES_OF_EDGE:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__face_of_edge_begin;
iter->step = bmiter__face_of_edge_step;
iter->edata = data;
break;
case BM_VERTS_OF_FACE:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__vert_of_face_begin;
iter->step = bmiter__vert_of_face_step;
iter->pdata = data;
break;
case BM_EDGES_OF_FACE:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__edge_of_face_begin;
iter->step = bmiter__edge_of_face_step;
iter->pdata = data;
break;
case BM_LOOPS_OF_FACE:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__loop_of_face_begin;
iter->step = bmiter__loop_of_face_step;
iter->pdata = data;
break;
case BM_LOOPS_OF_LOOP:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__loops_of_loop_begin;
iter->step = bmiter__loops_of_loop_step;
iter->ldata = data;
break;
case BM_LOOPS_OF_EDGE:
- if (UNLIKELY(!data)) {
- return FALSE;
- }
-
+ BLI_assert(data != NULL);
iter->begin = bmiter__loops_of_edge_begin;
iter->step = bmiter__loops_of_edge_step;
iter->edata = data;
@@ -169,13 +139,13 @@ BLI_INLINE int BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *dat
default:
/* should never happen */
BLI_assert(0);
- return FALSE;
+ return false;
break;
}
iter->begin(iter);
- return TRUE;
+ return true;
}
/**
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
new file mode 100644
index 00000000000..36a5412e401
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -0,0 +1,984 @@
+/*
+ * ***** 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 *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_ghash.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_mempool.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_customdata.h"
+
+#include "bmesh.h"
+#include "bmesh_log.h"
+#include "range_tree_c_api.h"
+
+struct BMLogEntry {
+ struct BMLogEntry *next, *prev;
+
+ /* The following GHashes map from an element ID to one of the log
+ * types above */
+
+ /* Elements that were in the previous entry, but have been
+ * deleted */
+ GHash *deleted_verts;
+ GHash *deleted_faces;
+ /* Elements that were not in the previous entry, but are in the
+ * result of this entry */
+ GHash *added_verts;
+ GHash *added_faces;
+
+ /* Vertices whose coordinates, mask value, or hflag have changed */
+ GHash *modified_verts;
+
+ BLI_mempool *pool_verts;
+ BLI_mempool *pool_faces;
+
+ /* This is only needed for dropping BMLogEntries while still in
+ * dynamic-topology mode, as that should release vert/face IDs
+ * back to the BMLog but no BMLog pointer is available at that
+ * time.
+ *
+ * This field is not guaranteed to be valid, any use of it should
+ * check for NULL. */
+ BMLog *log;
+};
+
+struct BMLog {
+ /* Tree of free IDs */
+ struct RangeTreeUInt *unused_ids;
+
+ /* Mapping from unique IDs to vertices and faces
+ *
+ * Each vertex and face in the log gets a unique unsigned integer
+ * assigned. That ID is taken from the set managed by the
+ * unused_ids range tree.
+ *
+ * The ID is needed because element pointers will change as they
+ * are created and deleted.
+ */
+ GHash *id_to_elem;
+ GHash *elem_to_id;
+
+ /* All BMLogEntrys, ordered from earliest to most recent */
+ ListBase entries;
+
+ /* The current log entry from entries list
+ *
+ * If null, then the original mesh from before any of the log
+ * entries is current (i.e. there is nothing left to undo.)
+ *
+ * If equal to the last entry in the entries list, then all log
+ * entries have been applied (i.e. there is nothing left to redo.)
+ */
+ BMLogEntry *current_entry;
+};
+
+typedef struct {
+ float co[3];
+ float mask;
+ char hflag;
+} BMLogVert;
+
+typedef struct {
+ unsigned int v_ids[3];
+} BMLogFace;
+
+/************************* Get/set element IDs ************************/
+
+/* Get the vertex's unique ID from the log */
+static unsigned int bm_log_vert_id_get(BMLog *log, BMVert *v)
+{
+ BLI_assert(BLI_ghash_haskey(log->elem_to_id, v));
+ return GET_INT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, v));
+}
+
+/* Set the vertex's unique ID in the log */
+static void bm_log_vert_id_set(BMLog *log, BMVert *v, unsigned int id)
+{
+ void *vid = SET_INT_IN_POINTER(id);
+
+ BLI_ghash_remove(log->id_to_elem, vid, NULL, NULL);
+ BLI_ghash_insert(log->id_to_elem, vid, v);
+ BLI_ghash_remove(log->elem_to_id, v, NULL, NULL);
+ BLI_ghash_insert(log->elem_to_id, v, vid);
+}
+
+/* Get a vertex from its unique ID */
+static BMVert *bm_log_vert_from_id(BMLog *log, unsigned int id)
+{
+ void *key = SET_INT_IN_POINTER(id);
+ BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
+ return BLI_ghash_lookup(log->id_to_elem, key);
+}
+
+/* Get the face's unique ID from the log */
+static unsigned int bm_log_face_id_get(BMLog *log, BMFace *f)
+{
+ BLI_assert(BLI_ghash_haskey(log->elem_to_id, f));
+ return GET_INT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, f));
+}
+
+/* Set the face's unique ID in the log */
+static void bm_log_face_id_set(BMLog *log, BMFace *f, unsigned int id)
+{
+ void *fid = SET_INT_IN_POINTER(id);
+
+ BLI_ghash_remove(log->id_to_elem, fid, NULL, NULL);
+ BLI_ghash_insert(log->id_to_elem, fid, f);
+ BLI_ghash_remove(log->elem_to_id, f, NULL, NULL);
+ BLI_ghash_insert(log->elem_to_id, f, fid);
+}
+
+/* Get a face from its unique ID */
+static BMFace *bm_log_face_from_id(BMLog *log, unsigned int id)
+{
+ void *key = SET_INT_IN_POINTER(id);
+ BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
+ return BLI_ghash_lookup(log->id_to_elem, key);
+}
+
+
+/************************ BMLogVert / BMLogFace ***********************/
+
+/* Get a vertex's paint-mask value
+ *
+ * Returns zero if no paint-mask layer is present */
+static float vert_mask_get(BMesh *bm, BMVert *v)
+{
+ float *mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
+ BLI_assert((CustomData_has_layer(&bm->vdata, CD_PAINT_MASK) == 0) == (mask == NULL));
+ if (mask) {
+ return *mask;
+ }
+ else {
+ return 0.0f;
+ }
+}
+
+/* Set a vertex's paint-mask value
+ *
+ * Has no effect is no paint-mask layer is present */
+static void vert_mask_set(BMesh *bm, BMVert *v, float new_mask)
+{
+ float *mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
+ BLI_assert((CustomData_has_layer(&bm->vdata, CD_PAINT_MASK) == 0) == (mask == NULL));
+ if (*mask) {
+ *mask = new_mask;
+ }
+}
+
+/* Update a BMLogVert with data from a BMVert */
+static void bm_log_vert_bmvert_copy(BMesh *bm, BMLogVert *lv, BMVert *v)
+{
+ copy_v3_v3(lv->co, v->co);
+ lv->mask = vert_mask_get(bm, v);
+ lv->hflag = v->head.hflag;
+}
+
+/* Allocate and initialize a BMLogVert */
+static BMLogVert *bm_log_vert_alloc(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
+
+ bm_log_vert_bmvert_copy(bm, lv, v);
+
+ return lv;
+}
+
+/* Allocate and initialize a BMLogFace */
+static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
+{
+ BMLogEntry *entry = log->current_entry;
+ BMLogFace *lf = BLI_mempool_alloc(entry->pool_faces);
+ BMVert *v[3];
+
+ BLI_assert(f->len == 3);
+
+ // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ BM_face_as_array_vert_tri(f, v);
+
+ lf->v_ids[0] = bm_log_vert_id_get(log, v[0]);
+ lf->v_ids[1] = bm_log_vert_id_get(log, v[1]);
+ lf->v_ids[2] = bm_log_vert_id_get(log, v[2]);
+
+ return lf;
+}
+
+
+/************************ Helpers for undo/redo ***********************/
+
+static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ BMVert *v = bm_log_vert_from_id(log, id);
+
+ /* Ensure the log has the final values of the vertex before
+ * deleting it */
+ bm_log_vert_bmvert_copy(bm, lv, v);
+
+ BM_vert_kill(bm, v);
+ }
+}
+
+static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ BMFace *f = bm_log_face_from_id(log, id);
+ BMEdge *e_tri[3];
+ BMLoop *l_iter;
+ int i;
+
+ l_iter = BM_FACE_FIRST_LOOP(f);
+ for (i = 0; i < 3; i++, l_iter = l_iter->next) {
+ e_tri[i] = l_iter->e;
+ }
+
+ /* Remove any unused edges */
+ BM_face_kill(bm, f);
+ for (i = 0; i < 3; i++) {
+ if (BM_edge_is_wire(e_tri[i])) {
+ BM_edge_kill(bm, e_tri[i]);
+ }
+ }
+ }
+}
+
+static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ BMVert *v = BM_vert_create(bm, lv->co, NULL, 0);
+ v->head.hflag = lv->hflag;
+ vert_mask_set(bm, v, lv->mask);
+ bm_log_vert_id_set(log, v, GET_INT_FROM_POINTER(key));
+ }
+}
+
+static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
+ BMVert *v[3] = {bm_log_vert_from_id(log, lf->v_ids[0]),
+ bm_log_vert_from_id(log, lf->v_ids[1]),
+ bm_log_vert_from_id(log, lf->v_ids[2])};
+ BMFace *f;
+
+ f = BM_face_create_quad_tri_v(bm, v, 3, NULL, false);
+ bm_log_face_id_set(log, f, GET_INT_FROM_POINTER(key));
+ }
+}
+
+static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ BMVert *v = bm_log_vert_from_id(log, id);
+ float mask;
+
+ swap_v3_v3(v->co, lv->co);
+ SWAP(char, v->head.hflag, lv->hflag);
+ mask = lv->mask;
+ lv->mask = vert_mask_get(bm, v);
+ vert_mask_set(bm, v, mask);
+ }
+}
+
+
+/**********************************************************************/
+
+/* Assign unique IDs to all vertices and faces already in the BMesh */
+static void bm_log_assign_ids(BMesh *bm, BMLog *log)
+{
+ BMIter iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Generate vertex IDs */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ unsigned int id = range_tree_uint_take_any(log->unused_ids);
+ bm_log_vert_id_set(log, v, id);
+ }
+
+ /* Generate face IDs */
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ unsigned int id = range_tree_uint_take_any(log->unused_ids);
+ bm_log_face_id_set(log, f, id);
+ }
+}
+
+/* Allocate an empty log entry */
+static BMLogEntry *bm_log_entry_create(void)
+{
+ BMLogEntry *entry = MEM_callocN(sizeof(BMLogEntry), AT);
+
+ entry->deleted_verts = BLI_ghash_ptr_new(AT);
+ entry->deleted_faces = BLI_ghash_ptr_new(AT);
+ entry->added_verts = BLI_ghash_ptr_new(AT);
+ entry->added_faces = BLI_ghash_ptr_new(AT);
+ entry->modified_verts = BLI_ghash_ptr_new(AT);
+
+ entry->pool_verts = BLI_mempool_create(sizeof(BMLogVert), 1, 64, 0);
+ entry->pool_faces = BLI_mempool_create(sizeof(BMLogFace), 1, 64, 0);
+
+ return entry;
+}
+
+/* Free the data in a log entry
+ *
+ * Note: does not free the log entry itself */
+static void bm_log_entry_free(BMLogEntry *entry)
+{
+ BLI_ghash_free(entry->deleted_verts, NULL, NULL);
+ BLI_ghash_free(entry->deleted_faces, NULL, NULL);
+ BLI_ghash_free(entry->added_verts, NULL, NULL);
+ BLI_ghash_free(entry->added_faces, NULL, NULL);
+ BLI_ghash_free(entry->modified_verts, NULL, NULL);
+
+ BLI_mempool_destroy(entry->pool_verts);
+ BLI_mempool_destroy(entry->pool_faces);
+}
+
+static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash)
+{
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, id_ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+
+ if (range_tree_uint_has(unused_ids, id)) {
+ range_tree_uint_take(unused_ids, id);
+ }
+ }
+}
+
+static int uint_compare(const void *a_v, const void *b_v)
+{
+ const unsigned int *a = a_v;
+ const unsigned int *b = b_v;
+ return (*a) < (*b);
+}
+
+/* Remap IDs to contiguous indices
+ *
+ * E.g. if the vertex IDs are (4, 1, 10, 3), the mapping will be:
+ * 4 -> 2
+ * 1 -> 0
+ * 10 -> 3
+ * 3 -> 1
+ */
+static GHash *bm_log_compress_ids_to_indices(unsigned int *ids, int totid)
+{
+ GHash *map = BLI_ghash_int_new(AT);
+ int i;
+
+ qsort(ids, totid, sizeof(*ids), uint_compare);
+
+ for (i = 0; i < totid; i++) {
+ void *key = SET_INT_IN_POINTER(ids[i]);
+ void *val = SET_INT_IN_POINTER(i);
+ BLI_ghash_insert(map, key, val);
+ }
+
+ return map;
+}
+
+/* Release all ID keys in id_ghash */
+static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
+{
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, id_ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ range_tree_uint_release(log->unused_ids, id);
+ }
+}
+
+/***************************** Public API *****************************/
+
+/* Allocate, initialize, and assign a new BMLog */
+BMLog *BM_log_create(BMesh *bm)
+{
+ BMLog *log = MEM_callocN(sizeof(*log), AT);
+
+ log->unused_ids = range_tree_uint_alloc(0, (unsigned)-1);
+ log->id_to_elem = BLI_ghash_ptr_new(AT);
+ log->elem_to_id = BLI_ghash_ptr_new(AT);
+
+ /* Assign IDs to all existing vertices and faces */
+ bm_log_assign_ids(bm, log);
+
+ return log;
+}
+
+/* Allocate and initialize a new BMLog using existing BMLogEntries
+ *
+ * The 'entry' should be the last entry in the BMLog. Its prev pointer
+ * will be followed back to find the first entry.
+ *
+ * The unused IDs field of the log will be initialized by taking all
+ * keys from all GHashes in the log entry.
+ */
+BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry)
+{
+ BMLog *log = BM_log_create(bm);
+
+ if (entry->prev)
+ log->current_entry = entry;
+ else
+ log->current_entry = NULL;
+
+ /* Let BMLog manage the entry list again */
+ log->entries.first = log->entries.last = entry;
+
+ {
+ while (entry->prev) {
+ entry = entry->prev;
+ log->entries.first = entry;
+ }
+ entry = log->entries.last;
+ while (entry->next) {
+ entry = entry->next;
+ log->entries.last = entry;
+ }
+ }
+
+ for (entry = log->entries.first; entry; entry = entry->next) {
+ entry->log = log;
+
+ /* Take all used IDs */
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->modified_verts);
+ }
+
+ return log;
+}
+
+/* Free all the data in a BMLog including the log itself */
+void BM_log_free(BMLog *log)
+{
+ BMLogEntry *entry;
+
+ if (log->unused_ids)
+ range_tree_uint_free(log->unused_ids);
+
+ if (log->id_to_elem)
+ BLI_ghash_free(log->id_to_elem, NULL, NULL);
+
+ if (log->elem_to_id)
+ BLI_ghash_free(log->elem_to_id, NULL, NULL);
+
+ /* Clear the BMLog references within each entry, but do not free
+ * the entries themselves */
+ for (entry = log->entries.first; entry; entry = entry->next)
+ entry->log = NULL;
+
+ MEM_freeN(log);
+}
+
+/* Get the number of log entries */
+int BM_log_length(const BMLog *log)
+{
+ return BLI_countlist(&log->entries);
+}
+
+/* Apply a consistent ordering to BMesh vertices */
+void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
+{
+ void *varr;
+ void *farr;
+
+ GHash *id_to_idx;
+
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ int i;
+
+ /* Put all vertex IDs into an array */
+ i = 0;
+ varr = MEM_mallocN(sizeof(int) * bm->totvert, AT);
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ ((unsigned int *)varr)[i++] = bm_log_vert_id_get(log, v);
+ }
+
+ /* Put all face IDs into an array */
+ i = 0;
+ farr = MEM_mallocN(sizeof(int) * bm->totface, AT);
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ ((unsigned int *)farr)[i++] = bm_log_face_id_get(log, f);
+ }
+
+ /* Create BMVert index remap array */
+ id_to_idx = bm_log_compress_ids_to_indices(varr, bm->totvert);
+ i = 0;
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ const unsigned id = bm_log_vert_id_get(log, v);
+ const void *key = SET_INT_IN_POINTER(id);
+ const void *val = BLI_ghash_lookup(id_to_idx, key);
+ ((int *)varr)[i++] = GET_INT_FROM_POINTER(val);
+ }
+ BLI_ghash_free(id_to_idx, NULL, NULL);
+
+ /* Create BMFace index remap array */
+ id_to_idx = bm_log_compress_ids_to_indices(farr, bm->totface);
+ i = 0;
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ const unsigned id = bm_log_face_id_get(log, f);
+ const void *key = SET_INT_IN_POINTER(id);
+ const void *val = BLI_ghash_lookup(id_to_idx, key);
+ ((int *)farr)[i++] = GET_INT_FROM_POINTER(val);
+ }
+ BLI_ghash_free(id_to_idx, NULL, NULL);
+
+ BM_mesh_remap(bm, varr, NULL, farr);
+
+ MEM_freeN(varr);
+ MEM_freeN(farr);
+}
+
+/* Start a new log entry and update the log entry list
+ *
+ * If the log entry list is empty, or if the current log entry is the
+ * last entry, the new entry is simply appended to the end.
+ *
+ * Otherwise, the new entry is added after the current entry and all
+ * following entries are deleted.
+ *
+ * In either case, the new entry is set as the current log entry.
+ */
+BMLogEntry *BM_log_entry_add(BMLog *log)
+{
+ BMLogEntry *entry, *next;
+
+ /* Delete any entries after the current one */
+ entry = log->current_entry;
+ if (entry) {
+ for (entry = entry->next; entry; entry = next) {
+ next = entry->next;
+ bm_log_entry_free(entry);
+ BLI_freelinkN(&log->entries, entry);
+ }
+ }
+
+ /* Create and append the new entry */
+ entry = bm_log_entry_create();
+ BLI_addtail(&log->entries, entry);
+ entry->log = log;
+ log->current_entry = entry;
+
+ return entry;
+}
+
+/* Remove an entry from the log
+ *
+ * Uses entry->log as the log. If the log is NULL, the entry will be
+ * free'd but not removed from any list, nor shall its IDs be
+ * released.
+ *
+ * This operation is only valid on the first and last entries in the
+ * log. Deleting from the middle will assert.
+ */
+void BM_log_entry_drop(BMLogEntry *entry)
+{
+ BMLog *log = entry->log;
+
+ if (!log) {
+ /* Unlink */
+ BLI_assert(!(entry->prev && entry->next));
+ if (entry->prev)
+ entry->prev->next = NULL;
+ else if (entry->next)
+ entry->next->prev = NULL;
+
+ bm_log_entry_free(entry);
+ MEM_freeN(entry);
+ return;
+ }
+
+ if (!entry->prev) {
+ /* Release IDs of elements that are deleted by this
+ * entry. Since the entry is at the beginning of the undo
+ * stack, and it's being deleted, those elements can never be
+ * restored. Their IDs can go back into the pool. */
+ bm_log_id_ghash_release(log, entry->deleted_faces);
+ bm_log_id_ghash_release(log, entry->deleted_verts);
+ }
+ else if (!entry->next) {
+ /* Release IDs of elements that are added by this entry. Since
+ * the entry is at the end of the undo stack, and it's being
+ * deleted, those elements can never be restored. Their IDs
+ * can go back into the pool. */
+ bm_log_id_ghash_release(log, entry->added_faces);
+ bm_log_id_ghash_release(log, entry->added_verts);
+ }
+ else {
+ BLI_assert(!"Cannot drop BMLogEntry from middle");
+ }
+
+ if (log->current_entry == entry)
+ log->current_entry = entry->prev;
+
+ bm_log_entry_free(entry);
+ BLI_freelinkN(&log->entries, entry);
+}
+
+/* Undo one BMLogEntry
+ *
+ * Has no effect if there's nothing left to undo */
+void BM_log_undo(BMesh *bm, BMLog *log)
+{
+ BMLogEntry *entry = log->current_entry;
+
+ if (entry) {
+ log->current_entry = entry->prev;
+
+ /* Delete added faces and verts */
+ bm_log_faces_unmake(bm, log, entry->added_faces);
+ bm_log_verts_unmake(bm, log, entry->added_verts);
+
+ /* Restore deleted verts and faces */
+ bm_log_verts_restore(bm, log, entry->deleted_verts);
+ bm_log_faces_restore(bm, log, entry->deleted_faces);
+
+ /* Restore vertex coordinates, mask, and hflag */
+ bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ }
+}
+
+/* Redo one BMLogEntry
+ *
+ * Has no effect if there's nothing left to redo */
+void BM_log_redo(BMesh *bm, BMLog *log)
+{
+ BMLogEntry *entry = log->current_entry;
+
+ if (!entry) {
+ /* Currently at the beginning of the undo stack, move to first entry */
+ entry = log->entries.first;
+ }
+ else if (entry && entry->next) {
+ /* Move to next undo entry */
+ entry = entry->next;
+ }
+ else {
+ /* Currently at the end of the undo stack, nothing left to redo */
+ return;
+ }
+
+ log->current_entry = entry;
+
+ if (entry) {
+ /* Re-delete previously deleted faces and verts */
+ bm_log_faces_unmake(bm, log, entry->deleted_faces);
+ bm_log_verts_unmake(bm, log, entry->deleted_verts);
+
+ /* Restore previously added verts and faces */
+ bm_log_verts_restore(bm, log, entry->added_verts);
+ bm_log_faces_restore(bm, log, entry->added_faces);
+
+ /* Restore vertex coordinates, mask, and hflag */
+ bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ }
+}
+
+/* Log a vertex before it is modified
+ *
+ * Before modifying vertex coordinates, masks, or hflags, call this
+ * function to log it's current values. This is better than logging
+ * after the coordinates have been modified, because only those
+ * vertices that are modified need to have their original values
+ * stored.
+ *
+ * Handles two separate cases:
+ *
+ * If the vertex was added in the current log entry, update the
+ * vertex in the map of added vertices.
+ *
+ * If the vertex already existed prior to the current log entry, a
+ * separate key/value map of modified vertices is used (using the
+ * vertex's ID as the key). The values stored in that case are
+ * the vertex's original state so that an undo can restore the
+ * previous state.
+ *
+ * On undo, the current vertex state will be swapped with the stored
+ * state so that a subsequent redo operation will restore the newer
+ * vertex state.
+ */
+void BM_log_vert_before_modified(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ BMLogVert *lv;
+ unsigned int v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ /* Find or create the BMLogVert entry */
+ if ((lv = BLI_ghash_lookup(entry->added_verts, key))) {
+ bm_log_vert_bmvert_copy(bm, lv, v);
+ }
+ else if (!BLI_ghash_haskey(entry->modified_verts, key)) {
+ lv = bm_log_vert_alloc(bm, log, v);
+ BLI_ghash_insert(entry->modified_verts, key, lv);
+ }
+}
+
+/* Log a new vertex as added to the BMesh
+ *
+ * The new vertex gets a unique ID assigned. It is then added to a map
+ * of added vertices, with the key being its ID and the value
+ * containing everything needed to reconstruct that vertex.
+ */
+void BM_log_vert_added(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogVert *lv;
+ unsigned int v_id = range_tree_uint_take_any(log->unused_ids);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ bm_log_vert_id_set(log, v, v_id);
+ lv = bm_log_vert_alloc(bm, log, v);
+ BLI_ghash_insert(log->current_entry->added_verts, key, lv);
+}
+
+/* Log a new face as added to the BMesh
+ *
+ * The new face gets a unique ID assigned. It is then added to a map
+ * of added faces, with the key being its ID and the value containing
+ * everything needed to reconstruct that face.
+ */
+void BM_log_face_added(BMLog *log, BMFace *f)
+{
+ BMLogFace *lf;
+ unsigned int f_id = range_tree_uint_take_any(log->unused_ids);
+ void *key = SET_INT_IN_POINTER(f_id);
+
+ /* Only triangles are supported for now */
+ BLI_assert(f->len == 3);
+
+ bm_log_face_id_set(log, f, f_id);
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(log->current_entry->added_faces, key, lf);
+}
+
+/* Log a vertex as removed from the BMesh
+ *
+ * A couple things can happen here:
+ *
+ * If the vertex was added as part of the current log entry, then it's
+ * deleted and forgotten about entirely. Its unique ID is returned to
+ * the unused pool.
+ *
+ * If the vertex was already part of the BMesh before the current log
+ * entry, it is added to a map of deleted vertices, with the key being
+ * its ID and the value containing everything needed to reconstruct
+ * that vertex.
+ *
+ * If there's a move record for the vertex, that's used as the
+ * vertices original location, then the move record is deleted.
+ */
+void BM_log_vert_removed(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ unsigned int v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ /* if it has a key, it shouldn't be NULL */
+ BLI_assert(!!BLI_ghash_lookup(entry->added_verts, key) ==
+ !!BLI_ghash_haskey(entry->added_verts, key));
+
+ if (BLI_ghash_remove(entry->added_verts, key, NULL, NULL)) {
+ range_tree_uint_release(log->unused_ids, v_id);
+ }
+ else {
+ BMLogVert *lv, *lv_mod;
+
+ lv = bm_log_vert_alloc(bm, log, v);
+ BLI_ghash_insert(entry->deleted_verts, key, lv);
+
+ /* If the vertex was modified before deletion, ensure that the
+ * original vertex values are stored */
+ if ((lv_mod = BLI_ghash_lookup(entry->modified_verts, key))) {
+ (*lv) = (*lv_mod);
+ BLI_ghash_remove(entry->modified_verts, key, NULL, NULL);
+ }
+ }
+}
+
+/* Log a face as removed from the BMesh
+ *
+ * A couple things can happen here:
+ *
+ * If the face was added as part of the current log entry, then it's
+ * deleted and forgotten about entirely. Its unique ID is returned to
+ * the unused pool.
+ *
+ * If the face was already part of the BMesh before the current log
+ * entry, it is added to a map of deleted faces, with the key being
+ * its ID and the value containing everything needed to reconstruct
+ * that face.
+ */
+void BM_log_face_removed(BMLog *log, BMFace *f)
+{
+ BMLogEntry *entry = log->current_entry;
+ unsigned int f_id = bm_log_face_id_get(log, f);
+ void *key = SET_INT_IN_POINTER(f_id);
+
+ /* if it has a key, it shouldn't be NULL */
+ BLI_assert(!!BLI_ghash_lookup(entry->added_faces, key) ==
+ !!BLI_ghash_haskey(entry->added_faces, key));
+
+ if (BLI_ghash_remove(entry->added_faces, key, NULL, NULL)) {
+ range_tree_uint_release(log->unused_ids, f_id);
+ }
+ else {
+ BMLogFace *lf;
+
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(entry->deleted_faces, key, lf);
+ }
+}
+
+/* Log all vertices/faces in the BMesh as added */
+void BM_log_all_added(BMesh *bm, BMLog *log)
+{
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Log all vertices as newly created */
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ BM_log_vert_added(bm, log, v);
+ }
+
+ /* Log all faces as newly created */
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ BM_log_face_added(log, f);
+ }
+}
+
+/* Log all vertices/faces in the BMesh as removed */
+void BM_log_before_all_removed(BMesh *bm, BMLog *log)
+{
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Log deletion of all faces */
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ BM_log_face_removed(log, f);
+ }
+
+ /* Log deletion of all vertices */
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ BM_log_vert_removed(bm, log, v);
+ }
+}
+
+/* Get the logged coordinates of a vertex
+ *
+ * Does not modify the log or the vertex */
+const float *BM_log_original_vert_co(BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ BLI_assert(entry);
+
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ return lv->co;
+}
+
+/* Get the logged mask of a vertex
+ *
+ * Does not modify the log or the vertex */
+float BM_log_original_mask(BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ BLI_assert(entry);
+
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ return lv->mask;
+}
+
+/************************ Debugging and Testing ***********************/
+
+/* For internal use only (unit testing) */
+BMLogEntry *BM_log_current_entry(BMLog *log)
+{
+ return log->current_entry;
+}
+
+/* For internal use only (unit testing) */
+RangeTreeUInt *BM_log_unused_ids(BMLog *log)
+{
+ return log->unused_ids;
+}
+
+#if 0
+/* Print the list of entries, marking the current one
+ *
+ * Keep around for debugging */
+void bm_log_print(const BMLog *log, const char *description)
+{
+ const BMLogEntry *entry;
+ const char *current = " <-- current";
+ int i;
+
+ printf("%s:\n", description);
+ printf(" % 2d: [ initial ]%s\n", 0,
+ (!log->current_entry) ? current : "");
+ for (entry = log->entries.first, i = 1; entry; entry = entry->next, i++) {
+ printf(" % 2d: [%p]%s\n", i, entry,
+ (entry == log->current_entry) ? current : "");
+ }
+}
+#endif
diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h
new file mode 100644
index 00000000000..958ff340b43
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_log.h
@@ -0,0 +1,102 @@
+/*
+ * ***** 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_LOG_H__
+#define __BMESH_LOG_H__
+
+/* The BMLog is an interface for storing undo/redo steps as a BMesh is
+ * modified. It only stores changes to the BMesh, not full copies.
+ *
+ * Currently it supports the following types of changes:
+ *
+ * - Adding and removing vertices
+ * - Adding and removing faces
+ * - Moving vertices
+ * - Setting vertex paint-mask values
+ * - Setting vertex hflags
+ */
+
+struct BMFace;
+struct BMVert;
+struct BMesh;
+struct RangeTreeUInt;
+
+typedef struct BMLog BMLog;
+typedef struct BMLogEntry BMLogEntry;
+
+/* Allocate and initialize a new BMLog */
+BMLog *BM_log_create(BMesh *bm);
+
+/* Allocate and initialize a new BMLog using existing BMLogEntries */
+BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry);
+
+/* Free all the data in a BMLog including the log itself */
+void BM_log_free(BMLog *log);
+
+/* Get the number of log entries */
+int BM_log_length(const BMLog *log);
+
+/* Apply a consistent ordering to BMesh vertices and faces */
+void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log);
+
+/* Start a new log entry and update the log entry list */
+BMLogEntry *BM_log_entry_add(BMLog *log);
+
+/* Remove an entry from the log */
+void BM_log_entry_drop(BMLogEntry *entry);
+
+/* Undo one BMLogEntry */
+void BM_log_undo(BMesh *bm, BMLog *log);
+
+/* Redo one BMLogEntry */
+void BM_log_redo(BMesh *bm, BMLog *log);
+
+/* Log a vertex before it is modified */
+void BM_log_vert_before_modified(BMesh *bm, BMLog *log, struct BMVert *v);
+
+/* Log a new vertex as added to the BMesh */
+void BM_log_vert_added(BMesh *bm, BMLog *log, struct BMVert *v);
+
+/* Log a new face as added to the BMesh */
+void BM_log_face_added(BMLog *log, struct BMFace *f);
+
+/* Log a vertex as removed from the BMesh */
+void BM_log_vert_removed(BMesh *bm, BMLog *log, struct BMVert *v);
+
+/* Log a face as removed from the BMesh */
+void BM_log_face_removed(BMLog *log, struct BMFace *f);
+
+/* Log all vertices/faces in the BMesh as added */
+void BM_log_all_added(BMesh *bm, BMLog *log);
+
+/* Log all vertices/faces in the BMesh as removed */
+void BM_log_before_all_removed(BMesh *bm, BMLog *log);
+
+/* Get the logged coordinates of a vertex */
+const float *BM_log_original_vert_co(BMLog *log, BMVert *v);
+
+/* Get the logged mask of a vertex */
+float BM_log_original_mask(BMLog *log, BMVert *v);
+
+/* For internal use only (unit testing) */
+BMLogEntry *BM_log_current_entry(BMLog *log);
+struct RangeTreeUInt *BM_log_unused_ids(BMLog *log);
+
+#endif
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 9af65d7dd7e..4e29756104a 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -44,8 +44,6 @@
static void recount_totsels(BMesh *bm)
{
- BMIter iter;
- BMElem *ele;
const char iter_types[3] = {BM_VERTS_OF_MESH,
BM_EDGES_OF_MESH,
BM_FACES_OF_MESH};
@@ -58,11 +56,16 @@ static void recount_totsels(BMesh *bm)
tots[1] = &bm->totedgesel;
tots[2] = &bm->totfacesel;
+#pragma omp parallel for schedule(dynamic)
for (i = 0; i < 3; i++) {
- ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) *tots[i] += 1;
+ BMIter iter;
+ BMElem *ele;
+ int count = 0;
+
+ BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) count += 1;
}
+ *tots[i] = count;
}
}
@@ -83,52 +86,61 @@ void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode)
BMIter eiter;
BMIter fiter;
- int ok;
-
if (selectmode & SCE_SELECT_VERTEX) {
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ /* both loops only set edge/face flags and read off verts */
+#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
{
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
- }
- else {
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
- }
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
- ok = FALSE;
- break;
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
}
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = FALSE;
+ else {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ }
}
+#pragma omp section
+ {
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ bool ok = true;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ ok = false;
+ }
- BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
+ BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
+ }
+ }
}
+ /* end sections */
}
else if (selectmode & SCE_SELECT_EDGE) {
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
+ bool ok = true;
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
if (!BM_elem_flag_test(l_iter->e, BM_ELEM_SELECT)) {
- ok = FALSE;
+ ok = false;
break;
}
} while ((l_iter = l_iter->next) != l_first);
}
else {
- ok = FALSE;
+ ok = false;
}
BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
@@ -159,36 +171,47 @@ void BM_mesh_deselect_flush(BMesh *bm)
BMIter eiter;
BMIter fiter;
- int ok;
+ bool ok;
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN)))
+ /* we can use 2 sections here because the second loop isnt checking edge selection */
+#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
{
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN)))
+ {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ }
}
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
- ok = FALSE;
- break;
+#pragma omp section
+ {
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ ok = true;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ ok = false;
}
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = FALSE;
- }
- if (ok == FALSE) {
- BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ if (ok == false) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ }
+ }
}
}
+ /* end sections */
/* Remove any deselected elements from the BMEditSelection */
BM_select_history_validate(bm);
@@ -210,34 +233,44 @@ void BM_mesh_select_flush(BMesh *bm)
BMIter eiter;
BMIter fiter;
- int ok;
+ bool ok;
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ /* we can use 2 sections here because the second loop isnt checking edge selection */
+#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
{
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ }
+ }
}
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
- ok = FALSE;
- break;
+#pragma omp section
+ {
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ ok = true;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ ok = false;
}
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = FALSE;
- }
- if (ok) {
- BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ if (ok) {
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ }
+ }
}
}
@@ -250,7 +283,7 @@ void BM_mesh_select_flush(BMesh *bm)
* Changes selection state of a single vertex
* in a mesh
*/
-void BM_vert_select_set(BMesh *bm, BMVert *v, int select)
+void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
{
BLI_assert(v->head.htype == BM_VERT);
@@ -277,7 +310,7 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, int select)
*
* Changes selection state of a single edge in a mesh.
*/
-void BM_edge_select_set(BMesh *bm, BMEdge *e, int select)
+void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
{
BLI_assert(e->head.htype == BM_EDGE);
@@ -289,8 +322,8 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, int select)
if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel += 1;
BM_elem_flag_enable(e, BM_ELEM_SELECT);
- BM_vert_select_set(bm, e->v1, TRUE);
- BM_vert_select_set(bm, e->v2, TRUE);
+ 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;
@@ -321,13 +354,13 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, int select)
}
if (deselect) {
- BM_vert_select_set(bm, verts[i], FALSE);
+ BM_vert_select_set(bm, verts[i], false);
}
}
}
else {
- BM_vert_select_set(bm, e->v1, FALSE);
- BM_vert_select_set(bm, e->v2, FALSE);
+ BM_vert_select_set(bm, e->v1, false);
+ BM_vert_select_set(bm, e->v2, false);
}
}
@@ -339,7 +372,7 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, int select)
* Changes selection state of a single
* face in a mesh.
*/
-void BM_face_select_set(BMesh *bm, BMFace *f, int select)
+void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
{
BMLoop *l_iter;
BMLoop *l_first;
@@ -358,8 +391,8 @@ void BM_face_select_set(BMesh *bm, BMFace *f, int select)
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);
- BM_edge_select_set(bm, l_iter->e, TRUE);
+ BM_vert_select_set(bm, l_iter->v, true);
+ BM_edge_select_set(bm, l_iter->e, true);
} while ((l_iter = l_iter->next) != l_first);
}
else {
@@ -379,7 +412,7 @@ void BM_face_select_set(BMesh *bm, BMFace *f, int select)
}
if (!f2) {
- BM_edge_select_set(bm, l->e, FALSE);
+ BM_edge_select_set(bm, l->e, false);
}
}
@@ -393,7 +426,7 @@ void BM_face_select_set(BMesh *bm, BMFace *f, int select)
}
if (!e) {
- BM_vert_select_set(bm, l->v, FALSE);
+ BM_vert_select_set(bm, l->v, false);
}
}
}
@@ -434,7 +467,7 @@ void BM_mesh_select_mode_set(BMesh *bm, int selectmode)
BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- BM_edge_select_set(bm, (BMEdge *)ele, TRUE);
+ BM_edge_select_set(bm, (BMEdge *)ele, true);
}
}
BM_mesh_select_mode_flush(bm);
@@ -448,7 +481,7 @@ void BM_mesh_select_mode_set(BMesh *bm, int selectmode)
#endif
BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- BM_face_select_set(bm, (BMFace *)ele, TRUE);
+ BM_face_select_set(bm, (BMFace *)ele, true);
}
}
BM_mesh_select_mode_flush(bm);
@@ -459,14 +492,12 @@ void BM_mesh_select_mode_set(BMesh *bm, int selectmode)
* counts number of elements with flag enabled/disabled
*/
static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag,
- const short respecthide, const short test_for_enabled)
+ const short respecthide, const bool test_for_enabled)
{
BMElem *ele;
BMIter iter;
int tot = 0;
- BLI_assert(ELEM(test_for_enabled, TRUE, FALSE));
-
if (htype & BM_VERT) {
for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) {
if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue;
@@ -489,21 +520,21 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag,
return tot;
}
-int BM_mesh_elem_hflag_count_enabled(BMesh *bm, const char htype, const char hflag, int respecthide)
+int BM_mesh_elem_hflag_count_enabled(BMesh *bm, const char htype, const char hflag, const bool respecthide)
{
- return bm_mesh_flag_count(bm, htype, hflag, respecthide, TRUE);
+ return bm_mesh_flag_count(bm, htype, hflag, respecthide, true);
}
-int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hflag, int respecthide)
+int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hflag, const bool respecthide)
{
- return bm_mesh_flag_count(bm, htype, hflag, respecthide, FALSE);
+ return bm_mesh_flag_count(bm, htype, hflag, respecthide, false);
}
/**
* \note use BM_elem_flag_test(ele, BM_ELEM_SELECT) to test selection
* \note by design, this will not touch the editselection history stuff
*/
-void BM_elem_select_set(BMesh *bm, BMElem *ele, int select)
+void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select)
{
switch (ele->head.htype) {
case BM_VERT:
@@ -527,12 +558,12 @@ void BM_active_face_set(BMesh *bm, BMFace *efa)
bm->act_face = efa;
}
-BMFace *BM_active_face_get(BMesh *bm, int sloppy, int selected)
+BMFace *BM_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected)
{
- if (bm->act_face && (!selected || BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT))) {
+ if (bm->act_face && (!is_selected || BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT))) {
return bm->act_face;
}
- else if (sloppy) {
+ else if (is_sloppy) {
BMIter iter;
BMFace *f = NULL;
BMEditSelection *ese;
@@ -546,7 +577,7 @@ BMFace *BM_active_face_get(BMesh *bm, int sloppy, int selected)
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
f = NULL;
}
- else if (selected && !BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ else if (is_selected && !BM_elem_flag_test(f, BM_ELEM_SELECT)) {
f = NULL;
}
else {
@@ -679,12 +710,13 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3])
cross_v3_v3v3(r_plane, efa->no, vec);
}
else {
- BMVert *verts[4] = {NULL};
-
- BM_iter_as_array(NULL, BM_VERTS_OF_FACE, efa, (void **)verts, 4);
-
if (efa->len == 4) {
+ BMVert *verts[4] = {NULL};
float vecA[3], vecB[3];
+
+ // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, efa, (void **)verts, 4);
+ BM_face_as_array_vert_quad(efa, verts);
+
sub_v3_v3v3(vecA, verts[3]->co, verts[2]->co);
sub_v3_v3v3(vecB, verts[0]->co, verts[1]->co);
add_v3_v3v3(r_plane, vecA, vecB);
@@ -710,20 +742,20 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3])
/* --- macro wrapped funcs --- */
-int _bm_select_history_check(BMesh *bm, const BMHeader *ele)
+bool _bm_select_history_check(BMesh *bm, const BMHeader *ele)
{
return (BLI_findptr(&bm->selected, ele, offsetof(BMEditSelection, ele)) != NULL);
}
-int _bm_select_history_remove(BMesh *bm, BMHeader *ele)
+bool _bm_select_history_remove(BMesh *bm, BMHeader *ele)
{
BMEditSelection *ese = BLI_findptr(&bm->selected, ele, offsetof(BMEditSelection, ele));
if (ese) {
BLI_freelinkN(&bm->selected, ese);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
@@ -767,10 +799,10 @@ void BM_select_history_validate(BMesh *bm)
}
/* utility function */
-int BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
+bool BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
{
BMEditSelection *ese_last = bm->selected.last;
- BMFace *efa = BM_active_face_get(bm, FALSE, FALSE);
+ BMFace *efa = BM_active_face_get(bm, false, false);
ese->next = ese->prev = NULL;
@@ -795,14 +827,14 @@ int BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
}
else {
ese->ele = NULL;
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hflag,
- int respecthide, const char hflag_test)
+ const bool respecthide, const char hflag_test)
{
const char iter_types[3] = {BM_VERTS_OF_MESH,
BM_EDGES_OF_MESH,
@@ -810,8 +842,6 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
- BMIter iter;
- BMElem *ele;
int i;
if (hflag & BM_ELEM_SELECT) {
@@ -820,21 +850,30 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
if ((htype == (BM_VERT | BM_EDGE | BM_FACE)) &&
(hflag == BM_ELEM_SELECT) &&
- (respecthide == FALSE) &&
+ (respecthide == false) &&
(hflag_test == 0))
{
/* fast path for deselect all, avoid topology loops
* since we know all will be de-selected anyway. */
+
+#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
for ( ; ele; ele = BM_iter_step(&iter)) {
BM_elem_flag_disable(ele, BM_ELEM_SELECT);
}
}
+
bm->totvertsel = bm->totedgesel = bm->totfacesel = 0;
}
else {
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
if (htype & flag_types[i]) {
ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
for ( ; ele; ele = BM_iter_step(&iter)) {
@@ -847,7 +886,7 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
}
if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, FALSE);
+ BM_elem_select_set(bm, ele, false);
}
BM_elem_flag_disable(ele, hflag);
}
@@ -857,7 +896,7 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
}
void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hflag,
- int respecthide, const char hflag_test)
+ const bool respecthide, const char hflag_test)
{
const char iter_types[3] = {BM_VERTS_OF_MESH,
BM_EDGES_OF_MESH,
@@ -895,7 +934,7 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla
}
if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, TRUE);
+ BM_elem_select_set(bm, ele, true);
}
BM_elem_flag_enable(ele, hflag_nosel);
}
@@ -904,14 +943,14 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla
}
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag,
- int respecthide)
+ const bool respecthide)
{
/* call with 0 hflag_test */
BM_mesh_elem_hflag_disable_test(bm, htype, hflag, respecthide, 0);
}
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag,
- int respecthide)
+ const bool respecthide)
{
/* call with 0 hflag_test */
BM_mesh_elem_hflag_enable_test(bm, htype, hflag, respecthide, 0);
@@ -923,7 +962,7 @@ static void vert_flush_hide_set(BMVert *v)
{
BMIter iter;
BMEdge *e;
- int hide = TRUE;
+ bool hide = true;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
hide = hide && BM_elem_flag_test(e, BM_ELEM_HIDDEN);
@@ -936,7 +975,7 @@ static void edge_flush_hide(BMEdge *e)
{
BMIter iter;
BMFace *f;
- int hide = TRUE;
+ bool hide = true;
BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
hide = hide && BM_elem_flag_test(f, BM_ELEM_HIDDEN);
@@ -945,13 +984,15 @@ static void edge_flush_hide(BMEdge *e)
BM_elem_flag_set(e, BM_ELEM_HIDDEN, hide);
}
-void BM_vert_hide_set(BMVert *v, int hide)
+void BM_vert_hide_set(BMVert *v, const bool hide)
{
/* vert hiding: vert + surrounding edges and faces */
BMIter iter, fiter;
BMEdge *e;
BMFace *f;
+ BLI_assert(v->head.htype == BM_VERT);
+
BM_elem_flag_set(v, BM_ELEM_HIDDEN, hide);
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
@@ -963,12 +1004,14 @@ void BM_vert_hide_set(BMVert *v, int hide)
}
}
-void BM_edge_hide_set(BMEdge *e, int hide)
+void BM_edge_hide_set(BMEdge *e, const bool hide)
{
BMIter iter;
BMFace *f;
/* BMVert *v; */
+ BLI_assert(e->head.htype == BM_EDGE);
+
/* edge hiding: faces around the edge */
BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
BM_elem_flag_set(f, BM_ELEM_HIDDEN, hide);
@@ -981,11 +1024,13 @@ void BM_edge_hide_set(BMEdge *e, int hide)
vert_flush_hide_set(e->v2);
}
-void BM_face_hide_set(BMFace *f, int hide)
+void BM_face_hide_set(BMFace *f, const bool hide)
{
BMIter iter;
BMLoop *l;
+ BLI_assert(f->head.htype == BM_FACE);
+
BM_elem_flag_set(f, BM_ELEM_HIDDEN, hide);
BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
@@ -997,21 +1042,21 @@ void BM_face_hide_set(BMFace *f, int hide)
}
}
-void _bm_elem_hide_set(BMesh *bm, BMHeader *head, int hide)
+void _bm_elem_hide_set(BMesh *bm, BMHeader *head, const bool hide)
{
/* Follow convention of always deselecting before
* hiding an element */
switch (head->htype) {
case BM_VERT:
- if (hide) BM_vert_select_set(bm, (BMVert *)head, FALSE);
+ if (hide) BM_vert_select_set(bm, (BMVert *)head, false);
BM_vert_hide_set((BMVert *)head, hide);
break;
case BM_EDGE:
- if (hide) BM_edge_select_set(bm, (BMEdge *)head, FALSE);
+ if (hide) BM_edge_select_set(bm, (BMEdge *)head, false);
BM_edge_hide_set((BMEdge *)head, hide);
break;
case BM_FACE:
- if (hide) BM_face_select_set(bm, (BMFace *)head, FALSE);
+ if (hide) BM_face_select_set(bm, (BMFace *)head, false);
BM_face_hide_set((BMFace *)head, hide);
break;
default:
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index 8d4397794d5..a3d2d4a6985 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -35,29 +35,29 @@ typedef struct BMEditSelection {
/* geometry hiding code */
#define BM_elem_hide_set(bm, ele, hide) _bm_elem_hide_set(bm, &(ele)->head, hide)
-void _bm_elem_hide_set(BMesh *bm, BMHeader *ele, int hide);
-void BM_vert_hide_set(BMVert *v, int hide);
-void BM_edge_hide_set(BMEdge *e, int hide);
-void BM_face_hide_set(BMFace *f, int hide);
+void _bm_elem_hide_set(BMesh *bm, BMHeader *ele, const bool hide);
+void BM_vert_hide_set(BMVert *v, const bool hide);
+void BM_edge_hide_set(BMEdge *e, const bool hide);
+void BM_face_hide_set(BMFace *f, const bool hide);
/* Selection code */
-void BM_elem_select_set(BMesh *bm, BMElem *ele, int select);
+void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select);
void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hflag,
- int respecthide, const char hflag_test);
+ const bool respecthide, const char hflag_test);
void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hflag,
- int respecthide, const char hflag_test);
+ const bool respecthide, const char hflag_test);
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag,
- int respecthide);
+ const bool respecthide);
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag,
- int respecthide);
+ const bool respecthide);
/* individual element select functions, BM_elem_select_set is a shortcut for these
* that automatically detects which one to use*/
-void BM_vert_select_set(BMesh *bm, BMVert *v, int select);
-void BM_edge_select_set(BMesh *bm, BMEdge *e, int select);
-void BM_face_select_set(BMesh *bm, BMFace *f, int select);
+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);
void BM_mesh_select_mode_set(BMesh *bm, int selectmode);
void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode);
@@ -66,12 +66,12 @@ void BM_mesh_select_mode_flush(BMesh *bm);
void BM_mesh_deselect_flush(BMesh *bm);
void BM_mesh_select_flush(BMesh *bm);
-int BM_mesh_elem_hflag_count_enabled(BMesh *bm, const char htype, const char hflag, int respecthide);
-int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hflag, int respecthide);
+int BM_mesh_elem_hflag_count_enabled(BMesh *bm, const char htype, const char hflag, const bool respecthide);
+int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hflag, const bool respecthide);
/* edit selection stuff */
void BM_active_face_set(BMesh *bm, BMFace *f);
-BMFace *BM_active_face_get(BMesh *bm, int sloppy, int selected);
+BMFace *BM_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected);
void BM_editselection_center(BMEditSelection *ese, float r_center[3]);
void BM_editselection_normal(BMEditSelection *ese, float r_normal[3]);
@@ -82,13 +82,13 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]);
#define BM_select_history_store_notest(bm, ele) _bm_select_history_store_notest(bm, &(ele)->head)
#define BM_select_history_store(bm, ele) _bm_select_history_store(bm, &(ele)->head)
-int _bm_select_history_check(BMesh *bm, const BMHeader *ele);
-int _bm_select_history_remove(BMesh *bm, BMHeader *ele);
+bool _bm_select_history_check(BMesh *bm, const BMHeader *ele);
+bool _bm_select_history_remove(BMesh *bm, BMHeader *ele);
void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele);
void _bm_select_history_store(BMesh *bm, BMHeader *ele);
void BM_select_history_validate(BMesh *bm);
void BM_select_history_clear(BMesh *em);
-int BM_select_history_active_get(BMesh *bm, struct BMEditSelection *ese);
+bool BM_select_history_active_get(BMesh *bm, struct BMEditSelection *ese);
#endif /* __BMESH_MARKING_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 590edc45d07..3c4fa490477 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -63,40 +63,62 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize)
void BM_mesh_elem_toolflags_ensure(BMesh *bm)
{
- if (bm->toolflagpool == NULL) {
- const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface);
- BLI_mempool *toolflagpool;
-
- BMIter iter;
- BMElemF *ele;
- const char iter_types[3] = {BM_VERTS_OF_MESH,
- BM_EDGES_OF_MESH,
- BM_FACES_OF_MESH};
-
- int i;
-
- BLI_assert(bm->totflags == 0);
-
- /* allocate one flag pool that we don't get rid of. */
- toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0);
-
+ if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) {
+ return;
+ }
- for (i = 0; i < 3; i++) {
- BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+ bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totvert), 512, 0);
+ bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totedge), 512, 0);
+ bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totface), 512, 0);
+
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ BLI_mempool *toolflagpool = bm->vtoolflagpool;
+ BMIter iter;
+ BMElemF *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ ele->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+ }
+#pragma omp section
+ {
+ BLI_mempool *toolflagpool = bm->etoolflagpool;
+ BMIter iter;
+ BMElemF *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ ele->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+ }
+#pragma omp section
+ {
+ BLI_mempool *toolflagpool = bm->ftoolflagpool;
+ BMIter iter;
+ BMElemF *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
ele->oflags = BLI_mempool_calloc(toolflagpool);
}
}
-
- bm->toolflagpool = toolflagpool;
- bm->totflags = 1;
}
+
+
+ bm->totflags = 1;
}
void BM_mesh_elem_toolflags_clear(BMesh *bm)
{
- if (bm->toolflagpool) {
- BLI_mempool_destroy(bm->toolflagpool);
- bm->toolflagpool = NULL;
+ if (bm->vtoolflagpool) {
+ BLI_mempool_destroy(bm->vtoolflagpool);
+ bm->vtoolflagpool = NULL;
+ }
+ if (bm->etoolflagpool) {
+ BLI_mempool_destroy(bm->etoolflagpool);
+ bm->etoolflagpool = NULL;
+ }
+ if (bm->ftoolflagpool) {
+ BLI_mempool_destroy(bm->ftoolflagpool);
+ bm->ftoolflagpool = NULL;
}
}
@@ -223,7 +245,7 @@ void BM_mesh_free(BMesh *bm)
BM_mesh_data_free(bm);
if (bm->py_handle) {
- /* keep this out of 'BM_mesh_data_free' because we wan't python
+ /* keep this out of 'BM_mesh_data_free' because we want python
* to be able to clear the mesh and maintain access. */
extern void bpy_bm_generic_invalidate(void *self);
@@ -239,7 +261,7 @@ void BM_mesh_free(BMesh *bm)
*
* Updates the normals of a mesh.
*/
-void BM_mesh_normals_update(BMesh *bm, const short skip_hidden)
+void BM_mesh_normals_update(BMesh *bm, const bool skip_hidden)
{
BMVert *v;
BMFace *f;
@@ -340,8 +362,8 @@ static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from
{
/* switch multires data out of tangent space */
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
- BMEditMesh *em = BMEdit_Create(bm, FALSE);
- DerivedMesh *dm = CDDM_from_editbmesh(em, TRUE, FALSE);
+ BMEditMesh *em = BMEdit_Create(bm, false);
+ DerivedMesh *dm = CDDM_from_editbmesh(em, true, false);
MDisps *mdisps;
BMFace *f;
BMIter iter;
@@ -433,63 +455,77 @@ void bmesh_edit_end(BMesh *bm, int UNUSED(flag))
#endif
/* compute normals, clear temp flags and flush selections */
- BM_mesh_normals_update(bm, TRUE);
+ BM_mesh_normals_update(bm, true);
BM_mesh_select_mode_flush(bm);
}
void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag)
{
- BMIter iter;
- BMElem *ele;
-
#ifdef DEBUG
BM_ELEM_INDEX_VALIDATE(bm, "Should Never Fail!", __func__);
#endif
- if (hflag & BM_VERT) {
- if (bm->elem_index_dirty & BM_VERT) {
- int index = 0;
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_index_set(ele, index); /* set_ok */
- index++;
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ if (hflag & BM_VERT) {
+ if (bm->elem_index_dirty & BM_VERT) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, index) {
+ BM_elem_index_set(ele, index); /* set_ok */
+ }
+ BLI_assert(index == bm->totvert);
+ }
+ else {
+ // printf("%s: skipping vert index calc!\n", __func__);
+ }
}
- bm->elem_index_dirty &= ~BM_VERT;
- BLI_assert(index == bm->totvert);
- }
- else {
- // printf("%s: skipping vert index calc!\n", __func__);
}
- }
- if (hflag & BM_EDGE) {
- if (bm->elem_index_dirty & BM_EDGE) {
- int index = 0;
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_index_set(ele, index); /* set_ok */
- index++;
+#pragma omp section
+ {
+ if (hflag & BM_EDGE) {
+ if (bm->elem_index_dirty & BM_EDGE) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, index) {
+ BM_elem_index_set(ele, index); /* set_ok */
+ }
+ BLI_assert(index == bm->totedge);
+ }
+ else {
+ // printf("%s: skipping edge index calc!\n", __func__);
+ }
}
- bm->elem_index_dirty &= ~BM_EDGE;
- BLI_assert(index == bm->totedge);
- }
- else {
- // printf("%s: skipping edge index calc!\n", __func__);
}
- }
- if (hflag & BM_FACE) {
- if (bm->elem_index_dirty & BM_FACE) {
- int index = 0;
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- BM_elem_index_set(ele, index); /* set_ok */
- index++;
+#pragma omp section
+ {
+ if (hflag & BM_FACE) {
+ if (bm->elem_index_dirty & BM_FACE) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, index) {
+ BM_elem_index_set(ele, index); /* set_ok */
+ }
+ BLI_assert(index == bm->totface);
+ }
+ else {
+ // printf("%s: skipping face index calc!\n", __func__);
+ }
}
- bm->elem_index_dirty &= ~BM_FACE;
- BLI_assert(index == bm->totface);
- }
- else {
- // printf("%s: skipping face index calc!\n", __func__);
}
}
+
+ bm->elem_index_dirty &= ~hflag;
}
@@ -517,12 +553,12 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu
BMIter iter;
BMElem *ele;
int i;
- int is_any_error = 0;
+ bool is_any_error = 0;
for (i = 0; i < 3; i++) {
- const int is_dirty = (flag_types[i] & bm->elem_index_dirty);
+ const bool is_dirty = (flag_types[i] & bm->elem_index_dirty);
int index = 0;
- int is_error = FALSE;
+ bool is_error = false;
int err_val = 0;
int err_idx = 0;
@@ -531,7 +567,7 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu
if (BM_elem_index_get(ele) != index) {
err_val = BM_elem_index_get(ele);
err_idx = index;
- is_error = TRUE;
+ is_error = true;
}
}
@@ -539,13 +575,13 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu
index++;
}
- if ((is_error == TRUE) && (is_dirty == FALSE)) {
- is_any_error = TRUE;
+ if ((is_error == true) && (is_dirty == false)) {
+ is_any_error = true;
fprintf(stderr,
"Invalid Index: at %s, %s, %s[%d] invalid index %d, '%s', '%s'\n",
location, func, type_names[i], err_idx, err_val, msg_a, msg_b);
}
- else if ((is_error == FALSE) && (is_dirty == TRUE)) {
+ else if ((is_error == false) && (is_dirty == true)) {
#if 0 /* mostly annoying */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 8baba568fb8..35ce1859c2b 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -37,7 +37,7 @@ void BM_mesh_free(BMesh *bm);
void BM_mesh_data_free(BMesh *bm);
void BM_mesh_clear(BMesh *bm);
-void BM_mesh_normals_update(BMesh *bm, const short skip_hidden);
+void BM_mesh_normals_update(BMesh *bm, const bool skip_hidden);
void bmesh_edit_begin(BMesh *bm, int type_flag);
void bmesh_edit_end(BMesh *bm, int type_flag);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 388d148377a..6697430a88d 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -98,8 +98,76 @@
#include "bmesh.h"
#include "intern/bmesh_private.h" /* for element checking */
-/* Mesh -> BMesh */
-void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
+void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
+{
+ const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
+ BM_mesh_cd_flag_apply(bm, cd_flag_all);
+ if (mesh) {
+ mesh->cd_flag = cd_flag_all;
+ }
+}
+
+void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
+{
+ /* CustomData_bmesh_init_pool() must run first */
+ BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
+ BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL);
+
+ if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->edata, CD_CREASE);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_free(bm, &bm->edata, CD_CREASE);
+ }
+ }
+}
+
+char BM_mesh_cd_flag_from_bmesh(BMesh *bm)
+{
+ char cd_flag = 0;
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+ return cd_flag;
+}
+
+/**
+ * \brief Mesh -> BMesh
+ *
+ * \warning This function doesn't calculate face normals.
+ */
+void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr)
{
MVert *mvert;
BLI_array_declare(verts);
@@ -110,12 +178,15 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
BMVert *v, **vt = NULL, **verts = NULL;
BMEdge *e, **fedges = NULL, **et = NULL;
BMFace *f;
- BMLoop *l;
BLI_array_declare(fedges);
float (*keyco)[3] = NULL;
int *keyi;
int totuv, i, j;
+ int cd_vert_bweight_offset;
+ int cd_edge_bweight_offset;
+ int cd_edge_crease_offset;
+
/* free custom data */
/* this isnt needed in most cases but do just incase */
CustomData_free(&bm->vdata, bm->totvert);
@@ -152,15 +223,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name);
}
- if (!CustomData_has_layer(&bm->edata, CD_CREASE))
- CustomData_add_layer(&bm->edata, CD_CREASE, CD_ASSIGN, NULL, 0);
-
- if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT))
- CustomData_add_layer(&bm->edata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
-
- if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT))
- CustomData_add_layer(&bm->vdata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
-
if ((act_key_nr != 0) && (me->key != NULL)) {
actkey = BLI_findlink(&me->key->block, act_key_nr - 1);
}
@@ -205,6 +267,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
+ BM_mesh_cd_flag_apply(bm, me->cd_flag);
+
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
@@ -215,15 +283,15 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
/* this is necessary for selection counts to work properly */
if (mvert->flag & SELECT) {
- BM_vert_select_set(bm, v, TRUE);
+ BM_vert_select_set(bm, v, true);
}
normal_short_to_float_v3(v->no, mvert->no);
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
+ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
+ if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);
/* set shapekey data */
if (me->key) {
@@ -263,21 +331,23 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
/* this is necessary for selection counts to work properly */
if (medge->flag & SELECT) {
- BM_edge_select_set(bm, e, TRUE);
+ BM_edge_select_set(bm, e, true);
}
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data);
+ CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
+
+ if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f);
+ if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f);
- BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f);
- BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f);
}
bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
mpoly = me->mpoly;
for (i = 0; i < me->totpoly; i++, mpoly++) {
- BMIter iter;
+ BMLoop *l_iter;
+ BMLoop *l_first;
BLI_array_empty(fedges);
BLI_array_empty(verts);
@@ -329,42 +399,41 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
/* this is necessary for selection counts to work properly */
if (mpoly->flag & ME_FACE_SEL) {
- BM_face_select_set(bm, f, TRUE);
+ BM_face_select_set(bm, f, true);
}
f->mat_nr = mpoly->mat_nr;
if (i == me->act_face) bm->act_face = f;
- j = 0;
- BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) {
+ j = mpoly->loopstart;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
/* Save index of correspsonding MLoop */
- CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data);
- }
+ CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
+ } while ((l_iter = l_iter->next) != l_first);
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data);
+ CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
}
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
if (me->mselect && me->totselect != 0) {
- BMVert **vert_array = MEM_callocN(sizeof(BMVert *) * bm->totvert,
- "Selection Conversion Vertex Pointer Array");
- BMEdge **edge_array = MEM_callocN(sizeof(BMEdge *) * bm->totedge,
- "Selection Conversion Edge Pointer Array");
- BMFace **face_array = MEM_callocN(sizeof(BMFace *) * bm->totface,
- "Selection Conversion Face Pointer Array");
-
- BMIter iter;
- BMVert *vert;
- BMEdge *edge;
- BMFace *face;
+ BMVert **vert_array = MEM_mallocN(sizeof(BMVert *) * bm->totvert, "VSelConv");
+ BMEdge **edge_array = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, "ESelConv");
+ BMFace **face_array = MEM_mallocN(sizeof(BMFace *) * bm->totface, "FSelConv");
MSelect *msel;
- BM_ITER_MESH_INDEX (vert, &iter, bm, BM_VERTS_OF_MESH, i) { vert_array[i] = vert; }
- BM_ITER_MESH_INDEX (edge, &iter, bm, BM_EDGES_OF_MESH, i) { edge_array[i] = edge; }
- BM_ITER_MESH_INDEX (face, &iter, bm, BM_FACES_OF_MESH, i) { face_array[i] = face; }
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ { BM_iter_as_array(bm, BM_VERTS_OF_MESH, NULL, (void **)vert_array, bm->totvert); }
+#pragma omp section
+ { BM_iter_as_array(bm, BM_EDGES_OF_MESH, NULL, (void **)edge_array, bm->totedge); }
+#pragma omp section
+ { BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)face_array, bm->totface); }
+ }
for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) {
switch (msel->type) {
@@ -400,7 +469,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
}
-/* BMesh -> Mesh */
+/**
+ * \brief BMesh -> Mesh
+ */
static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
{
BMVert **vertMap = NULL;
@@ -483,7 +554,7 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
}
}
-void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
+void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
{
MLoop *mloop;
MPoly *mpoly;
@@ -496,6 +567,10 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
BMIter iter, liter;
int i, j, ototvert;
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
ototvert = me->totvert;
/* new vertex block */
@@ -550,15 +625,13 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
+ me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
/* this is called again, 'dotess' arg is used there */
mesh_update_customdata_pointers(me, 0);
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- float *bweight = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BWEIGHT);
-
- mvert->bweight = bweight ? (char)((*bweight) * 255) : 0;
-
copy_v3_v3(mvert->co, v->co);
normal_float_to_short_v3(mvert->no, v->no);
@@ -569,6 +642,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
/* copy over customdat */
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
+ if (cd_vert_bweight_offset != -1) mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset);
+
i++;
mvert++;
@@ -579,13 +654,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
med = medge;
i = 0;
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- float *crease = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
- float *bweight = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
-
med->v1 = BM_elem_index_get(e->v1);
med->v2 = BM_elem_index_get(e->v2);
- med->crease = crease ? (char)((*crease) * 255) : 0;
- med->bweight = bweight ? (char)((*bweight) * 255) : 0;
med->flag = BM_edge_flag_to_mflag(e);
@@ -596,6 +666,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
bmesh_quick_edgedraw_flag(med, e);
+ if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset);
+
i++;
med++;
BM_CHECK_ELEMENT(e);
@@ -689,11 +762,11 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
if (vertMap) MEM_freeN(vertMap);
}
- if (dotess) {
+ if (do_tessface) {
BKE_mesh_tessface_calc(me);
}
- mesh_update_customdata_pointers(me, dotess);
+ mesh_update_customdata_pointers(me, do_tessface);
{
BMEditSelection *selected;
@@ -757,12 +830,12 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
* bmesh and the mesh are out of sync */
(oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */
{
- int act_is_basis = FALSE;
+ 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;
+ act_is_basis = true;
break;
}
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index f9c51584081..7fe4b8fe58b 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -34,7 +34,11 @@
struct Mesh;
-void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me, int set_key, int act_key_nr);
-void BM_mesh_bm_to_me(BMesh *bm, struct Mesh *me, int dotess);
+void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag);
+void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag);
+char BM_mesh_cd_flag_from_bmesh(BMesh *bm);
+
+void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me, bool set_key, int act_key_nr);
+void BM_mesh_bm_to_me(BMesh *bm, struct Mesh *me, bool do_tessface);
#endif /* __BMESH_MESH_CONV_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_validate.c b/source/blender/bmesh/intern/bmesh_mesh_validate.c
index 8ab5f10361f..e6eee16e49c 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_validate.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_validate.c
@@ -49,9 +49,9 @@
/**
* Check of this BMesh is valid, this function can be slow since its intended to help with debugging.
*
- * \return TRUE when the mesh is valid.
+ * \return true when the mesh is valid.
*/
-int BM_mesh_validate(BMesh *bm)
+bool BM_mesh_validate(BMesh *bm)
{
int errtot;
@@ -106,11 +106,11 @@ int BM_mesh_validate(BMesh *bm)
if (l_iter->e != e) {
ERRMSG("edge %d: has invalid loop, loop is of face %d", i, BM_elem_index_get(l_iter->f));
}
- else if (BM_vert_in_edge(e, l_iter->v) == FALSE) {
+ else if (BM_vert_in_edge(e, l_iter->v) == false) {
ERRMSG("edge %d: has invalid loop with vert not in edge, loop is of face %d",
i, BM_elem_index_get(l_iter->f));
}
- else if (BM_vert_in_edge(e, l_iter->next->v) == FALSE) {
+ else if (BM_vert_in_edge(e, l_iter->next->v) == false) {
ERRMSG("edge %d: has invalid loop with next vert not in edge, loop is of face %d",
i, BM_elem_index_get(l_iter->f));
}
@@ -181,7 +181,7 @@ int BM_mesh_validate(BMesh *bm)
ERRMSG("Finished - errors %d", errtot);
- return TRUE;
+ return true;
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_validate.h b/source/blender/bmesh/intern/bmesh_mesh_validate.h
index 6839dc74d25..f89141387d8 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_validate.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_validate.h
@@ -30,6 +30,6 @@
* \ingroup bmesh
*/
-int BM_mesh_validate(BMesh *bm);
+bool BM_mesh_validate(BMesh *bm);
#endif /* __BMESH_MESH_VALIDATE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 89516061f91..d98598cac89 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -64,36 +64,36 @@
* \note dissolves vert, in more situations then BM_disk_dissolve
* (e.g. if the vert is part of a wire edge, etc).
*/
-int BM_vert_dissolve(BMesh *bm, BMVert *v)
+bool BM_vert_dissolve(BMesh *bm, BMVert *v)
{
const int len = BM_vert_edge_count(v);
if (len == 1) {
BM_vert_kill(bm, v); /* will kill edges too */
- return TRUE;
+ return true;
}
else if (!BM_vert_is_manifold(v)) {
if (!v->e) {
BM_vert_kill(bm, v);
- return TRUE;
+ return true;
}
else if (!v->e->l) {
if (len == 2) {
- return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL);
+ return (BM_vert_collapse_edge(bm, v->e, v, true) != NULL);
}
else {
/* used to kill the vertex here, but it may be connected to faces.
* so better do nothing */
- return FALSE;
+ return false;
}
}
else {
- return FALSE;
+ return false;
}
}
else if (len == 2 && BM_vert_face_count(v) == 1) {
/* boundary vertex on a face */
- return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL);
+ return (BM_vert_collapse_edge(bm, v->e, v, true) != NULL);
}
else {
return BM_disk_dissolve(bm, v);
@@ -103,14 +103,14 @@ int BM_vert_dissolve(BMesh *bm, BMVert *v)
/**
* dissolves all faces around a vert, and removes it.
*/
-int BM_disk_dissolve(BMesh *bm, BMVert *v)
+bool BM_disk_dissolve(BMesh *bm, BMVert *v)
{
BMFace *f, *f2;
BMEdge *e, *keepedge = NULL, *baseedge = NULL;
int len = 0;
if (!BM_vert_is_manifold(v)) {
- return FALSE;
+ return false;
}
if (v->e) {
@@ -135,62 +135,62 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
* increasing valence to four. this may be hackish. . */
BMLoop *loop = e->l;
if (loop->v == v) loop = loop->next;
- if (!BM_face_split(bm, loop->f, v, loop->v, NULL, NULL, FALSE))
- return FALSE;
+ if (!BM_face_split(bm, loop->f, v, loop->v, NULL, NULL, false))
+ return false;
if (!BM_disk_dissolve(bm, v)) {
- return FALSE;
+ return false;
}
#else
- if (UNLIKELY(!BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE))) {
- return FALSE;
+ if (UNLIKELY(!BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true))) {
+ return false;
}
- else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE))) {
- return FALSE;
+ else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, false, true))) {
+ return false;
}
#endif
- return TRUE;
+ return true;
}
else if (keepedge == NULL && len == 2) {
- /* collapse the verte */
- e = BM_vert_collapse_faces(bm, v->e, v, 1.0, TRUE, TRUE);
+ /* collapse the vertex */
+ e = BM_vert_collapse_faces(bm, v->e, v, 1.0, true, true);
if (!e) {
- return FALSE;
+ return false;
}
- /* handle two-valenc */
+ /* handle two-valence */
f = e->l->f;
f2 = e->l->radial_next->f;
- if (f != f2 && !BM_faces_join_pair(bm, f, f2, e, TRUE)) {
- return FALSE;
+ if (f != f2 && !BM_faces_join_pair(bm, f, f2, e, true)) {
+ return false;
}
- return TRUE;
+ return true;
}
if (keepedge) {
- int done = FALSE;
+ bool done = false;
while (!done) {
- done = TRUE;
+ done = true;
e = v->e;
do {
f = NULL;
len = bmesh_radial_length(e->l);
if (len == 2 && (e != baseedge) && (e != keepedge)) {
- f = BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE);
+ f = BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true);
/* return if couldn't join faces in manifold
* conditions */
/* !disabled for testing why bad things happen */
if (!f) {
- return FALSE;
+ return false;
}
}
if (f) {
- done = FALSE;
+ done = false;
break;
}
e = bmesh_disk_edge_next(e, v);
@@ -199,25 +199,25 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
/* collapse the vertex */
/* note, the baseedge can be a boundary of manifold, use this as join_faces arg */
- e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, !BM_edge_is_boundary(baseedge), TRUE);
+ e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, !BM_edge_is_boundary(baseedge), true);
if (!e) {
- return FALSE;
+ return false;
}
- /* get remaining two face */
+ /* get remaining two faces */
f = e->l->f;
f2 = e->l->radial_next->f;
if (f != f2) {
- /* join two remaining face */
- if (!BM_faces_join_pair(bm, f, f2, e, TRUE)) {
- return FALSE;
+ /* join two remaining faces */
+ if (!BM_faces_join_pair(bm, f, f2, e, true)) {
+ return false;
}
}
}
- return TRUE;
+ return true;
}
/**
@@ -235,7 +235,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
*
* \return pointer to the combined face
*/
-BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const short do_del)
+BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const bool do_del)
{
BMLoop *l1, *l2;
BMEdge *jed = NULL;
@@ -302,7 +302,7 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f)
if (v_iter == v2) {
BMLoop *nl;
- f_iter = BM_face_split(bm, f_iter, v1, v2, &nl, NULL, FALSE);
+ f_iter = BM_face_split(bm, f_iter, v1, v2, &nl, NULL, false);
if (r_f) {
*r_f = f_iter;
@@ -336,22 +336,22 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f)
* other side). NULL if the split fails.
*/
BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l,
- BMEdge *example, const short nodouble)
+ BMEdge *example, const bool no_double)
{
- const int has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS);
+ const bool has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS);
BMFace *nf, *of;
BLI_assert(v1 != v2);
- /* do we have a multires layer */
+ /* do we have a multires layer? */
if (has_mdisp) {
- of = BM_face_copy(bm, f, FALSE, FALSE);
+ of = BM_face_copy(bm, f, false, false);
}
#ifdef USE_BMESH_HOLES
- nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, nodouble);
+ nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double);
#else
- nf = bmesh_sfme(bm, f, v1, v2, r_l, example, nodouble);
+ nf = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double);
#endif
if (nf) {
@@ -414,15 +414,15 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
BLI_assert(v1 != v2);
- of = BM_face_copy(bm, f, TRUE, TRUE);
+ of = BM_face_copy(bm, f, true, true);
if (!r_l)
r_l = &l_dummy;
#ifdef USE_BMESH_HOLES
- nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, FALSE);
+ nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false);
#else
- nf = bmesh_sfme(bm, f, v1, v2, r_l, example, FALSE);
+ nf = bmesh_sfme(bm, f, v1, v2, r_l, example, false);
#endif
/* bmesh_sfme returns in r_l a Loop for nf going from v1 to v2.
* The radial_next is for f and goes from v2 to v1 */
@@ -445,7 +445,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
do {
if (l_iter->v == newv) {
/* this interpolates both loop and vertex data */
- BM_loop_interp_from_face(bm, l_iter, of, TRUE, TRUE);
+ BM_loop_interp_from_face(bm, l_iter, of, true, true);
}
} while ((l_iter = l_iter->radial_next) != e_iter->l);
}
@@ -482,7 +482,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
* \returns The New Edge
*/
BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
- const short join_faces, const short kill_degenerate_faces)
+ const bool join_faces, const bool kill_degenerate_faces)
{
BMEdge *ne = NULL;
BMVert *tv = bmesh_edge_other_vert_get(ke, kv);
@@ -534,10 +534,10 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
}
if (BLI_array_count(faces) >= 2) {
- BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), TRUE);
+ BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true);
if (f2) {
BMLoop *nl = NULL;
- if (BM_face_split(bm, f2, tv, tv2, &nl, NULL, FALSE)) {
+ if (BM_face_split(bm, f2, tv, tv2, &nl, NULL, false)) {
ne = nl->e;
}
}
@@ -549,7 +549,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
/* single face or no faces */
/* same as BM_vert_collapse_edge() however we already
* have vars to perform this operation so don't call. */
- ne = bmesh_jekv(bm, ke, kv, TRUE);
+ ne = bmesh_jekv(bm, ke, kv, true);
/* ne = BM_edge_exists(tv, tv2); */ /* same as return above */
if (ne && kill_degenerate_faces) {
@@ -589,7 +589,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
* \return The New Edge
*/
BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
- const short kill_degenerate_faces)
+ const bool kill_degenerate_faces)
{
/* nice example implementation but we want loops to have their customdata
* accounted for */
@@ -618,7 +618,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
#else
/* with these args faces are never joined, same as above
* but account for loop customdata */
- return BM_vert_collapse_faces(bm, ke, kv, 1.0f, FALSE, kill_degenerate_faces);
+ return BM_vert_collapse_faces(bm, ke, kv, 1.0f, false, kill_degenerate_faces);
#endif
}
@@ -641,15 +641,14 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
BMFace **oldfaces = NULL;
BMEdge *e_dummy;
BLI_array_staticdeclare(oldfaces, 32);
- SmallHash hash;
- const int do_mdisp = (e->l && CustomData_has_layer(&bm->ldata, CD_MDISPS));
+ const bool do_mdisp = (e->l && CustomData_has_layer(&bm->ldata, CD_MDISPS));
/* we need this for handling multi-res */
if (!r_e) {
r_e = &e_dummy;
}
- /* do we have a multi-res layer */
+ /* do we have a multi-res layer? */
if (do_mdisp) {
BMLoop *l;
int i;
@@ -660,12 +659,11 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
l = l->radial_next;
} while (l != e->l);
- /* create a hash so we can differentiate oldfaces from new face */
- BLI_smallhash_init(&hash);
-
+ /* flag existing faces so we can differentiate oldfaces from new faces */
for (i = 0; i < BLI_array_count(oldfaces); i++) {
- oldfaces[i] = BM_face_copy(bm, oldfaces[i], TRUE, TRUE);
- BLI_smallhash_insert(&hash, (intptr_t)oldfaces[i], NULL);
+ BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP);
+ oldfaces[i] = BM_face_copy(bm, oldfaces[i], true, true);
+ BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP);
}
}
@@ -689,7 +687,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
if (do_mdisp) {
int i, j;
- /* interpolate new/changed loop data from copied old face */
+ /* interpolate new/changed loop data from copied old faces */
for (j = 0; j < 2; j++) {
for (i = 0; i < BLI_array_count(oldfaces); i++) {
BMEdge *e1 = j ? *r_e : e;
@@ -703,7 +701,8 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
}
do {
- if (!BLI_smallhash_haskey(&hash, (intptr_t)l->f)) {
+ /* check this is an old face */
+ if (BM_ELEM_API_FLAG_TEST(l->f, _FLAG_OVERLAP)) {
BMLoop *l2_first;
l2 = l2_first = BM_FACE_FIRST_LOOP(l->f);
@@ -716,7 +715,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
}
}
- /* destroy the old face */
+ /* destroy the old faces */
for (i = 0; i < BLI_array_count(oldfaces); i++) {
BM_face_verts_kill(bm, oldfaces[i]);
}
@@ -741,7 +740,6 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
#endif
BLI_array_free(oldfaces);
- BLI_smallhash_release(&hash);
}
return nv;
@@ -763,16 +761,18 @@ BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts)
return nv;
}
+#if 0
/**
* Checks if a face is valid in the data structure
*/
-int BM_face_validate(BMFace *face, FILE *err)
+bool BM_face_validate(BMFace *face, FILE *err)
{
BMIter iter;
BLI_array_declare(verts);
BMVert **verts = NULL;
BMLoop *l;
- int ret = 1, i, j;
+ int i, j;
+ bool ret = true;
if (face->len == 2) {
fprintf(err, "warning: found two-edged face. face ptr: %p\n", face);
@@ -786,7 +786,7 @@ int BM_face_validate(BMFace *face, FILE *err)
fprintf(err, "Found bmesh edge with identical verts!\n");
fprintf(err, " edge ptr: %p, vert: %p\n", l->e, l->e->v1);
fflush(err);
- ret = 0;
+ ret = false;
}
}
@@ -800,7 +800,7 @@ int BM_face_validate(BMFace *face, FILE *err)
fprintf(err, "Found duplicate verts in bmesh face!\n");
fprintf(err, " face ptr: %p, vert: %p\n", face, verts[i]);
fflush(err);
- ret = 0;
+ ret = false;
}
}
}
@@ -808,7 +808,7 @@ int BM_face_validate(BMFace *face, FILE *err)
BLI_array_free(verts);
return ret;
}
-
+#endif
/**
* Calculate the 2 loops which _would_ make up the newly rotated Edge
@@ -824,14 +824,14 @@ int BM_face_validate(BMFace *face, FILE *err)
*
* \note #BM_edge_rotate_check must have already run.
*/
-void BM_edge_calc_rotate(BMEdge *e, int ccw,
+void BM_edge_calc_rotate(BMEdge *e, const bool ccw,
BMLoop **r_l1, BMLoop **r_l2)
{
BMVert *v1, *v2;
BMFace *fa, *fb;
/* this should have already run */
- BLI_assert(BM_edge_rotate_check(e) == TRUE);
+ BLI_assert(BM_edge_rotate_check(e) == true);
/* we know this will work */
BM_edge_face_pair(e, &fa, &fb);
@@ -857,7 +857,7 @@ void BM_edge_calc_rotate(BMEdge *e, int ccw,
* Quick check to see if we could rotate the edge,
* use this to avoid calling exceptions on common cases.
*/
-int BM_edge_rotate_check(BMEdge *e)
+bool BM_edge_rotate_check(BMEdge *e)
{
BMFace *fa, *fb;
if (BM_edge_face_pair(e, &fa, &fb)) {
@@ -870,7 +870,7 @@ int BM_edge_rotate_check(BMEdge *e)
* (ie - the next edge doesn't share the same faces).
* since we can't rotate usefully in this case. */
if (la->v == lb->v) {
- return FALSE;
+ return false;
}
/* mirror of the check above but in the opposite direction */
@@ -878,13 +878,13 @@ int BM_edge_rotate_check(BMEdge *e)
lb = BM_face_other_vert_loop(fb, e->v1, e->v2);
if (la->v == lb->v) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
@@ -899,7 +899,7 @@ int BM_edge_rotate_check(BMEdge *e)
* \param l1,l2 are the loops of the proposed verts to rotate too and should
* be the result of calling #BM_edge_calc_rotate
*/
-int BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2)
+bool BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2)
{
/* note: for these vars 'old' just means initial edge state. */
@@ -926,7 +926,7 @@ int BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2)
BMVert *v1_alt, *v2_alt;
/* this should have already run */
- BLI_assert(BM_edge_rotate_check(e) == TRUE);
+ BLI_assert(BM_edge_rotate_check(e) == true);
BM_edge_ordered_verts(e, &v1_old, &v2_old);
@@ -967,12 +967,12 @@ int BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2)
cross_v3_v3v3(cross_old, ed_dir_old, ed_dir_v1_old);
cross_v3_v3v3(cross_new, ed_dir_new, ed_dir_v1_new);
if (dot_v3v3(cross_old, cross_new) < 0.0f) { /* does this flip? */
- return FALSE;
+ return false;
}
cross_v3_v3v3(cross_old, ed_dir_old, ed_dir_v2_old);
cross_v3_v3v3(cross_new, ed_dir_new, ed_dir_v2_new);
if (dot_v3v3(cross_old, cross_new) < 0.0f) { /* does this flip? */
- return FALSE;
+ return false;
}
negate_v3_v3(ed_dir_new_flip, ed_dir_new);
@@ -981,14 +981,14 @@ int BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2)
if ((dot_v3v3(ed_dir_new, ed_dir_v1_new) > 0.999f) ||
(dot_v3v3(ed_dir_new_flip, ed_dir_v2_new) > 0.999f))
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
-int BM_edge_rotate_check_beauty(BMEdge *e,
- BMLoop *l1, BMLoop *l2)
+bool BM_edge_rotate_check_beauty(BMEdge *e,
+ BMLoop *l1, BMLoop *l2)
{
/* Stupid check for now:
* Could compare angles of surrounding edges
@@ -1011,7 +1011,7 @@ int BM_edge_rotate_check_beauty(BMEdge *e,
*
* \see header definition for \a check_flag enum.
*/
-BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_flag)
+BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_flag)
{
BMVert *v1, *v2;
BMLoop *l1, *l2;
@@ -1068,7 +1068,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_
f_hflag_prev_2 = l2->f->head.hflag;
/* don't delete the edge, manually remove the egde after so we can copy its attributes */
- f = BM_faces_join_pair(bm, l1->f, l2->f, NULL, TRUE);
+ f = BM_faces_join_pair(bm, l1->f, l2->f, NULL, true);
if (f == NULL) {
return NULL;
@@ -1077,7 +1077,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_
/* note, this assumes joining the faces _didnt_ also remove the verts.
* the #BM_edge_rotate_check will ensure this, but its possibly corrupt state or future edits
* break this */
- if (!BM_face_split(bm, f, v1, v2, NULL, NULL, TRUE)) {
+ if (!BM_face_split(bm, f, v1, v2, NULL, NULL, true)) {
return NULL;
}
else {
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index 790f0cb6267..358268cb589 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -29,18 +29,18 @@
#include <stdio.h>
-int BM_vert_dissolve(BMesh *bm, BMVert *v);
+bool BM_vert_dissolve(BMesh *bm, BMVert *v);
-int BM_disk_dissolve(BMesh *bm, BMVert *v);
+bool BM_disk_dissolve(BMesh *bm, BMVert *v);
-BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const short do_del);
+BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const bool do_del);
BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f);
BMFace *BM_face_split(BMesh *bm, BMFace *f,
BMVert *v1, BMVert *v2,
BMLoop **r_l,
- BMEdge *example, const short nodouble);
+ BMEdge *example, const bool no_double);
BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
BMVert *v1, BMVert *v2,
@@ -48,25 +48,25 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
BMLoop **r_l, BMEdge *example);
BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
- const short join_faces, const short kill_degenerate_faces);
+ const bool join_faces, const bool kill_degenerate_faces);
BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
- const short kill_degenerate_faces);
+ const bool kill_degenerate_faces);
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent);
BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts);
-int BM_face_validate(BMFace *face, FILE *err);
+bool BM_face_validate(BMFace *face, FILE *err);
-void BM_edge_calc_rotate(BMEdge *e, int ccw,
+void BM_edge_calc_rotate(BMEdge *e, const bool ccw,
BMLoop **r_l1, BMLoop **r_l2);
-int BM_edge_rotate_check(BMEdge *e);
-int BM_edge_rotate_check_degenerate(BMEdge *e,
+bool BM_edge_rotate_check(BMEdge *e);
+bool BM_edge_rotate_check_degenerate(BMEdge *e,
BMLoop *l1, BMLoop *l2);
-int BM_edge_rotate_check_beauty(BMEdge *e,
+bool BM_edge_rotate_check_beauty(BMEdge *e,
BMLoop *l1, BMLoop *l2);
-BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_flag);
+BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_flag);
/* flags for BM_edge_rotate */
enum {
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 58c6e051e48..7e3ee9d249e 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -128,7 +128,7 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = {
"smooth_laplacian_vert",
/* slots_in */
{{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"lambda", BMO_OP_SLOT_FLT}, /* lambda param */
+ {"lambda_factor", BMO_OP_SLOT_FLT}, /* lambda param */
{"lambda_border", BMO_OP_SLOT_FLT}, /* lambda param in border */
{"use_x", BMO_OP_SLOT_BOOL}, /* Smooth object along X axis */
{"use_y", BMO_OP_SLOT_BOOL}, /* Smooth object along Y axis */
@@ -339,7 +339,7 @@ static BMOpDefine bmo_automerge_def = {
static BMOpDefine bmo_collapse_def = {
"collapse",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -374,7 +374,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = {
static BMOpDefine bmo_average_vert_facedata_def = {
"average_vert_facedata",
/* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -390,7 +390,7 @@ static BMOpDefine bmo_average_vert_facedata_def = {
static BMOpDefine bmo_pointmerge_def = {
"pointmerge",
/* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
{"merge_co", BMO_OP_SLOT_VEC},
{{'\0'}},
},
@@ -407,7 +407,7 @@ static BMOpDefine bmo_pointmerge_def = {
static BMOpDefine bmo_collapse_uvs_def = {
"collapse_uvs",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -513,7 +513,7 @@ static BMOpDefine bmo_contextual_create_def = {
static BMOpDefine bmo_bridge_loops_def = {
"bridge_loops",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{"use_merge", BMO_OP_SLOT_BOOL},
{"merge_factor", BMO_OP_SLOT_FLT},
{{'\0'}},
@@ -534,7 +534,7 @@ static BMOpDefine bmo_bridge_loops_def = {
static BMOpDefine bmo_edgenet_fill_def = {
"edgenet_fill",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
/* restricts edges to groups. maps edges to integer */
{"restrict", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}},
{"use_restrict", BMO_OP_SLOT_BOOL},
@@ -547,7 +547,7 @@ static BMOpDefine bmo_edgenet_fill_def = {
/* slots_out */
/* maps new faces to the group numbers they came from */
{{"face_groupmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new face */
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
{{'\0'}},
},
bmo_edgenet_fill_exec,
@@ -962,7 +962,7 @@ static BMOpDefine bmo_subdivide_edges_def = {
{/* these next three can have multiple types of elements in them */
{"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometr */
+ {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
{{'\0'}},
},
bmo_subdivide_edges_exec,
@@ -1403,24 +1403,13 @@ static BMOpDefine bmo_bevel_def = {
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
{"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
{"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */
+ {"vertex_only", BMO_OP_SLOT_BOOL}, /* only bevel vertices, not edges */
{{'\0'}},
},
/* slots_out */
{{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
{{'\0'}},
},
-/* old bevel*/
-// {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
-// {"face_spans", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */
-// {"face_holes", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */
-// {"use_lengths", BMO_OP_SLOT_BOOL}, /* grab edge lengths from a PROP_FLT customdata layer */
-// {"use_even", BMO_OP_SLOT_BOOL}, /* corner vert placement: use shell/angle calculations */
-// {"use_dist", BMO_OP_SLOT_BOOL}, /* corner vert placement: evaluate percent as a distance,
-// * modifier uses this. We could do this as another float setting */
-// {"lengthlayer", BMO_OP_SLOT_INT}, /* which PROP_FLT layer to us */
-// {"percent", BMO_OP_SLOT_FLT}, /* percentage to expand beveled edge */
-// {{'\0'}},
-// },
bmo_bevel_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
@@ -1435,7 +1424,7 @@ static BMOpDefine bmo_beautify_fill_def = {
"beautify_fill",
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"constrain_edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can't be flipped */
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
{{'\0'}},
},
/* slots_out */
@@ -1454,7 +1443,8 @@ static BMOpDefine bmo_beautify_fill_def = {
static BMOpDefine bmo_triangle_fill_def = {
"triangle_fill",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {{"use_beauty", BMO_OP_SLOT_BOOL},
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{{'\0'}},
},
/* slots_out */
@@ -1535,27 +1525,6 @@ static BMOpDefine bmo_wireframe_def = {
0
};
-/*
- * Vertex Slide.
- *
- * Translates verts along an edge
- */
-static BMOpDefine bmo_slide_vert_def = {
- "slide_vert",
- /* slots_in */
- {{"vert", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},
- {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"factor", BMO_OP_SLOT_FLT},
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {{'\0'}},
- },
- bmo_slide_vert_exec,
- BMO_OP_FLAG_UNTAN_MULTIRES
-};
-
#ifdef WITH_BULLET
/*
* Convex Hull
@@ -1675,7 +1644,6 @@ const BMOpDefine *bmo_opdefines[] = {
&bmo_similar_edges_def,
&bmo_similar_faces_def,
&bmo_similar_verts_def,
- &bmo_slide_vert_def,
&bmo_smooth_vert_def,
&bmo_smooth_laplacian_vert_def,
&bmo_solidify_def,
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 7df9c94a2f1..fd6571d136e 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -244,19 +244,19 @@ void BMO_push(BMesh *bm, BMOperator *op);
void BMO_pop(BMesh *bm);
/*executes an operator*/
-int BMO_op_callf(BMesh *bm, const int flag, const char *fmt, ...);
+bool BMO_op_callf(BMesh *bm, const int flag, const char *fmt, ...);
/* initializes, but doesn't execute an operator. this is so you can
* gain access to the outputs of the operator. note that you have
* to execute/finish (BMO_op_exec and BMO_op_finish) yourself. */
-int BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...);
+bool BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...);
/* va_list version, used to implement the above two functions,
* plus EDBM_op_callf in editmesh_utils.c. */
-int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, va_list vlist);
+bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, va_list vlist);
/* test whether a named slot exists */
-int BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
+bool BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
/* get a pointer to a slot. this may be removed layer on from the public API. */
BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
@@ -301,8 +301,8 @@ void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i);
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
-void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i);
-int BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const bool i);
+bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len);
@@ -360,11 +360,11 @@ void BMO_slot_buffer_flag_disable(BMesh *bm,
/* tool-flags all elements inside an element slot array with flag flag. */
void BMO_slot_buffer_hflag_enable(BMesh *bm,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const char do_flush);
+ const char htype, const char hflag, const bool do_flush);
/* clears tool-flag flag from all elements inside a slot array. */
void BMO_slot_buffer_hflag_disable(BMesh *bm,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const char do_flush);
+ const char htype, const char hflag, const bool do_flush);
/* puts every element of type 'type' (which is a bitmask) with header
* flag 'flag', into a slot. note: ignores hidden elements
@@ -435,7 +435,7 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_
* //whether it's a float, pointer, whatever.
* //
* // so to get a pointer, for example, use:
- * // *((void**)BMO_iter_map_value(&oiter));
+ * // *((void **)BMO_iter_map_value(&oiter));
* //or something like that.
* }
* \endcode
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index ad116011421..053d70349e8 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -80,7 +80,7 @@ BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot,
void *element, const int val)
{
BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
- BLI_assert(val == FALSE || val == TRUE);
+ BLI_assert(val == false || val == true);
BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
}
@@ -173,16 +173,16 @@ BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
return 0;
}
-BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
+BLI_INLINE bool BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
{
int *val;
BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
val = (int *) BMO_slot_map_data_get(slot, element);
- BLI_assert(val == NULL || *val == FALSE || *val == TRUE);
- if (val) return *val;
+ BLI_assert(val == NULL || *val == false || *val == true);
+ if (val) return (bool)*val;
- return 0;
+ return false;
}
BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 5e51f5a5ada..00f8dbe06bf 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -238,7 +238,7 @@ void BMO_op_finish(BMesh *bm, BMOperator *op)
*
* \return Success if the slot if found.
*/
-int BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
+bool BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
int slot_code = bmo_name_to_slotcode(slot_args, identifier);
return (slot_code >= 0);
@@ -390,7 +390,7 @@ void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_nam
slot->data.i = i;
}
-void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i)
+void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const bool i)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
@@ -495,7 +495,7 @@ int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name
return slot->data.i;
}
-int BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
+bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
@@ -549,7 +549,7 @@ void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_nam
*/
static int bmo_mesh_flag_count(BMesh *bm, const char htype, const short oflag,
- const short test_for_enabled)
+ const bool test_for_enabled)
{
const char iter_types[3] = {BM_VERTS_OF_MESH,
BM_EDGES_OF_MESH,
@@ -562,7 +562,7 @@ static int bmo_mesh_flag_count(BMesh *bm, const char htype, const short oflag,
BMElemF *ele_f;
int i;
- BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
+ BLI_assert((unsigned int)test_for_enabled <= 1);
for (i = 0; i < 3; i++) {
if (htype & flag_types[i]) {
@@ -579,12 +579,12 @@ static int bmo_mesh_flag_count(BMesh *bm, const char htype, const short oflag,
int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag)
{
- return bmo_mesh_flag_count(bm, htype, oflag, TRUE);
+ return bmo_mesh_flag_count(bm, htype, oflag, true);
}
int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag)
{
- return bmo_mesh_flag_count(bm, htype, oflag, FALSE);
+ return bmo_mesh_flag_count(bm, htype, oflag, false);
}
void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char htype, const short oflag)
@@ -595,12 +595,13 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty
const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
- BMIter iter;
BMElemF *ele;
int i;
+#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
for (i = 0; i < 3; i++) {
if (htype & flag_types[i]) {
+ BMIter iter;
BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
BMO_elem_flag_disable(bm, ele, oflag);
}
@@ -794,14 +795,12 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_
*/
static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag,
- const short test_for_enabled)
+ const bool test_for_enabled)
{
BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
int totelement = 0, i = 0;
const int respecthide = (op->flag & BMO_FLAG_RESPECT_HIDE) != 0;
- BLI_assert(ELEM(test_for_enabled, TRUE, FALSE));
-
if (test_for_enabled)
totelement = BM_mesh_elem_hflag_count_enabled(bm, htype, hflag, respecthide);
else
@@ -857,14 +856,14 @@ void BMO_slot_buffer_from_enabled_hflag(BMesh *bm, BMOperator *op,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag)
{
- bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, TRUE);
+ bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, true);
}
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)
{
- bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, FALSE);
+ bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, false);
}
void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele)
@@ -933,13 +932,13 @@ void _bmo_slot_buffer_append(BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const cha
static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag,
- const short test_for_enabled)
+ const bool test_for_enabled)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
int totelement, i = 0;
BLI_assert(op->slots_in == slot_args || op->slots_out == slot_args);
- BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
+ BLI_assert((unsigned int)test_for_enabled <= 1);
if (test_for_enabled)
totelement = BMO_mesh_enabled_flag_count(bm, htype, oflag);
@@ -996,14 +995,14 @@ void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
- bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, TRUE);
+ bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, true);
}
void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
- bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, FALSE);
+ bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, false);
}
/**
@@ -1014,13 +1013,13 @@ void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op,
*/
void BMO_slot_buffer_hflag_enable(BMesh *bm,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const char do_flush)
+ const char htype, const char hflag, const bool do_flush)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BMElem **data = (BMElem **)slot->data.buf;
int i;
- const char do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
- const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
+ const bool do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
+ const bool do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
@@ -1030,11 +1029,11 @@ void BMO_slot_buffer_hflag_enable(BMesh *bm,
continue;
if (do_flush_select) {
- BM_elem_select_set(bm, *data, TRUE);
+ BM_elem_select_set(bm, *data, true);
}
if (do_flush_hide) {
- BM_elem_hide_set(bm, *data, FALSE);
+ BM_elem_hide_set(bm, *data, false);
}
BM_elem_flag_enable(*data, hflag);
@@ -1049,13 +1048,13 @@ void BMO_slot_buffer_hflag_enable(BMesh *bm,
*/
void BMO_slot_buffer_hflag_disable(BMesh *bm,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const char do_flush)
+ const char htype, const char hflag, const bool do_flush)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BMElem **data = (BMElem **)slot->data.buf;
int i;
- const char do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
- const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
+ const bool do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
+ const bool do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
@@ -1065,11 +1064,11 @@ void BMO_slot_buffer_hflag_disable(BMesh *bm,
continue;
if (do_flush_select) {
- BM_elem_select_set(bm, *data, FALSE);
+ BM_elem_select_set(bm, *data, false);
}
if (do_flush_hide) {
- BM_elem_hide_set(bm, *data, FALSE);
+ BM_elem_hide_set(bm, *data, false);
}
BM_elem_flag_disable(*data, hflag);
@@ -1159,100 +1158,161 @@ void BMO_slot_buffer_flag_disable(BMesh *bm,
*/
static void bmo_flag_layer_alloc(BMesh *bm)
{
- BMElemF *ele;
/* set the index values since we are looping over all data anyway,
* may save time later on */
- int i;
- BMIter iter;
- BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */
- BLI_mempool *newpool;
- void *oldflags;
+ BLI_mempool *voldpool = bm->vtoolflagpool; /* old flag pool */
+ BLI_mempool *eoldpool = bm->etoolflagpool; /* old flag pool */
+ BLI_mempool *foldpool = bm->ftoolflagpool; /* old flag pool */
/* store memcpy size for reuse */
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
- BLI_assert(oldpool != NULL);
-
bm->totflags++;
- /* allocate new flag poo */
- bm->toolflagpool = newpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, 512, 512, 0);
-
- /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totvert), 512, 0);
+ bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totedge), 512, 0);
+ bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totface), 512, 0);
+
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->vtoolflagpool;
+
+ /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->etoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->ftoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
}
+ BLI_mempool_destroy(voldpool);
+ BLI_mempool_destroy(eoldpool);
+ BLI_mempool_destroy(foldpool);
+
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
- BLI_mempool_destroy(oldpool);
+
}
static void bmo_flag_layer_free(BMesh *bm)
{
- BMElemF *ele;
/* set the index values since we are looping over all data anyway,
* may save time later on */
- int i;
- BMIter iter;
- BLI_mempool *oldpool = bm->toolflagpool;
- BLI_mempool *newpool;
- void *oldflags;
-
+ BLI_mempool *voldpool = bm->vtoolflagpool;
+ BLI_mempool *eoldpool = bm->etoolflagpool;
+ BLI_mempool *foldpool = bm->ftoolflagpool;
+
/* store memcpy size for reuse */
const size_t new_totflags_size = ((bm->totflags - 1) * sizeof(BMFlagLayer));
/* de-increment the totflags first.. */
bm->totflags--;
- /* allocate new flag poo */
- bm->toolflagpool = newpool = BLI_mempool_create(new_totflags_size, 512, 512, 0);
-
- /* now go through and memcpy all the flag */
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+
+ bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, 0);
+ bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, 0);
+ bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, 0);
+
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->vtoolflagpool;
+
+ /* now go through and memcpy all the flag */
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->etoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->ftoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
}
- bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
+ BLI_mempool_destroy(voldpool);
+ BLI_mempool_destroy(eoldpool);
+ BLI_mempool_destroy(foldpool);
- BLI_mempool_destroy(oldpool);
+ bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
static void bmo_flag_layer_clear(BMesh *bm)
@@ -1261,22 +1321,35 @@ static void bmo_flag_layer_clear(BMesh *bm)
/* set the index values since we are looping over all data anyway,
* may save time later on */
int i;
+ const BMFlagLayer zero_flag = {0};
BMIter iter;
const int totflags_offset = bm->totflags - 1;
- /* now go through and memcpy all the flag */
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
- BM_elem_index_set(ele, i); /* set_inline */
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
- BM_elem_index_set(ele, i); /* set_inline */
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
- BM_elem_index_set(ele, i); /* set_inline */
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+ /* now go through and memcpy all the flag */
+#pragma omp section
+ {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(ele, i); /* set_inline */
+ }
+ }
+#pragma omp section
+ {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(ele, i); /* set_inline */
+ }
+ }
+#pragma omp section
+ {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(ele, i); /* set_inline */
+ }
+ }
}
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
@@ -1364,7 +1437,7 @@ void *BMO_iter_step(BMOIter *iter)
return NULL;
}
-/* used for iterating over mapping */
+/* used for iterating over mappings */
void *BMO_iter_map_value(BMOIter *iter)
{
return iter->val;
@@ -1380,7 +1453,7 @@ float BMO_iter_map_value_f(BMOIter *iter)
return *((float *)iter->val);
}
-/* error syste */
+/* error system */
typedef struct BMOpError {
struct BMOpError *next, *prev;
int errorcode;
@@ -1407,7 +1480,7 @@ void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg)
BLI_addhead(&bm->errorstack, err);
}
-int BMO_error_occurred(BMesh *bm)
+bool BMO_error_occurred(BMesh *bm)
{
return bm->errorstack.first != NULL;
}
@@ -1513,7 +1586,7 @@ static int bmo_opname_to_opcode(const char *opname)
* **Utility**
*
* Pass an existing slot which is copied to either an input or output slot.
- * Taking the operator and slot-name pair of args.
+ * Taking the operator and slot-name pair of args (BMOperator *, const char *).
* - `s` - slot_in (lower case)
* - `S` - slot_out (upper case)
*
@@ -1541,7 +1614,7 @@ static int bmo_opname_to_opcode(const char *opname)
* Order is not important so `Hfev` is also valid (all unflagged verts, edges and faces).
*/
-int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, va_list vlist)
+bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, va_list vlist)
{
// BMOpDefine *def;
char *opname, *ofmt, *fmt;
@@ -1562,7 +1635,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
goto error; \
} (void)0
- /* we muck around in here, so dup i */
+ /* we muck around in here, so dup it */
fmt = ofmt = BLI_strdup(_fmt);
/* find operator name */
@@ -1578,7 +1651,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
if (i == -1) {
MEM_freeN(ofmt);
- return FALSE;
+ return false;
}
BMO_op_init(bm, op, flag, opname);
@@ -1589,11 +1662,11 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
while (*fmt) {
if (state) {
- /* jump past leading whitespac */
+ /* jump past leading whitespace */
i = strspn(fmt, " ");
fmt += i;
- /* ignore trailing whitespac */
+ /* ignore trailing whitespace */
if (!fmt[i])
break;
@@ -1741,7 +1814,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
}
MEM_freeN(ofmt);
- return TRUE;
+ return true;
error:
/* non urgent todo - explain exactly what is failing */
@@ -1766,14 +1839,14 @@ error:
MEM_freeN(ofmt);
BMO_op_finish(bm, op);
- return FALSE;
+ return false;
#undef GOTO_ERROR
}
-int BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...)
+bool BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...)
{
va_list list;
@@ -1781,14 +1854,14 @@ int BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...
if (!BMO_op_vinitf(bm, op, flag, fmt, list)) {
printf("%s: failed\n", __func__);
va_end(list);
- return FALSE;
+ return false;
}
va_end(list);
- return TRUE;
+ return true;
}
-int BMO_op_callf(BMesh *bm, const int flag, const char *fmt, ...)
+bool BMO_op_callf(BMesh *bm, const int flag, const char *fmt, ...)
{
va_list list;
BMOperator op;
@@ -1797,12 +1870,12 @@ int BMO_op_callf(BMesh *bm, const int flag, const char *fmt, ...)
if (!BMO_op_vinitf(bm, &op, flag, fmt, list)) {
printf("%s: failed, format is:\n \"%s\"\n", __func__, fmt);
va_end(list);
- return FALSE;
+ return false;
}
BMO_op_exec(bm, &op);
BMO_op_finish(bm, &op);
va_end(list);
- return TRUE;
+ return true;
}
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 9175af1c822..ea9ad2ed151 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -89,7 +89,6 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op);
void bmo_similar_edges_exec(BMesh *bm, BMOperator *op);
void bmo_similar_faces_exec(BMesh *bm, BMOperator *op);
void bmo_similar_verts_exec(BMesh *bm, BMOperator *op);
-void bmo_slide_vert_exec(BMesh *bm, BMOperator *op);
void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op);
void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op);
void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 2e0471863d4..9592c34fc75 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -50,7 +50,7 @@
* Used for tessellator
*/
-static short testedgesidef(const float v1[2], const float v2[2], const float v3[2])
+static bool testedgesidef(const float v1[2], const float v2[2], const float v3[2])
{
/* is v3 to the right of v1 - v2 ? With exception: v3 == v1 || v3 == v2 */
double inp;
@@ -59,13 +59,13 @@ static short testedgesidef(const float v1[2], const float v2[2], const float v3[
inp = (v2[0] - v1[0]) * (v1[1] - v3[1]) + (v1[1] - v2[1]) * (v1[0] - v3[0]);
if (inp < 0.0) {
- return FALSE;
+ return false;
}
else if (inp == 0) {
- if (v1[0] == v3[0] && v1[1] == v3[1]) return FALSE;
- if (v2[0] == v3[0] && v2[1] == v3[1]) return FALSE;
+ if (v1[0] == v3[0] && v1[1] == v3[1]) return false;
+ if (v2[0] == v3[0] && v2[1] == v3[1]) return false;
}
- return TRUE;
+ return true;
}
/**
@@ -157,13 +157,10 @@ float BM_face_calc_area(BMFace *f)
{
BMLoop *l;
BMIter iter;
- float (*verts)[3];
- float normal[3];
+ float (*verts)[3] = BLI_array_alloca(verts, f->len);
float area;
int i;
- BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
-
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
copy_v3_v3(verts[i], l->v->co);
}
@@ -175,12 +172,11 @@ float BM_face_calc_area(BMFace *f)
area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]);
}
else {
+ float normal[3];
calc_poly_normal(normal, verts, f->len);
area = area_poly_v3(f->len, verts, normal);
}
- BLI_array_fixedstack_free(verts);
-
return area;
}
@@ -301,7 +297,6 @@ static void scale_edge_v3f(float v1[3], float v2[3], const float fac)
add_v3_v3v3(v2, v2, mid);
}
-
/**
* \brief POLY ROTATE PLANE
*
@@ -310,30 +305,14 @@ static void scale_edge_v3f(float v1[3], float v2[3], const float fac)
*/
void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nverts)
{
-
- float up[3] = {0.0f, 0.0f, 1.0f}, axis[3], q[4];
float mat[3][3];
- float angle;
- int i;
-
- cross_v3_v3v3(axis, normal, up);
-
- angle = saacos(dot_v3v3(normal, up));
-
- if (angle < FLT_EPSILON)
- return;
- if (len_v3(axis) < FLT_EPSILON) {
- axis[0] = 0.0f;
- axis[1] = 1.0f;
- axis[2] = 0.0f;
+ if (axis_dominant_v3_to_m3(mat, normal)) {
+ int i;
+ for (i = 0; i < nverts; i++) {
+ mul_m3_v3(mat, verts[i]);
+ }
}
-
- axis_angle_to_quat(q, axis, angle);
- quat_to_mat3(mat, q);
-
- for (i = 0; i < nverts; i++)
- mul_m3_v3(mat, verts[i]);
}
/**
@@ -502,7 +481,7 @@ void BM_face_normal_flip(BMesh *bm, BMFace *f)
/* detects if two line segments cross each other (intersects).
* note, there could be more winding cases then there needs to be. */
-static int line_crosses_v2f(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
+static bool line_crosses_v2f(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
#define GETMIN2_AXIS(a, b, ma, mb, axis) \
@@ -530,7 +509,7 @@ static int line_crosses_v2f(const float v1[2], const float v2[2], const float v3
w5 = !testedgesidef(v3, v1, v4);
if (w1 == w2 && w2 == w3 && w3 == w4 && w4 == w5) {
- return TRUE;
+ return true;
}
GETMIN2(v1, v2, mv1, mv2);
@@ -553,7 +532,7 @@ static int line_crosses_v2f(const float v1[2], const float v2[2], const float v3
return (mv4[1] >= mv1[1] && mv3[1] <= mv2[1]);
}
- return FALSE;
+ return false;
#undef GETMIN2_AXIS
#undef GETMIN2
@@ -571,7 +550,7 @@ static int line_crosses_v2f(const float v1[2], const float v2[2], const float v3
* instead of projecting co directly into f's orientation space,
* so there might be accuracy issues.
*/
-int BM_face_point_inside_test(BMFace *f, const float co[3])
+bool BM_face_point_inside_test(BMFace *f, const float co[3])
{
int ax, ay;
float co2[2], cent[2] = {0.0f, 0.0f}, out[2] = {FLT_MAX * 0.5f, FLT_MAX * 0.5f};
@@ -618,26 +597,26 @@ int BM_face_point_inside_test(BMFace *f, const float co[3])
return crosses % 2 != 0;
}
-static int bm_face_goodline(float const (*projectverts)[3], BMFace *f, int v1i, int v2i, int v3i)
+static bool bm_face_goodline(float const (*projectverts)[2], BMFace *f, int v1i, int v2i, int v3i)
{
BMLoop *l_iter;
BMLoop *l_first;
- float v1[3], v2[3], v3[3], pv1[3];
- int i;
- copy_v3_v3(v1, projectverts[v1i]);
- copy_v3_v3(v2, projectverts[v2i]);
- copy_v3_v3(v3, projectverts[v3i]);
+ float pv1[2];
+ const float *v1 = projectverts[v1i];
+ const float *v2 = projectverts[v2i];
+ const float *v3 = projectverts[v3i];
+ int i;
/* v3 must be on the left side of [v1, v2] line, else we know [v1, v3] is outside of f! */
if (testedgesidef(v1, v2, v3)) {
- return FALSE;
+ return false;
}
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
i = BM_elem_index_get(l_iter->v);
- copy_v3_v3(pv1, projectverts[i]);
+ copy_v2_v2(pv1, projectverts[i]);
if (ELEM3(i, v1i, v2i, v3i)) {
#if 0
@@ -653,23 +632,24 @@ static int bm_face_goodline(float const (*projectverts)[3], BMFace *f, int v1i,
else
printf("%d in (%d, %d, %d)\n", v1i, i, v3i, v2i);
#endif
- return FALSE;
+ return false;
}
} while ((l_iter = l_iter->next) != l_first);
- return TRUE;
+ return true;
}
/**
* \brief Find Ear
*
* Used by tessellator to find the next triangle to 'clip off' of a polygon while tessellating.
+ *
* \param f The face to search.
- * \param verts an array of face vert coords.
+ * \param projectverts an array of face vert coords.
* \param use_beauty Currently only applies to quads, can be extended later on.
* \param abscoss Must be allocated by caller, and at least f->len length
* (allow to avoid allocating a new one for each tri!).
*/
-static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, float *abscoss)
+static BMLoop *poly_find_ear(BMFace *f, float (*projectverts)[2], const bool use_beauty, float *abscoss)
{
BMLoop *bestear = NULL;
@@ -694,7 +674,7 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
i = (((len_squared_v3v3(larr[0]->v->co, larr[2]->v->co) >
len_squared_v3v3(larr[1]->v->co, larr[3]->v->co) * bias)) != use_beauty);
i4 = (i + 3) % 4;
- /* Check produced tris aren’t too flat/narrow...
+ /* Check produced tris aren't too flat/narrow...
* Probably not the best test, but is quite efficient and should at least avoid null-area faces! */
cos1 = fabsf(cos_v3v3v3(larr[i4]->v->co, larr[i]->v->co, larr[i + 1]->v->co));
cos2 = fabsf(cos_v3v3v3(larr[i4]->v->co, larr[i + 2]->v->co, larr[i + 1]->v->co));
@@ -715,7 +695,7 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
/* Last check we do not get overlapping triangles
* (as much as possible, there are some cases with no good solution!) */
i4 = (i + 3) % 4;
- if (!bm_face_goodline((float const (*)[3])verts, f, BM_elem_index_get(larr[i4]->v),
+ if (!bm_face_goodline((float const (*)[2])projectverts, f, BM_elem_index_get(larr[i4]->v),
BM_elem_index_get(larr[i]->v), BM_elem_index_get(larr[i + 1]->v)))
{
i = !i;
@@ -725,77 +705,44 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
}
else {
- BMVert *v1, *v2, *v3;
-
/* float angle, bestangle = 180.0f; */
- float cos, tcos, bestcos = 1.0f;
- float *tcoss;
- int isear, i = 0, j, len;
+ float cos, bestcos = 1.0f;
+ int i, j, len;
/* Compute cos of all corners! */
+ i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
len = l_iter->f->len;
- tcoss = abscoss;
do {
- v1 = l_iter->prev->v;
- v2 = l_iter->v;
- v3 = l_iter->next->v;
+ const BMVert *v1 = l_iter->prev->v;
+ const BMVert *v2 = l_iter->v;
+ const BMVert *v3 = l_iter->next->v;
- *tcoss = fabsf(cos_v3v3v3(v1->co, v2->co, v3->co));
+ abscoss[i] = fabsf(cos_v3v3v3(v1->co, v2->co, v3->co));
/* printf("tcoss: %f\n", *tcoss);*/
- tcoss++;
+ i++;
} while ((l_iter = l_iter->next) != l_first);
+ i = 0;
l_iter = l_first;
- tcoss = abscoss;
do {
- isear = TRUE;
+ const BMVert *v1 = l_iter->prev->v;
+ const BMVert *v2 = l_iter->v;
+ const BMVert *v3 = l_iter->next->v;
- v1 = l_iter->prev->v;
- v2 = l_iter->v;
- v3 = l_iter->next->v;
-
- /* We may have already internal edges... */
- if (BM_edge_exists(v1, v3)) {
- isear = FALSE;
- }
- else if (!bm_face_goodline((float const (*)[3])verts, f, BM_elem_index_get(v1),
- BM_elem_index_get(v2), BM_elem_index_get(v3)))
+ if (bm_face_goodline((float const (*)[2])projectverts, f,
+ BM_elem_index_get(v1), BM_elem_index_get(v2), BM_elem_index_get(v3)))
{
-#if 0
- printf("(%d, %d, %d) would not be a valid tri!\n",
- BM_elem_index_get(v1), BM_elem_index_get(v2), BM_elem_index_get(v3));
-#endif
- isear = FALSE;
- }
-
- if (isear) {
-#if 0 /* Old, already commented code */
- /* if this code comes back, it needs to be converted to radians */
- angle = angle_v3v3v3(verts[v1->head.eflag2], verts[v2->head.eflag2], verts[v3->head.eflag2]);
- if (!bestear || ABS(angle - 45.0f) < bestangle) {
- bestear = l;
- bestangle = ABS(45.0f - angle);
- }
-
- if (angle > 20 && angle < 90) break;
- if (angle < 100 && i > 5) break;
- i += 1;
-#endif
-
/* Compute highest cos (i.e. narrowest angle) of this tri. */
- cos = *tcoss;
- tcos = fabsf(cos_v3v3v3(v2->co, v3->co, v1->co));
- if (tcos > cos)
- cos = tcos;
- tcos = fabsf(cos_v3v3v3(v3->co, v1->co, v2->co));
- if (tcos > cos)
- cos = tcos;
+ cos = max_fff(abscoss[i],
+ fabsf(cos_v3v3v3(v2->co, v3->co, v1->co)),
+ fabsf(cos_v3v3v3(v3->co, v1->co, v2->co)));
/* Compare to prev best (i.e. lowest) cos. */
if (cos < bestcos) {
/* We must check this tri would not leave a (too much) degenerated remaining face! */
- /* For now just assume if the average of cos of all "remaining face"'s corners is below a given threshold, it’s OK. */
+ /* For now just assume if the average of cos of all
+ * "remaining face"'s corners is below a given threshold, it's OK. */
float avgcos = fabsf(cos_v3v3v3(v1->co, v3->co, l_iter->next->next->v->co));
const int i_limit = (i - 1 + len) % len;
avgcos += fabsf(cos_v3v3v3(l_iter->prev->prev->v->co, v1->co, v3->co));
@@ -819,7 +766,6 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
#endif
}
}
- tcoss++;
i++;
} while ((l_iter = l_iter->next) != l_first);
}
@@ -830,121 +776,71 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
/**
* \brief BMESH TRIANGULATE FACE
*
- * --- Prev description (wasn’t correct, ear clipping was currently simply picking the first tri in the loop!)
- * Triangulates a face using a simple 'ear clipping' algorithm that tries to
- * favor non-skinny triangles (angles less than 90 degrees).
- *
- * If the triangulator has bits left over (or cannot triangulate at all)
- * it uses a simple fan triangulation,
- * --- End of prev description
- *
- * Currently tries to repeatedly find the best triangle (i.e. the most "open" one), provided it does not
+ * Currently repeatedly find the best triangle (i.e. the most "open" one), provided it does not
* produces a "remaining" face with too much wide/narrow angles
* (using cos (i.e. dot product of normalized vectors) of angles).
*
- * newfaces, if non-null, must be an array of BMFace pointers,
- * with a length equal to f->len. It will be filled with the new
- * triangles, and will be NULL-terminated.
+ * \param r_faces_new if non-null, must be an array of BMFace pointers,
+ * with a length equal to (f->len - 2). It will be filled with the new
+ * triangles.
*
- * \note newedgeflag sets a flag layer flag, obviously not the header flag.
+ * \note use_tag tags new flags and edges.
*/
-void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], const short newedge_oflag,
- const short newface_oflag, BMFace **newfaces, const short use_beauty)
+void BM_face_triangulate(BMesh *bm, BMFace *f,
+ BMFace **r_faces_new,
+ const bool use_beauty, const bool use_tag)
{
- int i, done, nvert, nf_i = 0;
- BMLoop *newl;
+ const float f_len_orig = f->len;
+ int i, nf_i = 0;
+ BMLoop *l_new;
BMLoop *l_iter;
BMLoop *l_first;
- float *abscoss = NULL;
- BLI_array_fixedstack_declare(abscoss, 16, f->len, "BM_face_triangulate: temp absolute cosines of face corners");
+ /* BM_face_triangulate: temp absolute cosines of face corners */
+ float (*projectverts)[2] = BLI_array_alloca(projectverts, f_len_orig);
+ float *abscoss = BLI_array_alloca(abscoss, f_len_orig);
+ float mat[3][3];
+
+ axis_dominant_v3_to_m3(mat, f->no);
/* copy vertex coordinates to vertspace area */
i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- copy_v3_v3(projectverts[i], l_iter->v->co);
- BM_elem_index_set(l_iter->v, i); /* set dirty! */
- i++;
+ mul_v2_m3v3(projectverts[i], mat, l_iter->v->co);
+ BM_elem_index_set(l_iter->v, i++); /* set dirty! */
} while ((l_iter = l_iter->next) != l_first);
bm->elem_index_dirty |= BM_VERT; /* see above */
- /* bmesh_face_normal_update(bm, f, f->no, projectverts); */
-
- calc_poly_normal(f->no, projectverts, f->len);
- poly_rotate_plane(f->no, projectverts, i);
+ while (f->len > 3) {
+ l_iter = poly_find_ear(f, projectverts, use_beauty, abscoss);
- nvert = f->len;
-
- /* calc_poly_plane(projectverts, i); */
- for (i = 0; i < nvert; i++) {
- projectverts[i][2] = 0.0f;
- }
+ /* force triangulation - if we can't find an ear the face is degenerate */
+ if (l_iter == NULL) {
+ l_iter = BM_FACE_FIRST_LOOP(f);
+ }
- done = FALSE;
- while (!done && f->len > 3) {
- done = TRUE;
- l_iter = find_ear(f, projectverts, use_beauty, abscoss);
- if (l_iter) {
- done = FALSE;
-/* printf("Subdividing face...\n");*/
- f = BM_face_split(bm, l_iter->f, l_iter->prev->v, l_iter->next->v, &newl, NULL, TRUE);
-
- if (UNLIKELY(!f)) {
- fprintf(stderr, "%s: triangulator failed to split face! (bmesh internal error)\n", __func__);
- break;
- }
+/* printf("Subdividing face...\n");*/
+ f = BM_face_split(bm, l_iter->f, l_iter->prev->v, l_iter->next->v, &l_new, NULL, true);
- copy_v3_v3(f->no, l_iter->f->no);
- BMO_elem_flag_enable(bm, newl->e, newedge_oflag);
- BMO_elem_flag_enable(bm, f, newface_oflag);
-
- if (newfaces)
- newfaces[nf_i++] = f;
+ if (UNLIKELY(!f)) {
+ fprintf(stderr, "%s: triangulator failed to split face! (bmesh internal error)\n", __func__);
+ break;
+ }
-#if 0
- l = f->loopbase;
- do {
- if (l->v == v) {
- f->loopbase = l;
- break;
- }
- l = l->next;
- } while (l != f->loopbase);
-#endif
+ copy_v3_v3(f->no, l_iter->f->no);
+ if (use_tag) {
+ BM_elem_flag_enable(l_new->e, BM_ELEM_TAG);
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
}
- }
-
-#if 0 /* XXX find_ear should now always return a corner, so no more need for this piece of code... */
- if (f->len > 3) {
- l_iter = BM_FACE_FIRST_LOOP(f);
- while (l_iter->f->len > 3) {
- nextloop = l_iter->next->next;
- f = BM_face_split(bm, l_iter->f, l_iter->v, nextloop->v,
- &newl, NULL, TRUE);
- if (!f) {
- printf("triangle fan step of triangulator failed.\n");
-
- /* NULL-terminate */
- if (newfaces) newfaces[nf_i] = NULL;
- return;
- }
- if (newfaces) newfaces[nf_i++] = f;
-
- BMO_elem_flag_enable(bm, newl->e, newedge_oflag);
- BMO_elem_flag_enable(bm, f, newface_oflag);
- l_iter = nextloop;
+ if (r_faces_new) {
+ r_faces_new[nf_i++] = f;
}
}
-#endif
-
- BLI_array_fixedstack_free(abscoss);
- /* NULL-terminate */
- if (newfaces)
- newfaces[nf_i] = NULL;
+ BLI_assert(f->len == 3);
}
/**
@@ -961,13 +857,10 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
BMLoop *l;
float v1[3], v2[3], v3[3] /*, v4[3 */, no[3], mid[3], *p1, *p2, *p3, *p4;
float out[3] = {-FLT_MAX, -FLT_MAX, 0.0f};
- float (*projverts)[3];
- float (*edgeverts)[3];
+ float (*projverts)[3] = BLI_array_alloca(projverts, f->len);
+ float (*edgeverts)[3] = BLI_array_alloca(edgeverts, len * 2);
float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f;
int i, j, a = 0, clen;
-
- BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb");
- BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
i = 0;
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
@@ -1042,7 +935,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
}
}
- /* do line crossing test */
+ /* do line crossing tests */
for (i = 0; i < f->len; i++) {
p1 = projverts[i];
p2 = projverts[(i + 1) % f->len];
@@ -1085,7 +978,38 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
}
}
}
+}
+
+
+/**
+ * Small utility functions for fast access
+ *
+ * faster alternative to:
+ * BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3);
+ */
+void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3])
+{
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
+
+ BLI_assert(f->len == 3);
+
+ r_verts[0] = l->v; l = l->next;
+ r_verts[1] = l->v; l = l->next;
+ r_verts[2] = l->v;
+}
+
+/**
+ * faster alternative to:
+ * BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 4);
+ */
+void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4])
+{
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
+
+ BLI_assert(f->len == 4);
- BLI_array_fixedstack_free(projverts);
- BLI_array_fixedstack_free(edgeverts);
+ r_verts[0] = l->v; l = l->next;
+ r_verts[1] = l->v; l = l->next;
+ r_verts[2] = l->v; l = l->next;
+ r_verts[3] = l->v;
}
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index e5777d3611b..601caae2337 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -42,12 +42,14 @@ void BM_vert_normal_update(BMVert *v);
void BM_vert_normal_update_all(BMVert *v);
void BM_face_normal_flip(BMesh *bm, BMFace *f);
-int BM_face_point_inside_test(BMFace *f, const float co[3]);
+bool BM_face_point_inside_test(BMFace *f, const float co[3]);
-void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3],
- const short newedge_oflag, const short newface_oflag, BMFace **newfaces,
- const short use_beauty);
+void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **newfaces,
+ const bool use_beauty, const bool use_tag);
void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len);
+void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3]);
+void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4]);
+
#endif /* __BMESH_POLYGON_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 195c60c5a9c..44dc483d5a7 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -43,7 +43,7 @@
* Returns whether or not a given vertex is
* is part of a given edge.
*/
-int BM_vert_in_edge(BMEdge *e, BMVert *v)
+bool BM_vert_in_edge(BMEdge *e, BMVert *v)
{
return bmesh_vert_in_edge(e, v);
}
@@ -208,9 +208,9 @@ BMLoop *BM_vert_find_first_loop(BMVert *v)
}
/**
- * Returns TRUE if the vertex is used in a given face.
+ * Returns true if the vertex is used in a given face.
*/
-int BM_vert_in_face(BMFace *f, BMVert *v)
+bool BM_vert_in_face(BMFace *f, BMVert *v)
{
BMLoop *l_iter, *l_first;
@@ -226,19 +226,19 @@ int BM_vert_in_face(BMFace *f, BMVert *v)
#endif
do {
if (l_iter->v == v) {
- return TRUE;
+ return true;
}
} while ((l_iter = l_iter->next) != l_first);
}
- return FALSE;
+ return false;
}
/**
* Compares the number of vertices in an array
* that appear in a given face
*/
-int BM_verts_in_face(BMFace *f, BMVert **varr, int len)
+int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len)
{
BMLoop *l_iter, *l_first;
@@ -278,10 +278,64 @@ int BM_verts_in_face(BMFace *f, BMVert **varr, int len)
return count;
}
+
+/**
+ * Return true if all verts are in the face.
+ */
+bool BM_verts_in_face(BMFace *f, BMVert **varr, int len)
+{
+ BMLoop *l_iter, *l_first;
+
+#ifdef USE_BMESH_HOLES
+ BMLoopList *lst;
+#endif
+
+ int i;
+ bool ok = true;
+
+ /* simple check, we know can't succeed */
+ if (f->len < len) {
+ return false;
+ }
+
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
+ }
+
+#ifdef USE_BMESH_HOLES
+ for (lst = f->loops.first; lst; lst = lst->next)
+#endif
+ {
+
+#ifdef USE_BMESH_HOLES
+ l_iter = l_first = lst->first;
+#else
+ l_iter = l_first = f->l_first;
+#endif
+
+ do {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
+ /* pass */
+ }
+ else {
+ ok = false;
+ break;
+ }
+
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
+ }
+
+ return ok;
+}
+
/**
* Returns whether or not a given edge is is part of a given face.
*/
-int BM_edge_in_face(BMFace *f, BMEdge *e)
+bool BM_edge_in_face(BMFace *f, BMEdge *e)
{
BMLoop *l_iter;
BMLoop *l_first;
@@ -290,17 +344,17 @@ int BM_edge_in_face(BMFace *f, BMEdge *e)
do {
if (l_iter->e == e) {
- return TRUE;
+ return true;
}
} while ((l_iter = l_iter->next) != l_first);
- return FALSE;
+ return false;
}
/**
* Returns whether or not a given edge is is part of a given loop.
*/
-int BM_edge_in_loop(BMEdge *e, BMLoop *l)
+bool BM_edge_in_loop(BMEdge *e, BMLoop *l)
{
return (l->e == e || l->prev->e == e);
}
@@ -309,7 +363,7 @@ int BM_edge_in_loop(BMEdge *e, BMLoop *l)
* Returns whether or not two vertices are in
* a given edge
*/
-int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
+bool BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
{
return bmesh_verts_in_edge(v1, v2, e);
}
@@ -418,7 +472,7 @@ BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step)
* The function takes a vertex at the center of a fan and returns the opposite edge in the fan.
* All edges in the fan must be manifold, otherwise return NULL.
*
- * \note This could (probably) be done more effieiently.
+ * \note This could (probably) be done more efficiently.
*/
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
{
@@ -468,7 +522,7 @@ BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
}
/**
- * Returms edge length
+ * Returns edge length
*/
float BM_edge_calc_length(BMEdge *e)
{
@@ -476,12 +530,20 @@ float BM_edge_calc_length(BMEdge *e)
}
/**
+ * Returns edge length squared (for comparisons)
+ */
+float BM_edge_calc_length_squared(BMEdge *e)
+{
+ return len_squared_v3v3(e->v1->co, e->v2->co);
+}
+
+/**
* Utility function, since enough times we have an edge
* and want to access 2 connected faces.
*
- * \return TRUE when only 2 faces are found.
+ * \return true when only 2 faces are found.
*/
-int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
+bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
{
BMLoop *la, *lb;
@@ -492,12 +554,12 @@ int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
{
*r_fa = la->f;
*r_fb = lb->f;
- return TRUE;
+ return true;
}
else {
*r_fa = NULL;
*r_fb = NULL;
- return FALSE;
+ return false;
}
}
@@ -505,9 +567,9 @@ int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
* Utility function, since enough times we have an edge
* and want to access 2 connected loops.
*
- * \return TRUE when only 2 faces are found.
+ * \return true when only 2 faces are found.
*/
-int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
+bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
{
BMLoop *la, *lb;
@@ -518,12 +580,12 @@ int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
{
*r_la = la;
*r_lb = lb;
- return TRUE;
+ return true;
}
else {
*r_la = NULL;
*r_lb = NULL;
- return FALSE;
+ return false;
}
}
@@ -581,7 +643,7 @@ int BM_vert_face_count(BMVert *v)
* Tests whether or not the vertex is part of a wire edge.
* (ie: has no faces attached to it)
*/
-int BM_vert_is_wire(BMVert *v)
+bool BM_vert_is_wire(BMVert *v)
{
if (v->e) {
BMEdge *e_first, *e_iter;
@@ -589,14 +651,14 @@ int BM_vert_is_wire(BMVert *v)
e_first = e_iter = v->e;
do {
if (e_iter->l) {
- return FALSE;
+ return false;
}
} while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
@@ -604,9 +666,9 @@ int BM_vert_is_wire(BMVert *v)
* Tests whether or not the edge is part of a wire.
* (ie: has no faces attached to it)
*/
-int BM_edge_is_wire(BMEdge *e)
+bool BM_edge_is_wire(BMEdge *e)
{
- return (e->l) ? FALSE : TRUE;
+ return (e->l == NULL);
}
/**
@@ -616,7 +678,7 @@ int BM_edge_is_wire(BMEdge *e)
* 3: Is part of a an edge with more than 2 faces.
* 4: Is part of a wire edge.
*/
-int BM_vert_is_manifold(BMVert *v)
+bool BM_vert_is_manifold(BMVert *v)
{
BMEdge *e, *oe;
BMLoop *l;
@@ -624,7 +686,7 @@ int BM_vert_is_manifold(BMVert *v)
if (v->e == NULL) {
/* loose vert */
- return FALSE;
+ return false;
}
/* count edges while looking for non-manifold edges */
@@ -635,7 +697,7 @@ int BM_vert_is_manifold(BMVert *v)
* edges with 1 face user are OK, otherwise we could
* use BM_edge_is_manifold() here */
if (e->l == NULL || bmesh_radial_length(e->l) > 2) {
- return FALSE;
+ return false;
}
len++;
} while ((e = bmesh_disk_edge_next(e, v)) != oe);
@@ -669,10 +731,10 @@ int BM_vert_is_manifold(BMVert *v)
if (count < len) {
/* vert shared by multiple regions */
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/**
@@ -681,7 +743,7 @@ int BM_vert_is_manifold(BMVert *v)
*/
#if 1 /* fast path for checking manifold */
-int BM_edge_is_manifold(BMEdge *e)
+bool BM_edge_is_manifold(BMEdge *e)
{
const BMLoop *l = e->l;
return (l && (l->radial_next != l) && /* not 0 or 1 face users */
@@ -692,21 +754,34 @@ int BM_edge_is_manifold(BMEdge *e)
{
int count = BM_edge_face_count(e);
if (count == 2) {
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
#endif
/**
+ * Tests that the edge is manifold and
+ * that both its faces point the same way.
+ */
+bool BM_edge_is_contiguous(BMEdge *e)
+{
+ const BMLoop *l = e->l;
+ const BMLoop *l_other = l->radial_next;
+ return (l && (l_other != l) && /* not 0 or 1 face users */
+ (l_other->radial_next == l) && /* 2 face users */
+ (l_other->v != l->v));
+}
+
+/**
* Tests whether or not an edge is on the boundary
* of a shell (has one face associated with it)
*/
#if 1 /* fast path for checking boundary */
-int BM_edge_is_boundary(BMEdge *e)
+bool BM_edge_is_boundary(BMEdge *e)
{
const BMLoop *l = e->l;
return (l && (l->radial_next == l));
@@ -716,10 +791,10 @@ int BM_edge_is_boundary(BMEdge *e)
{
int count = BM_edge_face_count(e);
if (count == 1) {
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
#endif
@@ -749,7 +824,7 @@ int BM_face_share_face_count(BMFace *f1, BMFace *f2)
/**
* same as #BM_face_share_face_count but returns a bool
*/
-int BM_face_share_face_check(BMFace *f1, BMFace *f2)
+bool BM_face_share_face_check(BMFace *f1, BMFace *f2)
{
BMIter iter1, iter2;
BMEdge *e;
@@ -758,11 +833,11 @@ int BM_face_share_face_check(BMFace *f1, BMFace *f2)
BM_ITER_ELEM (e, &iter1, f1, BM_EDGES_OF_FACE) {
BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
if (f != f1 && f != f2 && BM_face_share_edge_check(f, f2))
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
/**
@@ -785,9 +860,9 @@ int BM_face_share_edge_count(BMFace *f1, BMFace *f2)
}
/**
- * Returns TRUE if the faces share an edge
+ * Returns true if the faces share an edge
*/
-int BM_face_share_edge_check(BMFace *f1, BMFace *f2)
+bool BM_face_share_edge_check(BMFace *f1, BMFace *f2)
{
BMLoop *l_iter;
BMLoop *l_first;
@@ -795,17 +870,17 @@ int BM_face_share_edge_check(BMFace *f1, BMFace *f2)
l_iter = l_first = BM_FACE_FIRST_LOOP(f1);
do {
if (bmesh_radial_face_find(l_iter->e, f2)) {
- return TRUE;
+ return true;
}
} while ((l_iter = l_iter->next) != l_first);
- return FALSE;
+ return false;
}
/**
- * Test if e1 shares any faces with e2
+ * Test if e1 shares any faces with e2
*/
-int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
+bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
{
BMLoop *l;
BMFace *f;
@@ -815,18 +890,18 @@ int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
do {
f = l->f;
if (bmesh_radial_face_find(e2, f)) {
- return TRUE;
+ return true;
}
l = l->radial_next;
} while (l != e1->l);
}
- return FALSE;
+ return false;
}
/**
* Test if e1 shares any quad faces with e2
*/
-int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
+bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
{
BMLoop *l;
BMFace *f;
@@ -837,19 +912,19 @@ int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
f = l->f;
if (f->len == 4) {
if (bmesh_radial_face_find(e2, f)) {
- return TRUE;
+ return true;
}
}
l = l->radial_next;
} while (l != e1->l);
}
- return FALSE;
+ return false;
}
/**
* Tests to see if e1 shares a vertex with e2
*/
-int BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
+bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
{
return (e1->v1 == e2->v1 ||
e1->v1 == e2->v2 ||
@@ -945,6 +1020,22 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2)
}
/**
+ * Check if the loop is convex or concave
+ * (depends on face normal)
+ */
+bool BM_loop_is_convex(BMLoop *l)
+{
+ float e_dir_prev[3];
+ float e_dir_next[3];
+ float l_no[3];
+
+ sub_v3_v3v3(e_dir_prev, l->prev->v->co, l->v->co);
+ sub_v3_v3v3(e_dir_next, l->next->v->co, l->v->co);
+ cross_v3_v3v3(l_no, e_dir_next, e_dir_prev);
+ return dot_v3v3(l_no, l->f->no) > 0.0f;
+}
+
+/**
* Calculates the angle between the previous and next loops
* (angle at this loops face corner).
*
@@ -972,7 +1063,7 @@ void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3])
l->v->co,
l->next->v->co) != 0.0f)
{
- return;
+ /* pass */
}
else {
copy_v3_v3(r_normal, l->f->no);
@@ -980,6 +1071,29 @@ void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3])
}
/**
+ * \brief BM_loop_calc_face_direction
+ *
+ * Calculate the direction a loop is pointing.
+ *
+ * \param l The loop to calculate the direction at
+ * \param r_dir Resulting direction
+ */
+void BM_loop_calc_face_direction(BMLoop *l, float r_dir[3])
+{
+ float v_prev[3];
+ float v_next[3];
+
+ sub_v3_v3v3(v_prev, l->v->co, l->prev->v->co);
+ sub_v3_v3v3(v_next, l->next->v->co, l->v->co);
+
+ normalize_v3(v_prev);
+ normalize_v3(v_next);
+
+ add_v3_v3v3(r_dir, v_prev, v_next);
+ normalize_v3(r_dir);
+}
+
+/**
* \brief BM_loop_calc_face_tangent
*
* Calculate the tangent at this loop corner or fallback to the face normal on straight lines.
@@ -992,23 +1106,27 @@ void BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3])
{
float v_prev[3];
float v_next[3];
+ float dir[3];
sub_v3_v3v3(v_prev, l->prev->v->co, l->v->co);
sub_v3_v3v3(v_next, l->v->co, l->next->v->co);
normalize_v3(v_prev);
normalize_v3(v_next);
+ add_v3_v3v3(dir, v_prev, v_next);
- if (compare_v3v3(v_prev, v_next, FLT_EPSILON) == FALSE) {
- float dir[3];
+ if (compare_v3v3(v_prev, v_next, FLT_EPSILON * 10.0f) == false) {
float nor[3]; /* for this purpose doesn't need to be normalized */
- add_v3_v3v3(dir, v_prev, v_next);
cross_v3_v3v3(nor, v_prev, v_next);
+ /* concave face check */
+ if (UNLIKELY(dot_v3v3(nor, l->f->no) < 0.0f)) {
+ negate_v3(nor);
+ }
cross_v3_v3v3(r_tangent, dir, nor);
}
else {
/* prev/next are the same - compare with face normal since we don't have one */
- cross_v3_v3v3(r_tangent, v_next, l->f->no);
+ cross_v3_v3v3(r_tangent, dir, l->f->no);
}
normalize_v3(r_tangent);
@@ -1113,6 +1231,40 @@ float BM_vert_calc_shell_factor(BMVert *v)
return 1.0f;
}
}
+/* 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)
+{
+ BMIter iter;
+ BMLoop *l;
+ float accum_shell = 0.0f;
+ float accum_angle = 0.0f;
+ int tot_sel = 0, tot = 0;
+
+ 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_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle;
+ accum_angle += face_angle;
+ tot_sel++;
+ }
+ tot++;
+ }
+
+ if (accum_angle != 0.0f) {
+ return accum_shell / accum_angle;
+ }
+ else {
+ /* other main difference from BM_vert_calc_shell_factor! */
+ if (tot != 0 && tot_sel == 0) {
+ /* none selected, so use all */
+ return BM_vert_calc_shell_factor(v);
+ }
+ else {
+ return 1.0f;
+ }
+ }
+}
/**
* \note quite an obscure function.
@@ -1231,67 +1383,94 @@ BMEdge *BM_edge_find_double(BMEdge *e)
}
/**
- * Given a set of vertices \a varr, find out if
- * all those vertices overlap an existing face.
- *
- * \note Making a face here is valid but in some cases you wont want to
- * make a face thats part of another.
- *
- * \returns TRUE for overlap
+ * Given a set of vertices (varr), find out if
+ * there is a face with exactly those vertices
+ * (and only those vertices).
*
+ * \note there used to be a BM_face_exists_overlap function that checked for partial overlap,
+ * however this is no longer used, simple to add back.
*/
-int BM_face_exists_overlap(BMVert **varr, int len, BMFace **r_overlapface)
+bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
{
+ BMVert *v_search = varr[0]; /* we can search any of the verts in the array */
BMIter viter;
BMFace *f;
- int i, amount;
- for (i = 0; i < len; i++) {
- BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- amount = BM_verts_in_face(f, varr, len);
- if (amount >= len) {
- if (r_overlapface) {
- *r_overlapface = f;
+
+#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 (r_existface) {
+ *r_existface = f;
}
- return TRUE;
+ return true;
}
}
}
- if (r_overlapface) {
- *r_overlapface = NULL;
+ if (r_existface) {
+ *r_existface = NULL;
}
+ return false;
- return FALSE;
-}
+#else
-/**
- * Given a set of vertices (varr), find out if
- * there is a face with exactly those vertices
- * (and only those vertices).
- */
-int BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
-{
- BMIter viter;
- BMFace *f;
- int i, amount;
+ /* faster to do the flagging once, and inline */
+ bool is_init = false;
+ bool is_found = false;
+ int i;
- for (i = 0; i < len; i++) {
- BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- amount = BM_verts_in_face(f, varr, len);
- if (amount == len && amount == f->len) {
+
+ BM_ITER_ELEM (f, &viter, v_search, BM_FACES_OF_VERT) {
+ if (f->len == len) {
+ if (is_init == false) {
+ is_init = true;
+ for (i = 0; i < len; i++) {
+ BLI_assert(!BM_ELEM_API_FLAG_TEST(varr[i], _FLAG_OVERLAP));
+ BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
+ }
+ }
+
+ is_found = true;
+
+ {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+
+ do {
+ if (!BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
+ is_found = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ if (is_found) {
if (r_existface) {
*r_existface = f;
}
- return TRUE;
+ break;
}
}
}
- if (r_existface) {
- *r_existface = NULL;
+ if (is_found == false) {
+ if (r_existface) {
+ *r_existface = NULL;
+ }
+ }
+
+ if (is_init == true) {
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
+ }
}
- return FALSE;
+
+ return is_found;
+#endif
}
@@ -1307,12 +1486,12 @@ int BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
*
* \a earr and \a varr can be in any order, however they _must_ form a closed loop.
*/
-int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
+bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
{
BMFace *f;
BMEdge *e;
BMVert *v;
- int ok;
+ bool ok;
int tot_tag;
BMIter fiter;
@@ -1352,10 +1531,10 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
for (i = 0; i < len; i++) {
BM_ITER_ELEM (f, &fiter, earr[i], BM_FACES_OF_EDGE) {
if (!BM_elem_flag_test(f, BM_ELEM_INTERNAL_TAG)) {
- ok = TRUE;
+ ok = true;
BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
if (!BM_elem_flag_test(v, BM_ELEM_INTERNAL_TAG)) {
- ok = FALSE;
+ ok = false;
break;
}
}
@@ -1374,20 +1553,20 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
if (tot_tag == 0) {
/* no faces use only boundary verts, quit early */
- return FALSE;
+ return false;
}
/* 2) loop over non-boundary edges that use boundary verts,
* check each have 2 tagges faces connected (faces that only use 'varr' verts) */
- ok = TRUE;
+ ok = true;
for (i = 0; i < len; i++) {
BM_ITER_ELEM (e, &fiter, varr[i], BM_EDGES_OF_VERT) {
if (/* non-boundary edge */
- BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == FALSE &&
+ BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == false &&
/* ...using boundary verts */
- BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) == TRUE &&
- BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG) == TRUE)
+ BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) == true &&
+ BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG) == true)
{
int tot_face_tag = 0;
BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
@@ -1397,14 +1576,14 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
}
if (tot_face_tag != 2) {
- ok = FALSE;
+ ok = false;
break;
}
}
}
- if (ok == FALSE) {
+ if (ok == false) {
break;
}
}
@@ -1413,44 +1592,40 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
}
/* same as 'BM_face_exists_multi' but built vert array from edges */
-int BM_face_exists_multi_edge(BMEdge **earr, int len)
+bool BM_face_exists_multi_edge(BMEdge **earr, int len)
{
- BMVert **varr;
- BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
+ BMVert **varr = BLI_array_alloca(varr, len);
- int ok;
+ bool ok;
int i, i_next;
/* first check if verts have edges, if not we can bail out early */
- ok = TRUE;
+ ok = true;
for (i = len - 1, i_next = 0; i_next < len; (i = i_next++)) {
if (!(varr[i] = BM_edge_share_vert(earr[i], earr[i_next]))) {
- ok = FALSE;
+ ok = false;
break;
}
}
- if (ok == FALSE) {
+ if (ok == false) {
BMESH_ASSERT(0);
- BLI_array_fixedstack_free(varr);
- return FALSE;
+ return false;
}
ok = BM_face_exists_multi(varr, earr, len);
- BLI_array_fixedstack_free(varr);
-
return ok;
}
/* convenience functions for checking flags */
-int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
+bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
{
return (BM_elem_flag_test(e->v1, hflag) ||
BM_elem_flag_test(e->v2, hflag));
}
-int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
+bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
{
BMLoop *l_iter;
BMLoop *l_first;
@@ -1458,13 +1633,13 @@ int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
if (BM_elem_flag_test(l_iter->v, hflag)) {
- return TRUE;
+ return true;
}
} while ((l_iter = l_iter->next) != l_first);
- return FALSE;
+ return false;
}
-int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
+bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
{
BMLoop *l_iter;
BMLoop *l_first;
@@ -1472,8 +1647,8 @@ int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
if (BM_elem_flag_test(l_iter->e, hflag)) {
- return TRUE;
+ return true;
}
} while ((l_iter = l_iter->next) != l_first);
- return FALSE;
+ return false;
}
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 7a18f69371e..7cb5749a4bf 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -27,18 +27,20 @@
* \ingroup bmesh
*/
-int BM_vert_in_face(BMFace *f, BMVert *v);
-int BM_verts_in_face(BMFace *f, BMVert **varr, int len);
+bool BM_vert_in_face(BMFace *f, BMVert *v);
+int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len);
+bool BM_verts_in_face(BMFace *f, BMVert **varr, int len);
-int BM_edge_in_face(BMFace *f, BMEdge *e);
-int BM_edge_in_loop(BMEdge *e, BMLoop *l);
+bool BM_edge_in_face(BMFace *f, BMEdge *e);
+bool BM_edge_in_loop(BMEdge *e, BMLoop *l);
-int BM_vert_in_edge(BMEdge *e, BMVert *v);
-int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e);
+bool BM_vert_in_edge(BMEdge *e, BMVert *v);
+bool BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e);
float BM_edge_calc_length(BMEdge *e);
-int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb);
-int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb);
+float BM_edge_calc_length_squared(BMEdge *e);
+bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb);
+bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb);
BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v);
BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l);
BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v);
@@ -53,15 +55,19 @@ int BM_edge_face_count(BMEdge *e);
int BM_vert_face_count(BMVert *v);
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e);
-int BM_vert_is_wire(BMVert *v);
-int BM_edge_is_wire(BMEdge *e);
+bool BM_vert_is_wire(BMVert *v);
+bool BM_edge_is_wire(BMEdge *e);
-int BM_vert_is_manifold(BMVert *v);
-int BM_edge_is_manifold(BMEdge *e);
-int BM_edge_is_boundary(BMEdge *e);
+bool BM_vert_is_manifold(BMVert *v);
+bool BM_edge_is_manifold(BMEdge *e);
+bool BM_edge_is_boundary(BMEdge *e);
+bool BM_edge_is_contiguous(BMEdge *e);
+
+bool BM_loop_is_convex(BMLoop *l);
float BM_loop_calc_face_angle(BMLoop *l);
void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3]);
+void BM_loop_calc_face_direction(BMLoop *l, float r_normal[3]);
void BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3]);
float BM_edge_calc_face_angle(BMEdge *e);
@@ -69,6 +75,7 @@ void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3])
float BM_vert_calc_edge_angle(BMVert *v);
float BM_vert_calc_shell_factor(BMVert *v);
+float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag);
float BM_vert_calc_mean_tagged_edge_length(BMVert *v);
BMLoop *BM_face_find_shortest_loop(BMFace *f);
@@ -77,21 +84,19 @@ BMLoop *BM_face_find_longest_loop(BMFace *f);
BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2);
BMEdge *BM_edge_find_double(BMEdge *e);
-int BM_face_exists_overlap(BMVert **varr, int len, BMFace **r_existface);
-
-int BM_face_exists(BMVert **varr, int len, BMFace **r_existface);
+bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface);
-int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len);
-int BM_face_exists_multi_edge(BMEdge **earr, int len);
+bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len);
+bool BM_face_exists_multi_edge(BMEdge **earr, int len);
int BM_face_share_face_count(BMFace *f1, BMFace *f2);
int BM_face_share_edge_count(BMFace *f1, BMFace *f2);
-int BM_face_share_face_check(BMFace *f1, BMFace *f2);
-int BM_face_share_edge_check(BMFace *f1, BMFace *f2);
-int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2);
-int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2);
-int BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2);
+bool BM_face_share_face_check(BMFace *f1, BMFace *f2);
+bool BM_face_share_edge_check(BMFace *f1, BMFace *f2);
+bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2);
+bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2);
+bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2);
BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2);
BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v);
@@ -101,8 +106,8 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
BMLoop *edge_loop);
-int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
-int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
-int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
+bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
+bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
+bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
#endif /* __BMESH_QUERIES_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index b58e61a3066..2f568a498c5 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -40,16 +40,16 @@
* MISC utility functions.
*/
-int bmesh_vert_in_edge(BMEdge *e, BMVert *v)
+bool bmesh_vert_in_edge(BMEdge *e, BMVert *v)
{
- if (e->v1 == v || e->v2 == v) return TRUE;
- return FALSE;
+ if (e->v1 == v || e->v2 == v) return true;
+ return false;
}
-int bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
+bool bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
{
- if (e->v1 == v1 && e->v2 == v2) return TRUE;
- else if (e->v1 == v2 && e->v2 == v1) return TRUE;
- return FALSE;
+ if (e->v1 == v1 && e->v2 == v2) return true;
+ else if (e->v1 == v2 && e->v2 == v1) return true;
+ return false;
}
BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v)
@@ -63,19 +63,19 @@ BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v)
return NULL;
}
-int bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv)
+bool bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv)
{
if (e->v1 == orig) {
e->v1 = newv;
e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
- return TRUE;
+ return true;
}
else if (e->v2 == orig) {
e->v2 = newv;
e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/**
@@ -165,7 +165,7 @@ BLI_INLINE BMDiskLink *bmesh_disk_edge_link_from_vert(BMEdge *e, BMVert *v)
}
}
-int bmesh_disk_edge_append(BMEdge *e, BMVert *v)
+void bmesh_disk_edge_append(BMEdge *e, BMVert *v)
{
if (!v->e) {
BMDiskLink *dl1 = bmesh_disk_edge_link_from_vert(e, v);
@@ -187,8 +187,6 @@ int bmesh_disk_edge_append(BMEdge *e, BMVert *v)
if (dl3)
dl3->next = e;
}
-
- return TRUE;
}
void bmesh_disk_edge_remove(BMEdge *e, BMVert *v)
@@ -280,23 +278,23 @@ int bmesh_disk_count(BMVert *v)
}
}
-int bmesh_disk_validate(int len, BMEdge *e, BMVert *v)
+bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v)
{
BMEdge *e_iter;
if (!BM_vert_in_edge(e, v))
- return FALSE;
+ return false;
if (bmesh_disk_count(v) != len || len == 0)
- return FALSE;
+ return false;
e_iter = e;
do {
if (len != 1 && bmesh_disk_edge_prev(e_iter, v) == e_iter) {
- return FALSE;
+ return false;
}
} while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
- return TRUE;
+ return true;
}
/**
@@ -362,34 +360,34 @@ BMEdge *bmesh_disk_faceedge_find_next(BMEdge *e, BMVert *v)
}
/*****radial cycle functions, e.g. loops surrounding edges**** */
-int bmesh_radial_validate(int radlen, BMLoop *l)
+bool bmesh_radial_validate(int radlen, BMLoop *l)
{
BMLoop *l_iter = l;
int i = 0;
if (bmesh_radial_length(l) != radlen)
- return FALSE;
+ return false;
do {
if (UNLIKELY(!l_iter)) {
BMESH_ASSERT(0);
- return FALSE;
+ return false;
}
if (l_iter->e != l->e)
- return FALSE;
+ return false;
if (l_iter->v != l->e->v1 && l_iter->v != l->e->v2)
- return FALSE;
+ return false;
if (UNLIKELY(i > BM_LOOP_RADIAL_MAX)) {
BMESH_ASSERT(0);
- return FALSE;
+ return false;
}
i++;
} while ((l_iter = l_iter->radial_next) != l);
- return TRUE;
+ return true;
}
/**
@@ -511,7 +509,7 @@ void bmesh_radial_append(BMEdge *e, BMLoop *l)
l->e = e;
}
-int bmesh_radial_face_find(BMEdge *e, BMFace *f)
+bool bmesh_radial_face_find(BMEdge *e, BMFace *f)
{
BMLoop *l_iter;
int i, len;
@@ -519,9 +517,9 @@ int bmesh_radial_face_find(BMEdge *e, BMFace *f)
len = bmesh_radial_length(e->l);
for (i = 0, l_iter = e->l; i < len; i++, l_iter = l_iter->radial_next) {
if (l_iter->f == f)
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/**
@@ -545,7 +543,7 @@ int bmesh_radial_facevert_count(BMLoop *l, BMVert *v)
}
/*****loop cycle functions, e.g. loops surrounding a face**** */
-int bmesh_loop_validate(BMFace *f)
+bool bmesh_loop_validate(BMFace *f)
{
int i;
int len = f->len;
@@ -554,7 +552,7 @@ int bmesh_loop_validate(BMFace *f)
l_first = BM_FACE_FIRST_LOOP(f);
if (l_first == NULL) {
- return FALSE;
+ return false;
}
/* Validate that the face loop cycle is the length specified by f->len */
@@ -562,22 +560,22 @@ int bmesh_loop_validate(BMFace *f)
if ((l_iter->f != f) ||
(l_iter == l_first))
{
- return FALSE;
+ return false;
}
}
if (l_iter != l_first) {
- return FALSE;
+ return false;
}
/* Validate the loop->prev links also form a cycle of length f->len */
for (i = 1, l_iter = l_first->prev; i < len; i++, l_iter = l_iter->prev) {
if (l_iter == l_first) {
- return FALSE;
+ return false;
}
}
if (l_iter != l_first) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h
index b19df4660b8..e67f1e4fb49 100644
--- a/source/blender/bmesh/intern/bmesh_structure.h
+++ b/source/blender/bmesh/intern/bmesh_structure.h
@@ -42,10 +42,10 @@
struct ListBase;
/* LOOP CYCLE MANAGEMENT */
-int bmesh_loop_validate(BMFace *f);
+bool bmesh_loop_validate(BMFace *f);
/* DISK CYCLE MANAGMENT */
-int bmesh_disk_edge_append(BMEdge *e, BMVert *v);
+void bmesh_disk_edge_append(BMEdge *e, BMVert *v);
void bmesh_disk_edge_remove(BMEdge *e, BMVert *v);
BMEdge *bmesh_disk_edge_next(BMEdge *e, BMVert *v);
BMEdge *bmesh_disk_edge_prev(BMEdge *e, BMVert *v);
@@ -60,19 +60,19 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e);
* bmesh_radial_loop_next(BMLoop *l) / prev.
* just use member access l->radial_next, l->radial_prev now */
-int bmesh_radial_face_find(BMEdge *e, BMFace *f);
+bool bmesh_radial_face_find(BMEdge *e, BMFace *f);
int bmesh_radial_facevert_count(BMLoop *l, BMVert *v);
BMLoop *bmesh_radial_faceloop_find_first(BMLoop *l, BMVert *v);
BMLoop *bmesh_radial_faceloop_find_next(BMLoop *l, BMVert *v);
BMLoop *bmesh_radial_faceloop_find_vert(BMFace *f, BMVert *v);
-int bmesh_radial_validate(int radlen, BMLoop *l);
+bool bmesh_radial_validate(int radlen, BMLoop *l);
/* EDGE UTILITIES */
-int bmesh_vert_in_edge(BMEdge *e, BMVert *v);
-int bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e);
-int bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv); /*relink edge*/
+bool bmesh_vert_in_edge(BMEdge *e, BMVert *v);
+bool bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e);
+bool bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv); /* relink edge */
BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v);
BMEdge *bmesh_disk_edge_exists(BMVert *v1, BMVert *v2);
-int bmesh_disk_validate(int len, BMEdge *e, BMVert *v);
+bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v);
#endif /* __BMESH_STRUCTURE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_walkers.h b/source/blender/bmesh/intern/bmesh_walkers.h
index 4f81f38aeb3..8be362b5afa 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.h
+++ b/source/blender/bmesh/intern/bmesh_walkers.h
@@ -100,10 +100,9 @@ void BMW_reset(BMWalker *walker);
* BMFace *f;
*
* BMW_init(&walker, bm, BMW_ISLAND, SOME_OP_FLAG);
- * f = BMW_begin(&walker, some_start_face);
- * for (; f; f = BMW_step(&walker))
- * {
- * //do something with f
+ *
+ * for (f = BMW_begin(&walker, some_start_face); f; f = BMW_step(&walker)) {
+ * // do something with f
* }
* BMW_end(&walker);
*/
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index bb013e6428e..ac6d4089372 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -34,42 +34,42 @@
#include "intern/bmesh_private.h"
#include "intern/bmesh_walkers_private.h"
-static int bmw_mask_check_vert(BMWalker *walker, BMVert *v)
+static bool bmw_mask_check_vert(BMWalker *walker, BMVert *v)
{
if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- return FALSE;
+ return false;
}
else if (walker->mask_vert && !BMO_elem_flag_test(walker->bm, v, walker->mask_vert)) {
- return FALSE;
+ return false;
}
else {
- return TRUE;
+ return true;
}
}
-static int bmw_mask_check_edge(BMWalker *walker, BMEdge *e)
+static bool bmw_mask_check_edge(BMWalker *walker, BMEdge *e)
{
if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- return FALSE;
+ return false;
}
else if (walker->mask_edge && !BMO_elem_flag_test(walker->bm, e, walker->mask_edge)) {
- return FALSE;
+ return false;
}
else {
- return TRUE;
+ return true;
}
}
-static int bmw_mask_check_face(BMWalker *walker, BMFace *f)
+static bool bmw_mask_check_face(BMWalker *walker, BMFace *f)
{
if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- return FALSE;
+ return false;
}
else if (walker->mask_face && !BMO_elem_flag_test(walker->bm, f, walker->mask_face)) {
- return FALSE;
+ return false;
}
else {
- return TRUE;
+ return true;
}
}
@@ -164,7 +164,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
{
BMEdge *curedge, *next = NULL;
BMVert *ov = NULL;
- int restrictpass = 1;
+ bool restrictpass = true;
BMwShellWalker shellWalk = *((BMwShellWalker *)BMW_current_state(walker));
if (!BLI_ghash_haskey(walker->visithash, shellWalk.base)) {
@@ -403,6 +403,11 @@ static void *bmw_IslandWalker_step(BMWalker *walker)
continue;
}
+ /* saves checking BLI_ghash_haskey below (manifold edges theres a 50% chance) */
+ if (f == iwalk->cur) {
+ continue;
+ }
+
if (BLI_ghash_haskey(walker->visithash, f)) {
continue;
}
@@ -442,7 +447,7 @@ static void bmw_LoopWalker_begin(BMWalker *walker, void *data)
lwalk->is_single = (vert_edge_count[0] == 2 && vert_edge_count[1] == 2);
/* could also check that vertex*/
- if ((lwalk->is_boundary == FALSE) &&
+ if ((lwalk->is_boundary == false) &&
(vert_edge_count[0] == 3 || vert_edge_count[1] == 3))
{
BMIter iter;
@@ -543,19 +548,19 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
/* typical loopiong over edges in the middle of a mesh */
/* however, why use 2 here at all? I guess for internal ngon loops it can be useful. Antony R. */
- ((vert_edge_tot == 4 || vert_edge_tot == 2) && owalk.is_boundary == FALSE) ||
+ ((vert_edge_tot == 4 || vert_edge_tot == 2) && owalk.is_boundary == false) ||
/* walk over boundary of faces but stop at corners */
- (owalk.is_boundary == TRUE && owalk.is_single == FALSE && vert_edge_tot > 2) ||
+ (owalk.is_boundary == true && 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 */
- (owalk.is_boundary == TRUE && owalk.is_single == TRUE && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
+ (owalk.is_boundary == true && owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
{
i = 0;
stopi = vert_edge_tot / 2;
while (1) {
- if ((owalk.is_boundary == FALSE) && (i == stopi)) {
+ if ((owalk.is_boundary == false) && (i == stopi)) {
break;
}
@@ -584,7 +589,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
bmw_mask_check_edge(walker, l->e) &&
!BLI_ghash_haskey(walker->visithash, l->e))
{
- if (!(owalk.is_boundary == FALSE && i != stopi)) {
+ if (!(owalk.is_boundary == false && i != stopi)) {
lwalk = BMW_state_add(walker);
lwalk->cur = l->e;
lwalk->lastv = v;
@@ -637,47 +642,47 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
/* Check whether the face loop should includes the face specified
* by the given BMLoop */
-static int bmw_FaceLoopWalker_include_face(BMWalker *walker, BMLoop *l)
+static bool bmw_FaceLoopWalker_include_face(BMWalker *walker, BMLoop *l)
{
/* face must have degree 4 */
if (l->f->len != 4) {
- return FALSE;
+ return false;
}
if (!bmw_mask_check_face(walker, l->f)) {
- return FALSE;
+ return false;
}
/* the face must not have been already visite */
if (BLI_ghash_haskey(walker->visithash, l->f) && BLI_ghash_haskey(walker->secvisithash, l->e)) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/* Check whether the face loop can start from the given edge */
-static int bmw_FaceLoopWalker_edge_begins_loop(BMWalker *walker, BMEdge *e)
+static bool bmw_FaceLoopWalker_edge_begins_loop(BMWalker *walker, BMEdge *e)
{
/* There is no face loop starting from a wire edge */
if (BM_edge_is_wire(e)) {
- return FALSE;
+ return false;
}
/* Don't start a loop from a boundary edge if it cannot
* be extended to cover any faces */
if (BM_edge_is_boundary(e)) {
if (!bmw_FaceLoopWalker_include_face(walker, e->l)) {
- return FALSE;
+ return false;
}
}
/* Don't start a face loop from non-manifold edges */
if (!BM_edge_is_manifold(e)) {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
@@ -692,7 +697,7 @@ static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
lwalk = BMW_state_add(walker);
lwalk->l = e->l;
- lwalk->nocalc = 0;
+ lwalk->no_calc = false;
BLI_ghash_insert(walker->visithash, lwalk->l->f, NULL);
/* rewin */
@@ -703,7 +708,7 @@ static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
lwalk = BMW_state_add(walker);
*lwalk = owalk;
- lwalk->nocalc = 0;
+ lwalk->no_calc = false;
BLI_ghash_free(walker->secvisithash, NULL, NULL);
walker->secvisithash = BLI_ghash_ptr_new("bmesh walkers 3");
@@ -735,7 +740,7 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
l = l->radial_next;
- if (lwalk->nocalc) {
+ if (lwalk->no_calc) {
return f;
}
@@ -753,11 +758,11 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
lwalk->l = l;
if (l->f->len != 4) {
- lwalk->nocalc = 1;
+ lwalk->no_calc = true;
lwalk->l = origl;
}
else {
- lwalk->nocalc = 0;
+ lwalk->no_calc = false;
}
BLI_ghash_insert(walker->secvisithash, l->e, NULL);
@@ -853,7 +858,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
if (!EDGE_CHECK(e)) {
/* walker won't traverse to a non-manifold edge, but may
* be started on one, and should not traverse *away* from
- * a non-manfold edge (non-manifold edges are never in an
+ * a non-manifold edge (non-manifold edges are never in an
* edge ring with manifold edges */
return e;
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers_private.h b/source/blender/bmesh/intern/bmesh_walkers_private.h
index fc563932c3c..09dd4f18d89 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_private.h
+++ b/source/blender/bmesh/intern/bmesh_walkers_private.h
@@ -62,14 +62,14 @@ typedef struct BMwLoopWalker {
BMEdge *cur, *start;
BMVert *lastv, *startv;
BMFace *f_hub;
- short is_boundary; /* boundary looping changes behavior */
- short is_single; /* single means the edge verts are only connected to 1 face */
+ bool is_boundary; /* boundary looping changes behavior */
+ bool is_single; /* single means the edge verts are only connected to 1 face */
} BMwLoopWalker;
typedef struct BMwFaceLoopWalker {
BMwGenericWalker header;
BMLoop *l;
- int nocalc;
+ bool no_calc;
} BMwFaceLoopWalker;
typedef struct BMwEdgeringWalker {
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 126d0f46119..795531d6776 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -34,6 +34,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
{
const float offset = BMO_slot_float_get(op->slots_in, "offset");
const int seg = BMO_slot_int_get(op->slots_in, "segments");
+ const bool vonly = BMO_slot_bool_get(op->slots_in, "vertex_only");
if (offset > 0) {
BMOIter siter;
@@ -42,7 +43,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
/* first flush 'geom' into flags, this makes it possible to check connected data,
* BM_FACE is cleared so we can put newly created faces into a bmesh slot. */
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
BM_elem_flag_enable(v, BM_ELEM_TAG);
@@ -54,7 +55,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
}
}
- BM_mesh_bevel(bm, offset, seg);
+ BM_mesh_bevel(bm, offset, seg, vonly, false, NULL, -1);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index c7cd1e742d8..9a17ebea38d 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -106,7 +106,7 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
}
for (i = 0; i < BLI_array_count(verts_pair); i++) {
- nf = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &nl, NULL, FALSE);
+ nf = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &nl, NULL, false);
f = nf;
if (!nl || !nf) {
@@ -221,7 +221,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
int c = 0, cl1 = 0, cl2 = 0;
/* merge-bridge support */
- const int use_merge = BMO_slot_bool_get(op->slots_in, "use_merge");
+ const bool use_merge = BMO_slot_bool_get(op->slots_in, "use_merge");
const float merge_factor = BMO_slot_float_get(op->slots_in, "merge_factor");
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
@@ -359,6 +359,17 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
/* Last point of loop 2 */
v4 = get_outer_vert(bm, ee2[clamp_index(-1, BLI_array_count(ee2))]);
+ /* ugh, happens when bridging single edges, user could just make a face
+ * but better support it for sake of completeness */
+ if (v1 == v2) {
+ BLI_assert(BLI_array_count(ee1) == 1);
+ v2 = (vv1[0] == v2) ? vv1[1] : vv1[0];
+ }
+ if (v3 == v4) {
+ BLI_assert(BLI_array_count(ee2) == 1);
+ v4 = (vv2[0] == v4) ? vv2[1] : vv2[0];
+ }
+
/* If v1 is a better match for v4 than v3, AND v2 is a better match
* for v3 than v4, the loops are in opposite directions, so reverse
* the order of reads from vv1. We can avoid sqrt for comparison */
@@ -508,7 +519,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
vv2[i2],
vv2[i2next],
vv1[i1next],
- f_example, TRUE);
+ f_example, true);
if (UNLIKELY((f == NULL) || (f->len != 4))) {
fprintf(stderr, "%s: in bridge! (bmesh internal error)\n", __func__);
}
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index aa69806fb37..ae07c2cf0bc 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -87,8 +87,8 @@ BLI_INLINE BMDiskLink *rs_edge_link_get(BMEdge *e, BMVert *v, EdgeData *e_data)
&(((EdgeData *)e_data)->v2_disk_link);
}
-static int rotsys_append_edge(BMEdge *e, BMVert *v,
- EdgeData *edata, VertData *vdata)
+static bool rotsys_append_edge(BMEdge *e, BMVert *v,
+ EdgeData *edata, VertData *vdata)
{
EdgeData *ed = &edata[BM_elem_index_get(e)];
VertData *vd = &vdata[BM_elem_index_get(v)];
@@ -116,7 +116,7 @@ static int rotsys_append_edge(BMEdge *e, BMVert *v,
}
}
- return TRUE;
+ return true;
}
static void UNUSED_FUNCTION(rotsys_remove_edge)(BMEdge *e, BMVert *v,
@@ -578,7 +578,7 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
//rotsys_fill_faces(bm, edata, vdata);
#if 0
- /* create visualizing geometr */
+ /* create visualizing geometry */
BMVert *lastv;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BMVert *v2;
@@ -613,10 +613,10 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
BM_elem_index_set(v2, -1); /* set_dirty! */
//BM_edge_create(bm, cv, v2, NULL, 0);
- BM_vert_select_set(bm, v2, TRUE);
+ BM_vert_select_set(bm, v2, true);
if (lastv) {
e2 = BM_edge_create(bm, lastv, v2, NULL, 0);
- BM_edge_select_set(bm, e2, TRUE);
+ BM_edge_select_set(bm, e2, true);
}
lastv = v2;
@@ -742,7 +742,7 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
BMVert *endv;
EPathNode *node;
int i;
- const int use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
+ const bool use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
@@ -899,10 +899,10 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
BMEdge **edges = NULL;
PathBase *pathbase;
BLI_array_declare(edges);
- int use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
- int use_fill_check = BMO_slot_bool_get(op->slots_in, "use_fill_check");
- const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
- const short use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
+ const bool use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
+ const bool use_fill_check = BMO_slot_bool_get(op->slots_in, "use_fill_check");
+ const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
+ const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
int i, j, group = 0;
unsigned int winding[2]; /* accumulte winding directions for each edge which has a face */
BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
@@ -1047,9 +1047,9 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
v2 = verts[0];
}
- if ((use_fill_check == FALSE) ||
+ if ((use_fill_check == false) ||
/* fairly expensive check - see if there are already faces filling this area */
- (BM_face_exists_multi_edge(edges, i) == FALSE))
+ (BM_face_exists_multi_edge(edges, i) == false))
{
f = BM_face_create_ngon(bm, v1, v2, edges, i, BM_CREATE_NO_DOUBLE);
if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
@@ -1287,7 +1287,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
BMFace *f;
int totv = 0, tote = 0, totf = 0, amount;
const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
- const short use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
+ const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
/* count number of each element type we were passe */
BMO_ITER (h, &oiter, op->slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE) {
@@ -1321,7 +1321,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (totf == 0 && totv >= 4 && totv == tote + 2) {
/* find a free standing vertex and 2 endpoint verts */
BMVert *v_free = NULL, *v_a = NULL, *v_b = NULL;
- int ok = TRUE;
+ bool ok = true;
BMO_ITER (v, &oiter, op->slots_in, "geom", BM_VERT) {
@@ -1339,26 +1339,26 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (tot_edges == 0) {
/* only accept 1 free vert */
if (v_free == NULL) v_free = v;
- else ok = FALSE; /* only ever want one of these */
+ else ok = false; /* only ever want one of these */
}
else if (tot_edges == 1) {
if (v_a == NULL) v_a = v;
else if (v_b == NULL) v_b = v;
- else ok = FALSE; /* only ever want 2 of these */
+ else ok = false; /* only ever want 2 of these */
}
else if (tot_edges == 2) {
/* do nothing, regular case */
}
else {
- ok = FALSE; /* if a vertex has 3+ edge users then cancel - this is only simple cases */
+ ok = false; /* if a vertex has 3+ edge users then cancel - this is only simple cases */
}
- if (ok == FALSE) {
+ if (ok == false) {
break;
}
}
- if (ok == TRUE && v_free && v_a && v_b) {
+ if (ok == true && v_free && v_a && v_b) {
e = BM_edge_create(bm, v_free, v_a, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
@@ -1377,7 +1377,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
BMO_op_initf(bm, &op2, op->flag,
"edgenet_fill edges=%fe use_fill_check=%b mat_nr=%i use_smooth=%b",
- ELE_NEW, TRUE, mat_nr, use_smooth);
+ ELE_NEW, true, mat_nr, use_smooth);
BMO_op_exec(bm, &op2);
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 7c3bcd60daa..47b2497816f 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -41,7 +41,7 @@
#define VERT_MARK 1
-static int UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
+static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
{
BMWalker regwalker;
BMIter liter2;
@@ -55,23 +55,21 @@ static int UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
BMW_FLAG_NOP,
BMW_NIL_LAY);
- f2 = BMW_begin(&regwalker, f);
- for ( ; f2; f2 = BMW_step(&regwalker)) {
- l2 = BM_iter_new(&liter2, bm, BM_LOOPS_OF_FACE, f2);
- for ( ; l2; l2 = BM_iter_step(&liter2)) {
+ for (f2 = BMW_begin(&regwalker, f); f2; f2 = BMW_step(&regwalker)) {
+ BM_ITER_ELEM (l2, &liter2, f2, BM_LOOPS_OF_FACE) {
l3 = l2->radial_next;
if (BMO_elem_flag_test(bm, l3->f, FACE_MARK) !=
BMO_elem_flag_test(bm, l2->f, FACE_MARK))
{
if (!BMO_elem_flag_test(bm, l2->e, EDGE_MARK)) {
- return FALSE;
+ return false;
}
}
}
}
BMW_end(&regwalker);
- return TRUE;
+ return true;
}
void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
@@ -85,7 +83,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BMWalker regwalker;
int i;
- int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
+ const bool use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
if (use_verts) {
/* tag verts that start out with only 2 edges,
@@ -115,8 +113,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BMW_FLAG_NOP, /* no need to check BMW_FLAG_TEST_HIDDEN, faces are already marked by the bmo */
BMW_NIL_LAY);
- f2 = BMW_begin(&regwalker, f);
- for ( ; f2; f2 = BMW_step(&regwalker)) {
+ for (f2 = BMW_begin(&regwalker, f); f2; f2 = BMW_step(&regwalker)) {
BLI_array_append(faces, f2);
}
BMW_end(&regwalker);
@@ -150,7 +147,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
while (faces[tot])
tot++;
- f = BM_faces_join(bm, faces, tot, TRUE);
+ f = BM_faces_join(bm, faces, tot, true);
if (!f) {
BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED,
"Could not create merged face");
@@ -174,7 +171,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
if (BM_vert_edge_count(v) == 2) {
- BM_vert_collapse_edge(bm, v->e, v, TRUE);
+ BM_vert_collapse_edge(bm, v->e, v, true);
}
}
}
@@ -215,7 +212,7 @@ void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later reference a removed edge */
- BM_faces_join_pair(bm, fa, fb, e, TRUE);
+ BM_faces_join_pair(bm, fa, fb, e, true);
}
}
@@ -228,7 +225,7 @@ void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
/* clean up extreneous 2-valence vertice */
for (i = 0; i < BLI_array_count(verts); i++) {
if (verts[i]->e) {
- BM_vert_collapse_edge(bm, verts[i]->e, verts[i], TRUE);
+ BM_vert_collapse_edge(bm, verts[i]->e, verts[i], true);
}
}
@@ -254,7 +251,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
BMIter viter;
BMVert *v;
- int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
+ const bool use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
if (use_verts) {
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
@@ -271,7 +268,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later reference a removed edge */
- BM_faces_join_pair(bm, fa, fb, e, TRUE);
+ BM_faces_join_pair(bm, fa, fb, e, true);
}
}
@@ -279,20 +276,20 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
if (BM_vert_edge_count(v) == 2) {
- BM_vert_collapse_edge(bm, v->e, v, TRUE);
+ BM_vert_collapse_edge(bm, v->e, v, true);
}
}
}
}
}
-static int test_extra_verts(BMesh *bm, BMVert *v)
+static bool test_extra_verts(BMesh *bm, BMVert *v)
{
BMIter iter, liter, iter2, iter3;
BMFace *f, *f2;
BMLoop *l;
BMEdge *e;
- int found;
+ bool found;
/* test faces around verts for verts that would be wrongly killed
* by dissolve faces. */
@@ -305,31 +302,31 @@ static int test_extra_verts(BMesh *bm, BMVert *v)
* then dissolve faces won't destroy it.
* also if it forms a boundary with one
* of the face region */
- found = FALSE;
+ found = false;
e = BM_iter_new(&iter2, bm, BM_EDGES_OF_VERT, l->v);
for ( ; e; e = BM_iter_step(&iter2)) {
if (BM_edge_is_boundary(e)) {
- found = TRUE;
+ found = true;
}
f2 = BM_iter_new(&iter3, bm, BM_FACES_OF_EDGE, e);
for ( ; f2; f2 = BM_iter_step(&iter3)) {
if (!BMO_elem_flag_test(bm, f2, FACE_MARK)) {
- found = TRUE;
+ found = true;
break;
}
}
- if (found == TRUE) {
+ if (found == true) {
break;
}
}
- if (found == FALSE) {
- return FALSE;
+ if (found == false) {
+ return false;
}
}
}
}
- return TRUE;
+ return true;
}
void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
{
@@ -349,9 +346,9 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
/* previously the faces were joined, but collapsing between 2 edges
* gives some advantage/difference in using vertex-dissolve over edge-dissolve */
#if 0
- BM_vert_collapse_faces(bm, v->e, v, 1.0f, TRUE, TRUE);
+ BM_vert_collapse_faces(bm, v->e, v, 1.0f, true, true);
#else
- BM_vert_collapse_edge(bm, v->e, v, TRUE);
+ BM_vert_collapse_edge(bm, v->e, v, true);
#endif
continue;
@@ -483,7 +480,7 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
BMOpSlot *vinput = BMO_slot_get(op->slots_in, "verts");
const float angle_max = (float)M_PI / 2.0f;
const float angle_limit = min_ff(angle_max, BMO_slot_float_get(op->slots_in, "angle_limit"));
- const int do_dissolve_boundaries = BMO_slot_bool_get(op->slots_in, "use_dissolve_boundaries");
+ const bool do_dissolve_boundaries = BMO_slot_bool_get(op->slots_in, "use_dissolve_boundaries");
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries,
(BMVert **)BMO_SLOT_AS_BUFFER(vinput), vinput->len,
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index 9a58d7acfb9..1448129ccde 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -213,13 +213,13 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
!BMO_elem_flag_test(bm_src, v, DUPE_DONE))
{
BMIter iter;
- int isolated = 1;
+ bool isolated = true;
v2 = copy_vertex(bm_src, v, bm_dst, vhash);
BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
if (BMO_elem_flag_test(bm_src, f, DUPE_INPUT)) {
- isolated = 0;
+ isolated = false;
break;
}
}
@@ -227,7 +227,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
if (isolated) {
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
if (BMO_elem_flag_test(bm_src, e, DUPE_INPUT)) {
- isolated = 0;
+ isolated = false;
break;
}
}
@@ -386,7 +386,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
BMOperator *splitop = op;
BMOperator dupeop;
BMOperator delop;
- const short use_only_faces = BMO_slot_bool_get(op->slots_in, "use_only_faces");
+ const bool use_only_faces = BMO_slot_bool_get(op->slots_in, "use_only_faces");
/* initialize our sub-operator */
BMO_op_init(bm, &dupeop, op->flag, "duplicate");
@@ -483,7 +483,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
{
BMOperator dupop, extop;
float cent[3], dvec[3];
- float axis[3] = {0.0f, 0.0f, 1.0f};
+ float axis[3];
float rmat[3][3];
float phi;
int steps, do_dupli, a, usedvec;
diff --git a/source/blender/bmesh/operators/bmo_edgesplit.c b/source/blender/bmesh/operators/bmo_edgesplit.c
index 9e9e4b8c962..378f790ef32 100644
--- a/source/blender/bmesh/operators/bmo_edgesplit.c
+++ b/source/blender/bmesh/operators/bmo_edgesplit.c
@@ -22,152 +22,32 @@
/** \file blender/bmesh/operators/bmo_edgesplit.c
* \ingroup bmesh
+ *
+ * Just a wrapper around #BM_mesh_edgesplit
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "bmesh.h"
+#include "tools/bmesh_edgesplit.h"
#include "intern/bmesh_operators_private.h" /* own include */
-enum {
- EDGE_SEAM = 1
-};
-
-enum {
- VERT_SEAM = 2
-};
-
-/**
- * Remove the EDGE_SEAM flag for edges we cant split
- *
- * un-tag edges not connected to other tagged edges,
- * unless they are on a boundary
- */
-static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op)
-{
- BMOIter siter;
- BMIter iter;
- BMEdge *e;
-
- unsigned char *vtouch;
- unsigned char *vt;
-
- BM_mesh_elem_index_ensure(bm, BM_VERT);
-
- vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__);
-
- /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-
- /* unrelated to flag assignment in this function - since this is the
- * only place we loop over all edges, disable tag */
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
-
- if (e->l == NULL) {
- BMO_elem_flag_disable(bm, e, EDGE_SEAM);
- }
- else if (BM_edge_is_boundary(e)) {
- vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
- vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
-
- /* while the boundary verts need to be tagged,
- * the edge its self can't be split */
- BMO_elem_flag_disable(bm, e, EDGE_SEAM);
- }
- }
-
- /* single marked edges unconnected to any other marked edges
- * are illegal, go through and unmark them */
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- /* lame, but we don't want the count to exceed 255,
- * so just count to 2, its all we need */
- unsigned char *vt;
- vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
- vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
- }
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
- vtouch[BM_elem_index_get(e->v2)] == 1)
- {
- BMO_elem_flag_disable(bm, e, EDGE_SEAM);
- }
- }
-
- MEM_freeN(vtouch);
-}
/* keep this operator fast, its used in a modifier */
void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
{
- BMOIter siter;
- BMEdge *e;
- const int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
+ const bool use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_SEAM);
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "edges", BM_EDGE, BM_ELEM_TAG, false);
if (use_verts) {
/* this slows down the operation but its ok because the modifier doesn't use */
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_SEAM);
-
- /* prevent one edge having both verts unflagged
- * we could alternately disable these edges, either way its a corner case.
- *
- * This is needed so we don't split off the edge but then none of its verts which
- * would leave a duplicate edge.
- */
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (UNLIKELY((BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE &&
- (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE))))
- {
- BMO_elem_flag_enable(bm, e->v1, VERT_SEAM);
- BMO_elem_flag_enable(bm, e->v2, VERT_SEAM);
- }
- }
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "verts", BM_VERT, BM_ELEM_TAG, false);
}
- bm_edgesplit_validate_seams(bm, op);
-
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
- /* this flag gets copied so we can be sure duplicate edges get it too (important) */
- BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
-
- /* keep splitting until each loop has its own edge */
- do {
- bmesh_edge_separate(bm, e, e->l);
- } while (!BM_edge_is_boundary(e));
-
- BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
- BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
- }
- }
-
- if (use_verts) {
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE) {
- BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
- }
- if (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE) {
- BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
- }
- }
- }
-
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
- BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
- bmesh_vert_separate(bm, e->v1, NULL, NULL);
- }
- if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) {
- BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
- bmesh_vert_separate(bm, e->v2, NULL, NULL);
- }
- }
- }
+ /* this is where everything happens */
+ BM_mesh_edgesplit(bm, use_verts, true);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 065a1b57737..4fde6150f05 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -51,28 +51,35 @@ enum {
void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
{
+ BMVert **verts = NULL;
+ BLI_array_declare(verts);
+ BMEdge **edges = NULL;
+ BLI_array_declare(edges);
+
BMOIter siter;
BMIter liter, liter2;
BMFace *f, *f2, *f3;
BMLoop *l, *l2, *l3, *l4, *l_tmp;
- BMEdge **edges = NULL, *e, *laste;
+ BMEdge *e, *laste;
BMVert *v, *lastv, *firstv;
- BLI_array_declare(edges);
int i;
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
+ BLI_array_empty(verts);
BLI_array_empty(edges);
+ BLI_array_grow_items(verts, f->len);
BLI_array_grow_items(edges, f->len);
i = 0;
firstv = lastv = NULL;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
v = BM_vert_create(bm, l->v->co, l->v, 0);
-
/* skip on the first iteration */
if (lastv) {
e = BM_edge_create(bm, lastv, v, l->e, 0);
- edges[i++] = e;
+ edges[i] = e;
+ verts[i] = lastv;
+ i++;
}
lastv = v;
@@ -82,11 +89,13 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
/* this fits in the array because we skip one in the loop above */
e = BM_edge_create(bm, v, firstv, laste, 0);
- edges[i++] = e;
+ edges[i] = e;
+ verts[i] = lastv;
+ i++;
BMO_elem_flag_enable(bm, f, EXT_DEL);
- f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, 0);
+ f2 = BM_face_create(bm, verts, edges, f->len, 0);
if (UNLIKELY(f2 == NULL)) {
BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed: could not create face");
BLI_array_free(edges);
@@ -103,7 +112,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
l3 = l->next;
l4 = l2->next;
- f3 = BM_face_create_quad_tri(bm, l3->v, l4->v, l2->v, l->v, f, FALSE);
+ f3 = BM_face_create_quad_tri(bm, l3->v, l4->v, l2->v, l->v, f, false);
/* XXX, no error check here, why? - Campbell */
l_tmp = BM_FACE_FIRST_LOOP(f3);
@@ -117,6 +126,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
}
}
+ BLI_array_free(verts);
BLI_array_free(edges);
BMO_op_callf(bm, op->flag,
@@ -215,7 +225,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
f_verts[3] = e_new->v2;
}
/* not sure what to do about example face, pass NULL for now */
- f = BM_face_create_quad_tri_v(bm, f_verts, 4, NULL, FALSE);
+ f = BM_face_create_quad_tri_v(bm, f_verts, 4, NULL, false);
bm_extrude_copy_face_loop_attributes(bm, f);
if (BMO_elem_flag_test(bm, e, EXT_INPUT))
@@ -238,7 +248,7 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMVert *v, *dupev;
BMEdge *e;
- const int has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN);
+ const bool has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN);
for (v = BMO_iter_new(&siter, op->slots_in, "verts", BM_VERT); v; v = BMO_iter_step(&siter)) {
dupev = BM_vert_create(bm, v->co, v, 0);
@@ -263,7 +273,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMEdge *e, *e_new;
BMVert *v, *v2;
BMFace *f;
- int found, fwd, delorig = FALSE;
+ bool found, fwd, delorig = false;
BMOpSlot *slot_facemap_out;
BMOpSlot *slot_edges_exclude;
@@ -283,20 +293,20 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
continue;
}
- found = FALSE; /* found a face that isn't input? */
+ found = false; /* found a face that isn't input? */
edge_face_tot = 0; /* edge/face count */
BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
if (!BMO_elem_flag_test(bm, f, EXT_INPUT)) {
- found = TRUE;
- delorig = TRUE;
+ found = true;
+ delorig = true;
break;
}
edge_face_tot++;
}
- if ((edge_face_tot > 1) && (found == FALSE)) {
+ if ((edge_face_tot > 1) && (found == false)) {
/* edge has a face user, that face isn't extrude input */
BMO_elem_flag_enable(bm, e, EXT_DEL);
}
@@ -305,27 +315,29 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
/* calculate verts to delete */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- found = FALSE;
+ if (v->e) { /* only deal with verts attached to geometry [#33651] */
+ found = false;
- BM_ITER_ELEM (e, &viter, v, BM_EDGES_OF_VERT) {
- if (!BMO_elem_flag_test(bm, e, EXT_INPUT) || !BMO_elem_flag_test(bm, e, EXT_DEL)) {
- found = TRUE;
- break;
+ BM_ITER_ELEM (e, &viter, v, BM_EDGES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, e, EXT_INPUT) || !BMO_elem_flag_test(bm, e, EXT_DEL)) {
+ found = true;
+ break;
+ }
}
- }
- /* avoid an extra loop */
- if (found == TRUE) {
- BM_ITER_ELEM (f, &viter, v, BM_FACES_OF_VERT) {
- if (!BMO_elem_flag_test(bm, f, EXT_INPUT)) {
- found = TRUE;
- break;
+ /* avoid an extra loop */
+ if (found == true) {
+ BM_ITER_ELEM (f, &viter, v, BM_FACES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, f, EXT_INPUT)) {
+ found = true;
+ break;
+ }
}
}
- }
- if (found == FALSE) {
- BMO_elem_flag_enable(bm, v, EXT_DEL);
+ if (found == false) {
+ BMO_elem_flag_enable(bm, v, EXT_DEL);
+ }
}
}
@@ -335,7 +347,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
}
- if (delorig == TRUE) {
+ if (delorig == true) {
BMO_op_initf(bm, &delop, op->flag,
"delete geom=%fvef context=%i",
EXT_DEL, DEL_ONLYTAGGED);
@@ -423,7 +435,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
/* not sure what to do about example face, pass NULL for now */
- f = BM_face_create_quad_tri_v(bm, f_verts, 4, NULL, FALSE);
+ f = BM_face_create_quad_tri_v(bm, f_verts, 4, NULL, false);
bm_extrude_copy_face_loop_attributes(bm, f);
}
@@ -600,39 +612,31 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
float *vert_accum = vert_angles + bm->totvert;
int i, index;
- /* array for passing verts to angle_poly_v3 */
- float **verts = NULL;
- BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
- /* array for receiving angles from angle_poly_v3 */
- float *face_angles = NULL;
- BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE);
-
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (!BMO_elem_flag_test(bm, f, FACE_MARK)) {
- continue;
- }
+ if (BMO_elem_flag_test(bm, f, FACE_MARK)) {
- BLI_array_grow_items(verts, f->len);
- BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) {
- verts[i] = l->v->co;
- }
+ /* array for passing verts to angle_poly_v3 */
+ float *face_angles = BLI_array_alloca(face_angles, f->len);
+ /* array for receiving angles from angle_poly_v3 */
+ float **verts = BLI_array_alloca(verts, f->len);
+
+ BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) {
+ verts[i] = l->v->co;
+ }
- BLI_array_grow_items(face_angles, f->len);
- angle_poly_v3(face_angles, (const float **)verts, f->len);
+ angle_poly_v3(face_angles, (const float **)verts, f->len);
- i = 0;
- BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) {
- v = l->v;
- index = BM_elem_index_get(v);
- vert_accum[index] += face_angles[i];
- vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i];
- i++;
+ i = 0;
+ BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) {
+ v = l->v;
+ index = BM_elem_index_get(v);
+ vert_accum[index] += face_angles[i];
+ vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i];
+ i++;
+ }
}
-
- BLI_array_empty(verts);
- BLI_array_empty(face_angles);
}
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -643,9 +647,6 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
}
MEM_freeN(vert_angles);
-
- BLI_array_free(verts);
- BLI_array_free(face_angles);
}
void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op)
@@ -664,7 +665,7 @@ void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op)
BMO_op_finish(bm, &reverseop);
/* Extrude the region */
- BMO_op_initf(bm, &extrudeop, op->flag, "extrude_face_region use_keep_orig=%b", TRUE);
+ BMO_op_initf(bm, &extrudeop, op->flag, "extrude_face_region use_keep_orig=%b", true);
BMO_slot_copy(op, slots_in, "geom",
&extrudeop, slots_in, "geom");
BMO_op_exec(bm, &extrudeop);
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index e2da4f4f89c..5d8689b9da6 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -136,12 +136,12 @@ static void hull_output_triangles(BMesh *bm, GHash *hull_triangles)
}
/* Create new hull face */
- f = BM_face_create_quad_tri_v(bm, t->v, 3, example, TRUE);
+ f = BM_face_create_quad_tri_v(bm, t->v, 3, example, true);
BM_face_copy_shared(bm, f);
}
/* Mark face for 'geom.out' slot and select */
BMO_elem_flag_enable(bm, f, HULL_FLAG_OUTPUT_GEOM);
- BM_face_select_set(bm, f, TRUE);
+ BM_face_select_set(bm, f, true);
/* Mark edges for 'geom.out' slot */
for (i = 0; i < 3; i++) {
@@ -200,7 +200,7 @@ static int hull_final_edges_lookup(HullFinalEdges *final_edges,
adj = BLI_ghash_lookup(final_edges->edges, v1);
if (!adj)
- return FALSE;
+ return false;
return !!final_edges_find_link(adj, v2);
}
@@ -268,17 +268,17 @@ static void hull_remove_overlapping(BMesh *bm, GHash *hull_triangles,
HullTriangle *t = BLI_ghashIterator_getKey(&hull_iter);
BMIter bm_iter1, bm_iter2;
BMFace *f;
- int f_on_hull;
+ bool f_on_hull;
BM_ITER_ELEM (f, &bm_iter1, t->v[0], BM_FACES_OF_VERT) {
BMEdge *e;
/* Check that all the face's edges are on the hull,
* otherwise can't reuse it */
- f_on_hull = TRUE;
+ f_on_hull = true;
BM_ITER_ELEM (e, &bm_iter2, f, BM_EDGES_OF_FACE) {
if (!hull_final_edges_lookup(final_edges, e->v1, e->v2)) {
- f_on_hull = FALSE;
+ f_on_hull = false;
break;
}
}
@@ -288,7 +288,7 @@ static void hull_remove_overlapping(BMesh *bm, GHash *hull_triangles,
if (BM_vert_in_face(f, t->v[1]) &&
BM_vert_in_face(f, t->v[2]) && f_on_hull)
{
- t->skip = TRUE;
+ t->skip = true;
BMO_elem_flag_disable(bm, f, HULL_FLAG_INTERIOR_ELE);
BMO_elem_flag_enable(bm, f, HULL_FLAG_HOLE);
}
@@ -330,18 +330,18 @@ static void hull_tag_unused(BMesh *bm, BMOperator *op)
* input set */
BMO_ITER (v, &oiter, op->slots_in, "input", BM_VERT) {
if (BMO_elem_flag_test(bm, v, HULL_FLAG_INTERIOR_ELE)) {
- int del = TRUE;
+ bool del = true;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
if (!BMO_elem_flag_test(bm, e, HULL_FLAG_INPUT)) {
- del = FALSE;
+ del = false;
break;
}
}
BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
if (!BMO_elem_flag_test(bm, f, HULL_FLAG_INPUT)) {
- del = FALSE;
+ del = false;
break;
}
}
@@ -353,11 +353,11 @@ static void hull_tag_unused(BMesh *bm, BMOperator *op)
BMO_ITER (e, &oiter, op->slots_in, "input", BM_EDGE) {
if (BMO_elem_flag_test(bm, e, HULL_FLAG_INTERIOR_ELE)) {
- int del = TRUE;
+ bool del = true;
BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
if (!BMO_elem_flag_test(bm, f, HULL_FLAG_INPUT)) {
- del = FALSE;
+ del = false;
break;
}
}
@@ -396,13 +396,13 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
/* Mark edges too if all adjacent faces are holes and the edge is
* not already isolated */
BMO_ITER (e, &oiter, op->slots_in, "input", BM_EDGE) {
- int hole = TRUE;
- int any_faces = FALSE;
+ bool hole = true;
+ bool any_faces = false;
BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
- any_faces = TRUE;
+ any_faces = true;
if (!BMO_elem_flag_test(bm, f, HULL_FLAG_HOLE)) {
- hole = FALSE;
+ hole = false;
break;
}
}
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index cef1181f63b..ef99dae5ac9 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -92,13 +92,13 @@ static BMLoop *bm_edge_is_mixed_face_tag(BMLoop *l)
void bmo_inset_exec(BMesh *bm, BMOperator *op)
{
- const int use_outset = BMO_slot_bool_get(op->slots_in, "use_outset");
- const int use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary") && (use_outset == FALSE);
- const int use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
- const int use_even_boundry = use_even_offset; /* could make own option */
- const int use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
- const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
- const float depth = BMO_slot_float_get(op->slots_in, "depth");
+ const bool use_outset = BMO_slot_bool_get(op->slots_in, "use_outset");
+ const bool use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary") && (use_outset == false);
+ const bool use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
+ const bool use_even_boundry = use_even_offset; /* could make own option */
+ const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
+ const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
+ const float depth = BMO_slot_float_get(op->slots_in, "depth");
int edge_info_len = 0;
@@ -111,13 +111,13 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
BMFace *f;
int i, j, k;
- if (use_outset == FALSE) {
- BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
- BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
+ if (use_outset == false) {
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
}
else {
- BM_mesh_elem_hflag_enable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
- BMO_slot_buffer_hflag_disable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_enable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+ BMO_slot_buffer_hflag_disable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
}
/* first count all inset edges we will split */
@@ -411,11 +411,11 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
/* this saves expensive/slow glue check for common cases */
if (r_vout_len > 2) {
- int ok = TRUE;
+ bool ok = true;
/* last step, NULL this vertex if has a tagged face */
BM_ITER_ELEM (f, &iter, v_split, BM_FACES_OF_VERT) {
if (BM_elem_flag_test(f, BM_ELEM_TAG)) {
- ok = FALSE;
+ ok = false;
break;
}
}
@@ -471,7 +471,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
#endif
/* no need to check doubles, we KNOW there won't be any */
/* yes - reverse face is correct in this case */
- f = BM_face_create_quad_tri_v(bm, varr, j, es->l->f, FALSE);
+ f = BM_face_create_quad_tri_v(bm, varr, j, es->l->f, false);
BMO_elem_flag_enable(bm, f, ELE_NEW);
/* copy for loop data, otherwise UV's and vcols are no good.
@@ -548,7 +548,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
/* done correcting edge verts normals */
/* untag verts */
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
/* tag face verts */
BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 1e18a83a0a0..e052968a6a0 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -105,7 +105,7 @@ static float measure_facepair(BMVert *v1, BMVert *v2,
#define T2QUV_LIMIT 0.005f
#define T2QCOL_LIMIT 3
-static int bm_edge_faces_cmp(BMesh *bm, BMEdge *e, const int do_uv, const int do_tf, const int do_vcol)
+static bool bm_edge_faces_cmp(BMesh *bm, BMEdge *e, const bool do_uv, const bool do_tf, const bool do_vcol)
{
/* first get loops */
BMLoop *l[4];
@@ -138,7 +138,7 @@ static int bm_edge_faces_cmp(BMesh *bm, BMEdge *e, const int do_uv, const int do
if (luv[0] && (!compare_v2v2(luv[0]->uv, luv[2]->uv, T2QUV_LIMIT) ||
!compare_v2v2(luv[1]->uv, luv[3]->uv, T2QUV_LIMIT)))
{
- return FALSE;
+ return false;
}
}
@@ -149,7 +149,7 @@ static int bm_edge_faces_cmp(BMesh *bm, BMEdge *e, const int do_uv, const int do
};
if (tp[0] && (tp[0]->tpage != tp[1]->tpage)) {
- return FALSE;
+ return false;
}
}
@@ -166,12 +166,12 @@ static int bm_edge_faces_cmp(BMesh *bm, BMEdge *e, const int do_uv, const int do
if (!compare_rgb_uchar((unsigned char *)&lcol[0]->r, (unsigned char *)&lcol[2]->r, T2QCOL_LIMIT) ||
!compare_rgb_uchar((unsigned char *)&lcol[1]->r, (unsigned char *)&lcol[3]->r, T2QCOL_LIMIT))
{
- return FALSE;
+ return false;
}
}
}
- return TRUE;
+ return true;
}
typedef struct JoinEdge {
@@ -197,6 +197,13 @@ static int fplcmp(const void *v1, const void *v2)
void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
{
+ const bool do_sharp = BMO_slot_bool_get(op->slots_in, "cmp_sharp");
+ const bool do_uv = BMO_slot_bool_get(op->slots_in, "cmp_uvs");
+ const bool do_tf = do_uv; /* texture face, make make its own option eventually */
+ const bool do_vcol = BMO_slot_bool_get(op->slots_in, "cmp_vcols");
+ const bool do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials");
+ const float limit = BMO_slot_float_get(op->slots_in, "limit");
+
BMIter iter, liter;
BMOIter siter;
BMFace *f;
@@ -204,12 +211,6 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
BLI_array_declare(jedges);
JoinEdge *jedges = NULL;
- int do_sharp = BMO_slot_bool_get(op->slots_in, "cmp_sharp");
- int do_uv = BMO_slot_bool_get(op->slots_in, "cmp_uvs");
- int do_tf = do_uv; /* texture face, make make its own option eventually */
- int do_vcol = BMO_slot_bool_get(op->slots_in, "cmp_vcols");
- int do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials");
- float limit = BMO_slot_float_get(op->slots_in, "limit");
int i, totedge;
/* flag all edges of all input face */
@@ -265,7 +266,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
if (do_mat && f1->mat_nr != f2->mat_nr)
continue;
- if ((do_uv || do_tf || do_vcol) && (bm_edge_faces_cmp(bm, e, do_uv, do_tf, do_vcol) == FALSE))
+ if ((do_uv || do_tf || do_vcol) && (bm_edge_faces_cmp(bm, e, do_uv, do_tf, do_vcol) == false))
continue;
measure = measure_facepair(v1, v2, v3, v4, limit);
@@ -308,7 +309,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
BM_edge_face_pair(e, &f1, &f2); /* checked above */
- BM_faces_join_pair(bm, f1, f2, e, TRUE);
+ BM_faces_join_pair(bm, f1, f2, e, true);
}
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
@@ -331,18 +332,18 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
}
}
- /* if l isn't NULL, we broke out of the loo */
+ /* if l isn't NULL, we broke out of the loop */
if (l) {
break;
}
}
- /* if i isn't 2, we broke out of that loo */
+ /* if i isn't 2, we broke out of that loop */
if (i != 2) {
continue;
}
- BM_faces_join_pair(bm, f1, f2, e, TRUE);
+ BM_faces_join_pair(bm, f1, f2, e, true);
}
}
diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c
index 4b897a24c8a..0976c4cdfbb 100644
--- a/source/blender/bmesh/operators/bmo_mesh_conv.c
+++ b/source/blender/bmesh/operators/bmo_mesh_conv.c
@@ -36,6 +36,9 @@
#include "DNA_key_types.h"
#include "DNA_modifier_types.h"
+#include "BLI_math.h"
+#include "BLI_array.h"
+
#include "BKE_mesh.h"
#include "BLI_listbase.h"
#include "BKE_global.h"
@@ -43,9 +46,6 @@
#include "BKE_main.h"
#include "BKE_customdata.h"
-#include "BLI_math.h"
-#include "BLI_array.h"
-
#include "bmesh.h"
#include "intern/bmesh_private.h"
@@ -53,9 +53,9 @@
void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op)
{
- Object *ob = BMO_slot_ptr_get(op->slots_in, "object");
- Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
- int set_key = BMO_slot_bool_get(op->slots_in, "use_shapekey");
+ Object *ob = BMO_slot_ptr_get(op->slots_in, "object");
+ Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
+ bool set_key = BMO_slot_bool_get(op->slots_in, "use_shapekey");
BM_mesh_bm_from_me(bm, me, set_key, ob->shapenr);
@@ -72,14 +72,14 @@ void bmo_object_load_bmesh_exec(BMesh *bm, BMOperator *op)
BMO_op_callf(bm, op->flag,
"bmesh_to_mesh mesh=%p object=%p skip_tessface=%b",
- me, ob, TRUE);
+ me, ob, true);
}
void bmo_bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
{
Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
/* Object *ob = BMO_slot_ptr_get(op, "object"); */
- int dotess = !BMO_slot_bool_get(op->slots_in, "skip_tessface");
+ const bool dotess = !BMO_slot_bool_get(op->slots_in, "skip_tessface");
BM_mesh_bm_to_me(bm, me, dotess);
}
diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c
index 61b061dd21f..48b2f76665c 100644
--- a/source/blender/bmesh/operators/bmo_mirror.c
+++ b/source/blender/bmesh/operators/bmo_mirror.c
@@ -53,8 +53,8 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
float dist = BMO_slot_float_get(op->slots_in, "merge_dist");
int i, ototvert /*, ototedge */;
int axis = BMO_slot_int_get(op->slots_in, "axis");
- int mirroru = BMO_slot_bool_get(op->slots_in, "mirror_u");
- int mirrorv = BMO_slot_bool_get(op->slots_in, "mirror_v");
+ bool mirror_u = BMO_slot_bool_get(op->slots_in, "mirror_u");
+ bool mirror_v = BMO_slot_bool_get(op->slots_in, "mirror_v");
BMOpSlot *slot_targetmap;
ototvert = bm->totvert;
@@ -97,7 +97,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
v = BM_iter_step(&iter);
}
- if (mirroru || mirrorv) {
+ if (mirror_u || mirror_v) {
BMFace *f;
BMLoop *l;
MLoopUV *luv;
@@ -109,9 +109,9 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
totlayer = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
for (i = 0; i < totlayer; i++) {
luv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
- if (mirroru)
+ if (mirror_u)
luv->uv[0] = 1.0f - luv->uv[0];
- if (mirrorv)
+ if (mirror_v)
luv->uv[1] = 1.0f - luv->uv[1];
}
}
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index c582f710f43..011002718d3 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -420,7 +420,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
v2 = eva[icoface[a][1]];
v3 = eva[icoface[a][2]];
- eftemp = BM_face_create_quad_tri(bm, v1, v2, v3, NULL, NULL, FALSE);
+ eftemp = BM_face_create_quad_tri(bm, v1, v2, v3, NULL, NULL, false);
BM_ITER_ELEM (l, &liter, eftemp, BM_LOOPS_OF_FACE) {
BMO_elem_flag_enable(bm, l->e, EDGE_MARK);
@@ -438,7 +438,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
"cuts=%i "
"use_grid_fill=%b use_sphere=%b",
EDGE_MARK, dia, (1 << (subdiv - 1)) - 1,
- TRUE, TRUE);
+ true, true);
BMO_op_exec(bm, &bmop);
BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK);
@@ -488,14 +488,14 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
tv[monkeyf[i][1] + i - monkeyo],
tv[monkeyf[i][2] + i - monkeyo],
(monkeyf[i][3] != monkeyf[i][2]) ? tv[monkeyf[i][3] + i - monkeyo] : NULL,
- NULL, FALSE);
+ NULL, false);
BM_face_create_quad_tri(bm,
tv[monkeynv + monkeyf[i][2] + i - monkeyo],
tv[monkeynv + monkeyf[i][1] + i - monkeyo],
tv[monkeynv + monkeyf[i][0] + i - monkeyo],
(monkeyf[i][3] != monkeyf[i][2]) ? tv[monkeynv + monkeyf[i][3] + i - monkeyo] : NULL,
- NULL, FALSE);
+ NULL, false);
}
MEM_freeN(tv);
@@ -508,8 +508,8 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
{
const float dia = BMO_slot_float_get(op->slots_in, "diameter");
const int segs = BMO_slot_int_get(op->slots_in, "segments");
- const int cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
- const int cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
+ const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
+ const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL;
float vec[3], mat[4][4], phi, phid;
@@ -547,7 +547,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (a && cap_ends) {
BMFace *f;
- f = BM_face_create_quad_tri(bm, cent1, lastv1, v1, NULL, NULL, FALSE);
+ f = BM_face_create_quad_tri(bm, cent1, lastv1, v1, NULL, NULL, false);
BMO_elem_flag_enable(bm, f, FACE_NEW);
}
@@ -565,7 +565,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (cap_ends) {
BMFace *f;
- f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, FALSE);
+ f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, false);
BMO_elem_flag_enable(bm, f, FACE_NEW);
}
@@ -584,8 +584,8 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
float dia2 = BMO_slot_float_get(op->slots_in, "diameter2");
float depth = BMO_slot_float_get(op->slots_in, "depth");
int segs = BMO_slot_int_get(op->slots_in, "segments");
- int cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
- int cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
+ const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
+ const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
int a;
if (!segs)
@@ -634,12 +634,12 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (cap_ends) {
BMFace *f;
- f = BM_face_create_quad_tri(bm, cent1, lastv1, v1, NULL, NULL, FALSE);
+ f = BM_face_create_quad_tri(bm, cent1, lastv1, v1, NULL, NULL, false);
BMO_elem_flag_enable(bm, f, FACE_NEW);
- f = BM_face_create_quad_tri(bm, cent2, v2, lastv2, NULL, NULL, FALSE);
+ f = BM_face_create_quad_tri(bm, cent2, v2, lastv2, NULL, NULL, false);
BMO_elem_flag_enable(bm, f, FACE_NEW);
}
- BM_face_create_quad_tri(bm, lastv1, lastv2, v2, v1, NULL, FALSE);
+ BM_face_create_quad_tri(bm, lastv1, lastv2, v2, v1, NULL, false);
}
else {
firstv1 = v1;
@@ -656,9 +656,9 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (cap_ends) {
BMFace *f;
- f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, FALSE);
+ f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, false);
BMO_elem_flag_enable(bm, f, FACE_NEW);
- f = BM_face_create_quad_tri(bm, cent2, firstv2, v2, NULL, NULL, FALSE);
+ f = BM_face_create_quad_tri(bm, cent2, firstv2, v2, NULL, NULL, false);
BMO_elem_flag_enable(bm, f, FACE_NEW);
}
@@ -666,7 +666,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
BMO_op_callf(bm, op->flag, "dissolve_faces faces=%ff", FACE_NEW);
}
- BM_face_create_quad_tri(bm, v1, v2, firstv2, firstv1, NULL, FALSE);
+ BM_face_create_quad_tri(bm, v1, v2, firstv2, firstv1, NULL, false);
BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, 0.000001);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
@@ -738,14 +738,14 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, v8, VERT_MARK);
/* the four sides */
- BM_face_create_quad_tri(bm, v5, v6, v2, v1, NULL, FALSE);
- BM_face_create_quad_tri(bm, v6, v7, v3, v2, NULL, FALSE);
- BM_face_create_quad_tri(bm, v7, v8, v4, v3, NULL, FALSE);
- BM_face_create_quad_tri(bm, v8, v5, v1, v4, NULL, FALSE);
+ BM_face_create_quad_tri(bm, v5, v6, v2, v1, NULL, false);
+ BM_face_create_quad_tri(bm, v6, v7, v3, v2, NULL, false);
+ BM_face_create_quad_tri(bm, v7, v8, v4, v3, NULL, false);
+ BM_face_create_quad_tri(bm, v8, v5, v1, v4, NULL, false);
/* top/bottom */
- BM_face_create_quad_tri(bm, v1, v2, v3, v4, NULL, FALSE);
- BM_face_create_quad_tri(bm, v8, v7, v6, v5, NULL, FALSE);
+ BM_face_create_quad_tri(bm, v1, v2, v3, v4, NULL, false);
+ BM_face_create_quad_tri(bm, v8, v7, v6, v5, NULL, false);
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 87e26f11d4b..7beac676868 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -41,7 +41,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
BMIter liter;
BMLoop *l;
BMVert *v2, *doub;
- int split = FALSE;
+ bool split = false;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
v2 = BMO_slot_map_elem_get(slot_targetmap, l->v);
@@ -52,14 +52,14 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
(v2 != l->next->v))
{
doub = l->v;
- split = TRUE;
+ split = true;
break;
}
}
if (split && doub != v2) {
BMLoop *nl;
- BMFace *f2 = BM_face_split(bm, f, doub, v2, &nl, NULL, FALSE);
+ BMFace *f2 = BM_face_split(bm, f, doub, v2, &nl, NULL, false);
remdoubles_splitface(f, bm, op, slot_targetmap);
remdoubles_splitface(f2, bm, op, slot_targetmap);
@@ -87,12 +87,12 @@ int remdoubles_face_overlaps(BMesh *bm, BMVert **varr,
amount = BM_verts_in_face(bm, f, varr, len);
if (amount >= len) {
if (overlapface) *overlapface = f;
- return TRUE;
+ return true;
}
f = BM_iter_step(&vertfaces);
}
}
- return FALSE;
+ return false;
}
#endif
@@ -394,11 +394,10 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
if (!BMO_elem_flag_test(bm, e, EDGE_MARK))
continue;
- e = BMW_begin(&walker, e->v1);
BLI_array_empty(edges);
INIT_MINMAX(min, max);
- for (tot = 0; e; tot++, e = BMW_step(&walker)) {
+ for (e = BMW_begin(&walker, e->v1), tot = 0; e; e = BMW_step(&walker), tot++) {
BLI_array_grow_one(edges);
edges[tot] = e;
@@ -454,11 +453,9 @@ static void bmo_collapsecon_do_layer(BMesh *bm, BMOperator *op, int layer)
if (BMO_elem_flag_test(bm, l->e, EDGE_MARK)) {
/* walk */
BLI_array_empty(blocks);
- tot = 0;
- l2 = BMW_begin(&walker, l);
CustomData_data_initminmax(type, &min, &max);
- for (tot = 0; l2; tot++, l2 = BMW_step(&walker)) {
+ for (l2 = BMW_begin(&walker, l), tot = 0; l2; l2 = BMW_step(&walker), tot++) {
BLI_array_grow_one(blocks);
blocks[tot] = CustomData_bmesh_get_layer_n(&bm->ldata, l2->head.data, layer);
CustomData_data_dominmax(type, blocks[tot], &min, &max);
diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c
index 548e1adf17d..baabcffd162 100644
--- a/source/blender/bmesh/operators/bmo_similar.c
+++ b/source/blender/bmesh/operators/bmo_similar.c
@@ -185,21 +185,21 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
for (i = 0; i < num_total; i++) {
fm = f_ext[i].f;
if (!BMO_elem_flag_test(bm, fm, FACE_MARK) && !BM_elem_flag_test(fm, BM_ELEM_HIDDEN)) {
- int cont = TRUE;
- for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+ bool cont = true;
+ for (idx = 0; idx < num_sels && cont == true; idx++) {
fs = f_ext[indices[idx]].f;
switch (type) {
case SIMFACE_MATERIAL:
if (fm->mat_nr == fs->mat_nr) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
case SIMFACE_IMAGE:
if (f_ext[i].t == f_ext[indices[idx]].t) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -207,7 +207,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
angle = angle_normalized_v3v3(fs->no, fm->no); /* if the angle between the normals -> 0 */
if (angle <= thresh_radians) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -217,7 +217,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
delta_fl = f_ext[i].d - f_ext[indices[idx]].d;
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
+ cont = false;
}
}
break;
@@ -226,7 +226,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
delta_fl = f_ext[i].area - f_ext[indices[idx]].area;
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -234,7 +234,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
delta_i = fm->len - fs->len;
if (bm_sel_similar_cmp_i(delta_i, compare)) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -242,7 +242,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
delta_fl = f_ext[i].perim - f_ext[indices[idx]].perim;
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
default:
@@ -373,15 +373,15 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
for (i = 0; i < num_total; i++) {
e = e_ext[i].e;
if (!BMO_elem_flag_test(bm, e, EDGE_MARK) && !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- int cont = TRUE;
- for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+ bool cont = true;
+ for (idx = 0; idx < num_sels && cont == true; idx++) {
es = e_ext[indices[idx]].e;
switch (type) {
case SIMEDGE_LENGTH:
delta_fl = e_ext[i].length - e_ext[indices[idx]].length;
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -394,7 +394,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
if (angle / (float)(M_PI / 2.0) <= thresh) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -402,7 +402,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
delta_i = e_ext[i].faces - e_ext[indices[idx]].faces;
if (bm_sel_similar_cmp_i(delta_i, compare)) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -411,12 +411,12 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
if (e_ext[indices[idx]].faces == 2) {
if (fabsf(e_ext[i].angle - e_ext[indices[idx]].angle) <= thresh) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
}
}
else {
- cont = FALSE;
+ cont = false;
}
break;
@@ -430,7 +430,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
}
break;
@@ -445,7 +445,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
}
break;
@@ -453,14 +453,14 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
case SIMEDGE_SEAM:
if (BM_elem_flag_test(e, BM_ELEM_SEAM) == BM_elem_flag_test(es, BM_ELEM_SEAM)) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
case SIMEDGE_SHARP:
if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == BM_elem_flag_test(es, BM_ELEM_SMOOTH)) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
+ cont = false;
}
break;
default:
@@ -562,15 +562,15 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
for (i = 0; i < num_total; i++) {
v = v_ext[i].v;
if (!BMO_elem_flag_test(bm, v, VERT_MARK) && !BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- int cont = TRUE;
- for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+ bool cont = true;
+ for (idx = 0; idx < num_sels && cont == true; idx++) {
vs = v_ext[indices[idx]].v;
switch (type) {
case SIMVERT_NORMAL:
/* compare the angle between the normals */
if (angle_normalized_v3v3(v->no, vs->no) <= thresh_radians) {
BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
+ cont = false;
}
break;
case SIMVERT_FACE:
@@ -578,7 +578,7 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
delta_i = v_ext[i].num_faces - v_ext[indices[idx]].num_faces;
if (bm_sel_similar_cmp_i(delta_i, compare)) {
BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
+ cont = false;
}
break;
@@ -586,7 +586,7 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
if (v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL) {
if (defvert_find_shared(v_ext[i].dvert, v_ext[indices[idx]].dvert) != -1) {
BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
+ cont = false;
}
}
break;
@@ -595,7 +595,7 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
delta_i = v_ext[i].num_edges - v_ext[indices[idx]].num_edges;
if (bm_sel_similar_cmp_i(delta_i, compare)) {
BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
+ cont = false;
}
break;
default:
diff --git a/source/blender/bmesh/operators/bmo_slide.c b/source/blender/bmesh/operators/bmo_slide.c
deleted file mode 100644
index ea9f9bf9eba..00000000000
--- a/source/blender/bmesh/operators/bmo_slide.c
+++ /dev/null
@@ -1,113 +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.
- *
- * Contributor(s): Francisco De La Cruz
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/bmesh/operators/bmo_slide.c
- * \ingroup bmesh
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "BKE_global.h"
-
-#include "BLI_math.h"
-
-#include "bmesh.h"
-#include "intern/bmesh_operators_private.h" /* own include */
-
-#define EDGE_MARK 1
-#define VERT_MARK 2
-
-/*
- * Slides a vertex along a connected edge
- *
- */
-void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
-{
- BMOIter oiter;
- BMIter iter;
- BMHeader *h;
- BMVert *vertex;
- BMEdge *edge;
- BMEdge *slide_edge;
-
- /* Selection counts */
- int selected_edges = 0;
-
- /* Get slide amount */
- const float factor = BMO_slot_float_get(op->slots_in, "factor");
-
- /* Get start vertex */
- vertex = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert"));
-
- if (!vertex) {
- if (G.debug & G_DEBUG) {
- fprintf(stderr, "slide_vert: No vertex selected...");
- }
- BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, "Vertex Slide error: invalid selection");
- return;
- }
-
- /* BMESH_TODO - this is odd, it only uses one edge, why take a list at all? */
- /* Count selected edges */
- BMO_ITER (h, &oiter, op->slots_in, "edges", BM_EDGE) {
- selected_edges++;
- /* Mark all selected edges (cast BMHeader->BMEdge) */
- BMO_elem_flag_enable(bm, (BMElemF *)h, EDGE_MARK);
- break;
- }
-
- /* Only allow sliding if an edge is selected */
- if (selected_edges == 0) {
- if (G.debug & G_DEBUG) {
- fprintf(stderr, "slide_vert: select a single edge\n");
- }
- BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, "Vertex Slide error: invalid selection");
- return;
- }
-
- /* Make sure we get the correct edge. */
- slide_edge = NULL;
- BM_ITER_ELEM (edge, &iter, vertex, BM_EDGES_OF_VERT) {
- if (BMO_elem_flag_test(bm, edge, EDGE_MARK) && BM_vert_in_edge(edge, vertex)) {
- slide_edge = edge;
- break;
- }
- }
-
- /* Found edge */
- if (slide_edge) {
- BMVert *other = BM_edge_other_vert(slide_edge, vertex);
-
- /* mark */
- BMO_elem_flag_enable(bm, vertex, VERT_MARK);
-
- /* Interpolate */
- interp_v3_v3v3(vertex->co, vertex->co, other->co, factor);
- }
-
- /* Return the new edge. The same previously marked with VERT_MARK */
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
- return;
-}
-
-#undef EDGE_MARK
-#undef VERT_MARK
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 4a367a8fd6f..ba755a866de 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -180,7 +180,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
float *v1, *v2, *v3, *v4;
float w1, w2, w3, w4;
int i, j;
- int has_4_vert;
+ bool has_4_vert;
unsigned int idv1, idv2, idv3, idv4, idv[4];
BMEdge *e;
BMFace *f;
@@ -297,7 +297,7 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
float *v1, *v2, *v3, *v4;
float w2, w3, w4;
int i, j;
- int has_4_vert;
+ bool has_4_vert;
unsigned int idv1, idv2, idv3, idv4, idv[4];
BMEdge *e;
@@ -537,8 +537,8 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
{
int i;
int m_vertex_id;
- int usex, usey, usez, preserve_volume;
- float lambda, lambda_border;
+ bool usex, usey, usez, preserve_volume;
+ float lambda_factor, lambda_border;
float w;
BMOIter siter;
BMVert *v;
@@ -553,7 +553,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
memset_laplacian_system(sys, 0);
BM_mesh_elem_index_ensure(bm, BM_VERT);
- lambda = BMO_slot_float_get(op->slots_in, "lambda");
+ lambda_factor = BMO_slot_float_get(op->slots_in, "lambda_factor");
lambda_border = BMO_slot_float_get(op->slots_in, "lambda_border");
sys->min_area = 0.00001f;
usex = BMO_slot_bool_get(op->slots_in, "use_x");
@@ -592,12 +592,12 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
i = m_vertex_id;
if (sys->zerola[i] == 0) {
w = sys->vweights[i] * sys->ring_areas[i];
- sys->vweights[i] = (w == 0.0f) ? 0.0f : -lambda / (4.0f * w);
+ sys->vweights[i] = (w == 0.0f) ? 0.0f : -lambda_factor / (4.0f * w);
w = sys->vlengths[i];
sys->vlengths[i] = (w == 0.0f) ? 0.0f : -lambda_border * 2.0f / w;
if (!vert_is_boundary(v)) {
- nlMatrixAdd(i, i, 1.0f + lambda / (4.0f * sys->ring_areas[i]));
+ nlMatrixAdd(i, i, 1.0f + lambda_factor / (4.0f * sys->ring_areas[i]));
}
else {
nlMatrixAdd(i, i, 1.0f + lambda_border * 2.0f);
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 7407eb4423a..36ad8ef506b 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -90,7 +90,7 @@ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace *
}
if (curf) {
- face = BM_face_split(bm, curf, v1, v2, &nl, NULL, FALSE);
+ face = BM_face_split(bm, curf, v1, v2, &nl, NULL, false);
if (r_nf) *r_nf = face;
return nl ? nl->e : NULL;
@@ -165,7 +165,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
}
/* apply the new difference to the rest of the shape keys,
- * note that this dosn't take rotations into account, we _could_ support
+ * note that this doesn't take rotations into account, we _could_ support
* this by getting the normals and coords for each shape key and
* re-calculate the smooth value for each but this is quite involved.
* for now its ok to simply apply the difference IMHO - campbell */
@@ -715,8 +715,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMFace *face;
BLI_array_declare(verts);
float smooth, fractal, along_normal;
- int use_sphere, cornertype, use_single_edge, use_grid_fill, use_only_quads;
- int skey, seed, i, j, matched, a, b, numcuts, totesel;
+ bool use_sphere, use_single_edge, use_grid_fill, use_only_quads;
+ int cornertype, skey, seed, i, j, matched, a, b, numcuts, totesel;
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT);
@@ -912,6 +912,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
j = BLI_array_count(facedata) - 1;
BMO_elem_flag_enable(bm, face, SUBD_SPLIT);
+
+ /* must initialize all members here */
+ facedata[j].start = NULL;
+ facedata[j].pat = NULL;
facedata[j].totedgesel = totesel;
facedata[j].face = face;
}
@@ -983,7 +987,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_grow_items(loops_split, numcuts);
for (j = 0; j < numcuts; j++) {
- int ok = TRUE;
+ bool ok = true;
/* Check for special case: [#32500]
* This edge pair could be used by more then one face,
@@ -1006,7 +1010,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_assert(other_loop->prev->v != loops[a]->v);
BLI_assert(other_loop->next->v != loops[a]->v);
- ok = FALSE;
+ ok = false;
break;
}
}
@@ -1014,7 +1018,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
- if (ok == TRUE) {
+ if (ok == true) {
loops_split[j][0] = loops[a];
loops_split[j][1] = loops[b];
}
@@ -1036,10 +1040,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
for (j = 0; j < BLI_array_count(loops_split); j++) {
if (loops_split[j][0]) {
- BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == FALSE);
+ BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL);
/* BMFace *nf = */ /* UNUSED */
- BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &nl, NULL, FALSE);
+ BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &nl, NULL, false);
}
}
@@ -1123,7 +1127,7 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
BMElem *ele;
for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) {
- BM_elem_select_set(bm, ele, TRUE);
+ BM_elem_select_set(bm, ele, true);
}
}
else if (seltype == SUBDIV_SELECT_LOOPCUT) {
@@ -1131,10 +1135,10 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
BMElem *ele;
/* deselect input */
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) {
- BM_elem_select_set(bm, ele, TRUE);
+ BM_elem_select_set(bm, ele, true);
if (ele->head.htype == BM_VERT) {
BMEdge *e;
@@ -1145,13 +1149,13 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
BM_elem_flag_test(e->v2, BM_ELEM_SELECT))
{
- BM_edge_select_set(bm, e, TRUE);
+ BM_edge_select_set(bm, e, true);
}
else if (BM_elem_flag_test(e, BM_ELEM_SELECT) &&
(!BM_elem_flag_test(e->v1, BM_ELEM_SELECT) ||
!BM_elem_flag_test(e->v2, BM_ELEM_SELECT)))
{
- BM_edge_select_set(bm, e, FALSE);
+ BM_edge_select_set(bm, e, false);
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index 248c7268ac6..0bfc81f83cf 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -176,7 +176,7 @@ static void symm_split_asymmetric_edges(Symm *symm)
plane_co[symm->axis][0],
plane_co[symm->axis][1],
plane_co[symm->axis][2],
- &lambda, TRUE);
+ &lambda, true);
BLI_assert(r);
madd_v3_v3v3fl(co, e->v1->co, edge_dir, lambda);
@@ -244,7 +244,7 @@ typedef struct {
int len;
/* True only if none of the polygon's edges were split */
- int already_symmetric;
+ bool already_symmetric;
BMFace *src_face;
} SymmPoly;
@@ -261,11 +261,11 @@ static void symm_poly_with_splits(const Symm *symm,
/* Count vertices and check for edge splits */
out->len = f->len;
- out->already_symmetric = TRUE;
+ out->already_symmetric = true;
BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
if (BLI_ghash_haskey(symm->edge_split_map, l->e)) {
out->len++;
- out->already_symmetric = FALSE;
+ out->already_symmetric = false;
}
}
@@ -332,11 +332,11 @@ static BMVert *symm_poly_mirror_dst(const Symm *symm,
return NULL;
}
-static int symm_poly_next_crossing(const Symm *symm,
- const SymmPoly *sp,
- int start,
- int *l1,
- int *l2)
+static bool symm_poly_next_crossing(const Symm *symm,
+ const SymmPoly *sp,
+ int start,
+ int *l1,
+ int *l2)
{
int i;
@@ -347,12 +347,12 @@ static int symm_poly_next_crossing(const Symm *symm,
if ((symm_poly_co_side(symm, sp, *l1) == SYMM_SIDE_KILL) ^
(symm_poly_co_side(symm, sp, *l2) == SYMM_SIDE_KILL))
{
- return TRUE;
+ return true;
}
}
BLI_assert(!"symm_poly_next_crossing failed");
- return FALSE;
+ return false;
}
static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
@@ -361,6 +361,12 @@ static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
BMFace *f_new;
int i;
+ /* TODO: calling symmetrize in dynamic-topology sculpt mode
+ * frequently tries to create faces of length less than two,
+ * should investigate further */
+ if (len < 3)
+ return NULL;
+
for (i = 0; i < len; i++) {
int j = (i + 1) % len;
fe[i] = BM_edge_exists(fv[i], fv[j]);
@@ -372,8 +378,9 @@ static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
f_new = BM_face_create(bm, fv, fe, len, BM_CREATE_NO_DOUBLE);
if (example)
BM_elem_attrs_copy(bm, bm, example, f_new);
- BM_face_select_set(bm, f_new, TRUE);
+ BM_face_select_set(bm, f_new, true);
BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM);
+
return f_new;
}
@@ -458,15 +465,15 @@ static void symm_mirror_polygons(Symm *symm)
BMO_ITER (f, &oiter, symm->op->slots_in, "input", BM_FACE) {
BMIter iter;
BMLoop *l;
- int mirror_all = TRUE, ignore_all = TRUE;
+ bool mirror_all = true, ignore_all = true;
/* Check if entire polygon can be mirrored or ignored */
BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
const SymmSide side = symm_co_side(symm, l->v->co);
if (side == SYMM_SIDE_KILL)
- mirror_all = FALSE;
+ mirror_all = false;
else if (side == SYMM_SIDE_KEEP)
- ignore_all = FALSE;
+ ignore_all = false;
}
if (mirror_all) {
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index d20d01af114..1f04c7ce845 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -37,45 +37,22 @@
#include "intern/bmesh_operators_private.h" /* own include */
-#define EDGE_NEW 1
-#define FACE_NEW 1
-
#define ELE_NEW 1
#define FACE_MARK 2
#define EDGE_MARK 4
void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
{
- BMOIter siter;
- BMFace *face, **newfaces = NULL;
- BLI_array_declare(newfaces);
- float (*projectverts)[3] = NULL;
- BLI_array_declare(projectverts);
- int i;
- const int use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty");
+ const bool use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty");
BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "face_map.out");
- for (face = BMO_iter_new(&siter, op->slots_in, "faces", BM_FACE); face; face = BMO_iter_step(&siter)) {
-
- BLI_array_empty(projectverts);
- BLI_array_empty(newfaces);
-
- BLI_array_grow_items(projectverts, face->len * 3);
- BLI_array_grow_items(newfaces, face->len);
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE | BM_EDGE, BM_ELEM_TAG, false);
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
- BM_face_triangulate(bm, face, projectverts, EDGE_NEW, FACE_NEW, newfaces, use_beauty);
+ BM_mesh_triangulate(bm, use_beauty, true, op, slot_facemap_out);
- BMO_slot_map_elem_insert(op, slot_facemap_out, face, face);
- for (i = 0; newfaces[i]; i++) {
- BMO_slot_map_elem_insert(op, slot_facemap_out, newfaces[i], face);
- }
- }
-
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_NEW);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_NEW);
-
- BLI_array_free(projectverts);
- BLI_array_free(newfaces);
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG);
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}
void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
@@ -86,7 +63,7 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
int stop = 0;
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "constrain_edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
if (f->len == 3) {
@@ -100,7 +77,7 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
BMVert *v1, *v2, *v3, *v4;
- if (!BM_edge_is_manifold(e) || BMO_elem_flag_test(bm, e, EDGE_MARK)) {
+ if (!BM_edge_is_manifold(e) || !BMO_elem_flag_test(bm, e, EDGE_MARK)) {
continue;
}
@@ -109,12 +86,12 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
{
continue;
}
-
+
v1 = e->l->prev->v;
v2 = e->l->v;
v3 = e->l->radial_next->prev->v;
v4 = e->l->next->v;
-
+
if (is_quad_convex_v3(v1->co, v2->co, v3->co, v4->co)) {
float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2;
/* testing rule:
@@ -138,9 +115,9 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
fac2 = opp1 / (len2 + len3 + len6) + opp2 / (len4 + len1 + len6);
if (fac1 > fac2) {
- e = BM_edge_rotate(bm, e, FALSE, BM_EDGEROT_CHECK_EXISTS);
+ e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS);
if (e) {
- BMO_elem_flag_enable(bm, e, ELE_NEW);
+ BMO_elem_flag_enable(bm, e, ELE_NEW | EDGE_MARK);
BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW);
BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW);
@@ -156,9 +133,9 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
{
+ const bool use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty");
BMOIter siter;
BMEdge *e;
- BMOperator bmop;
ScanFillContext sf_ctx;
/* ScanFillEdge *sf_edge; */ /* UNUSED */
ScanFillVert *sf_vert, *sf_vert_1, *sf_vert_2;
@@ -190,12 +167,12 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* sf_edge->tmp.p = e; */ /* UNUSED */
}
- BLI_scanfill_calc(&sf_ctx, 0);
+ BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_HOLES);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
BMFace *f = BM_face_create_quad_tri(bm,
sf_tri->v1->tmp.p, sf_tri->v2->tmp.p, sf_tri->v3->tmp.p, NULL,
- NULL, TRUE);
+ NULL, true);
BMLoop *l;
BMIter liter;
@@ -210,11 +187,14 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
BLI_scanfill_end(&sf_ctx);
BLI_smallhash_release(&hash);
- /* clean up fill */
- BMO_op_initf(bm, &bmop, op->flag, "beautify_fill faces=%ff constrain_edges=%fe", ELE_NEW, EDGE_MARK);
- BMO_op_exec(bm, &bmop);
- BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, ELE_NEW);
- BMO_op_finish(bm, &bmop);
+ if (use_beauty) {
+ BMOperator bmop;
+
+ BMO_op_initf(bm, &bmop, op->flag, "beautify_fill faces=%ff edges=%Fe", ELE_NEW, EDGE_MARK);
+ BMO_op_exec(bm, &bmop);
+ BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, ELE_NEW);
+ BMO_op_finish(bm, &bmop);
+ }
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_EDGE | BM_FACE, ELE_NEW);
}
diff --git a/source/blender/bmesh/operators/bmo_unsubdivide.c b/source/blender/bmesh/operators/bmo_unsubdivide.c
index fae7db3d175..784e695efb0 100644
--- a/source/blender/bmesh/operators/bmo_unsubdivide.c
+++ b/source/blender/bmesh/operators/bmo_unsubdivide.c
@@ -55,5 +55,5 @@ void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op)
}
/* do all the real work here */
- BM_mesh_decimate_unsubdivide_ex(bm, iterations, TRUE);
+ BM_mesh_decimate_unsubdivide_ex(bm, iterations, true);
}
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index 64dbf0cc0e7..6398d9d04b1 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -122,8 +122,8 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMEdge *e, *e2;
- const int use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
- const int is_single = BMO_slot_buffer_count(op->slots_in, "edges") == 1;
+ const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
+ const bool is_single = BMO_slot_buffer_count(op->slots_in, "edges") == 1;
short check_flag = is_single ?
BM_EDGEROT_CHECK_EXISTS :
BM_EDGEROT_CHECK_EXISTS | BM_EDGEROT_CHECK_DEGENERATE;
@@ -140,8 +140,8 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
if (BM_edge_face_pair(e, &fa, &fb)) {
/* check we're untouched */
- if (BMO_elem_flag_test(bm, fa, FACE_TAINT) == FALSE &&
- BMO_elem_flag_test(bm, fb, FACE_TAINT) == FALSE)
+ if (BMO_elem_flag_test(bm, fa, FACE_TAINT) == false &&
+ BMO_elem_flag_test(bm, fb, FACE_TAINT) == false)
{
if (!(e2 = BM_edge_rotate(bm, e, use_ccw, check_flag))) {
@@ -172,14 +172,14 @@ 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, int usefaces)
+static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, const bool use_faces)
{
BMVert *v;
BMEdge *e;
BMIter eiter;
BMOIter siter;
- if (!usefaces) {
+ if (!use_faces) {
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))
@@ -216,14 +216,14 @@ static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, int usefaces)
}
}
-static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, int usefaces)
+static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, const bool use_faces)
{
BMVert *v;
BMEdge *e;
BMIter eiter;
BMOIter siter;
- if (!usefaces) {
+ if (!use_faces) {
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))
@@ -265,8 +265,8 @@ static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, int usefaces)
void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
{
- int use_faces = BMO_slot_bool_get(op->slots_in, "use_faces");
- int constrict = BMO_slot_bool_get(op->slots_in, "use_constrict");
+ 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");
BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, SEL_ORIG);
@@ -314,7 +314,8 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(fstack);
BMLoop *l, *l2;
float maxx, maxx_test, cent[3];
- int i, i_max, flagflip = BMO_slot_bool_get(op->slots_in, "use_flip");
+ int i, i_max;
+ const bool use_flip = BMO_slot_bool_get(op->slots_in, "use_flip");
startf = NULL;
maxx = -1.0e10;
@@ -349,7 +350,7 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
BM_face_normal_flip(bm, startf);
BMO_elem_flag_toggle(bm, startf, FACE_FLIP);
- if (flagflip)
+ if (use_flip)
BM_elem_flag_toggle(startf, BM_ELEM_TAG);
}
@@ -381,11 +382,11 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
BM_face_normal_flip(bm, l2->f);
BMO_elem_flag_toggle(bm, l2->f, FACE_FLIP);
- if (flagflip)
+ if (use_flip)
BM_elem_flag_toggle(l2->f, BM_ELEM_TAG);
}
else if (BM_elem_flag_test(l2->f, BM_ELEM_TAG) || BM_elem_flag_test(l->f, BM_ELEM_TAG)) {
- if (flagflip) {
+ if (use_flip) {
BM_elem_flag_disable(l->f, BM_ELEM_TAG);
BM_elem_flag_disable(l2->f, BM_ELEM_TAG);
}
@@ -436,9 +437,11 @@ void bmo_smooth_vert_exec(BMesh *UNUSED(bm), BMOperator *op)
i = 0;
BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
BLI_array_grow_one(cos);
+
co = cos[i];
-
- j = 0;
+ zero_v3(co);
+
+ j = 0;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
co2 = BM_edge_other_vert(e, v)->co;
add_v3_v3v3(co, co, co2);
@@ -489,11 +492,11 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op)
BMFace *fs; /* current face */
BMIter l_iter; /* iteration loop */
- const int use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
+ const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (CustomData_has_layer(&(bm->ldata), CD_MLOOPUV)) {
- if (use_ccw == FALSE) { /* same loops direction */
+ if (use_ccw == false) { /* same loops direction */
BMLoop *lf; /* current face loops */
MLoopUV *f_luv; /* first face loop uv */
float p_uv[2]; /* previous uvs */
@@ -594,11 +597,11 @@ void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op)
BMFace *fs; /* current face */
BMIter l_iter; /* iteration loop */
- const int use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
+ const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (CustomData_has_layer(&(bm->ldata), CD_MLOOPCOL)) {
- if (use_ccw == FALSE) { /* same loops direction */
+ if (use_ccw == false) { /* same loops direction */
BMLoop *lf; /* current face loops */
MLoopCol *f_lcol; /* first face loop color */
MLoopCol p_col; /* previous color */
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index 7401704310f..0d603faf3c4 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -134,34 +134,34 @@ static void bm_vert_boundary_tangent(BMVert *v, float r_no[3], float r_no_face[3
}
/* check if we are the only tagged loop-face around this edge */
-static int bm_loop_is_radial_boundary(BMLoop *l_first)
+static bool bm_loop_is_radial_boundary(BMLoop *l_first)
{
BMLoop *l = l_first->radial_next;
if (l == l_first) {
- return TRUE; /* a real boundary */
+ return true; /* a real boundary */
}
else {
do {
if (BM_elem_flag_test(l->f, BM_ELEM_TAG)) {
- return FALSE;
+ return false;
}
} while ((l = l->radial_next) != l_first);
}
- return TRUE;
+ return true;
}
extern float BM_vert_calc_mean_tagged_edge_length(BMVert *v);
void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
{
- const int use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary");
- const int use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
- const int use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
- const int use_crease = (BMO_slot_bool_get(op->slots_in, "use_crease") &&
- CustomData_has_layer(&bm->edata, CD_CREASE));
- const float depth = BMO_slot_float_get(op->slots_in, "thickness");
- const float inset = depth;
+ const bool use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary");
+ const bool use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
+ const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
+ const bool use_crease = (BMO_slot_bool_get(op->slots_in, "use_crease") &&
+ CustomData_has_layer(&bm->edata, CD_CREASE));
+ const float depth = BMO_slot_float_get(op->slots_in, "thickness");
+ const float inset = depth;
const int totvert_orig = bm->totvert;
@@ -203,7 +203,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
}
/* setup tags, all faces and verts will be tagged which will be duplicated */
- BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) {
verts_loop_tot += f_src->len;
@@ -239,13 +239,13 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
}
/* conflicts with BM_vert_calc_mean_tagged_edge_length */
- if (use_relative_offset == FALSE) {
+ if (use_relative_offset == false) {
BM_elem_flag_disable(v_src, BM_ELEM_TAG);
}
}
if (use_relative_offset) {
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
}
verts_loop = MEM_mallocN(sizeof(BMVert **) * verts_loop_tot, __func__);
@@ -332,7 +332,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
BMVert *v_pos1 = verts_pos[i_1];
BMVert *v_pos2 = verts_pos[i_2];
- f_new = BM_face_create_quad_tri(bm, v_l1, v_l2, v_neg2, v_neg1, f_src, FALSE);
+ f_new = BM_face_create_quad_tri(bm, v_l1, v_l2, v_neg2, v_neg1, f_src, false);
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);
@@ -341,7 +341,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
BM_elem_attrs_copy(bm, bm, l_next, l_new->next);
BM_elem_attrs_copy(bm, bm, l_next, l_new->next->next);
- f_new = BM_face_create_quad_tri(bm, v_l2, v_l1, v_pos1, v_pos2, f_src, FALSE);
+ f_new = BM_face_create_quad_tri(bm, v_l2, v_l1, v_pos1, v_pos2, f_src, false);
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);
@@ -357,7 +357,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
BMVert *v_b1 = verts_boundary[i_1];
BMVert *v_b2 = verts_boundary[i_2];
- f_new = BM_face_create_quad_tri(bm, v_b2, v_b1, v_neg1, v_neg2, f_src, FALSE);
+ f_new = BM_face_create_quad_tri(bm, v_b2, v_b1, v_neg1, v_neg2, f_src, false);
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);
@@ -366,7 +366,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
BM_elem_attrs_copy(bm, bm, l, l_new->next);
BM_elem_attrs_copy(bm, bm, l, l_new->next->next);
- f_new = BM_face_create_quad_tri(bm, v_b1, v_b2, v_pos2, v_pos1, f_src, FALSE);
+ f_new = BM_face_create_quad_tri(bm, v_b1, v_b2, v_pos2, v_pos1, f_src, false);
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);
diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c
index 3f2ca21bcee..47b507603f4 100644
--- a/source/blender/bmesh/tools/BME_bevel.c
+++ b/source/blender/bmesh/tools/BME_bevel.c
@@ -90,7 +90,7 @@ static BME_TransData *BME_assign_transdata(BME_TransData_Head *td, BMesh *bm, BM
float factor, float weight, float maxfactor, float *max)
{
BME_TransData *vtd;
- int is_new = 0;
+ int is_new = false;
if (v == NULL) {
return NULL;
@@ -100,7 +100,7 @@ static BME_TransData *BME_assign_transdata(BME_TransData_Head *td, BMesh *bm, BM
vtd = BLI_memarena_alloc(td->ma, sizeof(*vtd));
BLI_ghash_insert(td->gh, v, vtd);
td->len++;
- is_new = 1;
+ is_new = true;
}
vtd->bm = bm;
@@ -151,12 +151,12 @@ static void BME_Bevel_Dissolve_Disk(BMesh *bm, BMVert *v)
{
BMFace *f;
BMEdge *e;
- int done;
+ bool done;
if (v->e) {
- done = FALSE;
+ done = false;
while (!done) {
- done = TRUE;
+ done = true;
e = v->e; /*loop the edge looking for a edge to dissolve*/
do {
f = NULL;
@@ -164,14 +164,14 @@ static void BME_Bevel_Dissolve_Disk(BMesh *bm, BMVert *v)
f = bmesh_jfke(bm, e->l->f, e->l->radial_next->f, e);
}
if (f) {
- done = FALSE;
+ done = false;
break;
}
e = bmesh_disk_edge_next(e, v);
} while (e != v->e);
}
- BM_vert_collapse_edge(bm, v->e, v, TRUE);
- // bmesh_jekv(bm, v->e, v, FALSE);
+ BM_vert_collapse_edge(bm, v->e, v, true);
+ // bmesh_jekv(bm, v->e, v, false);
}
}
@@ -539,18 +539,18 @@ static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(opti
se = l->next->e;
jf = NULL;
if (kl->v == kv) {
- BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, TRUE);
+ BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true);
ke = kl->e;
/* BMESH-TODO: jfke doesn't handle customdata */
jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
- BM_vert_collapse_edge(bm, ke, kv, FALSE);
+ BM_vert_collapse_edge(bm, ke, kv, false);
}
else {
- BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, TRUE);
+ BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true);
ke = kl->e;
/* BMESH-TODO: jfke doesn't handle customdata */
jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
- BM_vert_collapse_edge(bm, ke, kv, FALSE);
+ BM_vert_collapse_edge(bm, ke, kv, false);
}
/* find saved loop pointer */
l = se->l;
@@ -585,18 +585,18 @@ static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(opti
se = l->e;
jf = NULL;
if (kl->v == kv) {
- BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, TRUE);
+ BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true);
ke = kl->e;
/* BMESH-TODO: jfke doesn't handle customdata */
jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
- BM_vert_collapse_edge(bm, ke, kv, FALSE);
+ BM_vert_collapse_edge(bm, ke, kv, false);
}
else {
- BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, TRUE);
+ BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true);
ke = kl->e;
/* BMESH-TODO: jfke doesn't handle customdata */
jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
- BM_vert_collapse_edge(bm, ke, kv, FALSE);
+ BM_vert_collapse_edge(bm, ke, kv, false);
}
/* find saved loop pointer */
l = se->l;
@@ -607,7 +607,7 @@ static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(opti
}
if (!BMO_elem_flag_test(bm, v1, BME_BEVEL_NONMAN) || !BMO_elem_flag_test(bm, v2, BME_BEVEL_NONMAN)) {
- BM_face_split(bm, f, v2, v1, &l, e, TRUE);
+ BM_face_split(bm, f, v2, v1, &l, e, true);
BMO_elem_flag_enable(bm, l->e, BME_BEVEL_BEVEL);
l = l->radial_next;
}
@@ -636,7 +636,7 @@ static BMLoop *BME_bevel_vert(BMesh *bm, BMLoop *l, float value, int UNUSED(opti
l = l->next->next;
/* "cut off" this corner */
- /* f = */ BM_face_split(bm, l->f, v2, v1, NULL, l->e, TRUE);
+ /* f = */ BM_face_split(bm, l->f, v2, v1, NULL, l->e, true);
return l;
}
@@ -965,7 +965,7 @@ static BMesh *BME_bevel_initialize(BMesh *bm, int options,
BMIter iter;
int /* wire, */ len;
- /* tag non-manifold geometr */
+ /* tag non-manifold geometry */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG);
if (v->e) {
@@ -1069,7 +1069,7 @@ static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int option
/* get rid of beveled edge */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BMO_elem_flag_test(bm, e, BME_BEVEL_BEVEL) && BMO_elem_flag_test(bm, e, BME_BEVEL_ORIG)) {
- BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE);
+ BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true);
}
}
@@ -1083,9 +1083,9 @@ static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int option
if (l->v != v) l = l->next;
if (l2->v != v) l2 = l2->next;
if (l->f->len > 3)
- BM_face_split(bm, l->f, l->next->v, l->prev->v, &l, l->e, TRUE); /* clip this corner off */
+ BM_face_split(bm, l->f, l->next->v, l->prev->v, &l, l->e, true); /* clip this corner off */
if (l2->f->len > 3)
- BM_face_split(bm, l2->f, l2->next->v, l2->prev->v, &l, l2->e, TRUE); /* clip this corner off */
+ BM_face_split(bm, l2->f, l2->next->v, l2->prev->v, &l, l2->e, true); /* clip this corner off */
curedge = bmesh_disk_edge_next(curedge, v);
} while (curedge != v->e);
BME_Bevel_Dissolve_Disk(bm, v);
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 9125800d3e8..5adef16de14 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -30,20 +30,23 @@
#include "MEM_guardedalloc.h"
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+
#include "BLI_array.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BKE_customdata.h"
+#include "BKE_deform.h"
#include "bmesh.h"
+#include "./intern/bmesh_private.h"
-/* experemental - Campbell */
-// #define USE_ALTERNATE_ADJ
-
-#define BEVEL_EPSILON 1e-6
+#define BEVEL_EPSILON_D 1e-6
+#define BEVEL_EPSILON 1e-6f
/* for testing */
// #pragma GCC diagnostic error "-Wpadded"
@@ -93,7 +96,7 @@ typedef struct VMesh {
M_NONE, /* no polygon mesh needed */
M_POLY, /* a simple polygon */
M_ADJ, /* "adjacent edges" mesh pattern */
-// M_CROSS, /* "cross edges" mesh pattern */
+ M_ADJ_SUBDIV, /* like M_ADJ, but using subdivision */
M_TRI_FAN, /* a simple polygon - fan filled */
M_QUAD_STRIP, /* a simple polygon - cut into paralelle strips */
} mesh_kind;
@@ -105,6 +108,7 @@ typedef struct BevVert {
BMVert *v; /* original mesh vertex */
int edgecount; /* total number of edges around the vertex */
int selcount; /* number of selected edges around the vertex */
+ float offset; /* offset for this vertex, if vertex_only bevel */
EdgeHalf *edges; /* array of size edgecount; CCW order from vertex normal side */
VMesh *vmesh; /* mesh structure for replacing vertex */
} BevVert;
@@ -118,11 +122,15 @@ typedef struct BevelParams {
float offset; /* blender units to offset each side of a beveled edge */
int seg; /* number of segments in beveled edge profile */
+ bool vertex_only; /* bevel vertices only */
+ bool use_weights; /* bevel amount affected by weights on edges or verts */
+ const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */
+ int vertex_group; /* vertex group index, maybe set if vertex_only */
} BevelParams;
// #pragma GCC diagnostic ignored "-Wpadded"
-//#include "bevdebug.c"
+// #include "bevdebug.c"
/* Make a new BoundVert of the given kind, insert it at the end of the circular linked
* list with entry point bv->boundstart, and return it. */
@@ -165,6 +173,7 @@ static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert
{
NewVert *nv = mesh_vert(vm, i, j, k);
nv->v = BM_vert_create(bm, nv->co, eg, 0);
+ BM_elem_flag_disable(nv->v, BM_ELEM_TAG);
}
static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto,
@@ -263,14 +272,16 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF
}
else {
int i;
- BMEdge **ee = NULL;
- BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__);
+ BMEdge **ee = BLI_array_alloca(ee, totv);
for (i = 0; i < totv; i++) {
ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, BM_CREATE_NO_DOUBLE);
}
+#if 0
f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, 0);
- BLI_array_fixedstack_free(ee);
+#else
+ f = BM_face_create(bm, vert_arr, ee, totv, 0);
+#endif
}
if (facerep && f) {
int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
@@ -318,7 +329,7 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
- if (angle_v3v3(dir1, dir2) < 100.0f * (float)BEVEL_EPSILON) {
+ if (angle_v3v3(dir1, dir2) < 100.0f * BEVEL_EPSILON) {
/* special case: e1 and e2 are parallel; put offset point perp to both, from v.
* need to find a suitable plane.
* if offsets are different, we're out of luck: just use e1->offset */
@@ -381,6 +392,7 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
int iret;
BLI_assert(f1 != NULL && f2 != NULL);
+ (void)f1, (void)f2; /* UNUSED */
/* get direction vectors for two offset lines */
sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
@@ -404,7 +416,7 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
madd_v3_v3fl(off2a, norm_perp2, e2->offset);
add_v3_v3v3(off2b, off2a, dir2);
- if (angle_v3v3(dir1, dir2) < 100.0f * (float)BEVEL_EPSILON) {
+ if (angle_v3v3(dir1, dir2) < 100.0f * BEVEL_EPSILON) {
/* lines are parallel; off1a is a good meet point */
copy_v3_v3(meetco, off1a);
}
@@ -416,7 +428,7 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
}
else if (iret == 2) {
/* lines are not coplanar; meetco and isect2 are nearest to first and second lines */
- if (len_v3v3(meetco, isect2) > 100.0f * (float)BEVEL_EPSILON) {
+ if (len_v3v3(meetco, isect2) > 100.0f * BEVEL_EPSILON) {
/* offset lines don't meet: project average onto emid; this is not ideal (see TODO above) */
mid_v3_v3v3(co, meetco, isect2);
closest_to_line_v3(meetco, co, v->co, BM_edge_other_vert(emid->e, v)->co);
@@ -465,7 +477,7 @@ static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
sub_v3_v3v3(dir, v->co, BM_edge_other_vert(e->e, v)->co);
len = normalize_v3(dir);
if (d > len)
- d = len - (float)(50.0 * BEVEL_EPSILON);
+ d = len - (float)(50.0 * BEVEL_EPSILON_D);
copy_v3_v3(slideco, v->co);
madd_v3_v3fl(slideco, dir, -d);
}
@@ -496,79 +508,6 @@ static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f)
return lb->next == la ? 1 : -1;
}
-#ifdef USE_ALTERNATE_ADJ
-
-static void vmesh_cent(VMesh *vm, float r_cent[3])
-{
- BoundVert *v;
- zero_v3(r_cent);
-
- v = vm->boundstart;
- do {
- add_v3_v3(r_cent, v->nv.co);
- } while ((v = v->next) != vm->boundstart);
- mul_v3_fl(r_cent, 1.0f / (float)vm->count);
-}
-
-/**
- *
- * This example shows a tri fan of quads,
- * but could be an NGon fan of quads too.
- * <pre>
- * The whole triangle X
- * represents the / \
- * new bevel face. / \
- * / \
- * Split into / \
- * a quad fan. / \
- * / \
- * / \
- * / \
- * co_prev +-. .-+
- * / `-._ _.-' \
- * / co_cent`-+-' \
- * / | \
- * Quad of / | \
- * interest -- / ---> X | \
- * / | \
- * / | \
- * / co_next| \
- * co_orig +-----------------+-----------------+
- *
- * For each quad, calcualte UV's based on the following:
- * U = k / (vm->seg * 2)
- * V = ring / (vm->seg * 2)
- * quad = (co_orig, co_prev, co_cent, co_next)
- * ... note that co_cent is the same for all quads in the fan.
- * </pre>
- *
- */
-
-static void get_point_uv(float uv[2],
- /* all these args are int's originally
- * but pass as floats to the function */
- const float seg, const float ring, const float k)
-{
- uv[0] = (ring / seg) * 2.0f;
- uv[1] = (k / seg) * 2.0f;
-}
-
-/* TODO: make this a lot smarter!,
- * this is the main reason USE_ALTERNATE_ADJ isn't so good right now :S */
-static float get_point_uv_factor(const float uv[2])
-{
- return sinf(1.0f - max_ff(uv[0], uv[1]) / 2.0f);
-}
-
-static void get_point_on_round_edge(const float uv[2],
- float quad[4][3],
- float r_co[3])
-{
- interp_bilinear_quad_v3(quad, uv[0], uv[1], r_co);
-}
-
-#else /* USE_ALTERNATE_ADJ */
-
/* Fill matrix r_mat so that a point in the sheared parallelogram with corners
* va, vmid, vb (and the 4th that is implied by it being a parallelogram)
* is transformed to the unit square by multiplication with r_mat.
@@ -588,7 +527,7 @@ static void get_point_on_round_edge(const float uv[2],
* We want M to make M*A=B where A has the left side above, as columns
* and B has the right side as columns - both extended into homogeneous coords.
* So M = B*(Ainverse). Doing Ainverse by hand gives the code below.
-*/
+ */
static int make_unit_square_map(const float va[3], const float vmid[3], const float vb[3],
float r_mat[4][4])
{
@@ -596,7 +535,7 @@ static int make_unit_square_map(const float va[3], const float vmid[3], const fl
sub_v3_v3v3(va_vmid, vmid, va);
sub_v3_v3v3(vb_vmid, vmid, vb);
- if (fabsf(angle_v3v3(va_vmid, vb_vmid) - (float)M_PI) > 100.f *(float)BEVEL_EPSILON) {
+ if (fabsf(angle_v3v3(va_vmid, vb_vmid) - (float)M_PI) > 100.0f * BEVEL_EPSILON) {
sub_v3_v3v3(vo, va, vb_vmid);
cross_v3_v3v3(vddir, vb_vmid, va_vmid);
normalize_v3(vddir);
@@ -689,14 +628,13 @@ static void snap_to_edge_profile(EdgeHalf *e, const float va[3], const float vb[
}
}
-#endif /* !USE_ALTERNATE_ADJ */
-
/* 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.
* Also decide on the mesh pattern that will be used inside the boundary.
* Doesn't make the actual BMVerts */
-static void build_boundary(MemArena *mem_arena, BevVert *bv)
+static void build_boundary(BevelParams *bp, BevVert *bv)
{
+ MemArena *mem_arena = bp->mem_arena;
EdgeHalf *efirst, *e;
BoundVert *v;
VMesh *vm;
@@ -704,9 +642,13 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
const float *no;
float lastd;
- e = efirst = next_bev(bv, NULL);
vm = bv->vmesh;
+ if (bp->vertex_only)
+ e = efirst = &bv->edges[0];
+ else
+ e = efirst = next_bev(bv, NULL);
+
BLI_assert(bv->edgecount >= 2); /* since bevel edges incident to 2 faces */
if (bv->edgecount == 2 && bv->selcount == 1) {
@@ -731,7 +673,7 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
return;
}
- lastd = e->offset;
+ lastd = bp->vertex_only? bv->offset : e->offset;
vm->boundstart = NULL;
do {
if (e->is_bev) {
@@ -801,7 +743,10 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
} while ((e = e->next) != efirst);
BLI_assert(vm->count >= 2);
- if (vm->count == 2 && bv->edgecount == 3) {
+ if (bp->vertex_only) {
+ vm->mesh_kind = bp->seg > 1 ? M_ADJ_SUBDIV : M_POLY;
+ }
+ else if (vm->count == 2 && bv->edgecount == 3) {
vm->mesh_kind = M_NONE;
}
else if (bv->selcount == 2) {
@@ -836,19 +781,6 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
float co[3], coa[3], cob[3], midco[3];
float va_pipe[3], vb_pipe[3];
-#ifdef USE_ALTERNATE_ADJ
- /* ordered as follows (orig, prev, center, next)*/
- float quad_plane[4][3];
- float quad_orig[4][3];
-#endif
-
-
-#ifdef USE_ALTERNATE_ADJ
- /* the rest are initialized inline, this remains the same for all */
- vmesh_cent(vm, quad_plane[2]);
- copy_v3_v3(quad_orig[2], bv->v->co);
-#endif
-
n = vm->count;
ns = vm->seg;
ns2 = ns / 2;
@@ -865,7 +797,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
float dir1[3], dir2[3];
sub_v3_v3v3(dir1, bv->v->co, BM_edge_other_vert(e1->e, bv->v)->co);
sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, bv->v)->co, bv->v->co);
- if (angle_v3v3(dir1, dir2) < 100.0f * (float)BEVEL_EPSILON) {
+ if (angle_v3v3(dir1, dir2) < 100.0f * BEVEL_EPSILON) {
epipe = e1;
break;
}
@@ -908,37 +840,6 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(nv->co, cob);
nv->v = nvnext->v;
-#ifdef USE_ALTERNATE_ADJ
- /* plane */
- copy_v3_v3(quad_plane[0], v->nv.co);
- mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co);
- /* quad[2] is set */
- mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co);
-
- /* orig */
- copy_v3_v3(quad_orig[0], v->nv.co); /* only shared location between 2 quads */
- project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig[1]);
- project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig[3]);
-
- //bl_debug_draw_quad_add(UNPACK4(quad_plane));
- //bl_debug_draw_quad_add(UNPACK4(quad_orig));
-#endif
-
-#ifdef USE_ALTERNATE_ADJ
- for (k = 1; k < ns; k++) {
- float uv[2];
- float fac;
- float co_plane[3];
- float co_orig[3];
-
- get_point_uv(uv, v->ebev->seg, ring, k);
- get_point_on_round_edge(uv, quad_plane, co_plane);
- get_point_on_round_edge(uv, quad_orig, co_orig);
- fac = get_point_uv_factor(uv);
- interp_v3_v3v3(co, co_plane, co_orig, fac);
- copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
- }
-#else
/* TODO: better calculation of new midarc point? */
project_to_edge(v->ebev->e, coa, cob, midco);
@@ -952,7 +853,6 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(va_pipe, mesh_vert(vm, i, 0, 0)->co);
copy_v3_v3(vb_pipe, mesh_vert(vm, i, 0, ns)->co);
}
-#endif
}
} while ((v = v->next) != vm->boundstart);
}
@@ -980,9 +880,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
if (epipe)
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
-#ifndef USE_ALTERNATE_ADJ
copy_v3_v3(nv->co, co);
-#endif
BLI_assert(nv->v == NULL && nvprev->v == NULL);
create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
copy_mesh_vert(vm, vprev->index, k, ns - ring, i, ring, k);
@@ -1031,9 +929,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co);
if (epipe)
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
-#ifndef USE_ALTERNATE_ADJ
copy_v3_v3(nv->co, co);
-#endif
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
@@ -1043,9 +939,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
mid_v3_v3v3(co, nvprev->co, nv->co);
if (epipe)
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
-#ifndef USE_ALTERNATE_ADJ
copy_v3_v3(nv->co, co);
-#endif
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
@@ -1055,9 +949,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
mid_v3_v3v3(co, nv->co, nvnext->co);
if (epipe)
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
-#ifndef USE_ALTERNATE_ADJ
copy_v3_v3(nv->co, co);
-#endif
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
@@ -1137,7 +1029,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
/* Make center ngon if odd number of segments and fully beveled */
if (ns % 2 == 1 && vm->count == bv->selcount) {
BMVert **vv = NULL;
- BLI_array_declare(vv);
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
v = vm->boundstart;
do {
@@ -1155,7 +1047,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
if (vm->count > bv->selcount) {
int j;
BMVert **vv = NULL;
- BLI_array_declare(vv);
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
v = vm->boundstart;
f = boundvert_rep_face(v);
@@ -1210,6 +1102,413 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
}
+static VMesh *new_adj_subdiv_vmesh(MemArena *mem_arena, int count, int seg, BoundVert *bounds)
+{
+ VMesh *vm;
+
+ vm = (VMesh *)BLI_memarena_alloc(mem_arena, sizeof(VMesh));
+ vm->count = count;
+ vm->seg = seg;
+ vm->boundstart = bounds;
+ vm->mesh = (NewVert *)BLI_memarena_alloc(mem_arena, count * (1 + seg / 2) * (1 + seg) * sizeof(NewVert));
+ vm->mesh_kind = M_ADJ_SUBDIV;
+ return vm;
+}
+
+/* VMesh verts for vertex i have data for (i, 0 <= j <= ns2, 0 <= k <= ns), where ns2 = floor(nseg / 2).
+ * But these overlap data from previous and next i: there are some forced equivalences.
+ * Let's call these indices the canonical ones: we will just calculate data for these
+ * 0 <= j <= ns2, 0 <= k < ns2 (for odd ns2)
+ * 0 <= j < ns2, 0 <= k <= ns2 (for even ns2)
+ * also (j=ns2, k=ns2) at i=0 (for even ns2)
+ * This function returns the canonical one for any i, j, k in [0,n],[0,ns],[0,ns] */
+static NewVert *mesh_vert_canon(VMesh *vm, int i, int j, int k)
+{
+ int n, ns, ns2, odd;
+ NewVert *ans;
+
+ n = vm->count;
+ ns = vm->seg;
+ ns2 = ns / 2;
+ odd = ns % 2;
+ BLI_assert(0 <= i && i <= n && 0 <= j && j <= ns && 0 <= k && k <= ns);
+
+ if (!odd && j == ns2 && k == ns2)
+ ans = mesh_vert(vm, 0, j, k);
+ else if (j <= ns2 - 1 + odd && k <= ns2)
+ ans = mesh_vert(vm, i, j, k);
+ else if (k <= ns2)
+ ans = mesh_vert(vm, (i + n - 1) % n, k, ns - j);
+ else
+ ans = mesh_vert(vm, (i + 1) % n, ns - k, j);
+ return ans;
+}
+
+static int is_canon(VMesh *vm, int i, int j, int k)
+{
+ int ns2 = vm->seg / 2;
+ if (vm->seg % 2 == 1)
+ return (j <= ns2 && k <= ns2);
+ else
+ return ((j < ns2 && k <= ns2) || (j == ns2 && k == ns2 && i == 0));
+}
+
+/* Copy the vertex data to all of vm verts from canonical ones */
+static void vmesh_copy_equiv_verts(VMesh *vm)
+{
+ int n, ns, ns2, i, j, k;
+ NewVert *v0, *v1;
+
+ n = vm->count;
+ ns = vm->seg;
+ ns2 = ns / 2;
+ for (i = 0; i < n; i++) {
+ for (j = 0; j <= ns2; j++) {
+ for (k = 0; k <= ns; k++) {
+ if (is_canon(vm, i, j, k))
+ continue;
+ v1 = mesh_vert(vm, i, j, k);
+ v0 = mesh_vert_canon(vm, i, j, k);
+ copy_v3_v3(v1->co, v0->co);
+ v1->v = v0->v;
+ }
+ }
+ }
+}
+
+/* Calculate and return in r_cent the centroid of the center poly */
+static void vmesh_center(VMesh *vm, float r_cent[3])
+{
+ int n, ns2, i;
+
+ n = vm->count;
+ ns2 = vm->seg / 2;
+ if (vm->seg % 2) {
+ zero_v3(r_cent);
+ for (i = 0; i < n; i++) {
+ add_v3_v3(r_cent, mesh_vert(vm, i, ns2, ns2)->co);
+ }
+ mul_v3_fl(r_cent, 1.0f / (float) n);
+ }
+ else {
+ copy_v3_v3(r_cent, mesh_vert(vm, 0, ns2, ns2)->co);
+ }
+}
+
+/* Do one step of quadratic subdivision (Doo-Sabin), with special rules at boundaries.
+ * For now, this is written assuming vm0->nseg is odd.
+ * See Hwang-Chuang 2003 paper: "N-sided hole filling and vertex blending using subdivision surfaces" */
+static VMesh *quadratic_subdiv(MemArena *mem_arena, VMesh *vm0)
+{
+ int n, ns0, ns20, ns1 /*, ns21 */;
+ int i, j, k, j1, k1;
+ VMesh *vm1;
+ float co[3], co1[3], co2[3], co3[3], co4[3];
+ float co11[3], co21[3], co31[3], co41[3];
+ float denom;
+ const float wcorner[4] = {0.25f, 0.25f, 0.25f, 0.25f};
+ const float wboundary[4] = {0.375f, 0.375f, 0.125f, 0.125f}; /* {3, 3, 1, 1}/8 */
+ const float winterior[4] = {0.5625f, 0.1875f, 0.1875f, 0.0625f}; /* {9, 3, 3, 1}/16 */
+
+ n = vm0->count;
+ ns0 = vm0->seg;
+ ns20 = ns0 / 2;
+ BLI_assert(ns0 % 2 == 1);
+
+ ns1 = 2 * ns0 - 1;
+ // ns21 = ns1 / 2; /* UNUSED */
+ vm1 = new_adj_subdiv_vmesh(mem_arena, n, ns1, vm0->boundstart);
+
+ for (i = 0; i < n; i ++) {
+ /* For handle vm0 polys with lower left corner at (i,j,k) for
+ * j in [0, ns20], k in [0, ns20]; then the center ngon.
+ * but only fill in data for canonical verts of v1. */
+ for (j = 0; j <= ns20; j++) {
+ for (k = 0; k <= ns20; k++) {
+ if (j == ns20 && k == ns20)
+ continue; /* center ngon is special */
+ copy_v3_v3(co1, mesh_vert_canon(vm0, i, j, k)->co);
+ copy_v3_v3(co2, mesh_vert_canon(vm0, i, j, k + 1)->co);
+ copy_v3_v3(co3, mesh_vert_canon(vm0, i, j + 1, k + 1)->co);
+ copy_v3_v3(co4, mesh_vert_canon(vm0, i, j + 1, k)->co);
+ if (j == 0 && k == 0) {
+ /* corner */
+ copy_v3_v3(co11, co1);
+ interp_v3_v3v3(co21, co1, co2, 0.5f);
+ interp_v3_v3v3v3v3(co31, co1, co2, co3, co4, wcorner);
+ interp_v3_v3v3(co41, co1, co4, 0.5f);
+ }
+ else if (j == 0) {
+ /* ring 0 boundary */
+ interp_v3_v3v3(co11, co1, co2, 0.25f);
+ interp_v3_v3v3(co21, co1, co2, 0.75f);
+ interp_v3_v3v3v3v3(co31, co2, co3, co1, co4, wboundary);
+ interp_v3_v3v3v3v3(co41, co1, co4, co2, co3, wboundary);
+ }
+ else if (k == 0) {
+ /* ring-starts boundary */
+ interp_v3_v3v3(co11, co1, co4, 0.25f);
+ interp_v3_v3v3v3v3(co21, co1, co2, co3, co4, wboundary);
+ interp_v3_v3v3v3v3(co31, co3, co4, co1, co2, wboundary);
+ interp_v3_v3v3(co41, co1, co4, 0.75f);
+ }
+ else {
+ /* interior */
+ interp_v3_v3v3v3v3(co11, co1, co2, co4, co3, winterior);
+ interp_v3_v3v3v3v3(co21, co2, co1, co3, co4, winterior);
+ interp_v3_v3v3v3v3(co31, co3, co2, co4, co1, winterior);
+ interp_v3_v3v3v3v3(co41, co4, co1, co3, co2, winterior);
+ }
+ j1 = 2 * j;
+ k1 = 2 * k;
+ if (is_canon(vm1, i, j1, k1))
+ copy_v3_v3(mesh_vert(vm1, i, j1, k1)->co, co11);
+ if (is_canon(vm1, i, j1, k1 + 1))
+ copy_v3_v3(mesh_vert(vm1, i, j1, k1 + 1)->co, co21);
+ if (is_canon(vm1, i, j1 + 1, k1 + 1))
+ copy_v3_v3(mesh_vert(vm1, i, j1 + 1, k1 + 1)->co, co31);
+ if (is_canon(vm1, i, j1 + 1, k1))
+ copy_v3_v3(mesh_vert(vm1, i, j1 + 1, k1)->co, co41);
+ }
+ }
+
+ /* center ngon */
+ denom = 8.0f * (float) n;
+ zero_v3(co);
+ for (j = 0; j < n; j++) {
+ copy_v3_v3(co1, mesh_vert(vm0, j, ns20, ns20)->co);
+ if (i == j)
+ madd_v3_v3fl(co, co1, (4.0f * (float) n + 2.0f) / denom);
+ else if ((i + 1) % n == j || (i + n - 1) % n == j)
+ madd_v3_v3fl(co, co1, ((float) n + 2.0f) / denom);
+ else
+ madd_v3_v3fl(co, co1, 2.0f / denom);
+ }
+ copy_v3_v3(mesh_vert(vm1, i, 2 * ns20, 2 * ns20)->co, co);
+ }
+
+ vmesh_copy_equiv_verts(vm1);
+ return vm1;
+}
+
+/* After a step of quadratic_subdiv, adjust the ring 1 verts to be on the planes of their respective faces,
+ * so that the cross-tangents will match on further subdivision. */
+static void fix_vmesh_tangents(VMesh *vm, BevVert *bv)
+{
+ int i, n;
+ NewVert *v;
+ BoundVert *bndv;
+ float co[3];
+
+ n = vm->count;
+ bndv = vm->boundstart;
+ do {
+ i = bndv->index;
+
+ /* (i, 1, 1) snap to edge line */
+ v = mesh_vert(vm, i, 1, 1);
+ closest_to_line_v3(co, v->co, bndv->nv.co, bv->v->co);
+ copy_v3_v3(v->co, co);
+ copy_v3_v3(mesh_vert(vm, (i + n -1) % n, 1, vm->seg - 1)->co, co);
+
+ /* Also want (i, 1, k) snapped to plane of adjacent face for
+ * 1 < k < ns - 1, but current initial cage and subdiv rules
+ * ensure this, so nothing to do */
+ } while ((bndv = bndv->next) != vm->boundstart);
+}
+
+/* Fill frac with fractions of way along ring 0 for vertex i, for use with interp_range function */
+static void fill_vmesh_fracs(VMesh *vm, float *frac, int i)
+{
+ int k, ns;
+ float total = 0.0f;
+
+ ns = vm->seg;
+ frac[0] = 0.0f;
+ for (k = 0; k < ns; k++) {
+ total += len_v3v3(mesh_vert(vm, i, 0, k)->co, mesh_vert(vm, i, 0, k + 1)->co);
+ frac[k + 1] = total;
+ }
+ if (total > BEVEL_EPSILON) {
+ for (k = 1; k <= ns; k++)
+ frac[k] /= total;
+ }
+}
+
+/* Return i such that frac[i] <= f <= frac[i + 1], where frac[n] == 1.0
+ * and put fraction of rest of way between frac[i] and frac[i + 1] into r_rest */
+static int interp_range(const float *frac, int n, const float f, float *r_rest)
+{
+ int i;
+ float rest;
+
+ /* could binary search in frac, but expect n to be reasonably small */
+ for (i = 0; i < n; i++) {
+ if (f <= frac[i + 1]) {
+ rest = f - frac[i];
+ if (rest == 0)
+ *r_rest = 0.0f;
+ else
+ *r_rest = rest / (frac[i + 1] - frac[i]);
+ return i;
+ }
+ }
+ *r_rest = 0.0f;
+ return n;
+}
+
+/* Interpolate given vmesh to make one with target nseg and evenly spaced border vertices */
+static VMesh *interp_vmesh(MemArena *mem_arena, VMesh *vm0, int nseg)
+{
+ int n, ns0, nseg2, odd, i, j, k, j0, k0;
+ float *prev_frac, *frac, f, restj, restk;
+ float quad[4][3], co[3], center[3];
+ VMesh *vm1;
+
+ n = vm0->count;
+ ns0 = vm0->seg;
+ nseg2 = nseg / 2;
+ odd = nseg % 2;
+ vm1 = new_adj_subdiv_vmesh(mem_arena, n, nseg, vm0->boundstart);
+ prev_frac = (float *)BLI_memarena_alloc(mem_arena, (ns0 + 1 ) *sizeof(float));
+ frac = (float *)BLI_memarena_alloc(mem_arena, (ns0 + 1 ) *sizeof(float));
+
+ fill_vmesh_fracs(vm0, prev_frac, n - 1);
+ fill_vmesh_fracs(vm0, frac, 0);
+ for (i = 0; i < n; i++) {
+ for (j = 0; j <= nseg2 -1 + odd; j++) {
+ for (k = 0; k <= nseg2; k++) {
+ f = (float) k / (float) nseg;
+ k0 = interp_range(frac, ns0, f, &restk);
+ f = 1.0f - (float) j / (float) nseg;
+ j0 = interp_range(prev_frac, ns0, f, &restj);
+ if (restj < BEVEL_EPSILON) {
+ j0 = ns0 - j0;
+ restj = 0.0f;
+ }
+ else {
+ j0 = ns0 - j0 - 1;
+ restj = 1.0f - restj;
+ }
+ /* Use bilinear interpolation within the source quad; could be smarter here */
+ if (restj < BEVEL_EPSILON && restk < BEVEL_EPSILON) {
+ copy_v3_v3(co, mesh_vert_canon(vm0, i, j0, k0)->co);
+ }
+ else {
+ copy_v3_v3(quad[0], mesh_vert_canon(vm0, i, j0, k0)->co);
+ copy_v3_v3(quad[1], mesh_vert_canon(vm0, i, j0, k0 + 1)->co);
+ copy_v3_v3(quad[2], mesh_vert_canon(vm0, i, j0 + 1, k0 + 1)->co);
+ copy_v3_v3(quad[3], mesh_vert_canon(vm0, i, j0 + 1, k0)->co);
+ interp_bilinear_quad_v3(quad, restk, restj, co);
+ }
+ copy_v3_v3(mesh_vert(vm1, i, j, k)->co, co);
+ }
+ }
+ }
+ if (!odd) {
+ vmesh_center(vm0, center);
+ copy_v3_v3(mesh_vert(vm1, 0, nseg2, nseg2)->co, center);
+ }
+ vmesh_copy_equiv_verts(vm1);
+ return vm1;
+}
+
+/*
+ * Given that the boundary is built and the boundary BMVerts have been made,
+ * calculate the positions of the interior mesh points for the M_ADJ_SUBDIV pattern,
+ * then make the BMVerts and the new faces. */
+static void bevel_build_rings_subdiv(BevelParams *bp, BMesh *bm, BevVert *bv)
+{
+ int n, ns, ns2, odd, i, j, k;
+ VMesh *vm0, *vm1, *vm;
+ float coa[3], cob[3], coc[3];
+ BoundVert *v;
+ BMVert *bmv1, *bmv2, *bmv3, *bmv4;
+ BMFace *f;
+ MemArena *mem_arena = bp->mem_arena;
+ const float fullness = 0.5f;
+
+ n = bv->edgecount;
+ ns = bv->vmesh->seg;
+ ns2 = ns / 2;
+ odd = ns % 2;
+ BLI_assert(n >= 3 && ns > 1);
+
+ /* First construct an initial control mesh, with nseg==3 */
+ vm0 = new_adj_subdiv_vmesh(mem_arena, n, 3, bv->vmesh->boundstart);
+
+ for (i = 0; i < n; i++) {
+ /* Boundaries just divide input polygon edges into 3 even segments */
+ copy_v3_v3(coa, mesh_vert(bv->vmesh, i, 0, 0)->co);
+ copy_v3_v3(cob, mesh_vert(bv->vmesh, (i + 1) % n, 0, 0)->co);
+ copy_v3_v3(coc, mesh_vert(bv->vmesh, (i + n -1) % n, 0, 0)->co);
+ copy_v3_v3(mesh_vert(vm0, i, 0, 0)->co, coa);
+ interp_v3_v3v3(mesh_vert(vm0, i, 0, 1)->co, coa, cob, 1.0f / 3.0f);
+ interp_v3_v3v3(mesh_vert(vm0, i, 1, 0)->co, coa, coc, 1.0f / 3.0f);
+ interp_v3_v3v3(mesh_vert(vm0, i, 1, 1)->co, coa, bv->v->co, fullness);
+ }
+ vmesh_copy_equiv_verts(vm0);
+
+ vm1 = vm0;
+ do {
+ vm1 = quadratic_subdiv(mem_arena, vm1);
+ fix_vmesh_tangents(vm1, bv);
+ } while (vm1->seg <= ns);
+ vm1 = interp_vmesh(mem_arena, vm1, ns);
+
+ /* copy final vmesh into bv->vmesh, make BMVerts and BMFaces */
+ vm = bv->vmesh;
+ for (i = 0; i < n; i ++) {
+ for (j = 0; j <= ns2; j++) {
+ for (k = 0; k <= ns; k++) {
+ if (j == 0 && (k == 0 || k == ns))
+ continue; /* boundary corners already made */
+ if (!is_canon(vm, i, j, k))
+ continue;
+ copy_v3_v3(mesh_vert(vm, i, j, k)->co, mesh_vert(vm1, i, j, k)->co);
+ create_mesh_bmvert(bm, vm, i, j, k, bv->v);
+ }
+ }
+ }
+ vmesh_copy_equiv_verts(vm);
+ /* make the polygons */
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ f = boundvert_rep_face(v);
+ /* For odd ns, make polys with lower left corner at (i,j,k) for
+ * j in [0, ns2-1], k in [0, ns2]. And then the center ngon.
+ * For even ns,
+ * j in [0, ns2-1], k in [0, ns2-1] */
+ for (j = 0; j < ns2; j++) {
+ for (k = 0; k < ns2 + odd; k++) {
+ bmv1 = mesh_vert(vm, i, j, k)->v;
+ bmv2 = mesh_vert(vm, i, j, k + 1)->v;
+ bmv3 = mesh_vert(vm, i, j + 1, k + 1)->v;
+ bmv4 = mesh_vert(vm, i, j + 1, k)->v;
+ BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
+ bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f);
+ }
+ }
+ } while ((v = v->next) != vm->boundstart);
+
+ /* center ngon */
+ if (odd) {
+ BMVert **vv = NULL;
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
+
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
+ } while ((v = v->next) != vm->boundstart);
+ f = boundvert_rep_face(vm->boundstart);
+ bev_create_ngon(bm, vv, BLI_array_count(vv), f);
+
+ BLI_array_free(vv);
+ }
+}
+
static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv)
{
BMFace *f;
@@ -1217,7 +1516,7 @@ static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv)
VMesh *vm = bv->vmesh;
BoundVert *v;
BMVert **vv = NULL;
- BLI_array_declare(vv);
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
v = vm->boundstart;
n = 0;
@@ -1273,7 +1572,7 @@ static void bevel_build_trifan(BMesh *bm, BevVert *bv)
else { BLI_assert(0); }
}
else {
- if (l_fan->v == v_fan) { l_fan = l_fan; }
+ if (l_fan->v == v_fan) { /* l_fan = l_fan; */ }
else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; }
else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; }
else { BLI_assert(0); }
@@ -1322,30 +1621,14 @@ static void bevel_build_quadstrip(BMesh *bm, BevVert *bv)
/* Given that the boundary is built, now make the actual BMVerts
* for the boundary and the interior of the vertex mesh. */
-static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
+static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
{
+ MemArena *mem_arena = bp->mem_arena;
VMesh *vm = bv->vmesh;
BoundVert *v, *weld1, *weld2;
int n, ns, ns2, i, k, weld;
float *va, *vb, co[3];
-
-#ifdef USE_ALTERNATE_ADJ
- /* ordered as follows (orig, prev, center, next)*/
- float quad_plane[4][3];
- float quad_orig_a[4][3];
- float quad_orig_b[4][3];
- const int is_odd = (vm->seg % 2);
-#else
float midco[3];
-#endif
-
-#ifdef USE_ALTERNATE_ADJ
- /* the rest are initialized inline, this remains the same for all */
- /* NOTE; in this usage we only interpolate on the 'V' so cent and next points are unused (2,3)*/
- vmesh_cent(vm, quad_plane[2]);
- copy_v3_v3(quad_orig_a[2], bv->v->co);
- copy_v3_v3(quad_orig_b[2], bv->v->co);
-#endif
n = vm->count;
ns = vm->seg;
@@ -1378,69 +1661,21 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
i = v->index;
copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0);
if (v->ebev) {
-
-#ifdef USE_ALTERNATE_ADJ
- copy_v3_v3(quad_plane[0], v->nv.co);
- mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co);
- /* quad[2] is set */
- mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co);
-
- /* orig 'A' */
- copy_v3_v3(quad_orig_a[0], v->nv.co); /* only shared location between 2 quads */
- project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_a[1]);
- project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_a[3]);
-
- /* orig 'B' */
- copy_v3_v3(quad_orig_b[3], v->next->nv.co); /* only shared location between 2 quads */
- project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_b[1]);
- project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_b[0]);
-
- //bl_debug_draw_quad_add(UNPACK4(quad_plane));
- //bl_debug_draw_quad_add(UNPACK4(quad_orig_a));
- //bl_debug_draw_quad_add(UNPACK4(quad_orig_b));
-#endif /* USE_ALTERNATE_ADJ */
-
-#ifdef USE_ALTERNATE_ADJ
- for (k = 1; k < ns; k++) {
- float uv[2];
- float fac;
- float co_plane[3];
- float co_orig[3];
-
- /* quad_plane */
- get_point_uv(uv, v->ebev->seg, 0, k);
- get_point_on_round_edge(uv, quad_plane, co_plane);
-
- /* quad_orig */
- /* each half has different UV's */
- if (k <= ns2) {
- get_point_uv(uv, v->ebev->seg, 0, k);
- get_point_on_round_edge(uv, quad_orig_a, co_orig);
- }
- else {
- get_point_uv(uv, v->ebev->seg, 0, (k - ns2) - (is_odd ? 0.5f : 0.0f));
- get_point_on_round_edge(uv, quad_orig_b, co_orig);
- uv[1] = 1.0f - uv[1]; /* so we can get the factor */
- }
- fac = get_point_uv_factor(uv);
-
- /* done. interp */
- interp_v3_v3v3(co, co_plane, co_orig, fac);
- copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
- if (!weld)
- create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
- }
-#else /* USE_ALTERNATE_ADJ */
va = mesh_vert(vm, i, 0, 0)->co;
vb = mesh_vert(vm, i, 0, ns)->co;
- project_to_edge(v->ebev->e, va, vb, midco);
+ if (bv->edgecount == 3 && bv->selcount == 1) {
+ /* special case: profile cuts the third face, so line it up with that */
+ copy_v3_v3(midco, bv->v->co);
+ }
+ else {
+ project_to_edge(v->ebev->e, va, vb, midco);
+ }
for (k = 1; k < ns; k++) {
get_point_on_round_edge(v->ebev, k, va, midco, vb, co);
copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
if (!weld)
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
}
-#endif /* !USE_ALTERNATE_ADJ */
}
} while ((v = v->next) != vm->boundstart);
@@ -1467,6 +1702,9 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
case M_ADJ:
bevel_build_rings(bm, bv);
break;
+ case M_ADJ_SUBDIV:
+ bevel_build_rings_subdiv(bp, bm, bv);
+ break;
case M_TRI_FAN:
bevel_build_trifan(bm, bv);
break;
@@ -1477,9 +1715,9 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
}
/* take care, this flag isn't cleared before use, it just so happens that its not set */
-#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_elem_flag_enable( (bme)->l, BM_ELEM_TAG)
-#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_elem_flag_disable( (bme)->l, BM_ELEM_TAG)
-#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_elem_flag_test( (bme)->l, BM_ELEM_TAG)
+#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_ELEM_API_FLAG_ENABLE( (bme), _FLAG_OVERLAP)
+#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_ELEM_API_FLAG_DISABLE( (bme), _FLAG_OVERLAP)
+#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_ELEM_API_FLAG_TEST( (bme), _FLAG_OVERLAP)
/*
* Construction around the vertex
@@ -1488,10 +1726,11 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
{
BMEdge *bme;
BevVert *bv;
- BMEdge *bme2, *unflagged_bme;
+ BMEdge *bme2, *unflagged_bme, *first_bme;
BMFace *f;
BMIter iter, iter2;
EdgeHalf *e;
+ float weight;
int i, found_shared_face, ccw_test_sum;
int nsel = 0;
int ntot = 0;
@@ -1500,15 +1739,23 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
* Only bevel selected edges that have exactly two incident faces.
*/
+ if (bp->vertex_only)
+ first_bme = v->e;
+ else
+ first_bme = NULL;
BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(bme, BM_ELEM_TAG)) {
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
BLI_assert(BM_edge_is_manifold(bme));
nsel++;
+ if (!first_bme)
+ first_bme = bme;
}
ntot++;
+
+ BM_BEVEL_EDGE_TAG_DISABLE(bme);
}
- if (nsel == 0) {
+ if ((nsel == 0 && !bp->vertex_only) || (ntot < 3 && bp->vertex_only)) {
/* signal this vert isn't being beveled */
BM_elem_flag_disable(v, BM_ELEM_TAG);
return;
@@ -1522,15 +1769,29 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
bv->v = v;
bv->edgecount = ntot;
bv->selcount = nsel;
+ bv->offset = bp->offset;
bv->edges = (EdgeHalf *)BLI_memarena_alloc(bp->mem_arena, ntot * sizeof(EdgeHalf));
bv->vmesh = (VMesh *)BLI_memarena_alloc(bp->mem_arena, sizeof(VMesh));
bv->vmesh->seg = bp->seg;
BLI_ghash_insert(bp->vert_hash, v, bv);
+ if (bp->vertex_only) {
+ /* if weighted, modify offset by weight */
+ if (bp->dvert != NULL && bp->vertex_group != -1) {
+ weight = defvert_find_weight(bp->dvert + BM_elem_index_get(v), bp->vertex_group);
+ if (weight <= 0.0f) {
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ return;
+ }
+ bv->offset *= weight;
+ }
+ }
+
/* add edges to bv->edges in order that keeps adjacent edges sharing
* a face, if possible */
i = 0;
- bme = v->e;
+
+ bme = first_bme;
BM_BEVEL_EDGE_TAG_ENABLE(bme);
e = &bv->edges[0];
e->e = bme;
@@ -1544,6 +1805,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
continue;
if (!unflagged_bme)
unflagged_bme = bme2;
+ if (!bme->l)
+ continue;
BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) {
if (BM_face_edge_share_loop(f, bme)) {
found_shared_face = 1;
@@ -1565,7 +1828,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
}
bme = e->e;
BM_BEVEL_EDGE_TAG_ENABLE(bme);
- if (BM_elem_flag_test(bme, BM_ELEM_TAG)) {
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
e->is_bev = TRUE;
e->seg = bp->seg;
}
@@ -1574,11 +1837,20 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
e->seg = 0;
}
e->is_rev = (bme->v2 == v);
- e->offset = e->is_bev ? bp->offset : 0.0f;
+ if (e->is_bev) {
+ e->offset = bp->offset;
+ if (bp->use_weights) {
+ weight = BM_elem_float_data_get(&bm->edata, bme, CD_BWEIGHT);
+ e->offset *= weight;
+ }
+ }
+ else {
+ e->offset = 0.0f;
+ }
}
/* find wrap-around shared face */
BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) {
- if (BM_face_edge_share_loop(f, bv->edges[0].e)) {
+ if (bv->edges[0].e->l && BM_face_edge_share_loop(f, bv->edges[0].e)) {
if (bv->edges[0].fnext == f)
continue; /* if two shared faces, want the other one now */
bv->edges[ntot - 1].fnext = f;
@@ -1621,8 +1893,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
BM_BEVEL_EDGE_TAG_DISABLE(e->e);
}
- build_boundary(bp->mem_arena, bv);
- build_vmesh(bp->mem_arena, bm, bv);
+ build_boundary(bp, bv);
+ build_vmesh(bp, bm, bv);
}
/* Face f has at least one beveled vertex. Rebuild f */
@@ -1665,6 +1937,14 @@ static int bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
BLI_array_append(vv, bmv);
}
}
+ else if (bp->vertex_only && vm->mesh_kind == M_ADJ_SUBDIV && vm->seg > 1) {
+ BLI_assert(v->prev == vend);
+ i = vend->index;
+ for (k = vm->seg - 1; k > 0; k--) {
+ bmv = mesh_vert(vm, i, 0, k)->v;
+ BLI_array_append(vv, bmv);
+ }
+ }
v = v->prev;
BLI_array_append(vv, v->nv.v);
}
@@ -1785,7 +2065,9 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
*
* \warning all tagged edges _must_ be manifold.
*/
-void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
+ const bool vertex_only, const bool use_weights,
+ const struct MDeformVert *dvert, const int vertex_group)
{
BMIter iter;
BMVert *v;
@@ -1794,6 +2076,10 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
bp.offset = offset;
bp.seg = segments;
+ bp.vertex_only = vertex_only;
+ bp.use_weights = use_weights;
+ bp.dvert = dvert;
+ bp.vertex_group = vertex_group;
if (bp.offset > 0) {
/* primary alloc */
@@ -1809,9 +2095,11 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
}
/* Build polygons for edges */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
- bevel_build_edge_polygons(bm, &bp, e);
+ if (!bp.vertex_only) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ bevel_build_edge_polygons(bm, &bp, e);
+ }
}
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
index a80e4f3a4a2..f214125fa1c 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.h
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -27,6 +27,10 @@
* \ingroup bmesh
*/
-void BM_mesh_bevel(BMesh *bm, const float offset, const float segments);
+struct MDeformVert;
+
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
+ const bool vertex_only, const bool use_weights,
+ const struct MDeformVert *dvert, const int vertex_group);
#endif /* __BMESH_BEVEL_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index 4a557c20ae3..d3eaf1c6670 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -27,15 +27,15 @@
* \ingroup bmesh
*/
-void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, const int do_triangulate);
+void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, const bool do_triangulate);
-void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int tag_only);
+void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool tag_only);
void BM_mesh_decimate_unsubdivide(BMesh *bm, const int iterations);
-void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries,
+void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
BMVert **vinput_arr, const int vinput_len,
BMEdge **einput_arr, const int einput_len);
-void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries);
+void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries);
/* these weights are accumulated so too high values may reach 'inf' too quickly */
#define BM_MESH_DECIM_WEIGHT_MAX 100000.0f
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 7c054d84405..e94bb9f5417 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -134,7 +134,7 @@ static void bm_decim_calc_target_co(BMEdge *e, float optimize_co[3],
}
}
-static int bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_co[3])
+static bool bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_co[3])
{
BMIter liter;
BMLoop *l;
@@ -172,16 +172,16 @@ static int bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_c
#endif
/* use a small value rather then zero so we don't flip a face in multiple steps
- * (first making it zero area, then flipping again)*/
+ * (first making it zero area, then flipping again) */
if (dot_v3v3(cross_exist, cross_optim) <= FLT_EPSILON) {
//printf("no flip\n");
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
static void bm_decim_build_edge_cost_single(BMEdge *e,
@@ -291,15 +291,15 @@ static void bm_decim_build_edge_cost(BMesh *bm,
* collapsing edges so even has some advantage over decimating quads
* directly.
*
- * \return TRUE if any faces were triangulated.
+ * \return true if any faces were triangulated.
*/
-static int bm_decim_triangulate_begin(BMesh *bm)
+static bool bm_decim_triangulate_begin(BMesh *bm)
{
BMIter iter;
BMFace *f;
- // int has_quad; // could optimize this a little
- int has_cut = FALSE;
+ // bool has_quad; // could optimize this a little
+ bool has_cut = false;
BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
@@ -345,7 +345,7 @@ static int bm_decim_triangulate_begin(BMesh *bm)
}
#ifdef USE_SAFETY_CHECKS
- if (BM_edge_exists(l_a->v, l_b->v) == FALSE)
+ if (BM_edge_exists(l_a->v, l_b->v) == false)
#endif
{
BMFace *f_new;
@@ -355,7 +355,7 @@ static int bm_decim_triangulate_begin(BMesh *bm)
* - if there is a quad that has a free standing edge joining it along
* where we want to split the face, there isnt a good way we can handle this.
* currently that edge will get removed when joining the tris back into a quad. */
- f_new = BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, FALSE);
+ f_new = BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, false);
if (f_new) {
/* the value of this doesn't matter, only that the 2 loops match and have unique values */
@@ -370,7 +370,7 @@ static int bm_decim_triangulate_begin(BMesh *bm)
BM_face_normal_update(f);
BM_face_normal_update(f_new);
- has_cut = TRUE;
+ has_cut = true;
}
}
}
@@ -410,15 +410,15 @@ static void bm_decim_triangulate_end(BMesh *bm)
BM_vert_in_edge(e, l_b->next->v) ? l_b->prev->v : l_b->next->v,
};
- BLI_assert(ELEM3(vquad[0], vquad[1], vquad[2], vquad[3]) == FALSE);
- BLI_assert(ELEM3(vquad[1], vquad[0], vquad[2], vquad[3]) == FALSE);
- BLI_assert(ELEM3(vquad[2], vquad[1], vquad[0], vquad[3]) == FALSE);
- BLI_assert(ELEM3(vquad[3], vquad[1], vquad[2], vquad[0]) == FALSE);
+ BLI_assert(ELEM3(vquad[0], vquad[1], vquad[2], vquad[3]) == false);
+ BLI_assert(ELEM3(vquad[1], vquad[0], vquad[2], vquad[3]) == false);
+ BLI_assert(ELEM3(vquad[2], vquad[1], vquad[0], vquad[3]) == false);
+ BLI_assert(ELEM3(vquad[3], vquad[1], vquad[2], vquad[0]) == false);
if (is_quad_convex_v3(vquad[0]->co, vquad[1]->co, vquad[2]->co, vquad[3]->co)) {
/* highly unlikely to fail, but prevents possible double-ups */
BMFace *f[2] = {l_a->f, l_b->f};
- BM_faces_join(bm, f, 2, TRUE);
+ BM_faces_join(bm, f, 2, true);
}
}
}
@@ -441,9 +441,11 @@ static void bm_decim_triangulate_end(BMesh *bm)
static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_clear, BMVert *v_other,
const float customdata_fac)
{
+ /* disable seam check - the seam check would have to be done per layer, its not really that important */
+//#define USE_SEAM
/* these don't need to be updated, since they will get removed when the edge collapses */
BMLoop *l_clear, *l_other;
- const int is_manifold = BM_edge_is_manifold(l->e);
+ const bool is_manifold = BM_edge_is_manifold(l->e);
int side;
/* l defines the vert to collapse into */
@@ -464,7 +466,9 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
/* now we have both corners of the face 'l->f' */
for (side = 0; side < 2; side++) {
- int is_seam = FALSE;
+#ifdef USE_SEAM
+ bool is_seam = false;
+#endif
void *src[2];
BMFace *f_exit = is_manifold ? l->radial_next->f : NULL;
BMEdge *e_prev = l->e;
@@ -501,34 +505,40 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
break;
}
+#ifdef USE_SEAM
/* break out unless we find a match */
- is_seam = TRUE;
+ is_seam = true;
+#endif
/* ok. we have a loop. now be smart with it! */
for (i = 0; i < bm->ldata.totlayer; i++) {
if (CustomData_layer_has_math(&bm->ldata, i)) {
const int offset = bm->ldata.layers[i].offset;
const int type = bm->ldata.layers[i].type;
- void *cd_src, *cd_iter;
-
- /* todo, make nicer macros for this */
- cd_src = (char *)src[0] + offset;
- // cd_dst = (char *)src[1] + offset; // UNUSED
- cd_iter = (char *)l_iter->head.data + offset;
+ void *cd_src[2] = {(char *)src[0] + offset,
+ (char *)src[1] + offset};
+ void *cd_iter = (char *)l_iter->head.data + offset;
/* detect seams */
- if (CustomData_data_equals(type, cd_src, cd_iter)) {
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_iter->head.data);
- is_seam = FALSE;
+ if (CustomData_data_equals(type, cd_src[0], cd_iter)) {
+ CustomData_bmesh_interp_n(&bm->ldata, cd_src, w, NULL, 2, l_iter->head.data, i);
+#ifdef USE_SEAM
+ is_seam = false;
+#endif
}
}
}
+#ifdef USE_SEAM
if (is_seam) {
break;
}
+#endif
}
}
+
+//#undef USE_SEAM
+
}
#endif /* USE_CUSTOMDATA */
@@ -588,7 +598,7 @@ BLI_INLINE int bm_edge_is_manifold_or_boundary(BMLoop *l)
#endif
}
-static int bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
+static bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
{
/* simply check that there is no overlap between faces and edges of each vert,
* (excluding the 2 faces attached to 'e' and 'e' its self) */
@@ -599,7 +609,7 @@ static int bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
e_iter = e_first;
do {
if (!bm_edge_is_manifold_or_boundary(e_iter->l)) {
- return TRUE;
+ return true;
}
bm_edge_tag_disable(e_iter);
} while ((e_iter = bmesh_disk_edge_next(e_iter, e_first->v1)) != e_first);
@@ -607,7 +617,7 @@ static int bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
e_iter = e_first;
do {
if (!bm_edge_is_manifold_or_boundary(e_iter->l)) {
- return TRUE;
+ return true;
}
bm_edge_tag_disable(e_iter);
} while ((e_iter = bmesh_disk_edge_next(e_iter, e_first->v2)) != e_first);
@@ -663,11 +673,11 @@ static int bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
e_iter = e_first;
do {
if (bm_edge_tag_test(e_iter)) {
- return TRUE;
+ return true;
}
} while ((e_iter = bmesh_disk_edge_next(e_iter, e_first->v2)) != e_first);
- return FALSE;
+ return false;
}
/**
@@ -680,13 +690,13 @@ static int bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
* \param e_clear_other let caller know what edges we remove besides \a e_clear
* \param customdata_flag merge factor, scales from 0 - 1 ('v_clear' -> 'v_other')
*/
-static int bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_e_clear_other[2],
+static bool bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_e_clear_other[2],
#ifdef USE_CUSTOMDATA
- const CD_UseFlag customdata_flag,
- const float customdata_fac
+ const CD_UseFlag customdata_flag,
+ const float customdata_fac
#else
- const CD_UseFlag UNUSED(customdata_flag),
- const float UNUSED(customdata_fac)
+ const CD_UseFlag UNUSED(customdata_flag),
+ const float UNUSED(customdata_fac)
#endif
)
{
@@ -698,11 +708,11 @@ static int bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_e
if (BM_edge_is_manifold(e_clear)) {
BMLoop *l_a, *l_b;
BMEdge *e_a_other[2], *e_b_other[2];
- int ok;
+ bool ok;
ok = BM_edge_loop_pair(e_clear, &l_a, &l_b);
- BLI_assert(ok == TRUE);
+ BLI_assert(ok == true);
BLI_assert(l_a->f->len == 3);
BLI_assert(l_b->f->len == 3);
@@ -739,7 +749,7 @@ static int bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_e
if (ELEM(e_a_other[0], e_b_other[0], e_b_other[1]) ||
ELEM(e_a_other[1], e_b_other[0], e_b_other[1]))
{
- return FALSE;
+ return false;
}
r_e_clear_other[0] = BM_elem_index_get(e_a_other[0]);
@@ -772,7 +782,7 @@ static int bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_e
// BM_mesh_validate(bm);
- return TRUE;
+ return true;
}
else if (BM_edge_is_boundary(e_clear)) {
/* same as above but only one triangle */
@@ -819,10 +829,10 @@ static int bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_e
// BM_mesh_validate(bm);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
@@ -859,7 +869,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
}
/* use for customdata merging */
- if (LIKELY(compare_v3v3(e->v1->co, e->v2->co, FLT_EPSILON) == FALSE)) {
+ if (LIKELY(compare_v3v3(e->v1->co, e->v2->co, FLT_EPSILON) == false)) {
customdata_fac = line_point_factor_v3(optimize_co, e->v1->co, e->v2->co);
#if 0
/* simple test for stupid collapse */
@@ -936,7 +946,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
else
e_outer = l->prev->e;
- BLI_assert(BM_vert_in_edge(e_outer, l->v) == FALSE);
+ BLI_assert(BM_vert_in_edge(e_outer, l->v) == false);
bm_decim_build_edge_cost_single(e_outer, vquadrics, vweights, eheap, eheap_table);
}
@@ -962,14 +972,14 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
* \param vweights Optional array of vertex aligned weights [0 - 1],
* a vertex group is the usual source for this.
*/
-void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, const int do_triangulate)
+void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, const bool do_triangulate)
{
Heap *eheap; /* edge heap */
HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */
Quadric *vquadrics; /* vert index aligned quadrics */
int tot_edge_orig;
int face_tot_target;
- int use_triangulate;
+ bool use_triangulate;
CD_UseFlag customdata_flag = 0;
@@ -1005,7 +1015,7 @@ void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, c
/* iterative edge collapse and maintain the eheap */
while ((bm->totface > face_tot_target) &&
- (BLI_heap_is_empty(eheap) == FALSE) &&
+ (BLI_heap_is_empty(eheap) == false) &&
(BLI_heap_node_value(BLI_heap_top(eheap)) != COST_INVALID))
{
// const float value = BLI_heap_node_value(BLI_heap_top(eheap));
@@ -1023,7 +1033,7 @@ void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, c
#ifdef USE_TRIANGULATE
- if (do_triangulate == FALSE) {
+ if (do_triangulate == false) {
/* its possible we only had triangles, skip this step in that case */
if (LIKELY(use_triangulate)) {
/* temp convert quads to triangles */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index f67f01e4585..3a724769f2a 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -69,7 +69,7 @@ static int dissolve_elem_cmp(const void *a1, const void *a2)
return 0;
}
-void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries,
+void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
BMVert **vinput_arr, const int vinput_len,
BMEdge **einput_arr, const int einput_len)
{
@@ -117,7 +117,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
BMFace *nf = BM_faces_join_pair(bm, e->l->f,
e->l->radial_next->f,
e,
- FALSE); /* join faces */
+ false); /* join faces */
/* there may be some errors, we don't mind, just move on */
if (nf) {
@@ -148,7 +148,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
for (i = bm->totedge - 1; i != -1; i--) {
e_iter = earray[i];
- if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == FALSE)) {
+ if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == false)) {
/* edge has become wire */
int vidx_reverse;
BMVert *v1 = e_iter->v1;
@@ -179,7 +179,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
if (LIKELY(v != NULL) &&
BM_vert_edge_count(v) == 2)
{
- BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */
+ BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
}
}
}
@@ -210,7 +210,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
/* check twice because cumulative effect could dissolve over angle limit */
bm_vert_edge_face_angle(v) < angle_limit)
{
- BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */
+ BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
if (ne && ne->l) {
BM_edge_normals_update(ne);
@@ -223,7 +223,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
MEM_freeN(weight_elems);
}
-void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries)
+void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries)
{
int vinput_len;
int einput_len;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index acdab2510a4..7e9a5784552 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -36,7 +36,7 @@
#include "intern/bmesh_operators_private.h" /* own include */
-static int bm_vert_dissolve_fan_test(BMVert *v)
+static bool bm_vert_dissolve_fan_test(BMVert *v)
{
/* check if we should walk over these verts */
BMIter iter;
@@ -61,21 +61,21 @@ static int bm_vert_dissolve_fan_test(BMVert *v)
}
if ((tot_edge == 4) && (tot_edge_boundary == 0) && (tot_edge_manifold == 4)) {
- return TRUE;
+ return true;
}
else if ((tot_edge == 3) && (tot_edge_boundary == 0) && (tot_edge_manifold == 3)) {
- return TRUE;
+ return true;
}
else if ((tot_edge == 3) && (tot_edge_boundary == 2) && (tot_edge_manifold == 1)) {
- return TRUE;
+ return true;
}
else if ((tot_edge == 2) && (tot_edge_wire == 2)) {
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-static int bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
+static bool bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
{
/* collapse under 2 conditions.
* - vert connects to 4 manifold edges (and 4 faces).
@@ -110,7 +110,7 @@ static int bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
if (tot_edge == 2) {
/* check for 2 wire verts only */
if (tot_edge_wire == 2) {
- return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL);
+ return (BM_vert_collapse_edge(bm, v->e, v, true) != NULL);
}
}
else if (tot_edge == 4) {
@@ -145,7 +145,7 @@ static int bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
if (l->f->len > 3) {
BMLoop *l_new;
BLI_assert(l->prev->v != l->next->v);
- BM_face_split(bm, l->f, l->prev->v, l->next->v, &l_new, NULL, TRUE);
+ BM_face_split(bm, l->f, l->prev->v, l->next->v, &l_new, NULL, true);
BM_elem_flag_merge_into(l_new->e, l->e, l->prev->e);
}
}
@@ -153,7 +153,7 @@ static int bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
return BM_vert_dissolve(bm, v);
}
- return FALSE;
+ return false;
}
enum {
@@ -170,7 +170,7 @@ enum {
/**
* \param tag_only so we can call this from an operator */
-void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int tag_only)
+void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool tag_only)
{
#ifdef USE_WALKER
# define ELE_VERT_TAG 1
@@ -189,16 +189,16 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int
int iter_step;
- /* if tag_only is set, we assyme the caller knows what verts to tag
+ /* if tag_only is set, we assume the caller knows what verts to tag
* needed for the operator */
- if (tag_only == FALSE) {
+ if (tag_only == false) {
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BM_elem_flag_enable(v, BM_ELEM_TAG);
}
}
for (iter_step = 0; iter_step < iterations; iter_step++) {
- int iter_done;
+ bool iter_done;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG) && bm_vert_dissolve_fan_test(v)) {
@@ -215,7 +215,7 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int
/* main loop, keep tagging until we can't tag any more islands */
- while (TRUE) {
+ while (true) {
#ifdef USE_WALKER
BMWalker walker;
#else
@@ -268,12 +268,12 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int
BMW_end(&walker);
#else
- BM_elem_index_set(v_first, (offset + depth) % nth ? VERT_INDEX_IGNORE : VERT_INDEX_DO_COLLAPSE); /* set_dirty! */
+ BM_elem_index_set(v_first, ((offset + depth) % nth) ? VERT_INDEX_IGNORE : VERT_INDEX_DO_COLLAPSE); /* set_dirty! */
vert_seek_b_tot = 0;
vert_seek_b[vert_seek_b_tot++] = v_first;
- while (TRUE) {
+ while (true) {
BMEdge *e;
if ((offset + depth) % nth) {
@@ -318,14 +318,16 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int
}
/* now we tagged all verts -1 for removal, lets loop over and rebuild faces */
- iter_done = FALSE;
+ iter_done = false;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE) {
- iter_done |= bm_vert_dissolve_fan(bm, v);
+ if (bm_vert_dissolve_fan(bm, v)) {
+ iter_done = true;
+ }
}
}
- if (iter_done == FALSE) {
+ if (iter_done == false) {
break;
}
}
@@ -340,5 +342,5 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int
void BM_mesh_decimate_unsubdivide(BMesh *bm, const int iterations)
{
- BM_mesh_decimate_unsubdivide_ex(bm, iterations, FALSE);
+ BM_mesh_decimate_unsubdivide_ex(bm, iterations, false);
}
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
new file mode 100644
index 00000000000..1d3f973dbc0
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.c
@@ -0,0 +1,170 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/tools/bmesh_edgesplit.c
+ * \ingroup bmesh
+ *
+ * Edge-Split.
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "bmesh.h"
+
+#include "bmesh_edgesplit.h" /* own include */
+
+
+/**
+ * Remove the BM_ELEM_TAG flag for edges we cant split
+ *
+ * un-tag edges not connected to other tagged edges,
+ * unless they are on a boundary
+ */
+static void bm_edgesplit_validate_seams(BMesh *bm)
+{
+ BMIter iter;
+ BMEdge *e;
+
+ unsigned char *vtouch;
+ unsigned char *vt;
+
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+ vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__);
+
+ /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+
+ /* unrelated to flag assignment in this function - since this is the
+ * only place we loop over all edges, disable tag */
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+
+ if (e->l == NULL) {
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ else if (BM_edge_is_boundary(e)) {
+ vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+ vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
+
+ /* while the boundary verts need to be tagged,
+ * the edge its self can't be split */
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ }
+
+ /* single marked edges unconnected to any other marked edges
+ * are illegal, go through and unmark them */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ /* lame, but we don't want the count to exceed 255,
+ * so just count to 2, its all we need */
+ unsigned char *vt;
+ vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+ vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
+ }
+ }
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
+ vtouch[BM_elem_index_get(e->v2)] == 1)
+ {
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ }
+ }
+
+ MEM_freeN(vtouch);
+}
+
+void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only)
+{
+ BMIter iter;
+ BMEdge *e;
+
+
+ if (tag_only == false) {
+ BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, false);
+ }
+
+ if (use_verts) {
+ /* prevent one edge having both verts unflagged
+ * we could alternately disable these edges, either way its a corner case.
+ *
+ * This is needed so we don't split off the edge but then none of its verts which
+ * would leave a duplicate edge.
+ */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == false) &&
+ (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == false))))
+ {
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+
+ bm_edgesplit_validate_seams(bm);
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ /* this flag gets copied so we can be sure duplicate edges get it too (important) */
+ BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
+
+ /* keep splitting until each loop has its own edge */
+ do {
+ bmesh_edge_separate(bm, e, e->l);
+ } while (!BM_edge_is_boundary(e));
+
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
+ }
+
+ if (use_verts) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == false) {
+ BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+ }
+ if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == false) {
+ BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+ }
+ }
+ }
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
+ BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+ bmesh_vert_separate(bm, e->v1, NULL, NULL);
+ }
+ if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) {
+ BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+ bmesh_vert_separate(bm, e->v2, NULL, NULL);
+ }
+ }
+ }
+}
diff --git a/source/gameengine/Physics/common/PHY_IMotionState.cpp b/source/blender/bmesh/tools/bmesh_edgesplit.h
index 1953e748bc0..8c1231dd794 100644
--- a/source/gameengine/Physics/common/PHY_IMotionState.cpp
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.h
@@ -15,23 +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.
*
- * 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.
+ * Contributor(s):
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file gameengine/Physics/common/PHY_IMotionState.cpp
- * \ingroup phys
- */
+#ifndef __BMESH_EDGESPLIT_H__
+#define __BMESH_EDGESPLIT_H__
-#include "PHY_IMotionState.h"
+/** \file blender/bmesh/tools/bmesh_edgesplit.h
+ * \ingroup bmesh
+ */
-PHY_IMotionState::~PHY_IMotionState()
-{
+void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only);
-}
+#endif /* __BMESH_EDGESPLIT_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c
new file mode 100644
index 00000000000..79f6c76afc7
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_triangulate.c
@@ -0,0 +1,87 @@
+/*
+ * ***** 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): Joseph Eagar
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/tools/bmesh_triangulate.c
+ * \ingroup bmesh
+ *
+ * Triangulate.
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_array.h"
+
+#include "bmesh.h"
+
+#include "bmesh_triangulate.h" /* own include */
+
+/**
+ * a version of #BM_face_triangulate that maps to #BMOpSlot
+ */
+static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, const bool use_beauty, const bool use_tag,
+ BMOperator *op, BMOpSlot *slot_facemap_out)
+{
+ const 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, use_beauty, use_tag);
+
+ if (faces_array) {
+ int i;
+ BMO_slot_map_elem_insert(op, slot_facemap_out, face, face);
+ for (i = 0; i < faces_array_tot; i++) {
+ BMO_slot_map_elem_insert(op, slot_facemap_out, faces_array[i], face);
+ }
+ }
+}
+
+
+void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only,
+ BMOperator *op, BMOpSlot *slot_facemap_out)
+{
+ BMIter iter;
+ BMFace *face;
+
+ 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, use_beauty, tag_only,
+ op, slot_facemap_out);
+ }
+ }
+ }
+ }
+ else {
+ 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, use_beauty, tag_only);
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/bmesh/tools/bmesh_triangulate.h b/source/blender/bmesh/tools/bmesh_triangulate.h
new file mode 100644
index 00000000000..936a90d3a16
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_triangulate.h
@@ -0,0 +1,36 @@
+/*
+ * ***** 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): Joseph Eagar
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/tools/bmesh_triangulate.h
+ * \ingroup bmesh
+ *
+ * Triangulate.
+ *
+ */
+
+#ifndef __BMESH_TRIAMGULATE_H__
+#define __BMESH_TRIAMGULATE_H__
+
+void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only,
+ BMOperator *op, BMOpSlot *slot_facemap_out);
+
+#endif /* __BMESH_TRIAMGULATE_H__ */
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index 26b5edf7ea6..a69f7918e40 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -24,6 +24,8 @@
#include "AnimationExporter.h"
#include "MaterialExporter.h"
+Global G;
+
template<class Functor>
void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
@@ -83,6 +85,11 @@ void AnimationExporter::operator()(Object *ob)
}
+ export_object_constraint_animation(ob);
+
+ //This needs to be handled by extra profiles, so postponed for now
+ //export_morph_animation(ob);
+
//Export Lamp parameter animations
if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) {
fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
@@ -134,7 +141,69 @@ void AnimationExporter::operator()(Object *ob)
fcu = fcu->next;
}
}
+ }
+
+
+}
+
+void AnimationExporter::export_object_constraint_animation(Object *ob)
+{
+ std::vector<float> fra;
+ //Takes frames of target animations
+ make_anim_frames_from_targets(ob, fra);
+
+ if (fra.size())
+ dae_baked_object_animation(fra, ob);
+}
+
+void AnimationExporter::export_morph_animation(Object *ob)
+{
+ FCurve *fcu;
+ char *transformName;
+ Key *key = BKE_key_from_object(ob);
+ if (!key) return;
+
+ if (key->adt && key->adt->action) {
+ fcu = (FCurve *)key->adt->action->curves.first;
+
+ while (fcu) {
+ transformName = extract_transform_name(fcu->rna_path);
+
+ dae_animation(ob, fcu, transformName, true);
+
+ fcu = fcu->next;
+ }
+ }
+
+}
+void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<float> &frames )
+{
+ ListBase *conlist = get_active_constraints(ob);
+ if (conlist == NULL) return;
+ bConstraint *con;
+ for (con = (bConstraint*)conlist->first; con; con = con->next) {
+ ListBase targets = {NULL, NULL};
+
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+
+ if (!validateConstraints(con)) continue;
+
+ if (cti && cti->get_constraint_targets) {
+ bConstraintTarget *ct;
+ Object *obtar;
+ /* get targets
+ * - constraints should use ct->matrix, not directly accessing values
+ * - ct->matrix members have not yet been calculated here!
+ */
+ cti->get_constraint_targets(con, &targets);
+ if (cti) {
+ for (ct = (bConstraintTarget*)targets.first; ct; ct = ct->next) {
+ obtar = ct->tar;
+ find_frames(obtar, frames);
+ }
+ }
+ }
}
}
@@ -205,8 +274,8 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
//axis names for colors
else if (!strcmp(transformName, "color") ||
- !strcmp(transformName, "specular_color") ||
- !strcmp(transformName, "diffuse_color") ||
+ !strcmp(transformName, "specular_color") ||
+ !strcmp(transformName, "diffuse_color") ||
!strcmp(transformName, "alpha"))
{
const char *axis_names[] = {"R", "G", "B"};
@@ -216,9 +285,9 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
//axis names for transforms
else if (!strcmp(transformName, "location") ||
- !strcmp(transformName, "scale") ||
+ !strcmp(transformName, "scale") ||
!strcmp(transformName, "rotation_euler") ||
- !strcmp(transformName, "rotation_quaternion"))
+ !strcmp(transformName, "rotation_quaternion"))
{
const char *axis_names[] = {"X", "Y", "Z"};
if (fcu->array_index < 3)
@@ -320,6 +389,9 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
if (ma)
target = translate_id(id_name(ma)) + "-effect" +
"/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
+ //if shape key animation, this is the main problem, how to define the channel targets.
+ /*target = get_morph_id(ob) +
+ "/value" +*/
}
addChannel(COLLADABU::URI(empty, sampler_id), target);
@@ -367,7 +439,10 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B
std::vector<float> fra;
//char prefix[256];
- FCurve *fcu = (FCurve *)ob_arm->adt->action->curves.first;
+ //Check if there is a fcurve in the armature for the bone in param
+ //when baking this check is not needed, solve every bone for every frame.
+ /*FCurve *fcu = (FCurve *)ob_arm->adt->action->curves.first;
+
while (fcu) {
std::string bone_name = getObjectBoneName(ob_arm, fcu);
int val = BLI_strcasecmp((char *)bone_name.c_str(), bone->name);
@@ -375,11 +450,13 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B
fcu = fcu->next;
}
- if (!(fcu)) return;
+ if (!(fcu)) return;*/
+
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
if (!pchan)
return;
+ //every inserted keyframe of bones.
find_frames(ob_arm, fra);
if (flag & ARM_RESTPOS) {
@@ -415,7 +492,8 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_
// create output source
std::string output_id;
- output_id = create_4x4_source(fra, ob_arm, bone, anim_id);
+
+ output_id = create_4x4_source(fra, ob_arm, bone, anim_id);
// create interpolations source
std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
@@ -439,6 +517,48 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_
closeAnimation();
}
+void AnimationExporter::dae_baked_object_animation(std::vector<float> &fra, Object *ob)
+{
+ std::string ob_name = id_name(ob);
+ char anim_id[200];
+
+ if (!fra.size())
+ return;
+
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s", (char*)translate_id(ob_name).c_str(),
+ "object_matrix");
+
+ openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
+
+ // create input source
+ std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, false, anim_id, "");
+
+ // create output source
+ std::string output_id;
+ output_id = create_4x4_source( fra, ob, NULL, anim_id);
+
+ // create interpolations source
+ std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
+ std::string empty;
+ sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // TODO create in/out tangents source
+
+ // this input is required
+ sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ addSampler(sampler);
+
+ std::string target = translate_id(ob_name) + "/transform";
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+}
+
// dae_bone_animation -> add_bone_animation
// (blend this into dae_bone_animation)
void AnimationExporter::dae_bone_animation(std::vector<float> &fra, float *values, int tm_type, int axis, std::string ob_name, std::string bone_name)
@@ -610,7 +730,6 @@ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSeman
values[1] = bezt->vec[2][1];
}
break;
- break;
default:
*length = 0;
break;
@@ -762,7 +881,8 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti
return source_id;
}
-std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object *ob_arm, Bone *bone, const std::string& anim_id)
+
+std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object * ob, Bone *bone, const std::string& anim_id)
{
COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
std::string source_id = anim_id + get_semantic_suffix(semantic);
@@ -780,71 +900,90 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
bPoseChannel *parchan = NULL;
bPoseChannel *pchan = NULL;
- bPose *pose = ob_arm->pose;
-
- pchan = BKE_pose_channel_find_name(pose, bone->name);
- if (!pchan)
- return "";
+ if (ob->type == OB_ARMATURE ) {
+ bPose *pose = ob->pose;
+ pchan = BKE_pose_channel_find_name(pose, bone->name);
+ if (!pchan)
+ return "";
- parchan = pchan->parent;
-
- enable_fcurves(ob_arm->adt->action, bone->name);
+ parchan = pchan->parent;
+ enable_fcurves(ob->adt->action, bone->name);
+ }
+
std::vector<float>::iterator it;
int j = 0;
for (it = frames.begin(); it != frames.end(); it++) {
float mat[4][4], ipar[4][4];
float ctime = BKE_scene_frame_get_from_ctime(scene, *it);
-
- BKE_animsys_evaluate_animdata(scene, &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM);
- BKE_pose_where_is_bone(scene, ob_arm, pchan, ctime, 1);
-
- // compute bone local mat
- if (bone->parent) {
- invert_m4_m4(ipar, parchan->pose_mat);
- mult_m4_m4m4(mat, ipar, pchan->pose_mat);
- }
- else
- copy_m4_m4(mat, pchan->pose_mat);
- UnitConverter converter;
-
+ CFRA = BKE_scene_frame_get_from_ctime(scene, *it);
+ //BKE_scene_update_for_newframe(G.main,scene,scene->lay);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
+
+ if (bone) {
+ if (pchan->flag & POSE_CHAIN) {
+ enable_fcurves(ob->adt->action, NULL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
+ BKE_pose_where_is(scene, ob);
+ }
+ else {
+ BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1);
+ }
+
+ // compute bone local mat
+ if (bone->parent) {
+ invert_m4_m4(ipar, parchan->pose_mat);
+ mult_m4_m4m4(mat, ipar, pchan->pose_mat);
+ }
+ else
+ copy_m4_m4(mat, pchan->pose_mat);
+
// SECOND_LIFE_COMPATIBILITY
// AFAIK animation to second life is via BVH, but no
// reason to not have the collada-animation be correct
- if (export_settings->second_life) {
- float temp[4][4];
- copy_m4_m4(temp, bone->arm_mat);
- temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
- invert_m4(temp);
+ if (export_settings->second_life) {
+ float temp[4][4];
+ copy_m4_m4(temp, bone->arm_mat);
+ temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
+ invert_m4(temp);
- mult_m4_m4m4(mat, mat, temp);
+ mult_m4_m4m4(mat, mat, temp);
- if (bone->parent) {
- copy_m4_m4(temp, bone->parent->arm_mat);
- temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
+ if (bone->parent) {
+ copy_m4_m4(temp, bone->parent->arm_mat);
+ temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
- mult_m4_m4m4(mat, temp, mat);
+ mult_m4_m4m4(mat, temp, mat);
+ }
}
- }
- float outmat[4][4];
- converter.mat4_to_dae(outmat, mat);
+ }
+ else {
+ calc_ob_mat_at_time(ob, ctime, mat);
+ }
+
+ UnitConverter converter;
+ double outmat[4][4];
+ converter.mat4_to_dae_double(outmat, mat);
source.appendValues(outmat);
-
j++;
+
+ BIK_release_tree(scene, ob, ctime);
}
- enable_fcurves(ob_arm->adt->action, NULL);
+ enable_fcurves(ob->adt->action, NULL);
source.finish();
return source_id;
}
+
+
// only used for sources with OUTPUT semantic ( locations and scale)
std::string AnimationExporter::create_xyz_source(float *v, int tot, const std::string& anim_id)
{
@@ -1184,6 +1323,12 @@ bool AnimationExporter::hasAnimations(Scene *sce)
}
}
+ //check shape key animation
+ if (!fcu) {
+ Key *key = BKE_key_from_object(ob);
+ if (key && key->adt && key->adt->action)
+ fcu = (FCurve *)key->adt->action->curves.first;
+ }
if (fcu)
return true;
}
@@ -1351,3 +1496,43 @@ void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, i
enable_fcurves(ob_arm->adt->action, NULL);
}
+
+bool AnimationExporter::validateConstraints(bConstraint *con)
+{
+ bool valid = true;
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ /* these we can skip completely (invalid constraints...) */
+ if (cti == NULL) valid = false;
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) valid = false;
+ /* these constraints can't be evaluated anyway */
+ if (cti->evaluate_constraint == NULL) valid = false;
+ /* influence == 0 should be ignored */
+ if (con->enforce == 0.0f) valid = false;
+
+ return valid;
+}
+
+void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[][4])
+{
+ ListBase *conlist = get_active_constraints(ob);
+ bConstraint *con;
+ for (con = (bConstraint*)conlist->first; con; con = con->next) {
+ ListBase targets = {NULL, NULL};
+
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+
+ if (cti && cti->get_constraint_targets) {
+ bConstraintTarget *ct;
+ Object *obtar;
+ cti->get_constraint_targets(con, &targets);
+ for (ct = (bConstraintTarget*)targets.first; ct; ct = ct->next) {
+ obtar = ct->tar;
+ BKE_animsys_evaluate_animdata(scene, &obtar->id, obtar->adt, ctime, ADT_RECALC_ANIM);
+ BKE_object_where_is_calc_time(scene, obtar, ctime);
+ }
+ }
+ }
+ BKE_object_where_is_calc_time(scene, ob, ctime);
+ copy_m4_m4(mat, ob->obmat);
+}
+
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
index 349930dea8f..d2f50b22d02 100644
--- a/source/blender/collada/AnimationExporter.h
+++ b/source/blender/collada/AnimationExporter.h
@@ -34,6 +34,7 @@ extern "C"
#include "DNA_camera_types.h"
#include "DNA_armature_types.h"
#include "DNA_material_types.h"
+#include "DNA_constraint_types.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -47,6 +48,10 @@ extern "C"
#include "BKE_action.h" // pose functions
#include "BKE_armature.h"
#include "BKE_object.h"
+#include "BKE_constraint.h"
+#include "BIK_api.h"
+#include "BKE_global.h"
+#include "ED_object.h"
#ifdef NAN_BUILDINFO
extern char build_rev[];
@@ -73,9 +78,13 @@ extern char build_rev[];
#include "collada_internal.h"
+#include "IK_solver.h"
+
#include <vector>
#include <algorithm> // std::find
+
+
class AnimationExporter: COLLADASW::LibraryAnimations
{
private:
@@ -98,6 +107,10 @@ protected:
const ExportSettings *export_settings;
void dae_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma = NULL);
+
+ void export_object_constraint_animation(Object *ob);
+
+ void export_morph_animation(Object *ob);
void write_bone_animation_matrix(Object *ob_arm, Bone *bone);
@@ -119,6 +132,8 @@ protected:
void dae_baked_animation(std::vector<float> &fra, Object *ob_arm, Bone *bone);
+ void dae_baked_object_animation(std::vector<float> &fra, Object *ob);
+
float convert_time(float frame);
float convert_angle(float angle);
@@ -130,7 +145,7 @@ protected:
void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length);
- float * get_eul_source_for_quat(Object *ob );
+ float* get_eul_source_for_quat(Object *ob );
std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name);
@@ -143,17 +158,21 @@ protected:
std::string create_xyz_source(float *v, int tot, const std::string& anim_id);
std::string create_4x4_source(std::vector<float> &frames, Object * ob_arm, Bone *bone, const std::string& anim_id);
-
+
std::string create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents);
std::string fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name);
+
// for rotation, axis name is always appended and the value of append_axis is ignored
std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
std::string get_light_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
std::string get_camera_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
+
void find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name);
void find_frames(Object *ob, std::vector<float> &fra);
+ void make_anim_frames_from_targets(Object *ob, std::vector<float> &frames );
+
void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode);
// enable fcurves driving a specific bone, disable all the rest
@@ -165,4 +184,11 @@ protected:
char *extract_transform_name(char *rna_path);
std::string getObjectBoneName(Object *ob, const FCurve * fcu);
+
+ void getBakedPoseData(Object *obarm, int startFrame, int endFrame, bool ActionBake, bool ActionBakeFirstFrame);
+
+ bool validateConstraints(bConstraint *con);
+
+ void calc_ob_mat_at_time(Object *ob, float ctime , float mat[][4]);
+
};
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index 44e74e320cc..60188071832 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -937,10 +937,9 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
if (is_matrix) {
apply_matrix_curves(ob, animcurves, root, node, transform);
}
- else {
+ else {
if (is_joint) {
-
add_bone_animation_sampled(ob, animcurves, root, node, transform);
}
else {
@@ -1194,7 +1193,7 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurv
calc_joint_parent_mat_rest(par, NULL, root, node);
mult_m4_m4m4(temp, par, matfra);
- // evaluate_joint_world_transform_at_frame(temp, NULL,, node, fra);
+ // evaluate_joint_world_transform_at_frame(temp, NULL, node, fra);
// calc special matrix
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
@@ -1529,7 +1528,7 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node,
calc_joint_parent_mat_rest(par, NULL, root, node);
mult_m4_m4m4(temp, par, matfra);
- // evaluate_joint_world_transform_at_frame(temp, NULL,, node, fra);
+ // evaluate_joint_world_transform_at_frame(temp, NULL, node, fra);
// calc special matrix
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
@@ -1676,8 +1675,6 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW::
default:
fprintf(stderr, "unsupported transformation type %d\n", type);
}
- // dae_matrix_to_mat4(tm, m);
-
}
float temp[4][4];
@@ -1891,7 +1888,7 @@ Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, COLLADAFW::No
job->lay = BKE_scene_base_find(scene, job)->lay = 2;
mul_v3_fl(job->size, 0.5f);
- job->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&job->id, OB_RECALC_OB);
verify_adt_action((ID *)&job->id, 1);
@@ -1912,14 +1909,14 @@ Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, COLLADAFW::No
if (par_job) {
job->parent = par_job;
- par_job->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&par_job->id, OB_RECALC_OB);
job->parsubstr[0] = 0;
}
BKE_object_where_is_calc(scene, job);
// after parenting and layer change
- DAG_scene_sort(CTX_data_main(C), scene);
+ DAG_relations_tag_update(CTX_data_main(C));
joint_objects[node->getUniqueId()] = job;
}
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 134fd639a73..a56010aeb27 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -75,12 +75,6 @@ void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce,
}
}
-bool ArmatureExporter::is_skinned_mesh(Object *ob)
-{
- return bc_get_assigned_armature(ob) != NULL;
-}
-
-
void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone)
{
if (bc_is_root_bone(bone, this->export_settings->deform_bones_only))
@@ -117,26 +111,12 @@ bool ArmatureExporter::add_instance_controller(Object *ob)
return true;
}
-void ArmatureExporter::export_controllers(Scene *sce)
-{
- scene = sce;
-
- openLibrary();
-
- GeometryFunctor gf;
- gf.forEachMeshObjectInExportSet<ArmatureExporter>(sce, *this, this->export_settings->export_set);
-
- closeLibrary();
-}
-
+#if 0
void ArmatureExporter::operator()(Object *ob)
{
Object *ob_arm = bc_get_assigned_armature(ob);
- if (ob_arm /*&& !already_written(ob_arm)*/)
- export_controller(ob, ob_arm);
}
-#if 0
bool ArmatureExporter::already_written(Object *ob_arm)
{
@@ -187,67 +167,67 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce,
node.setNodeName(node_name);
node.setNodeSid(node_sid);
-#if 0
+#if 0
if (bone->childbase.first == NULL || BLI_countlist(&(bone->childbase)) >= 2) {
add_blender_leaf_bone( bone, ob_arm, node);
}
- else {
+ else{
#endif
- node.start();
+ node.start();
- add_bone_transform(ob_arm, bone, node);
+ add_bone_transform(ob_arm, bone, node);
- // Write nodes of childobjects, remove written objects from list
- std::list<Object *>::iterator i = child_objects.begin();
+ // Write nodes of childobjects, remove written objects from list
+ std::list<Object *>::iterator i = child_objects.begin();
- while (i != child_objects.end()) {
- if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) {
- float backup_parinv[4][4];
- copy_m4_m4(backup_parinv, (*i)->parentinv);
+ while (i != child_objects.end()) {
+ if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) {
+ float backup_parinv[4][4];
+ copy_m4_m4(backup_parinv, (*i)->parentinv);
- // crude, temporary change to parentinv
- // so transform gets exported correctly.
+ // crude, temporary change to parentinv
+ // so transform gets exported correctly.
- // Add bone tail- translation... don't know why
- // bone parenting is against the tail of a bone
- // and not it's head, seems arbitrary.
- (*i)->parentinv[3][1] += bone->length;
+ // Add bone tail- translation... don't know why
+ // bone parenting is against the tail of a bone
+ // and not it's head, seems arbitrary.
+ (*i)->parentinv[3][1] += bone->length;
- // SECOND_LIFE_COMPATIBILITY
- // TODO: when such objects are animated as
- // single matrix the tweak must be applied
- // to the result.
- if (export_settings->second_life) {
- // tweak objects parentinverse to match compatibility
- float temp[4][4];
+ // SECOND_LIFE_COMPATIBILITY
+ // TODO: when such objects are animated as
+ // single matrix the tweak must be applied
+ // to the result.
+ if (export_settings->second_life) {
+ // tweak objects parentinverse to match compatibility
+ float temp[4][4];
- copy_m4_m4(temp, bone->arm_mat);
- temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
+ copy_m4_m4(temp, bone->arm_mat);
+ temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
- mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv);
- }
+ mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv);
+ }
- se->writeNodes(*i, sce);
+ se->writeNodes(*i, sce);
- copy_m4_m4((*i)->parentinv, backup_parinv);
- child_objects.erase(i++);
+ copy_m4_m4((*i)->parentinv, backup_parinv);
+ child_objects.erase(i++);
+ }
+ else i++;
}
- else i++;
- }
- for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
- add_bone_node(child, ob_arm, sce, se, child_objects);
+ for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ add_bone_node(child, ob_arm, sce, se, child_objects);
+ }
+ node.end();
}
- node.end();
- }
- else {
- for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
- add_bone_node(child, ob_arm, sce, se, child_objects);
+ else {
+ for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ add_bone_node(child, ob_arm, sce, se, child_objects);
+ }
}
- }
}
-#if 0
+//#if 1
void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node)
{
node.start();
@@ -258,33 +238,38 @@ void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADA
node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1]);
node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2]);
- for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ /*for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
add_bone_node(child, ob_arm, sce, se, child_objects);
- }
+ }*/
node.end();
}
-#endif
+//#endif
void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node)
{
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
+ //bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
float mat[4][4];
if (bone->parent) {
- // get bone-space matrix from armature-space
- bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, bone->parent->name);
-
+ // get bone-space matrix from parent pose
+ /*bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, bone->parent->name);
float invpar[4][4];
invert_m4_m4(invpar, parchan->pose_mat);
- mult_m4_m4m4(mat, invpar, pchan->pose_mat);
+ mult_m4_m4m4(mat, invpar, pchan->pose_mat);*/
+
+ float invpar[4][4];
+ invert_m4_m4(invpar, bone->parent->arm_mat);
+ mult_m4_m4m4(mat, invpar, bone->arm_mat);
+
}
else {
- copy_m4_m4(mat, pchan->pose_mat);
- // Why? Joint's localspace is still it's parent node
- //get world-space from armature-space
- //mult_m4_m4m4(mat, ob_arm->obmat, pchan->pose_mat);
+
+ //copy_m4_m4(mat, pchan->pose_mat);
+ //pose mat is object space
+ //New change: export bone->arm_mat
+ copy_m4_m4(mat, bone->arm_mat);
}
// SECOND_LIFE_COMPATIBILITY
@@ -313,315 +298,3 @@ std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob)
{
return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + SKIN_CONTROLLER_ID_SUFFIX;
}
-
-// ob should be of type OB_MESH
-// both args are required
-void ArmatureExporter::export_controller(Object *ob, Object *ob_arm)
-{
- // joint names
- // joint inverse bind matrices
- // vertex weights
-
- // input:
- // joint names: ob -> vertex group names
- // vertex group weights: me->dvert -> groups -> index, weight
-
-#if 0
- me->dvert :
-
- typedef struct MDeformVert {
- struct MDeformWeight *dw;
- int totweight;
- int flag; // flag only in use for weightpaint now
- } MDeformVert;
-
- typedef struct MDeformWeight {
- int def_nr;
- float weight;
- } MDeformWeight;
-#endif
-
- bool use_instantiation = this->export_settings->use_object_instantiation;
- Mesh *me;
-
- if (this->export_settings->apply_modifiers) {
- me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type);
- }
- else {
- me = (Mesh *)ob->data;
- }
- BKE_mesh_tessface_ensure(me);
-
- if (!me->dvert) return;
-
- std::string controller_name = id_name(ob_arm);
- std::string controller_id = get_controller_id(ob_arm, ob);
-
- openSkin(controller_id, controller_name,
- COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation)));
-
- add_bind_shape_mat(ob);
-
- std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id);
- std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, &ob->defbase, controller_id);
-
- std::list<int> vcounts;
- std::list<int> joints;
- std::list<float> weights;
-
- {
- int i, j;
-
- // def group index -> joint index
- std::vector<int> joint_index_by_def_index;
- bDeformGroup *def;
-
- for (def = (bDeformGroup *)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) {
- if (is_bone_defgroup(ob_arm, def))
- joint_index_by_def_index.push_back(j++);
- else
- joint_index_by_def_index.push_back(-1);
- }
-
- for (i = 0; i < me->totvert; i++) {
- MDeformVert *vert = &me->dvert[i];
- std::map<int, float> jw;
-
- // We're normalizing the weights later
- float sumw = 0.0f;
-
- for (j = 0; j < vert->totweight; j++) {
- int joint_index = joint_index_by_def_index[vert->dw[j].def_nr];
- if (joint_index != -1 && vert->dw[j].weight > 0.0f) {
- jw[joint_index] += vert->dw[j].weight;
- sumw += vert->dw[j].weight;
- }
- }
-
- if (sumw > 0.0f) {
- float invsumw = 1.0f / sumw;
- vcounts.push_back(jw.size());
- for (std::map<int, float>::iterator m = jw.begin(); m != jw.end(); ++m) {
- joints.push_back((*m).first);
- weights.push_back(invsumw * (*m).second);
- }
- }
- else {
- vcounts.push_back(0);
-#if 0
- vcounts.push_back(1);
- joints.push_back(-1);
- weights.push_back(1.0f);
-#endif
- }
- }
- }
-
- std::string weights_source_id = add_weights_source(me, controller_id, weights);
- add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
- add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
-
- if (this->export_settings->apply_modifiers)
- {
- BKE_libblock_free_us(&(G.main->mesh), me);
- }
- closeSkin();
- closeController();
-}
-
-void ArmatureExporter::add_joints_element(ListBase *defbase,
- const std::string& joints_source_id, const std::string& inv_bind_mat_source_id)
-{
- COLLADASW::JointsElement joints(mSW);
- COLLADASW::InputList &input = joints.getInputList();
-
- input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h
- COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id)));
- input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX,
- COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id)));
- joints.add();
-}
-
-void ArmatureExporter::add_bind_shape_mat(Object *ob)
-{
- double bind_mat[4][4];
-
- converter.mat4_to_dae_double(bind_mat, ob->obmat);
-
- addBindShapeTransform(bind_mat);
-}
-
-std::string ArmatureExporter::add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id)
-{
- std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX;
-
- int totjoint = 0;
- bDeformGroup *def;
- for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
- if (is_bone_defgroup(ob_arm, def))
- totjoint++;
- }
-
- COLLADASW::NameSource source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(totjoint);
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- param.push_back("JOINT");
-
- source.prepareToAppendValues();
-
- for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
- Bone *bone = get_bone_from_defgroup(ob_arm, def);
- if (bone)
- source.appendValues(get_joint_sid(bone, ob_arm));
- }
-
- source.finish();
-
- return source_id;
-}
-
-std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id)
-{
- std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
-
- int totjoint = 0;
- for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
- if (is_bone_defgroup(ob_arm, def))
- totjoint++;
- }
-
- COLLADASW::FloatSourceF source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(totjoint); //BLI_countlist(defbase));
- source.setAccessorStride(16);
-
- source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- param.push_back("TRANSFORM");
-
- source.prepareToAppendValues();
-
- bPose *pose = ob_arm->pose;
- bArmature *arm = (bArmature *)ob_arm->data;
-
- int flag = arm->flag;
-
- // put armature in rest position
- if (!(arm->flag & ARM_RESTPOS)) {
- arm->flag |= ARM_RESTPOS;
- BKE_pose_where_is(scene, ob_arm);
- }
-
- for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
- if (is_bone_defgroup(ob_arm, def)) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(pose, def->name);
-
- float mat[4][4];
- float world[4][4];
- float inv_bind_mat[4][4];
-
- // SECOND_LIFE_COMPATIBILITY
- if (export_settings->second_life) {
- // Only translations, no rotation vs armature
- float temp[4][4];
- unit_m4(temp);
- copy_v3_v3(temp[3], pchan->bone->arm_mat[3]);
- mult_m4_m4m4(world, ob_arm->obmat, temp);
- }
- else {
- // make world-space matrix, arm_mat is armature-space
- mult_m4_m4m4(world, ob_arm->obmat, pchan->bone->arm_mat);
- }
-
- invert_m4_m4(mat, world);
- converter.mat4_to_dae(inv_bind_mat, mat);
-
- source.appendValues(inv_bind_mat);
- }
- }
-
- // back from rest positon
- if (!(flag & ARM_RESTPOS)) {
- arm->flag = flag;
- BKE_pose_where_is(scene, ob_arm);
- }
-
- source.finish();
-
- return source_id;
-}
-
-Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def)
-{
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, def->name);
- return pchan ? pchan->bone : NULL;
-}
-
-bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup *def)
-{
- return get_bone_from_defgroup(ob_arm, def) != NULL;
-}
-
-std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& controller_id, const std::list<float>& weights)
-{
- std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX;
-
- COLLADASW::FloatSourceF source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(weights.size());
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- param.push_back("WEIGHT");
-
- source.prepareToAppendValues();
-
- for (std::list<float>::const_iterator i = weights.begin(); i != weights.end(); ++i) {
- source.appendValues(*i);
- }
-
- source.finish();
-
- return source_id;
-}
-
-void ArmatureExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id,
- const std::list<int>& vcounts,
- const std::list<int>& joints)
-{
- COLLADASW::VertexWeightsElement weightselem(mSW);
- COLLADASW::InputList &input = weightselem.getInputList();
-
- int offset = 0;
- input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h
- COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++));
- input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT,
- COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++));
-
- weightselem.setCount(vcounts.size());
-
- // write number of deformers per vertex
- COLLADASW::PrimitivesBase::VCountList vcountlist;
-
- vcountlist.resize(vcounts.size());
- std::copy(vcounts.begin(), vcounts.end(), vcountlist.begin());
-
- weightselem.prepareToAppendVCountValues();
- weightselem.appendVertexCount(vcountlist);
-
- weightselem.CloseVCountAndOpenVElement();
-
- // write deformer index - weight index pairs
- int weight_index = 0;
- for (std::list<int>::const_iterator i = joints.begin(); i != joints.end(); ++i) {
- weightselem.appendValues(*i, weight_index++);
- }
-
- weightselem.finish();
-}
diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h
index 086c16f0cd5..931cc5d2988 100644
--- a/source/blender/collada/ArmatureExporter.h
+++ b/source/blender/collada/ArmatureExporter.h
@@ -41,6 +41,7 @@
#include "DNA_listBase.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
+#include "DNA_constraint_types.h"
#include "DNA_scene_types.h"
#include "TransformWriter.h"
@@ -62,16 +63,13 @@ public:
void add_armature_bones(Object *ob_arm, Scene *sce, SceneExporter *se,
std::list<Object *>& child_objects);
- bool is_skinned_mesh(Object *ob);
-
bool add_instance_controller(Object *ob);
- void export_controllers(Scene *sce);
+ //void export_controllers(Scene *sce);*/
- void operator()(Object *ob);
+ //void operator()(Object *ob);
private:
- Scene *scene;
UnitConverter converter;
const ExportSettings *export_settings;
@@ -98,29 +96,6 @@ private:
std::string get_controller_id(Object *ob_arm, Object *ob);
- // ob should be of type OB_MESH
- // both args are required
- void export_controller(Object *ob, Object *ob_arm);
-
- void add_joints_element(ListBase *defbase,
- const std::string& joints_source_id, const std::string& inv_bind_mat_source_id);
-
- void add_bind_shape_mat(Object *ob);
-
- std::string add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id);
-
- std::string add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id);
-
- Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def);
-
- bool is_bone_defgroup(Object *ob_arm, bDeformGroup *def);
-
- std::string add_weights_source(Mesh *me, const std::string& controller_id,
- const std::list<float>& weights);
-
- void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id,
- const std::list<int>& vcount, const std::list<int>& joints);
-
void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone);
};
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index cd2574d055e..c270a1e6b20 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -78,85 +78,9 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
return &joint_index_to_joint_info_map[joint_index];
}
#endif
-void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], Object *ob_arm)
-{
- std::vector<COLLADAFW::Node *>::iterator it;
- it = std::find(finished_joints.begin(), finished_joints.end(), node);
- if (it != finished_joints.end()) return;
-
- float mat[4][4];
- float obmat[4][4];
-
- // object-space
- get_node_mat(obmat, node, NULL, NULL);
- EditBone *bone = ED_armature_edit_bone_add((bArmature *)ob_arm->data, (char *)bc_get_joint_name(node));
- totbone++;
-
- if (parent) bone->parent = parent;
-
- float angle = 0;
-
- // get world-space
- if (parent) {
- mult_m4_m4m4(mat, parent_mat, obmat);
-
- }
- else {
- copy_m4_m4(mat, obmat);
-
- }
- float loc[3], size[3], rot[3][3];
- mat4_to_loc_rot_size(loc, rot, size, obmat);
- mat3_to_vec_roll(rot, NULL, &angle);
- bone->roll = angle;
- // set head
- copy_v3_v3(bone->head, mat[3]);
-
- // set tail, don't set it to head because 0-length bones are not allowed
- float vec[3] = {0.0f, 0.5f, 0.0f};
- add_v3_v3v3(bone->tail, bone->head, vec);
-
- // set parent tail
- if (parent && totchild == 1) {
- copy_v3_v3(parent->tail, bone->head);
-
- // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
- // bone->flag |= BONE_CONNECTED;
-
- // XXX increase this to prevent "very" small bones?
- const float epsilon = 0.000001f;
-
- // derive leaf bone length
- float length = len_v3v3(parent->head, parent->tail);
- if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
- leaf_bone_length = length;
- }
-
- // treat zero-sized bone like a leaf bone
- if (length <= epsilon) {
- add_leaf_bone(parent_mat, parent, node);
- }
-
- }
-
- COLLADAFW::NodePointerArray& children = node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
- create_unskinned_bone(children[i], bone, children.getCount(), mat, ob_arm);
- }
-
- // 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);
- }
-
- finished_joints.push_back(node);
-
-}
-
-void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], bArmature *arm)
+void ArmatureImporter::create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
+ float parent_mat[4][4], bArmature *arm)
{
//Checking if bone is already made.
std::vector<COLLADAFW::Node *>::iterator it;
@@ -168,50 +92,52 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
// JointData* jd = get_joint_data(node);
float mat[4][4];
-
+ float obmat[4][4];
+
// TODO rename from Node "name" attrs later
EditBone *bone = ED_armature_edit_bone_add(arm, (char *)bc_get_joint_name(node));
totbone++;
- if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
+ if (skin && skin->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
// get original world-space matrix
invert_m4_m4(mat, joint_inv_bind_mat);
}
// create a bone even if there's no joint data for it (i.e. it has no influence)
else {
- float obmat[4][4];
-
- // object-space
+ // bone-space
get_node_mat(obmat, node, NULL, NULL);
// get world-space
- if (parent)
+ if (parent) {
mult_m4_m4m4(mat, parent_mat, obmat);
- else
+ }
+ else {
copy_m4_m4(mat, obmat);
-
- float loc[3], size[3], rot[3][3], angle;
- mat4_to_loc_rot_size(loc, rot, size, obmat);
- mat3_to_vec_roll(rot, NULL, &angle);
- bone->roll = angle;
+ }
}
-
if (parent) bone->parent = parent;
+ float loc[3], size[3], rot[3][3];
+ float angle;
+ float vec[3] = {0.0f, 0.5f, 0.0f};
+ mat4_to_loc_rot_size(loc, rot, size, mat);
+ //copy_m3_m4(bonemat,mat);
+ mat3_to_vec_roll(rot, vec, &angle);
+
+ bone->roll = angle;
// set head
copy_v3_v3(bone->head, mat[3]);
// set tail, don't set it to head because 0-length bones are not allowed
- float vec[3] = {0.0f, 0.5f, 0.0f};
add_v3_v3v3(bone->tail, bone->head, vec);
// set parent tail
if (parent && totchild == 1) {
- copy_v3_v3(parent->tail, bone->head);
+ 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;
+ bone->flag |= BONE_CONNECTED;
// XXX increase this to prevent "very" small bones?
const float epsilon = 0.000001f;
@@ -227,32 +153,6 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
add_leaf_bone(parent_mat, parent, node);
}
- /*
-#if 0
- // and which row in mat is bone direction
- float vec[3];
- sub_v3_v3v3(vec, parent->tail, parent->head);
-#ifdef COLLADA_DEBUG
- print_v3("tail - head", vec);
- print_m4("matrix", parent_mat);
-#endif
- for (int i = 0; i < 3; i++) {
-#ifdef COLLADA_DEBUG
- char *axis_names[] = {"X", "Y", "Z"};
- printf("%s-axis length is %f\n", axis_names[i], len_v3(parent_mat[i]));
-#endif
- float angle = angle_v2v2(vec, parent_mat[i]);
- if (angle < min_angle) {
-#ifdef COLLADA_DEBUG
- print_v3("picking", parent_mat[i]);
- printf("^ %s axis of %s's matrix\n", axis_names[i], get_dae_name(node));
-#endif
- bone_direction_row = i;
- min_angle = angle;
- }
- }
-#endif
- */
}
COLLADAFW::NodePointerArray& children = node->getChildNodes();
@@ -265,10 +165,12 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
add_leaf_bone(mat, bone, node);
}
+ bone->length = len_v3v3(bone->head, bone->tail);
+
finished_joints.push_back(node);
}
-void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node *node)
+void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node *node)
{
LeafBone leaf;
@@ -299,7 +201,6 @@ void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW:
void ArmatureImporter::fix_leaf_bones( )
{
// 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;
@@ -307,11 +208,10 @@ void ArmatureImporter::fix_leaf_bones( )
// pointing up
float vec[3] = {0.0f, 0.0f, 0.1f};
- // if parent: take parent length and direction
- if (leaf.bone->parent) sub_v3_v3v3(vec, leaf.bone->parent->tail, leaf.bone->parent->head);
+ sub_v3_v3v3(vec, leaf.bone->tail , leaf.bone->head);
+ mul_v3_fl(vec, leaf_bone_length);
+ add_v3_v3v3(leaf.bone->tail, leaf.bone->head , vec);
- copy_v3_v3(leaf.bone->tail, leaf.bone->head);
- add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
}
}
@@ -410,46 +310,40 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm)
void ArmatureImporter::create_armature_bones( )
{
std::vector<COLLADAFW::Node *>::iterator ri;
+
+ leaf_bone_length = FLT_MAX;
//if there is an armature created for root_joint next root_joint
for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
if (get_armature_for_joint(*ri) != NULL) continue;
- //add armature object for current joint
- //Object *ob_arm = bc_add_object(scene, OB_ARMATURE, NULL);
-
Object *ob_arm = joint_parent_map[(*ri)->getUniqueId()];
if (!ob_arm)
continue;
- //ob_arm->type = OB_ARMATURE;
ED_armature_to_edit(ob_arm);
- // min_angle = 360.0f; // minimum angle between bone head-tail and a row of bone matrix
-
- // create unskinned bones
/*
* TODO:
* check if bones have already been created for a given joint
*/
- leaf_bone_length = FLT_MAX;
- create_unskinned_bone(*ri, NULL, (*ri)->getChildNodes().getCount(), NULL, ob_arm);
+ create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature *)ob_arm->data);
+
+ //leaf bone tails are derived from the matrix, so no need of this.
fix_leaf_bones();
// exit armature edit mode
-
unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
ED_armature_from_edit(ob_arm);
- set_pose(ob_arm, *ri, NULL, NULL);
+ //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(ob_arm);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
}
-
-
}
void ArmatureImporter::create_armature_bones(SkinInfo& skin)
@@ -521,10 +415,23 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
break;
}
- if (shared)
+ if (!shared && this->joint_parent_map.size() > 0) {
+ // All armatures have been created while creating the Node tree.
+ // The Collada exporter currently does not create a
+ // strict relationship between geometries and armatures
+ // So when we reimport a Blender collada file, then we have
+ // to guess what is meant.
+ // XXX This is not safe when we have more than one armatures
+ // in the import.
+ shared = this->joint_parent_map.begin()->second;
+ }
+
+ if (shared) {
ob_arm = skin.set_armature(shared);
- else
+ }
+ else {
ob_arm = skin.create_armature(scene); //once for every armature
+ }
// enter armature edit mode
ED_armature_to_edit(ob_arm);
@@ -533,7 +440,6 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
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;
- // min_angle = 360.0f; // minimum angle between bone head-tail and a row of bone matrix
// create bones
/*
@@ -549,7 +455,7 @@ 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, (bArmature *)ob_arm->data);
if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]);
@@ -563,24 +469,14 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
ED_armature_edit_free(ob_arm);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
- // set_leaf_bone_shapes(ob_arm);
- // set_euler_rotmode();
}
-
-// 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::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[][4])
+void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4])
{
char *bone_name = (char *) bc_get_joint_name(root_node);
float mat[4][4];
float obmat[4][4];
- float ax[3];
- float angle = 0.0f;
-
// object-space
get_node_mat(obmat, root_node, NULL, NULL);
@@ -597,14 +493,17 @@ void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, con
}
else {
+
copy_m4_m4(mat, obmat);
float invObmat[4][4];
invert_m4_m4(invObmat, ob_arm->obmat);
mult_m4_m4m4(pchan->pose_mat, invObmat, mat);
+
}
- mat4_to_axis_angle(ax, &angle, mat);
- pchan->bone->roll = angle;
+ //float angle = 0.0f;
+ ///*mat4_to_axis_angle(ax, &angle, mat);
+ //pchan->bone->roll = angle;*/
COLLADAFW::NodePointerArray& children = root_node->getChildNodes();
@@ -614,6 +513,10 @@ 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
void ArmatureImporter::add_joint(COLLADAFW::Node *node, bool root, Object *parent, Scene *sce)
{
joint_by_uid[node->getUniqueId()] = node;
@@ -729,13 +632,12 @@ bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControlle
bool ArmatureImporter::write_controller(const COLLADAFW::Controller *controller)
{
// - create and store armature object
-
- const COLLADAFW::UniqueId& skin_id = controller->getUniqueId();
+ const COLLADAFW::UniqueId& con_id = controller->getUniqueId();
if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
COLLADAFW::SkinController *co = (COLLADAFW::SkinController *)controller;
// to be able to find geom id by controller id
- geom_uid_by_controller_uid[skin_id] = co->getSource();
+ geom_uid_by_controller_uid[con_id] = co->getSource();
const COLLADAFW::UniqueId& data_uid = co->getSkinControllerData();
if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) {
@@ -746,14 +648,71 @@ bool ArmatureImporter::write_controller(const COLLADAFW::Controller *controller)
skin_by_data_uid[data_uid].set_controller(co);
}
// morph controller
- else {
- // shape keys? :)
- fprintf(stderr, "Morph controller is not supported yet.\n");
+ else if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_MORPH) {
+ COLLADAFW::MorphController *co = (COLLADAFW::MorphController *)controller;
+ // to be able to find geom id by controller id
+ geom_uid_by_controller_uid[con_id] = co->getSource();
+ //Shape keys are applied in DocumentImporter->finish()
+ morph_controllers.push_back(co);
}
return true;
}
+void ArmatureImporter::make_shape_keys()
+{
+ std::vector<COLLADAFW::MorphController *>::iterator mc;
+ float weight;
+
+ for (mc = morph_controllers.begin(); mc != morph_controllers.end(); mc++) {
+ //Controller data
+ COLLADAFW::UniqueIdArray& morphTargetIds = (*mc)->getMorphTargets();
+ COLLADAFW::FloatOrDoubleArray& morphWeights = (*mc)->getMorphWeights();
+
+ //Prereq: all the geometries must be imported and mesh objects must be made
+ Object *source_ob = this->mesh_importer->get_object_by_geom_uid((*mc)->getSource());
+
+ if (source_ob) {
+
+ Mesh *source_me = (Mesh*) source_ob->data;
+ //insert key to source mesh
+ Key *key = source_me->key = BKE_key_add((ID *)source_me);
+ key->type = KEY_RELATIVE;
+ KeyBlock *kb;
+
+ //insert basis key
+ kb = BKE_keyblock_add_ctime(key, "Basis", FALSE);
+ BKE_key_convert_from_mesh(source_me, kb);
+
+ //insert other shape keys
+ for (int i = 0 ; i < morphTargetIds.getCount() ; i++ ) {
+ //better to have a seperate map of morph objects,
+ //This'll do for now since only mesh morphing is imported
+
+ Mesh *me = this->mesh_importer->get_mesh_by_geom_uid(morphTargetIds[i]);
+
+ if (me) {
+ me->key = key;
+ 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);
+
+ //apply weights
+ weight = morphWeights.getFloatValues()->getData()[i];
+ kb->curval = weight;
+ }
+ else {
+ fprintf(stderr, "Morph target geometry not found.\n");
+ }
+ }
+ }
+ else {
+ fprintf(stderr, "Morph target object not found.\n");
+ }
+ }
+}
+
COLLADAFW::UniqueId *ArmatureImporter::get_geometry_uid(const COLLADAFW::UniqueId& controller_uid)
{
@@ -792,7 +751,7 @@ void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, char *joint
}
// gives a world-space mat
-bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
+bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
{
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
bool found = false;
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index a6b37287479..b07edfbf34d 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -29,13 +29,16 @@
#include "COLLADAFWNode.h"
#include "COLLADAFWUniqueId.h"
+#include "COLLADAFWMorphController.h"
extern "C" {
#include "BKE_context.h"
+#include "BKE_key.h"
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_key_types.h"
#include "ED_armature.h"
}
@@ -88,6 +91,7 @@ private:
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> joint_by_uid; // contains all joints
std::vector<COLLADAFW::Node*> root_joints;
std::vector<COLLADAFW::Node*> finished_joints;
+ std::vector<COLLADAFW::MorphController*> morph_controllers;
std::map<COLLADAFW::UniqueId, Object*> joint_parent_map;
std::map<COLLADAFW::UniqueId, Object*> unskinned_armature_map;
@@ -103,17 +107,14 @@ private:
JointData *get_joint_data(COLLADAFW::Node *node);
#endif
- void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], bArmature *arm);
+ void create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
+ float parent_mat[4][4], bArmature *arm);
- void create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], Object * ob_arm);
-
- void add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node);
+ void add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node * node);
void fix_leaf_bones();
- void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[][4]);
+ void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[4][4]);
#if 0
@@ -140,9 +141,6 @@ public:
ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce);
~ArmatureImporter();
- // 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 add_joint(COLLADAFW::Node *node, bool root, Object *parent, Scene *sce);
#if 0
@@ -152,6 +150,8 @@ public:
// here we add bones to armatures, having armatures previously created in write_controller
void make_armatures(bContext *C);
+ void make_shape_keys();
+
#if 0
// link with meshes, create vertex groups, assign weights
void link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id);
@@ -168,7 +168,7 @@ public:
void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count);
// gives a world-space mat
- bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint);
+ bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint);
void set_tags_map( TagsMap& tags_map);
diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt
index 0091df3c502..326ca2b9937 100644
--- a/source/blender/collada/CMakeLists.txt
+++ b/source/blender/collada/CMakeLists.txt
@@ -36,6 +36,9 @@ set(INC
../windowmanager
../imbuf
../../../intern/guardedalloc
+ ../ikplugin
+ ../../../intern/iksolver/extern
+
)
set(INC_SYS
@@ -48,11 +51,13 @@ set(SRC
ArmatureExporter.cpp
ArmatureImporter.cpp
CameraExporter.cpp
+ ControllerExporter.cpp
DocumentExporter.cpp
DocumentImporter.cpp
EffectExporter.cpp
ErrorHandler.cpp
ExportSettings.cpp
+ ImportSettings.cpp
ExtraHandler.cpp
ExtraTags.cpp
GeometryExporter.cpp
@@ -74,11 +79,13 @@ set(SRC
ArmatureExporter.h
ArmatureImporter.h
CameraExporter.h
+ ControllerExporter.h
DocumentExporter.h
DocumentImporter.h
EffectExporter.h
ErrorHandler.h
ExportSettings.h
+ ImportSettings.h
ExtraHandler.h
ExtraTags.h
GeometryExporter.h
diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp
index 7d438f7f12f..fc56ff8c63c 100644
--- a/source/blender/collada/CameraExporter.cpp
+++ b/source/blender/collada/CameraExporter.cpp
@@ -70,7 +70,8 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
switch (cam->type) {
case CAM_PANO:
- case CAM_PERSP: {
+ case CAM_PERSP:
+ {
COLLADASW::PerspectiveOptic persp(mSW);
persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov");
persp.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio");
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
new file mode 100644
index 00000000000..41693d4d680
--- /dev/null
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -0,0 +1,604 @@
+/*
+ * ***** 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): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed,
+ * Nathan Letwory, Sukhitha Jayathilake
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/collada/ControllerExporter.cpp
+ * \ingroup collada
+ */
+
+#include "COLLADASWBaseInputElement.h"
+#include "COLLADASWInstanceController.h"
+#include "COLLADASWPrimitves.h"
+#include "COLLADASWSource.h"
+
+#include "DNA_action_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+
+#include "BKE_action.h"
+#include "BKE_armature.h"
+
+extern "C" {
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+}
+
+#include "ED_armature.h"
+
+#include "BLI_listbase.h"
+
+#include "GeometryExporter.h"
+#include "ArmatureExporter.h"
+#include "ControllerExporter.h"
+#include "SceneExporter.h"
+
+#include "collada_utils.h"
+
+// XXX exporter writes wrong data for shared armatures. A separate
+// controller should be written for each armature-mesh binding how do
+// we make controller ids then?
+ControllerExporter::ControllerExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {
+}
+
+bool ControllerExporter::is_skinned_mesh(Object *ob)
+{
+ return bc_get_assigned_armature(ob) != NULL;
+}
+
+
+void ControllerExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone)
+{
+ if (bc_is_root_bone(bone, this->export_settings->deform_bones_only))
+ ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm)));
+ else {
+ for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ write_bone_URLs(ins, ob_arm, child);
+ }
+ }
+}
+
+bool ControllerExporter::add_instance_controller(Object *ob)
+{
+ Object *ob_arm = bc_get_assigned_armature(ob);
+ bArmature *arm = (bArmature *)ob_arm->data;
+
+ const std::string& controller_id = get_controller_id(ob_arm, ob);
+
+ COLLADASW::InstanceController ins(mSW);
+ ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id));
+
+ Mesh *me = (Mesh *)ob->data;
+ if (!me->dvert) return false;
+
+ // write root bone URLs
+ Bone *bone;
+ for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) {
+ write_bone_URLs(ins, ob_arm, bone);
+ }
+
+ InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only);
+
+ ins.add();
+ return true;
+}
+
+void ControllerExporter::export_controllers(Scene *sce)
+{
+ scene = sce;
+
+ openLibrary();
+
+ GeometryFunctor gf;
+ gf.forEachMeshObjectInExportSet<ControllerExporter>(sce, *this, this->export_settings->export_set);
+
+ closeLibrary();
+}
+
+void ControllerExporter::operator()(Object *ob)
+{
+ Object *ob_arm = bc_get_assigned_armature(ob);
+ Key *key = BKE_key_from_object(ob);
+
+ if (ob_arm) {
+ export_skin_controller(ob, ob_arm);
+ }
+ if (key) {
+ export_morph_controller(ob, key);
+ }
+}
+#if 0
+
+bool ArmatureExporter::already_written(Object *ob_arm)
+{
+ return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) != written_armatures.end();
+}
+
+void ArmatureExporter::wrote(Object *ob_arm)
+{
+ written_armatures.push_back(ob_arm);
+}
+
+void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<Object *>& objects, Scene *sce)
+{
+ objects.clear();
+
+ Base *base = (Base *) sce->base.first;
+ while (base) {
+ Object *ob = base->object;
+
+ if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) {
+ objects.push_back(ob);
+ }
+
+ base = base->next;
+ }
+}
+#endif
+
+std::string ControllerExporter::get_joint_sid(Bone *bone, Object *ob_arm)
+{
+ return get_joint_id(bone, ob_arm);
+}
+
+std::string ControllerExporter::get_controller_id(Object *ob_arm, Object *ob)
+{
+ return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + SKIN_CONTROLLER_ID_SUFFIX;
+}
+
+std::string ControllerExporter::get_controller_id(Key *key, Object *ob)
+{
+ return translate_id(id_name(ob)) + MORPH_CONTROLLER_ID_SUFFIX;
+}
+
+// ob should be of type OB_MESH
+// both args are required
+void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
+{
+ // joint names
+ // joint inverse bind matrices
+ // vertex weights
+
+ // input:
+ // joint names: ob -> vertex group names
+ // vertex group weights: me->dvert -> groups -> index, weight
+
+#if 0
+ me->dvert :
+
+ typedef struct MDeformVert {
+ struct MDeformWeight *dw;
+ int totweight;
+ int flag; // flag only in use for weightpaint now
+ } MDeformVert;
+
+ typedef struct MDeformWeight {
+ int def_nr;
+ float weight;
+ } MDeformWeight;
+#endif
+
+ bool use_instantiation = this->export_settings->use_object_instantiation;
+ Mesh *me;
+
+ if (this->export_settings->apply_modifiers)
+ me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type);
+ else
+ me = (Mesh *)ob->data;
+
+ BKE_mesh_tessface_ensure(me);
+
+ if (!me->dvert) return;
+
+ std::string controller_name = id_name(ob_arm);
+ std::string controller_id = get_controller_id(ob_arm, ob);
+
+ openSkin(controller_id, controller_name,
+ COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation)));
+
+ add_bind_shape_mat(ob);
+
+ std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id);
+ std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, &ob->defbase, controller_id);
+
+ std::list<int> vcounts;
+ std::list<int> joints;
+ std::list<float> weights;
+
+ {
+ int i, j;
+
+ // def group index -> joint index
+ std::vector<int> joint_index_by_def_index;
+ bDeformGroup *def;
+
+ for (def = (bDeformGroup *)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) {
+ if (is_bone_defgroup(ob_arm, def))
+ joint_index_by_def_index.push_back(j++);
+ else
+ joint_index_by_def_index.push_back(-1);
+ }
+
+ for (i = 0; i < me->totvert; i++) {
+ MDeformVert *vert = &me->dvert[i];
+ std::map<int, float> jw;
+
+ // We're normalizing the weights later
+ float sumw = 0.0f;
+
+ for (j = 0; j < vert->totweight; j++) {
+ int idx = vert->dw[j].def_nr;
+ if (idx >= 0) {
+ int joint_index = joint_index_by_def_index[idx];
+ if (joint_index != -1 && vert->dw[j].weight > 0.0f) {
+ jw[joint_index] += vert->dw[j].weight;
+ sumw += vert->dw[j].weight;
+ }
+ }
+ }
+
+ if (sumw > 0.0f) {
+ float invsumw = 1.0f / sumw;
+ vcounts.push_back(jw.size());
+ for (std::map<int, float>::iterator m = jw.begin(); m != jw.end(); ++m) {
+ joints.push_back((*m).first);
+ weights.push_back(invsumw * (*m).second);
+ }
+ }
+ else {
+ vcounts.push_back(0);
+#if 0
+ vcounts.push_back(1);
+ joints.push_back(-1);
+ weights.push_back(1.0f);
+#endif
+ }
+ }
+ }
+
+ std::string weights_source_id = add_weights_source(me, controller_id, weights);
+ add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
+ add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
+
+ if (this->export_settings->apply_modifiers)
+ {
+ BKE_libblock_free_us(&(G.main->mesh), me);
+ }
+ closeSkin();
+ closeController();
+}
+
+void ControllerExporter::export_morph_controller(Object *ob, Key *key)
+{
+ bool use_instantiation = this->export_settings->use_object_instantiation;
+ Mesh *me;
+
+ if (this->export_settings->apply_modifiers) {
+ me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type);
+ }
+ else {
+ me = (Mesh *)ob->data;
+ }
+ BKE_mesh_tessface_ensure(me);
+
+ std::string controller_name = id_name(ob) + "-morph";
+ std::string controller_id = get_controller_id(key, ob);
+
+ openMorph(controller_id, controller_name,
+ COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation)));
+
+ std::string targets_id = add_morph_targets(key, ob);
+ std::string morph_weights_id = add_morph_weights(key, ob);
+
+ COLLADASW::TargetsElement targets(mSW);
+
+ COLLADASW::InputList &input = targets.getInputList();
+
+ input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_TARGET, // constant declared in COLLADASWInputList.h
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, targets_id)));
+ input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT,
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id)));
+ targets.add();
+
+ if (this->export_settings->apply_modifiers)
+ {
+ BKE_libblock_free_us(&(G.main->mesh), me);
+ }
+
+ //support for animations
+ //can also try the base element and param alternative
+ add_weight_extras(key);
+ closeMorph();
+ closeController();
+}
+
+std::string ControllerExporter::add_morph_targets(Key *key, Object *ob)
+{
+ std::string source_id = translate_id(id_name(ob)) + TARGETS_SOURCE_ID_SUFFIX;
+
+ COLLADASW::IdRefSource source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(key->totkey - 1);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("IDREF");
+
+ source.prepareToAppendValues();
+
+ KeyBlock * kb = (KeyBlock*)key->block.first;
+ //skip the basis
+ kb = kb->next;
+ for (; kb; kb = kb->next) {
+ std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name);
+ source.appendValues(geom_id);
+
+ }
+
+ source.finish();
+
+ return source_id;
+}
+
+std::string ControllerExporter::add_morph_weights(Key *key, Object *ob)
+{
+ std::string source_id = translate_id(id_name(ob)) + WEIGHTS_SOURCE_ID_SUFFIX;
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(key->totkey - 1);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("MORPH_WEIGHT");
+
+ source.prepareToAppendValues();
+
+ KeyBlock * kb = (KeyBlock*)key->block.first;
+ //skip the basis
+ kb = kb->next;
+ for (; kb; kb = kb->next) {
+ float weight = kb->curval;
+ source.appendValues(weight);
+ }
+ source.finish();
+
+ return source_id;
+}
+
+//Added to implemente support for animations.
+void ControllerExporter::add_weight_extras(Key *key)
+{
+ // can also try the base element and param alternative
+ COLLADASW::BaseExtraTechnique extra;
+
+ KeyBlock * kb = (KeyBlock*)key->block.first;
+ //skip the basis
+ kb = kb->next;
+ for (; kb; kb = kb->next) {
+ // XXX why is the weight not used here and set to 0.0?
+ float weight = kb->curval;
+ extra.addExtraTechniqueParameter ("KHR", "morph_weights" , 0.000, "MORPH_WEIGHT_TO_TARGET");
+ }
+}
+
+
+
+void ControllerExporter::add_joints_element(ListBase *defbase,
+ const std::string& joints_source_id, const std::string& inv_bind_mat_source_id)
+{
+ COLLADASW::JointsElement joints(mSW);
+ COLLADASW::InputList &input = joints.getInputList();
+
+ input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id)));
+ input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX,
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id)));
+ joints.add();
+}
+
+void ControllerExporter::add_bind_shape_mat(Object *ob)
+{
+ double bind_mat[4][4];
+
+ converter.mat4_to_dae_double(bind_mat, ob->obmat);
+
+ addBindShapeTransform(bind_mat);
+}
+
+std::string ControllerExporter::add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id)
+{
+ std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX;
+
+ int totjoint = 0;
+ bDeformGroup *def;
+ for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
+ if (is_bone_defgroup(ob_arm, def))
+ totjoint++;
+ }
+
+ COLLADASW::NameSource source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(totjoint);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("JOINT");
+
+ source.prepareToAppendValues();
+
+ for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
+ Bone *bone = get_bone_from_defgroup(ob_arm, def);
+ if (bone)
+ source.appendValues(get_joint_sid(bone, ob_arm));
+ }
+
+ source.finish();
+
+ return source_id;
+}
+
+std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id)
+{
+ std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
+
+ int totjoint = 0;
+ for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
+ if (is_bone_defgroup(ob_arm, def))
+ totjoint++;
+ }
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(totjoint); //BLI_countlist(defbase));
+ source.setAccessorStride(16);
+
+ source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("TRANSFORM");
+
+ source.prepareToAppendValues();
+
+ bPose *pose = ob_arm->pose;
+ bArmature *arm = (bArmature *)ob_arm->data;
+
+ int flag = arm->flag;
+
+ // put armature in rest position
+ if (!(arm->flag & ARM_RESTPOS)) {
+ arm->flag |= ARM_RESTPOS;
+ BKE_pose_where_is(scene, ob_arm);
+ }
+
+ for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
+ if (is_bone_defgroup(ob_arm, def)) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(pose, def->name);
+
+ float mat[4][4];
+ float world[4][4];
+ float inv_bind_mat[4][4];
+
+ // SECOND_LIFE_COMPATIBILITY
+ if (export_settings->second_life) {
+ // Only translations, no rotation vs armature
+ float temp[4][4];
+ unit_m4(temp);
+ copy_v3_v3(temp[3], pchan->bone->arm_mat[3]);
+ mult_m4_m4m4(world, ob_arm->obmat, temp);
+ }
+ else {
+ // make world-space matrix, arm_mat is armature-space
+ mult_m4_m4m4(world, ob_arm->obmat, pchan->bone->arm_mat);
+ }
+
+ invert_m4_m4(mat, world);
+ converter.mat4_to_dae(inv_bind_mat, mat);
+
+ source.appendValues(inv_bind_mat);
+ }
+ }
+
+ // back from rest positon
+ if (!(flag & ARM_RESTPOS)) {
+ arm->flag = flag;
+ BKE_pose_where_is(scene, ob_arm);
+ }
+
+ source.finish();
+
+ return source_id;
+}
+
+Bone *ControllerExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def)
+{
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, def->name);
+ return pchan ? pchan->bone : NULL;
+}
+
+bool ControllerExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup *def)
+{
+ return get_bone_from_defgroup(ob_arm, def) != NULL;
+}
+
+std::string ControllerExporter::add_weights_source(Mesh *me, const std::string& controller_id, const std::list<float>& weights)
+{
+ std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX;
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(weights.size());
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("WEIGHT");
+
+ source.prepareToAppendValues();
+
+ for (std::list<float>::const_iterator i = weights.begin(); i != weights.end(); ++i) {
+ source.appendValues(*i);
+ }
+
+ source.finish();
+
+ return source_id;
+}
+
+void ControllerExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id,
+ const std::list<int>& vcounts,
+ const std::list<int>& joints)
+{
+ COLLADASW::VertexWeightsElement weightselem(mSW);
+ COLLADASW::InputList &input = weightselem.getInputList();
+
+ int offset = 0;
+ input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++));
+ input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT,
+ COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++));
+
+ weightselem.setCount(vcounts.size());
+
+ // write number of deformers per vertex
+ COLLADASW::PrimitivesBase::VCountList vcountlist;
+
+ vcountlist.resize(vcounts.size());
+ std::copy(vcounts.begin(), vcounts.end(), vcountlist.begin());
+
+ weightselem.prepareToAppendVCountValues();
+ weightselem.appendVertexCount(vcountlist);
+
+ weightselem.CloseVCountAndOpenVElement();
+
+ // write deformer index - weight index pairs
+ int weight_index = 0;
+ for (std::list<int>::const_iterator i = joints.begin(); i != joints.end(); ++i) {
+ weightselem.appendValues(*i, weight_index++);
+ }
+
+ weightselem.finish();
+}
diff --git a/source/blender/collada/ControllerExporter.h b/source/blender/collada/ControllerExporter.h
new file mode 100644
index 00000000000..0be51187f6f
--- /dev/null
+++ b/source/blender/collada/ControllerExporter.h
@@ -0,0 +1,127 @@
+/*
+ * ***** 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): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed,
+ * Nathan Letwory, Sukhitha Jayathilake
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ControllerExporter.h
+ * \ingroup collada
+ */
+
+#ifndef __CONTROLLEREXPORTER_H__
+#define __CONTROLLEREXPORTER_H__
+
+#include <list>
+#include <string>
+//#include <vector>
+
+#include "COLLADASWStreamWriter.h"
+#include "COLLADASWLibraryControllers.h"
+#include "COLLADASWInstanceController.h"
+#include "COLLADASWInputList.h"
+#include "COLLADASWNode.h"
+#include "COLLADASWExtraTechnique.h"
+
+#include "DNA_armature_types.h"
+#include "DNA_listBase.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_key_types.h"
+
+#include "TransformWriter.h"
+#include "InstanceWriter.h"
+
+#include "ExportSettings.h"
+
+#include "BKE_key.h"
+
+class SceneExporter;
+
+class ControllerExporter : public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter
+{
+public:
+ ControllerExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
+
+ bool is_skinned_mesh(Object *ob);
+
+ bool add_instance_controller(Object *ob);
+
+ void export_controllers(Scene *sce);
+
+ void operator()(Object *ob);
+
+private:
+ Scene *scene;
+ UnitConverter converter;
+ const ExportSettings *export_settings;
+
+#if 0
+ std::vector<Object *> written_armatures;
+
+ bool already_written(Object *ob_arm);
+
+ void wrote(Object *ob_arm);
+
+ void find_objects_using_armature(Object *ob_arm, std::vector<Object *>& objects, Scene *sce);
+#endif
+
+ std::string get_joint_sid(Bone *bone, Object *ob_arm);
+
+ std::string get_controller_id(Object *ob_arm, Object *ob);
+
+ std::string get_controller_id(Key *key, Object *ob);
+
+ // ob should be of type OB_MESH
+ // both args are required
+ void export_skin_controller(Object *ob, Object *ob_arm);
+
+ void export_morph_controller(Object *ob, Key *key);
+
+ void add_joints_element(ListBase *defbase,
+ const std::string& joints_source_id, const std::string& inv_bind_mat_source_id);
+
+ void add_bind_shape_mat(Object *ob);
+
+ std::string add_morph_targets(Key *key, Object *ob);
+
+ std::string add_morph_weights(Key *key, Object *ob);
+
+ void add_weight_extras(Key *key);
+
+ std::string add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id);
+
+ std::string add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id);
+
+ Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def);
+
+ bool is_bone_defgroup(Object *ob_arm, bDeformGroup *def);
+
+ std::string add_weights_source(Mesh *me, const std::string& controller_id,
+ const std::list<float>& weights);
+
+ void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id,
+ const std::list<int>& vcount, const std::list<int>& joints);
+
+ void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone);
+};
+
+#endif
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index c491326519f..71909b33db8 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -123,6 +123,7 @@ extern bool bc_has_object_type(LinkNode *export_set, short obtype);
#include "ArmatureExporter.h"
#include "AnimationExporter.h"
#include "CameraExporter.h"
+#include "ControllerExporter.h"
#include "EffectExporter.h"
#include "GeometryExporter.h"
#include "ImageExporter.h"
@@ -269,11 +270,15 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
// <library_controllers>
ArmatureExporter arm_exporter(&sw, this->export_settings);
- if (bc_has_object_type(export_set, OB_ARMATURE)) {
- arm_exporter.export_controllers(sce);
- }
+ ControllerExporter controller_exporter(&sw , this->export_settings);
+ //for Morph controller export, removing the check
+ /*if (bc_has_object_type(export_set, OB_ARMATURE))
+ {*/
+ controller_exporter.export_controllers(sce);
+ //}
// <library_visual_scenes>
+
SceneExporter se(&sw, &arm_exporter, this->export_settings);
se.exportScene(sce);
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 084f71e0afc..2b906fa9ac2 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -54,6 +54,7 @@ extern "C" {
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops.h"
#include "BKE_camera.h"
#include "BKE_main.h"
@@ -76,6 +77,9 @@ extern "C" {
#include "MEM_guardedalloc.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
}
#include "ExtraHandler.h"
@@ -96,9 +100,9 @@ extern "C" {
// creates empties for each imported bone on layer 2, for debugging
// #define ARMATURE_TEST
-DocumentImporter::DocumentImporter(bContext *C, const char *filename) :
+DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_settings) :
+ import_settings(import_settings),
mImportStage(General),
- mFilename(filename),
mContext(C),
armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)),
mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
@@ -128,7 +132,9 @@ bool DocumentImporter::import()
// deselect all to select new objects
BKE_scene_base_deselect_all(CTX_data_scene(mContext));
- if (!root.loadDocument(mFilename)) {
+ std::string mFilename = std::string(this->import_settings->filepath);
+ const std::string encodedFilename = bc_url_encode(mFilename);
+ if (!root.loadDocument(encodedFilename)) {
fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n");
return false;
}
@@ -143,7 +149,7 @@ bool DocumentImporter::import()
COLLADASaxFWL::Loader loader2;
COLLADAFW::Root root2(&loader2, this);
- if (!root2.loadDocument(mFilename)) {
+ if (!root2.loadDocument(encodedFilename)) {
fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n");
return false;
}
@@ -174,46 +180,68 @@ void DocumentImporter::finish()
{
if (mImportStage != General)
return;
-
+
+ Main *bmain = CTX_data_main(mContext);
+ // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it
+ Scene *sce = CTX_data_scene(mContext);
+
/** TODO Break up and put into 2-pass parsing of DAE */
std::vector<const COLLADAFW::VisualScene *>::iterator it;
for (it = vscenes.begin(); it != vscenes.end(); it++) {
PointerRNA sceneptr, unit_settings;
PropertyRNA *system, *scale;
- // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it
- Scene *sce = CTX_data_scene(mContext);
// for scene unit settings: system, scale_length
+
RNA_id_pointer_create(&sce->id, &sceneptr);
unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
system = RNA_struct_find_property(&unit_settings, "system");
scale = RNA_struct_find_property(&unit_settings, "scale_length");
-
- switch (unit_converter.isMetricSystem()) {
- case UnitConverter::Metric:
- RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
- break;
- case UnitConverter::Imperial:
- RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
- break;
- default:
- RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
- break;
+
+ if (this->import_settings->import_units) {
+
+ switch (unit_converter.isMetricSystem()) {
+ case UnitConverter::Metric:
+ RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
+ break;
+ case UnitConverter::Imperial:
+ RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
+ break;
+ default:
+ RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
+ break;
+ }
+ float unit_factor = unit_converter.getLinearMeter();
+ RNA_property_float_set(&unit_settings, scale, unit_factor);
+ fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor);
+
}
- RNA_property_float_set(&unit_settings, scale, unit_converter.getLinearMeter());
-
- const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
+ // Write nodes to scene
+ const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
for (unsigned int i = 0; i < roots.getCount(); i++) {
- write_node(roots[i], NULL, sce, NULL, false);
+ std::vector<Object *> *objects_done;
+ objects_done = write_node(roots[i], NULL, sce, NULL, false);
+
+ if (!this->import_settings->import_units) {
+ // Match incoming scene with current unit settings
+ bc_match_scale(objects_done, *sce, unit_converter);
+ }
}
+
+ // update scene
+ DAG_relations_tag_update(bmain);
+ WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL);
+
}
- mesh_importer.optimize_material_assignments();
+ mesh_importer.optimize_material_assignements();
armature_importer.set_tags_map(this->uid_tags_map);
armature_importer.make_armatures(mContext);
+ armature_importer.make_shape_keys();
+ DAG_relations_tag_update(bmain);
#if 0
armature_importer.fix_animation();
@@ -222,8 +250,9 @@ void DocumentImporter::finish()
for (std::vector<const COLLADAFW::VisualScene *>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
- for (unsigned int i = 0; i < roots.getCount(); i++)
+ for (unsigned int i = 0; i < roots.getCount(); i++) {
translate_anim_recursive(roots[i], NULL, NULL);
+ }
}
if (libnode_ob.size()) {
@@ -246,8 +275,7 @@ void DocumentImporter::finish()
}
libnode_ob.clear();
- DAG_scene_sort(CTX_data_main(mContext), sce);
- DAG_ids_flush_update(CTX_data_main(mContext), 0);
+ DAG_relations_tag_update(bmain);
}
}
@@ -256,7 +284,7 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW
{
// The split in #29246, rootmap must point at actual root when
- // calculating bones in apply_curves_as_matrix.
+ // calculating bones in apply_curves_as_matrix. - actual root is the root node.
// This has to do with inverse bind poses being world space
// (the sources for skinned bones' restposes) and the way
// non-skinning nodes have their "restpose" recursively calculated.
@@ -265,7 +293,7 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW
if (par) { // && par->getType() == COLLADAFW::Node::JOINT) {
// par is root if there's no corresp. key in root_map
if (root_map.find(par->getUniqueId()) == root_map.end())
- root_map[node->getUniqueId()] = par;
+ root_map[node->getUniqueId()] = node;
else
root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
}
@@ -282,13 +310,22 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW
#endif
unsigned int i;
+
//for (i = 0; i < 4; i++)
// ob =
anim_importer.translate_Animations(node, root_map, object_map, FW_object_map);
- COLLADAFW::NodePointerArray &children = node->getChildNodes();
- for (i = 0; i < children.getCount(); i++) {
- translate_anim_recursive(children[i], node, NULL);
+ if (node->getType() == COLLADAFW::Node::JOINT && par == NULL) {
+ // For Skeletons without root node we have to simulate the
+ // root node here and recursively enter the same function
+ // XXX: maybe this can be made more elegant.
+ translate_anim_recursive(node, node, parob);
+ }
+ else {
+ COLLADAFW::NodePointerArray &children = node->getChildNodes();
+ for (i = 0; i < children.getCount(); i++) {
+ translate_anim_recursive(children[i], node, NULL);
+ }
}
}
@@ -349,7 +386,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod
fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL);
Object *obn = BKE_object_copy(source_ob);
- obn->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
BKE_scene_base_add(sce, obn);
if (instance_node) {
@@ -376,8 +413,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod
anim_importer.read_node_transform(source_node, obn);
}
- DAG_scene_sort(CTX_data_main(mContext), sce);
- DAG_ids_flush_update(CTX_data_main(mContext), 0);
+ /*DAG_relations_tag_update(CTX_data_main(mContext));*/
COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
if (children.getCount()) {
@@ -406,23 +442,50 @@ Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod
return obn;
}
-void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
+// to create constraints off node <extra> tags. Assumes only constraint data in
+// current <extra> with blender profile.
+void DocumentImporter::create_constraints(ExtraTags *et, Object *ob)
+{
+ if (et && et->isProfile("blender")) {
+ std::string name;
+ short* type = 0;
+ et->setData("type", type);
+ BKE_add_ob_constraint(ob, "Test_con", *type);
+
+ }
+}
+
+std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
{
Object *ob = NULL;
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
bool read_transform = true;
+ std::string id = node->getOriginalId();
+ std::string name = node->getName();
std::vector<Object *> *objects_done = new std::vector<Object *>();
+ fprintf(stderr,
+ "Writing node id='%s', name='%s'\n",
+ id.c_str(),
+ name.c_str());
+
if (is_joint) {
- if (par) {
- Object *empty = par;
- par = bc_add_object(sce, OB_ARMATURE, NULL);
- bc_set_parent(par, empty->parent, mContext);
- //remove empty : todo
- object_map.insert(std::make_pair<COLLADAFW::UniqueId, Object *>(parent_node->getUniqueId(), par));
+ if (parent_node == NULL) {
+ // A Joint on root level is a skeleton without root node.
+ // Here we add the armature "on the fly":
+ par = bc_add_object(sce, OB_ARMATURE, std::string("Armature").c_str());
+ objects_done->push_back(par);
+ object_map.insert(std::make_pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par));
+ node_map[node->getUniqueId()] = node;
}
armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce);
+
+ if (parent_node == NULL) {
+ // for skeletons without root node all has been done above.
+ // Skeletons with root node are handled further down.
+ return objects_done;
+ }
}
else {
COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
@@ -442,13 +505,21 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent
while (geom_done < geom.getCount()) {
ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map,
material_texture_mapping_map);
- objects_done->push_back(ob);
+ if (ob == NULL) {
+ fprintf(stderr,
+ "<node id=\"%s\", name=\"%s\" >...contains a reference to an unknown instance_mesh.\n",
+ id.c_str(),
+ name.c_str());
+ }
+ else {
+ objects_done->push_back(ob);
+ }
++geom_done;
}
while (camera_done < camera.getCount()) {
ob = create_camera_object(camera[camera_done], sce);
if (ob == NULL) {
- std::string id = node->getOriginalId();
+ std::string id = node->getOriginalId();
std::string name = node->getName();
fprintf(stderr, "<node id=\"%s\", name=\"%s\" >...contains a reference to an unknown instance_camera.\n", id.c_str(), name.c_str());
}
@@ -487,16 +558,25 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent
read_transform = false;
}
+
// if node is empty - create empty object
// XXX empty node may not mean it is empty object, not sure about this
if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
- ob = bc_add_object(sce, OB_EMPTY, NULL);
+ //Check if Object is armature, by checking if immediate child is a JOINT node.
+ if (is_armature(node)) {
+ ob = bc_add_object(sce, OB_ARMATURE, name.c_str());
+ }
+ else {
+ ob = bc_add_object(sce, OB_EMPTY, NULL);
+ }
objects_done->push_back(ob);
+
}
// XXX: if there're multiple instances, only one is stored
- if (!ob) return;
+ if (!ob) return objects_done;
+
for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
ob = *it;
std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
@@ -508,6 +588,9 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent
libnode_ob.push_back(ob);
}
+
+ //create_constraints(et,ob);
+
}
for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
@@ -524,9 +607,19 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent
}
// if node has child nodes write them
COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
+
+ if (objects_done->size() > 0) {
+ ob = *objects_done->begin();
+ }
+ else {
+ ob = NULL;
+ }
+
for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
write_node(child_nodes[i], node, sce, ob, is_library_node);
}
+
+ return objects_done;
}
/** When this method is called, the writer must write the entire visual scene.
@@ -588,7 +681,7 @@ bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat)
return true;
const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();
- Material *ma = BKE_material_add((char *)str_mat_id.c_str());
+ Material *ma = BKE_material_add(G.main, (char *)str_mat_id.c_str());
this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
this->uid_material_map[cmat->getUniqueId()] = ma;
@@ -612,9 +705,8 @@ MTex *DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::T
ma->mtex[i] = add_mtex();
ma->mtex[i]->texco = TEXCO_UV;
- ma->mtex[i]->tex = add_texture("Texture");
+ ma->mtex[i]->tex = add_texture(G.main, "Texture");
ma->mtex[i]->tex->type = TEX_IMAGE;
- ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA;
ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
@@ -745,7 +837,6 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
if (mtex != NULL) {
mtex->mapto = MAP_ALPHA;
- mtex->tex->imaflag |= TEX_USEALPHA;
i++;
ma->spectra = ma->alpha = 0;
ma->mode |= MA_ZTRANSP | MA_TRANSP;
@@ -820,8 +911,8 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
cam_id = camera->getOriginalId();
cam_name = camera->getName();
- if (cam_name.size()) cam = (Camera *)BKE_camera_add((char *)cam_name.c_str());
- else cam = (Camera *)BKE_camera_add((char *)cam_id.c_str());
+ if (cam_name.size()) cam = (Camera *)BKE_camera_add(G.main, (char *)cam_name.c_str());
+ else cam = (Camera *)BKE_camera_add(G.main, (char *)cam_id.c_str());
if (!cam) {
fprintf(stderr, "Cannot create camera.\n");
@@ -933,17 +1024,29 @@ bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
if (mImportStage != General)
return true;
- // XXX maybe it is necessary to check if the path is absolute or relative
- const std::string& filepath = image->getImageURI().toNativePath();
- const char *filename = (const char *)mFilename.c_str();
+ const std::string& imagepath = image->getImageURI().toNativePath();
+
char dir[FILE_MAX];
- char full_path[FILE_MAX];
-
- BLI_split_dir_part(filename, dir, sizeof(dir));
- BLI_join_dirfile(full_path, sizeof(full_path), dir, filepath.c_str());
- Image *ima = BKE_image_load_exists(full_path);
+ char absolute_path[FILE_MAX];
+ const char *workpath;
+
+ BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir));
+ BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str());
+ if (BLI_exists(absolute_path)) {
+ workpath = absolute_path;
+ }
+ else {
+ // Maybe imagepath was already absolute ?
+ if (!BLI_exists(imagepath.c_str())) {
+ fprintf(stderr, "Image not found: %s.\n", imagepath.c_str() );
+ return true;
+ }
+ workpath = imagepath.c_str();
+ }
+
+ Image *ima = BKE_image_load_exists(workpath);
if (!ima) {
- fprintf(stderr, "Cannot create image.\n");
+ fprintf(stderr, "Cannot create image: %s\n", workpath);
return true;
}
this->uid_image_map[image->getUniqueId()] = ima;
@@ -961,16 +1064,17 @@ bool DocumentImporter::writeLight(const COLLADAFW::Light *light)
Lamp *lamp = NULL;
std::string la_id, la_name;
- TagsMap::iterator etit;
+ ExtraTags *et = getExtraTags(light->getUniqueId());
+ /*TagsMap::iterator etit;
ExtraTags *et = 0;
etit = uid_tags_map.find(light->getUniqueId().toAscii());
if (etit != uid_tags_map.end())
- et = etit->second;
+ et = etit->second;*/
la_id = light->getOriginalId();
la_name = light->getName();
- if (la_name.size()) lamp = (Lamp *)BKE_lamp_add((char *)la_name.c_str());
- else lamp = (Lamp *)BKE_lamp_add((char *)la_id.c_str());
+ if (la_name.size()) lamp = (Lamp *)BKE_lamp_add(G.main, (char *)la_name.c_str());
+ else lamp = (Lamp *)BKE_lamp_add(G.main, (char *)la_id.c_str());
if (!lamp) {
fprintf(stderr, "Cannot create lamp.\n");
@@ -1185,3 +1289,18 @@ bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *e
return true;
}
+bool DocumentImporter::is_armature(COLLADAFW::Node *node)
+{
+ COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
+ for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
+ if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) {
+ return true;
+ }
+ else {
+ continue;
+ }
+ }
+
+ //no child is JOINT
+ return false;
+}
diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h
index d54b8db9f00..ff0cbd44043 100644
--- a/source/blender/collada/DocumentImporter.h
+++ b/source/blender/collada/DocumentImporter.h
@@ -40,11 +40,14 @@
#include "BKE_object.h"
+#include "BKE_constraint.h"
#include "TransformReader.h"
#include "AnimationImporter.h"
#include "ArmatureImporter.h"
+#include "ControllerExporter.h"
#include "MeshImporter.h"
+#include "ImportSettings.h"
@@ -61,7 +64,7 @@ public:
Controller, //!< Second pass to collect controller data
};
/** Constructor */
- DocumentImporter(bContext *C, const char *filename);
+ DocumentImporter(bContext *C, const ImportSettings *import_settings);
/** Destructor */
~DocumentImporter();
@@ -73,9 +76,11 @@ public:
Object* create_camera_object(COLLADAFW::InstanceCamera*, Scene*);
Object* create_lamp_object(COLLADAFW::InstanceLight*, Scene*);
Object* create_instance_node(Object*, COLLADAFW::Node*, COLLADAFW::Node*, Scene*, bool);
- void write_node(COLLADAFW::Node*, COLLADAFW::Node*, Scene*, Object*, bool);
+ void create_constraints(ExtraTags *et, Object *ob);
+ std::vector<Object *> *write_node(COLLADAFW::Node*, COLLADAFW::Node*, Scene*, Object*, bool);
MTex* create_texture(COLLADAFW::EffectCommon*, COLLADAFW::Texture&, Material*, int, TexIndexTextureArrayMap&);
void write_profile_COMMON(COLLADAFW::EffectCommon*, Material*);
+
void translate_anim_recursive(COLLADAFW::Node*, COLLADAFW::Node*, Object*);
/**
@@ -128,11 +133,15 @@ public:
/** Get an extisting ExtraTags for uid */
ExtraTags* getExtraTags(const COLLADAFW::UniqueId &uid);
+ bool is_armature(COLLADAFW::Node * node);
+
+
+
private:
+ const ImportSettings *import_settings;
/** Current import stage we're in. */
ImportStage mImportStage;
- std::string mFilename;
bContext *mContext;
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
index 2504c276036..cf45b9b8391 100644
--- a/source/blender/collada/ExportSettings.h
+++ b/source/blender/collada/ExportSettings.h
@@ -37,6 +37,7 @@ public:
bool selected;
bool include_children;
bool include_armatures;
+ bool include_shapekeys;
bool deform_bones_only;
bool active_uv_only;
diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp
index df49b4fe8b4..bcf7e573d24 100644
--- a/source/blender/collada/ExtraHandler.cpp
+++ b/source/blender/collada/ExtraHandler.cpp
@@ -74,6 +74,7 @@ bool ExtraHandler::parseElement(
if (!et) {
et = new ExtraTags(std::string(profileName));
dimp->addExtraTags(uniqueId, et);
+
}
currentExtraTags = et;
return true;
diff --git a/source/blender/collada/ExtraHandler.h b/source/blender/collada/ExtraHandler.h
index 900e7b70331..aa1ae52a521 100644
--- a/source/blender/collada/ExtraHandler.h
+++ b/source/blender/collada/ExtraHandler.h
@@ -31,6 +31,7 @@
#include "COLLADASaxFWLIExtraDataCallbackHandler.h"
#include "COLLADASaxFWLFilePartLoader.h"
+#include "COLLADASWInstanceController.h"
#include "DocumentImporter.h"
#include "AnimationImporter.h"
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index f33f0fa110d..4a6c5b43ce2 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -53,7 +53,8 @@ extern "C" {
#include "collada_utils.h"
// TODO: optimize UV sets by making indexed list with duplicates removed
-GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {
+GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings)
+{
}
@@ -69,9 +70,8 @@ void GeometryExporter::exportGeom(Scene *sce)
}
void GeometryExporter::operator()(Object *ob)
-{
+{
// XXX don't use DerivedMesh, Mesh instead?
-
#if 0
DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH);
#endif
@@ -155,17 +155,93 @@ void GeometryExporter::operator()(Object *ob)
closeGeometry();
- if (this->export_settings->apply_modifiers)
- {
+ if (this->export_settings->apply_modifiers) {
BKE_libblock_free_us(&(G.main->mesh), me);
}
-
+ if (this->export_settings->include_shapekeys) {
+ Key * key = BKE_key_from_object(ob);
+ if (key) {
+ KeyBlock * kb = (KeyBlock*)key->block.first;
+ //skip the basis
+ kb = kb->next;
+ for (; kb; kb = kb->next) {
+ BKE_key_convert_to_mesh(kb, me);
+ export_key_mesh(ob, me, kb);
+ }
+ }
+ }
#if 0
dm->release(dm);
#endif
}
+void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
+{
+ std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name);
+ std::vector<Normal> nor;
+ std::vector<Face> norind;
+
+ if (exportedGeometry.find(geom_id) != exportedGeometry.end())
+ {
+ return;
+ }
+
+ std::string geom_name = kb->name;
+
+ exportedGeometry.insert(geom_id);
+
+ bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
+
+ create_normals(nor, norind, me);
+
+ // openMesh(geoId, geoName, meshId)
+ openMesh(geom_id, geom_name);
+
+ // writes <source> for vertex coords
+ createVertsSource(geom_id, me);
+
+ // writes <source> for normal coords
+ createNormalsSource(geom_id, me, nor);
+
+ bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
+
+ // writes <source> for uv coords if mesh has uv coords
+ if (has_uvs)
+ createTexcoordsSource(geom_id, me);
+
+ if (has_color)
+ createVertexColorSource(geom_id, me);
+
+ // <vertices>
+
+ COLLADASW::Vertices verts(mSW);
+ verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX));
+ COLLADASW::InputList &input_list = verts.getInputList();
+ COLLADASW::Input input(COLLADASW::InputSemantic::POSITION, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
+ input_list.push_back(input);
+ verts.add();
+
+ //createLooseEdgeList(ob, me, geom_id, norind);
+
+ // XXX slow
+ if (ob->totcol) {
+ for (int a = 0; a < ob->totcol; a++) {
+ createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
+ }
+ }
+ else {
+ createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
+ }
+
+ closeMesh();
+
+ if (me->flag & ME_TWOSIDED) {
+ mSW->appendTextBlock("<extra><technique profile=\"MAYA\"><double_sided>1</double_sided></technique></extra>");
+ }
+
+ closeGeometry();
+}
void GeometryExporter::createLooseEdgeList(Object *ob,
Mesh *me,
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 7161bb751dd..7cbbf0da8fa 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -39,9 +39,12 @@
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_key_types.h"
#include "ExportSettings.h"
+#include "BKE_key.h"
+
extern Object *bc_get_highest_selected_ancestor_or_self(Object *ob);
// TODO: optimize UV sets by making indexed list with duplicates removed
@@ -100,6 +103,8 @@ public:
COLLADASW::URI getUrlBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix = "");
COLLADASW::URI makeUrl(std::string id);
+
+ void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb);
/* int getTriCount(MFace *faces, int totface);*/
private:
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index aba290f5ce4..55fe2034869 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -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.imtype);
+ BKE_add_image_extension(export_file, &imageFormat);
BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file);
diff --git a/intern/cycles/util/util_attribute.h b/source/blender/collada/ImportSettings.cpp
index 334864c7f44..74607787f25 100644
--- a/intern/cycles/util/util_attribute.h
+++ b/source/blender/collada/ImportSettings.cpp
@@ -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
@@ -14,18 +14,14 @@
* 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): Gaia Clary.
+ *
+ * ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __UTIL_ATTRIBUTE_H__
-#define __UTIL_ATTRIBUTE_H__
-
-#include "util_types.h"
-
-CCL_NAMESPACE_BEGIN
-
-const char *attribute_standard_name(AttributeStandard std);
-
-CCL_NAMESPACE_END
-
-#endif /* __UTIL_ATTRIBUTE_H__ */
+/** \file blender/collada/ExportSettings.cpp
+ * \ingroup collada
+ */
+#include "ImportSettings.h"
diff --git a/source/gameengine/Physics/common/PHY_IController.cpp b/source/blender/collada/ImportSettings.h
index 8568ffa74e6..3f3a9fb354e 100644
--- a/source/gameengine/Physics/common/PHY_IController.cpp
+++ b/source/blender/collada/ImportSettings.h
@@ -15,24 +15,25 @@
* 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.
+ * Contributor(s): Gaia Clary
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file gameengine/Physics/common/PHY_IController.cpp
- * \ingroup phys
+/** \file ExportSettings.h
+ * \ingroup collada
*/
-#include "PHY_IController.h"
+#ifndef __IMPORTSETTINGS_H__
+#define __IMPORTSETTINGS_H__
+
+#include "collada.h"
-PHY_IController::~PHY_IController()
-{
+struct ImportSettings {
+public:
+ bool import_units;
-}
+ char *filepath;
+};
+#endif
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index de8d1e85eb9..26915f37002 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -63,10 +63,9 @@ extern "C" {
// get node name, or fall back to original id if not present (name is optional)
template<class T>
-static const char *bc_get_dae_name(T *node)
+static const std::string bc_get_dae_name(T *node)
{
- const std::string& name = node->getName();
- return name.size() ? name.c_str() : node->getOriginalId().c_str();
+ return node->getName().size() ? node->getName(): node->getOriginalId();
}
static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
@@ -268,7 +267,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has su
{
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
- const char *name = bc_get_dae_name(mesh);
+ const std::string &name = bc_get_dae_name(mesh);
for (unsigned i = 0; i < prim_arr.getCount(); i++) {
@@ -287,7 +286,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has su
int count = vca[j];
if (count < 3) {
fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n",
- type_str, name);
+ type_str, name.c_str());
return false;
}
}
@@ -305,7 +304,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has su
}
if (mesh->getPositions().empty()) {
- fprintf(stderr, "Mesh %s has no vertices.\n", name);
+ fprintf(stderr, "Mesh %s has no vertices.\n", name.c_str());
return false;
}
@@ -946,6 +945,20 @@ Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid
return NULL;
}
+Mesh *MeshImporter::get_mesh_by_geom_uid(const COLLADAFW::UniqueId& mesh_uid)
+{
+ if (uid_mesh_map.find(mesh_uid) != uid_mesh_map.end())
+ return uid_mesh_map[mesh_uid];
+ return NULL;
+}
+
+std::string *MeshImporter::get_geometry_name(const std::string &mesh_name)
+{
+ if (this->mesh_geom_map.find(mesh_name) != this->mesh_geom_map.end())
+ return &this->mesh_geom_map[mesh_name];
+ return NULL;
+}
+
MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
MTex *color_texture)
@@ -1061,7 +1074,7 @@ std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
*
* During import all materials have been assigned to Object.
* Now we iterate over the imported objects and optimize
- * the assignments as follows:
+ * the assignements as follows:
*
* for each imported geometry:
* if number of users is 1:
@@ -1075,7 +1088,7 @@ std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
* adjust all other users accordingly.
*
**/
-void MeshImporter::optimize_material_assignments()
+void MeshImporter::optimize_material_assignements()
{
for (std::vector<Object *>::iterator it = imported_objects.begin();
it != imported_objects.end(); ++it)
@@ -1083,8 +1096,8 @@ void MeshImporter::optimize_material_assignments()
Object *ob = (*it);
Mesh *me = (Mesh *) ob->data;
if (me->id.us==1) {
- bc_copy_materials_to_data(ob,me);
- bc_remove_materials_from_object(ob,me);
+ bc_copy_materials_to_data(ob, me);
+ bc_remove_materials_from_object(ob, me);
bc_remove_mark(ob);
}
else if (me->id.us > 1)
@@ -1101,10 +1114,10 @@ void MeshImporter::optimize_material_assignments()
}
}
if (can_move) {
- bc_copy_materials_to_data(ref_ob,me);
+ bc_copy_materials_to_data(ref_ob, me);
for (int index = 0; index < mesh_users.size(); index++) {
Object *object = mesh_users[index];
- bc_remove_materials_from_object(object,me);
+ bc_remove_materials_from_object(object, me);
bc_remove_mark(object);
}
}
@@ -1119,7 +1132,7 @@ void MeshImporter::optimize_material_assignments()
* come along with different materials. So we first create the objects
* and assign the materials to Object, then in a later cleanup we decide
* which materials shall be moved to the created geometries. Also see
- * optimize_material_assignments() above.
+ * optimize_material_assignements() above.
*/
MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
@@ -1284,17 +1297,19 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom;
if (!is_nice_mesh(mesh)) {
- fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh));
+ fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh).c_str());
return true;
}
const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
- Mesh *me = BKE_mesh_add((char *)str_geom_id.c_str());
+ Mesh *me = BKE_mesh_add(G.main, (char *)str_geom_id.c_str());
me->id.us--; // is already 1 here, but will be set later in set_mesh
// store the Mesh pointer to link it later with an Object
this->uid_mesh_map[mesh->getUniqueId()] = me;
-
+ // needed to map mesh to its geometry name (needed for shape key naming)
+ this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
+
int new_tris = 0;
read_vertices(mesh, me);
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 746b0738108..8b0f5cdc200 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -59,6 +59,8 @@ class MeshImporterBase
{
public:
virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) = 0;
+ virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId& mesh_uid) = 0;
+ virtual std::string *get_geometry_name(const std::string &mesh_name) = 0;
};
class UVDataWrapper
@@ -83,6 +85,7 @@ private:
Scene *scene;
ArmatureImporter *armature_importer;
+ std::map<std::string, std::string> mesh_geom_map; // needed for correct shape key naming
std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
std::map<COLLADAFW::UniqueId, Object*> uid_object_map; // geom uid-to-object
std::vector<Object*> imported_objects; // list of imported objects
@@ -106,10 +109,10 @@ private:
#endif
void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
- COLLADAFW::IndexList& index_list, unsigned int *tris_indices);
+ COLLADAFW::IndexList& index_list, unsigned int *tris_indices);
void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
- COLLADAFW::IndexList& index_list, int index, bool quad);
+ COLLADAFW::IndexList& index_list, int index, bool quad);
#ifdef COLLADA_DEBUG
void print_index_list(COLLADAFW::IndexList& index_list);
@@ -151,28 +154,30 @@ public:
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);
MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
- Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
- MTex *color_texture);
+ Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
+ MTex *color_texture);
- void optimize_material_assignments();
+ void optimize_material_assignements();
MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
- std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
- Object *ob, const COLLADAFW::UniqueId *geom_uid,
- MTex **color_texture, char *layername, MTFace *texture_face,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
+ std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
+ Object *ob, const COLLADAFW::UniqueId *geom_uid,
+ MTex **color_texture, char *layername, MTFace *texture_face,
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
- bool isController,
- std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map);
+ bool isController,
+ std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map);
// create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
bool write_geometry(const COLLADAFW::Geometry* geom);
-
+ std::string *get_geometry_name(const std::string &mesh_name);
};
#endif
diff --git a/source/blender/collada/SConscript b/source/blender/collada/SConscript
index 5d921681aea..18ef62e6c85 100644
--- a/source/blender/collada/SConscript
+++ b/source/blender/collada/SConscript
@@ -1,4 +1,5 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
@@ -32,9 +33,9 @@ defs = []
# TODO sanitize inc path building
# relative paths to include dirs, space-separated, string
if env['OURPLATFORM']=='darwin':
- incs = '../blenlib ../blenkernel ../windowmanager ../blenloader ../makesdna ../makesrna ../editors/include ../imbuf ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter [OPENCOLLADA]/COLLADABaseUtils [OPENCOLLADA]/COLLADAFramework [OPENCOLLADA]/COLLADASaxFrameworkLoader [OPENCOLLADA]/GeneratedSaxParser '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC'])
+ incs = '../ikplugin ../../../intern/iksolver/extern ../blenlib ../blenkernel ../windowmanager ../blenloader ../makesdna ../makesrna ../editors/include ../imbuf ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter [OPENCOLLADA]/COLLADABaseUtils [OPENCOLLADA]/COLLADAFramework [OPENCOLLADA]/COLLADASaxFrameworkLoader [OPENCOLLADA]/GeneratedSaxParser '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC'])
else:
- incs = '../blenlib ../blenkernel ../windowmanager ../makesdna ../blenloader ../makesrna ../editors/include ../imbuf ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter/include [OPENCOLLADA]/COLLADABaseUtils/include [OPENCOLLADA]/COLLADAFramework/include [OPENCOLLADA]/COLLADASaxFrameworkLoader/include [OPENCOLLADA]/GeneratedSaxParser/include '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC'])
+ incs = '../ikplugin ../../../intern/iksolver/extern ../blenlib ../blenkernel ../windowmanager ../makesdna ../blenloader ../makesrna ../editors/include ../imbuf ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter/include [OPENCOLLADA]/COLLADABaseUtils/include [OPENCOLLADA]/COLLADAFramework/include [OPENCOLLADA]/COLLADASaxFrameworkLoader/include [OPENCOLLADA]/GeneratedSaxParser/include '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC'])
if env['BF_BUILDINFO']:
defs.append('WITH_BUILDINFO')
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index 6d239ae0fb1..dbf7d40b373 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -182,6 +182,45 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
colladaNode.end();
}
+ if (ob->constraints.first != NULL ) {
+ bConstraint *con = (bConstraint*) ob->constraints.first;
+ while (con) {
+ std::string con_name(id_name(con));
+ std::string con_tag = con_name + "_constraint";
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"type",con->type);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"enforce",con->enforce);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"flag",con->flag);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"headtail",con->headtail);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"own_space",con->ownspace);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"rot_error",con->rot_error);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"tar_space",con->tarspace);
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error);
+
+ //not ideal: add the target object name as another parameter.
+ //No real mapping in the .dae
+ //Need support for multiple target objects also.
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ if (cti && cti->get_constraint_targets) {
+
+ bConstraintTarget *ct;
+ Object *obtar;
+
+ cti->get_constraint_targets(con, &targets);
+ if (cti) {
+ for (ct = (bConstraintTarget*)targets.first; ct; ct = ct->next) {
+ obtar = ct->tar;
+ std::string tar_id(id_name(obtar));
+ colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"target_id",tar_id);
+ }
+ }
+ }
+
+ con = con->next;
+ }
+ }
+
for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) {
if (bc_is_marked(*i)) {
bc_remove_mark(*i);
@@ -189,8 +228,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
}
}
- if (ob->type != OB_ARMATURE) {
+ if (ob->type != OB_ARMATURE)
colladaNode.end();
- }
}
diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h
index 31b471a3e4c..f438c002f91 100644
--- a/source/blender/collada/SceneExporter.h
+++ b/source/blender/collada/SceneExporter.h
@@ -43,6 +43,7 @@ extern "C" {
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
+#include "DNA_constraint_types.h"
#include "DNA_armature_types.h"
#include "DNA_modifier_types.h"
#include "DNA_userdef_types.h"
@@ -51,6 +52,7 @@ extern "C" {
#include "BKE_fcurve.h"
#include "BKE_animsys.h"
#include "BLI_path_util.h"
+#include "BKE_constraint.h"
#include "BLI_fileops.h"
#include "ED_keyframing.h"
}
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index 9b0d59d66ea..15320a8f221 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -168,7 +168,7 @@ Object *SkinInfo::set_armature(Object *ob_arm)
return ob_arm;
}
-bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node)
+bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node)
{
const COLLADAFW::UniqueId& uid = node->getUniqueId();
std::vector<JointData>::iterator it;
@@ -237,10 +237,9 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique
BKE_object_workob_calc_parent(scene, ob, &workob);
invert_m4_m4(ob->parentinv, workob.obmat);
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
+ DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA);
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
#endif
diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h
index 894f53f07c3..e074f59cffc 100644
--- a/source/blender/collada/SkinInfo.h
+++ b/source/blender/collada/SkinInfo.h
@@ -103,7 +103,7 @@ public:
Object* set_armature(Object *ob_arm);
- bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node);
+ bool get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node);
Object *BKE_armature_from_object();
diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp
index 61793589422..67166d819a6 100644
--- a/source/blender/collada/TransformReader.cpp
+++ b/source/blender/collada/TransformReader.cpp
@@ -34,7 +34,7 @@ TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv)
/* pass */
}
-void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob)
+void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob)
{
float cur[4][4];
float copy[4][4];
@@ -46,28 +46,31 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m
COLLADAFW::Transformation *tm = node->getTransformations()[i];
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
- switch (type) {
- case COLLADAFW::Transformation::TRANSLATE:
- dae_translate_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::ROTATE:
- dae_rotate_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::SCALE:
- dae_scale_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::MATRIX:
- dae_matrix_to_mat4(tm, cur);
- break;
- case COLLADAFW::Transformation::LOOKAT:
- case COLLADAFW::Transformation::SKEW:
- fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n");
- break;
+ if (type == COLLADAFW::Transformation::MATRIX) {
+ // XXX why does this return and discard all following transformations?
+ dae_matrix_to_mat4(tm, mat);
+ return;
}
-
- copy_m4_m4(copy, mat);
- mult_m4_m4m4(mat, copy, cur);
-
+ else {
+ switch (type) {
+ case COLLADAFW::Transformation::TRANSLATE:
+ dae_translate_to_mat4(tm, cur);
+ break;
+ case COLLADAFW::Transformation::ROTATE:
+ dae_rotate_to_mat4(tm, cur);
+ break;
+ case COLLADAFW::Transformation::SCALE:
+ dae_scale_to_mat4(tm, cur);
+ break;
+ case COLLADAFW::Transformation::LOOKAT:
+ case COLLADAFW::Transformation::SKEW:
+ fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n");
+ break;
+ }
+ copy_m4_m4(copy, mat);
+ mult_m4_m4m4(mat, copy, cur);
+ }
+
if (animation_map) {
// AnimationList that drives this Transformation
const COLLADAFW::UniqueId& anim_list_id = tm->getAnimationList();
@@ -79,7 +82,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m
}
}
-void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm;
COLLADABU::Math::Vector3& axis = ro->getRotationAxis();
@@ -91,7 +94,7 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[
axis_angle_to_mat4(m, ax, angle);
}
-void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADAFW::Translate *tra = (COLLADAFW::Translate *)tm;
COLLADABU::Math::Vector3& t = tra->getTranslation();
@@ -103,14 +106,14 @@ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float
m[3][2] = (float)t[2];
}
-void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale *)tm)->getScale();
float size[3] = {(float)s[0], (float)s[1], (float)s[2]};
size_to_mat4(m, size);
}
-void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix *)tm)->getMatrix());
}
diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h
index 47e59a1bf52..ab974b9ba85 100644
--- a/source/blender/collada/TransformReader.h
+++ b/source/blender/collada/TransformReader.h
@@ -58,12 +58,12 @@ public:
TransformReader(UnitConverter *conv);
- void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob);
+ void get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob);
- void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
- void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
- void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
- void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
+ void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
+ void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
+ void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
+ void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]);
void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]);
void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]);
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index 0d6e3831637..fa813e0b961 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -32,7 +32,7 @@
#include "BLI_math.h"
-void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4])
+void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4])
{
float loc[3], rot[3], scale[3];
float local[4][4];
@@ -51,10 +51,10 @@ void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4],
converter->mat4_to_dae_double(dmat, local);
TransformBase::decompose(local, loc, rot, NULL, scale);
- if (node.getType() == COLLADASW::Node::JOINT)
- node.addMatrix("transform", dmat);
- else
- add_transform(node, loc, rot, scale);
+ //if (node.getType() == COLLADASW::Node::JOINT)
+ node.addMatrix("transform", dmat);
+ //else
+ //add_transform(node, loc, rot, scale);
}
void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
@@ -93,12 +93,13 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
add_transform(node, loc, rot, scale);
#endif
-
+ UnitConverter converter;
+
/* Using parentinv should allow use of existing curves */
if (ob->parent) {
// If parentinv is identity don't add it.
bool add_parinv = false;
-
+
for (int i = 0; i < 16; ++i) {
float f = (i % 4 == i / 4) ? 1.0f : 0.0f;
add_parinv |= (ob->parentinv[i % 4][i / 4] != f);
@@ -106,13 +107,15 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
if (add_parinv) {
double dmat[4][4];
- UnitConverter converter;
converter.mat4_to_dae_double(dmat, ob->parentinv);
node.addMatrix("parentinverse", dmat);
}
}
- add_transform(node, ob->loc, ob->rot, ob->size);
+ double d_obmat[4][4];
+ converter.mat4_to_dae_double(d_obmat, ob->obmat);
+ node.addMatrix("transform",d_obmat);
+ //add_transform(node, ob->loc, ob->rot, ob->size);
}
void TransformWriter::add_node_transform_identity(COLLADASW::Node& node)
@@ -123,15 +126,15 @@ void TransformWriter::add_node_transform_identity(COLLADASW::Node& node)
void TransformWriter::add_transform(COLLADASW::Node& node, float loc[3], float rot[3], float scale[3])
{
- node.addTranslate("location", loc[0], loc[1], loc[2]);
#if 0
node.addRotateZ("rotationZ", COLLADABU::Math::Utils::radToDegF(rot[2]));
node.addRotateY("rotationY", COLLADABU::Math::Utils::radToDegF(rot[1]));
node.addRotateX("rotationX", COLLADABU::Math::Utils::radToDegF(rot[0]));
#endif
+ node.addTranslate("location", loc[0], loc[1], loc[2]);
node.addRotateZ("rotationZ", RAD2DEGF(rot[2]));
node.addRotateY("rotationY", RAD2DEGF(rot[1]));
node.addRotateX("rotationX", RAD2DEGF(rot[0]));
-
node.addScale("scale", scale[0], scale[1], scale[2]);
+
}
diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h
index 917e26dac1a..d2a4b54a570 100644
--- a/source/blender/collada/TransformWriter.h
+++ b/source/blender/collada/TransformWriter.h
@@ -37,7 +37,7 @@
class TransformWriter : protected TransformBase
{
protected:
- void add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]);
+ void add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]);
void add_node_transform_ob(COLLADASW::Node& node, Object *ob);
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index fbb18887d1b..b3c288c8fc5 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -31,6 +31,7 @@
#include "DocumentExporter.h"
#include "DocumentImporter.h"
#include "ExportSettings.h"
+#include "ImportSettings.h"
extern "C"
{
@@ -39,12 +40,19 @@ extern "C"
/* make dummy file */
#include "BLI_fileops.h"
-#include "BLI_path_util.h"
#include "BLI_linklist.h"
-int collada_import(bContext *C, const char *filepath)
+int collada_import(bContext *C,
+ const char *filepath,
+ int import_units)
{
- DocumentImporter imp(C, filepath);
+
+ ImportSettings import_settings;
+ import_settings.filepath = (char *)filepath;
+
+ import_settings.import_units = import_units != 0;
+
+ DocumentImporter imp(C, &import_settings);
if (imp.import()) return 1;
return 0;
@@ -59,6 +67,7 @@ int collada_export(Scene *sce,
int selected,
int include_children,
int include_armatures,
+ int include_shapekeys,
int deform_bones_only,
int active_uv_only,
@@ -89,6 +98,7 @@ int collada_export(Scene *sce,
export_settings.selected = selected != 0;
export_settings.include_children = include_children != 0;
export_settings.include_armatures = include_armatures != 0;
+ export_settings.include_shapekeys = include_shapekeys != 0;
export_settings.deform_bones_only = deform_bones_only != 0;
export_settings.active_uv_only = active_uv_only != 0;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 13f8151da3d..2fa5b22bb15 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -33,6 +33,7 @@ extern "C" {
#endif
#include "BLI_linklist.h"
+#include "BLI_path_util.h"
#include "RNA_types.h"
typedef enum BC_export_mesh_type {
@@ -46,7 +47,10 @@ struct Scene;
/*
* both return 1 on success, 0 on error
*/
-int collada_import(bContext *C, const char *filepath);
+int collada_import(bContext *C,
+ const char *filepath,
+ int import_units);
+
int collada_export(Scene *sce,
const char *filepath,
int apply_modifiers,
@@ -55,6 +59,7 @@ int collada_export(Scene *sce,
int selected,
int include_children,
int include_armatures,
+ int include_shapekeys,
int deform_bones_only,
int active_uv_only,
diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp
index a4969735757..85f98dad437 100644
--- a/source/blender/collada/collada_internal.cpp
+++ b/source/blender/collada/collada_internal.cpp
@@ -33,7 +33,14 @@
UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP)
{
- /* pass */
+ unit_m4(x_up_mat4);
+ rotate_m4(x_up_mat4, 'Y', -0.5 * M_PI);
+
+ unit_m4(y_up_mat4);
+ rotate_m4(y_up_mat4, 'X', 0.5 * M_PI);
+
+ unit_m4(z_up_mat4);
+
}
void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset)
@@ -74,7 +81,7 @@ void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
// TODO need also for angle conversion, time conversion...
-void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in)
+void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in)
{
// in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
// so here, to make a blender matrix, we swap columns and rows
@@ -85,13 +92,13 @@ void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::M
}
}
-void UnitConverter::mat4_to_dae(float out[][4], float in[][4])
+void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4])
{
copy_m4_m4(out, in);
transpose_m4(out);
}
-void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4])
+void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4])
{
float mat[4][4];
@@ -102,7 +109,22 @@ void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4])
out[i][j] = mat[i][j];
}
-void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size)
+float(&UnitConverter::get_rotation())[4][4]
+{
+ switch(up_axis) {
+ case COLLADAFW::FileInfo::X_UP:
+ return x_up_mat4;
+ break;
+ case COLLADAFW::FileInfo::Y_UP:
+ return y_up_mat4;
+ break;
+ default:
+ return z_up_mat4;
+ break;
+ }
+}
+
+void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
{
mat4_to_size(size, mat);
if (eul) {
@@ -283,3 +305,9 @@ std::string get_material_id(Material *mat)
{
return translate_id(id_name(mat)) + "-material";
}
+
+std::string get_morph_id(Object *ob)
+{
+ return translate_id(id_name(ob)) + "-morph";
+}
+
diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h
index 6eec6a1675e..7d59932bac9 100644
--- a/source/blender/collada/collada_internal.h
+++ b/source/blender/collada/collada_internal.h
@@ -39,7 +39,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BLI_math.h"
-#include "BLI_math.h"
#include "BLI_linklist.h"
class UnitConverter
@@ -48,6 +47,10 @@ private:
COLLADAFW::FileInfo::Unit unit;
COLLADAFW::FileInfo::UpAxisType up_axis;
+ float x_up_mat4[4][4];
+ float y_up_mat4[4][4];
+ float z_up_mat4[4][4];
+
public:
enum UnitSystem {
@@ -69,17 +72,21 @@ public:
// TODO need also for angle conversion, time conversion...
- void dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in);
+ void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in);
+
+ void mat4_to_dae(float out[4][4], float in[4][4]);
+
+ void mat4_to_dae_double(double out[4][4], float in[4][4]);
+
+ float(&get_rotation())[4][4];
- void mat4_to_dae(float out[][4], float in[][4]);
- void mat4_to_dae_double(double out[][4], float in[][4]);
};
class TransformBase
{
public:
- void decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size);
+ void decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size);
};
extern void clear_global_id_map();
@@ -99,4 +106,6 @@ extern std::string get_camera_id(Object *ob);
extern std::string get_material_id(Material *mat);
+extern std::string get_morph_id(Object *ob);
+
#endif /* __COLLADA_INTERNAL_H__ */
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index 7bdda387d5e..f43878943c1 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -49,6 +49,7 @@ extern "C" {
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_object.h"
+#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_scene.h"
#include "BKE_DerivedMesh.h"
@@ -84,7 +85,6 @@ int bc_test_parent_loop(Object *par, Object *ob)
int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
{
Object workob;
- Main *bmain = CTX_data_main(C);
Scene *sce = CTX_data_scene(C);
if (!par || bc_test_parent_loop(par, ob))
@@ -112,23 +112,25 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
BKE_object_workob_calc_parent(sce, ob, &workob);
invert_m4_m4(ob->parentinv, workob.obmat);
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
- par->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
+ DAG_id_tag_update(&par->id, OB_RECALC_OB);
- DAG_scene_sort(bmain, sce);
- DAG_ids_flush_update(bmain, 0);
+ /** done once after import
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ */
+
return true;
}
Object *bc_add_object(Scene *scene, int type, const char *name)
{
- Object *ob = BKE_object_add_only_object(type, name);
+ Object *ob = BKE_object_add_only_object(G.main, type, name);
ob->data = BKE_object_obdata_add_from_type(type);
ob->lay = scene->lay;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
BKE_scene_base_select(scene, BKE_scene_base_add(scene, ob));
@@ -151,7 +153,7 @@ Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type e
}
}
- tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here
+ tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here
DM_to_mesh(dm, tmpmesh, ob);
dm->release(dm);
return tmpmesh;
@@ -282,3 +284,85 @@ int bc_get_active_UVLayer(Object *ob)
Mesh *me = (Mesh *)ob->data;
return CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
}
+
+std::string bc_url_encode(std::string data) {
+ /* XXX We probably do not need to do a full encoding.
+ But in case that is necessary,then it can be added here.
+ */
+ return bc_replace_string(data,"#", "%23");
+}
+
+std::string bc_replace_string(std::string data, const std::string& pattern,
+ const std::string& replacement) {
+ size_t pos = 0;
+ while((pos = data.find(pattern, pos)) != std::string::npos) {
+ data.replace(pos, pattern.length(), replacement);
+ pos += replacement.length();
+ }
+ return data;
+}
+
+/**
+ Calculate a rescale factor such that the imported scene's scale
+ is preserved. I.e. 1 meter in the import will also be
+ 1 meter in the current scene.
+ XXX : I am not sure if it is correct to map 1 Blender Unit
+ to 1 Meter for unit type NONE. But it looks reasonable to me.
+*/
+void bc_match_scale(std::vector<Object *> *objects_done,
+ Scene &sce,
+ UnitConverter &bc_unit) {
+
+ Object *ob = NULL;
+
+ PointerRNA scene_ptr, unit_settings;
+ PropertyRNA *system_ptr, *scale_ptr;
+ RNA_id_pointer_create(&sce.id, &scene_ptr);
+
+ unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
+ system_ptr = RNA_struct_find_property(&unit_settings, "system");
+ scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
+
+ int type = RNA_property_enum_get(&unit_settings, system_ptr);
+
+ float bl_scale;
+
+ switch (type) {
+ case USER_UNIT_NONE:
+ bl_scale = 1.0; // map 1 Blender unit to 1 Meter
+ break;
+
+ case USER_UNIT_METRIC:
+ bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
+ break;
+
+ default :
+ bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
+ // it looks like the conversion to Imperial is done implicitly.
+ // So nothing to do here.
+ break;
+ }
+
+ float scale_conv = bc_unit.getLinearMeter() / bl_scale;
+
+ float rescale[3];
+ rescale[0] = rescale[1] = rescale[2] = scale_conv;
+
+ float size_mat4[4][4];
+
+ float axis_mat4[4][4];
+ unit_m4(axis_mat4);
+
+ size_to_mat4(size_mat4, rescale);
+
+ for (std::vector<Object *>::iterator it = objects_done->begin();
+ it != objects_done->end();
+ ++it)
+ {
+ ob = *it;
+ mult_m4_m4m4(ob->obmat, size_mat4, ob->obmat);
+ mult_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat);
+ BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
+ }
+
+}
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index b8990c3fcdd..892b57e6a4a 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -42,15 +42,19 @@ extern "C" {
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
+#include "RNA_access.h"
+
#include "BLI_linklist.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_object.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_scene.h"
}
#include "ExportSettings.h"
+#include "collada_internal.h"
typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *> > TexIndexTextureArrayMap;
@@ -77,4 +81,7 @@ extern void bc_bubble_sort_by_Object_name(LinkNode *export_set);
extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only);
extern int bc_get_active_UVLayer(Object *ob);
+extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement);
+extern std::string bc_url_encode(std::string data);
+extern void bc_match_scale(std::vector<Object *> *objects_done, Scene &sce, UnitConverter &unit_converter);
#endif
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 8259cb6f297..ba897a87f97 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -35,13 +35,13 @@ set(INC
../imbuf
../makesdna
../makesrna
- ../opencl
../windowmanager
../nodes
../nodes/composite
../nodes/intern
../render/extern/include
../render/intern/include
+ ../../../intern/opencl
../../../intern/guardedalloc
)
@@ -491,10 +491,10 @@ set(SRC
operations/COM_ColorMatteOperation.h
operations/COM_ChannelMatteOperation.cpp
operations/COM_ChannelMatteOperation.h
- operations/COM_ConvertPremulToKeyOperation.cpp
- operations/COM_ConvertPremulToKeyOperation.h
- operations/COM_ConvertKeyToPremulOperation.cpp
- operations/COM_ConvertKeyToPremulOperation.h
+ operations/COM_ConvertPremulToStraightOperation.cpp
+ operations/COM_ConvertPremulToStraightOperation.h
+ operations/COM_ConvertStraightToPremulOperation.cpp
+ operations/COM_ConvertStraightToPremulOperation.h
operations/COM_ReadBufferOperation.cpp
operations/COM_ReadBufferOperation.h
@@ -580,6 +580,8 @@ set(SRC
# Distort operation
operations/COM_TranslateOperation.h
operations/COM_TranslateOperation.cpp
+ operations/COM_WrapOperation.h
+ operations/COM_WrapOperation.cpp
operations/COM_RotateOperation.h
operations/COM_RotateOperation.cpp
operations/COM_ScaleOperation.h
diff --git a/source/blender/compositor/SConscript b/source/blender/compositor/SConscript
index 9f947ca7327..64169ac7403 100644
--- a/source/blender/compositor/SConscript
+++ b/source/blender/compositor/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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 = ['GLEW_STATIC']
@@ -6,7 +32,7 @@ sources = env.Glob('intern/*.cpp') + env.Glob('nodes/*.cpp') + env.Glob('operati
incs = '. nodes intern operations ../blenlib ../blenkernel ../makesdna ../render/extern/include ../render/intern/include'
incs += ' ../makesrna ../blenloader ../../../intern/guardedalloc ../imbuf ../windowmanager '
-incs += '../opencl ../nodes ../nodes/intern ../nodes/composite '
+incs += '#intern/opencl ../nodes ../nodes/intern ../nodes/composite '
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h
index 2f5e8c0648d..840a9e59584 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.h
+++ b/source/blender/compositor/intern/COM_CompositorContext.h
@@ -74,7 +74,7 @@ private:
* @brief does this system have active opencl devices?
*/
bool m_hasActiveOpenCLDevices;
-
+
/**
* @brief Skip slow nodes
*/
@@ -178,6 +178,7 @@ public:
void setFastCalculation(bool fastCalculation) {this->m_fastCalculation = fastCalculation;}
bool isFastCalculation() {return this->m_fastCalculation;}
+ inline bool isGroupnodeBufferEnabled() {return this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER;}
};
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h
index 25f06108d96..9beccba0c73 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.h
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.h
@@ -41,7 +41,8 @@ using namespace std;
* In order to get to an efficient model for execution, several steps are being done. these steps are explained below.
*
* @section EM_Step1 Step 1: translating blender node system to the new compsitor system
- * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture. We want to use classes in order to simplify the system.
+ * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture.
+ * We want to use classes in order to simplify the system.
* during this step the blender node_tree is evaluated and converted to a CPP node system.
*
* @see ExecutionSystem
@@ -49,13 +50,17 @@ using namespace std;
* @see Node
*
* @section EM_Step2 Step2: translating nodes to operations
- * Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's. The new system only supports a single level of node_tree. We will 'flatten' the system in a single level.
+ * Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's.
+ * The new system only supports a single level of node_tree. We will 'flatten' the system in a single level.
* @see GroupNode
* @see ExecutionSystemHelper.ungroup
*
- * Every node has the ability to convert itself to operations. The node itself is responsible to create a correct NodeOperation setup based on its internal settings.
- * Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything, but replaces itself with a ConvertColorToBWOperation.
- * More complex nodes can use different NodeOperation based on settings; like MixNode. based on the selected Mixtype a different operation will be used.
+ * Every node has the ability to convert itself to operations. The node itself is responsible to create a correct
+ * NodeOperation setup based on its internal settings.
+ * Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything,
+ * but replaces itself with a ConvertColorToBWOperation.
+ * More complex nodes can use different NodeOperation based on settings; like MixNode.
+ * based on the selected Mixtype a different operation will be used.
* for more information see the page about creating new Nodes. [@subpage newnode]
*
* @see ExecutionSystem.convertToOperations
@@ -63,9 +68,12 @@ using namespace std;
* @see NodeOperation base class for all operations in the system
*
* @section EM_Step3 Step3: add additional conversions to the operation system
- * - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR. The user can connect a Value socket to a color socket. As values are ordered differently than colors a conversion happens.
+ * - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR.
+ * The user can connect a Value socket to a color socket.
+ * As values are ordered differently than colors a conversion happens.
*
- * - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the following settings.
+ * - Image size conversions: the system can automatically convert when resolutions do not match.
+ * An InputSocket has a resize mode. This can be any of the following settings.
* - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned
@@ -77,8 +85,10 @@ using namespace std;
* @see Converter.convertResolution Image size conversions
*
* @section EM_Step4 Step4: group operations in executions groups
- * ExecutionGroup are groups of operations that are calculated as being one bigger operation. All operations will be part of an ExecutionGroup.
- * Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers. ReadBufferOperations and WriteBufferOperations are added where needed.
+ * ExecutionGroup are groups of operations that are calculated as being one bigger operation.
+ * All operations will be part of an ExecutionGroup.
+ * Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers.
+ * ReadBufferOperations and WriteBufferOperations are added where needed.
*
* <pre>
*
diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h
index c098d6da32b..5b0381f6443 100644
--- a/source/blender/compositor/intern/COM_Node.h
+++ b/source/blender/compositor/intern/COM_Node.h
@@ -58,7 +58,7 @@ private:
* @brief The group node this node belongs to.
* @note: used to find the links in the current subtree for muting nodes
*/
- bNode* m_bNodeGroup;
+ bNode *m_bNodeGroup;
public:
Node(bNode *editorNode, bool create_sockets = true);
@@ -145,8 +145,8 @@ public:
*/
OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket);
- inline void setbNodeGroup(bNode* group) {this->m_bNodeGroup = group;}
- inline bNode* getbNodeGroup() {return this->m_bNodeGroup;}
+ inline void setbNodeGroup(bNode *group) {this->m_bNodeGroup = group;}
+ inline bNode *getbNodeGroup() {return this->m_bNodeGroup;}
protected:
void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket);
void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket);
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp
index a05c37e1b09..d33b8085022 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cpp
+++ b/source/blender/compositor/intern/COM_NodeOperation.cpp
@@ -34,6 +34,7 @@ NodeOperation::NodeOperation() : NodeBase()
this->m_complex = false;
this->m_width = 0;
this->m_height = 0;
+ this->m_isResolutionSet = false;
this->m_openCL = false;
this->m_btree = NULL;
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index f856d8e6a11..60ffadf60f7 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -81,6 +81,7 @@ private:
*/
const bNodeTree *m_btree;
+ bool m_isResolutionSet;
public:
/**
* @brief is this node an operation?
@@ -170,7 +171,7 @@ public:
virtual void deinitExecution();
bool isResolutionSet() {
- return this->m_width != 0 && this->m_height != 0;
+ return this->m_isResolutionSet;
}
/**
@@ -181,6 +182,7 @@ public:
if (!isResolutionSet()) {
this->m_width = resolution[0];
this->m_height = resolution[1];
+ this->m_isResolutionSet = true;
}
}
@@ -254,8 +256,8 @@ public:
protected:
NodeOperation();
- void setWidth(unsigned int width) { this->m_width = width; }
- void setHeight(unsigned int height) { this->m_height = height; }
+ void setWidth(unsigned int width) { this->m_width = width; this->m_isResolutionSet = true; }
+ void setHeight(unsigned int height) { this->m_height = height; this->m_isResolutionSet = true; }
SocketReader *getInputSocketReader(unsigned int inputSocketindex);
NodeOperation *getInputOperation(unsigned int inputSocketindex);
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
index d5da079c9fd..bb60a629812 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
@@ -65,12 +65,16 @@ void OpenCLDevice::execute(WorkPackage *work)
executionGroup->finalizeChunkExecution(chunkNumber, inputBuffers);
}
-cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader *reader)
+cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
+ list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
+ SocketReader *reader)
{
return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader);
}
-cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, ReadBufferOperation *reader)
+cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
+ list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
+ ReadBufferOperation *reader)
{
cl_int error;
diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp
index e3313750e66..fc4dea8cee3 100644
--- a/source/blender/compositor/nodes/COM_CompositorNode.cpp
+++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp
@@ -41,6 +41,7 @@ void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorConte
compositorOperation->setSceneName(editorNode->id->name);
compositorOperation->setRenderData(context->getRenderData());
compositorOperation->setbNodeTree(context->getbNodeTree());
+ compositorOperation->setIgnoreAlpha(editorNode->custom2 & 1);
imageSocket->relinkConnections(compositorOperation->getInputSocket(0), 0, graph);
alphaSocket->relinkConnections(compositorOperation->getInputSocket(1));
depthSocket->relinkConnections(compositorOperation->getInputSocket(2));
diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
index 254dfb7b9c7..a7149cc63b2 100644
--- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
+++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
@@ -20,8 +20,8 @@
*/
#include "COM_ConvertAlphaNode.h"
-#include "COM_ConvertPremulToKeyOperation.h"
-#include "COM_ConvertKeyToPremulOperation.h"
+#include "COM_ConvertPremulToStraightOperation.h"
+#include "COM_ConvertStraightToPremulOperation.h"
#include "COM_ExecutionSystem.h"
void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
@@ -31,10 +31,10 @@ void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorCon
/* value hardcoded in rna_nodetree.c */
if (node->custom1 == 1) {
- operation = new ConvertPremulToKeyOperation();
+ operation = new ConvertPremulToStraightOperation();
}
else {
- operation = new ConvertKeyToPremulOperation();
+ operation = new ConvertStraightToPremulOperation();
}
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
diff --git a/source/blender/compositor/nodes/COM_GroupNode.cpp b/source/blender/compositor/nodes/COM_GroupNode.cpp
index e10d7dbad2e..05c749345d5 100644
--- a/source/blender/compositor/nodes/COM_GroupNode.cpp
+++ b/source/blender/compositor/nodes/COM_GroupNode.cpp
@@ -58,17 +58,18 @@ void GroupNode::ungroup(ExecutionSystem &system)
InputSocket *inputSocket = inputsockets[index];
bNodeSocket *editorInput = inputSocket->getbNodeSocket();
if (editorInput->groupsock) {
- SocketProxyNode *proxy = new SocketProxyNode(bnode, editorInput, editorInput->groupsock);
+ SocketProxyNode *proxy = new SocketProxyNode(bnode, editorInput, editorInput->groupsock, false);
inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system);
ExecutionSystemHelper::addNode(system.getNodes(), proxy);
}
}
+ const bool groupnodeBuffering = system.getContext().isGroupnodeBufferEnabled();
for (index = 0; index < outputsockets.size(); index++) {
OutputSocket *outputSocket = outputsockets[index];
bNodeSocket *editorOutput = outputSocket->getbNodeSocket();
if (editorOutput->groupsock) {
- SocketProxyNode *proxy = new SocketProxyNode(bnode, editorOutput->groupsock, editorOutput);
+ SocketProxyNode *proxy = new SocketProxyNode(bnode, editorOutput->groupsock, editorOutput, groupnodeBuffering);
outputSocket->relinkConnections(proxy->getOutputSocket(0));
ExecutionSystemHelper::addNode(system.getNodes(), proxy);
}
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index 4293e344c65..864d6f08311 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -28,6 +28,10 @@
#include "BKE_node.h"
#include "BLI_utildefines.h"
+#include "COM_SetValueOperation.h"
+#include "COM_SetVectorOperation.h"
+#include "COM_SetColorOperation.h"
+
ImageNode::ImageNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
@@ -165,6 +169,46 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
graph->addOperation(depthOperation);
}
}
+ if (numberOfOutputs > 3) {
+ /* happens when unlinking image datablock from multilayer node */
+ for (int i = 3; i < numberOfOutputs; i++) {
+ OutputSocket *output = this->getOutputSocket(i);
+ NodeOperation *operation = NULL;
+ switch (output->getDataType()) {
+ case COM_DT_VALUE:
+ {
+ SetValueOperation *valueoperation = new SetValueOperation();
+ valueoperation->setValue(0.0f);
+ operation = valueoperation;
+ break;
+ }
+ case COM_DT_VECTOR:
+ {
+ SetVectorOperation *vectoroperation = new SetVectorOperation();
+ vectoroperation->setX(0.0f);
+ vectoroperation->setY(0.0f);
+ vectoroperation->setW(0.0f);
+ operation = vectoroperation;
+ break;
+ }
+ case COM_DT_COLOR:
+ {
+ SetColorOperation *coloroperation = new SetColorOperation();
+ coloroperation->setChannel1(0.0f);
+ coloroperation->setChannel2(0.0f);
+ coloroperation->setChannel3(0.0f);
+ coloroperation->setChannel4(0.0f);
+ operation = coloroperation;
+ break;
+ }
+ }
+
+ if (operation) {
+ output->relinkConnections(operation->getOutputSocket());
+ graph->addOperation(operation);
+ }
+ }
+ }
}
}
diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cpp b/source/blender/compositor/nodes/COM_PixelateNode.cpp
index f1c7c616a30..b751c9a6e9f 100644
--- a/source/blender/compositor/nodes/COM_PixelateNode.cpp
+++ b/source/blender/compositor/nodes/COM_PixelateNode.cpp
@@ -36,8 +36,8 @@ void PixelateNode::convertToOperations(ExecutionSystem *graph, CompositorContext
OutputSocket *outputSocket = this->getOutputSocket(0);
DataType datatype = inputSocket->getDataType();
if (inputSocket->isConnected()) {
- SocketConnection * connection = inputSocket->getConnection();
- OutputSocket* otherOutputSocket = connection->getFromSocket();
+ SocketConnection *connection = inputSocket->getConnection();
+ OutputSocket *otherOutputSocket = connection->getFromSocket();
datatype = otherOutputSocket->getDataType();
}
diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp
index 6f7bd33db6f..e139eb83e04 100644
--- a/source/blender/compositor/nodes/COM_ScaleNode.cpp
+++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp
@@ -43,7 +43,8 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
bNode *bnode = this->getbNode();
switch (bnode->custom1) {
- case CMP_SCALE_RELATIVE: {
+ case CMP_SCALE_RELATIVE:
+ {
ScaleOperation *operation = new ScaleOperation();
inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
@@ -51,9 +52,10 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
scaleoperation = operation;
+ break;
}
- break;
- case CMP_SCALE_SCENEPERCENT: {
+ case CMP_SCALE_SCENEPERCENT:
+ {
SetValueOperation *scaleFactorOperation = new SetValueOperation();
scaleFactorOperation->setValue(context->getRenderData()->size / 100.0f);
ScaleOperation *operation = new ScaleOperation();
@@ -63,10 +65,10 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
graph->addOperation(scaleFactorOperation);
scaleoperation = operation;
+ break;
}
- break;
-
- case CMP_SCALE_RENDERPERCENT: {
+ case CMP_SCALE_RENDERPERCENT:
+ {
const RenderData *rd = context->getRenderData();
ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation();
@@ -81,10 +83,10 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
operation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true);
scaleoperation = operation;
+ break;
}
- break;
-
- case CMP_SCALE_ABSOLUTE: {
+ case CMP_SCALE_ABSOLUTE:
+ {
ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation(); // TODO: what is the use of this one.... perhaps some issues when the ui was updated....
inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
@@ -92,8 +94,8 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
scaleoperation = operation;
+ break;
}
- break;
}
outputSocket->relinkConnections(scaleoperation->getOutputSocket(0));
diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp
index 709dc75b502..dd3ff5fbaa7 100644
--- a/source/blender/compositor/nodes/COM_SetAlphaNode.cpp
+++ b/source/blender/compositor/nodes/COM_SetAlphaNode.cpp
@@ -27,7 +27,11 @@
void SetAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
SetAlphaOperation *operation = new SetAlphaOperation();
-
+
+ if (!this->getInputSocket(0)->isConnected() && this->getInputSocket(1)->isConnected()) {
+ operation->setResolutionInputSocketIndex(1);
+ }
+
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
index bfb32a96156..ded6186ad77 100644
--- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
+++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
@@ -27,11 +27,14 @@
#include "COM_SetValueOperation.h"
#include "COM_SetVectorOperation.h"
#include "COM_SetColorOperation.h"
+#include "COM_WriteBufferOperation.h"
+#include "COM_ReadBufferOperation.h"
-SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput) : Node(editorNode, false)
+SocketProxyNode::SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput, bool buffer) : Node(editorNode, false)
{
DataType dt;
-
+ this->m_buffer = buffer;
+
dt = COM_DT_VALUE;
if (editorInput->type == SOCK_RGBA) dt = COM_DT_COLOR;
if (editorInput->type == SOCK_VECTOR) dt = COM_DT_VECTOR;
@@ -53,6 +56,17 @@ void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorCont
inputsocket->relinkConnections(operation->getInputSocket(0));
outputsocket->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
+ if (m_buffer) {
+ WriteBufferOperation *writeOperation = new WriteBufferOperation();
+ ReadBufferOperation *readOperation = new ReadBufferOperation();
+ readOperation->setMemoryProxy(writeOperation->getMemoryProxy());
+
+ operation->getOutputSocket()->relinkConnections(readOperation->getOutputSocket());
+ addLink(graph, operation->getOutputSocket(), writeOperation->getInputSocket(0));
+
+ graph->addOperation(writeOperation);
+ graph->addOperation(readOperation);
+ }
}
else {
/* If input is not connected, add a constant value operation instead */
diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h
index ea50be418e2..a83ac094b2b 100644
--- a/source/blender/compositor/nodes/COM_SocketProxyNode.h
+++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h
@@ -30,8 +30,10 @@
* @ingroup Node
*/
class SocketProxyNode : public Node {
+private:
+ bool m_buffer;
public:
- SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput);
+ SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput, bool buffer);
void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
virtual bool isProxyNode() const { return true; }
diff --git a/source/blender/compositor/nodes/COM_TranslateNode.cpp b/source/blender/compositor/nodes/COM_TranslateNode.cpp
index c805f8f8baa..44d796c2911 100644
--- a/source/blender/compositor/nodes/COM_TranslateNode.cpp
+++ b/source/blender/compositor/nodes/COM_TranslateNode.cpp
@@ -23,6 +23,7 @@
#include "COM_TranslateNode.h"
#include "COM_TranslateOperation.h"
+#include "COM_WrapOperation.h"
#include "COM_ExecutionSystem.h"
TranslateNode::TranslateNode(bNode *editorNode) : Node(editorNode)
@@ -37,10 +38,32 @@ void TranslateNode::convertToOperations(ExecutionSystem *graph, CompositorContex
InputSocket *inputYSocket = this->getInputSocket(2);
OutputSocket *outputSocket = this->getOutputSocket(0);
TranslateOperation *operation = new TranslateOperation();
-
- inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
+
+ bNode *bnode = this->getbNode();
+ NodeTranslateData *data = (NodeTranslateData *)bnode->storage;
+
+ if (data->wrap_axis) {
+ WrapOperation *wrapOperation = new WrapOperation();
+ wrapOperation->setWrapping(data->wrap_axis);
+ inputSocket->relinkConnections(wrapOperation->getInputSocket(0), 0, graph);
+ addLink(graph, wrapOperation->getOutputSocket(), operation->getInputSocket(0));
+ graph->addOperation(wrapOperation);
+ }
+ else {
+ inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
+ }
+
+ if (data->relative) {
+ const RenderData *rd = context->getRenderData();
+ float fx = rd->xsch * rd->size / 100.0f;
+ float fy = rd->ysch * rd->size / 100.0f;
+
+ operation->setFactorXY(fx, fy);
+ }
+
inputXSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
inputYSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
outputSocket->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
}
+
diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp
index f44470a9b9a..94f3c2ebd80 100644
--- a/source/blender/compositor/nodes/COM_ViewerNode.cpp
+++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp
@@ -47,6 +47,7 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1);
viewerOperation->setCenterX(editorNode->custom3);
viewerOperation->setCenterY(editorNode->custom4);
+ viewerOperation->setIgnoreAlpha(editorNode->custom2 & 1);
viewerOperation->setViewSettings(context->getViewSettings());
viewerOperation->setDisplaySettings(context->getDisplaySettings());
diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp
index 234a1c7b1e5..84cc8aad950 100644
--- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp
+++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp
@@ -38,7 +38,8 @@ void ChannelMatteOperation::initExecution()
switch (this->m_limit_method) {
/* SINGLE */
- case 0: {
+ case 0:
+ {
/* 123 / RGB / HSV / YUV / YCC */
const int matte_channel = this->m_matte_channel - 1;
const int limit_channel = this->m_limit_channel - 1;
@@ -48,21 +49,25 @@ void ChannelMatteOperation::initExecution()
break;
}
/* MAX */
- case 1: {
+ case 1:
+ {
switch (this->m_matte_channel) {
- case 1: {
+ case 1:
+ {
this->m_ids[0] = 0;
this->m_ids[1] = 1;
this->m_ids[2] = 2;
break;
}
- case 2: {
+ case 2:
+ {
this->m_ids[0] = 1;
this->m_ids[1] = 0;
this->m_ids[2] = 2;
break;
}
- case 3: {
+ case 3:
+ {
this->m_ids[0] = 2;
this->m_ids[1] = 0;
this->m_ids[2] = 1;
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp
index 141d071dddc..43f491ad2d9 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.cpp
+++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp
@@ -49,6 +49,8 @@ CompositorOperation::CompositorOperation() : NodeOperation()
this->m_alphaInput = NULL;
this->m_depthInput = NULL;
+ this->m_ignoreAlpha = false;
+
this->m_sceneName[0] = '\0';
}
@@ -91,14 +93,14 @@ void CompositorOperation::deinitExecution()
}
}
- BLI_lock_thread(LOCK_DRAW_IMAGE);
- BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
-
if (re) {
RE_ReleaseResult(re);
re = NULL;
}
+
+ BLI_lock_thread(LOCK_DRAW_IMAGE);
+ BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
+ BLI_unlock_thread(LOCK_DRAW_IMAGE);
}
else {
if (this->m_outputBuffer) {
@@ -138,9 +140,15 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
for (y = y1; y < y2 && (!breaked); y++) {
for (x = x1; x < x2 && (!breaked); x++) {
this->m_imageInput->read(color, x, y, COM_PS_NEAREST);
- if (this->m_alphaInput != NULL) {
- this->m_alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST);
+ if (this->m_ignoreAlpha) {
+ color[3] = 1.0f;
}
+ else {
+ if (this->m_alphaInput != NULL) {
+ this->m_alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST);
+ }
+ }
+
copy_v4_v4(buffer + offset4, color);
if (this->m_depthInput != NULL) {
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h
index c1d91c16a3c..27d29664610 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.h
+++ b/source/blender/compositor/operations/COM_CompositorOperation.h
@@ -65,6 +65,10 @@ private:
* @brief local reference to the depth operation
*/
SocketReader *m_depthInput;
+
+ /* Ignore any alpha input */
+ bool m_ignoreAlpha;
+
public:
CompositorOperation();
void executeRegion(rcti *rect, unsigned int tileNumber);
@@ -75,5 +79,6 @@ public:
void deinitExecution();
const CompositorPriority getRenderPriority() const { return COM_PRIORITY_MEDIUM; }
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
+ void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.cpp
index b92da4c324f..2af4b55de1a 100644
--- a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp
+++ b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.cpp
@@ -19,10 +19,10 @@
* Dalai Felinto
*/
-#include "COM_ConvertPremulToKeyOperation.h"
+#include "COM_ConvertPremulToStraightOperation.h"
#include "BLI_math.h"
-ConvertPremulToKeyOperation::ConvertPremulToKeyOperation() : NodeOperation()
+ConvertPremulToStraightOperation::ConvertPremulToStraightOperation() : NodeOperation()
{
this->addInputSocket(COM_DT_COLOR);
this->addOutputSocket(COM_DT_COLOR);
@@ -30,12 +30,12 @@ ConvertPremulToKeyOperation::ConvertPremulToKeyOperation() : NodeOperation()
this->m_inputColor = NULL;
}
-void ConvertPremulToKeyOperation::initExecution()
+void ConvertPremulToStraightOperation::initExecution()
{
this->m_inputColor = getInputSocketReader(0);
}
-void ConvertPremulToKeyOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
+void ConvertPremulToStraightOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
float inputValue[4];
float alpha;
@@ -54,7 +54,7 @@ void ConvertPremulToKeyOperation::executePixel(float output[4], float x, float y
output[3] = alpha;
}
-void ConvertPremulToKeyOperation::deinitExecution()
+void ConvertPremulToStraightOperation::deinitExecution()
{
this->m_inputColor = NULL;
}
diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.h
index 04a9965858d..9d3ab156555 100644
--- a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h
+++ b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.h
@@ -19,8 +19,8 @@
* Dalai Felinto
*/
-#ifndef _COM_ConvertPremulToKeyOperation_h
-#define _COM_ConvertPremulToKeyOperation_h
+#ifndef _COM_ConvertPremulToStraightOperation_h
+#define _COM_ConvertPremulToStraightOperation_h
#include "COM_NodeOperation.h"
@@ -28,14 +28,14 @@
* this program converts an input color to an output value.
* it assumes we are in sRGB color space.
*/
-class ConvertPremulToKeyOperation : public NodeOperation {
+class ConvertPremulToStraightOperation : public NodeOperation {
private:
SocketReader *m_inputColor;
public:
/**
* Default constructor
*/
- ConvertPremulToKeyOperation();
+ ConvertPremulToStraightOperation();
/**
* the inner loop of this program
diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.cpp
index 4497db52a0f..ae55d949ff2 100644
--- a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp
+++ b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.cpp
@@ -19,10 +19,10 @@
* Dalai Felinto
*/
-#include "COM_ConvertKeyToPremulOperation.h"
+#include "COM_ConvertStraightToPremulOperation.h"
#include "BLI_math.h"
-ConvertKeyToPremulOperation::ConvertKeyToPremulOperation() : NodeOperation()
+ConvertStraightToPremulOperation::ConvertStraightToPremulOperation() : NodeOperation()
{
this->addInputSocket(COM_DT_COLOR);
this->addOutputSocket(COM_DT_COLOR);
@@ -30,12 +30,12 @@ ConvertKeyToPremulOperation::ConvertKeyToPremulOperation() : NodeOperation()
this->m_inputColor = NULL;
}
-void ConvertKeyToPremulOperation::initExecution()
+void ConvertStraightToPremulOperation::initExecution()
{
this->m_inputColor = getInputSocketReader(0);
}
-void ConvertKeyToPremulOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
+void ConvertStraightToPremulOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
float inputValue[4];
float alpha;
@@ -49,7 +49,7 @@ void ConvertKeyToPremulOperation::executePixel(float output[4], float x, float y
output[3] = alpha;
}
-void ConvertKeyToPremulOperation::deinitExecution()
+void ConvertStraightToPremulOperation::deinitExecution()
{
this->m_inputColor = NULL;
}
diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.h
index 502674e26db..d0191f292d2 100644
--- a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h
+++ b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.h
@@ -19,8 +19,8 @@
* Dalai Felinto
*/
-#ifndef _COM_ConvertKeyToPremulOperation_h
-#define _COM_ConvertKeyToPremulOperation_h
+#ifndef _COM_ConvertStraightToPremulOperation_h
+#define _COM_ConvertStraightToPremulOperation_h
#include "COM_NodeOperation.h"
@@ -28,14 +28,14 @@
* this program converts an input color to an output value.
* it assumes we are in sRGB color space.
*/
-class ConvertKeyToPremulOperation : public NodeOperation {
+class ConvertStraightToPremulOperation : public NodeOperation {
private:
SocketReader *m_inputColor;
public:
/**
* Default constructor
*/
- ConvertKeyToPremulOperation();
+ ConvertStraightToPremulOperation();
/**
* the inner loop of this program
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
index f0fffa770f8..b54e47c136d 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
@@ -323,89 +323,147 @@ DilateStepOperation::DilateStepOperation() : NodeOperation()
void DilateStepOperation::initExecution()
{
this->m_inputProgram = this->getInputSocketReader(0);
- this->m_cached_buffer = NULL;
- this->initMutex();
+}
+
+
+// small helper to pass data from initializeTileData to executePixel
+typedef struct tile_info {
+ rcti rect;
+ int width;
+ float *buffer;
+} tile_info;
+
+static tile_info *create_cache(int xmin, int xmax, int ymin, int ymax)
+{
+ tile_info *result = (tile_info *)MEM_mallocN(sizeof(tile_info), "dilate erode tile");
+ result->rect.xmin = xmin;
+ result->rect.xmax = xmax;
+ result->rect.ymin = ymin;
+ result->rect.ymax = ymax;
+ result->width = xmax - xmin;
+ result->buffer = (float *)MEM_callocN(sizeof(float) * (ymax - ymin) * result->width, "dilate erode cache");
+ return result;
}
void *DilateStepOperation::initializeTileData(rcti *rect)
{
- if (this->m_cached_buffer != NULL) {
- return this->m_cached_buffer;
- }
- lockMutex();
- if (this->m_cached_buffer == NULL) {
- MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
- float *rectf = buffer->convertToValueBuffer();
- int x, y, i;
- float *p;
- int bwidth = buffer->getWidth();
- int bheight = buffer->getHeight();
- for (i = 0; i < this->m_iterations; i++) {
- for (y = 0; y < bheight; y++) {
- for (x = 0; x < bwidth - 1; x++) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p + 1));
- }
+ MemoryBuffer *tile = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
+ int x, y, i;
+ int width = tile->getWidth();
+ int height = tile->getHeight();
+ float *buffer = tile->getBuffer();
+
+ int half_window = this->m_iterations;
+ int window = half_window * 2 + 1;
+
+ int xmin = max(0, rect->xmin - half_window);
+ int ymin = max(0, rect->ymin - half_window);
+ int xmax = min(width, rect->xmax + half_window);
+ int ymax = min(height, rect->ymax + half_window);
+
+ int bwidth = rect->xmax - rect->xmin;
+ int bheight = rect->ymax - rect->ymin;
+
+ // Note: Cache buffer has original tilesize width, but new height.
+ // We have to calculate the additional rows in the first pass,
+ // to have valid data available for the second pass.
+ tile_info *result = create_cache(rect->xmin, rect->xmax, ymin, ymax);
+ float *rectf = result->buffer;
+
+ // temp holds maxima for every step in the algorithm, buf holds a
+ // single row or column of input values, padded with MAXFLOATs to
+ // simplify the logic.
+ float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
+ float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window), "dilate erode buf");
+
+ // The following is based on the van Herk/Gil-Werman algorithm for morphology operations.
+ // first pass, horizontal dilate/erode
+ for (y = ymin; y < ymax; y++) {
+ for (x = 0; x < bwidth + 5 * half_window; x++) {
+ buf[x] = -MAXFLOAT;
+ }
+ for (x = xmin; x < xmax; ++x) {
+ buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
+ }
+
+ for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (x = 1; x < window; x++) {
+ temp[window - 1 - x] = max(temp[window - x], buf[start - x]);
+ temp[window - 1 + x] = max(temp[window + x - 2], buf[start + x]);
}
-
- for (y = 0; y < bheight; y++) {
- for (x = bwidth - 1; x >= 1; x--) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p - 1));
- }
+
+ start = half_window + (i - 1) * window + 1;
+ for (x = -min(0, start); x < window - max(0, start + window - bwidth); x++) {
+ rectf[bwidth * (y - ymin) + (start + x)] = max(temp[x], temp[x + window - 1]);
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = 0; y < bheight - 1; y++) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p + bwidth));
- }
+ }
+ }
+
+ // second pass, vertical dilate/erode
+ for (x = 0; x < bwidth; x++) {
+ for (y = 0; y < bheight + 5 * half_window; y++) {
+ buf[y] = -MAXFLOAT;
+ }
+ for (y = ymin; y < ymax; y++) {
+ buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
+ }
+
+ for (i = 0; i < (bheight + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (y = 1; y < window; y++) {
+ temp[window - 1 - y] = max(temp[window - y], buf[start - y]);
+ temp[window - 1 + y] = max(temp[window + y - 2], buf[start + y]);
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = bheight - 1; y >= 1; y--) {
- p = rectf + (bwidth * y + x);
- *p = max(*p, *(p - bwidth));
- }
+
+ start = half_window + (i - 1) * window + 1;
+ for (y = -min(0, start); y < window - max(0, start + window - bheight); y++) {
+ rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = max(temp[y], temp[y + window - 1]);
}
}
- this->m_cached_buffer = rectf;
}
- unlockMutex();
- return this->m_cached_buffer;
+
+ MEM_freeN(temp);
+ MEM_freeN(buf);
+
+ return result;
}
void DilateStepOperation::executePixel(float output[4], int x, int y, void *data)
{
- output[0] = this->m_cached_buffer[y * this->getWidth() + x];
+ tile_info *tile = (tile_info *)data;
+ int nx = x - tile->rect.xmin;
+ int ny = y - tile->rect.ymin;
+ output[0] = tile->buffer[tile->width * ny + nx];
}
void DilateStepOperation::deinitExecution()
{
this->m_inputProgram = NULL;
- this->deinitMutex();
- if (this->m_cached_buffer) {
- MEM_freeN(this->m_cached_buffer);
- this->m_cached_buffer = NULL;
- }
+}
+
+void DilateStepOperation::deinitializeTileData(rcti *rect, void *data)
+{
+ tile_info *tile = (tile_info *)data;
+ MEM_freeN(tile->buffer);
+ MEM_freeN(tile);
}
bool DilateStepOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- if (this->m_cached_buffer) {
- return false;
- }
- else {
- rcti newInput;
-
- newInput.xmax = getWidth();
- newInput.xmin = 0;
- newInput.ymax = getHeight();
- newInput.ymin = 0;
-
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
- }
+ rcti newInput;
+ int it = this->m_iterations;
+ newInput.xmax = input->xmax + it;
+ newInput.xmin = input->xmin - it;
+ newInput.ymax = input->ymax + it;
+ newInput.ymin = input->ymin - it;
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
// Erode step
@@ -416,48 +474,88 @@ ErodeStepOperation::ErodeStepOperation() : DilateStepOperation()
void *ErodeStepOperation::initializeTileData(rcti *rect)
{
- if (this->m_cached_buffer != NULL) {
- return this->m_cached_buffer;
- }
- lockMutex();
- if (this->m_cached_buffer == NULL) {
- MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
- float *rectf = buffer->convertToValueBuffer();
- int x, y, i;
- float *p;
- int bwidth = buffer->getWidth();
- int bheight = buffer->getHeight();
- for (i = 0; i < this->m_iterations; i++) {
- for (y = 0; y < bheight; y++) {
- for (x = 0; x < bwidth - 1; x++) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p + 1));
- }
+ MemoryBuffer *tile = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
+ int x, y, i;
+ int width = tile->getWidth();
+ int height = tile->getHeight();
+ float *buffer = tile->getBuffer();
+
+ int half_window = this->m_iterations;
+ int window = half_window * 2 + 1;
+
+ int xmin = max(0, rect->xmin - half_window);
+ int ymin = max(0, rect->ymin - half_window);
+ int xmax = min(width, rect->xmax + half_window);
+ int ymax = min(height, rect->ymax + half_window);
+
+ int bwidth = rect->xmax - rect->xmin;
+ int bheight = rect->ymax - rect->ymin;
+
+ // Note: Cache buffer has original tilesize width, but new height.
+ // We have to calculate the additional rows in the first pass,
+ // to have valid data available for the second pass.
+ tile_info *result = create_cache(rect->xmin, rect->xmax, ymin, ymax);
+ float *rectf = result->buffer;
+
+ // temp holds maxima for every step in the algorithm, buf holds a
+ // single row or column of input values, padded with MAXFLOATs to
+ // simplify the logic.
+ float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
+ float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window), "dilate erode buf");
+
+ // The following is based on the van Herk/Gil-Werman algorithm for morphology operations.
+ // first pass, horizontal dilate/erode
+ for (y = ymin; y < ymax; y++) {
+ for (x = 0; x < bwidth + 5 * half_window; x++) {
+ buf[x] = MAXFLOAT;
+ }
+ for (x = xmin; x < xmax; ++x) {
+ buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
+ }
+
+ for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (x = 1; x < window; x++) {
+ temp[window - 1 - x] = min(temp[window - x], buf[start - x]);
+ temp[window - 1 + x] = min(temp[window + x - 2], buf[start + x]);
}
-
- for (y = 0; y < bheight; y++) {
- for (x = bwidth - 1; x >= 1; x--) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p - 1));
- }
+
+ start = half_window + (i - 1) * window + 1;
+ for (x = -min(0, start); x < window - max(0, start + window - bwidth); x++) {
+ rectf[bwidth * (y - ymin) + (start + x)] = min(temp[x], temp[x + window - 1]);
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = 0; y < bheight - 1; y++) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p + bwidth));
- }
+ }
+ }
+
+ // second pass, vertical dilate/erode
+ for (x = 0; x < bwidth; x++) {
+ for (y = 0; y < bheight + 5 * half_window; y++) {
+ buf[y] = MAXFLOAT;
+ }
+ for (y = ymin; y < ymax; y++) {
+ buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
+ }
+
+ for (i = 0; i < (bheight + 3 * half_window) / window; i++) {
+ int start = (i + 1) * window - 1;
+
+ temp[window - 1] = buf[start];
+ for (y = 1; y < window; y++) {
+ temp[window - 1 - y] = min(temp[window - y], buf[start - y]);
+ temp[window - 1 + y] = min(temp[window + y - 2], buf[start + y]);
}
-
- for (x = 0; x < bwidth; x++) {
- for (y = bheight - 1; y >= 1; y--) {
- p = rectf + (bwidth * y + x);
- *p = MIN2(*p, *(p - bwidth));
- }
+
+ start = half_window + (i - 1) * window + 1;
+ for (y = -min(0, start); y < window - max(0, start + window - bheight); y++) {
+ rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = min(temp[y], temp[y + window - 1]);
}
}
- this->m_cached_buffer = rectf;
}
- unlockMutex();
- return this->m_cached_buffer;
+
+ MEM_freeN(temp);
+ MEM_freeN(buf);
+
+ return result;
}
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h
index 47480d47c3b..51bad81d0ca 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.h
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h
@@ -128,7 +128,6 @@ protected:
int m_iterations;
- float *m_cached_buffer;
public:
DilateStepOperation();
@@ -147,6 +146,7 @@ public:
* Deinitialize the execution
*/
void deinitExecution();
+ void deinitializeTileData(rcti *rect, void *data);
void setIterations(int iterations) { this->m_iterations = iterations; }
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
index 0efead77cd4..aaf5f92505b 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
@@ -182,8 +182,8 @@ bool GaussianAlphaXBlurOperation::determineDependingAreaOfInterest(rcti *input,
#endif
{
if (this->m_sizeavailable && this->m_gausstab != NULL) {
- newInput.xmax = input->xmax + this->m_rad;
- newInput.xmin = input->xmin - this->m_rad;
+ newInput.xmax = input->xmax + this->m_rad + 1;
+ newInput.xmin = input->xmin - this->m_rad - 1;
newInput.ymax = input->ymax;
newInput.ymin = input->ymin;
}
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
index 1f9cc8e461a..650805f91d5 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
@@ -184,8 +184,8 @@ bool GaussianAlphaYBlurOperation::determineDependingAreaOfInterest(rcti *input,
if (this->m_sizeavailable && this->m_gausstab != NULL) {
newInput.xmax = input->xmax;
newInput.xmin = input->xmin;
- newInput.ymax = input->ymax + this->m_rad;
- newInput.ymin = input->ymin - this->m_rad;
+ newInput.ymax = input->ymax + this->m_rad + 1;
+ newInput.ymin = input->ymin - this->m_rad - 1;
}
else {
newInput.xmax = this->getWidth();
diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
index 573a19466e8..af231d118a6 100644
--- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
@@ -133,8 +133,8 @@ bool GaussianXBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB
}
{
if (this->m_sizeavailable && this->m_gausstab != NULL) {
- newInput.xmax = input->xmax + this->m_rad;
- newInput.xmin = input->xmin - this->m_rad;
+ newInput.xmax = input->xmax + this->m_rad + 1;
+ newInput.xmin = input->xmin - this->m_rad - 1;
newInput.ymax = input->ymax;
newInput.ymin = input->ymin;
}
diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
index 0c0a4d8aa4f..7bf85a953f4 100644
--- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
@@ -136,8 +136,8 @@ bool GaussianYBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB
if (this->m_sizeavailable && this->m_gausstab != NULL) {
newInput.xmax = input->xmax;
newInput.xmin = input->xmin;
- newInput.ymax = input->ymax + this->m_rad;
- newInput.ymin = input->ymin - this->m_rad;
+ newInput.ymax = input->ymax + this->m_rad + 1;
+ newInput.ymin = input->ymin - this->m_rad - 1;
}
else {
newInput.xmax = this->getWidth();
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp
index 84557118a1c..c8e3dbf993d 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_ImageOperation.cpp
@@ -120,7 +120,7 @@ void ImageOperation::executePixel(float output[4], float x, float y, PixelSample
else {
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_buffer, NULL, output, x, y);
+ nearest_interpolation_color(this->m_buffer, NULL, output, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_buffer, NULL, output, x, y);
@@ -143,7 +143,7 @@ void ImageAlphaOperation::executePixel(float output[4], float x, float y, PixelS
tempcolor[3] = 1.0f;
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_buffer, NULL, tempcolor, x, y);
+ nearest_interpolation_color(this->m_buffer, NULL, tempcolor, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_buffer, NULL, tempcolor, x, y);
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp
index 81ca06cfff0..edcd1563e03 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.cpp
+++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp
@@ -84,8 +84,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_NUMBER_OF_CHANNELS +
+ x * COM_NUMBER_OF_CHANNELS];
}
int InpaintSimpleOperation::mdist(int x, int y)
diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
index 709e4b7d4b0..74761f00e1f 100644
--- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp
+++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
@@ -95,7 +95,7 @@ void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSa
else {
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y);
+ nearest_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y);
diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp
index 68a61dff801..863a404ba67 100644
--- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp
+++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp
@@ -75,9 +75,31 @@ void MovieDistortionOperation::initExecution()
calibration_width, calibration_height, this->m_distortion);
s_cache.push_back(newC);
this->m_cache = newC;
+
+ if (this->m_distortion) {
+ float delta[2];
+ rcti full_frame;
+ full_frame.xmin = full_frame.ymin = 0;
+ full_frame.xmax = this->m_width;
+ full_frame.ymax = this->m_height;
+ BKE_tracking_max_undistortion_delta_across_bound(&this->m_movieClip->tracking, &full_frame, delta);
+
+ /* 5 is just in case we didn't hit real max of distortion in
+ * BKE_tracking_max_undistortion_delta_across_bound
+ */
+ m_margin[0] = delta[0] + 5;
+ m_margin[1] = delta[1] + 5;
+ }
+ else {
+ /* undistortion with sane distortion coefficients would be mapped inside
+ * of each tile, should be no need in margin in this case
+ */
+ m_margin[0] = m_margin[1] = 0;
+ }
}
else {
this->m_cache = NULL;
+ m_margin[0] = m_margin[1] = 0;
}
}
@@ -112,3 +134,13 @@ void MovieDistortionOperation::executePixel(float output[4], float x, float y, P
this->m_inputOperation->read(output, x, y, COM_PS_BILINEAR);
}
}
+
+bool MovieDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+ rcti newInput;
+ newInput.xmin = input->xmin - m_margin[0];
+ newInput.ymin = input->ymin - m_margin[1];
+ newInput.xmax = input->xmax + m_margin[0];
+ newInput.ymax = input->ymax + m_margin[1];
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+}
diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h
index 9f8aa065e3e..c9629451992 100644
--- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h
+++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h
@@ -148,6 +148,7 @@ private:
DistortionCache *m_cache;
SocketReader *m_inputOperation;
MovieClip *m_movieClip;
+ int m_margin[2];
protected:
bool m_distortion;
@@ -162,6 +163,8 @@ public:
void setMovieClip(MovieClip *clip) { this->m_movieClip = clip; }
void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
+ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
};
void deintializeDistortionCache(void);
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
index af0d5161835..1c9dd0f170e 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
@@ -54,7 +54,7 @@ void MultilayerColorOperation::executePixel(float output[4], float x, float y, P
if (this->m_numberOfChannels == 4) {
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_buffer, NULL, output, x, y);
+ nearest_interpolation_color(this->m_buffer, NULL, output, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_buffer, NULL, output, x, y);
diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl
index 36205bb94cc..8cc25fc3360 100644
--- a/source/blender/compositor/operations/COM_OpenCLKernels.cl
+++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl
@@ -66,7 +66,8 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima
}
color /= multiplyer;
- } else {
+ }
+ else {
int2 imageCoordinates = realCoordinate - offsetInput;
color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates);
}
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index 7d05202df96..47b69ec87f9 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -141,7 +141,7 @@ 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->imtype,
+ BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
(this->m_rd->scemode & R_EXTENSION), true);
if (0 == BKE_imbuf_write(ibuf, filename, this->m_format))
@@ -205,7 +205,7 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
char filename[FILE_MAX];
void *exrhandle = IMB_exr_get_handle();
- BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
+ BKE_makepicstring_from_type(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
(this->m_rd->scemode & R_EXTENSION), true);
BLI_make_existing_file(filename);
diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
index d2c6c833e2e..fb996f2abaf 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
@@ -204,10 +204,10 @@ bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input
}
#define UPDATE_INPUT { \
- newInput.xmin = MIN4(newInput.xmin, coords[0], coords[2], coords[4]); \
- newInput.ymin = MIN4(newInput.ymin, coords[1], coords[3], coords[5]); \
- newInput.xmax = MAX4(newInput.xmax, coords[0], coords[2], coords[4]); \
- newInput.ymax = MAX4(newInput.ymax, coords[1], coords[3], coords[5]); \
+ newInput.xmin = min_ffff(newInput.xmin, coords[0], coords[2], coords[4]); \
+ newInput.ymin = min_ffff(newInput.ymin, coords[1], coords[3], coords[5]); \
+ newInput.xmax = max_ffff(newInput.xmax, coords[0], coords[2], coords[4]); \
+ newInput.ymax = max_ffff(newInput.ymax, coords[1], coords[3], coords[5]); \
} (void)0
rcti newInput;
@@ -273,7 +273,7 @@ void ScreenLensDistortionOperation::updateVariables(float distortion, float disp
const float d = 0.25f * max_ff(min_ff(dispersion, 1.0f), 0.0f);
this->m_kr = max_ff(min_ff((this->m_kg + d), 1.0f), -0.999f);
this->m_kb = max_ff(min_ff((this->m_kg - d), 1.0f), -0.999f);
- this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb);
+ this->m_maxk = max_fff(this->m_kr, this->m_kg, this->m_kb);
this->m_sc = (this->m_data->fit && (this->m_maxk > 0.0f)) ? (1.0f / (1.0f + 2.0f * this->m_maxk)) :
(1.0f / (1.0f + this->m_maxk));
this->m_drg = 4.0f * (this->m_kg - this->m_kr);
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp
index f8d6c0cfc01..23a3abe61ee 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.cpp
+++ b/source/blender/compositor/operations/COM_TextureOperation.cpp
@@ -23,6 +23,7 @@
#include "COM_TextureOperation.h"
#include "BLI_listbase.h"
+#include "BKE_image.h"
TextureBaseOperation::TextureBaseOperation() : NodeOperation()
{
@@ -46,11 +47,14 @@ void TextureBaseOperation::initExecution()
{
this->m_inputOffset = getInputSocketReader(0);
this->m_inputSize = getInputSocketReader(1);
+ this->m_pool = BKE_image_pool_new();
}
void TextureBaseOperation::deinitExecution()
{
this->m_inputSize = NULL;
this->m_inputOffset = NULL;
+ BKE_image_pool_free(this->m_pool);
+ this->m_pool = NULL;
}
void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
@@ -95,7 +99,7 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel
vec[1] = textureSize[1] * (v + textureOffset[1]);
vec[2] = textureSize[2] * textureOffset[2];
- retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres);
+ retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool);
if (texres.talpha)
output[3] = texres.ta;
diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h
index f8435ecdaa2..227ad37579a 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.h
+++ b/source/blender/compositor/operations/COM_TextureOperation.h
@@ -45,6 +45,7 @@ private:
const RenderData *m_rd;
SocketReader *m_inputSize;
SocketReader *m_inputOffset;
+ struct ImagePool *m_pool;
protected:
diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp
index 8b5288321c1..e647ae975ff 100644
--- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp
+++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp
@@ -42,7 +42,7 @@ TrackPositionOperation::TrackPositionOperation() : NodeOperation()
this->m_trackingObjectName[0] = 0;
this->m_trackName[0] = 0;
this->m_axis = 0;
- this->m_position = POSITION_ABSOLUTE;;
+ this->m_position = POSITION_ABSOLUTE;
this->m_relativeFrame = 0;
}
diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp
index 761f55a1455..9f6924eb428 100644
--- a/source/blender/compositor/operations/COM_TranslateOperation.cpp
+++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp
@@ -15,9 +15,10 @@
* 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
+ * Contributor:
+ * Jeroen Bakker
* Monique Dewanchand
+ * Thomas Beck (plasmasolutions.de)
*/
#include "COM_TranslateOperation.h"
@@ -33,6 +34,8 @@ TranslateOperation::TranslateOperation() : NodeOperation()
this->m_inputXOperation = NULL;
this->m_inputYOperation = NULL;
this->m_isDeltaSet = false;
+ this->m_factorX = 1.0f;
+ this->m_factorY = 1.0f;
}
void TranslateOperation::initExecution()
{
@@ -40,6 +43,7 @@ void TranslateOperation::initExecution()
this->m_inputXOperation = this->getInputSocketReader(1);
this->m_inputYOperation = this->getInputSocketReader(2);
+ ensureDelta();
}
void TranslateOperation::deinitExecution()
@@ -53,18 +57,30 @@ void TranslateOperation::deinitExecution()
void TranslateOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
ensureDelta();
- this->m_inputOperation->read(output, x - this->getDeltaX(), y - this->getDeltaY(), sampler);
+
+ float originalXPos = x - this->getDeltaX();
+ float originalYPos = y - this->getDeltaY();
+
+ this->m_inputOperation->read(output, originalXPos, originalYPos, sampler);
}
bool TranslateOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- ensureDelta();
rcti newInput;
-
- newInput.xmax = input->xmax - this->getDeltaX();
+
+ ensureDelta();
+
newInput.xmin = input->xmin - this->getDeltaX();
- newInput.ymax = input->ymax - this->getDeltaY();
+ newInput.xmax = input->xmax - this->getDeltaX();
newInput.ymin = input->ymin - this->getDeltaY();
-
+ newInput.ymax = input->ymax - this->getDeltaY();
+
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
+
+void TranslateOperation::setFactorXY(float factorX, float factorY)
+{
+ m_factorX = factorX;
+ m_factorY = factorY;
+}
+
diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h
index faaadb1ced2..d53c3e464fc 100644
--- a/source/blender/compositor/operations/COM_TranslateOperation.h
+++ b/source/blender/compositor/operations/COM_TranslateOperation.h
@@ -33,6 +33,10 @@ private:
float m_deltaX;
float m_deltaY;
bool m_isDeltaSet;
+ float m_relativeOffsetX;
+ float m_relativeOffsetY;
+ float m_factorX;
+ float m_factorY;
public:
TranslateOperation();
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
@@ -41,8 +45,8 @@ public:
void initExecution();
void deinitExecution();
- float getDeltaX() { return this->m_deltaX; }
- float getDeltaY() { return this->m_deltaY; }
+ float getDeltaX() { return this->m_deltaX * this->m_factorX; }
+ float getDeltaY() { return this->m_deltaY * this->m_factorY; }
inline void ensureDelta() {
if (!this->m_isDeltaSet) {
@@ -54,6 +58,8 @@ public:
this->m_isDeltaSet = true;
}
}
+
+ void setFactorXY(float factorX, float factorY);
};
#endif
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
index d5f2c283c72..072246932db 100644
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
@@ -48,6 +48,7 @@ ViewerBaseOperation::ViewerBaseOperation() : NodeOperation()
this->m_doDepthBuffer = false;
this->m_viewSettings = NULL;
this->m_displaySettings = NULL;
+ this->m_ignoreAlpha = false;
}
void ViewerBaseOperation::initExecution()
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h
index f7d479eb3b8..9f7e80ad6fc 100644
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h
+++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h
@@ -39,6 +39,7 @@ protected:
OrderOfChunks m_chunkOrder;
bool m_doDepthBuffer;
ImBuf *m_ibuf;
+ bool m_ignoreAlpha;
const ColorManagedViewSettings *m_viewSettings;
const ColorManagedDisplaySettings *m_displaySettings;
@@ -59,6 +60,7 @@ public:
OrderOfChunks getChunkOrder() { return this->m_chunkOrder; }
const CompositorPriority getRenderPriority() const;
bool isViewerOperation() { return true; }
+ void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp
index d1ac7d74ead..4d10e49aeeb 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp
@@ -89,9 +89,14 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
for (y = y1; y < y2 && (!breaked); y++) {
for (x = x1; x < x2; x++) {
this->m_imageInput->read(&(buffer[offset4]), x, y, COM_PS_NEAREST);
- if (this->m_alphaInput != NULL) {
- this->m_alphaInput->read(alpha, x, y, COM_PS_NEAREST);
- buffer[offset4 + 3] = alpha[0];
+ if (this->m_ignoreAlpha) {
+ buffer[offset4 + 3] = 1.0f;
+ }
+ else {
+ if (this->m_alphaInput != NULL) {
+ this->m_alphaInput->read(alpha, x, y, COM_PS_NEAREST);
+ buffer[offset4 + 3] = alpha[0];
+ }
}
if (m_depthInput) {
this->m_depthInput->read(depth, x, y, COM_PS_NEAREST);
diff --git a/source/blender/compositor/operations/COM_WrapOperation.cpp b/source/blender/compositor/operations/COM_WrapOperation.cpp
new file mode 100644
index 00000000000..37a93520c7c
--- /dev/null
+++ b/source/blender/compositor/operations/COM_WrapOperation.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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
+ * Thomas Beck (plasmasolutions.de)
+ */
+
+#include "COM_WrapOperation.h"
+
+WrapOperation::WrapOperation() : NodeOperation()
+{
+ this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_COLOR);
+ this->setResolutionInputSocketIndex(0);
+ this->m_inputOperation = NULL;
+}
+void WrapOperation::initExecution()
+{
+ this->m_inputOperation = this->getInputSocketReader(0);
+}
+
+void WrapOperation::deinitExecution()
+{
+ this->m_inputOperation = NULL;
+}
+
+inline float WrapOperation::getWrappedOriginalXPos(float x)
+{
+ while (x < 0) x += this->m_width;
+ return fmodf(x, this->getWidth());
+}
+
+inline float WrapOperation::getWrappedOriginalYPos(float y)
+{
+ while (y < 0) y += this->m_height;
+ return fmodf(y, this->getHeight());
+}
+
+void WrapOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
+{
+ float nx, ny;
+ nx = x;
+ ny = y;
+ switch (m_wrappingType) {
+ case CMP_NODE_WRAP_NONE:
+ //Intentionally empty, originalXPos and originalYPos have been set before
+ break;
+ case CMP_NODE_WRAP_X:
+ // wrap only on the x-axis
+ nx = this->getWrappedOriginalXPos(x);
+ break;
+ case CMP_NODE_WRAP_Y:
+ // wrap only on the y-axis
+ ny = this->getWrappedOriginalYPos(y);
+ break;
+ case CMP_NODE_WRAP_XY:
+ // wrap on both
+ nx = this->getWrappedOriginalXPos(x);
+ ny = this->getWrappedOriginalYPos(y);
+ break;
+ }
+
+ this->m_inputOperation->read(output, nx, ny, sampler);
+
+}
+
+bool WrapOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+ rcti newInput;
+
+ newInput.xmin = input->xmin;
+ newInput.xmax = input->xmax;
+ newInput.ymin = input->ymin;
+ newInput.ymax = input->ymax;
+
+ if (m_wrappingType == 1 || m_wrappingType == 3) {
+ // wrap only on the x-axis if tile is wrapping
+ newInput.xmin = getWrappedOriginalXPos(input->xmin);
+ newInput.xmax = getWrappedOriginalXPos(input->xmax);
+ if (newInput.xmin > newInput.xmax) {
+ newInput.xmin = 0;
+ newInput.xmax = this->getWidth();
+ }
+ }
+ if (m_wrappingType == 2 || m_wrappingType == 3) {
+ // wrap only on the y-axis if tile is wrapping
+ newInput.ymin = getWrappedOriginalYPos(input->ymin);
+ newInput.ymax = getWrappedOriginalYPos(input->ymax);
+ if (newInput.ymin > newInput.ymax) {
+ newInput.ymin = 0;
+ newInput.ymax = this->getHeight();
+ }
+ }
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+}
+
+void WrapOperation::setWrapping(int wrapping_type)
+{
+ m_wrappingType = wrapping_type;
+}
diff --git a/source/blender/compositor/operations/COM_WrapOperation.h b/source/blender/compositor/operations/COM_WrapOperation.h
new file mode 100644
index 00000000000..b84d85e7b5d
--- /dev/null
+++ b/source/blender/compositor/operations/COM_WrapOperation.h
@@ -0,0 +1,47 @@
+/*
+ * 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_WrapOperation_h_
+#define _COM_WrapOperation_h_
+
+#include "COM_NodeOperation.h"
+
+class WrapOperation : public NodeOperation {
+private:
+ SocketReader *m_inputOperation;
+ int m_wrappingType;
+public:
+ WrapOperation();
+ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+ void executePixel(float output[4], float x, float y, PixelSampler sampler);
+
+ void initExecution();
+ void deinitExecution();
+
+ void setWrapping(int wrapping_type);
+ float getWrappedOriginalXPos(float x);
+ float getWrappedOriginalYPos(float y);
+
+ void setFactorXY(float factorX, float factorY);
+};
+
+#endif
diff --git a/source/blender/datatoc/datatoc.c b/source/blender/datatoc/datatoc.c
index 379658bb4c4..236d9af8ef1 100644
--- a/source/blender/datatoc/datatoc.c
+++ b/source/blender/datatoc/datatoc.c
@@ -51,6 +51,7 @@ int main(int argc, char **argv)
FILE *fpin, *fpout;
long size;
int i;
+ int argv_len;
if (argc < 2) {
printf("Usage: datatoc <data_file_from> <data_file_to>\n");
@@ -75,7 +76,8 @@ int main(int argc, char **argv)
printf("Making C file <%s>\n", argv[2]);
#endif
- for (i = 0; i < (int)strlen(argv[1]); i++)
+ argv_len = (int)strlen(argv[1]);
+ for (i = 0; i < argv_len; i++)
if (argv[1][i] == '.') argv[1][i] = '_';
fpout = fopen(argv[2], "w");
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript
index 6233ea0dc39..1ea2bc0e4ef 100644
--- a/source/blender/editors/SConscript
+++ b/source/blender/editors/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
diff --git a/source/blender/editors/animation/SConscript b/source/blender/editors/animation/SConscript
index 658ad2794a1..2a6b381ba66 100644
--- a/source/blender/editors/animation/SConscript
+++ b/source/blender/editors/animation/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 9ceecd60bef..ad6098010f8 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -36,6 +36,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
@@ -82,7 +84,7 @@
#define EXTRA_SCROLL_PAD 100.0f
/* size of indent steps */
-#define INDENT_STEP_SIZE 7
+#define INDENT_STEP_SIZE (0.35f * U.widget_unit)
/* size of string buffers used for animation channel displayed names */
#define ANIM_CHAN_NAME_SIZE 256
@@ -305,15 +307,15 @@ static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
if (ale->id) {
/* texture animdata */
if (GS(ale->id->name) == ID_TE) {
- offset += 21;
+ offset += U.widget_unit;
}
/* materials and particles animdata */
else if (ELEM(GS(ale->id->name), ID_MA, ID_PA))
- offset += 14;
+ offset += (short)(0.7f * U.widget_unit);
/* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */
else if (ac->datatype != ANIMCONT_ACTION)
- offset += 14;
+ offset += (short)(0.7f * U.widget_unit);
/* nodetree animdata */
if (GS(ale->id->name) == ID_NT) {
@@ -2911,12 +2913,12 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting,
/* --------------------------- */
-// XXX hardcoded size of icons
-#define ICON_WIDTH 17
-// XXX hardcoded width of sliders
-#define SLIDER_WIDTH 80
-// XXX hardcoded width of rename textboxes
-#define RENAME_TEXT_WIDTH 100
+// size of icons
+#define ICON_WIDTH (0.85f * U.widget_unit)
+// width of sliders
+#define SLIDER_WIDTH (4 * U.widget_unit)
+// width of rename textboxes
+#define RENAME_TEXT_WIDTH (5 * U.widget_unit)
/* Draw the given channel */
void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
@@ -2936,13 +2938,11 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
else
offset = 0;
- /* calculate appropriate y-coordinates for icon buttons
- * 7 is hardcoded factor for half-height of icons
- */
+ /* calculate appropriate y-coordinates for icon buttons */
y = (ymaxc - yminc) / 2 + yminc;
- ymid = y - 7;
+ ymid = y - 0.5f * ICON_WIDTH;
/* y-coordinates for text is only 4 down from middle */
- ytext = y - 4;
+ ytext = y - 0.2f * U.widget_unit;
/* check if channel is selected */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
@@ -2989,10 +2989,8 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
glColor3fv(fcu->color);
/* just a solid color rect
- * hardcoded 17 pixels width is slightly wider than icon width, so that
- * there's a slight border around it
*/
- glRectf(offset, yminc, offset + 17, ymaxc);
+ glRectf(offset, yminc, offset + ICON_WIDTH, ymaxc);
}
/* icon is drawn as widget now... */
@@ -3086,7 +3084,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
}
- /* finally draw a backdrop rect behind these
+ /* finally draw a backdrop rect behind these
* - starts from the point where the first toggle/slider starts,
* - ends past the space that might be reserved for a scroller
*/
@@ -3260,21 +3258,21 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
icon = ICON_VISIBLE_IPO_OFF;
if (ale->type == ANIMTYPE_FCURVE)
- tooltip = "Channel is visible in Graph Editor for editing";
+ tooltip = TIP_("Channel is visible in Graph Editor for editing");
else
- tooltip = "Channel(s) are visible in Graph Editor for editing";
+ tooltip = TIP_("Channels are visible in Graph Editor for editing");
break;
case ACHANNEL_SETTING_EXPAND: /* expanded triangle */
//icon = ((enabled)? ICON_TRIA_DOWN : ICON_TRIA_RIGHT);
icon = ICON_TRIA_RIGHT;
- tooltip = "Make channels grouped under this channel visible";
+ tooltip = TIP_("Make channels grouped under this channel visible");
break;
case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */
//icon = ((enabled)? ICON_LAYER_ACTIVE : ICON_LAYER_USED);
icon = ICON_LAYER_USED;
- tooltip = "NLA Track is the only one evaluated for the AnimData block it belongs to";
+ tooltip = TIP_("NLA Track is the only one evaluated for the AnimData block it belongs to");
break;
/* --- */
@@ -3283,7 +3281,7 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
// TODO: what about when there's no protect needed?
//icon = ((enabled)? ICON_LOCKED : ICON_UNLOCKED);
icon = ICON_UNLOCKED;
- tooltip = "Editability of keyframes for this channel";
+ tooltip = TIP_("Editability of keyframes for this channel");
break;
case ACHANNEL_SETTING_MUTE: /* muted speaker */
@@ -3291,9 +3289,9 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
icon = ICON_MUTE_IPO_OFF;
if (ale->type == ALE_FCURVE)
- tooltip = "Does F-Curve contribute to result";
+ tooltip = TIP_("Does F-Curve contribute to result");
else
- tooltip = "Do channels contribute to result";
+ tooltip = TIP_("Do channels contribute to result");
break;
default:
@@ -3365,12 +3363,9 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
offset = 0;
/* calculate appropriate y-coordinates for icon buttons
- * 7 is hardcoded factor for half-height of icons
*/
y = (ymaxc - yminc) / 2 + yminc;
- ymid = y - 7;
- /* y-coordinates for text is only 4 down from middle */
- /* ytext = y - 4; */
+ ymid = y - 0.5f * ICON_WIDTH;
/* no button backdrop behind icons */
uiBlockSetEmboss(block, UI_EMBOSSN);
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index fe836204c27..d218cc537da 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -538,12 +538,26 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
BLI_remlink(&adt->drivers, fcu);
}
else if (adt->action) {
+ bAction *act = adt->action;
+
/* remove from group or action, whichever one "owns" the F-Curve */
- if (fcu->grp)
- action_groups_remove_channel(adt->action, fcu);
- else
- BLI_remlink(&adt->action->curves, fcu);
+ if (fcu->grp) {
+ bActionGroup *agrp = fcu->grp;
+
+ /* remove F-Curve from group+action */
+ action_groups_remove_channel(act, fcu);
+ /* if group has no more channels, remove it too,
+ * otherwise can have many dangling groups [#33541]
+ */
+ if (agrp->channels.first == NULL) {
+ BLI_freelinkN(&act->groups, agrp);
+ }
+ }
+ else {
+ BLI_remlink(&act->curves, fcu);
+ }
+
/* if action has no more F-Curves as a result of this, unlink it from
* AnimData if it did not come from a NLA Strip being tweaked.
*
@@ -551,12 +565,8 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
* channel list that are empty, and linger around long after the data they
* are for has disappeared (and probably won't come back).
*/
- // XXX: does everybody always want this?
- /* XXX: there's a problem where many actions could build up in the file if multiple
- * full add/delete cycles are performed on the same objects, but assume that this is rare
- */
- if ((adt->action->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
- id_us_min(&adt->action->id);
+ if ((act->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
+ id_us_min(&act->id);
adt->action = NULL;
}
}
@@ -1137,6 +1147,218 @@ static void ANIM_OT_channels_move(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "direction", prop_animchannel_rearrange_types, REARRANGE_ANIMCHAN_DOWN, "Direction", "");
}
+/* ******************** Group Channel Operator ************************ */
+
+static int animchannels_grouping_poll(bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceLink *sl;
+
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
+
+ /* animation editor test - must be suitable modes only */
+ sl = CTX_wm_space_data(C);
+
+ switch (sa->spacetype) {
+ /* supported... */
+ case SPACE_ACTION:
+ {
+ SpaceAction *saction = (SpaceAction *)sl;
+
+ /* dopesheet and action only - all others are for other datatypes or have no groups */
+ if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_DOPESHEET) == 0)
+ return 0;
+ }
+ break;
+
+ case SPACE_IPO:
+ {
+ SpaceIpo *sipo = (SpaceIpo *)sl;
+
+ /* drivers can't have groups... */
+ if (sipo->mode != SIPO_MODE_ANIMATION)
+ return 0;
+ }
+ break;
+
+ /* unsupported... */
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* ----------------------------------------------------------- */
+
+static void animchannels_group_channels(bAnimContext *ac, bAnimListElem *adt_ref, const char name[])
+{
+ AnimData *adt = adt_ref->adt;
+ bAction *act = adt->action;
+
+ if (act) {
+ ListBase anim_data = {NULL, NULL};
+ int filter;
+
+ /* find selected F-Curves to re-group */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
+ ANIM_animdata_filter(ac, &anim_data, filter, adt_ref, ANIMCONT_CHANNEL);
+
+ if (anim_data.first) {
+ bActionGroup *agrp;
+ bAnimListElem *ale;
+
+ /* create new group, which should now be part of the action */
+ agrp = action_groups_add_new(act, name);
+ BLI_assert(agrp != NULL);
+
+ /* transfer selected F-Curves across to new group */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ bActionGroup *grp = fcu->grp;
+
+ /* remove F-Curve from group, then group too if it is now empty */
+ action_groups_remove_channel(act, fcu);
+
+ if ((grp) && (grp->channels.first == NULL)) {
+ BLI_freelinkN(&act->groups, grp);
+ }
+
+ /* add F-Curve to group */
+ action_groups_add_channel(act, agrp, fcu);
+ }
+ }
+
+ /* cleanup */
+ BLI_freelistN(&anim_data);
+ }
+}
+
+static int animchannels_group_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ char name[MAX_NAME];
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get name for new group */
+ RNA_string_get(op->ptr, "name", name);
+
+ /* XXX: name for group should never be empty... */
+ if (name[0]) {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* handle each animdata block separately, so that the regrouping doesn't flow into blocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ animchannels_group_channels(&ac, ale, name);
+ }
+
+ /* free temp data */
+ BLI_freelistN(&anim_data);
+
+ /* updatss */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void ANIM_OT_channels_group(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Group Channels";
+ ot->idname = "ANIM_OT_channels_group";
+ ot->description = "Add selected F-Curves to a new group";
+
+ /* callbacks */
+ ot->invoke = WM_operator_props_popup;
+ ot->exec = animchannels_group_exec;
+ ot->poll = animchannels_grouping_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ ot->prop = RNA_def_string(ot->srna, "name", "New Group",
+ sizeof(((bActionGroup *)NULL)->name),
+ "Name", "Name of newly created group");
+ /* RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); */ /* XXX: still not too sure about this - keeping same text is confusing... */
+}
+
+/* ----------------------------------------------------------- */
+
+static int animchannels_ungroup_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* just selected F-Curves... */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* find action for this F-Curve... */
+ if (ale->adt && ale->adt->action) {
+ FCurve *fcu = (FCurve *)ale->data;
+ bAction *act = ale->adt->action;
+
+ /* only proceed to remove if F-Curve is in a group... */
+ if (fcu->grp) {
+ bActionGroup *agrp = fcu->grp;
+
+ /* remove F-Curve from group and add at tail (ungrouped) */
+ action_groups_remove_channel(act, fcu);
+ BLI_addtail(&act->curves, fcu);
+
+ /* delete group if it is now empty */
+ if (agrp->channels.first == NULL) {
+ BLI_freelinkN(&act->groups, agrp);
+ }
+ }
+ }
+ }
+
+ /* cleanup */
+ BLI_freelistN(&anim_data);
+
+ /* updates */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Ungroup Channels";
+ ot->idname = "ANIM_OT_channels_ungroup";
+ ot->description = "Remove selected F-Curves from their current groups";
+
+ /* callbacks */
+ ot->exec = animchannels_ungroup_exec;
+ ot->poll = animchannels_grouping_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* ******************** Delete Channel Operator *********************** */
static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1223,13 +1445,13 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
BLI_freelinkN(&gpd->layers, gpl);
}
break;
-
+
case ANIMTYPE_MASKLAYER:
{
- /* Grease Pencil layer */
+ /* Mask layer */
Mask *mask = (Mask *)ale->id;
MaskLayer *masklay = (MaskLayer *)ale->data;
-
+
/* try to delete the layer's data and the layer itself */
BKE_mask_layer_remove(mask, masklay);
}
@@ -1320,10 +1542,10 @@ static int animchannels_visibility_set_exec(bContext *C, wmOperator *UNUSED(op))
/* 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);
}
@@ -1397,10 +1619,10 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *UNUSED(o
/* 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));
}
@@ -2218,7 +2440,7 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in
}
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- }
+ }
break;
case ANIMTYPE_GROUP:
@@ -2470,6 +2692,9 @@ void ED_operatortypes_animchannels(void)
WM_operatortype_append(ANIM_OT_channels_visibility_set);
WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
+
+ WM_operatortype_append(ANIM_OT_channels_group);
+ WM_operatortype_append(ANIM_OT_channels_ungroup);
}
// TODO: check on a poll callback for this, to get hotkeys into menus
@@ -2523,6 +2748,10 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_BOTTOM);
+ /* 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_draw.c b/source/blender/editors/animation/anim_draw.c
index 0f0584ad8fe..eb1f5ef1043 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -33,9 +33,12 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+
#include "BLI_math.h"
#include "BKE_context.h"
+#include "BKE_blender.h"
#include "BKE_global.h"
#include "BKE_nla.h"
#include "BKE_object.h"
@@ -197,15 +200,15 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, float cfra, short time)
/* get starting coordinates for drawing */
x = cfra * xscale;
- y = 18;
+ y = 0.9f * U.widget_unit;
/* draw green box around/behind text */
UI_ThemeColorShade(TH_CFRAME, 0);
- glRectf(x, y, x + slen, y + 15);
+ glRectf(x, y, x + slen, y + 0.75f * U.widget_unit);
/* draw current frame number - black text */
UI_ThemeColor(TH_TEXT);
- UI_DrawString(x - 5, y + 3, numstr);
+ UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr);
/* restore view transform */
glScalef(xscale, 1.0, 1.0);
@@ -396,20 +399,23 @@ float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short rest
static short bezt_unit_mapping_apply(KeyframeEditData *ked, BezTriple *bezt)
{
/* mapping factor is stored in f1, flags are stored in i1 */
- short only_keys = (ked->i1 & ANIM_UNITCONV_ONLYKEYS);
- short sel_vs = (ked->i1 & ANIM_UNITCONV_SELVERTS);
+ const bool only_keys = (ked->i1 & ANIM_UNITCONV_ONLYKEYS);
+ const bool sel_vs = (ked->i1 & ANIM_UNITCONV_SELVERTS);
+ const bool skip_knot = (ked->i1 & ANIM_UNITCONV_SKIPKNOTS);
float fac = ked->f1;
/* adjust BezTriple handles only if allowed to */
- if (only_keys == 0) {
- if ((sel_vs == 0) || (bezt->f1 & SELECT))
+ if (only_keys == false) {
+ if ((sel_vs == false) || (bezt->f1 & SELECT))
bezt->vec[0][1] *= fac;
- if ((sel_vs == 0) || (bezt->f3 & SELECT))
+ if ((sel_vs == false) || (bezt->f3 & SELECT))
bezt->vec[2][1] *= fac;
}
- if ((sel_vs == 0) || (bezt->f2 & SELECT))
- bezt->vec[1][1] *= fac;
+ if (skip_knot == false) {
+ if ((sel_vs == false) || (bezt->f2 & SELECT))
+ bezt->vec[1][1] *= fac;
+ }
return 0;
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 5e215fbd6a2..ec6172d5041 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -290,7 +290,7 @@ static short nlaedit_get_context(bAnimContext *ac, SpaceNla *snla)
short ANIM_animdata_context_getdata(bAnimContext *ac)
{
SpaceLink *sl = ac->sl;
- short ok = 0;
+ short ok = FALSE;
/* context depends on editor we are currently in */
if (sl) {
@@ -319,10 +319,7 @@ short ANIM_animdata_context_getdata(bAnimContext *ac)
}
/* check if there's any valid data */
- if (ok && ac->data)
- return 1;
- else
- return 0;
+ return (ok && ac->data);
}
/* Obtain current anim-data context from Blender Context info
@@ -354,6 +351,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->regiontype = (ar) ? ar->regiontype : 0;
/* get data context info */
+ // XXX: if the below fails, try to grab this info from context instead... (to allow for scripting)
return ANIM_animdata_context_getdata(ac);
}
@@ -913,14 +911,14 @@ static short skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_i
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = NULL;
char *seq_name;
-
+
if (ed) {
/* get strip name, and check if this strip is selected */
seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, FALSE);
if (seq_name) MEM_freeN(seq_name);
}
-
+
/* can only add this F-Curve if it is selected */
if (ads->filterflag & ADS_FILTER_ONLYSEL) {
if ((seq == NULL) || (seq->flag & SELECT) == 0)
@@ -2146,7 +2144,7 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
}
-
+
/* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */
}
END_ANIMFILTER_SUBCHANNELS;
@@ -2318,6 +2316,10 @@ static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bD
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
break;
+ case ANIMTYPE_ANIMDATA:
+ items += animfilter_block_data(ac, anim_data, ads, channel->id, filter_mode);
+ break;
+
default:
printf("ERROR: Unsupported channel type (%d) in animdata_filter_animchan()\n", channel->type);
break;
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index d8e3349e998..b6d24e21057 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -143,7 +143,7 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
/* no array index */
arrayname = "";
}
-
+
/* putting this all together into the buffer */
/* XXX we need to check for invalid names...
* XXX the name length limit needs to be passed in or as some define */
@@ -151,7 +151,7 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname);
else
BLI_snprintf(name, 256, "%s%s", arrayname, propname);
-
+
/* free temp name if nameprop is set */
if (free_structname)
MEM_freeN((void *)structname);
@@ -170,11 +170,11 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
else {
/* invalid path */
BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
-
+
/* icon for this should be the icon for the base ID */
/* TODO: or should we just use the error icon? */
icon = RNA_struct_ui_icon(id_ptr.type);
-
+
/* tag F-Curve as disabled - as not usable path */
fcu->flag |= FCURVE_DISABLED;
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 1b980790fdc..62725cb6c70 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -41,6 +41,7 @@
#include "RNA_enum_types.h"
#include "BLI_blenlib.h"
+#include "BLI_math_base.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -146,16 +147,15 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f
marker->frame += (int)floorf(value + 0.5f);
changed++;
}
+ break;
}
- break;
-
case TFM_TIME_SCALE:
{
/* rescale the distance between the marker and the current frame */
marker->frame = cfra + (int)floorf(((float)(marker->frame - cfra) * value) + 0.5f);
changed++;
+ break;
}
- break;
}
}
}
@@ -395,28 +395,33 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
ICON_MARKER;
}
- UI_icon_draw(xpos * xscale - 5.0f, 16.0f, icon_id);
+ UI_icon_draw(xpos * xscale - 0.3f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id);
glDisable(GL_BLEND);
/* and the marker name too, shifted slightly to the top-right */
if (marker->name && marker->name[0]) {
float x, y;
+
+ /* minimal y coordinate which wouldn't be occluded by scroll */
+ int min_y = 17.0f * UI_DPI_FAC;
if (marker->flag & SELECT) {
UI_ThemeColor(TH_TEXT_HI);
- x = xpos * xscale + 4.0f;
- y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f;
+ x = xpos * xscale + 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 + 4.0f;
- y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f;
+ x = xpos * xscale + 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 + 4.0f;
- y = 17.0f;
+ x = xpos * xscale + 8.0f * UI_DPI_FAC;
+ y = 17.0f * UI_DPI_FAC;
}
}
@@ -1203,7 +1208,7 @@ static int ed_marker_select_border_invoke_wrapper(bContext *C, wmOperator *op, w
static void MARKER_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Marker Border select";
+ ot->name = "Marker Border Select";
ot->description = "Select all time markers using border selection";
ot->idname = "MARKER_OT_select_border";
@@ -1260,7 +1265,7 @@ static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
static void MARKER_OT_select_all(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "(De)select all markers";
+ ot->name = "(De)select all Markers";
ot->description = "Change selection of all time markers";
ot->idname = "MARKER_OT_select_all";
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index ca036a8540e..6687cce88cd 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -62,16 +62,28 @@
/* Check if the operator can be run from the current context */
static int change_frame_poll(bContext *C)
{
- ScrArea *curarea = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
/* XXX temp? prevent changes during render */
- if (G.is_rendering) return 0;
+ if (G.is_rendering) return FALSE;
- /* as long as there is an active area, and it isn't a Graph Editor
- * (since the Graph Editor has its own version which does extra stuff),
- * we're fine
+ /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
+ * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
*/
- return ((curarea) && (curarea->spacetype != SPACE_IPO));
+ if (sa) {
+ if (ELEM5(sa->spacetype, SPACE_TIME, SPACE_ACTION, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
+ return TRUE;
+ }
+ else if (sa->spacetype == SPACE_IPO) {
+ /* NOTE: Graph Editor has special version which does some extra stuff.
+ * No need to show the generic error message for that case though!
+ */
+ return FALSE;
+ }
+ }
+
+ CTX_wm_operator_poll_msg_set(C, "Expected an timeline/animation area to be active");
+ return FALSE;
}
/* Set the new frame number */
@@ -83,7 +95,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
/* set the new frame number */
CFRA = RNA_int_get(op->ptr, "frame");
FRAMENUMBER_MIN_CLAMP(CFRA);
- SUBFRA = 0.f;
+ SUBFRA = 0.0f;
/* do updates */
sound_seek_scene(bmain, scene);
@@ -161,7 +173,7 @@ static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
static void ANIM_OT_change_frame(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Change frame";
+ ot->name = "Change Frame";
ot->idname = "ANIM_OT_change_frame";
ot->description = "Interactively change the current frame number";
@@ -175,7 +187,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO | OPTYPE_GRAB_POINTER;
/* rna */
- RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
+ ot->prop = RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
}
/* ****************** set preview range operator ****************************/
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 25833c13925..cd5e873f40d 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -489,8 +489,6 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
/* send updates */
uiContextAnimUpdate(C);
- DAG_ids_flush_update(CTX_data_main(C), 0);
-
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
}
@@ -541,8 +539,6 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
/* send updates */
uiContextAnimUpdate(C);
- DAG_ids_flush_update(CTX_data_main(C), 0);
-
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 79a4c9a769d..dc0fba0930f 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -151,7 +151,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
}
else {
/* basic size (just "x") */
- maxXWidth = 15;
+ maxXWidth = UI_GetStringWidth("x") + 10;
}
/* draw controls for each coefficient and a + sign at end of row */
@@ -231,16 +231,16 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 100, 20, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Second coefficient"));
- /* closing bracket and '+' sign */
+ /* closing bracket and multiplication sign */
if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) {
- uiDefBut(block, LABEL, 1, ") +", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, ") ×", 0, 0, 40, 20, 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, 20, 20, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, ") ", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
}
}
break;
@@ -327,88 +327,7 @@ static void draw_modifier__noise(uiLayout *layout, ID *id, FModifier *fcm, short
uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
}
-/* --------------- */
-
-#define BINARYSEARCH_FRAMEEQ_THRESH 0.0001f
-
-/* Binary search algorithm for finding where to insert Envelope Data Point.
- * Returns the index to insert at (data already at that index will be offset if replace is 0)
- */
-static int binarysearch_fcm_envelopedata_index(FCM_EnvelopeData array[], float frame, int arraylen, short *exists)
-{
- int start = 0, end = arraylen;
- int loopbreaker = 0, maxloop = arraylen * 2;
-
- /* initialize exists-flag first */
- *exists = 0;
-
- /* sneaky optimizations (don't go through searching process if...):
- * - keyframe to be added is to be added out of current bounds
- * - keyframe to be added would replace one of the existing ones on bounds
- */
- if ((arraylen <= 0) || (array == NULL)) {
- printf("Warning: binarysearch_fcm_envelopedata_index() encountered invalid array\n");
- return 0;
- }
- else {
- /* check whether to add before/after/on */
- float framenum;
-
- /* 'First' Point (when only one point, this case is used) */
- framenum = array[0].time;
- if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *exists = 1;
- return 0;
- }
- else if (frame < framenum)
- return 0;
-
- /* 'Last' Point */
- framenum = array[(arraylen - 1)].time;
- if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *exists = 1;
- return (arraylen - 1);
- }
- else if (frame > framenum)
- return arraylen;
- }
-
-
- /* most of the time, this loop is just to find where to put it
- * - 'loopbreaker' is just here to prevent infinite loops
- */
- for (loopbreaker = 0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
- /* compute and get midpoint */
- int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
- float midfra = array[mid].time;
-
- /* check if exactly equal to midpoint */
- if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *exists = 1;
- return mid;
- }
-
- /* repeat in upper/lower half */
- if (frame > midfra)
- start = mid + 1;
- else if (frame < midfra)
- end = mid - 1;
- }
-
- /* print error if loop-limit exceeded */
- if (loopbreaker == (maxloop - 1)) {
- printf("Error: binarysearch_fcm_envelopedata_index() was taking too long\n");
-
- // include debug info
- printf("\tround = %d: start = %d, end = %d, arraylen = %d\n", loopbreaker, start, end, arraylen);
- }
-
- /* not found, so return where to place it */
- return start;
-}
-
/* callback to add new envelope data point */
-// TODO: should we have a separate file for things like this?
static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(arg))
{
Scene *scene = CTX_data_scene(C);
@@ -425,7 +344,7 @@ static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(ar
/* check that no data exists for the current frame... */
if (env->data) {
short exists = -1;
- int i = binarysearch_fcm_envelopedata_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
+ int i = BKE_fcm_envelope_find_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
/* binarysearch_...() will set exists by default to 0, so if it is non-zero, that means that the point exists already */
if (exists)
@@ -665,9 +584,9 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier
/* name */
if (fmi)
- uiItemL(sub, fmi->name, ICON_NONE);
+ uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
else
- uiItemL(sub, "<Unknown Modifier>", ICON_NONE);
+ uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
/* right-align ------------------------------------------- */
sub = uiLayoutRow(row, TRUE);
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index e520a95aa95..d9d2180e184 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -649,7 +649,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
ActKeyColumn *ak;
ActKeyBlock *ab;
float xscale;
-
+ float iconsize = U.widget_unit / 4.0f;
glEnable(GL_BLEND);
/* get View2D scaling factor */
@@ -665,7 +665,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
else
UI_ThemeColor4(TH_STRIP);
- glRectf(ab->start, ypos - 5, ab->end, ypos + 5);
+ glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize);
}
}
}
@@ -686,7 +686,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
/* draw using OpenGL - uglier but faster */
/* NOTE1: a previous version of this didn't work nice for some intel cards
* NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */
- draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha);
+ draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha);
}
}
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 015c2667a93..decbc351cad 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -300,7 +300,14 @@ static short summary_keyframes_loop(KeyframeEditData *ked, bAnimContext *ac, Key
/* loop through each F-Curve, working on the keyframes until the first curve aborts */
for (ale = anim_data.first; ale; ale = ale->next) {
- ret_code = ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
+ switch (ale->datatype) {
+ case ALE_MASKLAY:
+ case ALE_GPFRAME:
+ break;
+ default:
+ ret_code = ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
+ break;
+ }
if (ret_code)
break;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 8ba330e7c3c..6d1e6eab26b 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -52,6 +52,7 @@
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_rigidbody_types.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
@@ -142,7 +143,7 @@ bAction *verify_adt_action(ID *id, short add)
if ((adt->action == NULL) && (add)) {
char actname[sizeof(id->name) - 2];
BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2);
- adt->action = add_empty_action(actname);
+ adt->action = add_empty_action(G.main, actname);
}
/* return the action */
@@ -540,8 +541,8 @@ static float setting_get_rna_value(PointerRNA *ptr, PropertyRNA *prop, int index
enum {
VISUALKEY_NONE = 0,
VISUALKEY_LOC,
- VISUALKEY_ROT
- /* VISUALKEY_SCA */ /* TODO - looks like support can be added now */
+ VISUALKEY_ROT,
+ VISUALKEY_SCA,
};
/* This helper function determines if visual-keyframing should be used when
@@ -550,17 +551,18 @@ enum {
* blocktypes, when using "standard" keying but 'Visual Keying' option in Auto-Keying
* settings is on.
*/
-static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
+static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
{
bConstraint *con = NULL;
short searchtype = VISUALKEY_NONE;
- short has_parent = FALSE;
+ bool has_rigidbody = false;
+ bool has_parent = false;
const char *identifier = NULL;
/* validate data */
if (ELEM3(NULL, ptr, ptr->data, prop))
return 0;
-
+
/* 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
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
@@ -569,10 +571,14 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
if (ptr->type == &RNA_Object) {
/* Object */
Object *ob = (Object *)ptr->data;
+ RigidBodyOb *rbo = ob->rigidbody_object;
con = ob->constraints.first;
identifier = RNA_property_identifier(prop);
has_parent = (ob->parent != NULL);
+
+ /* active rigidbody objects only, as only those are affected by sim */
+ has_rigidbody = ((rbo) && (rbo->type == RBO_TYPE_ACTIVE));
}
else if (ptr->type == &RNA_PoseBone) {
/* Pose Channel */
@@ -584,13 +590,13 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
}
/* check if any data to search using */
- if (ELEM(NULL, con, identifier) && (has_parent == FALSE))
- return 0;
-
+ if (ELEM(NULL, con, identifier) && (has_parent == false) && (has_rigidbody == false))
+ return false;
+
/* location or rotation identifiers only... */
if (identifier == NULL) {
printf("%s failed: NULL identifier\n", __func__);
- return 0;
+ return false;
}
else if (strstr(identifier, "location")) {
searchtype = VISUALKEY_LOC;
@@ -598,17 +604,20 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
else if (strstr(identifier, "rotation")) {
searchtype = VISUALKEY_ROT;
}
+ else if (strstr(identifier, "scale")) {
+ searchtype = VISUALKEY_SCA;
+ }
else {
printf("%s failed: identifier - '%s'\n", __func__, identifier);
- return 0;
+ return false;
}
/* only search if a searchtype and initial constraint are available */
if (searchtype) {
- /* parent is always matching */
- if (has_parent)
- return 1;
+ /* parent or rigidbody are always matching */
+ if (has_parent || has_rigidbody)
+ return true;
/* constraints */
for (; con; con = con->next) {
@@ -620,42 +629,48 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
switch (con->type) {
/* multi-transform constraints */
case CONSTRAINT_TYPE_CHILDOF:
- return 1;
+ return true;
case CONSTRAINT_TYPE_TRANSFORM:
case CONSTRAINT_TYPE_TRANSLIKE:
- return 1;
+ return true;
case CONSTRAINT_TYPE_FOLLOWPATH:
- return 1;
+ return true;
case CONSTRAINT_TYPE_KINEMATIC:
- return 1;
-
+ return true;
+
/* single-transform constraits */
case CONSTRAINT_TYPE_TRACKTO:
- if (searchtype == VISUALKEY_ROT) return 1;
+ if (searchtype == VISUALKEY_ROT) return true;
break;
case CONSTRAINT_TYPE_DAMPTRACK:
- if (searchtype == VISUALKEY_ROT) return 1;
+ if (searchtype == VISUALKEY_ROT) return true;
break;
case CONSTRAINT_TYPE_ROTLIMIT:
- if (searchtype == VISUALKEY_ROT) return 1;
+ if (searchtype == VISUALKEY_ROT) return true;
break;
case CONSTRAINT_TYPE_LOCLIMIT:
- if (searchtype == VISUALKEY_LOC) return 1;
+ if (searchtype == VISUALKEY_LOC) return true;
break;
- case CONSTRAINT_TYPE_ROTLIKE:
- if (searchtype == VISUALKEY_ROT) return 1;
+ case CONSTRAINT_TYPE_SIZELIMIT:
+ if (searchtype == VISUALKEY_SCA) return true;
break;
case CONSTRAINT_TYPE_DISTLIMIT:
- if (searchtype == VISUALKEY_LOC) return 1;
+ if (searchtype == VISUALKEY_LOC) return true;
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ if (searchtype == VISUALKEY_ROT) return true;
break;
case CONSTRAINT_TYPE_LOCLIKE:
- if (searchtype == VISUALKEY_LOC) return 1;
+ if (searchtype == VISUALKEY_LOC) return true;
+ break;
+ case CONSTRAINT_TYPE_SIZELIKE:
+ if (searchtype == VISUALKEY_SCA) return true;
break;
case CONSTRAINT_TYPE_LOCKTRACK:
- if (searchtype == VISUALKEY_ROT) return 1;
+ if (searchtype == VISUALKEY_ROT) return true;
break;
case CONSTRAINT_TYPE_MINMAX:
- if (searchtype == VISUALKEY_LOC) return 1;
+ if (searchtype == VISUALKEY_LOC) return true;
break;
default:
@@ -664,8 +679,8 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
}
}
- /* when some condition is met, this function returns, so here it can be 0 */
- return 0;
+ /* when some condition is met, this function returns, so that means we've got nothing */
+ return false;
}
/* This helper function extracts the value to use for visual-keyframing
@@ -675,45 +690,26 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_index)
{
const char *identifier = RNA_property_identifier(prop);
+ float tmat[4][4];
+ int rotmode;
/* handle for Objects or PoseChannels only
+ * - only Location, Rotation or Scale keyframes are supported curently
* - constraints can be on either Objects or PoseChannels, so we only check if the
- * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
+ * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
* those structs, allowing us to identify the owner of the data
- * - assume that array_index will be sane
+ * - assume that array_index will be sane
*/
if (ptr->type == &RNA_Object) {
Object *ob = (Object *)ptr->data;
- /* only Location or Rotation keyframes are supported now */
+ /* Loc code is specific... */
if (strstr(identifier, "location")) {
return ob->obmat[3][array_index];
}
- else if (strstr(identifier, "rotation_euler")) {
- float eul[3];
-
- mat4_to_eulO(eul, ob->rotmode, ob->obmat);
- return eul[array_index];
- }
- else if (strstr(identifier, "rotation_quaternion")) {
- float trimat[3][3], quat[4];
-
- copy_m3_m4(trimat, ob->obmat);
- mat3_to_quat_is_ok(quat, trimat);
-
- return quat[array_index];
- }
- else if (strstr(identifier, "rotation_axis_angle")) {
- float axis[3], angle;
-
- mat4_to_axis_angle(axis, &angle, ob->obmat);
-
- /* w = 0, x,y,z = 1,2,3 */
- if (array_index == 0)
- return angle;
- else
- return axis[array_index - 1];
- }
+
+ copy_m4_m4(tmat, ob->obmat);
+ rotmode = ob->rotmode;
}
else if (ptr->type == &RNA_PoseBone) {
Object *ob = (Object *)ptr->id.data; /* we assume that this is always set, and is an object */
@@ -726,41 +722,52 @@ static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_i
* will be what owns the pose-channel that is getting this anyway.
*/
copy_m4_m4(tmat, pchan->pose_mat);
- constraint_mat_convertspace(ob, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ rotmode = pchan->rotmode;
- /* Loc, Rot/Quat keyframes are supported... */
+ /* Loc code is specific... */
if (strstr(identifier, "location")) {
/* only use for non-connected bones */
- if ((pchan->bone->parent) && !(pchan->bone->flag & BONE_CONNECTED))
- return tmat[3][array_index];
- else if (pchan->bone->parent == NULL)
+ if ((pchan->bone->parent == NULL) || !(pchan->bone->flag & BONE_CONNECTED))
return tmat[3][array_index];
}
- else if (strstr(identifier, "rotation_euler")) {
- float eul[3];
-
- mat4_to_eulO(eul, pchan->rotmode, tmat);
- return eul[array_index];
- }
- else if (strstr(identifier, "rotation_quaternion")) {
- float trimat[3][3], quat[4];
-
- copy_m3_m4(trimat, tmat);
- mat3_to_quat_is_ok(quat, trimat);
-
- return quat[array_index];
- }
- else if (strstr(identifier, "rotation_axis_angle")) {
- float axis[3], angle;
-
- mat4_to_axis_angle(axis, &angle, tmat);
-
- /* w = 0, x,y,z = 1,2,3 */
- if (array_index == 0)
- return angle;
- else
- return axis[array_index - 1];
- }
+ }
+ else {
+ return setting_get_rna_value(ptr, prop, array_index);
+ }
+
+ /* Rot/Scale code are common! */
+ if (strstr(identifier, "rotation_euler")) {
+ float eul[3];
+
+ mat4_to_eulO(eul, rotmode, tmat);
+ return eul[array_index];
+ }
+ else if (strstr(identifier, "rotation_quaternion")) {
+ float mat3[3][3], quat[4];
+
+ copy_m3_m4(mat3, tmat);
+ mat3_to_quat_is_ok(quat, mat3);
+
+ return quat[array_index];
+ }
+ else if (strstr(identifier, "rotation_axis_angle")) {
+ float axis[3], angle;
+
+ mat4_to_axis_angle(axis, &angle, tmat);
+
+ /* w = 0, x,y,z = 1,2,3 */
+ if (array_index == 0)
+ return angle;
+ else
+ return axis[array_index - 1];
+ }
+ else if (strstr(identifier, "scale")) {
+ float scale[3];
+
+ mat4_to_size(scale, tmat);
+
+ return scale[array_index];
}
/* as the function hasn't returned yet, read value from system in the default way */
@@ -1208,7 +1215,6 @@ static int modify_key_op_poll(bContext *C)
static int insert_key_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks = NULL;
int type = RNA_enum_get(op->ptr, "type");
@@ -1254,9 +1260,6 @@ static int insert_key_exec(bContext *C, wmOperator *op)
else
BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes");
- /* send updates */
- DAG_ids_flush_update(bmain, 0);
-
return OPERATOR_FINISHED;
}
@@ -1364,7 +1367,6 @@ void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)
static int delete_key_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks = NULL;
int type = RNA_enum_get(op->ptr, "type");
@@ -1410,9 +1412,6 @@ static int delete_key_exec(bContext *C, wmOperator *op)
else
BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes");
- /* send updates */
- DAG_ids_flush_update(bmain, 0);
-
return OPERATOR_FINISHED;
}
@@ -1452,8 +1451,6 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot)
static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
-
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
/* just those in active action... */
@@ -1498,12 +1495,11 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
}
/* update... */
- ob->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
/* send updates */
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
return OPERATOR_FINISHED;
@@ -1529,7 +1525,6 @@ void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
static int delete_key_v3d_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
float cfra = (float)CFRA;
@@ -1556,12 +1551,11 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op)
/* report success (or failure) */
BKE_reportf(op->reports, RPT_INFO, "Object '%s' successfully had %d keyframes removed", id->name + 2, success);
- ob->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
/* send updates */
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
return OPERATOR_FINISHED;
@@ -1589,7 +1583,6 @@ void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
static int insert_key_button_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
@@ -1648,8 +1641,6 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
/* send updates */
uiContextAnimUpdate(C);
- DAG_ids_flush_update(bmain, 0);
-
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
@@ -1679,7 +1670,6 @@ void ANIM_OT_keyframe_insert_button(wmOperatorType *ot)
static int delete_key_button_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
@@ -1721,8 +1711,6 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
/* send updates */
uiContextAnimUpdate(C);
- DAG_ids_flush_update(bmain, 0);
-
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
@@ -1753,7 +1741,6 @@ void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
static int clear_key_button_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
char *path;
@@ -1793,8 +1780,6 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
/* send updates */
uiContextAnimUpdate(C);
- DAG_ids_flush_update(bmain, 0);
-
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 28db7bf572d..4e8d7bdafe5 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -289,7 +289,6 @@ void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
static int add_keyingset_button_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks = NULL;
PropertyRNA *prop = NULL;
@@ -360,7 +359,6 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
if (success) {
/* send updates */
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
/* show notification/report header, so that users notice that something changed */
@@ -392,7 +390,6 @@ void ANIM_OT_keyingset_button_add(wmOperatorType *ot)
static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks = NULL;
PropertyRNA *prop = NULL;
@@ -442,7 +439,6 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
if (success) {
/* send updates */
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
/* show warning */
@@ -1006,7 +1002,8 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
{
Object *ob = (Object *)ksp->id;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; // XXX: only object transforms only?
+ // XXX: only object transforms?
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
break;
}
diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h
index 06ee3fbb64c..71109574fe0 100644
--- a/source/blender/editors/armature/BIF_generate.h
+++ b/source/blender/editors/armature/BIF_generate.h
@@ -40,9 +40,10 @@ int nextFixedSubdivision(struct ToolSettings *toolsettings, struct BArcIterator
int nextLengthSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
int nextAdaptativeSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
-struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion);
+struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter,
+ float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion);
-void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[][4], float tmat[][3]);
+void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[4][4], float tmat[3][3]);
#endif /* __BIF_GENERATE_H__ */
diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript
index ba375f30093..1911d76a894 100644
--- a/source/blender/editors/armature/SConscript
+++ b/source/blender/editors/armature/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index e801d3689e5..574cf18773b 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -52,6 +52,8 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLF_translation.h"
+
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -563,7 +565,9 @@ void docenter_armature(Scene *scene, Object *ob, float cursor[3], int centermode
add_v3_v3(cent, ebone->head);
add_v3_v3(cent, ebone->tail);
}
- mul_v3_fl(cent, 1.0f / (float)total);
+ if (total) {
+ mul_v3_fl(cent, 1.0f / (float)total);
+ }
}
else {
float min[3], max[3];
@@ -812,7 +816,7 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
pose = ob->pose;
for (pchant = pose->chanbase.first; pchant; pchant = pchant->next) {
for (con = pchant->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -859,7 +863,7 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
/* fix object-level constraints */
if (ob != srcArm) {
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1002,7 +1006,7 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene); /* because we removed object(s) */
+ DAG_relations_tag_update(bmain); /* because we removed object(s) */
ED_armature_from_edit(ob);
ED_armature_edit_free(ob);
@@ -1032,7 +1036,7 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
if (ob->type == OB_ARMATURE) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1070,7 +1074,7 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
/* fix object-level constraints */
if (ob != origArm) {
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1215,7 +1219,7 @@ static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op))
/* 2) duplicate base */
newbase = ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
newob = newbase->object;
newbase->flag &= ~SELECT;
@@ -1712,7 +1716,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
}
else {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2002,7 +2006,7 @@ float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const short
sub_v3_v3v3(nor, bone->tail, bone->head);
vec_roll_to_mat3(nor, 0.0f, mat);
-
+
/* check the bone isn't aligned with the axis */
if (!is_zero_v3(align_axis) && angle_v3v3(align_axis, mat[2]) > FLT_EPSILON) {
float vec[3], align_axis_proj[3], roll;
@@ -2062,7 +2066,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
float cursor_local[3];
- float *cursor = give_cursor(scene, v3d);
+ const float *cursor = give_cursor(scene, v3d);
copy_v3_v3(cursor_local, cursor);
@@ -2256,6 +2260,7 @@ void undo_push_armature(bContext *C, const char *name)
/* *************** Adding stuff in editmode *************** */
/* default bone add, returns it selected, but without tail set */
+/* XXX should be used everywhere, now it mallocs bones still locally in functions */
EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name)
{
EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone");
@@ -2323,7 +2328,8 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
View3D *v3d;
bArmature *arm;
EditBone *ebone, *newbone, *flipbone;
- float *curs, mat[3][3], imat[3][3];
+ float mat[3][3], imat[3][3];
+ const float *curs;
int a, to_root = 0;
Object *obedit;
Scene *scene;
@@ -2418,7 +2424,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *e
Scene *scene;
ARegion *ar;
View3D *v3d;
- float *fp = NULL, tvec[3], oldcurs[3], mval_f[2];
+ float *fp, tvec[3], oldcurs[3], mval_f[2];
int retv;
scene = CTX_data_scene(C);
@@ -2521,7 +2527,7 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
/* does this constraint have a subtarget in
* this armature?
*/
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -3409,7 +3415,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
copy_v3_v3(newbone->tail, newbone->head);
newbone->parent = ebone;
- newbone->flag = ebone->flag & BONE_TIPSEL; // copies it, in case mirrored bone
+ newbone->flag = ebone->flag & (BONE_TIPSEL | BONE_RELATIVE_PARENTING); // copies it, in case mirrored bone
if (newbone->parent) newbone->flag |= BONE_CONNECTED;
}
@@ -3656,6 +3662,16 @@ void ARMATURE_OT_subdivide(wmOperatorType *ot)
* easy to retrieve any hierarchical/chain relationships which are necessary for
* this to be done easily.
*/
+
+/* helper to clear BONE_TRANSFORM flags */
+static void armature_clear_swap_done_flags(bArmature *arm)
+{
+ EditBone *ebone;
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ ebone->flag &= ~BONE_TRANSFORM;
+ }
+}
static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -3667,9 +3683,16 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
/* get chains of bones (ends on chains) */
chains_find_tips(arm->edbo, &chains);
if (chains.first == NULL) return OPERATOR_CANCELLED;
-
+
+ /* ensure that mirror bones will also be operated on */
armature_tag_select_mirrored(arm);
-
+
+ /* clear BONE_TRANSFORM flags
+ * - used to prevent duplicate/cancelling operations from occurring [#34123]
+ * - BONE_DONE cannot be used here as that's already used for mirroring
+ */
+ armature_clear_swap_done_flags(arm);
+
/* loop over chains, only considering selected and visible bones */
for (chain = chains.first; chain; chain = chain->next) {
EditBone *ebo, *child = NULL, *parent = NULL;
@@ -3682,51 +3705,59 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
*/
parent = ebo->parent;
- /* only if selected and editable */
- if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {
- /* swap head and tail coordinates */
- SWAP(float, ebo->head[0], ebo->tail[0]);
- SWAP(float, ebo->head[1], ebo->tail[1]);
- SWAP(float, ebo->head[2], ebo->tail[2]);
-
- /* do parent swapping:
- * - use 'child' as new parent
- * - connected flag is only set if points are coincidental
- */
- ebo->parent = child;
- if ((child) && equals_v3v3(ebo->head, child->tail))
- ebo->flag |= BONE_CONNECTED;
- else
- ebo->flag &= ~BONE_CONNECTED;
-
- /* get next bones
- * - child will become the new parent of next bone
- */
- child = ebo;
- }
- else {
- /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it
- * as it will be facing in opposite direction
- */
- if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
- ebo->parent = NULL;
- ebo->flag &= ~BONE_CONNECTED;
+ /* skip bone if already handled... [#34123] */
+ if ((ebo->flag & BONE_TRANSFORM) == 0) {
+ /* only if selected and editable */
+ if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {
+ /* swap head and tail coordinates */
+ SWAP(float, ebo->head[0], ebo->tail[0]);
+ SWAP(float, ebo->head[1], ebo->tail[1]);
+ SWAP(float, ebo->head[2], ebo->tail[2]);
+
+ /* do parent swapping:
+ * - use 'child' as new parent
+ * - connected flag is only set if points are coincidental
+ */
+ ebo->parent = child;
+ if ((child) && equals_v3v3(ebo->head, child->tail))
+ ebo->flag |= BONE_CONNECTED;
+ else
+ ebo->flag &= ~BONE_CONNECTED;
+
+ /* get next bones
+ * - child will become the new parent of next bone
+ */
+ child = ebo;
+ }
+ else {
+ /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it
+ * as it will be facing in opposite direction
+ */
+ if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
+ ebo->parent = NULL;
+ ebo->flag &= ~BONE_CONNECTED;
+ }
+
+ /* get next bones
+ * - child will become new parent of next bone (not swapping occurred,
+ * so set to NULL to prevent infinite-loop)
+ */
+ child = NULL;
}
- /* get next bones
- * - child will become new parent of next bone (not swapping occurred,
- * so set to NULL to prevent infinite-loop)
- */
- child = NULL;
+ /* tag as done (to prevent double-swaps) */
+ ebo->flag |= BONE_TRANSFORM;
}
}
}
/* free chains */
BLI_freelistN(&chains);
-
+
+ /* clear temp flags */
+ armature_clear_swap_done_flags(arm);
armature_tag_unselect(arm);
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
@@ -3887,7 +3918,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
{
EditBone *actbone = CTX_data_active_bone(C);
- uiPopupMenu *pup = uiPupMenuBegin(C, "Make Parent ", ICON_NONE);
+ uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
int allchildbones = 0;
@@ -4347,7 +4378,7 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "direction", direction_items,
BONE_SELECT_PARENT, "Direction", "");
- RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/* ***************** EditBone Alignment ********************* */
@@ -4995,13 +5026,18 @@ 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);
+ int defbase_add;
/* Traverse the bone list, trying to create empty vertex
* groups corresponding to the bone.
*/
- bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
+ defbase_add = bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
- if (ob->type == OB_MESH)
- ED_vgroup_data_create(ob->data);
+ if (defbase_add) {
+ /* its possible there are DWeight's outside the range of the current
+ * objects deform groups, in this case the new groups wont be empty [#33889] */
+ ED_vgroup_data_clamp_range(ob->data, defbase_tot);
+ }
}
else if (mode == ARM_GROUPS_ENVELOPE || mode == ARM_GROUPS_AUTO) {
/* Traverse the bone list, trying to create vertex groups
@@ -5531,7 +5567,7 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldnam
bConstraintTarget *ct;
for (curcon = conlist->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
index d9c7e78c01e..979c352c4b2 100644
--- a/source/blender/editors/armature/editarmature_generate.c
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -50,7 +50,7 @@
#include "armature_intern.h"
#include "BIF_generate.h"
-void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[][4]), float tmat[][3])
+void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[4][4]), float tmat[3][3])
{
if (no != NULL && !is_zero_v3(no)) {
float normal[3];
@@ -257,7 +257,8 @@ int nextLengthSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int st
return -1;
}
-EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion)
+EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter,
+ float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion)
{
EditBone *lastBone = NULL;
EditBone *child = NULL;
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 68cfc7fb8c0..3e34a4c6808 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -725,7 +725,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* DO SOME MAGIC HERE */
for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -850,7 +850,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* DO SOME MAGIC HERE */
for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1830,7 +1830,9 @@ static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEd
}
#endif
-static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge, float *vec0, float *vec1, float *vec2, int i1, int i2, float angle_weight, float length_weight, float distance_weight)
+static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge,
+ float *vec0, float *vec1, float *vec2, int i1, int i2,
+ float angle_weight, float length_weight, float distance_weight)
{
float vec_second[3], vec_first[3];
float length2;
@@ -1878,7 +1880,9 @@ static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions,
}
}
-static MemoNode *solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache, int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, int joints_left, float angle_weight, float length_weight, float distance_weight)
+static MemoNode *solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache,
+ int nb_joints, int nb_positions, int previous, int current, RigEdge *edge,
+ int joints_left, float angle_weight, float length_weight, float distance_weight)
{
MemoNode *node;
int index = indexMemoNode(nb_positions, previous, current, joints_left);
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index f9cf4a29269..b61aa86a52f 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -361,7 +361,7 @@ static void sk_autoname(bContext *C, ReebArc *arc)
}
}
-static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
+static ReebNode *sk_pointToNode(SK_Point *pt, float imat[4][4], float tmat[3][3])
{
ReebNode *node;
@@ -375,7 +375,7 @@ static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
return node;
}
-static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
+static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[4][4], float tmat[3][3])
{
ReebArc *arc;
int i;
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 9152ea8e198..a7e84d590b5 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -649,7 +649,9 @@ static float heat_limit_weight(float weight)
return weight;
}
-void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, const char **err_str)
+void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
+ bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
+ float (*root)[3], float (*tip)[3], int *selected, const char **err_str)
{
LaplacianSystem *sys;
MPoly *mp;
@@ -666,8 +668,8 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
*err_str = NULL;
/* count triangles and create mask */
- if ((use_face_sel = ((me->editflag & ME_EDIT_PAINT_MASK) != 0)) ||
- (use_vert_sel = ((me->editflag & ME_EDIT_VERT_SEL) != 0)))
+ if ((use_face_sel = ((me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0)) ||
+ (use_vert_sel = ((me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0)))
{
mask = MEM_callocN(sizeof(int) * me->totvert, "heat_bone_weighting mask");
@@ -862,7 +864,7 @@ static void rigid_add_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2
rigid_add_half_edge_to_R(sys, v2, v1, w);
}
-static void rigid_orthogonalize_R(float R[][3])
+static void rigid_orthogonalize_R(float R[3][3])
{
HMatrix M, Q, S;
@@ -1120,7 +1122,7 @@ typedef struct MeshDeformBind {
typedef struct MeshDeformIsect {
float start[3];
float vec[3];
- float labda;
+ float lambda;
void *face;
int isect;
@@ -1227,7 +1229,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
copy_v3_v3(hit->co, co);
isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f);
- isec->labda = dist;
+ isec->lambda = dist;
isec->face = mf;
}
}
@@ -1245,7 +1247,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float
/* setup isec */
memset(&isect_mdef, 0, sizeof(isect_mdef));
- isect_mdef.labda = 1e10f;
+ isect_mdef.lambda = 1e10f;
add_v3_v3v3(isect_mdef.start, co1, epsilon);
add_v3_v3v3(end, co2, epsilon);
@@ -1256,7 +1258,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float
if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec,
0.0, &hit, harmonic_ray_callback, data) != -1)
{
- len = isect_mdef.labda;
+ len = isect_mdef.lambda;
isect_mdef.face = mface = mface1 + hit.index;
/* create MDefBoundIsect */
@@ -1767,7 +1769,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi");
mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect");
mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound");
- mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6);
+ mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6);
mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
@@ -1956,7 +1958,7 @@ static void heat_weighting_bind(Scene *scene, DerivedMesh *dm, MeshDeformModifie
}
#endif
-void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4])
+void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[4][4])
{
MeshDeformBind mdb;
MVert *mvert;
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c
index ae3d496b641..48c0a4a38c3 100644
--- a/source/blender/editors/armature/poselib.c
+++ b/source/blender/editors/armature/poselib.c
@@ -54,6 +54,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_depsgraph.h"
+#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_object.h"
@@ -196,7 +197,7 @@ static bAction *poselib_init_new(Object *ob)
/* init object's poselib action (unlink old one if there) */
if (ob->poselib)
id_us_min(&ob->poselib->id);
- ob->poselib = add_empty_action("PoseLib");
+ ob->poselib = add_empty_action(G.main, "PoseLib");
return ob->poselib;
}
@@ -662,7 +663,7 @@ static int poselib_rename_exec(bContext *C, wmOperator *op)
}
/* get index (and pointer) of pose to remove */
- marker = BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose"));
+ marker = BLI_findlink(&act->markers, RNA_enum_get(op->ptr, "pose"));
if (marker == NULL) {
BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
return OPERATOR_CANCELLED;
@@ -687,9 +688,6 @@ static int poselib_rename_exec(bContext *C, wmOperator *op)
void POSELIB_OT_pose_rename(wmOperatorType *ot)
{
PropertyRNA *prop;
- static EnumPropertyItem prop_poses_dummy_types[] = {
- {0, NULL, 0, NULL, NULL}
- };
/* identifiers */
ot->name = "PoseLib Rename Pose";
@@ -707,7 +705,7 @@ void POSELIB_OT_pose_rename(wmOperatorType *ot)
/* properties */
/* NOTE: name not pose is the operator's "main" property, so that it will get activated in the popup for easy renaming */
ot->prop = RNA_def_string(ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose");
- prop = RNA_def_enum(ot->srna, "pose", prop_poses_dummy_types, 0, "Pose", "The pose to rename");
+ prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to rename");
RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 576e5983d16..c7d1e428355 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -238,7 +238,7 @@ static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *UNU
/* show popup dialog to allow editing of range... */
// FIXME: hardcoded dimensions here are just arbitrary
- return WM_operator_props_dialog_popup(C, op, 200, 200);
+ return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
}
/* For the object with pose/action: create path curves for selected bones
@@ -417,7 +417,7 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op
{
if (pchan->bone->flag & BONE_SELECTED) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -576,7 +576,7 @@ void POSE_OT_select_hierarchy(wmOperatorType *ot)
/* props */
ot->prop = RNA_def_enum(ot->srna, "direction", direction_items, BONE_SELECT_PARENT, "Direction", "");
- RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/* ******************* select grouped operator ************* */
@@ -925,7 +925,7 @@ static void pose_copy_menu(Scene *scene)
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
- copy_constraints(&tmp_constraints, &pchanact->constraints, TRUE);
+ BKE_copy_constraints(&tmp_constraints, &pchanact->constraints, TRUE);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
bConstraint *con;
@@ -1034,7 +1034,7 @@ static void pose_copy_menu(Scene *scene)
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
- copy_constraints(&tmp_constraints, &const_copy, TRUE);
+ BKE_copy_constraints(&tmp_constraints, &const_copy, TRUE);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
/* add proxy-local tags */
for (con = tmp_constraints.first; con; con = con->next)
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index b1bf13db69b..1b5c550df11 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -634,7 +634,7 @@ static void mergeArcBuckets(ReebArc *aDst, ReebArc *aSrc, float start, float end
if (aDst->bcount > 0 && aSrc->bcount > 0) {
int indexDst = 0, indexSrc = 0;
- start = MAX3(start, aDst->buckets[0].val, aSrc->buckets[0].val);
+ start = max_fff(start, aDst->buckets[0].val, aSrc->buckets[0].val);
while (indexDst < aDst->bcount && aDst->buckets[indexDst].val < start) {
indexDst++;
diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt
index 25df17d232a..c38ded49830 100644
--- a/source/blender/editors/curve/CMakeLists.txt
+++ b/source/blender/editors/curve/CMakeLists.txt
@@ -20,6 +20,7 @@
set(INC
../include
+ ../../blenfont
../../blenkernel
../../blenlib
../../blenloader
@@ -42,4 +43,8 @@ set(SRC
curve_intern.h
)
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_curve "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/curve/SConscript b/source/blender/editors/curve/SConscript
index 95dd7fc6233..21c6a3732fa 100644
--- a/source/blender/editors/curve/SConscript
+++ b/source/blender/editors/curve/SConscript
@@ -1,11 +1,42 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+defs = []
+
+incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../bmesh ../../gpu ../../blenloader'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
-env.BlenderLib ( 'bf_editors_curve', sources, Split(incs), [], libtype=['core'], priority=[45] )
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
+env.BlenderLib ( 'bf_editors_curve', sources, Split(incs), defs, libtype=['core'], priority=[45] )
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 23fed4ce8fc..d01e5c5d9bf 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -53,6 +53,8 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
@@ -1022,13 +1024,12 @@ static int curve_is_animated(Curve *cu)
return ad && (ad->action || ad->drivers.first);
}
-static void fcurve_path_rename(AnimData *ad, char *orig_rna_path, char *rna_path, ListBase *orig_curves, ListBase *curves)
+static void fcurve_path_rename(AnimData *adt, char *orig_rna_path, char *rna_path, ListBase *orig_curves, ListBase *curves)
{
FCurve *fcu, *nfcu, *nextfcu;
int len = strlen(orig_rna_path);
- fcu = orig_curves->first;
- while (fcu) {
+ for (fcu = orig_curves->first; fcu; fcu = nextfcu) {
nextfcu = fcu->next;
if (!strncmp(fcu->rna_path, orig_rna_path, len)) {
char *spath, *suffix = fcu->rna_path + len;
@@ -1038,26 +1039,25 @@ static void fcurve_path_rename(AnimData *ad, char *orig_rna_path, char *rna_path
BLI_addtail(curves, nfcu);
if (fcu->grp) {
- action_groups_remove_channel(ad->action, fcu);
- action_groups_add_channel(ad->action, fcu->grp, nfcu);
+ action_groups_remove_channel(adt->action, fcu);
+ action_groups_add_channel(adt->action, fcu->grp, nfcu);
}
- else if (ad->action && &ad->action->curves == orig_curves)
- BLI_remlink(&ad->action->curves, fcu);
+ else if ((adt->action) && (&adt->action->curves == orig_curves))
+ BLI_remlink(&adt->action->curves, fcu);
else
- BLI_remlink(&ad->drivers, fcu);
+ BLI_remlink(&adt->drivers, fcu);
free_fcurve(fcu);
MEM_freeN(spath);
}
- fcu = nextfcu;
}
}
-static void fcurve_remove(AnimData *ad, ListBase *orig_curves, FCurve *fcu)
+static void fcurve_remove(AnimData *adt, ListBase *orig_curves, FCurve *fcu)
{
- if (orig_curves == &ad->drivers) BLI_remlink(&ad->drivers, fcu);
- else action_groups_remove_channel(ad->action, fcu);
+ if (orig_curves == &adt->drivers) BLI_remlink(&adt->drivers, fcu);
+ else action_groups_remove_channel(adt->action, fcu);
free_fcurve(fcu);
}
@@ -1073,7 +1073,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
ListBase curves = {NULL, NULL};
FCurve *fcu, *next;
- while (nu) {
+ for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
a = nu->pntsu;
@@ -1126,8 +1126,6 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
pt_index++;
}
}
- nu = nu->next;
- nu_index++;
}
/* remove paths for removed control points
@@ -1144,9 +1142,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
}
}
- nu_index = 0;
- nu = editnurb->nurbs.first;
- while (nu) {
+ for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
keyIndex = NULL;
if (nu->pntsu) {
if (nu->bezt) keyIndex = getCVKeyIndex(editnurb, &nu->bezt[0]);
@@ -1158,9 +1154,6 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d]", keyIndex->nu_index);
fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
}
-
- nu_index++;
- nu = nu->next;
}
/* the remainders in orig_curves can be copied back (like follow path) */
@@ -1288,8 +1281,24 @@ void CU_deselect_all(Object *obedit)
ListBase *editnurb = object_editcurve_get(obedit);
if (editnurb) {
- selectend_nurb(obedit, FIRST, 0, DESELECT); /* set first control points as unselected */
- select_adjacent_cp(editnurb, 1, 1, DESELECT); /* cascade selection */
+ Nurb *nu;
+ int a;
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ BezTriple *bezt;
+ for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+ bezt->f1 &= ~SELECT;
+ bezt->f2 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp;
+ for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+ bp->f1 &= ~SELECT;
+ }
+ }
+ }
}
}
@@ -1298,8 +1307,27 @@ void CU_select_all(Object *obedit)
ListBase *editnurb = object_editcurve_get(obedit);
if (editnurb) {
- selectend_nurb(obedit, FIRST, 0, SELECT); /* set first control points as unselected */
- select_adjacent_cp(editnurb, 1, 1, SELECT); /* cascade selection */
+ Nurb *nu;
+ int a;
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ BezTriple *bezt;
+ for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+ if (bezt->hide == 0) {
+ bezt->f1 |= SELECT;
+ bezt->f2 |= SELECT;
+ bezt->f3 |= SELECT;
+ }
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp;
+ for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+ if (bp->hide == 0)
+ bp->f1 |= SELECT;
+ }
+ }
+ }
}
}
@@ -1369,7 +1397,7 @@ static int separate_exec(bContext *C, wmOperator *op)
/* 1. duplicate the object and data */
newbase = ED_object_add_duplicate(bmain, scene, oldbase, 0); /* 0 = fully linked */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
ED_base_object_select(newbase, BA_DESELECT);
newob = newbase->object;
@@ -1493,7 +1521,7 @@ static void setflagsNurb(ListBase *editnurb, short flag)
}
}
-static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][3])
+static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[3][3])
{
/* all verts with (flag & 'flag') rotate */
Nurb *nu;
@@ -2008,11 +2036,12 @@ static int switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
EditNurb *editnurb = cu->editnurb;
Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next)
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
if (isNurbsel(nu)) {
BKE_nurb_direction_switch(nu);
keyData_switchDirectionNurb(cu, nu);
}
+ }
if (ED_curve_updateAnimPaths(obedit->data))
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
@@ -2455,10 +2484,11 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
/**************** select start/end operators **************/
-/* (de)selects first or last of visible part of each Nurb depending on selFirst */
-/* selFirst: defines the end of which to select */
-/* doswap: defines if selection state of each first/last control point is swapped */
-/* selstatus: selection status in case doswap is false */
+/* (de)selects first or last of visible part of each Nurb depending on selFirst
+ * selFirst: defines the end of which to select
+ * doswap: defines if selection state of each first/last control point is swapped
+ * selstatus: selection status in case doswap is false
+ */
void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatus)
{
ListBase *editnurb = object_editcurve_get(obedit);
@@ -2532,7 +2562,7 @@ void CURVE_OT_de_select_first(wmOperatorType *ot)
/* identifiers */
ot->name = "(De)select First";
ot->idname = "CURVE_OT_de_select_first";
- ot->description = "(De)select first of visible part of each Nurb";
+ ot->description = "(De)select first of visible part of each NURBS";
/* api cfirstbacks */
ot->exec = de_select_first_exec;
@@ -2557,7 +2587,7 @@ void CURVE_OT_de_select_last(wmOperatorType *ot)
/* identifiers */
ot->name = "(De)select Last";
ot->idname = "CURVE_OT_de_select_last";
- ot->description = "(De)select last of visible part of each Nurb";
+ ot->description = "(De)select last of visible part of each NURBS";
/* api clastbacks */
ot->exec = de_select_last_exec;
@@ -4278,7 +4308,7 @@ int mouse_nurb(bContext *C, const int mval[2], int extend, int deselect, int tog
/* 'cent' is in object space and 'dvec' in worldspace.
*/
-static int spin_nurb(float viewmat[][4], Object *obedit, float *axis, float *cent)
+static int spin_nurb(float viewmat[4][4], Object *obedit, float *axis, float *cent)
{
Curve *cu = (Curve *)obedit->data;
ListBase *editnurb = object_editcurve_get(obedit);
@@ -4897,7 +4927,7 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->pntsu > 1 || nu->pntsv > 1) {
if (nu->type == CU_NURBS) {
- pup = uiPupMenuBegin(C, "Direction", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Direction"), ICON_NONE);
layout = uiPupMenuLayout(pup);
uiItemsEnumO(layout, op->type->idname, "direction");
uiPupMenuEnd(C, pup);
@@ -5519,7 +5549,7 @@ void CURVE_OT_select_random(wmOperatorType *ot)
/* properties */
RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, "Percent", "Percentage of elements to select randomly", 0.f, 100.0f);
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend Selection", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/********************* every nth number of point *******************/
@@ -6023,14 +6053,14 @@ static int delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
uiLayout *layout;
if (obedit->type == OB_SURF) {
- pup = uiPupMenuBegin(C, "Delete", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Delete"), ICON_NONE);
layout = uiPupMenuLayout(pup);
uiItemEnumO_ptr(layout, op->type, NULL, 0, "type", 0);
uiItemEnumO_ptr(layout, op->type, NULL, 0, "type", 2);
uiPupMenuEnd(C, pup);
}
else {
- pup = uiPupMenuBegin(C, "Delete", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Delete"), ICON_NONE);
layout = uiPupMenuLayout(pup);
uiItemsEnumO(layout, op->type->idname, "type");
uiPupMenuEnd(C, pup);
@@ -6190,7 +6220,7 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
cu = ob->data;
BLI_movelisttolist(&cu->nurb, &tempbase);
- DAG_scene_sort(bmain, scene); // because we removed object(s), call before editmode!
+ DAG_relations_tag_update(bmain); // because we removed object(s), call before editmode!
ED_object_enter_editmode(C, EM_WAITCURSOR);
ED_object_exit_editmode(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 257dfca051f..af6b90a9958 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -1070,21 +1070,13 @@ void FONT_OT_change_character(wmOperatorType *ot)
/******************* line break operator ********************/
-static int line_break_exec(bContext *C, wmOperator *op)
+static int line_break_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
- EditFont *ef = cu->editfont;
- const int ctrl = RNA_boolean_get(op->ptr, "ctrl");
- if (ctrl) {
- insert_into_textbuf(obedit, 1);
- if (ef->textbuf[cu->pos] != '\n')
- insert_into_textbuf(obedit, '\n');
- }
- else
- insert_into_textbuf(obedit, '\n');
+ insert_into_textbuf(obedit, '\n');
cu->selstart = cu->selend = 0;
@@ -1106,9 +1098,6 @@ void FONT_OT_line_break(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_boolean(ot->srna, "ctrl", 0, "Ctrl", ""); // XXX what is this?
}
/******************* delete operator **********************/
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index ec20e2d3d09..8d108644470 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -43,10 +43,12 @@ if(WITH_BLENDER)
# blends
data_to_c_simple(../../../../release/datafiles/preview.blend SRC)
+ data_to_c_simple(../../../../release/datafiles/preview_cycles.blend SRC)
# images
data_to_c_simple(../../../../release/datafiles/splash.png SRC)
- data_to_c_simple(../../../../release/datafiles/blender_icons.png SRC)
+ data_to_c_simple(../../../../release/datafiles/blender_icons16.png SRC)
+ data_to_c_simple(../../../../release/datafiles/blender_icons32.png SRC)
data_to_c_simple(../../../../release/datafiles/prvicons.png SRC)
# brushes
@@ -80,6 +82,33 @@ if(WITH_BLENDER)
data_to_c_simple(../../../../release/datafiles/brushicons/thumb.png SRC)
data_to_c_simple(../../../../release/datafiles/brushicons/twist.png SRC)
data_to_c_simple(../../../../release/datafiles/brushicons/vertexdraw.png SRC)
+
+ # matcap
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc01.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc02.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc03.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc04.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc05.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc06.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc07.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc08.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc09.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc10.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc11.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc12.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc13.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc14.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc15.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc16.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc17.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc18.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc19.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc20.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc21.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc22.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc23.jpg SRC)
+ data_to_c_simple(../../../../release/datafiles/matcaps/mc24.jpg SRC)
+
endif()
data_to_c_simple(../../../../release/datafiles/startup.blend SRC)
diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript
index e0816f783d3..c17ab386fe6 100644
--- a/source/blender/editors/datafiles/SConscript
+++ b/source/blender/editors/datafiles/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
# all source generated now
@@ -14,11 +40,13 @@ sources.extend((
os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"),
os.path.join(env['DATA_SOURCES'], "splash.png.c"),
- os.path.join(env['DATA_SOURCES'], "blender_icons.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"),
os.path.join(env['DATA_SOURCES'], "prvicons.png.c"),
os.path.join(env['DATA_SOURCES'], "startup.blend.c"),
os.path.join(env['DATA_SOURCES'], "preview.blend.c"),
+ os.path.join(env['DATA_SOURCES'], "preview_cycles.blend.c"),
os.path.join(env['DATA_SOURCES'], "add.png.c"),
os.path.join(env['DATA_SOURCES'], "blob.png.c"),
@@ -50,6 +78,32 @@ sources.extend((
os.path.join(env['DATA_SOURCES'], "thumb.png.c"),
os.path.join(env['DATA_SOURCES'], "twist.png.c"),
os.path.join(env['DATA_SOURCES'], "vertexdraw.png.c"),
+
+ os.path.join(env['DATA_SOURCES'], "mc01.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc02.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc03.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc04.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc05.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc06.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc07.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc08.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc09.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc10.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc11.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc12.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc13.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc14.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc15.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc16.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc17.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc18.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc19.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc20.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc21.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc22.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc23.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc24.jpg.c"),
+
))
env.BlenderLib ( 'bf_editor_datafiles', sources, Split(incs), [], libtype=['core', 'player'], priority=[235, 30] )
diff --git a/source/blender/editors/gpencil/SConscript b/source/blender/editors/gpencil/SConscript
index 9d92a238eb7..f72e124e862 100644
--- a/source/blender/editors/gpencil/SConscript
+++ b/source/blender/editors/gpencil/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 11e07584405..09a7890a539 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -27,7 +27,6 @@
* \ingroup edgpencil
*/
-
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -45,8 +44,10 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
+#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
index 8a3c996a481..0aa109a0aef 100644
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ b/source/blender/editors/gpencil/gpencil_buttons.c
@@ -312,6 +312,13 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin
}
}
+void 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 gpencil_panel_standard(const bContext *C, Panel *pa)
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index e9ca7392752..671adfb8d1e 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -451,7 +451,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
copy_v3_v3(p3d, &pt->x);
}
else {
- float *fp = give_cursor(scene, v3d);
+ const float *fp = give_cursor(scene, v3d);
float mvalf[2];
/* get screen coordinate */
@@ -1387,12 +1387,15 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- bGPDframe *gpf = gpencil_layer_getframe(gpl, CFRA, 0);
- bGPDstroke *gps = gpf->strokes.first;
+ bGPDframe *gpf = NULL;
+ bGPDstroke *gps = NULL;
bGPDspoint *pt;
double base_time, cur_time, prev_time = -1.0;
int i, 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) {
@@ -1438,11 +1441,19 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN
static int gp_convert_poll(bContext *C)
{
bGPdata *gpd = gpencil_data_get_active(C);
+ bGPDlayer *gpl = NULL;
+ bGPDframe *gpf = NULL;
ScrArea *sa = CTX_wm_area(C);
Scene *scene = CTX_data_scene(C);
- /* only if there's valid data, and the current view is 3D View */
- return ((sa && sa->spacetype == SPACE_VIEW3D) && gpencil_layer_getactive(gpd) && (scene->obedit == NULL));
+ /* 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!
+ */
+ return ((sa && sa->spacetype == SPACE_VIEW3D) &&
+ (gpl = gpencil_layer_getactive(gpd)) &&
+ (gpf = gpencil_layer_getframe(gpl, CFRA, 0)) &&
+ (gpf->strokes.first) &&
+ (scene->obedit == NULL));
}
static int gp_convert_layer_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 8fdca730674..8cd2bd861bc 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -39,6 +39,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "PIL_time.h"
#include "BKE_gpencil.h"
@@ -208,7 +210,7 @@ static int gpencil_project_check(tGPsdata *p)
static void gp_get_3d_reference(tGPsdata *p, float vec[3])
{
View3D *v3d = p->sa->spacedata.first;
- float *fp = give_cursor(p->scene, v3d);
+ const float *fp = give_cursor(p->scene, v3d);
/* the reference point used depends on the owner... */
#if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */
@@ -1457,28 +1459,27 @@ static void gpencil_draw_status_indicators(tGPsdata *p)
case GP_STATUS_PAINTING:
/* only print this for paint-sessions, otherwise it gets annoying */
if (GPENCIL_SKETCH_SESSIONS_ON(p->scene))
- ED_area_headerprint(p->sa, "Grease Pencil: Drawing/erasing stroke... Release to end stroke");
+ ED_area_headerprint(p->sa, IFACE_("Grease Pencil: Drawing/erasing stroke... Release to end stroke"));
break;
case GP_STATUS_IDLING:
/* print status info */
switch (p->paintmode) {
case GP_PAINTMODE_ERASER:
- ED_area_headerprint(p->sa,
- "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase |"
- " ESC/Enter to end");
+ ED_area_headerprint(p->sa, IFACE_("Grease Pencil Erase Session: Hold and drag LMB or RMB to erase |"
+ " ESC/Enter to end"));
break;
case GP_PAINTMODE_DRAW_STRAIGHT:
- ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | "
- "ESC/Enter to end");
+ ED_area_headerprint(p->sa, IFACE_("Grease Pencil Line Session: Hold and drag LMB to draw | "
+ "ESC/Enter to end"));
break;
case GP_PAINTMODE_DRAW:
- ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | "
- "ESC/Enter to end");
+ 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, "Grease Pencil Session: ESC/Enter to end");
+ ED_area_headerprint(p->sa, IFACE_("Grease Pencil Session: ESC/Enter to end"));
break;
}
break;
@@ -1564,8 +1565,8 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
p->curtime = PIL_check_seconds_timer();
/* handle pressure sensitivity (which is supplied by tablets) */
- if (event->custom == EVT_DATA_TABLET) {
- wmTabletData *wmtab = event->customdata;
+ if (event->tablet_data) {
+ wmTabletData *wmtab = event->tablet_data;
tablet = (wmtab->Active != EVT_TABLET_NONE);
p->pressure = wmtab->Pressure;
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h
index 479e0b65177..cdf9b71972d 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/editors/include/BIF_gl.h
@@ -35,6 +35,14 @@
#include "GL/glew.h"
+#ifdef __APPLE__
+
+/* hacking pointsize and linewidth */
+#define glPointSize(f) glPointSize(U.pixelsize*(f))
+#define glLineWidth(f) glLineWidth(U.pixelsize*(f))
+
+#endif
+
/*
* these should be phased out. cpack should be replaced in
* code with calls to glColor3ub. - zr
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 577113927d1..31f89063f05 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -51,10 +51,10 @@ void fdrawcheckerboard(float x1, float y1, float x2, float y2);
/* OpenGL stipple defines */
/* OpenGL stipple defines */
-extern unsigned char stipple_halftone[128];
-extern unsigned char stipple_quarttone[128];
-extern unsigned char stipple_diag_stripes_pos[128];
-extern unsigned char stipple_diag_stripes_neg[128];
+extern const unsigned char stipple_halftone[128];
+extern const unsigned char stipple_quarttone[128];
+extern const unsigned char stipple_diag_stripes_pos[128];
+extern const unsigned char stipple_diag_stripes_neg[128];
/**
* Draw a lined (non-looping) arc with the given
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 8d7ae3aad6a..20f568a3642 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -300,34 +300,34 @@ typedef enum eAnimFilter_Flags {
/* -------------- Channel Defines -------------- */
/* channel heights */
-#define ACHANNEL_FIRST -16
-#define ACHANNEL_HEIGHT 16
-#define ACHANNEL_HEIGHT_HALF 8
-#define ACHANNEL_SKIP 2
+#define ACHANNEL_FIRST (-0.8f * U.widget_unit)
+#define ACHANNEL_HEIGHT (0.8f * U.widget_unit)
+#define ACHANNEL_HEIGHT_HALF (0.4f * U.widget_unit)
+#define ACHANNEL_SKIP (0.1f * U.widget_unit)
#define ACHANNEL_STEP (ACHANNEL_HEIGHT + ACHANNEL_SKIP)
/* channel widths */
-#define ACHANNEL_NAMEWIDTH 200
+#define ACHANNEL_NAMEWIDTH (10 * U.widget_unit)
/* channel toggle-buttons */
-#define ACHANNEL_BUTTON_WIDTH 16
+#define ACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit)
/* -------------- NLA Channel Defines -------------- */
/* NLA channel heights */
// XXX: NLACHANNEL_FIRST isn't used?
-#define NLACHANNEL_FIRST -16
-#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 16 : 24)
-#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 8 : 12)
-#define NLACHANNEL_SKIP 2
+#define NLACHANNEL_FIRST (-0.8f * U.widget_unit)
+#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit))
+#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.4f * U.widget_unit) : (0.6f * U.widget_unit))
+#define NLACHANNEL_SKIP (0.1f * U.widget_unit)
#define NLACHANNEL_STEP(snla) (NLACHANNEL_HEIGHT(snla) + NLACHANNEL_SKIP)
/* channel widths */
-#define NLACHANNEL_NAMEWIDTH 200
+#define NLACHANNEL_NAMEWIDTH (10 * U.widget_unit)
/* channel toggle-buttons */
-#define NLACHANNEL_BUTTON_WIDTH 16
+#define NLACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit)
/* ---------------- API -------------------- */
@@ -552,7 +552,8 @@ typedef enum eAnimUnitConv_Flags {
/* only touch selected BezTriples */
ANIM_UNITCONV_ONLYSEL = (1 << 2),
/* only touch selected vertices */
- ANIM_UNITCONV_SELVERTS = (1 << 3)
+ ANIM_UNITCONV_SELVERTS = (1 << 3),
+ ANIM_UNITCONV_SKIPKNOTS = (1 << 4),
} eAnimUnitConv_Flags;
/* Get unit conversion factor for given ID + F-Curve */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index efd10f3cb6b..4db79df033e 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -184,7 +184,7 @@ int BDR_drawSketchNames(struct ViewContext *vc);
/* meshlaplacian.c */
void mesh_deform_bind(struct Scene *scene,
struct MeshDeformModifierData *mmd,
- float *vertexcos, int totvert, float cagemat[][4]);
+ float *vertexcos, int totvert, float cagemat[4][4]);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index 8ad36397ce5..81dbb8e9aa5 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -36,8 +36,17 @@
extern int datatoc_startup_blend_size;
extern char datatoc_startup_blend[];
-extern int datatoc_blender_icons_png_size;
-extern char datatoc_blender_icons_png[];
+extern int datatoc_preview_blend_size;
+extern char datatoc_preview_blend[];
+
+extern int datatoc_preview_cycles_blend_size;
+extern char datatoc_preview_cycles_blend[];
+
+extern int datatoc_blender_icons16_png_size;
+extern char datatoc_blender_icons16_png[];
+
+extern int datatoc_blender_icons32_png_size;
+extern char datatoc_blender_icons32_png[];
extern int datatoc_prvicons_png_size;
extern char datatoc_prvicons_png[];
@@ -147,6 +156,81 @@ extern char datatoc_twist_png[];
extern int datatoc_vertexdraw_png_size;
extern char datatoc_vertexdraw_png[];
+/* Matcap files */
+
+extern int datatoc_mc01_jpg_size;
+extern char datatoc_mc01_jpg[];
+
+extern int datatoc_mc02_jpg_size;
+extern char datatoc_mc02_jpg[];
+
+extern int datatoc_mc03_jpg_size;
+extern char datatoc_mc03_jpg[];
+
+extern int datatoc_mc04_jpg_size;
+extern char datatoc_mc04_jpg[];
+
+extern int datatoc_mc05_jpg_size;
+extern char datatoc_mc05_jpg[];
+
+extern int datatoc_mc06_jpg_size;
+extern char datatoc_mc06_jpg[];
+
+extern int datatoc_mc07_jpg_size;
+extern char datatoc_mc07_jpg[];
+
+extern int datatoc_mc08_jpg_size;
+extern char datatoc_mc08_jpg[];
+
+extern int datatoc_mc09_jpg_size;
+extern char datatoc_mc09_jpg[];
+
+extern int datatoc_mc10_jpg_size;
+extern char datatoc_mc10_jpg[];
+
+extern int datatoc_mc11_jpg_size;
+extern char datatoc_mc11_jpg[];
+
+extern int datatoc_mc12_jpg_size;
+extern char datatoc_mc12_jpg[];
+
+extern int datatoc_mc13_jpg_size;
+extern char datatoc_mc13_jpg[];
+
+extern int datatoc_mc14_jpg_size;
+extern char datatoc_mc14_jpg[];
+
+extern int datatoc_mc15_jpg_size;
+extern char datatoc_mc15_jpg[];
+
+extern int datatoc_mc16_jpg_size;
+extern char datatoc_mc16_jpg[];
+
+extern int datatoc_mc17_jpg_size;
+extern char datatoc_mc17_jpg[];
+
+extern int datatoc_mc18_jpg_size;
+extern char datatoc_mc18_jpg[];
+
+extern int datatoc_mc19_jpg_size;
+extern char datatoc_mc19_jpg[];
+
+extern int datatoc_mc20_jpg_size;
+extern char datatoc_mc20_jpg[];
+
+extern int datatoc_mc21_jpg_size;
+extern char datatoc_mc21_jpg[];
+
+extern int datatoc_mc22_jpg_size;
+extern char datatoc_mc22_jpg[];
+
+extern int datatoc_mc23_jpg_size;
+extern char datatoc_mc23_jpg[];
+
+extern int datatoc_mc24_jpg_size;
+extern char datatoc_mc24_jpg[];
+
+
#endif /* __ED_DATAFILES_H__ */
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 5cc1ecade3e..29d4097521d 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -81,6 +81,7 @@ void draw_gpencil_2dimage(const struct bContext *C);
void draw_gpencil_view2d(const struct bContext *C, short onlyv2d);
void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d);
+void gpencil_panel_standard_header(const struct bContext *C, struct Panel *pa);
void gpencil_panel_standard(const struct bContext *C, struct Panel *pa);
/* ----------- Grease-Pencil AnimEdit API ------------------ */
diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h
index 1321765588d..4655188a3dd 100644
--- a/source/blender/editors/include/ED_mball.h
+++ b/source/blender/editors/include/ED_mball.h
@@ -32,6 +32,7 @@
#define __ED_MBALL_H__
struct bContext;
+struct MetaBall;
struct Object;
struct wmKeyConfig;
@@ -48,5 +49,6 @@ void load_editMball(struct Object *obedit);
void undo_push_mball(struct bContext *C, const char *name);
-#endif
+void ED_mball_transform(struct MetaBall *mb, float *mat);
+#endif /* __ED_MBALL_H__ */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 865da8f0e6e..d3de2593b9d 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -86,11 +86,15 @@ void EDBM_mesh_clear(struct BMEditMesh *em);
void EDBM_selectmode_to_scene(struct bContext *C);
void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object *ob);
-void EDBM_mesh_free(struct BMEditMesh *tm);
+void EDBM_mesh_free(struct BMEditMesh *em);
void EDBM_mesh_load(struct Object *ob);
-void EDBM_index_arrays_init(struct BMEditMesh *em, int forvert, int foredge, int forface);
+void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype);
+void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype);
void EDBM_index_arrays_free(struct BMEditMesh *em);
+#ifndef NDEBUG
+int EDBM_index_arrays_check(struct BMEditMesh *em);
+#endif
struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index);
struct BMEdge *EDBM_edge_at_index(struct BMEditMesh *em, int index);
struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index);
@@ -115,7 +119,7 @@ int EDBM_vert_color_check(struct BMEditMesh *em);
void EDBM_mesh_hide(struct BMEditMesh *em, int swap);
void EDBM_mesh_reveal(struct BMEditMesh *em);
-void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, const short do_tessface);
+void EDBM_update_generic(struct BMEditMesh *em, const bool do_tessface, const bool is_destructive);
struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands);
void EDBM_uv_element_map_free(struct UvElementMap *vmap);
@@ -126,7 +130,7 @@ struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace *
void EDBM_uv_vert_map_free(struct UvVertMap *vmap);
struct UvMapVert *EDBM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v);
-struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]);
+struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, bool use_select, const float limit[2]);
void EDBM_flag_enable_all(struct BMEditMesh *em, const char hflag);
void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag);
@@ -223,6 +227,7 @@ void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *de
void ED_vgroup_clear(struct Object *ob);
void ED_vgroup_select_by_name(struct Object *ob, const char *name);
int ED_vgroup_data_create(struct ID *id);
+void ED_vgroup_data_clamp_range(struct ID *id, const int total);
int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
int ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from);
void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups, const short all_vgroups);
@@ -287,9 +292,9 @@ int mesh_get_x_mirror_vert(struct Object *ob, int index);
struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em, struct BMVert *eve, const float co[3], int index);
int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em);
-int ED_mesh_pick_vert(struct bContext *C, struct Mesh *me, const int mval[2], unsigned int *index, int size);
-int ED_mesh_pick_face(struct bContext *C, struct Mesh *me, const int mval[2], unsigned int *index, int size);
-int ED_mesh_pick_face_vert(struct bContext *C, struct Mesh *me, struct Object *ob, const int mval[2], unsigned int *index, int size);
+int ED_mesh_pick_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size, int use_zbuf);
+int ED_mesh_pick_face(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size);
+int ED_mesh_pick_face_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size);
#define ED_MESH_PICK_DEFAULT_VERT_SIZE 50
#define ED_MESH_PICK_DEFAULT_FACE_SIZE 3
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 0d0b8d8e797..2c43f6e4f25 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -83,6 +83,7 @@ typedef enum eParentType {
PAR_ARMATURE_ENVELOPE,
PAR_ARMATURE_AUTO,
PAR_BONE,
+ PAR_BONE_RELATIVE,
PAR_CURVE,
PAR_FOLLOW,
PAR_PATH_CONST,
@@ -134,7 +135,7 @@ void ED_object_location_from_view(struct bContext *C, float loc[3]);
void ED_object_rotation_from_view(struct bContext *C, float rot[3]);
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],
+ const float loc[3], const float rot[3], float primmat[4][4],
int apply_diameter);
void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode);
@@ -160,7 +161,7 @@ void object_test_constraints(struct Object *ob);
void ED_object_constraint_set_active(struct Object *ob, struct bConstraint *con);
void ED_object_constraint_update(struct Object *ob);
-void ED_object_constraint_dependency_update(struct Main *bmain, struct Scene *scene, struct Object *ob);
+void ED_object_constraint_dependency_update(struct Main *bmain, struct Object *ob);
/* object_lattice.c */
int mouse_lattice(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
@@ -178,9 +179,9 @@ enum {
struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
struct Object *ob, const char *name, int type);
-int ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
+int ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain,
struct Object *ob, struct ModifierData *md);
-void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct Object *ob);
+void ED_object_modifier_clear(struct Main *bmain, struct Object *ob);
int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/editors/include/ED_physics.h
index cd9ddd3d7d1..192bcd8f712 100644
--- a/source/blender/editors/include/ED_physics.h
+++ b/source/blender/editors/include/ED_physics.h
@@ -32,13 +32,26 @@
#ifndef __ED_PHYSICS_H__
#define __ED_PHYSICS_H__
+struct bContext;
+struct wmOperator;
struct wmKeyConfig;
+struct Scene;
+struct Object;
+
/* particle_edit.c */
int PE_poll(struct bContext *C);
int PE_hair_poll(struct bContext *C);
int PE_poll_view3d(struct bContext *C);
+/* rigidbody_object.c */
+void ED_rigidbody_ob_add(struct wmOperator *op, struct Scene *scene, struct Object *ob, int type);
+void ED_rigidbody_ob_remove(struct Scene *scene, struct Object *ob);
+
+/* rigidbody_constraint.c */
+void ED_rigidbody_con_add(struct wmOperator *op, struct Scene *scene, struct Object *ob, int type);
+void ED_rigidbody_con_remove(struct Scene *scene, struct Object *ob);
+
/* operators */
void ED_operatortypes_physics(void);
void ED_keymap_physics(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 860d176ffb3..72208a8e93d 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -64,9 +64,11 @@ void ED_region_panels(const struct bContext *C, struct ARegion *ar, int verti
void ED_region_header_init(struct ARegion *ar);
void ED_region_header(const struct bContext *C, struct ARegion *ar);
void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar);
-void region_scissor_winrct(struct ARegion *ar, struct rcti *winrct);
void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float alpha);
void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
+float ED_region_blend_factor(struct ARegion *ar);
+void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
+
/* spaces */
void ED_spacetypes_init(void);
diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h
index 84fd5332316..23d173aebdc 100644
--- a/source/blender/editors/include/ED_sequencer.h
+++ b/source/blender/editors/include/ED_sequencer.h
@@ -38,6 +38,8 @@ int ED_space_sequencer_maskedit_mask_poll(struct bContext *C);
int ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene);
int ED_space_sequencer_maskedit_poll(struct bContext *C);
+int ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq);
+
void ED_operatormacros_sequencer(void);
#endif /* __ED_SEQUENCER_H__ */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index d7e9fc323a6..a41aaca15bd 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -83,6 +83,7 @@ enum {
TFM_BWEIGHT,
TFM_ALIGN,
TFM_EDGE_SLIDE,
+ TFM_VERT_SLIDE,
TFM_SEQ_SLIDE
} TfmMode;
@@ -124,7 +125,7 @@ void BIF_createTransformOrientation(struct bContext *C, struct ReportList *repor
void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
void BIF_selectTransformOrientationValue(struct bContext *C, int orientation);
-void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[][3], int activeOnly);
+void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], int activeOnly);
struct EnumPropertyItem *BIF_enumTransformOrientation(struct bContext *C);
const char *BIF_menustringTransformOrientation(const struct bContext *C, const char *title); /* the returned value was allocated and needs to be freed after use */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index f15f2418707..46f4515e0ca 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -85,9 +85,10 @@ typedef struct ViewDepths {
} ViewDepths;
float *give_cursor(struct Scene *scene, struct View3D *v3d);
+void ED_view3d_cursor3d_position(struct bContext *C, float fp[3], const int mval[2]);
-void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist);
-void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist);
+void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist);
+void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist);
void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist);
@@ -114,15 +115,20 @@ typedef enum {
V3D_PROJ_TEST_NOP = 0,
V3D_PROJ_TEST_CLIP_BB = (1 << 0),
V3D_PROJ_TEST_CLIP_WIN = (1 << 1),
+ V3D_PROJ_TEST_CLIP_NEAR = (1 << 2),
} eV3DProjTest;
-#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN)
-#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN)
+#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
+#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
/* view3d_iterators.c */
/* foreach iterators */
+void meshobject_foreachScreenVert(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct MVert *eve, const float screen_co[2], int index),
+ void *userData, const eV3DProjTest clip_flag);
void mesh_foreachScreenVert(
struct ViewContext *vc,
void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index),
@@ -208,7 +214,7 @@ void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struc
void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]);
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]);
+void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local);
void ED_view3d_clipping_set(struct RegionView3D *rv3d);
void ED_view3d_clipping_enable(void);
@@ -219,7 +225,7 @@ float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]);
float ED_view3d_radius_to_persp_dist(const float angle, const float radius);
float ED_view3d_radius_to_ortho_dist(const float lens, const float radius);
-void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]);
+void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4]);
/* backbuffer select and draw support */
void view3d_validate_backbuf(struct ViewContext *vc);
@@ -264,17 +270,17 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
int ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
- int winx, int winy, float viewmat[][4], float winmat[][4], int do_bgpic, int colormanage_background);
+ int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag,
- int draw_background, int colormanage_background, char err_out[256]);
+ int draw_background, int alpha_mode, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype,
- int draw_background, int colormanage_background, char err_out[256]);
-
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]);
+void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip);
-void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]);
+void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]);
int ED_view3d_lock(struct RegionView3D *rv3d);
uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d);
@@ -295,7 +301,8 @@ void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic);
void ED_view3D_background_image_clear(struct View3D *v3d);
#define VIEW3D_MARGIN 1.4f
-float ED_view3d_offset_distance(float mat[4][4], float ofs[3]);
+#define VIEW3D_DIST_FALLBACK 1.0f
+float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback);
float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit);
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 99f7f0856b3..0560cbd69cc 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -699,9 +699,7 @@ DEF_ICON(RNDCURVE)
DEF_ICON(PROP_OFF)
DEF_ICON(PROP_ON)
DEF_ICON(PROP_CON)
-#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK212)
-#endif
+DEF_ICON(SCULPT_DYNTOPO)
DEF_ICON(PARTICLE_POINT)
DEF_ICON(PARTICLE_TIP)
DEF_ICON(PARTICLE_PATH)
@@ -992,11 +990,37 @@ DEF_ICON(BRUSH_THUMB)
DEF_ICON(BRUSH_ROTATE)
DEF_ICON(BRUSH_VERTEXDRAW)
+ /* Matcaps */
+DEF_ICON(MATCAP_01)
+DEF_ICON(MATCAP_02)
+DEF_ICON(MATCAP_03)
+DEF_ICON(MATCAP_04)
+DEF_ICON(MATCAP_05)
+DEF_ICON(MATCAP_06)
+DEF_ICON(MATCAP_07)
+DEF_ICON(MATCAP_08)
+DEF_ICON(MATCAP_09)
+DEF_ICON(MATCAP_10)
+DEF_ICON(MATCAP_11)
+DEF_ICON(MATCAP_12)
+DEF_ICON(MATCAP_13)
+DEF_ICON(MATCAP_14)
+DEF_ICON(MATCAP_15)
+DEF_ICON(MATCAP_16)
+DEF_ICON(MATCAP_17)
+DEF_ICON(MATCAP_18)
+DEF_ICON(MATCAP_19)
+DEF_ICON(MATCAP_20)
+DEF_ICON(MATCAP_21)
+DEF_ICON(MATCAP_22)
+DEF_ICON(MATCAP_23)
+DEF_ICON(MATCAP_24)
+
/* vector icons, VICO_ prefix added */
DEF_VICO(VIEW3D_VEC)
DEF_VICO(EDIT_VEC)
-DEF_VICO(EDITMODE_DEHLT)
-DEF_VICO(EDITMODE_HLT)
+DEF_VICO(EDITMODE_VEC_DEHLT)
+DEF_VICO(EDITMODE_VEC_HLT)
DEF_VICO(DISCLOSURE_TRI_RIGHT_VEC)
DEF_VICO(DISCLOSURE_TRI_DOWN_VEC)
DEF_VICO(MOVE_UP_VEC)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 2dc552d0fce..78689c078c6 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -42,6 +42,7 @@ struct ID;
struct Main;
struct ListBase;
struct ARegion;
+struct ARegionType;
struct ScrArea;
struct wmWindow;
struct wmWindowManager;
@@ -56,6 +57,7 @@ struct PropertyRNA;
struct ReportList;
struct rcti;
struct rctf;
+struct uiList;
struct uiStyle;
struct uiFontStyle;
struct uiWidgetColors;
@@ -83,6 +85,9 @@ typedef struct uiLayout uiLayout;
#define UI_MAX_DRAW_STR 400
#define UI_MAX_NAME_STR 128
+/* use for clamping popups within the screen */
+#define UI_SCREEN_MARGIN 10
+
/* uiBlock->dt */
#define UI_EMBOSS 0 /* use widget style for drawing */
#define UI_EMBOSSN 1 /* Nothing, only icon and/or text */
@@ -175,12 +180,11 @@ typedef struct uiLayout uiLayout;
/* uiBut->drawflag */
#define UI_BUT_DRAW_ENUM_ARROWS (1 << 0) /* draw enum-like up/down arrows for button */
-/* scale fixed button widths by this to account for DPI
- * 8.4852 == sqrtf(72.0f)) */
-#define UI_DPI_FAC (sqrtf((float)U.dpi) / 8.48528137423857f)
-#define UI_DPI_ICON_FAC (((float)U.dpi) / 72.0f)
+/* scale fixed button widths by this to account for DPI */
+
+#define UI_DPI_FAC ((U.pixelsize * (float)U.dpi) / 72.0f)
/* 16 to copy ICON_DEFAULT_HEIGHT */
-#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC)
+#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_FAC)
/* Button types, bits stored in 1 value... and a short even!
* - bits 0-4: bitnr (0-31)
@@ -218,7 +222,7 @@ typedef enum {
NUMSLI = (14 << 9),
COLOR = (15 << 9),
IDPOIN = (16 << 9),
- HSVSLI = (17 << 9),
+ HSVSLI = (17 << 9), /* UNUSED, but code still references */
SCROLL = (18 << 9),
BLOCK = (19 << 9),
BUTM = (20 << 9),
@@ -253,7 +257,8 @@ typedef enum {
HISTOGRAM = (48 << 9),
WAVEFORM = (49 << 9),
VECTORSCOPE = (50 << 9),
- PROGRESSBAR = (51 << 9)
+ PROGRESSBAR = (51 << 9),
+ SEARCH_MENU_UNLINK = (52 << 9)
} eButType;
#define BUTTYPE (63 << 9)
@@ -287,7 +292,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float
#define UI_SCROLL_PRESSED 1
#define UI_SCROLL_ARROWS 2
#define UI_SCROLL_NO_OUTLINE 4
-void uiWidgetScrollDraw(struct uiWidgetColors *wcol, struct rcti *rect, struct rcti *slider, int state);
+void uiWidgetScrollDraw(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state);
/* Callbacks
*
@@ -356,7 +361,7 @@ void uiPupMenuInvoke(struct bContext *C, const char *idname); /* popup registere
* but allow using all button types and creating an own layout. */
typedef uiBlock * (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
-typedef void (*uiBlockCancelFunc)(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);
@@ -432,6 +437,7 @@ void uiButSetDragValue(uiBut *but);
void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale);
int UI_but_active_drop_name(struct bContext *C);
+struct uiBut *ui_but_find_mouse_over(struct ARegion *ar, int x, int y);
void uiButSetFlag(uiBut *but, int flag);
void uiButClearFlag(uiBut *but, int flag);
@@ -442,6 +448,8 @@ void uiButClearDrawFlag(uiBut *but, int flag);
/* special button case, only draw it when used actively, for outliner etc */
int uiButActiveOnly(const struct bContext *C, uiBlock *block, uiBut *but);
+void uiButExecute(const struct bContext *C, uiBut *but);
+
/* Buttons
*
@@ -659,6 +667,7 @@ void uiDrawPanels(const struct bContext *C, struct ARegion *ar);
struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, struct PanelType *pt, int *open);
void uiEndPanel(uiBlock *block, int width, int height);
+void uiScalePanels(struct ARegion *ar, float new_width);
/* Handlers
*
@@ -779,7 +788,7 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align);
uiLayout *uiLayoutColumn(uiLayout *layout, int align);
uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align);
uiLayout *uiLayoutBox(uiLayout *layout);
-uiLayout *uiLayoutListBox(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop,
+uiLayout *uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, struct PointerRNA *ptr, struct PropertyRNA *prop,
struct PointerRNA *actptr, struct PropertyRNA *actprop);
uiLayout *uiLayoutAbsolute(uiLayout *layout, int align);
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align);
@@ -804,6 +813,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct Pointe
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout, struct ID *id, int show_buttons, struct ID *parent, struct MTex *slot);
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int expand);
+void uiTemplateIconView(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
void uiTemplateHistogram(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
void uiTemplateWaveform(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
void uiTemplateVectorscope(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
@@ -825,7 +835,11 @@ void uiTemplateTextureImage(uiLayout *layout, struct bContext *C, struct Tex *te
void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C);
void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
-void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *activeptr, const char *activeprop, const char *prop_list, int rows, int maxrows, int type);
+/* Default UIList class name, keep in sync with its declaration in bl_ui/__init__.py */
+#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);
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);
@@ -885,7 +899,7 @@ void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct Prop
/* Styled text draw */
void uiStyleFontSet(struct uiFontStyle *fs);
-void uiStyleFontDrawExt(struct uiFontStyle *fs, struct rcti *rect, const char *str,
+void uiStyleFontDrawExt(struct uiFontStyle *fs, const struct rcti *rect, const char *str,
float *r_xofs, float *r_yofs);
void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, const char *str);
void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const char *str);
@@ -893,7 +907,10 @@ void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const cha
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);
-uiStyle *UI_GetStyle(void);
+
+uiStyle *UI_GetStyle(void); /* use for fonts etc */
+uiStyle *UI_GetStyleDraw(void); /* DPI scaled settings for drawing */
+
/* linker workaround ack! */
void UI_template_fix_linking(void);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index aa94bdec724..10026bbd50f 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -32,12 +32,15 @@
#ifndef __UI_INTERFACE_ICONS_H__
#define __UI_INTERFACE_ICONS_H__
+struct bContext;
struct Image;
struct ImBuf;
struct World;
struct Tex;
struct Lamp;
struct Material;
+struct PreviewImage;
+struct PointerRNA;
typedef struct IconFile {
struct IconFile *next, *prev;
@@ -74,5 +77,8 @@ void UI_icons_free_drawinfo(void *drawinfo);
struct ListBase *UI_iconfile_list(void);
int UI_iconfile_get_index(const char *filename);
+struct PreviewImage *UI_icon_to_preview(int icon_id);
+
+int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, int big);
#endif /* __UI_INTERFACE_ICONS_H__ */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index f4e921e2fa4..b497a97569f 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -64,10 +64,11 @@ enum {
TH_HEADER_TEXT,
TH_HEADER_TEXT_HI,
- /* float panels */
- TH_PANEL,
- TH_PANEL_TEXT,
- TH_PANEL_TEXT_HI,
+ /* panels */
+ TH_PANEL_HEADER,
+ TH_PANEL_BACK,
+ TH_PANEL_SHOW_HEADER,
+ TH_PANEL_SHOW_BACK,
TH_BUTBACK,
TH_BUTBACK_TEXT,
@@ -121,9 +122,12 @@ enum {
TH_SYNTAX_B,
TH_SYNTAX_V,
+ TH_SYNTAX_R,
TH_SYNTAX_C,
TH_SYNTAX_L,
+ TH_SYNTAX_D,
TH_SYNTAX_N,
+ TH_SYNTAX_S,
TH_BONE_SOLID,
TH_BONE_POSE,
@@ -143,12 +147,15 @@ enum {
TH_NODE_CONVERTOR,
TH_NODE_GROUP,
TH_NODE_FRAME,
+ TH_NODE_MATTE,
+ TH_NODE_DISTORT,
TH_CONSOLE_OUTPUT,
TH_CONSOLE_INPUT,
TH_CONSOLE_INFO,
TH_CONSOLE_ERROR,
TH_CONSOLE_CURSOR,
+ TH_CONSOLE_SELECT,
TH_SEQ_MOVIE,
TH_SEQ_MOVIECLIP,
@@ -219,7 +226,11 @@ enum {
TH_AXIS_X, /* X/Y/Z Axis */
TH_AXIS_Y,
- TH_AXIS_Z
+ TH_AXIS_Z,
+
+ TH_LOW_GRAD,
+ TH_HIGH_GRAD,
+ TH_SHOW_BACK_GRAD
};
/* XXX WARNING: previous is saved in file, so do not change order! */
@@ -286,6 +297,9 @@ void UI_SetTheme(int spacetype, int regionid);
// get current theme
struct bTheme *UI_GetTheme(void);
+// return shadow width outside menus and popups */
+int UI_ThemeMenuShadowWidth(void);
+
/* only for buttons in theme editor! */
const unsigned char *UI_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 24759fa778a..81a0f526049 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -102,11 +102,11 @@ enum {
/* ------ Defines for Scrollers ----- */
/* scroller area */
-#define V2D_SCROLL_HEIGHT 17
-#define V2D_SCROLL_WIDTH 17
+#define V2D_SCROLL_HEIGHT (0.85f * U.widget_unit)
+#define V2D_SCROLL_WIDTH (0.85f * U.widget_unit)
/* scroller 'handles' hotspot radius for mouse */
-#define V2D_SCROLLER_HANDLE_SIZE 12
+#define V2D_SCROLLER_HANDLE_SIZE (0.6f * U.widget_unit)
/* ------ Define for UI_view2d_sync ----- */
@@ -132,6 +132,7 @@ struct View2DScrollers;
struct wmKeyConfig;
struct bScreen;
+struct Scene;
struct ScrArea;
struct ARegion;
struct bContext;
@@ -147,7 +148,6 @@ typedef struct View2DScrollers View2DScrollers;
void UI_view2d_region_reinit(struct View2D *v2d, short type, int winx, int winy);
void UI_view2d_curRect_validate(struct View2D *v2d);
-void UI_view2d_curRect_validate_resize(struct View2D *v2d, int resize);
void UI_view2d_curRect_reset(struct View2D *v2d);
void UI_view2d_sync(struct bScreen *screen, struct ScrArea *sa, struct View2D *v2dcur, int flag);
@@ -198,6 +198,7 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C);
struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C);
void UI_view2d_getscale(struct View2D *v2d, float *x, float *y);
+void UI_view2d_getscale_inverse(struct View2D *v2d, float *x, float *y);
short UI_view2d_mouse_in_scrollers(const struct bContext *C, struct View2D *v2d, int x, int y);
diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript
index 2d6d5cd235e..8d277d6cd35 100644
--- a/source/blender/editors/interface/SConscript
+++ b/source/blender/editors/interface/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index ce82e064531..0d9795c5438 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -69,7 +69,6 @@
#include "WM_api.h"
#include "WM_types.h"
#include "wm_subwindow.h"
-#include "wm_window.h"
#include "RNA_access.h"
@@ -298,9 +297,9 @@ static void ui_centered_bounds_block(const bContext *C, uiBlock *block)
/* note: this is used for the splash where window bounds event has not been
* updated by ghost, get the window bounds from ghost directly */
- // wm_window_get_size(window, &xmax, &ymax);
- wm_window_get_size_ghost(window, &xmax, &ymax);
-
+ xmax = WM_window_pixels_x(window);
+ ymax = WM_window_pixels_y(window);
+
ui_bounds_block(block);
width = BLI_rctf_size_x(&block->rect);
@@ -320,13 +319,15 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound
wmWindow *window = CTX_wm_window(C);
int startx, starty, endx, endy, width, height, oldwidth, oldheight;
int oldbounds, xmax, ymax;
+ const int margin = UI_SCREEN_MARGIN;
oldbounds = block->bounds;
/* compute mouse position with user defined offset */
ui_bounds_block(block);
- wm_window_get_size(window, &xmax, &ymax);
+ xmax = WM_window_pixels_x(window);
+ ymax = WM_window_pixels_y(window);
oldwidth = BLI_rctf_size_x(&block->rect);
oldheight = BLI_rctf_size_y(&block->rect);
@@ -334,7 +335,7 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound
/* first we ensure wide enough text bounds */
if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) {
if (block->flag & UI_BLOCK_LOOP) {
- block->bounds = 50;
+ block->bounds = 2.5f * UI_UNIT_X;
ui_text_bounds_block(block, block->rect.xmin);
}
}
@@ -356,20 +357,20 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound
startx = window->eventstate->x + block->rect.xmin + (block->mx * width) / oldwidth;
starty = window->eventstate->y + block->rect.ymin + (block->my * height) / oldheight;
- if (startx < 10)
- startx = 10;
- if (starty < 10)
- starty = 10;
+ if (startx < margin)
+ startx = margin;
+ if (starty < margin)
+ starty = margin;
endx = startx + width;
endy = starty + height;
if (endx > xmax) {
- endx = xmax - 10;
+ endx = xmax - margin;
startx = endx - width;
}
- if (endy > ymax - 20) {
- endy = ymax - 20;
+ if (endy > ymax - margin) {
+ endy = ymax - margin;
starty = endy - height;
}
@@ -635,7 +636,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut
/* move button over from oldblock to new block */
BLI_remlink(&oldblock->buttons, oldbut);
- BLI_insertlink(&block->buttons, but, oldbut);
+ BLI_insertlinkafter(&block->buttons, but, oldbut);
oldbut->block = block;
*butpp = oldbut;
@@ -712,6 +713,12 @@ int uiButActiveOnly(const bContext *C, uiBlock *block, uiBut *but)
return 1;
}
+/* simulate button click */
+void uiButExecute(const bContext *C, uiBut *but)
+{
+ ui_button_execute_do((bContext *)C, CTX_wm_region(C), but);
+}
+
/* use to check if we need to disable undo, but don't make any changes
* returns FALSE if undo needs to be disabled. */
static int ui_but_is_rna_undo(uiBut *but)
@@ -927,6 +934,8 @@ void uiEndBlock(const bContext *C, uiBlock *block)
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));
block->oldblock = NULL;
}
@@ -983,7 +992,8 @@ void ui_fontscale(short *points, float aspect)
float pointsf = *points;
/* for some reason scaling fonts goes too fast compared to widget size */
- aspect = sqrt(aspect);
+ /* XXX not true anymore? (ton) */
+ //aspect = sqrt(aspect);
pointsf /= aspect;
if (aspect > 1.0f)
@@ -996,11 +1006,11 @@ void ui_fontscale(short *points, float aspect)
/* project button or block (but==NULL) to pixels in regionspace */
static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, uiBut *but)
{
- rctf rectf = (but)? but->rect: block->rect;
+ rctf rectf = (but) ? but->rect : block->rect;
ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin);
ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax);
-
+
rectf.xmin -= ar->winrct.xmin;
rectf.ymin -= ar->winrct.ymin;
rectf.xmax -= ar->winrct.xmin;
@@ -1015,7 +1025,7 @@ 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)
{
- uiStyle style = *UI_GetStyle(); /* XXX pass on as arg */
+ uiStyle style = *UI_GetStyleDraw(); /* XXX pass on as arg */
ARegion *ar;
uiBut *but;
rcti rect;
@@ -1290,7 +1300,7 @@ void ui_delete_linkline(uiLinkLine *line, uiBut *but)
void ui_get_but_vectorf(uiBut *but, float vec[3])
{
PropertyRNA *prop;
- int a, tot;
+ int a;
if (but->editvec) {
copy_v3_v3(vec, but->editvec);
@@ -1299,18 +1309,25 @@ void ui_get_but_vectorf(uiBut *but, float vec[3])
if (but->rnaprop) {
prop = but->rnaprop;
- vec[0] = vec[1] = vec[2] = 0.0f;
+ zero_v3(vec);
if (RNA_property_type(prop) == PROP_FLOAT) {
- tot = RNA_property_array_length(&but->rnapoin, prop);
- tot = min_ii(tot, 3);
-
- for (a = 0; a < tot; a++)
- vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
+ int tot = RNA_property_array_length(&but->rnapoin, prop);
+ BLI_assert(tot > 0);
+ if (tot == 3) {
+ RNA_property_float_get_array(&but->rnapoin, prop, vec);
+ }
+ else {
+ tot = min_ii(tot, 3);
+ for (a = 0; a < tot; a++) {
+ vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
+ }
+ }
}
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
char *cp = (char *)but->poin;
+
vec[0] = ((float)cp[0]) / 255.0f;
vec[1] = ((float)cp[1]) / 255.0f;
vec[2] = ((float)cp[2]) / 255.0f;
@@ -1321,8 +1338,8 @@ void ui_get_but_vectorf(uiBut *but, float vec[3])
}
else {
if (but->editvec == NULL) {
- fprintf(stderr, "ui_get_but_vectorf: can't get color, should never happen\n");
- vec[0] = vec[1] = vec[2] = 0.0f;
+ fprintf(stderr, "%s: can't get color, should never happen\n", __func__);
+ zero_v3(vec);
}
}
@@ -1348,10 +1365,15 @@ void ui_set_but_vectorf(uiBut *but, const float vec[3])
int a;
tot = RNA_property_array_length(&but->rnapoin, prop);
- tot = min_ii(tot, 3);
-
- for (a = 0; a < tot; a++) {
- RNA_property_float_set_index(&but->rnapoin, prop, a, vec[a]);
+ BLI_assert(tot > 0);
+ if (tot == 3) {
+ RNA_property_float_set_array(&but->rnapoin, prop, vec);
+ }
+ else {
+ tot = min_ii(tot, 3);
+ for (a = 0; a < tot; a++) {
+ RNA_property_float_set_index(&but->rnapoin, prop, a, vec[a]);
+ }
}
}
}
@@ -1378,6 +1400,18 @@ int ui_is_but_float(uiBut *but)
return 0;
}
+int ui_is_but_bool(uiBut *but)
+{
+ if (ELEM5(but->type, TOG, TOGN, TOGR, ICONTOG, ICONTOGN))
+ return 1;
+
+ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN)
+ return 1;
+
+ return 0;
+}
+
+
int ui_is_but_unit(uiBut *but)
{
UnitSettings *unit = but->block->unit;
@@ -1592,7 +1626,7 @@ void ui_set_but_val(uiBut *but, double value)
int ui_get_but_string_max_length(uiBut *but)
{
- if (ELEM(but->type, TEX, SEARCH_MENU))
+ if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK))
return but->hardmax;
else if (but->type == IDPOIN)
return MAX_ID_NAME - 2;
@@ -1675,7 +1709,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
{
- if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
PropertyType type;
const char *buf = NULL;
int buf_len;
@@ -1729,7 +1763,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
BLI_strncpy(str, but->poin, maxlen);
return;
}
- else if (but->type == SEARCH_MENU) {
+ else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(str, but->poin, maxlen);
return;
@@ -1784,9 +1818,9 @@ int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double
#ifdef WITH_PYTHON
if (str[0] != '\0') {
- int is_unit_but = ui_is_but_unit(but);
+ bool is_unit_but = (ui_is_but_float(but) && ui_is_but_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 (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 */
if (is_unit_but) {
char str_new[128];
@@ -1820,7 +1854,7 @@ int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double
int ui_set_but_string(bContext *C, uiBut *but, const char *str)
{
- if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
PropertyType type;
@@ -1877,7 +1911,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
return 1;
}
- else if (but->type == SEARCH_MENU) {
+ else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(but->poin, str, but->hardmax);
return 1;
@@ -2347,6 +2381,7 @@ void ui_check_but(uiBut *but)
case IDPOIN:
case TEX:
case SEARCH_MENU:
+ case SEARCH_MENU_UNLINK:
if (!but->editstr) {
char str[UI_MAX_DRAW_STR];
@@ -2650,9 +2685,11 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
BLI_assert(width >= 0);
BLI_assert(height >= 0);
-
+
/* we could do some more error checks here */
if ((type & BUTTYPE) == LABEL) {
+ if ((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)))
+ printf("blah\n");
BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE);
}
@@ -2726,7 +2763,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
if ((block->flag & UI_BLOCK_LOOP) ||
- ELEM8(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR))
+ ELEM9(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK))
{
but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT);
}
@@ -2762,21 +2799,21 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
return but;
}
-/* ui_def_but_rna_propname and ui_def_but_rna
+static void ui_def_but_rna__disable(uiBut *but)
+{
+ but->flag |= UI_BUT_DISABLED;
+ but->lock = true;
+ but->lockstr = "";
+}
+
+/**
+ * ui_def_but_rna_propname and ui_def_but_rna
* both take the same args except for propname vs prop, this is done so we can
* avoid an extra lookup on 'prop' when its already available.
*
* When this kind of change won't disrupt branches, best look into making more
* of our UI functions take prop rather then propname.
*/
-
-#define UI_DEF_BUT_RNA_DISABLE(but) { \
- but->flag |= UI_BUT_DISABLED; \
- but->lock = TRUE; \
- but->lockstr = ""; \
- } (void)0
-
-
static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str,
int x, int y, short width, short height,
PointerRNA *ptr, PropertyRNA *prop, int index,
@@ -2786,6 +2823,10 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
uiBut *but;
int freestr = 0, icon = 0;
+ if (ELEM3(type, COLOR, HSVCIRCLE, HSVCUBE)) {
+ BLI_assert(index == -1);
+ }
+
/* use rna values if parameters are not specified */
if (!str) {
if (type == MENU && proptype == PROP_ENUM) {
@@ -2826,12 +2867,13 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
EnumPropertyItem *item;
int i, totitem, free;
- /* TODO, translate after getting the item, saves many lookups */
- RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free);
+ /* get untranslated, then translate the single string we need */
+ RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
for (i = 0; i < totitem; i++) {
if (item[i].identifier[0] && item[i].value == (int)max) {
- str = item[i].name;
+ str = CTX_IFACE_(RNA_property_translation_context(prop), item[i].name);
icon = item[i].icon;
+ break;
}
}
@@ -2908,7 +2950,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
}
if (!RNA_property_editable(&but->rnapoin, prop)) {
- UI_DEF_BUT_RNA_DISABLE(but);
+ ui_def_but_rna__disable(but);
}
if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == FALSE)) {
@@ -2938,7 +2980,7 @@ static uiBut *ui_def_but_rna_propname(uiBlock *block, int type, int retval, cons
else {
but = ui_def_but(block, type, retval, propname, x, y, width, height, NULL, min, max, a1, a2, tip);
- UI_DEF_BUT_RNA_DISABLE(but);
+ ui_def_but_rna__disable(but);
}
return but;
@@ -3887,15 +3929,20 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
}
}
else if (type == BUT_GET_RNA_LABEL_CONTEXT) {
+ const char *_tmp = NULL;
if (but->rnaprop)
- tmp = BLI_strdup(RNA_property_translation_context(but->rnaprop));
+ _tmp = RNA_property_translation_context(but->rnaprop);
else if (but->optype)
- tmp = BLI_strdup(RNA_struct_translation_context(but->optype->srna));
+ _tmp = RNA_struct_translation_context(but->optype->srna);
else if (ELEM(but->type, MENU, PULLDOWN)) {
MenuType *mt = uiButGetMenuType(but);
if (mt)
- tmp = BLI_strdup(RNA_struct_translation_context(mt->ext.srna));
+ _tmp = RNA_struct_translation_context(mt->ext.srna);
+ }
+ if (!_tmp) { /* _tmp == BLF_I18NCONTEXT_DEFAULT */
+ _tmp = BLF_I18NCONTEXT_DEFAULT_BPY;
}
+ tmp = BLI_strdup(_tmp);
}
else if (ELEM3(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) {
PointerRNA *ptr = NULL;
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 5d62ef768d2..e4c163e9162 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -57,7 +57,11 @@
static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, int *driven)
{
- return rna_get_fcurve(&but->rnapoin, but->rnaprop, but->rnaindex, action, 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(&but->rnapoin, but->rnaprop, rnaindex, action, driven);
}
void ui_but_anim_flag(uiBut *but, float cfra)
@@ -131,7 +135,7 @@ int ui_but_anim_expression_create(uiBut *but, const char *str)
ID *id;
FCurve *fcu;
char *path;
- short ok = 0;
+ bool ok = false;
/* button must have RNA-pointer to a numeric-capable property */
if (ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
@@ -140,6 +144,14 @@ int ui_but_anim_expression_create(uiBut *but, const char *str)
return 0;
}
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0) {
+ if (but->rnaindex == -1) {
+ if (G.debug & G_DEBUG)
+ printf("ERROR: create expression failed - can't create expression for entire array\n");
+ return 0;
+ }
+ }
+
/* make sure we have animdata for this */
/* FIXME: until materials can be handled by depsgraph, don't allow drivers to be created for them */
id = (ID *)but->rnapoin.id.data;
@@ -168,6 +180,7 @@ int ui_but_anim_expression_create(uiBut *but, const char *str)
/* updates */
driver->flag |= DRIVER_FLAG_RECOMPILE;
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, NULL);
+ ok = true;
}
}
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 4d96ad810d4..e19e89af5da 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -373,7 +373,7 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
glEnable(GL_BLEND);
uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
-
+
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
}
@@ -429,17 +429,18 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
#else
ImBuf *ibuf = (ImBuf *)but->poin;
//GLint scissor[4];
- //int w, h;
+ int w, h;
if (!ibuf) return;
+ w = BLI_rcti_size_x(rect);
+ h = BLI_rcti_size_y(rect);
+
/* scissor doesn't seem to be doing the right thing...? */
#if 0
//glColor4f(1.0, 0.f, 0.f, 1.f);
//fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax)
- w = BLI_rcti_size_x(rect);
- h = BLI_rcti_size_y(rect);
/* prevent drawing outside widget area */
glGetIntegerv(GL_SCISSOR_BOX, scissor);
glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h);
@@ -448,9 +449,16 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
glEnable(GL_BLEND);
glColor4f(0.0, 0.0, 0.0, 0.0);
+ if (w != ibuf->x || h != ibuf->y) {
+ float facx = (float)w / (float)ibuf->x;
+ float facy = (float)h / (float)ibuf->y;
+ glPixelZoom(facx, facy);
+ }
glaDrawPixelsSafe((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
//glaDrawPixelsTex((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+ glPixelZoom(1.0f, 1.0f);
+
glDisable(GL_BLEND);
#if 0
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b80025e0d77..fbb1ad10f56 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -44,6 +44,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -84,6 +85,7 @@
/* 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 int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event);
/***************** structs and defines ****************/
@@ -213,12 +215,46 @@ typedef struct uiAfterFunc {
static int ui_but_contains_pt(uiBut *but, int mx, int my);
static int ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
-static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata);
+static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userdata);
static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
static void button_timers_tooltip_remove(bContext *C, uiBut *but);
/* ******************** menu navigation helpers ************** */
+/* assumes event type is MOUSEPAN */
+void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
+{
+ static int lastdy = 0;
+ int dy = event->prevy - event->y;
+
+ /* This event should be originally from event->type,
+ * converting wrong event into wheel is bad, see [#33803] */
+ BLI_assert(*type == MOUSEPAN);
+
+ /* sign differs, reset */
+ if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0))
+ lastdy = dy;
+ else {
+ lastdy += dy;
+
+ if (ABS(lastdy) > (int)UI_UNIT_Y) {
+ int dy = event->prevy - event->y;
+
+ if (U.uiflag2 & USER_TRACKPAD_NATURAL)
+ dy = -dy;
+
+ *val = KM_PRESS;
+
+ if (dy > 0)
+ *type = WHEELUPMOUSE;
+ else
+ *type = WHEELDOWNMOUSE;
+
+ lastdy = 0;
+ }
+ }
+}
+
static int ui_but_editable(uiBut *but)
{
return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR);
@@ -266,15 +302,15 @@ static uiBut *ui_but_last(uiBlock *block)
return NULL;
}
-static int ui_is_a_warp_but(uiBut *but)
+static bool ui_is_a_warp_but(uiBut *but)
{
if (U.uiflag & USER_CONTINUOUS_MOUSE) {
- if (ELEM6(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) {
- return TRUE;
+ if (ELEM7(but->type, NUM, NUMSLI, NUMABS, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) {
+ return true;
}
}
- return FALSE;
+ return false;
}
static float ui_mouse_scale_warp_factor(const short shift)
@@ -397,6 +433,17 @@ static void ui_apply_autokey_undo(bContext *C, uiBut *but)
/* try autokey */
ui_but_anim_autokey(C, but, scene, scene->r.cfra);
+
+ /* make a little report about what we've done! */
+ if (but->rnaprop) {
+ char *buf = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex);
+ if (buf) {
+ BKE_report(CTX_wm_reports(C), RPT_PROPERTY, buf);
+ MEM_freeN(buf);
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
+ }
+ }
}
static void ui_apply_but_funcs_after(bContext *C)
@@ -685,7 +732,7 @@ static void ui_apply_but_CHARTAB(bContext *C, uiBut *but, uiHandleButtonData *da
/* ****************** drag drop code *********************** */
-static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event)
+static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *event)
{
rcti rect;
int x = event->x, y = event->y;
@@ -709,20 +756,33 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event)
return BLI_rcti_isect_pt(&rect, x, y);
}
-static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
/* prevent other WM gestures to start while we try to drag */
WM_gestures_remove(C);
if (ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > U.dragthreshold) {
- wmDrag *drag;
-
+
button_activate_state(C, but, BUTTON_STATE_EXIT);
data->cancel = TRUE;
- drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but));
- 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));
+ if (ui_is_but_bool(but)) {
+ const bool is_set = (ui_get_but_val(but) != 0.0);
+ PointerRNA ptr;
+ WM_operator_properties_create(&ptr, "UI_OT_drag_toggle");
+ RNA_boolean_set(&ptr, "state", !is_set);
+ RNA_int_set(&ptr, "last_x", data->dragstartx);
+ RNA_int_set(&ptr, "last_y", data->dragstarty);
+ WM_operator_name_call(C, "UI_OT_drag_toggle", WM_OP_INVOKE_DEFAULT, &ptr);
+ WM_operator_properties_free(&ptr);
+ }
+ else {
+ wmDrag *drag;
+
+ drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but));
+ 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));
+ }
return 1;
}
@@ -1026,6 +1086,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
ui_apply_but_BUT(C, but, data);
break;
case TEX:
+ case SEARCH_MENU_UNLINK:
case SEARCH_MENU:
ui_apply_but_TEX(C, but, data);
break;
@@ -1125,7 +1186,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
/* ******************* drop event ******************** */
/* only call if event type is EVT_DROP */
-static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonData *data)
+static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data)
{
wmDrag *wmd;
ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
@@ -1133,7 +1194,7 @@ static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonD
for (wmd = drags->first; wmd; wmd = wmd->next) {
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
ID *id = (ID *)wmd->poin;
if (but->poin == NULL && but->rnapoin.data == NULL) {}
@@ -1197,37 +1258,44 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* RGB triple */
else if (but->type == COLOR) {
- float rgb[3];
+ float rgba[4];
if (but->poin == NULL && but->rnapoin.data == NULL) {
/* pass */
}
else if (mode == 'c') {
-
- ui_get_but_vectorf(but, rgb);
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ rgba[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
+ else
+ rgba[3] = 1.0f;
+
+ ui_get_but_vectorf(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(rgb, rgb);
+ srgb_to_linearrgb_v3_v3(rgba, rgba);
- BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f]", rgb[0], rgb[1], rgb[2]);
+ BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f, %f]", rgba[0], rgba[1], rgba[2], rgba[3]);
WM_clipboard_text_set(buf, 0);
}
else {
- if (sscanf(buf, "[%f, %f, %f]", &rgb[0], &rgb[1], &rgb[2]) == 3) {
+ if (sscanf(buf, "[%f, %f, %f, %f]", &rgba[0], &rgba[1], &rgba[2], &rgba[3]) == 4) {
/* assume linear colors in buffer */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
- linearrgb_to_srgb_v3_v3(rgb, rgb);
+ linearrgb_to_srgb_v3_v3(rgba, rgba);
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- ui_set_but_vectorf(but, rgb);
+ ui_set_but_vectorf(but, rgba);
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ RNA_property_float_set_index(&but->rnapoin, but->rnaprop, 3, rgba[3]);
+
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
}
/* text/string and ID data */
- else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ else if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
uiHandleButtonData *active_data = but->active;
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1246,7 +1314,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
if (ui_is_but_utf8(but)) BLI_strncpy_utf8(active_data->str, buf, active_data->maxlen);
else BLI_strncpy(active_data->str, buf, active_data->maxlen);
- if (but->type == SEARCH_MENU) {
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* else uiSearchboxData.active member is not updated [#26856] */
ui_searchbox_update(C, data->searchbox, but, 1);
}
@@ -1372,11 +1440,11 @@ static int ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
}
/* note, but->block->aspect is used here, when drawing button style is getting scaled too */
-static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, short x)
+static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, const float x)
{
uiStyle *style = UI_GetStyle(); // XXX pass on as arg
uiFontStyle *fstyle = &style->widget;
- int startx = but->rect.xmin;
+ float startx = but->rect.xmin;
char *origstr, password_str[UI_MAX_DRAW_STR];
uiStyleFontSet(fstyle);
@@ -1386,24 +1454,27 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
ui_button_text_password_hide(password_str, but, FALSE);
- origstr = MEM_callocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
+ origstr = MEM_mallocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
BLI_strncpy(origstr, but->drawstr, data->maxlen);
- /* XXX solve generic */
- if (but->type == NUM || but->type == NUMSLI)
+ /* XXX solve generic, see: #widget_draw_text_icon */
+ if (but->type == NUM || but->type == NUMSLI) {
startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect)));
- else if (ELEM(but->type, TEX, SEARCH_MENU)) {
- startx += 5;
- if (but->flag & UI_HAS_ICON)
+ }
+ else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (but->flag & UI_HAS_ICON) {
startx += UI_DPI_ICON_SIZE;
+ }
+ /* but this extra .05 makes clicks inbetween characters feel nicer */
+ startx += ((UI_TEXT_MARGIN_X + 0.05f) * U.widget_unit);
}
/* mouse dragged outside the widget to the left */
- if (x < startx && but->ofs > 0) {
+ if (x < startx) {
int i = but->ofs;
- origstr[but->ofs] = 0;
+ origstr[but->ofs] = '\0';
while (i > 0) {
if (BLI_str_cursor_step_prev_utf8(origstr, but->ofs, &i)) {
@@ -1419,21 +1490,18 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
but->ofs = i;
but->pos = but->ofs;
}
- /* mouse inside the widget */
- else if (x >= startx) {
+ /* mouse inside the widget, mouse coords mapped in widget space */
+ else { /* (x >= startx) */
int pos_i;
/* keep track of previous distance from the cursor to the char */
float cdist, cdist_prev = 0.0f;
short pos_prev;
-
- const float aspect_sqrt = sqrtf(but->block->aspect);
but->pos = pos_prev = strlen(origstr) - but->ofs;
- while (TRUE) {
- /* XXX does not take zoom level into account */
- cdist = startx + aspect_sqrt * BLF_width(fstyle->uifont_id, origstr + but->ofs);
+ while (true) {
+ cdist = startx + BLF_width(fstyle->uifont_id, origstr + but->ofs);
/* check if position is found */
if (cdist < x) {
@@ -1469,7 +1537,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
MEM_freeN(origstr);
}
-static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, short x)
+static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, const float x)
{
if (x > data->selstartx) data->selextend = EXTEND_RIGHT;
else if (x < data->selstartx) data->selextend = EXTEND_LEFT;
@@ -1556,7 +1624,7 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJump
}
else {
int pos_i = but->pos;
- BLI_str_cursor_step_utf8(str, len, &pos_i, direction, jump);
+ BLI_str_cursor_step_utf8(str, len, &pos_i, direction, jump, true);
but->pos = pos_i;
if (select) {
@@ -1625,7 +1693,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
else if (but->pos >= 0 && but->pos < len) {
int pos = but->pos;
int step;
- BLI_str_cursor_step_utf8(str, len, &pos, direction, jump);
+ BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
step = pos - but->pos;
memmove(&str[but->pos], &str[but->pos + step], (len + 1) - but->pos);
changed = 1;
@@ -1640,7 +1708,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
int pos = but->pos;
int step;
- BLI_str_cursor_step_utf8(str, len, &pos, direction, jump);
+ BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
step = but->pos - pos;
memmove(&str[but->pos - step], &str[but->pos], (len + 1) - but->pos);
but->pos -= step;
@@ -1674,10 +1742,11 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
{
char buf[UI_MAX_DRAW_STR] = {0};
char *str, *p, *pbuf;
- int len, x, i, changed = 0;
+ int x, changed = 0;
+ int str_len, buf_len;
str = data->str;
- len = strlen(str);
+ str_len = strlen(str);
/* paste */
if (paste) {
@@ -1687,28 +1756,28 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
if (p && p[0]) {
unsigned int y;
- i = 0;
- while (*p && *p != '\r' && *p != '\n' && i < UI_MAX_DRAW_STR - 1) {
- buf[i++] = *p;
+ buf_len = 0;
+ while (*p && *p != '\r' && *p != '\n' && buf_len < UI_MAX_DRAW_STR - 1) {
+ buf[buf_len++] = *p;
p++;
}
- buf[i] = 0;
+ buf[buf_len] = 0;
/* paste over the current selection */
if ((but->selend - but->selsta) > 0) {
ui_textedit_delete_selection(but, data);
- len = strlen(str);
+ str_len = strlen(str);
}
- for (y = 0; y < strlen(buf); y++) {
+ for (y = 0; y < buf_len; y++) {
/* add contents of buffer */
- if (len + 1 < data->maxlen) {
+ if (str_len + 1 < data->maxlen) {
for (x = data->maxlen; x > but->pos; x--)
str[x] = str[x - 1];
str[but->pos] = buf[y];
but->pos++;
- len++;
- str[len] = '\0';
+ str_len++;
+ str[str_len] = '\0';
}
}
@@ -1772,7 +1841,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
but->selend = len;
/* optional searchbox */
- if (but->type == SEARCH_MENU) {
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
data->searchbox = ui_searchbox_create(C, data->region, but);
ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */
}
@@ -1818,7 +1887,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
return;
for (but = actbut->next; but; but = but->next) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1827,7 +1896,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.first; but != actbut; but = but->next) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1846,7 +1915,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
return;
for (but = actbut->prev; but; but = but->prev) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1855,7 +1924,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.last; but != actbut; but = but->prev) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1866,7 +1935,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
-static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, changed = 0, inbox = 0, update = 0, retval = WM_UI_HANDLER_CONTINUE;
@@ -1874,6 +1943,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
case MOUSEMOVE:
+ case MOUSEPAN:
if (data->searchbox)
ui_searchbox_event(C, data->searchbox, but, event);
@@ -2057,7 +2127,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
ED_region_tag_redraw(data->region);
}
-static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, retval = WM_UI_HANDLER_CONTINUE;
@@ -2246,7 +2316,7 @@ int ui_button_open_menu_direction(uiBut *but)
/* ***************** events for different button types *************** */
-static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
@@ -2274,7 +2344,7 @@ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEv
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
@@ -2335,7 +2405,7 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
@@ -2360,7 +2430,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
@@ -2385,20 +2455,59 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ /* unlink icon is on right */
+ if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
+ ARegion *ar = CTX_wm_region(C);
+ rcti rect;
+ int x = event->x, y = event->y;
+
+ ui_window_to_block(ar, but->block, &x, &y);
+
+ BLI_rcti_rctf_copy(&rect, &but->rect);
+
+ rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
+ if ( BLI_rcti_isect_pt(&rect, x, y) ) {
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (data->str == NULL)
+ data->str = MEM_callocN(16, "temp str");
+ data->str[0] = 0;
+
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ return ui_do_but_TEX(C, block, but, data, event);
+}
+
+static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_is_but_bool(but)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_CONTINUE;
+ }
+
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
data->togdual = event->ctrl;
data->togonly = !event->shift;
button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
+ return WM_UI_HANDLER_CONTINUE;
}
}
+ else if (data->state == BUTTON_STATE_WAIT_DRAG) {
+ /* note: the 'BUTTON_STATE_WAIT_DRAG' part of 'ui_do_but_EXIT' could be refactored into its own function */
+ return ui_do_but_EXIT(C, but, data, event);
+ }
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
@@ -2415,6 +2524,12 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
return WM_UI_HANDLER_CONTINUE;
}
}
+ if (event->type == LEFTMOUSE && ui_is_but_bool(but)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_CONTINUE;
+ }
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
int ret = WM_UI_HANDLER_BREAK;
@@ -2519,6 +2634,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
{
float deler, tempf, softmin, softmax, softrange;
int lvalue, temp, changed = 0;
+ const bool is_float = ui_is_but_float(but);
if (mx == data->draglastx)
return changed;
@@ -2540,7 +2656,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
if (ui_is_a_warp_but(but)) {
/* Mouse location isn't screen clamped to the screen so use a linear mapping
* 2px == 1-int, or 1px == 1-ClickStep */
- if (ui_is_but_float(but)) {
+ if (is_float) {
fac *= 0.01f * but->a1;
tempf = (float)data->startvalue + ((float)(mx - data->dragstartx) * fac);
tempf = ui_numedit_apply_snapf(but, tempf, softmin, softmax, softrange, snap);
@@ -2597,21 +2713,21 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
else {
/* Use a non-linear mapping of the mouse drag especially for large floats (normal behavior) */
deler = 500;
- if (!ui_is_but_float(but)) {
+ if (!is_float) {
/* prevent large ranges from getting too out of control */
- if (softrange > 600) deler = powf(softrange, 0.75);
- else if (softrange < 100) deler = 200.0;
+ if (softrange > 600) deler = powf(softrange, 0.75f);
else if (softrange < 25) deler = 50.0;
+ else if (softrange < 100) deler = 100.0;
}
deler /= fac;
- if (softrange > 11) {
+ if ((is_float == true) && (softrange > 11)) {
/* non linear change in mouse input- good for high precicsion */
- data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(data->dragstartx - mx) * 0.002f);
+ data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(mx - data->dragstartx) / 500.0f);
}
- else if (softrange > 129) { /* only scale large int buttons */
+ else if ((is_float == false) && (softrange > 129)) { /* only scale large int buttons */
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
- data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(data->dragstartx - mx) * 0.004f);
+ data->dragf += (((float)(mx - data->draglastx)) / deler) * (fabsf(mx - data->dragstartx) / 250.0f);
}
else {
/*no scaling */
@@ -2623,7 +2739,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
tempf = (softmin + data->dragf * softrange);
- if (!ui_is_but_float(but)) {
+ if (!is_float) {
temp = floorf(tempf + 0.5f);
temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
@@ -2655,7 +2771,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
return changed;
}
-static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my; /* mouse location scaled to fit the UI */
int screen_mx, screen_my; /* mouse location kept at screen pixel coords */
@@ -2668,12 +2784,20 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_window_to_block(data->region, block, &mx, &my);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
/* XXX hardcoded keymap check.... */
- if (event->type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 1;
}
- else if (event->type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->alt) {
mx = but->rect.xmax;
click = 1;
}
@@ -2801,36 +2925,66 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return retval;
}
-static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short shift, const short ctrl, int mx)
+static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
+ const bool is_horizontal, const bool shift, const bool ctrl, int mx)
{
float deler, f, tempf, softmin, softmax, softrange;
- int temp, lvalue, changed = 0;
+ int temp, lvalue;
+ bool changed = false;
+ float mx_fl, my_fl;
+ /* note, 'offs' is really from the widget drawing rounded corners see 'widget_numslider' */
+ float offs;
softmin = but->softmin;
softmax = but->softmax;
softrange = softmax - softmin;
+ /* yes, 'mx' as both x/y is intentional */
+ ui_mouse_scale_warp(data, mx, mx, &mx_fl, &my_fl, shift);
+
if (but->type == NUMSLI) {
- deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
+ offs = (BLI_rctf_size_y(&but->rect) / 2.0f) * but->aspect;
+ deler = BLI_rctf_size_x(&but->rect) - offs;
}
else if (but->type == HSVSLI) {
- deler = (BLI_rctf_size_x(&but->rect) / 2.0f - 5.0f * but->aspect);
+ offs = (BLI_rctf_size_y(&but->rect) / 2.0f) * but->aspect;
+ deler = (BLI_rctf_size_x(&but->rect) / 2.0f) - offs;
}
else if (but->type == SCROLL) {
- int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
- float size = (horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect);
+ 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;
}
else {
- deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
+ offs = (BLI_rctf_size_y(&but->rect) / 2.0f) * but->aspect;
+ deler = (BLI_rctf_size_x(&but->rect) - offs);
}
- f = (float)(mx - data->dragstartx) / deler + data->dragfstart;
-
- if (shift)
- f = (f - data->dragfstart) / 10.0f + data->dragfstart;
-
+ f = (mx_fl - data->dragstartx) / deler + data->dragfstart;
CLAMP(f, 0.0f, 1.0f);
+
+
+ /* deal with mouse correction */
+#ifdef USE_CONT_MOUSE_CORRECT
+ if (ui_is_a_warp_but(but)) {
+ /* OK but can go outside bounds */
+ if (is_horizontal) {
+ data->ungrab_mval[0] = (but->rect.xmin + offs / but->aspect) + (f * deler);
+ data->ungrab_mval[1] = BLI_rctf_cent_y(&but->rect);
+ }
+ else {
+ data->ungrab_mval[1] = (but->rect.ymin + offs / but->aspect) + (f * deler);
+ data->ungrab_mval[0] = BLI_rctf_cent_x(&but->rect);
+ }
+ BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+ }
+#endif
+ if (is_horizontal == false) {
+ mx_fl = my_fl;
+ }
+ /* done correcting mouse */
+
+
tempf = softmin + f * softrange;
temp = floorf(tempf + 0.5f);
@@ -2866,7 +3020,7 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short
if (temp != lvalue) {
data->value = temp;
data->dragchange = 1;
- changed = 1;
+ changed = true;
}
}
else {
@@ -2875,14 +3029,14 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short
if (tempf != (float)data->value) {
data->value = tempf;
data->dragchange = 1;
- changed = 1;
+ changed = true;
}
}
return changed;
}
-static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, click = 0;
int retval = WM_UI_HANDLER_CONTINUE;
@@ -2892,12 +3046,20 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_window_to_block(data->region, block, &mx, &my);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
/* XXX hardcoded keymap check.... */
- if (event->type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 2;
}
- else if (event->type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->alt) {
mx = but->rect.xmax;
click = 2;
}
@@ -2945,7 +3107,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
click = 1;
}
else if (event->type == MOUSEMOVE) {
- if (ui_numedit_but_SLI(but, data, event->shift, event->ctrl, mx))
+ if (ui_numedit_but_SLI(but, data, true, event->shift, event->ctrl, mx))
ui_numedit_apply(C, block, but, data);
}
retval = WM_UI_HANDLER_BREAK;
@@ -3018,11 +3180,11 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return retval;
}
-static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my /*, click = 0 */;
int retval = WM_UI_HANDLER_CONTINUE;
- int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
+ bool horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
mx = event->x;
my = event->y;
@@ -3059,7 +3221,7 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (event->type == MOUSEMOVE) {
- if (ui_numedit_but_SLI(but, data, 0, 0, (horizontal) ? mx : my))
+ if (ui_numedit_but_SLI(but, data, horizontal, false, false, (horizontal) ? mx : my))
ui_numedit_apply(C, block, but, data);
}
@@ -3070,7 +3232,7 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
}
-static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
@@ -3084,6 +3246,12 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
return WM_UI_HANDLER_BREAK;
}
}
+ if (event->type == LEFTMOUSE && ui_is_but_bool(but)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_BREAK;
+ }
/* regular open menu */
if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
@@ -3123,7 +3291,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
}
}
else if (but->type == COLOR) {
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ if (ELEM3(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
float *hsv = ui_block_hsv_get(but->block);
float col[3];
@@ -3132,8 +3300,12 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
if (event->type == WHEELDOWNMOUSE)
hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f);
- else
+ else if (event->type == WHEELUPMOUSE)
hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f);
+ else {
+ float fac = 0.005 * (event->y - event->prevy);
+ hsv[2] = CLAMPIS(hsv[2] + fac, 0.0f, 1.0f);
+ }
hsv_to_rgb_v(hsv, data->vec);
ui_set_but_vectorf(but, data->vec);
@@ -3229,7 +3401,7 @@ static int ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, i
return changed;
}
-static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -3269,6 +3441,19 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
return WM_UI_HANDLER_CONTINUE;
}
+/* scales a vector so no axis exceeds max
+ * (could become BLI_math func) */
+static void clamp_axis_max_v3(float v[3], const float max)
+{
+ const float v_max = max_fff(v[0], v[1], v[2]);
+ if (v_max > max) {
+ mul_v3_fl(v, max / v_max);
+ if (v[0] > max) v[0] = max;
+ if (v[1] > max) v[1] = max;
+ if (v[2] > max) v[2] = max;
+ }
+}
+
static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my, const short shift)
{
float rgb[3];
@@ -3345,6 +3530,11 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
if (color_profile && ((int)but->a1 != UI_GRAD_SV))
ui_block_to_scene_linear_v3(but->block, rgb);
+ /* clamp because with color conversion we can exceed range [#34295] */
+ if ((int)but->a1 == UI_GRAD_V_ALT) {
+ clamp_axis_max_v3(rgb, but->softmax);
+ }
+
copy_v3_v3(data->vec, rgb);
data->draglastx = mx;
@@ -3415,7 +3605,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF
ui_set_but_vectorf(but, data->vec);
}
-static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -3615,7 +3805,7 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmND
}
-static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
mx = event->x;
@@ -3734,7 +3924,7 @@ static int ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx
return changed;
}
-static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
ColorBand *coba;
CBData *cbd;
@@ -3898,7 +4088,7 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
return changed;
}
-static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my, a, changed = 0;
@@ -4063,7 +4253,7 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize histogram widget itself */
- hist->height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ hist->height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
else {
/* scale histogram values (dy / 10 for better control) */
@@ -4080,7 +4270,7 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx
return changed;
}
-static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4147,7 +4337,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx,
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize waveform widget itself */
- scopes->wavefrm_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ scopes->wavefrm_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
else {
/* scale waveform values */
@@ -4163,7 +4353,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx,
return changed;
}
-static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4229,7 +4419,7 @@ static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize vectorscope widget itself */
- scopes->vecscope_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ scopes->vecscope_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
data->draglastx = mx;
@@ -4238,7 +4428,7 @@ static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int
return changed;
}
-static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4283,7 +4473,7 @@ static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHand
}
#ifdef WITH_INTERNATIONAL
-static int ui_do_but_CHARTAB(bContext *UNUSED(C), uiBlock *UNUSED(block), uiBut *UNUSED(but), uiHandleButtonData *UNUSED(data), wmEvent *UNUSED(event))
+static int ui_do_but_CHARTAB(bContext *UNUSED(C), uiBlock *UNUSED(block), uiBut *UNUSED(but), uiHandleButtonData *UNUSED(data), const wmEvent *UNUSED(event))
{
/* XXX 2.50 bad global and state access */
#if 0
@@ -4388,7 +4578,7 @@ static int ui_do_but_CHARTAB(bContext *UNUSED(C), uiBlock *UNUSED(block), uiBut
#endif
-static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
VECCOPY2D(but->linkto, event->mval);
@@ -4432,7 +4622,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa
if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize preview widget itself */
- scopes->track_preview_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my);
+ scopes->track_preview_height = (BLI_rctf_size_y(&but->rect) + (data->dragstarty - my)) / UI_DPI_FAC;
}
else {
if (!scopes->track_locked) {
@@ -4455,7 +4645,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa
return changed;
}
-static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4530,7 +4720,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
@@ -4562,7 +4752,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id;
@@ -4629,10 +4819,9 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
static int ui_but_menu(bContext *C, uiBut *but)
{
- ARegion *ar = CTX_wm_region(C);
uiPopupMenu *pup;
uiLayout *layout;
- int length;
+ bool is_array, is_array_component;
const char *name;
uiStringInfo label = {BUT_GET_LABEL, NULL};
@@ -4659,12 +4848,14 @@ static int ui_but_menu(bContext *C, uiBut *but)
if (is_anim)
is_anim = RNA_property_path_from_ID_check(&but->rnapoin, but->rnaprop);
- length = RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ /* determine if we can key a single component of an array */
+ is_array = RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0;
+ is_array_component = (is_array && but->rnaindex != -1);
/* Keyframes */
if (but->flag & UI_BUT_ANIMATED_KEY) {
/* replace/delete keyfraemes */
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Single Keyframe"),
@@ -4676,9 +4867,9 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
}
/* keyframe settings */
@@ -4690,7 +4881,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
/* pass */
}
else if (is_anim) {
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"),
@@ -4698,12 +4889,12 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 1);
}
}
if (but->flag & UI_BUT_ANIMATED) {
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Single Keyframes"),
@@ -4711,7 +4902,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
- ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 0);
+ ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 1);
}
}
@@ -4719,7 +4910,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
if (but->flag & UI_BUT_DRIVEN) {
uiItemS(layout);
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Drivers"),
ICON_NONE, "ANIM_OT_driver_button_remove", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"),
@@ -4727,7 +4918,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"),
- ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0);
+ ICON_NONE, "ANIM_OT_driver_button_remove", "all", 1);
}
uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"),
@@ -4743,7 +4934,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
else if (is_anim) {
uiItemS(layout);
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Drivers"),
ICON_NONE, "ANIM_OT_driver_button_add", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single Driver"),
@@ -4751,7 +4942,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"),
- ICON_NONE, "ANIM_OT_driver_button_add", "all", 0);
+ ICON_NONE, "ANIM_OT_driver_button_add", "all", 1);
}
if (ANIM_driver_can_paste()) {
@@ -4765,7 +4956,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
if (is_anim) {
uiItemS(layout);
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add All to Keying Set"),
ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single to Keying Set"),
@@ -4775,7 +4966,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
else {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 0);
+ ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 1);
uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
ICON_NONE, "ANIM_OT_keyingset_button_remove");
}
@@ -4788,15 +4979,15 @@ static int ui_but_menu(bContext *C, uiBut *but)
/* Copy Property Value
* Paste Property Value */
- if (length) {
+ if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset All to Default Values"),
ICON_NONE, "UI_OT_reset_default_button", "all", 1);
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"),
ICON_NONE, "UI_OT_reset_default_button", "all", 0);
}
else {
- uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
- ICON_NONE, "UI_OT_reset_default_button");
+ uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
+ ICON_NONE, "UI_OT_reset_default_button", "all", 1);
}
uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
@@ -4845,9 +5036,13 @@ static int ui_but_menu(bContext *C, uiBut *but)
}
/* Show header tools for header buttons. */
- if (ar->regiontype == RGN_TYPE_HEADER) {
- uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
- uiItemS(layout);
+ if (CTX_wm_region(C)) {
+ ARegion *ar = CTX_wm_region(C);
+ if (ar->regiontype == RGN_TYPE_HEADER) {
+
+ uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
+ uiItemS(layout);
+ }
}
{ /* Docs */
@@ -4912,7 +5107,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
return 1;
}
-static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
+static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
{
uiHandleButtonData *data;
int retval;
@@ -5074,6 +5269,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
case SEARCH_MENU:
retval = ui_do_but_TEX(C, block, but, data, event);
break;
+ case SEARCH_MENU_UNLINK:
+ retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
+ break;
case MENU:
case ICONROW:
case ICONTEXTROW:
@@ -5187,7 +5385,7 @@ int UI_but_active_drop_name(bContext *C)
uiBut *but = ui_but_find_activated(ar);
if (but) {
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU))
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK))
return 1;
}
@@ -5226,32 +5424,15 @@ static int ui_mouse_inside_region(ARegion *ar, int x, int y)
*/
if (ar->v2d.mask.xmin != ar->v2d.mask.xmax) {
View2D *v2d = &ar->v2d;
- rcti mask_rct;
int mx, my;
/* convert window coordinates to region coordinates */
mx = x;
my = y;
ui_window_to_region(ar, &mx, &my);
-
- /* make a copy of the mask rect, and tweak accordingly for hidden scrollbars */
- mask_rct = v2d->mask;
-
- if (v2d->scroll & (V2D_SCROLL_VERTICAL_HIDE | V2D_SCROLL_VERTICAL_FULLR)) {
- if (v2d->scroll & V2D_SCROLL_LEFT)
- mask_rct.xmin = v2d->vert.xmin;
- else if (v2d->scroll & V2D_SCROLL_RIGHT)
- mask_rct.xmax = v2d->vert.xmax;
- }
- if (v2d->scroll & (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_HORIZONTAL_FULLR)) {
- if (v2d->scroll & (V2D_SCROLL_BOTTOM | V2D_SCROLL_BOTTOM_O))
- mask_rct.ymin = v2d->hor.ymin;
- else if (v2d->scroll & V2D_SCROLL_TOP)
- mask_rct.ymax = v2d->hor.ymax;
- }
-
+
/* check if in the rect */
- if (!BLI_rcti_isect_pt(&mask_rct, mx, my))
+ if (!BLI_rcti_isect_pt(&v2d->mask, mx, my))
return 0;
}
@@ -5271,7 +5452,7 @@ static int ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y)
return 1;
}
-static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
+uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
{
uiBlock *block;
uiBut *but, *butover = NULL;
@@ -5530,7 +5711,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) {
+ if (ELEM3(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* XXX curve is temp */
}
else {
@@ -5585,7 +5766,8 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
}
-static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *but, int mousemove, int onfree)
+static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data,
+ const bool mousemove, const bool onfree)
{
uiBlock *block = but->block;
uiBut *bt;
@@ -5640,8 +5822,10 @@ static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *b
ED_region_tag_redraw(data->region);
/* clean up button */
- MEM_freeN(but->active);
- but->active = NULL;
+ if (but->active) {
+ MEM_freeN(but->active);
+ but->active = NULL;
+ }
but->flag &= ~(UI_ACTIVE | UI_SELECT);
but->flag |= UI_BUT_LAST_ACTIVE;
if (!onfree)
@@ -5664,7 +5848,7 @@ void ui_button_active_free(const bContext *C, uiBut *but)
if (but->active) {
data = but->active;
data->cancel = TRUE;
- button_activate_exit((bContext *)C, data, but, 0, 1);
+ button_activate_exit((bContext *)C, but, data, false, true);
}
}
@@ -5839,7 +6023,7 @@ void uiContextAnimUpdate(const bContext *C)
/************** handle activating a button *************/
-static uiBut *uit_but_find_open_event(ARegion *ar, wmEvent *event)
+static uiBut *uit_but_find_open_event(ARegion *ar, const wmEvent *event)
{
uiBlock *block;
uiBut *but;
@@ -5852,7 +6036,7 @@ static uiBut *uit_but_find_open_event(ARegion *ar, wmEvent *event)
return NULL;
}
-static int ui_handle_button_over(bContext *C, wmEvent *event, ARegion *ar)
+static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar)
{
uiBut *but;
@@ -5890,6 +6074,20 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but)
ui_do_button(C, but->block, but, &event);
}
+void ui_button_execute_do(struct bContext *C, struct ARegion *ar, uiBut *but)
+{
+ /* note: ideally we would not have to change 'but->active' howevwer
+ * some functions we call don't use data (as they should be doing) */
+ void *active_back = but->active;
+ uiHandleButtonData *data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData_Fake");
+ but->active = data;
+ data->region = ar;
+ ui_apply_button(C, but->block, but, data, true);
+ /* use onfree event so undo is handled by caller and apply is already done above */
+ button_activate_exit((bContext *)C, but, data, false, true);
+ but->active = active_back;
+}
+
static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type)
{
uiBut *oldbut;
@@ -5899,7 +6097,7 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
if (oldbut) {
data = oldbut->active;
data->cancel = TRUE;
- button_activate_exit(C, data, oldbut, 0, 0);
+ button_activate_exit(C, oldbut, data, false, false);
}
button_activate_init(C, ar, but, type);
@@ -5907,7 +6105,7 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
/************ handle events for an activated button ***********/
-static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
+static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
{
uiHandleButtonData *data;
uiBlock *block;
@@ -5968,19 +6166,18 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
retval = WM_UI_HANDLER_CONTINUE;
break;
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- case MIDDLEMOUSE:
- /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
- if (data->tooltiptimer) {
- WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
- data->tooltiptimer = NULL;
- }
- /* pass on purposedly */
- default:
- /* handle button type specific events */
- retval = ui_do_button(C, block, but, event);
}
+ /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE:
+ case MIDDLEMOUSE:
+ case MOUSEPAN:
+ button_timers_tooltip_remove(C, but);
+
+ /* pass on purposedly */
+ default:
+ /* handle button type specific events */
+ retval = ui_do_button(C, block, but, event);
}
}
else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
@@ -6072,7 +6269,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
postbut = data->postbut;
posttype = data->posttype;
- button_activate_exit(C, data, but, (postbut == NULL), 0);
+ button_activate_exit(C, but, data, (postbut == NULL), false);
/* for jumping to the next button with tab while text editing */
if (postbut)
@@ -6082,69 +6279,86 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
return retval;
}
-static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar)
+static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
{
uiBut *but = ui_list_find_mouse_over(ar, event->x, event->y);
int retval = WM_UI_HANDLER_CONTINUE;
int value, min, max;
+ int type = event->type, val = event->val;
- if (but && (event->val == KM_PRESS)) {
- Panel *pa = but->block->panel;
+ if (but) {
+ uiList *ui_list = but->custom_data;
- if (ELEM(event->type, UPARROWKEY, DOWNARROWKEY) ||
- ((ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
- {
- /* activate up/down the list */
- value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
+ if (ui_list) {
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+
+ /* if type still is mousepan, we call it handled, since delta-y accumulate */
+ /* also see wm_event_system.c do_wheel_ui hack */
+ if (type == MOUSEPAN)
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ if (val == KM_PRESS) {
+
+ if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
+ {
+ /* activate up/down the list */
+ value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
- if (ELEM(event->type, UPARROWKEY, WHEELUPMOUSE))
- value--;
- else
- value++;
+ if (ELEM(type, UPARROWKEY, WHEELUPMOUSE))
+ value--;
+ else
+ value++;
- CLAMP(value, 0, pa->list_last_len - 1);
+ CLAMP(value, 0, ui_list->list_last_len - 1);
- if (value < pa->list_scroll)
- pa->list_scroll = value;
- else if (value >= pa->list_scroll + pa->list_size)
- pa->list_scroll = value - pa->list_size + 1;
+ if (value < ui_list->list_scroll)
+ ui_list->list_scroll = value;
+ else if (value >= ui_list->list_scroll + ui_list->list_size)
+ ui_list->list_scroll = value - ui_list->list_size + 1;
- RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
- value = CLAMPIS(value, min, max);
+ RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
+ value = CLAMPIS(value, min, max);
- RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
- ED_region_tag_redraw(ar);
+ RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
- /* silly replacement for proper grip */
- if (pa->list_grip_size == 0)
- pa->list_grip_size = pa->list_size;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
+ /* silly replacement for proper grip */
+ if (ui_list->list_grip_size == 0)
+ ui_list->list_grip_size = ui_list->list_size;
- if (event->type == WHEELUPMOUSE)
- pa->list_grip_size--;
- else
- pa->list_grip_size++;
+ if (type == WHEELUPMOUSE)
+ ui_list->list_grip_size--;
+ else
+ ui_list->list_grip_size++;
- pa->list_grip_size = MAX2(pa->list_grip_size, 1);
+ ui_list->list_grip_size = MAX2(ui_list->list_grip_size, 1);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
- if (pa->list_last_len > pa->list_size) {
- /* list template will clamp */
- if (event->type == WHEELUPMOUSE)
- pa->list_scroll--;
- else
- pa->list_scroll++;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ if (ui_list->list_last_len > ui_list->list_size) {
+ /* list template will clamp */
+ if (type == WHEELUPMOUSE)
+ ui_list->list_scroll--;
+ else
+ ui_list->list_scroll++;
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
}
}
}
@@ -6152,7 +6366,7 @@ static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar)
return retval;
}
-static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *but)
+static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, uiBut *but)
{
uiHandleButtonData *data;
uiPopupBlockHandle *menu;
@@ -6184,7 +6398,7 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
if (menu->menuretval != UI_RETURN_OK)
data->cancel = TRUE;
- button_activate_exit(C, data, but, 1, 0);
+ 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)) {
@@ -6198,7 +6412,7 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
}
else {
data->cancel = TRUE;
- button_activate_exit(C, data, but, 1, 0);
+ button_activate_exit(C, but, data, true, false);
}
}
}
@@ -6324,7 +6538,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymax = max_ff(ymax, bt->rect.ymax);
- if (ymax + dy - UI_UNIT_Y*0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
+ if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD;
}
else {
@@ -6334,7 +6548,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymin = min_ff(ymin, bt->rect.ymin);
- if (ymin + dy + UI_UNIT_Y*0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
+ if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD;
}
@@ -6355,7 +6569,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
return 0;
}
-static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
{
ARegion *ar;
uiBlock *block;
@@ -6377,7 +6591,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
/* if there's an active modal button, don't check events or outside, except for search menu */
but = ui_but_find_activated(ar);
- if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU) {
+ if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK) {
/* if a button is activated modal, always reset the start mouse
* position of the towards mechanism to avoid loosing focus,
* and don't handle events */
@@ -6403,7 +6617,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
if (block->block_event_func && block->block_event_func(C, block, event)) {
/* pass */
} /* events not for active search menu button */
- else if (but == NULL || but->type != SEARCH_MENU) {
+ else if (but == NULL || (but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK)) {
switch (event->type) {
@@ -6450,31 +6664,40 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
case DOWNARROWKEY:
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
+ case MOUSEPAN:
/* arrowkeys: only handle for block_loop blocks */
if (event->alt || event->shift || event->ctrl || event->oskey) {
/* pass */
}
else if (inside || (block->flag & UI_BLOCK_LOOP)) {
- if (event->val == KM_PRESS) {
+ int type = event->type;
+ int val = event->val;
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN)
+ ui_pan_to_scroll(event, &type, &val);
+
+ if (val == KM_PRESS) {
+ const eButType type_flip = BUT | ROW;
PASS_EVENT_TO_PARENT_IF_NONACTIVE;
but = ui_but_find_activated(ar);
if (but) {
/* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */
- if (((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_TOP)))
+ 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 & BUT)
+ if (but->type & type_flip)
but = ui_but_next(but);
else
but = ui_but_prev(but);
}
else {
- if (but->type & BUT)
+ if (but->type & type_flip)
but = ui_but_prev(but);
else
but = ui_but_next(but);
@@ -6487,11 +6710,11 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
}
if (!but) {
- if (((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_TOP)))
+ 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 & BUT)) {
+ if ((bt = ui_but_first(block)) && (bt->type & type_flip)) {
bt = ui_but_last(block);
}
else {
@@ -6499,7 +6722,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
}
}
else {
- if ((bt = ui_but_first(block)) && (bt->type & BUT)) {
+ if ((bt = ui_but_first(block)) && (bt->type & type_flip)) {
/* keep ui_but_first() */
}
else {
@@ -6757,7 +6980,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
return retval;
}
-static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlockHandle *menu)
+static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
{
ARegion *ar;
uiBut *but;
@@ -6806,7 +7029,7 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
return WM_UI_HANDLER_BREAK;
}
-static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
{
uiBut *but;
uiHandleButtonData *data;
@@ -6828,7 +7051,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa
retval = ui_handle_menu_return_submenu(C, event, menu);
submenu = NULL; /* hint not to use this, it may be freed by call above */
(void)submenu;
- /* we may wan't to quit the submenu and handle the even in this menu,
+ /* we may want to quit the submenu and handle the even in this menu,
* if its important to use it, check 'data->menu' first */
if ((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) {
retval = ui_handle_menu_event(C, event, menu, level);
@@ -6844,7 +7067,7 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa
/* *************** UI event handlers **************** */
-static int ui_handler_region(bContext *C, wmEvent *event, void *UNUSED(userdata))
+static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
ARegion *ar;
uiBut *but;
@@ -6902,12 +7125,10 @@ static void ui_handler_remove_region(bContext *C, void *UNUSED(userdata))
ui_apply_but_funcs_after(C);
}
-static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(userdata))
+static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
ARegion *ar;
uiBut *but;
- uiHandleButtonData *data;
- int retval;
/* here we handle buttons at the window level, modal, for example
* while number sliding, text editing, or when a menu block is open */
@@ -6918,17 +7139,24 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user
but = ui_but_find_activated(ar);
if (but) {
+ uiHandleButtonData *data;
+
/* handle activated button events */
data = but->active;
if (data->state == BUTTON_STATE_MENU_OPEN) {
+ int retval;
+
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
- retval = ui_handle_menus_recursive(C, event, data->menu, 0);
+ if (data->menu)
+ retval = ui_handle_menus_recursive(C, event, data->menu, 0);
/* handle events for the activated button */
- if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- if (data->menu->menuretval)
+ if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
+ (event->type == TIMER))
+ {
+ if (data->menu && data->menu->menuretval)
ui_handle_button_return_submenu(C, event, but);
else
ui_handle_button_event(C, event, but);
@@ -6952,7 +7180,7 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user
}
/* two types of popups, one with operator + enum, other with regular callbacks */
-static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
+static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
{
uiPopupBlockHandle *menu = userdata;
@@ -6985,7 +7213,7 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
WM_operator_name_call(C, temp.optype->idname, temp.opcontext, NULL);
}
else if (temp.cancel_func)
- temp.cancel_func(temp.popup_arg);
+ temp.cancel_func(C, temp.popup_arg);
}
else {
/* re-enable tooltips */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index bb0cc1176d8..086e9dad895 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -49,6 +49,7 @@
#include "BLI_utildefines.h"
#include "DNA_brush_types.h"
+#include "DNA_dynamicpaint_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -74,21 +75,19 @@
#include "interface_intern.h"
-
-#define ICON_IMAGE_W 600
-#define ICON_IMAGE_H 640
-
#define ICON_GRID_COLS 26
#define ICON_GRID_ROWS 30
-#define ICON_GRID_MARGIN 5
-#define ICON_GRID_W 16
-#define ICON_GRID_H 16
+#define ICON_GRID_MARGIN 10
+#define ICON_GRID_W 32
+#define ICON_GRID_H 32
typedef struct IconImage {
int w;
int h;
- unsigned int *rect;
+ unsigned int *rect;
+ unsigned char *datatoc_rect;
+ int datatoc_size;
} IconImage;
typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
@@ -131,13 +130,13 @@ static IconTexture icongltex = {0, 0, 0, 0.0f, 0.0f};
/* **************************************************** */
-static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int size, int type)
+#ifndef WITH_HEADLESS
+
+static DrawInfo *def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int size, int type)
{
Icon *new_icon = NULL;
IconImage *iimg = NULL;
DrawInfo *di;
- int y = 0;
- int imgsize = 0;
new_icon = MEM_callocN(sizeof(Icon), "texicon");
@@ -154,17 +153,27 @@ static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int
di->data.texture.h = size;
}
else if (type == ICON_TYPE_BUFFER) {
- iimg = MEM_mallocN(sizeof(IconImage), "icon_img");
- iimg->rect = MEM_mallocN(size * size * sizeof(unsigned int), "icon_rect");
+ iimg = MEM_callocN(sizeof(IconImage), "icon_img");
iimg->w = size;
iimg->h = size;
- /* Here we store the rect in the icon - same as before */
- imgsize = bbuf->x;
- for (y = 0; y < size; y++) {
- memcpy(&iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], size * sizeof(int));
+ /* icon buffers can get initialized runtime now, via datatoc */
+ if (bbuf) {
+ int y, imgsize;
+
+ iimg->rect = MEM_mallocN(size * size * sizeof(unsigned int), "icon_rect");
+
+ /* Here we store the rect in the icon - same as before */
+ if (size == bbuf->x && size == bbuf->y && xofs == 0 && yofs == 0)
+ memcpy(iimg->rect, bbuf->rect, size * size * sizeof(int));
+ else {
+ /* this code assumes square images */
+ imgsize = bbuf->x;
+ for (y = 0; y < size; y++) {
+ memcpy(&iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], size * sizeof(int));
+ }
+ }
}
-
di->data.buffer.image = iimg;
}
@@ -172,6 +181,8 @@ static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int
new_icon->drawinfo = di;
BKE_icon_set(icon_id, new_icon);
+
+ return di;
}
static void def_internal_vicon(int icon_id, VectorDrawFunc drawFunc)
@@ -459,21 +470,23 @@ static void vicon_move_down_draw(int x, int y, int w, int h, float UNUSED(alpha)
}
#ifndef WITH_HEADLESS
+
static void init_brush_icons(void)
{
-#define INIT_BRUSH_ICON(icon_id, name) \
- { \
- bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_ ##name## _png, \
- datatoc_ ##name## _png_size, \
- IB_rect, NULL, "<brush icon>"); \
- def_internal_icon(bbuf, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
- IMB_freeImBuf(bbuf); \
- } (void)0
+#define INIT_BRUSH_ICON(icon_id, name) \
+ { \
+ unsigned char *rect = (unsigned char *)datatoc_ ##name## _png; \
+ int size = datatoc_ ##name## _png_size; \
+ DrawInfo *di; \
+ \
+ di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
+ di->data.buffer.image->datatoc_rect = rect; \
+ di->data.buffer.image->datatoc_size = size; \
+ }
/* end INIT_BRUSH_ICON */
- ImBuf *bbuf;
- const int w = 96;
+ const int w = 96; /* warning, brush size hardcoded in C, but it gets scaled */
INIT_BRUSH_ICON(ICON_BRUSH_ADD, add);
INIT_BRUSH_ICON(ICON_BRUSH_BLOB, blob);
@@ -509,15 +522,79 @@ static void init_brush_icons(void)
#undef INIT_BRUSH_ICON
}
+static void icon_verify_datatoc(IconImage *iimg)
+{
+ /* if it has own rect, things are all OK */
+ if (iimg->rect)
+ return;
+
+ if (iimg->datatoc_rect) {
+ ImBuf *bbuf = IMB_ibImageFromMemory(iimg->datatoc_rect,
+ iimg->datatoc_size, IB_rect, NULL, "<matcap icon>");
+ /* w and h were set on initialize */
+ if (bbuf->x != iimg->h && bbuf->y != iimg->w)
+ IMB_scaleImBuf(bbuf, iimg->w, iimg->h);
+
+ iimg->rect = bbuf->rect;
+ bbuf->rect = NULL;
+ IMB_freeImBuf(bbuf);
+ }
+}
+
+static void init_matcap_icons(void)
+{
+ /* dynamic allocation now, tucking datatoc pointers in DrawInfo */
+#define INIT_MATCAP_ICON(icon_id, name) \
+ { \
+ unsigned char *rect = (unsigned char *)datatoc_ ##name## _jpg; \
+ int size = datatoc_ ##name## _jpg_size; \
+ DrawInfo *di; \
+ \
+ di = def_internal_icon(NULL, icon_id, 0, 0, 96, ICON_TYPE_BUFFER); \
+ di->data.buffer.image->datatoc_rect = rect; \
+ di->data.buffer.image->datatoc_size = size; \
+ } (void)0
+
+ INIT_MATCAP_ICON(ICON_MATCAP_01, mc01);
+ INIT_MATCAP_ICON(ICON_MATCAP_02, mc02);
+ INIT_MATCAP_ICON(ICON_MATCAP_03, mc03);
+ INIT_MATCAP_ICON(ICON_MATCAP_04, mc04);
+ INIT_MATCAP_ICON(ICON_MATCAP_05, mc05);
+ INIT_MATCAP_ICON(ICON_MATCAP_06, mc06);
+ INIT_MATCAP_ICON(ICON_MATCAP_07, mc07);
+ INIT_MATCAP_ICON(ICON_MATCAP_08, mc08);
+ INIT_MATCAP_ICON(ICON_MATCAP_09, mc09);
+ INIT_MATCAP_ICON(ICON_MATCAP_10, mc10);
+ INIT_MATCAP_ICON(ICON_MATCAP_11, mc11);
+ INIT_MATCAP_ICON(ICON_MATCAP_12, mc12);
+ INIT_MATCAP_ICON(ICON_MATCAP_13, mc13);
+ INIT_MATCAP_ICON(ICON_MATCAP_14, mc14);
+ INIT_MATCAP_ICON(ICON_MATCAP_15, mc15);
+ INIT_MATCAP_ICON(ICON_MATCAP_16, mc16);
+ INIT_MATCAP_ICON(ICON_MATCAP_17, mc17);
+ INIT_MATCAP_ICON(ICON_MATCAP_18, mc18);
+ INIT_MATCAP_ICON(ICON_MATCAP_19, mc19);
+ INIT_MATCAP_ICON(ICON_MATCAP_20, mc20);
+ INIT_MATCAP_ICON(ICON_MATCAP_21, mc21);
+ INIT_MATCAP_ICON(ICON_MATCAP_22, mc22);
+ INIT_MATCAP_ICON(ICON_MATCAP_23, mc23);
+ INIT_MATCAP_ICON(ICON_MATCAP_24, mc24);
+
+#undef INIT_MATCAP_ICON
+
+}
+
static void init_internal_icons(void)
{
- bTheme *btheme = UI_GetTheme();
- ImBuf *bbuf = NULL;
+// bTheme *btheme = UI_GetTheme();
+ ImBuf *b16buf = NULL, *b32buf = NULL;
int x, y, icontype;
- char iconfilestr[FILE_MAX];
-
+
+#if 0 // temp disabled
if ((btheme != NULL) && btheme->tui.iconfile[0]) {
char *icondir = BLI_get_folder(BLENDER_DATAFILES, "icons");
+ char iconfilestr[FILE_MAX];
+
if (icondir) {
BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL); /* if the image is missing bbuf will just be NULL */
@@ -531,11 +608,20 @@ static void init_internal_icons(void)
printf("%s: 'icons' data path not found, continuing\n", __func__);
}
}
- if (bbuf == NULL)
- bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png,
- datatoc_blender_icons_png_size, IB_rect, NULL, "<blender icons>");
-
- if (bbuf) {
+#endif
+ if (b16buf == NULL)
+ b16buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons16_png,
+ datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>");
+ if (b16buf)
+ IMB_premultiply_alpha(b16buf);
+
+ if (b32buf == NULL)
+ b32buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons32_png,
+ datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>");
+ if (b32buf)
+ IMB_premultiply_alpha(b32buf);
+
+ if (b16buf && b32buf) {
/* free existing texture if any */
if (icongltex.id) {
glDeleteTextures(1, &icongltex.id);
@@ -547,17 +633,31 @@ static void init_internal_icons(void)
glGenTextures(1, &icongltex.id);
if (icongltex.id) {
- icongltex.w = bbuf->x;
- icongltex.h = bbuf->y;
- icongltex.invw = 1.0f / bbuf->x;
- icongltex.invh = 1.0f / bbuf->y;
+ int level = 2;
+
+ icongltex.w = b32buf->x;
+ icongltex.h = b32buf->y;
+ icongltex.invw = 1.0f / b32buf->x;
+ icongltex.invh = 1.0f / b32buf->y;
glBindTexture(GL_TEXTURE_2D, icongltex.id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bbuf->x, bbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, b32buf->x, b32buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b32buf->rect);
+ glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect);
+
+ while (b16buf->x > 1) {
+ ImBuf *nbuf = IMB_onehalf(b16buf);
+ glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, nbuf->x, nbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nbuf->rect);
+ level++;
+ IMB_freeImBuf(b16buf);
+ b16buf = nbuf;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
glBindTexture(GL_TEXTURE_2D, 0);
-
+
if (glGetError() == GL_OUT_OF_MEMORY) {
glDeleteTextures(1, &icongltex.id);
icongltex.id = 0;
@@ -571,10 +671,10 @@ static void init_internal_icons(void)
else
icontype = ICON_TYPE_BUFFER;
- if (bbuf) {
+ if (b32buf) {
for (y = 0; y < ICON_GRID_ROWS; y++) {
for (x = 0; x < ICON_GRID_COLS; x++) {
- def_internal_icon(bbuf, BIFICONID_FIRST + y * ICON_GRID_COLS + x,
+ def_internal_icon(b32buf, BIFICONID_FIRST + y * ICON_GRID_COLS + x,
x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W,
icontype);
@@ -584,8 +684,8 @@ static void init_internal_icons(void)
def_internal_vicon(VICO_VIEW3D_VEC, vicon_view3d_draw);
def_internal_vicon(VICO_EDIT_VEC, vicon_edit_draw);
- def_internal_vicon(VICO_EDITMODE_DEHLT, vicon_editmode_dehlt_draw);
- def_internal_vicon(VICO_EDITMODE_HLT, vicon_editmode_hlt_draw);
+ def_internal_vicon(VICO_EDITMODE_VEC_DEHLT, vicon_editmode_dehlt_draw);
+ def_internal_vicon(VICO_EDITMODE_VEC_HLT, vicon_editmode_hlt_draw);
def_internal_vicon(VICO_DISCLOSURE_TRI_RIGHT_VEC, vicon_disclosure_tri_right_draw);
def_internal_vicon(VICO_DISCLOSURE_TRI_DOWN_VEC, vicon_disclosure_tri_down_draw);
def_internal_vicon(VICO_MOVE_UP_VEC, vicon_move_up_draw);
@@ -593,7 +693,9 @@ static void init_internal_icons(void)
def_internal_vicon(VICO_X_VEC, vicon_x_draw);
def_internal_vicon(VICO_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw);
- IMB_freeImBuf(bbuf);
+ IMB_freeImBuf(b16buf);
+ IMB_freeImBuf(b32buf);
+
}
#endif /* WITH_HEADLESS */
@@ -689,6 +791,8 @@ static void free_iconfile_list(struct ListBase *list)
}
}
+#endif /* WITH_HEADLESS */
+
int UI_iconfile_get_index(const char *filename)
{
IconFile *ifile;
@@ -731,7 +835,8 @@ void UI_icons_free_drawinfo(void *drawinfo)
if (di) {
if (di->type == ICON_TYPE_BUFFER) {
if (di->data.buffer.image) {
- MEM_freeN(di->data.buffer.image->rect);
+ if (di->data.buffer.image->rect)
+ MEM_freeN(di->data.buffer.image->rect);
MEM_freeN(di->data.buffer.image);
}
}
@@ -750,7 +855,7 @@ static DrawInfo *icon_create_drawinfo(void)
return di;
}
-/* note!, returns unscaled by DPI, may need to multiply result by UI_DPI_ICON_FAC */
+/* note!, returns unscaled by DPI */
int UI_icon_get_width(int icon_id)
{
Icon *icon = NULL;
@@ -811,6 +916,7 @@ void UI_icons_init(int first_dyn_id)
BKE_icons_init(first_dyn_id);
init_internal_icons();
init_brush_icons();
+ init_matcap_icons();
#endif
}
@@ -860,6 +966,34 @@ static void icon_set_image(bContext *C, ID *id, PreviewImage *prv_img, enum eIco
prv_img->w[size], prv_img->h[size]);
}
+PreviewImage *UI_icon_to_preview(int icon_id)
+{
+ Icon *icon = BKE_icon_get(icon_id);
+
+ if (icon) {
+ DrawInfo *di = (DrawInfo *)icon->drawinfo;
+ if (di && di->data.buffer.image) {
+ ImBuf *bbuf;
+
+ bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size, IB_rect, NULL, "<matcap buffer>");
+ if (bbuf) {
+ PreviewImage *prv = BKE_previewimg_create();
+
+ prv->rect[0] = bbuf->rect;
+
+ prv->w[0] = bbuf->x;
+ prv->h[0] = bbuf->y;
+
+ bbuf->rect = NULL;
+ IMB_freeImBuf(bbuf);
+
+ return prv;
+ }
+ }
+ }
+ return NULL;
+}
+
static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect), int rw, int rh,
unsigned int *rect, float alpha, const float rgb[3], short is_preview)
{
@@ -920,7 +1054,7 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
float x1, x2, y1, y2;
if (rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha);
- else glColor4f(1.0f, 1.0f, 1.0f, alpha);
+ else glColor4f(alpha, alpha, alpha, alpha);
x1 = ix * icongltex.invw;
x2 = (ix + ih) * icongltex.invw;
@@ -930,6 +1064,9 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, icongltex.id);
+ /* sharper downscaling, has no effect when scale matches with a mip level */
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -0.5f);
+
glBegin(GL_QUADS);
glTexCoord2f(x1, y1);
glVertex2f(x, y);
@@ -944,6 +1081,8 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
glVertex2f(x, y + h);
glEnd();
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.0f);
+
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
@@ -958,6 +1097,8 @@ static int get_draw_size(enum eIconSizes size)
return 0;
}
+
+
static void icon_draw_size(float x, float y, int icon_id, float aspect, float alpha, const float rgb[3],
enum eIconSizes size, int draw_size, int UNUSED(nocreate), short is_preview)
{
@@ -965,7 +1106,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
Icon *icon = NULL;
DrawInfo *di = NULL;
IconImage *iimg;
- float fdraw_size = is_preview ? draw_size : (draw_size * UI_DPI_ICON_FAC);
+ const float fdraw_size = (float)draw_size;
int w, h;
icon = BKE_icon_get(icon_id);
@@ -993,19 +1134,26 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
if (di->type == ICON_TYPE_VECTOR) {
/* vector icons use the uiBlock transformation, they are not drawn
* with untransformed coordinates like the other icons */
- di->data.vector.func((int)x, (int)y, ICON_DEFAULT_HEIGHT, ICON_DEFAULT_HEIGHT, 1.0f);
+ di->data.vector.func((int)x, (int)y, w, h, 1.0f);
}
else if (di->type == ICON_TYPE_TEXTURE) {
+ /* texture image use premul alpha for correct scaling */
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
icon_draw_texture(x, y, (float)w, (float)h, di->data.texture.x, di->data.texture.y,
di->data.texture.w, di->data.texture.h, alpha, rgb);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_BUFFER) {
/* it is a builtin icon */
iimg = di->data.buffer.image;
-
+#ifndef WITH_HEADLESS
+ icon_verify_datatoc(iimg);
+#endif
if (!iimg->rect) return; /* something has gone wrong! */
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, is_preview);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_PREVIEW) {
PreviewImage *pi = BKE_previewimg_get((ID *)icon->obj);
@@ -1141,6 +1289,44 @@ int ui_id_icon_get(bContext *C, ID *id, int big)
return iconid;
}
+int UI_rnaptr_icon_get(bContext *C, PointerRNA *ptr, int rnaicon, int big)
+{
+ ID *id = NULL;
+
+ if (!ptr->data)
+ return rnaicon;
+
+ /* try ID, material, texture or dynapaint slot */
+ if (RNA_struct_is_ID(ptr->type)) {
+ id = ptr->id.data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_MaterialSlot)) {
+ id = RNA_pointer_get(ptr, "material").data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_TextureSlot)) {
+ id = RNA_pointer_get(ptr, "texture").data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_DynamicPaintSurface)) {
+ DynamicPaintSurface *surface = (DynamicPaintSurface *)ptr->data;
+
+ if (surface->format == MOD_DPAINT_SURFACE_F_PTEX)
+ return ICON_TEXTURE_SHADED;
+ else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX)
+ return ICON_OUTLINER_DATA_MESH;
+ else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
+ return ICON_FILE_IMAGE;
+ }
+
+ /* get icon from ID */
+ if (id) {
+ int icon = ui_id_icon_get(C, id, big);
+
+ return icon ? icon : rnaicon;
+ }
+
+ return rnaicon;
+}
+
static void icon_draw_at_size(float x, float y, int icon_id, float aspect, float alpha, enum eIconSizes size, int nocreate)
{
int draw_size = get_draw_size(size);
@@ -1158,9 +1344,10 @@ void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, cons
icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, ICON_SIZE_ICON, draw_size, FALSE, FALSE);
}
+/* draws icon with dpi scale factor */
void UI_icon_draw(float x, float y, int icon_id)
{
- UI_icon_draw_aspect(x, y, icon_id, 1.0f, 1.0f);
+ UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f);
}
void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 23d3810e058..f0e59f1f935 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -267,10 +267,13 @@ struct uiBut {
void *dragpoin;
struct ImBuf *imb;
float imb_scale;
-
+
/* active button data */
struct uiHandleButtonData *active;
+ /* Custom button data. */
+ void *custom_data;
+
char *editstr;
double *editval;
float *editvec;
@@ -316,7 +319,7 @@ struct uiBlock {
void *handle_func_arg;
/* custom extra handling */
- int (*block_event_func)(const struct bContext *C, struct uiBlock *, struct wmEvent *);
+ int (*block_event_func)(const struct bContext *C, struct uiBlock *, const struct wmEvent *);
/* extra draw function for custom blocks */
void (*drawextra)(const struct bContext *C, void *idv, void *arg1, void *arg2, rcti *rect);
@@ -358,7 +361,7 @@ struct uiBlock {
char color_profile; /* color profile for correcting linear colors for display */
- char *display_device; /* display device name used to display this block,
+ const char *display_device; /* display device name used to display this block,
* used by color widgets to transform colors from/to scene linear
*/
};
@@ -403,6 +406,7 @@ extern void ui_set_but_soft_range(uiBut *but, double value);
extern void ui_check_but(uiBut *but);
extern int ui_is_but_float(uiBut *but);
+extern int ui_is_but_bool(uiBut *but);
extern int ui_is_but_unit(uiBut *but);
extern int ui_is_but_rna_valid(uiBut *but);
extern int ui_is_but_utf8(uiBut *but);
@@ -426,7 +430,7 @@ struct uiPopupBlockHandle {
int popup;
void (*popup_func)(struct bContext *C, void *arg, int event);
- void (*cancel_func)(void *arg);
+ void (*cancel_func)(struct bContext *C, void *arg);
void *popup_arg;
struct wmTimer *scrolltimer;
@@ -465,7 +469,7 @@ ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBu
int ui_searchbox_inside(struct ARegion *ar, int x, int y);
void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, int reset);
void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
-void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, struct wmEvent *event);
+void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event);
void 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);
@@ -486,13 +490,13 @@ int ui_step_name_menu(uiBut *but, int step);
struct AutoComplete;
/* interface_panel.c */
-extern int ui_handler_panel_region(struct bContext *C, struct wmEvent *event);
+extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *event);
extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, rcti *rect);
/* interface_draw.c */
extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
-void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha);
+void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha);
void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
@@ -504,7 +508,9 @@ void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rct
void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
/* interface_handlers.c */
+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_execute_do(struct bContext *C, struct ARegion *ar, uiBut *but);
extern void ui_button_active_free(const struct bContext *C, uiBut *but);
extern int ui_button_is_active(struct ARegion *ar);
extern int ui_button_open_menu_direction(uiBut *but);
@@ -517,8 +523,8 @@ void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
uiWidgetColors *ui_tooltip_get_theme(void);
void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock * block, rcti * rect);
void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect);
-int ui_link_bezier_points(rcti * rect, float coord_array[][2], int resol);
-void ui_draw_link_bezier(rcti *rect);
+int ui_link_bezier_points(const rcti * rect, float coord_array[][2], int resol);
+void ui_draw_link_bezier(const rcti *rect);
extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
/* theme color init */
@@ -533,6 +539,8 @@ extern unsigned char checker_stipple_sml[32 * 32 / 8];
#define UI_TRANSP_DARK 100
#define UI_TRANSP_LIGHT 160
+#define UI_TEXT_MARGIN_X 0.4f
+
/* interface_style.c */
void uiStyleInit(void);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 9759c22f30e..c69f53a53d2 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -65,8 +65,6 @@
#define RNA_NO_INDEX -1
#define RNA_ENUM_VALUE -2
-#define EM_SEPR_X 6
-#define EM_SEPR_Y 6
// #define USE_OP_RESET_BUT // we may want to make this optional, disable for now.
@@ -188,13 +186,13 @@ static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_
static int ui_item_fit(int item, int pos, int all, int available, int last, int alignment, int *offset)
{
+ if (offset)
+ *offset = 0;
+
/* available == 0 is unlimited */
if (available == 0)
return item;
-
- if (offset)
- *offset = 0;
-
+
if (all > available) {
/* contents is bigger than available space */
if (last)
@@ -227,14 +225,16 @@ static int ui_layout_vary_direction(uiLayout *layout)
/* estimated size of text + icon */
static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, int compact)
{
+ float f5 = 0.25f * UI_UNIT_X;
+ float f10 = 0.5f * UI_UNIT_X;
int variable = ui_layout_vary_direction(layout) == UI_ITEM_VARY_X;
if (icon && !name[0])
return UI_UNIT_X; /* icon only */
else if (icon)
- return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */
+ return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */
else
- return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */
+ return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */
}
static void ui_item_size(uiItem *item, int *r_w, int *r_h)
@@ -346,7 +346,9 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
}
/* 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)
+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)
{
uiStyle *style = layout->root->style;
uiBut *but;
@@ -489,7 +491,14 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free);
- uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1));
+ /* we dont want nested rows, cols in menus */
+ if (layout->root->type != UI_LAYOUT_MENU) {
+ uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1));
+ }
+ else {
+ uiBlockSetCurLayout(block, layout);
+ }
+
for (a = 0; a < totitem; a++) {
if (!item[a].identifier[0])
continue;
@@ -615,6 +624,18 @@ void uiFileBrowseContextProperty(const bContext *C, PointerRNA *ptr, PropertyRNA
/********************* Button Items *************************/
+/**
+ * Update a buttons tip with an enum's description if possible.
+ */
+static void ui_but_tip_from_enum_item(uiBut *but, EnumPropertyItem *item)
+{
+ if (but->tip == NULL || but->tip[0] == '\0') {
+ if (item->description && item->description[0]) {
+ but->tip = item->description;
+ }
+ }
+}
+
/* disabled item */
static void ui_item_disabled(uiLayout *layout, const char *name)
{
@@ -718,8 +739,11 @@ static const char *ui_menu_enumpropname(uiLayout *layout, PointerRNA *ptr, Prope
int totitem, free;
const char *name;
- RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free);
- if (RNA_enum_name(item, retval, &name) == 0) {
+ RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free);
+ if (RNA_enum_name(item, retval, &name)) {
+ name = CTX_IFACE_(RNA_property_translation_context(prop), name);
+ }
+ else {
name = "";
}
@@ -825,6 +849,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
else {
uiItemEnumO_ptr__internal(column, ot, item[i].name, item[i].icon, prop, item[i].value);
}
+ ui_but_tip_from_enum_item(block->buttons.last, &item[i]);
}
else {
if (item[i].name) {
@@ -837,6 +862,8 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
uiItemL(column, item[i].name, ICON_NONE);
bt = block->buttons.last;
bt->flag = UI_TEXT_LEFT;
+
+ ui_but_tip_from_enum_item(bt, &item[i]);
}
else { /* XXX bug here, colums draw bottom item badly */
uiItemS(column);
@@ -904,10 +931,11 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char
UI_OPERATOR_ERROR_RET(ot, opname, return );
WM_operator_properties_create_ptr(&ptr, ot);
-
+
/* enum lookup */
if ((prop = RNA_struct_find_property(&ptr, propname))) {
- RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
+ /* no need for translations here */
+ RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
if (item == NULL || RNA_enum_value_from_id(item, value_str, &value) == 0) {
if (free) {
MEM_freeN(item);
@@ -924,9 +952,9 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char
RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
return;
}
-
+
RNA_property_enum_set(&ptr, prop, value);
-
+
/* same as uiItemEnumO */
if (!name)
name = ui_menu_enumpropname(layout, &ptr, prop, value);
@@ -1172,7 +1200,7 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
return;
}
- RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
+ RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
if (!RNA_enum_value_from_id(item, value, &ivalue)) {
if (free) {
@@ -1185,7 +1213,9 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
for (a = 0; item[a].identifier; a++) {
if (item[a].value == ivalue) {
- uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, name ? name : item[a].name, icon ? icon : item[a].icon);
+ const char *item_name = CTX_IFACE_(RNA_property_translation_context(prop), item[a].name);
+
+ uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, item_name ? item_name : name, icon ? icon : item[a].icon);
break;
}
}
@@ -1224,6 +1254,7 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname
for (i = 0; i < totitem; i++) {
if (item[i].identifier[0]) {
uiItemEnumR(column, item[i].name, ICON_NONE, ptr, propname, item[i].value);
+ ui_but_tip_from_enum_item(block->buttons.last, &item[i]);
}
else {
if (item[i].name) {
@@ -1236,6 +1267,8 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname
uiItemL(column, item[i].name, ICON_NONE);
bt = block->buttons.last;
bt->flag = UI_TEXT_LEFT;
+
+ ui_but_tip_from_enum_item(bt, &item[i]);
}
else
uiItemS(column);
@@ -1378,7 +1411,11 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
/* turn button into search button */
if (searchprop) {
- but->type = SEARCH_MENU;
+ if (RNA_property_flag(prop) & PROP_NEVER_UNLINK)
+ but->type = SEARCH_MENU;
+ else
+ but->type = SEARCH_MENU_UNLINK;
+
but->hardmax = MAX2(but->hardmax, 256.0f);
but->rnasearchpoin = *searchptr;
but->rnasearchprop = searchprop;
@@ -1448,6 +1485,7 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna
block = uiLayoutGetBlock(layout);
ui_item_rna_size(layout, name, icon, ptr, prop, 0, 0, &w, &h);
+ w += UI_UNIT_X; /* X icon needs more space */
but = ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h, 0);
ui_but_add_search(but, ptr, prop, searchptr, searchprop);
@@ -1466,7 +1504,13 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
printf("%s: opening menu \"%s\"\n", __func__, mt->idname);
}
+ if (layout->context)
+ CTX_store_set(C, layout->context);
+
mt->draw(C, &menu);
+
+ if (layout->context)
+ CTX_store_set(C, NULL);
}
static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN, const char *tip)
@@ -1489,7 +1533,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre
h = UI_UNIT_Y;
if (layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */
- w -= 10;
+ w -= UI_UNIT_Y / 2;
if (name[0] && icon)
but = uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip);
@@ -1604,7 +1648,7 @@ void uiItemS(uiLayout *layout)
uiBlock *block = layout->root->block;
uiBlockSetCurLayout(block, layout);
- uiDefBut(block, SEPR, 0, "", 0, 0, EM_SEPR_X, EM_SEPR_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, SEPR, 0, "", 0, 0, 0.3f * UI_UNIT_X, 0.3f * UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
/* level items */
@@ -2294,11 +2338,14 @@ uiLayout *uiLayoutBox(uiLayout *layout)
return (uiLayout *)ui_layout_box(layout, ROUNDBOX);
}
-uiLayout *uiLayoutListBox(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr, PropertyRNA *actprop)
+uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr,
+ PropertyRNA *actprop)
{
uiLayoutItemBx *box = ui_layout_box(layout, LISTBOX);
uiBut *but = box->roundbox;
+ but->custom_data = ui_list;
+
but->rnasearchpoin = *ptr;
but->rnasearchprop = prop;
but->rnapoin = *actptr;
@@ -2935,7 +2982,7 @@ 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, 18, 20,
+ but = uiDefIconTextBut(block, 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);
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index e57e52d74b6..d48d699d881 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -661,11 +661,12 @@ static int reports_to_text_poll(bContext *C)
static int reports_to_text_exec(bContext *C, wmOperator *UNUSED(op))
{
ReportList *reports = CTX_wm_reports(C);
+ Main *bmain = CTX_data_main(C);
Text *txt;
char *str;
/* create new text-block to write to */
- txt = BKE_text_add("Recent Reports");
+ txt = BKE_text_add(bmain, "Recent Reports");
/* convert entire list to a display string, and add this to the text-block
* - if commandline debug option enabled, show debug reports too
@@ -803,7 +804,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op,
}
if (text == NULL) {
- text = BKE_text_load(filepath, bmain->name);
+ text = BKE_text_load(bmain, filepath, bmain->name);
}
if (text == NULL) {
@@ -1070,6 +1071,222 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot)
ot->exec = reloadtranslation_exec;
}
+
+/* -------------------------------------------------------------------- */
+/* Toggle Drag Operator */
+
+typedef struct DragOpInfo {
+ bool xy_lock[2];
+ float but_cent_start[2];
+ eButType but_type_start;
+} DragOpInfo;
+
+typedef struct DragOpPlotData {
+ bContext *C;
+ ARegion *ar;
+ bool is_set;
+ eButType but_type_start;
+ bool do_draw;
+ const uiBut *but_prev;
+} DragOpPlotData;
+
+static const uiBut *ui_but_set_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
+ const int xy[2], const uiBut *but_prev)
+{
+ uiBut *but = ui_but_find_mouse_over(ar, xy[0], xy[1]);
+
+ if (but_prev == but) {
+ return but_prev;
+ }
+
+ if (but && ui_is_but_bool(but) && but->type == but_type_start) {
+ /* is it pressed? */
+ bool is_set_but = (ui_get_but_val(but) != 0.0);
+ BLI_assert(ui_is_but_bool(but) == true);
+ if (is_set_but != is_set) {
+ uiButExecute(C, but);
+ return but;
+ }
+ }
+
+ return but_prev;
+}
+
+static int ui_but_set_cb(int x, int y, void *data_v)
+{
+ DragOpPlotData *data = data_v;
+ int xy[2] = {x, y};
+ data->but_prev = ui_but_set_xy(data->C, data->ar, data->is_set, data->but_type_start, xy, data->but_prev);
+ return 1; /* keep going */
+}
+
+/* operates on buttons between 2 mouse-points */
+static bool ui_but_set_xy_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
+ const int xy_src[2], const int xy_dst[2])
+{
+ DragOpPlotData data;
+ data.C = C;
+ data.ar = ar;
+ data.is_set = is_set;
+ data.but_type_start = but_type_start;
+ data.do_draw = false;
+ data.but_prev = NULL;
+
+
+ /* prevent dragging too fast loosing buttons */
+ plot_line_v2v2i(xy_src, xy_dst, ui_but_set_cb, &data);
+
+ return data.do_draw;
+}
+
+static void ui_drag_but_set(bContext *C, wmOperator *op, const int xy_input[2])
+{
+ ARegion *ar = CTX_wm_region(C);
+ DragOpInfo *drag_info = op->customdata;
+ bool do_draw = false;
+
+ const bool is_set = RNA_boolean_get(op->ptr, "state");
+ const int xy_last[2] = {RNA_int_get(op->ptr, "last_x"),
+ RNA_int_get(op->ptr, "last_y")};
+
+ int xy[2];
+
+ /**
+ * Initialize Locking:
+ *
+ * Check if we need to initialize the lock axis by finding if the first
+ * button we mouse over is X or Y aligned, then lock the mouse to that axis after.
+ */
+ if (drag_info->xy_lock[0] == false && drag_info->xy_lock[1] == false) {
+ ARegion *ar = CTX_wm_region(C);
+
+ /* first store the buttons original coords */
+ uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]);
+ if (but) {
+ const float but_cent_new[2] = {BLI_rctf_cent_x(&but->rect),
+ BLI_rctf_cent_y(&but->rect)};
+
+ /* check if this is a different button, chances are high the button wont move about :) */
+ if (len_manhattan_v2v2(drag_info->but_cent_start, but_cent_new) > 1.0f) {
+ if (fabsf(drag_info->but_cent_start[0] - but_cent_new[0]) <
+ fabsf(drag_info->but_cent_start[1] - but_cent_new[1]))
+ {
+ drag_info->xy_lock[0] = true;
+ }
+ else {
+ drag_info->xy_lock[1] = true;
+ }
+ }
+ }
+ }
+ /* done with axis locking */
+
+
+ xy[0] = (drag_info->xy_lock[0] == false) ? xy_input[0] : xy_last[0];
+ xy[1] = (drag_info->xy_lock[1] == false) ? xy_input[1] : xy_last[1];
+
+
+ /* touch all buttons between last mouse coord and this one */
+ do_draw = ui_but_set_xy_xy(C, ar, is_set, drag_info->but_type_start, xy_last, xy);
+
+ if (do_draw) {
+ ED_region_tag_redraw(ar);
+ }
+
+ RNA_int_set(op->ptr, "last_x", xy[0]);
+ RNA_int_set(op->ptr, "last_y", xy[1]);
+}
+
+static int ui_drag_toggle_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int xy_last[2] = {RNA_int_get(op->ptr, "last_x"),
+ RNA_int_get(op->ptr, "last_y")};
+
+ float but_cent_start[2];
+ eButType but_type_start;
+ DragOpInfo *drag_info;
+
+ {
+ /* find the button where we started dragging */
+ ARegion *ar = CTX_wm_region(C);
+ uiBut *but = ui_but_find_mouse_over(ar, xy_last[0], xy_last[1]);
+ if (but) {
+ but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
+ but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
+ but_type_start = but->type;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ drag_info = op->customdata = MEM_callocN(sizeof(DragOpInfo), __func__);
+ copy_v2_v2(drag_info->but_cent_start, but_cent_start);
+ drag_info->but_type_start = but_type_start;
+
+ /* set the initial button */
+ ui_drag_but_set(C, op, xy_last);
+ ui_drag_but_set(C, op, &event->x);
+
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int ui_drag_toggle_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ bool done = false;
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ {
+ if (event->val != KM_PRESS) {
+ done = true;
+ }
+ break;
+ }
+ case MOUSEMOVE:
+ {
+ ui_drag_but_set(C, op, &event->x);
+ break;
+ }
+ }
+
+ if (done) {
+ MEM_freeN(op->customdata);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_RUNNING_MODAL;
+ }
+}
+
+static int ui_drag_toggle_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+}
+
+static void UI_OT_drag_toggle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Button Drag Toggle";
+ ot->description = "";
+ ot->idname = "UI_OT_drag_toggle";
+
+ /* api callbacks */
+ ot->invoke = ui_drag_toggle_invoke;
+ ot->modal = ui_drag_toggle_modal;
+ ot->cancel = ui_drag_toggle_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "state", true, "State", "");
+ RNA_def_int(ot->srna, "last_x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
+ RNA_def_int(ot->srna, "last_y", 0, 0, INT_MAX, "Y", "", 0, INT_MAX);
+}
+
/* ********************************************************* */
/* Registration */
@@ -1087,5 +1304,6 @@ void UI_buttons_operatortypes(void)
WM_operatortype_append(UI_OT_edittranslation_init);
#endif
WM_operatortype_append(UI_OT_reloadtranslation);
+ WM_operatortype_append(UI_OT_drag_toggle);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 2b170ea546b..e466c481151 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -112,7 +112,7 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
return BUT_VERTICAL;
else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
- return BUT_VERTICAL;
+ return BUT_VERTICAL;
else if (ELEM3(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS))
return BUT_VERTICAL;
@@ -133,8 +133,6 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
if (sbuts->re_align || sbuts->mainbo != sbuts->mainb)
return 1;
}
- else if (ar->regiontype == RGN_TYPE_UI)
- return 1;
else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
return 1;
else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
@@ -164,15 +162,20 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
/****************************** panels ******************************/
-static void panels_collapse_all(ScrArea *sa, ARegion *ar)
+static void panels_collapse_all(ScrArea *sa, ARegion *ar, Panel *from_pa)
{
Panel *pa;
+ PanelType *pt, *from_pt;
int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY);
for (pa = ar->panels.first; pa; pa = pa->next) {
- if (pa->type && !(pa->type->flag & PNL_NO_HEADER)) {
- pa->flag = flag;
- }
+ pt = pa->type;
+ from_pt = from_pa->type;
+
+ /* close panels with headers in the same context */
+ if (pt && from_pt && !(pt->flag & PNL_NO_HEADER))
+ if (!pt->context[0] || strcmp(pt->context, from_pt->context) == 0)
+ pa->flag = flag;
}
}
@@ -244,6 +247,14 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int
}
}
+ /* Do not allow closed panels without headers! Else user could get "disappeared" UI! */
+ if ((pt->flag & PNL_NO_HEADER) && (pa->flag & PNL_CLOSED)) {
+ pa->flag &= ~PNL_CLOSED;
+ /* Force update of panels' positions! */
+ pa->sizex = 0;
+ pa->sizey = 0;
+ }
+
BLI_strncpy(pa->drawname, drawname, UI_MAX_NAME_STR);
/* if a new panel is added, we insert it right after the panel
@@ -305,7 +316,7 @@ void uiEndPanel(uiBlock *block, int width, int height)
static void ui_offset_panel_block(uiBlock *block)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiBut *but;
int ofsy;
@@ -345,14 +356,18 @@ static void uiPanelPop(uiBlock *UNUSED(block))
/* triangle 'icon' for panel header */
void UI_DrawTriIcon(float x, float y, char dir)
{
+ float f3 = 0.15 * U.widget_unit;
+ float f5 = 0.25 * U.widget_unit;
+ float f7 = 0.35 * U.widget_unit;
+
if (dir == 'h') {
- ui_draw_anti_tria(x - 3, y - 5, x - 3, y + 5, x + 7, y);
+ ui_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y);
}
else if (dir == 't') {
- ui_draw_anti_tria(x - 5, y - 7, x + 5, y - 7, x, y + 3);
+ ui_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3);
}
else { /* 'v' = vertical, down */
- ui_draw_anti_tria(x - 5, y + 3, x + 5, y + 3, x, y - 7);
+ ui_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7);
}
}
@@ -432,8 +447,8 @@ static void ui_draw_panel_dragwidget(const rctf *rect)
ymin = rect->ymin;
ymax = rect->ymax;
- dx = 0.333f * (xmax - xmin);
- dy = 0.333f * (ymax - ymin);
+ dx = (xmax - xmin) / 3.0f;
+ dy = (ymax - ymin) / 3.0f;
glEnable(GL_BLEND);
glColor4ub(255, 255, 255, 50);
@@ -495,7 +510,6 @@ static void rectf_scale(rctf *rect, const float scale)
/* panel integrated in buttonswindow, tool/property lists etc */
void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
{
- bTheme *btheme = UI_GetTheme();
Panel *panel = block->panel;
rcti headrect;
rctf itemrect;
@@ -516,11 +530,10 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
float y = headrect.ymax;
glEnable(GL_BLEND);
-
- if (btheme->tui.panel.show_header) {
+
+ if (UI_GetThemeValue(TH_PANEL_SHOW_HEADER)) {
/* draw with background color */
- glEnable(GL_BLEND);
- glColor4ubv((unsigned char *)btheme->tui.panel.header);
+ UI_ThemeColor4(TH_PANEL_HEADER);
glRectf(minx, headrect.ymin + 1, maxx, y);
fdrawline(minx, y, maxx, y);
@@ -535,7 +548,6 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
fdrawline(minx, y, maxx, y);
glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
fdrawline(minx, y - 1, maxx, y - 1);
- glDisable(GL_BLEND);
}
glDisable(GL_BLEND);
@@ -577,6 +589,14 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8);
}
+ /* panel backdrop */
+ if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
+ /* draw with background color */
+ glEnable(GL_BLEND);
+ UI_ThemeColor4(TH_PANEL_BACK);
+ glRecti(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ }
+
if (panel->control & UI_PNL_SCALE)
ui_draw_panel_scalewidget(rect);
}
@@ -797,8 +817,8 @@ static void ui_panels_size(ScrArea *sa, ARegion *ar, int *x, int *y)
{
Panel *pa;
int align = panel_aligned(sa, ar);
- int sizex = UI_PANEL_WIDTH;
- int sizey = UI_PANEL_WIDTH;
+ int sizex = 0;
+ int sizey = 0;
/* compute size taken up by panels, for setting in view2d */
for (pa = ar->panels.first; pa; pa = pa->next) {
@@ -819,6 +839,11 @@ static void ui_panels_size(ScrArea *sa, ARegion *ar, int *x, int *y)
}
}
+ if (sizex == 0)
+ sizex = UI_PANEL_WIDTH;
+ if (sizey == 0)
+ sizey = -UI_PANEL_WIDTH;
+
*x = sizex;
*y = sizey;
}
@@ -850,7 +875,7 @@ static void ui_do_animate(const bContext *C, Panel *panel)
void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar)
{
Panel *pa;
-
+
/* set all panels as inactive, so that at the end we know
* which ones were used */
for (pa = ar->panels.first; pa; pa = pa->next) {
@@ -900,6 +925,7 @@ void uiEndPanels(const bContext *C, ARegion *ar, int *x, int *y)
/* re-align, possibly with animation */
if (panels_re_align(sa, ar, &pa)) {
+ /* XXX code never gets here... PNL_ANIM_ALIGN flag is never set */
if (pa)
panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
else
@@ -940,6 +966,25 @@ void uiDrawPanels(const bContext *C, ARegion *ar)
}
}
+void uiScalePanels(ARegion *ar, float new_width)
+{
+ uiBlock *block;
+ uiBut *but;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ if (block->panel) {
+ float fac = new_width / (float)block->panel->sizex;
+ printf("scaled %f\n", fac);
+ block->panel->sizex = new_width;
+
+ for (but = block->buttons.first; but; but = but->next) {
+ but->rect.xmin *= fac;
+ but->rect.xmax *= fac;
+ }
+ }
+ }
+}
+
/* ------------ panel merging ---------------- */
static void check_panel_overlap(ARegion *ar, Panel *panel)
@@ -971,7 +1016,7 @@ static void check_panel_overlap(ARegion *ar, Panel *panel)
/************************ panel dragging ****************************/
-static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel)
+static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
{
uiHandlePanelData *data = panel->activedata;
ScrArea *sa = CTX_wm_area(C);
@@ -1016,7 +1061,7 @@ static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel)
/* this function is supposed to call general window drawing too */
/* also it supposes a block has panel, and isn't a menu */
-static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event)
+static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event, int ctrl)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -1049,6 +1094,9 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
ED_region_tag_redraw(ar);
}
else { /* collapse */
+ if (ctrl)
+ panels_collapse_all(sa, ar, block->panel);
+
if (block->panel->flag & PNL_CLOSED) {
block->panel->flag &= ~PNL_CLOSED;
/* snap back up so full panel aligns with screen edge */
@@ -1086,43 +1134,64 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
/* XXX should become modal keymap */
/* AKey is opening/closing panels, independent of button state now */
-int ui_handler_panel_region(bContext *C, wmEvent *event)
+int ui_handler_panel_region(bContext *C, const wmEvent *event)
{
- ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
uiBlock *block;
Panel *pa;
- int retval, mx, my, inside_header = 0, inside_scale = 0, inside;
+ int retval, mx, my;
retval = WM_UI_HANDLER_CONTINUE;
for (block = ar->uiblocks.last; block; block = block->prev) {
+ int inside = 0, inside_header = 0, inside_scale = 0;
+
mx = event->x;
my = event->y;
ui_window_to_block(ar, block, &mx, &my);
- /* check if inside boundbox */
- inside = 0;
+ /* checks for mouse position inside */
pa = block->panel;
if (!pa || pa->paneltab != NULL)
continue;
if (pa->type && pa->type->flag & PNL_NO_HEADER) /* XXX - accessed freed panels when scripts reload, need to fix. */
continue;
-
- if (block->rect.xmin <= mx && block->rect.xmax >= mx)
- if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my)
- inside = 1;
- if (inside && event->val == KM_PRESS) {
+ /* clicked at panel header? */
+ if (pa->flag & PNL_CLOSEDX) {
+ if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx)
+ inside_header = 1;
+ }
+ else if (block->rect.xmin > mx || block->rect.xmax < mx) {
+ /* outside left/right side */
+ }
+ else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
+ inside_header = 1;
+ }
+ else if (!(pa->flag & PNL_CLOSEDY)) {
+ /* open panel */
+ if (pa->control & UI_PNL_SCALE) {
+ if (block->rect.xmax - PNL_HEADER <= mx)
+ if (block->rect.ymin + PNL_HEADER >= my)
+ inside_scale = 1;
+ }
+ if (block->rect.xmin <= mx && block->rect.xmax >= mx)
+ if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my)
+ inside = 1;
+ }
+
+ /* XXX hardcoded key warning */
+ if ((inside || inside_header) && event->val == KM_PRESS) {
if (event->type == AKEY && !ELEM4(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) {
if (pa->flag & PNL_CLOSEDY) {
if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my))
- ui_handle_panel_header(C, block, mx, my, event->type);
+ ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
}
else
- ui_handle_panel_header(C, block, mx, my, event->type);
+ ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
+ retval = WM_UI_HANDLER_BREAK;
continue;
}
}
@@ -1131,40 +1200,33 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
if (ui_button_is_active(ar))
continue;
- if (inside) {
- /* clicked at panel header? */
- if (pa->flag & PNL_CLOSEDX) {
- if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx)
- inside_header = 1;
- }
- else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
- inside_header = 1;
- }
- else if (pa->control & UI_PNL_SCALE) {
- if (block->rect.xmax - PNL_HEADER <= mx)
- if (block->rect.ymin + PNL_HEADER >= my)
- inside_scale = 1;
- }
+ if (inside || inside_header) {
if (event->val == KM_PRESS) {
+
/* open close on header */
if (ELEM(event->type, RETKEY, PADENTER)) {
if (inside_header) {
- ui_handle_panel_header(C, block, mx, my, RETKEY);
+ ui_handle_panel_header(C, block, mx, my, RETKEY, event->ctrl);
+ retval = WM_UI_HANDLER_BREAK;
break;
}
}
else if (event->type == LEFTMOUSE) {
+ /* all inside clicks should return in break - overlapping/float panels */
+ retval = WM_UI_HANDLER_BREAK;
+
if (inside_header) {
- if (event->ctrl)
- panels_collapse_all(sa, ar);
- ui_handle_panel_header(C, block, mx, my, 0);
+ ui_handle_panel_header(C, block, mx, my, 0, event->ctrl);
+ retval = WM_UI_HANDLER_BREAK;
break;
}
else if (inside_scale && !(pa->flag & PNL_CLOSED)) {
panel_activate_state(C, pa, PANEL_STATE_DRAG_SCALE);
+ retval = WM_UI_HANDLER_BREAK;
break;
}
+
}
else if (event->type == ESCKEY) {
/*XXX 2.50*/
@@ -1215,7 +1277,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
/**************** window level modal panel interaction **************/
/* note, this is modal handler and should not swallow events for animation */
-static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
+static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
{
Panel *panel = userdata;
uiHandlePanelData *data = panel->activedata;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index c13aadee069..03c127f33c8 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -73,8 +73,6 @@
#include "interface_intern.h"
#define B_NOP -1
-#define MENU_SHADOW_SIDE 8
-#define MENU_SHADOW_BOTTOM 10
#define MENU_TOP 8
/*********************** Menu Data Parsing ********************* */
@@ -306,8 +304,9 @@ static ARegion *ui_add_temporary_region(bScreen *sc)
static void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar)
{
- if (CTX_wm_window(C))
- wm_draw_region_clear(CTX_wm_window(C), ar);
+ wmWindow *win = CTX_wm_window(C);
+ if (win)
+ wm_draw_region_clear(win, ar);
ED_region_exit(C, ar);
BKE_area_region_free(NULL, ar); /* NULL: no spacetype */
@@ -416,6 +415,7 @@ static void ui_tooltip_region_free_cb(ARegion *ar)
ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
{
+ wmWindow *win = CTX_wm_window(C);
uiStyle *style = UI_GetStyle();
static ARegionType type;
ARegion *ar;
@@ -423,7 +423,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* IDProperty *prop;*/
char buf[512];
float fonth, fontw, aspect = but->block->aspect;
- int winx, winy, ofsx, ofsy, w, h, a;
+ int winx /*, winy */, ofsx, ofsy, w, h, a;
rctf rect_fl;
rcti rect_i;
@@ -466,7 +466,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->totline++;
}
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* full string */
ui_get_but_string(but, buf, sizeof(buf));
if (buf[0]) {
@@ -565,7 +565,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
char *data_path = NULL;
/* never fails */
- id_path = RNA_path_from_ID_python(id);
+ id_path = RNA_path_full_ID_py(id);
if (ptr->id.data && ptr->data && prop) {
data_path = RNA_path_from_ID_to_property(ptr, prop);
@@ -622,12 +622,14 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* set font, get bb */
data->fstyle = style->widget; /* copy struct */
data->fstyle.align = UI_STYLE_TEXT_CENTER;
+ ui_fontscale(&data->fstyle.points, aspect);
+
uiStyleFontSet(&data->fstyle);
- /* these defines may need to be tweaked depending on font */
-#define TIP_MARGIN_Y 2
-#define TIP_BORDER_X 16.0f
-#define TIP_BORDER_Y 6.0f
+ /* these defines tweaked depending on font */
+#define TIP_MARGIN_Y (2.0f / aspect)
+#define TIP_BORDER_X (16.0f / aspect)
+#define TIP_BORDER_Y (6.0f / aspect)
h = BLF_height_max(data->fstyle.uifont_id);
@@ -637,7 +639,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
fonth += (a == 0) ? h : h + TIP_MARGIN_Y;
}
- fontw *= aspect;
+ //fontw *= aspect;
ar->regiondata = data;
@@ -645,34 +647,30 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->lineh = h;
data->spaceh = TIP_MARGIN_Y;
-
/* compute position */
- ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
- ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
+ ofsx = 0; //(but->block->panel) ? but->block->panel->ofsx : 0;
+ ofsy = 0; //(but->block->panel) ? but->block->panel->ofsy : 0;
+
+ rect_fl.xmin = BLI_rctf_cent_x(&but->rect) + ofsx - TIP_BORDER_X;
+ rect_fl.xmax = rect_fl.xmin + fontw + TIP_BORDER_X;
+ rect_fl.ymax = but->rect.ymin + ofsy - TIP_BORDER_Y;
+ rect_fl.ymin = rect_fl.ymax - fonth - TIP_BORDER_Y;
- rect_fl.xmin = (but->rect.xmin + but->rect.xmax) * 0.5f + ofsx - (TIP_BORDER_X * aspect);
- rect_fl.xmax = rect_fl.xmin + fontw + (TIP_BORDER_X * aspect);
- rect_fl.ymax = but->rect.ymin + ofsy - (TIP_BORDER_Y * aspect);
- rect_fl.ymin = rect_fl.ymax - fonth * aspect - (TIP_BORDER_Y * aspect);
-
#undef TIP_MARGIN_Y
#undef TIP_BORDER_X
#undef TIP_BORDER_Y
-
- /* copy to int, gets projected if possible too */
- BLI_rcti_rctf_copy(&rect_i, &rect_fl);
+ /* since the text has beens caled already, the size of tooltips is defined now */
+ /* here we try to figure out the right location */
if (butregion) {
- /* XXX temp, region v2ds can be empty still */
- if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
- UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmin, rect_fl.ymin, &rect_i.xmin, &rect_i.ymin);
- UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmax, rect_fl.ymax, &rect_i.xmax, &rect_i.ymax);
- }
-
- BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
+ float ofsx = rect_fl.xmin, ofsy = rect_fl.ymax;
+ ui_block_to_window_fl(butregion, but->block, &ofsx, &ofsy);
+ BLI_rctf_translate(&rect_fl, ofsx - rect_fl.xmin, ofsy - rect_fl.ymax);
}
+ BLI_rcti_rctf_copy(&rect_i, &rect_fl);
- wm_window_get_size(CTX_wm_window(C), &winx, &winy);
+ /* clip with window boundaries */
+ winx = WM_window_pixels_x(win);
if (rect_i.xmax > winx) {
/* super size */
@@ -693,16 +691,20 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
}
/* widget rect, in region coords */
- data->bbox.xmin = MENU_SHADOW_SIDE;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) + MENU_SHADOW_SIDE;
- data->bbox.ymin = MENU_SHADOW_BOTTOM;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i) + MENU_SHADOW_BOTTOM;
-
- /* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - MENU_SHADOW_SIDE;
- ar->winrct.xmax = rect_i.xmax + MENU_SHADOW_SIDE;
- ar->winrct.ymin = rect_i.ymin - MENU_SHADOW_BOTTOM;
- ar->winrct.ymax = rect_i.ymax + MENU_TOP;
+ {
+ int width = UI_ThemeMenuShadowWidth();
+
+ data->bbox.xmin = width;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) + width;
+ data->bbox.ymin = width;
+ data->bbox.ymax = BLI_rcti_size_y(&rect_i) + width;
+
+ /* 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 + MENU_TOP;
+ }
/* adds subwindow */
ED_region_init(C, ar);
@@ -891,11 +893,15 @@ void ui_searchbox_apply(uiBut *but, ARegion *ar)
}
}
-void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, wmEvent *event)
+void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, const wmEvent *event)
{
uiSearchboxData *data = ar->regiondata;
+ int type = event->type, val = event->val;
- switch (event->type) {
+ if (type == MOUSEPAN)
+ ui_pan_to_scroll(event, &type, &val);
+
+ switch (type) {
case WHEELUPMOUSE:
case UPARROWKEY:
ui_searchbox_select(C, ar, but, -1);
@@ -1097,6 +1103,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();
static ARegionType type;
ARegion *ar;
@@ -1104,7 +1111,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
float aspect = but->block->aspect;
rctf rect_fl;
rcti rect_i;
- int winx, winy, ofsx, ofsy;
+ int winx /*, winy */, ofsx, ofsy;
int i;
/* create area region */
@@ -1139,16 +1146,17 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
/* compute position */
if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
+ int width = UI_ThemeMenuShadowWidth();
/* this case is search menu inside other menu */
/* we copy region size */
ar->winrct = butregion->winrct;
/* widget rect, in region coords */
- data->bbox.xmin = MENU_SHADOW_SIDE;
- data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - MENU_SHADOW_SIDE;
- data->bbox.ymin = MENU_SHADOW_BOTTOM;
- data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - MENU_SHADOW_BOTTOM;
+ data->bbox.xmin = width;
+ data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - width;
+ data->bbox.ymin = width;
+ data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - width;
/* check if button is lower half */
if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) {
@@ -1160,6 +1168,8 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
}
else {
const int searchbox_width = uiSearchBoxWidth();
+ const int shadow_width = UI_ThemeMenuShadowWidth();
+
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;
@@ -1185,7 +1195,9 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
- wm_window_get_size(CTX_wm_window(C), &winx, &winy);
+ winx = WM_window_pixels_x(win);
+ // winy = WM_window_pixels_y(win); /* UNUSED */
+ //wm_window_get_size(win, &winx, &winy);
if (rect_i.xmax > winx) {
/* super size */
@@ -1209,15 +1221,15 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
}
/* widget rect, in region coords */
- data->bbox.xmin = MENU_SHADOW_SIDE;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) + MENU_SHADOW_SIDE;
- data->bbox.ymin = MENU_SHADOW_BOTTOM;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i) + MENU_SHADOW_BOTTOM;
+ 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;
/* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - MENU_SHADOW_SIDE;
- ar->winrct.xmax = rect_i.xmax + MENU_SHADOW_SIDE;
- ar->winrct.ymin = rect_i.ymin - MENU_SHADOW_BOTTOM;
+ 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.ymax = rect_i.ymax;
}
@@ -1314,11 +1326,11 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
/* widget_roundbox_set has this correction too, keep in sync */
if (but->type != PULLDOWN) {
if (but->flag & UI_BUT_ALIGN_TOP)
- butrct.ymax += 1.0f;
+ butrct.ymax += U.pixelsize;
if (but->flag & UI_BUT_ALIGN_LEFT)
- butrct.xmin -= 1.0f;
+ butrct.xmin -= U.pixelsize;
}
-
+
/* calc block rect */
if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
if (block->buttons.first) {
@@ -1334,7 +1346,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
block->rect.xmax = block->rect.ymax = 20;
}
}
-
+
/* aspect = (float)(BLI_rcti_size_x(&block->rect) + 4);*/ /*UNUSED*/
ui_block_to_window_fl(butregion, but->block, &block->rect.xmin, &block->rect.ymin);
ui_block_to_window_fl(butregion, but->block, &block->rect.xmax, &block->rect.ymax);
@@ -1342,8 +1354,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
//block->rect.xmin -= 2.0; block->rect.ymin -= 2.0;
//block->rect.xmax += 2.0; block->rect.ymax += 2.0;
- xsize = BLI_rctf_size_x(&block->rect) + 4; /* 4 for shadow */
- ysize = BLI_rctf_size_y(&block->rect) + 4;
+ xsize = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */
+ ysize = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y;
/* aspect /= (float)xsize;*/ /*UNUSED*/
{
@@ -1351,7 +1363,9 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
int winx, winy;
// int offscreen;
- wm_window_get_size(window, &winx, &winy);
+ winx = WM_window_pixels_x(window);
+ winy = WM_window_pixels_y(window);
+ // wm_window_get_size(window, &winx, &winy);
if (block->direction & UI_CENTER) center = ysize / 2;
else center = 0;
@@ -1517,23 +1531,35 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
{
+ uiBut *bt;
+ int width = UI_SCREEN_MARGIN;
int winx, winy;
if (block->flag & UI_BLOCK_NO_WIN_CLIP) {
return;
}
- wm_window_get_size(window, &winx, &winy);
+ winx = WM_window_pixels_x(window);
+ winy = WM_window_pixels_y(window);
- if (block->rect.xmin < MENU_SHADOW_SIDE)
- block->rect.xmin = MENU_SHADOW_SIDE;
- if (block->rect.xmax > winx - MENU_SHADOW_SIDE)
- block->rect.xmax = winx - MENU_SHADOW_SIDE;
+ if (block->rect.xmin < width)
+ block->rect.xmin = width;
+ if (block->rect.xmax > winx - width)
+ block->rect.xmax = winx - width;
- if (block->rect.ymin < MENU_SHADOW_BOTTOM)
- block->rect.ymin = MENU_SHADOW_BOTTOM;
+ if (block->rect.ymin < width)
+ block->rect.ymin = width;
if (block->rect.ymax > winy - MENU_TOP)
block->rect.ymax = winy - MENU_TOP;
+
+ /* ensure menu items draw inside left/right boundary */
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (bt->rect.xmin < block->rect.xmin)
+ bt->rect.xmin = block->rect.xmin;
+ if (bt->rect.xmax > block->rect.xmax)
+ bt->rect.xmax = block->rect.xmax;
+ }
+
}
void ui_popup_block_scrolltest(uiBlock *block)
@@ -1583,6 +1609,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
uiBlock *block;
uiPopupBlockHandle *handle;
uiSafetyRct *saferct;
+ int width = UI_ThemeMenuShadowWidth();
/* create handle */
handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
@@ -1635,7 +1662,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
/* if this is being created from a button */
if (but) {
block->aspect = but->block->aspect;
-
ui_block_position(window, butregion, but, block);
handle->direction = block->direction;
}
@@ -1652,9 +1678,9 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
/* 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 - MENU_SHADOW_SIDE;
- ar->winrct.xmax = block->rect.xmax + MENU_SHADOW_SIDE;
- ar->winrct.ymin = block->rect.ymin - MENU_SHADOW_BOTTOM;
+ ar->winrct.xmin = block->rect.xmin - width;
+ ar->winrct.xmax = block->rect.xmax + width;
+ ar->winrct.ymin = block->rect.ymin - width;
ar->winrct.ymax = block->rect.ymax + MENU_TOP;
ui_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);
@@ -2019,10 +2045,10 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a
picker_new_hide_reveal(bt->block, colormode);
}
-#define PICKER_H 150
-#define PICKER_W 150
-#define PICKER_SPACE 6
-#define PICKER_BAR 14
+#define PICKER_H (7.5f * U.widget_unit)
+#define PICKER_W (7.5f * U.widget_unit)
+#define PICKER_SPACE (0.3f * U.widget_unit)
+#define PICKER_BAR (0.7f * U.widget_unit)
#define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR)
@@ -2031,11 +2057,11 @@ static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop)
uiBut *bt;
/* HS circle */
- bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, 0, 0.0, 0.0, 0, 0, "Color");
+ bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0, 0, "Color");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
+ 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, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
@@ -2046,11 +2072,11 @@ static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, in
int bartype = type + 3;
/* HS square */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, 0, 0.0, 0.0, type, 0, "Color");
+ 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, "Color");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, 0, 0.0, 0.0, bartype, 0, "Value");
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
@@ -2066,11 +2092,12 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
float rgb_gamma[3];
float min, max, step, precision;
float *hsv = ui_block_hsv_get(block);
+ int yco;
ui_block_hsv_get(block);
width = PICKER_TOTAL_W;
- butwidth = width - UI_UNIT_X - 10;
+ butwidth = width - 1.5f * UI_UNIT_X;
/* existence of profile means storage is in linear color space, with display correction */
/* XXX That tip message is not use anywhere! */
@@ -2108,44 +2135,47 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
}
/* mode */
+ yco = -1.5f * UI_UNIT_Y;
uiBlockBeginAlign(block);
- bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
+ 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);
- bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
+ 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, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
+ 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);
+ yco = -3.0f * UI_UNIT_Y;
if (show_picker) {
- bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, -60, UI_UNIT_X, UI_UNIT_Y, NULL);
+ bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL);
uiButSetFunc(bt, close_popup_cb, bt, NULL);
}
/* RGB values */
uiBlockBeginAlign(block);
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red"));
+ 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, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green"));
+ 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, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue"));
+ 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);
/* 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 */
/* HSV values */
+ yco = -3.0f * UI_UNIT_Y;
uiBlockBeginAlign(block);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
+ 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_hsv_rna_cb, bt, hsv);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, -80, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
+ 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_hsv_rna_cb, bt, hsv);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, -100, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
+ bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
uiBlockEndAlign(block);
if (rgba[3] != FLT_MAX) {
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha"));
+ 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, 0, TIP_("Alpha"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
else {
@@ -2154,9 +2184,10 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
- bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
+ 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, -80, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
rgb_to_hsv_v(rgba, hsv);
@@ -2164,7 +2195,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
}
-static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, wmEvent *event)
+static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, const wmEvent *event)
{
float add = 0.0f;
@@ -2228,7 +2259,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
uiBlockPicker(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, 10);
+ uiBoundsBlock(block, 0.5 * UI_UNIT_X);
block->block_event_func = ui_picker_small_wheel_cb;
@@ -2240,7 +2271,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
/************************ Popup Menu Memory ****************************/
-static int ui_popup_string_hash(char *str)
+static int ui_popup_string_hash(const char *str)
{
/* sometimes button contains hotkey, sometimes not, strip for proper compare */
int hash;
@@ -2386,7 +2417,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
}
block->minbounds = minwidth;
- uiTextBoundsBlock(block, 50);
+ uiTextBoundsBlock(block, 2.5 * UI_UNIT_X);
}
/* if menu slides out of other menu, override direction */
@@ -2402,7 +2433,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
uiMenuCreateFunc menu_func, void *arg, char *str)
{
wmWindow *window = CTX_wm_window(C);
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiPopupBlockHandle *handle;
uiPopupMenu *pup;
pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
@@ -2466,7 +2497,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
/* only return handler, and set optional title */
uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
uiBut *but;
@@ -2543,7 +2574,7 @@ static void operator_cb(bContext *C, void *arg, int retval)
WM_operator_free(op);
}
-static void confirm_cancel_operator(void *opv)
+static void confirm_cancel_operator(bContext *UNUSED(C), void *opv)
{
WM_operator_free(opv);
}
@@ -2590,7 +2621,7 @@ void uiPupMenuOkee(bContext *C, const char *opname, const char *str, ...)
va_list ap;
char titlestr[256];
- BLI_snprintf(titlestr, sizeof(titlestr), "OK? %%i%d", ICON_QUESTION);
+ BLI_snprintf(titlestr, sizeof(titlestr), IFACE_("OK? %%i%d"), ICON_QUESTION);
va_start(ap, str);
vconfirm_opname(C, opname, titlestr, str, ap);
@@ -2604,7 +2635,7 @@ void uiPupMenuOkee(bContext *C, const char *opname, const char *str, ...)
* The operator state for this is implicitly OPERATOR_RUNNING_MODAL */
void uiPupMenuSaveOver(bContext *C, wmOperator *op, const char *filename)
{
- confirm_operator(C, op, "Save Over?", filename);
+ confirm_operator(C, op, IFACE_("Save Over?"), filename);
}
void uiPupMenuNotice(bContext *C, const char *str, ...)
@@ -2622,7 +2653,7 @@ void uiPupMenuError(bContext *C, const char *str, ...)
char nfmt[256];
char titlestr[256];
- BLI_snprintf(titlestr, sizeof(titlestr), "Error %%i%d", ICON_ERROR);
+ BLI_snprintf(titlestr, sizeof(titlestr), IFACE_("Error %%i%d"), ICON_ERROR);
BLI_strncpy(nfmt, str, sizeof(nfmt));
@@ -2649,13 +2680,13 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
/* pass */
}
else if (report->type >= RPT_ERROR) {
- BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message);
+ BLI_dynstr_appendf(ds, IFACE_("Error %%i%d%%t|%s"), ICON_ERROR, report->message);
}
else if (report->type >= RPT_WARNING) {
- BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message);
+ BLI_dynstr_appendf(ds, IFACE_("Warning %%i%d%%t|%s"), ICON_ERROR, report->message);
}
else if (report->type >= RPT_INFO) {
- BLI_dynstr_appendf(ds, "Info %%i%d%%t|%s", ICON_INFO, report->message);
+ BLI_dynstr_appendf(ds, IFACE_("Info %%i%d%%t|%s"), ICON_INFO, report->message);
}
}
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 7e7db6aeaaa..ef24ea951e3 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -143,7 +143,7 @@ static uiFont *uifont_to_blfont(int id)
/* *************** draw ************************ */
-void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str,
+void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str,
float *r_xofs, float *r_yofs)
{
float height;
@@ -166,7 +166,7 @@ void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str,
}
/* clip is very strict, so we give it some space */
- BLF_clipping(fs->uifont_id, rect->xmin - 1, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4);
+ BLF_clipping(fs->uifont_id, rect->xmin - 2, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4);
BLF_enable(fs->uifont_id, BLF_CLIPPING);
BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f);
@@ -261,6 +261,32 @@ uiStyle *UI_GetStyle(void)
return (style != NULL) ? style : U.uistyles.first;
}
+/* for drawing, scaled with DPI setting */
+uiStyle *UI_GetStyleDraw(void)
+{
+ uiStyle *style = UI_GetStyle();
+ static uiStyle _style;
+
+ _style = *style;
+
+ _style.paneltitle.shadx = (short)(UI_DPI_FAC * _style.paneltitle.shadx);
+ _style.paneltitle.shady = (short)(UI_DPI_FAC * _style.grouplabel.shady);
+ _style.grouplabel.shadx = (short)(UI_DPI_FAC * _style.grouplabel.shadx);
+ _style.grouplabel.shady = (short)(UI_DPI_FAC * _style.paneltitle.shady);
+ _style.widgetlabel.shadx = (short)(UI_DPI_FAC * _style.widgetlabel.shadx);
+ _style.widgetlabel.shady = (short)(UI_DPI_FAC * _style.widgetlabel.shady);
+
+ _style.columnspace = (short)(UI_DPI_FAC * _style.columnspace);
+ _style.templatespace = (short)(UI_DPI_FAC * _style.templatespace);
+ _style.boxspace = (short)(UI_DPI_FAC * _style.boxspace);
+ _style.buttonspacex = (short)(UI_DPI_FAC * _style.buttonspacex);
+ _style.buttonspacey = (short)(UI_DPI_FAC * _style.buttonspacey);
+ _style.panelspace = (short)(UI_DPI_FAC * _style.panelspace);
+ _style.panelouter = (short)(UI_DPI_FAC * _style.panelouter);
+
+ return &_style;
+}
+
/* temporarily, does widget font */
int UI_GetStringWidth(const char *str)
{
@@ -364,9 +390,9 @@ void uiStyleInit(void)
* Yes, this build the glyph cache and create
* the texture.
*/
- BLF_size(font->blf_id, 11, U.dpi);
- BLF_size(font->blf_id, 12, U.dpi);
- BLF_size(font->blf_id, 14, U.dpi);
+ BLF_size(font->blf_id, 11 * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, 12 * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, 14 * U.pixelsize, U.dpi);
}
}
@@ -378,19 +404,19 @@ void uiStyleInit(void)
if (blf_mono_font == -1)
blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
- BLF_size(blf_mono_font, 12, 72);
+ BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
/* second for rendering else we get threading problems */
if (blf_mono_font_render == -1)
blf_mono_font_render = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
- BLF_size(blf_mono_font_render, 12, 72);
+ BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72 );
}
void uiStyleFontSet(uiFontStyle *fs)
{
uiFont *font = uifont_to_blfont(fs->uifont_id);
- BLF_size(font->blf_id, fs->points, U.dpi);
+ BLF_size(font->blf_id, fs->points * U.pixelsize, U.dpi);
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index f7a53c6bab2..bddd7f0c821 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -31,38 +31,45 @@
#include "MEM_guardedalloc.h"
-#include "DNA_anim_types.h"
#include "DNA_dynamicpaint_types.h"
-#include "DNA_key_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_userdef_types.h"
+#include "DNA_object_force.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_ghash.h"
#include "BLI_rect.h"
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLF_api.h"
#include "BLF_translation.h"
#include "BKE_animsys.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_displist.h"
#include "BKE_dynamicpaint.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_object.h"
#include "BKE_material.h"
-#include "BKE_texture.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_packedFile.h"
+#include "BKE_particle.h"
#include "BKE_report.h"
-#include "BKE_displist.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
+#include "BKE_texture.h"
#include "ED_screen.h"
#include "ED_object.h"
#include "ED_render.h"
+#include "ED_util.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -71,11 +78,9 @@
#include "WM_types.h"
#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "interface_intern.h"
-#include "BLF_api.h"
-#include "BLF_translation.h"
-
void UI_template_fix_linking(void)
{
}
@@ -179,13 +184,13 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
/* preview thumbnails */
if (template.prv_rows > 0 && template.prv_cols > 0) {
- int w = 96 * template.prv_cols;
- int h = 96 * template.prv_rows + 20;
+ int w = 4 * U.widget_unit * template.prv_cols;
+ 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);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19,
+ 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);
}
@@ -193,15 +198,15 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
else {
const int searchbox_width = uiSearchBoxWidth();
const int searchbox_height = uiSearchBoxHeight();
+
/* fake button, it holds space for search items */
uiDefBut(block, 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);
}
- uiBoundsBlock(block, 6);
+ uiBoundsBlock(block, 0.3f * U.widget_unit);
uiBlockSetDirection(block, UI_DOWN);
uiEndBlock(C, block);
@@ -347,6 +352,7 @@ static const char *template_id_browse_tip(StructRNA *type)
/* Return a type-based i18n context, needed e.g. by "New" button.
* In most languages, this adjective takes different form based on gender of type name...
*/
+#ifdef WITH_INTERNATIONAL
static const char *template_id_context(StructRNA *type)
{
if (type) {
@@ -377,6 +383,7 @@ static const char *template_id_context(StructRNA *type)
}
return BLF_I18NCONTEXT_DEFAULT;
}
+#endif
static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag,
const char *newop, const char *openop, const char *unlinkop)
@@ -387,7 +394,6 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
// ListBase *lb; // UNUSED
ID *id, *idfrom;
int editable = RNA_property_editable(&template->ptr, template->prop);
- const char *i18n_ctxt = template_id_context(type);
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
id = idptr.data;
@@ -506,7 +512,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
BLF_I18NCONTEXT_ID_CAMERA,
BLF_I18NCONTEXT_ID_WORLD,
BLF_I18NCONTEXT_ID_SCREEN,
- BLF_I18NCONTEXT_ID_TEXT);
+ BLF_I18NCONTEXT_ID_TEXT,
+ );
BLF_I18N_MSGID_MULTI_CTXT("New", BLF_I18NCONTEXT_ID_SPEAKER,
BLF_I18NCONTEXT_ID_SOUND,
BLF_I18NCONTEXT_ID_ARMATURE,
@@ -514,15 +521,16 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
BLF_I18NCONTEXT_ID_NODETREE,
BLF_I18NCONTEXT_ID_BRUSH,
BLF_I18NCONTEXT_ID_PARTICLESETTINGS,
- BLF_I18NCONTEXT_ID_GPENCIL);
+ BLF_I18NCONTEXT_ID_GPENCIL,
+ );
if (newop) {
but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
- (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"), 0, 0, w, UI_UNIT_Y, NULL);
+ (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));
}
else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"),
+ but = uiDefIconTextBut(block, 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));
}
@@ -531,7 +539,18 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
uiButSetFlag(but, UI_BUT_DISABLED);
}
- if (flag & UI_ID_OPEN) {
+ /* 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,
+ UI_UNIT_X, UI_UNIT_Y, TIP_("Packed File, click to unpack"));
+ uiButGetOperatorPtrRNA(but);
+
+ RNA_string_set(but->opptr, "id_name", id->name + 2);
+ RNA_int_set(but->opptr, "id_type", GS(id->name));
+
+ }
+ else if (flag & UI_ID_OPEN) {
int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
if (openop) {
@@ -672,7 +691,7 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
uiItemL(row, text, ICON_NONE);
}
else
- uiItemL(row, "ID-Block:", ICON_NONE);
+ uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
/* ID-Type Selector - just have a menu of icons */
/* FIXME: the icon-only setting doesn't work when we supply a blank name */
@@ -716,22 +735,7 @@ void uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propna
/************************ Modifier Template *************************/
-#define ERROR_LIBDATA_MESSAGE "Can't edit external libdata"
-
-#include <string.h>
-
-#include "DNA_object_force.h"
-
-#include "BKE_depsgraph.h"
-#include "BKE_modifier.h"
-#include "BKE_particle.h"
-
-#include "ED_util.h"
-
-#include "BLI_math.h"
-#include "BLI_listbase.h"
-
-#include "ED_object.h"
+#define ERROR_LIBDATA_MESSAGE IFACE_("Can't edit external libdata")
static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v)
{
@@ -831,8 +835,8 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
block = uiLayoutGetBlock(row);
/* VIRTUAL MODIFIER */
/* XXX this is not used now, since these cannot be accessed via RNA */
- BLI_snprintf(str, sizeof(str), "%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, "Modifier name");
+ 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"));
but = uiDefBut(block, 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"));
@@ -939,18 +943,22 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
if (!(ob->mode & OB_MODE_PARTICLE_EDIT) && psys->pathcache) {
if (ELEM(psys->part->ren_as, PART_DRAW_GR, PART_DRAW_OB))
- uiItemO(row, "Convert", ICON_NONE, "OBJECT_OT_duplicates_make_real");
+ uiItemO(row, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE,
+ "OBJECT_OT_duplicates_make_real");
else if (psys->part->ren_as == PART_DRAW_PATH)
- uiItemO(row, "Convert", ICON_NONE, "OBJECT_OT_modifier_convert");
+ uiItemO(row, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE,
+ "OBJECT_OT_modifier_convert");
}
}
else {
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
- uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA);
+ uiItemEnumO(row, "OBJECT_OT_modifier_apply", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
+ 0, "apply_as", MODIFIER_APPLY_DATA);
if (modifier_isSameTopology(md) && !modifier_isNonGeometrical(md)) {
- uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0,
- "apply_as", MODIFIER_APPLY_SHAPE);
+ uiItemEnumO(row, "OBJECT_OT_modifier_apply",
+ CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Apply as Shape Key"),
+ 0, "apply_as", MODIFIER_APPLY_SHAPE);
}
}
@@ -960,7 +968,8 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
if (!ELEM5(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem,
eModifierType_Cloth, eModifierType_Smoke))
{
- uiItemO(row, IFACE_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy");
+ uiItemO(row, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"), ICON_NONE,
+ "OBJECT_OT_modifier_copy");
}
}
@@ -1039,9 +1048,8 @@ static void do_constraint_panels(bContext *C, void *ob_pt, int event)
case B_CONSTRAINT_CHANGETARGET:
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
if (ob->pose) ob->pose->flag |= POSE_RECALC; /* checks & sorts pose channels */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
break;
}
#endif
@@ -1079,16 +1087,16 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
// int rb_col; // UNUSED
/* get constraint typeinfo */
- cti = constraint_get_typeinfo(con);
+ cti = BKE_constraint_get_typeinfo(con);
if (cti == NULL) {
/* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
- BLI_strncpy(typestr, (con->type == CONSTRAINT_TYPE_NULL) ? "Null" : "Unknown", sizeof(typestr));
+ BLI_strncpy(typestr, (con->type == CONSTRAINT_TYPE_NULL) ? IFACE_("Null") : IFACE_("Unknown"), sizeof(typestr));
}
else
- BLI_strncpy(typestr, cti->name, sizeof(typestr));
+ BLI_strncpy(typestr, IFACE_(cti->name), sizeof(typestr));
/* determine whether constraint is proxy protected or not */
- if (proxylocked_constraints_owner(ob, pchan))
+ if (BKE_proxylocked_constraints_owner(ob, pchan))
proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
else
proxy_protected = 0;
@@ -1150,7 +1158,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
*
* Up/Down buttons should only be shown (or not grayed - todo) if they serve some purpose.
*/
- if (proxylocked_constraints_owner(ob, pchan)) {
+ if (BKE_proxylocked_constraints_owner(ob, pchan)) {
if (con->prev) {
prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
}
@@ -1190,7 +1198,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* Set but-locks for protected settings (magic numbers are used here!) */
if (proxy_protected)
- uiBlockSetButLock(block, 1, "Cannot edit Proxy-Protected Constraint");
+ uiBlockSetButLock(block, 1, IFACE_("Cannot edit Proxy-Protected Constraint"));
/* Draw constraint data */
if ((con->flag & CONSTRAINT_EXPAND) == 0) {
@@ -1437,7 +1445,7 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
const int line2_y = yoffs + 65;
if (coba == NULL) return;
-
+
bt = uiDefBut(block, BUT, 0, IFACE_("Add"), 0 + xoffs, line1_y, 40, 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);
@@ -1474,7 +1482,7 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
row = uiLayoutRow(layout, FALSE);
- uiItemR(row, &ptr, "position", 0, "Pos", ICON_NONE);
+ uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
bt = block->buttons.last;
uiButSetFunc(bt, colorband_update_cb, bt, coba);
@@ -1547,8 +1555,8 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 19.5f * UI_UNIT_X;
block = uiLayoutAbsoluteBlock(layout);
colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
@@ -1556,6 +1564,90 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
MEM_freeN(cb);
}
+
+/********************* Icon viewer Template ************************/
+
+/* ID Search browse menu, open */
+static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem)
+{
+ static RNAUpdateCb cb;
+ uiBlock *block;
+ uiBut *but;
+ int icon;
+ EnumPropertyItem *item;
+ int a, free;
+
+ /* arg_litem is malloced, can be freed by parent button */
+ cb = *((RNAUpdateCb *)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);
+
+
+ RNA_property_enum_items(C, &cb.ptr, cb.prop, &item, NULL, &free);
+
+ for (a = 0; item[a].identifier; a++) {
+ int x, y;
+
+ /* XXX hardcoded size to 5 x unit */
+ x = (a % 8) * UI_UNIT_X * 5;
+ 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);
+ }
+
+ uiBoundsBlock(block, 0.3f * U.widget_unit);
+ uiBlockSetDirection(block, UI_TOP);
+ uiEndBlock(C, block);
+
+ if (free) {
+ MEM_freeN(item);
+ }
+
+ return block;
+}
+
+void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ RNAUpdateCb *cb;
+ uiBlock *block;
+ uiBut *but;
+// rctf rect; /* UNUSED */
+ int icon;
+
+ if (!prop || RNA_property_type(prop) != PROP_ENUM)
+ return;
+
+ icon = RNA_property_enum_get(ptr, prop);
+
+ cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr = *ptr;
+ cb->prop = prop;
+
+// rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+// rect.ymin = 0; rect.ymax = 10.0f * UI_UNIT_X;
+
+ block = uiLayoutAbsoluteBlock(layout);
+
+ but = uiDefBlockButN(block, icon_view_menu, 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->icon = icon;
+ uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
+
+ uiButSetNFunc(but, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ MEM_freeN(cb);
+}
+
/********************* Histogram Template ************************/
void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
@@ -1579,18 +1671,19 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
block = uiLayoutAbsoluteBlock(layout);
//colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
hist = (Histogram *)cptr.data;
- hist->height = (hist->height <= UI_UNIT_Y) ? UI_UNIT_Y : hist->height;
+ hist->height = (hist->height <= 20) ? 20 : hist->height;
+
+ bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * hist->height,
+ hist, 0, 0, 0, 0, "");
- bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), hist->height, hist,
- 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
@@ -1620,15 +1713,15 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
block = uiLayoutAbsoluteBlock(layout);
- scopes->wavefrm_height = (scopes->wavefrm_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->wavefrm_height;
+ scopes->wavefrm_height = (scopes->wavefrm_height <= 20) ? 20 : scopes->wavefrm_height;
- bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->wavefrm_height, scopes,
- 0, 0, 0, 0, "");
+ bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * scopes->wavefrm_height,
+ scopes, 0, 0, 0, 0, "");
(void)bt; /* UNUSED */
MEM_freeN(cb);
@@ -1658,15 +1751,15 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
block = uiLayoutAbsoluteBlock(layout);
- scopes->vecscope_height = (scopes->vecscope_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->vecscope_height;
+ scopes->vecscope_height = (scopes->vecscope_height <= 20) ? 20 : scopes->vecscope_height;
bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect),
- scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
+ UI_DPI_FAC * scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
@@ -1760,7 +1853,7 @@ static uiBlock *curvemap_clipping_func(bContext *C, ARegion *ar, void *cumap_v)
/* 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, "");
- bt = uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, "Use Clipping",
+ bt = uiDefButBitI(block, TOG, 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);
@@ -2010,7 +2103,7 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
/* curve itself */
size = uiLayoutGetWidth(layout);
row = uiLayoutRow(layout, FALSE);
- uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 200), cumap, 0.0f, 1.0f, bg, 0, "");
+ uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 10.0f * UI_UNIT_X), cumap, 0.0f, 1.0f, bg, 0, "");
/* sliders for selected point */
for (i = 0; i < cm->totpoint; i++) {
@@ -2021,16 +2114,22 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
}
if (cmp) {
- const float range_clamp[2] = {0.0f, 1.0f};
- const float range_unclamp[2] = {-1000.0f, 1000.0f}; /* arbitrary limits here */
- const float *range = (cumap->flag & CUMA_DO_CLIP) ? range_clamp : range_unclamp;
+ rctf bounds;
+
+ if (cumap->flag & CUMA_DO_CLIP) {
+ bounds = cumap->clipr;
+ }
+ else {
+ bounds.xmin = bounds.ymin = -1000.0;
+ bounds.xmax = bounds.ymax = 1000.0;
+ }
uiLayoutRow(layout, TRUE);
uiBlockSetNFunc(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
bt = uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->x, range[0], range[1], 1, 5, "");
+ &cmp->x, bounds.xmin, bounds.xmax, 1, 5, "");
bt = uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->y, range[0], range[1], 1, 5, "");
+ &cmp->y, bounds.ymin, bounds.ymax, 1, 5, "");
}
/* black/white levels */
@@ -2081,7 +2180,7 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn
/********************* ColorPicker Template ************************/
-#define WHEEL_SIZE 100
+#define WHEEL_SIZE (5 * U.widget_unit)
/* This template now follows User Preference for type - name is not correct anymore... */
void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider,
@@ -2329,254 +2428,28 @@ void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propnam
/************************* List Template **************************/
-
-static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon, int big)
-{
- ID *id = NULL;
- int icon;
-
- if (!itemptr->data)
- return rnaicon;
-
- /* try ID, material or texture slot */
- if (RNA_struct_is_ID(itemptr->type)) {
- id = itemptr->id.data;
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) {
- id = RNA_pointer_get(itemptr, "material").data;
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_TextureSlot)) {
- id = RNA_pointer_get(itemptr, "texture").data;
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_DynamicPaintSurface)) {
- DynamicPaintSurface *surface = (DynamicPaintSurface *)itemptr->data;
-
- if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) return ICON_TEXTURE_SHADED;
- else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) return ICON_OUTLINER_DATA_MESH;
- else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return ICON_FILE_IMAGE;
- }
-
- /* get icon from ID */
- if (id) {
- icon = ui_id_icon_get(C, id, big);
-
- if (icon)
- return icon;
- }
-
- return rnaicon;
-}
-
-static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i,
- int rnaicon, PointerRNA *activeptr, PropertyRNA *activeprop, const char *prop_list_id)
+static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout,
+ struct PointerRNA *UNUSED(dataptr), struct PointerRNA *itemptr, int icon,
+ struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname),
+ int UNUSED(index))
{
- uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but;
- uiLayout *split, *overlap, *sub, *row;
char *namebuf;
const char *name;
- int icon;
-
- overlap = uiLayoutOverlap(layout);
-
- /* list item behind label & other buttons */
- sub = uiLayoutRow(overlap, FALSE);
-
- but = uiDefButR_prop(block, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr, activeprop,
- 0, 0, i, 0, 0, "");
- uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
-
- sub = uiLayoutRow(overlap, FALSE);
-
- /* retrieve icon and name */
- icon = list_item_icon_get(C, itemptr, rnaicon, 0);
- if (icon == ICON_NONE || icon == ICON_DOT)
- icon = 0;
namebuf = RNA_struct_name_get_alloc(itemptr, NULL, 0, NULL);
name = (namebuf) ? namebuf : "";
- /* hardcoded types */
- if (itemptr->type == &RNA_MeshTexturePolyLayer || itemptr->type == &RNA_MeshLoopColorLayer) {
- uiItemL(sub, name, icon);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render",
- 0, 0, 0, 0, 0, NULL);
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_MaterialTextureSlot)) {
- uiItemL(sub, name, icon);
- uiBlockSetEmboss(block, UI_EMBOSS);
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer)) {
- uiItemL(sub, name, icon);
- uiBlockSetEmboss(block, UI_EMBOSS);
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "use", 0, 0, 0, 0, 0, NULL);
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) {
- /* provision to draw active node name */
- Material *ma, *manode;
- Scene *scene = CTX_data_scene(C);
- Object *ob = (Object *)ptr->id.data;
- int index = (Material **)itemptr->data - ob->mat;
-
- /* default item with material base name */
- uiItemL(sub, name, icon);
-
- ma = give_current_material(ob, index + 1);
- if (ma && !BKE_scene_use_new_shading_nodes(scene)) {
- manode = give_node_material(ma);
- if (manode) {
- char str[MAX_ID_NAME + 12];
- BLI_snprintf(str, sizeof(str), IFACE_("Node %s"), manode->id.name + 2);
- uiItemL(sub, str, ui_id_icon_get(C, &manode->id, 1));
- }
- else if (ma->use_nodes) {
- uiItemL(sub, IFACE_("Node <none>"), ICON_NONE);
- }
- }
+ /* Simplest one! */
+ switch (ui_list->layout_type) {
+ case UILST_LAYOUT_GRID:
+ uiItemL(layout, "", icon);
+ break;
+ case UILST_LAYOUT_DEFAULT:
+ case UILST_LAYOUT_COMPACT:
+ default:
+ uiItemL(layout, name, icon);
+ break;
}
- else if (itemptr->type == &RNA_ShapeKey) {
- Object *ob = (Object *)activeptr->data;
- Key *key = (Key *)itemptr->id.data;
- KeyBlock *kb = (KeyBlock *)itemptr->data;
-
- split = uiLayoutSplit(sub, 0.66f, FALSE);
-
- uiItemL(split, name, icon);
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
- row = uiLayoutRow(split, TRUE);
- if (i == 0 || (key->type != KEY_RELATIVE)) uiItemL(row, "", ICON_NONE);
- else uiItemR(row, itemptr, "value", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "mute", 0, "", ICON_NONE);
-
- if ((kb->flag & KEYBLOCK_MUTE) ||
- (ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH)))
- {
- uiLayoutSetActive(row, FALSE);
- }
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else if (itemptr->type == &RNA_VertexGroup) {
- bDeformGroup *dg = (bDeformGroup *)itemptr->data;
- uiItemL(sub, name, icon);
- /* RNA does not allow nice lock icons, use lower level buttons */
-#if 0
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "lock_weight", 0, 0, 0, 0, 0, NULL);
-#else
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButBitC(block, TOG, DG_LOCK_WEIGHT, 0, (dg->flag & DG_LOCK_WEIGHT) ? ICON_LOCKED : ICON_UNLOCKED,
- 0, 0, UI_UNIT_X, UI_UNIT_Y, &dg->flag, 0, 0, 0, 0,
- TIP_("Maintain relative weights while painting"));
- uiBlockSetEmboss(block, UI_EMBOSS);
-#endif
- }
- else if (itemptr->type == &RNA_KeyingSetPath) {
- KS_Path *ksp = (KS_Path *)itemptr->data;
-
- /* icon needs to be the type of ID which is currently active */
- RNA_enum_icon_from_value(id_type_items, ksp->idtype, &icon);
-
- /* nothing else special to do... */
- uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */
- }
- else if (itemptr->type == &RNA_DynamicPaintSurface) {
- char name_final[96];
- const char *enum_name;
- PropertyRNA *prop = RNA_struct_find_property(itemptr, "surface_type");
- DynamicPaintSurface *surface = (DynamicPaintSurface *)itemptr->data;
-
- RNA_property_enum_name(C, itemptr, prop, RNA_property_enum_get(itemptr, prop), &enum_name);
-
- BLI_snprintf(name_final, sizeof(name_final), "%s (%s)", name, enum_name);
- uiItemL(sub, name_final, icon);
- if (dynamicPaint_surfaceHasColorPreview(surface)) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButR(block, OPTION, 0,
- (surface->flags & MOD_DPAINT_PREVIEW) ? ICON_RESTRICT_VIEW_OFF : ICON_RESTRICT_VIEW_ON,
- 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "show_preview", 0, 0, 0, 0, 0, NULL);
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "is_active", i, 0, 0, 0, 0, NULL);
- }
- else if (itemptr->type == &RNA_MovieTrackingObject) {
- MovieTrackingObject *tracking_object = (MovieTrackingObject *)itemptr->data;
-
- split = uiLayoutSplit(sub, 0.75f, FALSE);
- if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
- uiItemL(split, name, ICON_CAMERA_DATA);
- }
- else {
- uiItemL(split, name, ICON_OBJECT_DATA);
- }
- }
- else if (itemptr->type == &RNA_MaskLayer) {
- split = uiLayoutRow(sub, FALSE);
-
- uiItemL(split, name, icon);
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
- row = uiLayoutRow(split, TRUE);
- uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "hide", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "hide_select", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "hide_render", 0, "", ICON_NONE);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
-
- /* There is a last chance to display custom controls (in addition to the name/label):
- * If the given item property group features a string property named as prop_list,
- * this tries to add controls for all properties of the item listed in that string property.
- * (colon-separated names).
- *
- * This is especially useful for python. E.g., if you list a collection of this property
- * group:
- *
- * class TestPropertyGroup(bpy.types.PropertyGroup):
- * bool = BoolProperty(default=False)
- * integer = IntProperty()
- * string = StringProperty()
- *
- * # A string of all identifiers (colon-separated) which property's controls should be
- * # displayed in a template_list.
- * template_list_controls = StringProperty(default="integer:bool:string", options={"HIDDEN"})
- *
- * ... you'll get a numfield for the integer prop, a check box for the bool prop, and a textfield
- * for the string prop, after the name of each item of the collection.
- */
- else if (prop_list_id) {
- row = uiLayoutRow(sub, TRUE);
- uiItemL(row, name, icon);
-
- /* XXX: Check, as sometimes we get an itemptr looking like
- * {id = {data = 0x0}, type = 0x0, data = 0x0}
- * which would obviously produce a sigsev... */
- if (itemptr->type) {
- /* If the special property is set for the item, and it is a collection... */
- PropertyRNA *prop_list = RNA_struct_find_property(itemptr, prop_list_id);
-
- if (prop_list && RNA_property_type(prop_list) == PROP_STRING) {
- int prop_names_len;
- char *prop_names = RNA_property_string_get_alloc(itemptr, prop_list, NULL, 0, &prop_names_len);
- char *prop_names_end = prop_names + prop_names_len;
- char *id = prop_names;
- char *id_next;
- while (id < prop_names_end) {
- if ((id_next = strchr(id, ':'))) *id_next++ = '\0';
- else id_next = prop_names_end;
- uiItemR(row, itemptr, id, 0, NULL, ICON_NONE);
- id = id_next;
- }
- MEM_freeN(prop_names);
- }
- }
- }
-
- else
- uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */
/* free name */
if (namebuf) {
@@ -2584,177 +2457,173 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
}
}
-void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *activeptr,
- const char *activepropname, const char *prop_list, int rows, int maxrows, int listtype)
+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)
{
+ uiListType *ui_list_type;
+ uiList *ui_list = NULL;
+ ARegion *ar;
+ uiListDrawItemFunc draw_item;
+
PropertyRNA *prop = NULL, *activeprop;
PropertyType type, activetype;
StructRNA *ptype;
- uiLayout *box, *row, *col;
- uiBlock *block;
+ uiLayout *box, *row, *col, *sub, *overlap;
+ uiBlock *block, *subblock;
uiBut *but;
- Panel *pa;
- const char *name;
+
+ char ui_list_id[UI_MAX_NAME_STR];
char numstr[32];
- int rnaicon = 0, icon = 0, i = 0, activei = 0, len = 0, items, found, min, max;
+ int rnaicon = ICON_NONE, icon = ICON_NONE;
+ int i = 0, activei = 0;
+ int len = 0;
+ int items;
+ int found;
+ int min, max;
/* 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])) {
+ RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
+ UI_UL_DEFAULT_CLASS_NAME);
+ return;
+ }
+
block = uiLayoutGetBlock(layout);
- pa = block->panel;
- if (!pa) {
- RNA_warning("Only works inside a panel");
+ if (!active_dataptr->data) {
+ RNA_warning("No active data");
return;
}
- if (!activeptr->data)
- return;
-
- if (ptr->data) {
- prop = RNA_struct_find_property(ptr, propname);
+ if (dataptr->data) {
+ prop = RNA_struct_find_property(dataptr, propname);
if (!prop) {
- RNA_warning("Property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
return;
}
}
- activeprop = RNA_struct_find_property(activeptr, activepropname);
+ activeprop = RNA_struct_find_property(active_dataptr, active_propname);
if (!activeprop) {
- RNA_warning("Property not found: %s.%s", RNA_struct_identifier(ptr->type), activepropname);
+ RNA_warning("Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
return;
}
if (prop) {
type = RNA_property_type(prop);
if (type != PROP_COLLECTION) {
- RNA_warning("uiExpected collection property");
+ RNA_warning("Expected a collection data property");
return;
}
}
activetype = RNA_property_type(activeprop);
if (activetype != PROP_INT) {
- RNA_warning("Expected integer property");
+ RNA_warning("Expected an integer active data property");
return;
}
/* get icon */
- if (ptr->data && prop) {
- ptype = RNA_property_pointer_type(ptr, prop);
+ if (dataptr->data && prop) {
+ ptype = RNA_property_pointer_type(dataptr, prop);
rnaicon = RNA_struct_ui_icon(ptype);
}
/* get active data */
- activei = RNA_property_int_get(activeptr, activeprop);
+ activei = RNA_property_int_get(active_dataptr, activeprop);
- if (listtype == 'i') {
- box = uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
- col = uiLayoutColumn(box, TRUE);
- row = uiLayoutRow(col, FALSE);
-
- if (ptr->data && prop) {
- /* create list items */
- RNA_PROP_BEGIN (ptr, itemptr, prop)
- {
- /* create button */
- if (!(i % 9))
- row = uiLayoutRow(col, FALSE);
-
- icon = list_item_icon_get(C, &itemptr, rnaicon, 1);
- but = uiDefIconButR_prop(block, LISTROW, 0, icon, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr,
- activeprop, 0, 0, i, 0, 0, "");
- uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
-
+ /* Find the uiList type. */
+ ui_list_type = WM_uilisttype_find(listtype_name, FALSE);
- i++;
- }
- RNA_PROP_END;
- }
+ if (ui_list_type == NULL) {
+ RNA_warning("List type %s not found", listtype_name);
+ return;
}
- else if (listtype == 'c') {
- /* compact layout */
- row = uiLayoutRow(layout, TRUE);
+ draw_item = ui_list_type->draw_item ? ui_list_type->draw_item : uilist_draw_item_default;
- if (ptr->data && prop) {
- /* create list items */
- RNA_PROP_BEGIN (ptr, itemptr, prop)
- {
- found = (activei == i);
+ /* Find or add the uiList to the current Region. */
+ /* We tag the list id with the list type... */
+ BLI_snprintf(ui_list_id, sizeof(ui_list_id), "%s_%s", ui_list_type->idname, list_id ? list_id : "");
- if (found) {
- /* create button */
- name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL);
- icon = list_item_icon_get(C, &itemptr, rnaicon, 0);
- uiItemL(row, (name) ? name : "", icon);
+ ar = CTX_wm_region(C);
+ ui_list = BLI_findstring(&ar->ui_lists, ui_list_id, offsetof(uiList, list_id));
- if (name) {
- MEM_freeN((void *)name);
- }
- }
-
- i++;
- }
- RNA_PROP_END;
- }
+ if (!ui_list) {
+ ui_list = MEM_callocN(sizeof(uiList), __func__);
+ BLI_strncpy(ui_list->list_id, ui_list_id, sizeof(ui_list->list_id));
+ BLI_addtail(&ar->ui_lists, ui_list);
+ }
- /* if not found, add in dummy button */
- if (i == 0)
- uiItemL(row, "", ICON_NONE);
+ /* Because we can't actually pass type across save&load... */
+ ui_list->type = ui_list_type;
+ ui_list->layout_type = layout_type;
- /* next/prev button */
- BLI_snprintf(numstr, sizeof(numstr), "%d :", i);
- but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, activeptr,
- activeprop, 0, 0, 0, 0, 0, "");
- if (i == 0)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- else {
+ switch (layout_type) {
+ case UILST_LAYOUT_DEFAULT:
/* default rows */
if (rows == 0)
rows = 5;
if (maxrows == 0)
maxrows = 5;
- if (pa->list_grip_size != 0)
- rows = pa->list_grip_size;
+ if (ui_list->list_grip_size != 0)
+ rows = ui_list->list_grip_size;
/* layout */
- box = uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
+ box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
row = uiLayoutRow(box, FALSE);
col = uiLayoutColumn(row, TRUE);
/* init numbers */
- RNA_property_int_range(activeptr, activeprop, &min, &max);
+ RNA_property_int_range(active_dataptr, activeprop, &min, &max);
if (prop)
- len = RNA_property_collection_length(ptr, prop);
+ len = RNA_property_collection_length(dataptr, prop);
items = CLAMPIS(len, rows, MAX2(rows, maxrows));
/* if list length changes and active is out of view, scroll to it */
- if (pa->list_last_len != len)
- if ((activei < pa->list_scroll || activei >= pa->list_scroll + items))
- pa->list_scroll = activei;
+ if ((ui_list->list_last_len != len) &&
+ (activei < ui_list->list_scroll || activei >= ui_list->list_scroll + items)) {
+ ui_list->list_scroll = activei;
+ }
- pa->list_scroll = MIN2(pa->list_scroll, len - items);
- pa->list_scroll = MAX2(pa->list_scroll, 0);
- pa->list_size = items;
- pa->list_last_len = len;
+ ui_list->list_scroll = min_ii(ui_list->list_scroll, len - items);
+ ui_list->list_scroll = max_ii(ui_list->list_scroll, 0);
+ ui_list->list_size = items;
+ ui_list->list_last_len = len;
- if (ptr->data && prop) {
+ if (dataptr->data && prop) {
/* create list items */
- RNA_PROP_BEGIN (ptr, itemptr, prop)
+ RNA_PROP_BEGIN (dataptr, itemptr, prop)
{
- if (i >= pa->list_scroll && i < pa->list_scroll + items)
- list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activeprop, prop_list);
+ if (i >= ui_list->list_scroll && i < ui_list->list_scroll + items) {
+ subblock = uiLayoutGetBlock(col);
+ overlap = uiLayoutOverlap(col);
+ /* 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, i, 0, 0, "");
+ uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
+
+ sub = uiLayoutRow(overlap, FALSE);
+
+ icon = UI_rnaptr_icon_get(C, &itemptr, rnaicon, FALSE);
+ if (icon == ICON_DOT)
+ icon = ICON_NONE;
+ draw_item(ui_list, C, sub, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
+ }
i++;
}
RNA_PROP_END;
}
/* add dummy buttons to fill space */
- while (i < pa->list_scroll + items) {
- if (i >= pa->list_scroll)
+ while (i < ui_list->list_scroll + items) {
+ if (i >= ui_list->list_scroll)
uiItemL(col, "", ICON_NONE);
i++;
}
@@ -2762,9 +2631,75 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* add scrollbar */
if (len > items) {
col = uiLayoutColumn(row, FALSE);
- uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * items, &pa->list_scroll,
+ uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * items, &ui_list->list_scroll,
0, len - items, items, 0, "");
}
+ break;
+ case UILST_LAYOUT_COMPACT:
+ row = uiLayoutRow(layout, TRUE);
+
+ if (dataptr->data && prop) {
+ /* create list items */
+ RNA_PROP_BEGIN (dataptr, itemptr, prop)
+ {
+ found = (activei == i);
+
+ if (found) {
+ icon = UI_rnaptr_icon_get(C, &itemptr, rnaicon, FALSE);
+ if (icon == ICON_DOT)
+ icon = ICON_NONE;
+ draw_item(ui_list, C, row, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
+ }
+
+ i++;
+ }
+ RNA_PROP_END;
+ }
+
+ /* if list is empty, add in dummy button */
+ if (i == 0)
+ uiItemL(row, "", ICON_NONE);
+
+ /* next/prev button */
+ BLI_snprintf(numstr, sizeof(numstr), "%d :", i);
+ but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y,
+ active_dataptr, activeprop, 0, 0, 0, 0, 0, "");
+ if (i == 0)
+ uiButSetFlag(but, UI_BUT_DISABLED);
+ break;
+ case UILST_LAYOUT_GRID:
+ box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ col = uiLayoutColumn(box, TRUE);
+ row = uiLayoutRow(col, FALSE);
+
+ if (dataptr->data && prop) {
+ /* create list items */
+ RNA_PROP_BEGIN (dataptr, itemptr, prop)
+ {
+ /* create button */
+ if (!(i % 9))
+ row = uiLayoutRow(col, FALSE);
+
+ subblock = uiLayoutGetBlock(row);
+ overlap = uiLayoutOverlap(row);
+
+ /* 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, i, 0, 0, "");
+ uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
+
+ sub = uiLayoutRow(overlap, FALSE);
+
+ icon = UI_rnaptr_icon_get(C, &itemptr, rnaicon, FALSE);
+ draw_item(ui_list, C, sub, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
+
+ i++;
+ }
+ RNA_PROP_END;
+ }
+ break;
}
}
@@ -3078,7 +3013,7 @@ void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char
colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
- uiItemL(layout, "Color Space:", ICON_NONE);
+ uiItemL(layout, IFACE_("Input Color Space:"), ICON_NONE);
uiItemR(layout, &colorspace_settings_ptr, "name", 0, "", ICON_NONE);
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index d363609fbd9..7c84784c46b 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -78,7 +78,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
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, 0, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, 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);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index c4b80f0a42f..68df8e29957 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -119,7 +119,7 @@ typedef struct uiWidgetType {
void (*state)(struct uiWidgetType *, int state);
void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign);
void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign);
- void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *);
+ void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *);
} uiWidgetType;
@@ -251,7 +251,7 @@ static void widget_init(uiWidgetBase *wtb)
/* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
/* return tot */
-static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step)
+static int round_box_shadow_edges(float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step)
{
float vec[WIDGET_CURVE_RESOLU][2];
float minx, miny, maxx, maxy;
@@ -261,7 +261,7 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
if (2.0f * rad > BLI_rcti_size_y(rect))
rad = 0.5f * BLI_rcti_size_y(rect);
-
+
minx = rect->xmin - step;
miny = rect->ymin - step;
maxx = rect->xmax + step;
@@ -329,14 +329,14 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
}
/* this call has 1 extra arg to allow mask outline */
-static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi)
+static void round_box__edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi)
{
float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2];
float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax;
- float minxi = minx + 1.0f; /* boundbox inner */
- float maxxi = maxx - 1.0f;
- float minyi = miny + 1.0f;
- float maxyi = maxy - 1.0f;
+ float minxi = minx + U.pixelsize; /* boundbox inner */
+ float maxxi = maxx - U.pixelsize;
+ float minyi = miny + U.pixelsize;
+ float maxyi = maxy - U.pixelsize;
float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f; /* for uv, can divide by zero */
float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f;
int a, tot = 0, minsize;
@@ -346,13 +346,13 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
(roundboxalign & (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) == (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) ? 1 : 2;
minsize = min_ii(BLI_rcti_size_x(rect) * hnum,
- BLI_rcti_size_y(rect) * vnum);
+ BLI_rcti_size_y(rect) * vnum);
if (2.0f * rad > minsize)
rad = 0.5f * minsize;
if (2.0f * (radi + 1.0f) > minsize)
- radi = 0.5f * minsize - 1.0f;
+ radi = 0.5f * minsize - U.pixelsize;
/* mult */
for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
@@ -479,14 +479,14 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
wt->totvert = tot;
}
-static void round_box_edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad)
+static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad)
{
- round_box__edges(wt, roundboxalign, rect, rad, rad - 1.0f);
+ round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize);
}
/* based on button rect, return scaled array of triangles */
-static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+static void widget_num_tria(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
{
float centx, centy, sizex, sizey, minsize;
int a, i1 = 0, i2 = 1;
@@ -521,7 +521,7 @@ static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, cha
tria->index = num_tria_face;
}
-static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+static void widget_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
{
float centx, centy, sizex, sizey, minsize;
int a, i1 = 0, i2 = 1;
@@ -564,21 +564,16 @@ static void widget_trias_draw(uiWidgetTrias *tria)
glDisableClientState(GL_VERTEX_ARRAY);
}
-static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
+static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect)
{
- float centx, centy, size, asp;
+ float centx, centy, size;
int a;
/* center position and size */
- centx = rect->xmax - 0.5f * BLI_rcti_size_y(rect);
- centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect);
+ centx = rect->xmax - 0.32f * BLI_rcti_size_y(rect);
+ centy = rect->ymin + 0.50f * BLI_rcti_size_y(rect);
size = 0.4f * (float)BLI_rcti_size_y(rect);
- /* XXX exception */
- asp = ((float)BLI_rcti_size_x(rect)) / ((float)BLI_rcti_size_y(rect));
- if (asp > 1.2f && asp < 2.6f)
- centx = rect->xmax - 0.4f * (float)BLI_rcti_size_y(rect);
-
for (a = 0; a < 6; a++) {
tria->vec[a][0] = size * menu_tria_vert[a][0] + centx;
tria->vec[a][1] = size * menu_tria_vert[a][1] + centy;
@@ -588,7 +583,7 @@ static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
tria->index = menu_tria_face;
}
-static void widget_check_trias(uiWidgetTrias *tria, rcti *rect)
+static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect)
{
float centx, centy, size;
int a;
@@ -651,8 +646,8 @@ static void widget_verts_to_quad_strip_open(uiWidgetBase *wtb, const int totvert
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->inner_v[a][0];
- quad_strip[a * 2 + 1][1] = wtb->inner_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;
}
}
@@ -833,7 +828,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
#define PREVIEW_PAD 4
-static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect)
+static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti *rect)
{
int w, h, size;
@@ -861,9 +856,9 @@ static int ui_but_draw_menu_icon(uiBut *but)
/* icons have been standardized... and this call draws in untransformed coordinates */
-static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect)
+static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti *rect)
{
- int xs = 0, ys = 0;
+ float xs = 0.0f, ys = 0.0f;
float aspect, height;
if (but->flag & UI_ICON_PREVIEW) {
@@ -874,21 +869,9 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
/* this icon doesn't need draw... */
if (icon == ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU) == 0) return;
- /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */
- aspect = but->block->aspect;
- if (aspect != but->aspect) {
- /* prevent scaling up icon in pupmenu */
- if (aspect < 1.0f) {
- height = UI_DPI_ICON_SIZE;
- aspect = 1.0f;
-
- }
- else
- height = UI_DPI_ICON_SIZE / aspect;
- }
- else
- height = UI_DPI_ICON_SIZE;
-
+ aspect = but->block->aspect / UI_DPI_FAC;
+ height = ICON_DEFAULT_HEIGHT / aspect;
+
/* calculate blend color */
if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) {
if (but->flag & UI_SELECT) {}
@@ -902,32 +885,40 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
glEnable(GL_BLEND);
if (icon && icon != ICON_BLANK1) {
+ float ofs = 1.0f / aspect;
+
if (but->flag & UI_ICON_LEFT) {
if (but->type == BUT_TOGDUAL) {
if (but->drawstr[0]) {
- xs = rect->xmin - 1;
+ xs = rect->xmin - ofs;
}
else {
- xs = (rect->xmin + rect->xmax - height) / 2;
+ xs = (rect->xmin + rect->xmax - height) / 2.0f;
}
}
else if (but->block->flag & UI_BLOCK_LOOP) {
- if (but->type == SEARCH_MENU)
- xs = rect->xmin + 4;
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK))
+ xs = rect->xmin + 4.0f * ofs;
else
- xs = rect->xmin + 1;
+ xs = rect->xmin + ofs;
}
else if ((but->type == ICONROW) || (but->type == ICONTEXTROW)) {
- xs = rect->xmin + 3;
+ xs = rect->xmin + 3.0f * ofs;
}
else {
- xs = rect->xmin + 4;
+ xs = rect->xmin + 4.0f * ofs;
}
- ys = (rect->ymin + rect->ymax - height) / 2;
+ ys = (rect->ymin + rect->ymax - height) / 2.0f;
}
else {
- xs = (rect->xmin + rect->xmax - height) / 2;
- ys = (rect->ymin + rect->ymax - height) / 2;
+ xs = (rect->xmin + rect->xmax - height) / 2.0f;
+ ys = (rect->ymin + rect->ymax - height) / 2.0f;
+ }
+
+ /* force positions to integers, for zoom levels near 1. draws icons crisp. */
+ if (aspect > 0.95f && aspect < 1.05f) {
+ xs = (int)(xs + 0.1f);
+ ys = (int)(ys + 0.1f);
}
/* to indicate draggable */
@@ -940,8 +931,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
}
if (ui_but_draw_menu_icon(but)) {
- xs = rect->xmax - UI_DPI_ICON_SIZE - 1;
- ys = (rect->ymin + rect->ymax - height) / 2;
+ xs = rect->xmax - UI_DPI_ICON_SIZE - aspect;
+ ys = (rect->ymin + rect->ymax - height) / 2.0f;
UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, aspect, alpha);
}
@@ -971,7 +962,7 @@ static void ui_text_clip_give_next_off(uiBut *but)
* \note Sets but->ofs to make sure text is correctly visible.
* \note Clips right in some cases, this function could be cleaned up.
*/
-static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1000,7 +991,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect)
/**
* Cut off the text, taking into account the cursor location (text display while editing).
*/
-static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1064,7 +1055,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect)
*
* \note deals with ': ' especially for number buttons
*/
-static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1292,7 +1283,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) {
ui_text_clip_right_label(fstyle, but, rect);
}
- else if (ELEM(but->type, TEX, SEARCH_MENU)) {
+ else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
ui_text_clip_left(fstyle, but, rect);
}
else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
@@ -1329,14 +1320,25 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
if (but->flag & UI_HAS_ICON) {
widget_draw_icon(but, but->icon + but->iconadd, 1.0f, rect);
+
+ /* icons default draw 0.8f x height */
+ rect->xmin += (int)(0.8f * BLI_rcti_size_y(rect));
- rect->xmin += (int)((float)UI_icon_get_width(but->icon + but->iconadd) * UI_DPI_ICON_FAC);
-
- if (but->editstr || (but->flag & UI_TEXT_LEFT))
- rect->xmin += 5;
+ if (but->editstr || (but->flag & UI_TEXT_LEFT)) {
+ rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
+ }
+ }
+ else if ((but->flag & UI_TEXT_LEFT)) {
+ rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
+ }
+
+ /* unlink icon for this button type */
+ if (but->type == SEARCH_MENU_UNLINK && but->drawstr[0]) {
+ rcti temp = *rect;
+
+ temp.xmin = temp.xmax - BLI_rcti_size_y(rect);
+ widget_draw_icon(but, ICON_X, 1.0f, &temp);
}
- else if ((but->flag & UI_TEXT_LEFT))
- rect->xmin += 5;
/* always draw text for textbutton cursor */
widget_draw_text(fstyle, wcol, but, rect);
@@ -1792,11 +1794,19 @@ static void widget_state_menu_item(uiWidgetType *wt, int state)
{
wt->wcol = *(wt->wcol_theme);
- if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- wt->wcol.text[0] = 0.5f * (wt->wcol.text[0] + wt->wcol.text_sel[0]);
- wt->wcol.text[1] = 0.5f * (wt->wcol.text[1] + wt->wcol.text_sel[1]);
- wt->wcol.text[2] = 0.5f * (wt->wcol.text[2] + wt->wcol.text_sel[2]);
+ /* active and disabled (not so common) */
+ if ((state & UI_BUT_DISABLED) && (state & UI_ACTIVE)) {
+ widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.5f);
+ /* draw the backdrop at low alpha, helps navigating with keys
+ * when disabled items are active */
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ wt->wcol.inner[3] = 64;
+ }
+ /* regular disabled */
+ else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
}
+ /* regular active */
else if (state & UI_ACTIVE) {
copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
@@ -1807,38 +1817,45 @@ static void widget_state_menu_item(uiWidgetType *wt, int state)
/* ************ menu backdrop ************************* */
/* outside of rect, rad to left/bottom/right */
-static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float radout)
+static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin)
{
+ bTheme *btheme = UI_GetTheme();
uiWidgetBase wtb;
rcti rect1 = *rect;
- float alpha, alphastep;
+ float alphastep;
int step, totvert;
- float quad_strip[WIDGET_SIZE_MAX * 2][2];
+ float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2];
+ const float radout = UI_ThemeMenuShadowWidth();
+
+ /* disabled shadow */
+ if (radout == 0.0f)
+ return;
/* prevent tooltips to not show round shadow */
- if (2.0f * radout > 0.2f * BLI_rcti_size_y(&rect1))
+ if (radout > 0.2f * BLI_rcti_size_y(&rect1))
rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1);
else
- rect1.ymax -= 2.0f * radout;
+ rect1.ymax -= radout;
/* inner part */
totvert = round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), 0.0f);
- /* inverse linear shadow alpha */
- alpha = 0.15;
- alphastep = 0.67;
+ /* we draw a number of increasing size alpha quad strips */
+ alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
glEnableClientState(GL_VERTEX_ARRAY);
- for (step = 1; step <= radout; step++, alpha *= alphastep) {
+ for (step = 1; step <= (int)radout; step++) {
+ float expfac = sqrt(step / radout);
+
round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step);
- glColor4f(0.0f, 0.0f, 0.0f, alpha);
+ glColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
- widget_verts_to_quad_strip_open(&wtb, totvert, quad_strip);
+ widget_verts_to_quad_strip(&wtb, totvert, quad_strip);
glVertexPointer(2, GL_FLOAT, 0, quad_strip);
- glDrawArrays(GL_QUAD_STRIP, 0, totvert * 2);
+ glDrawArrays(GL_QUAD_STRIP, 0, totvert * 2 + 2);
}
glDisableClientState(GL_VERTEX_ARRAY);
@@ -1858,17 +1875,17 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
}
else if (direction == UI_DOWN) {
roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
- rect->ymin -= 4.0;
+ rect->ymin -= 0.1f * U.widget_unit;
}
else if (direction == UI_TOP) {
roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
- rect->ymax += 4.0;
+ rect->ymax += 0.1f * U.widget_unit;
}
glEnable(GL_BLEND);
- widget_softshadow(rect, roundboxalign, 5.0f, 8.0f);
+ widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit);
- round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+ round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit);
wtb.emboss = 0;
widgetbase_draw(&wtb, wcol);
@@ -1883,12 +1900,12 @@ static void ui_hsv_cursor(float x, float y)
glTranslatef(x, y, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
- glutil_draw_filled_arc(0.0f, M_PI * 2.0, 3.0f, 8);
+ glutil_draw_filled_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 8);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glColor3f(0.0f, 0.0f, 0.0f);
- glutil_draw_lined_arc(0.0f, M_PI * 2.0, 3.0f, 12);
+ glutil_draw_lined_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 12);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
@@ -1912,7 +1929,7 @@ void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rec
static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
{
- const int tot = 32;
+ const int tot = 64;
const float radstep = 2.0f * (float)M_PI / (float)tot;
const float centx = BLI_rcti_cent_x_fl(rect);
@@ -2000,7 +2017,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
/* ************ custom buttons, old stuff ************** */
/* draws in resolution of 20x4 colors */
-void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha)
+void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha)
{
const float color_step = (type == UI_GRAD_H) ? 0.02f : 0.05f;
int a;
@@ -2139,16 +2156,24 @@ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const floa
-static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
+static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
{
float rgb[3];
float x = 0.0f, y = 0.0f;
float *hsv = ui_block_hsv_get(but->block);
float hsv_n[3];
+ int color_profile = but->block->color_profile;
+
+ if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
+ color_profile = FALSE;
copy_v3_v3(hsv_n, hsv);
ui_get_but_vectorf(but, rgb);
+
+ if (color_profile && (int)but->a1 != UI_GRAD_SV)
+ ui_block_to_display_space_v3(but->block, rgb);
+
rgb_to_hsv_compat_v(rgb, hsv_n);
ui_draw_gradient(rect, hsv_n, but->a1, 1.0f);
@@ -2182,10 +2207,10 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
}
/* vertical 'value' slider, using new widget code */
-static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
+static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
{
uiWidgetBase wtb;
- float rad = 0.5f * BLI_rcti_size_x(rect);
+ const float rad = 0.5f * BLI_rcti_size_x(rect);
float x, y;
float rgb[3], hsv[3], v, range;
int color_profile = but->block->color_profile;
@@ -2230,7 +2255,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
/* ************ separator, for menus etc ***************** */
-static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol)
+static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
{
int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1;
unsigned char col[4];
@@ -2251,7 +2276,7 @@ static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol)
static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
uiWidgetBase wtb;
- float rad = 0.5f * BLI_rcti_size_y(rect);
+ const float rad = 0.5f * BLI_rcti_size_y(rect);
float textofs = rad * 0.75f;
if (state & UI_SELECT)
@@ -2275,7 +2300,7 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
rect->xmax -= textofs;
}
-int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol)
+int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
{
float dist, vec[4][2];
@@ -2299,7 +2324,7 @@ int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol)
}
#define LINK_RESOL 24
-void ui_draw_link_bezier(rcti *rect)
+void ui_draw_link_bezier(const rcti *rect)
{
float coord_array[LINK_RESOL + 1][2];
@@ -2312,7 +2337,7 @@ void ui_draw_link_bezier(rcti *rect)
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, coord_array);
- glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL);
+ glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL + 1);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
@@ -2322,18 +2347,18 @@ void ui_draw_link_bezier(rcti *rect)
}
/* function in use for buttons and for view2d sliders */
-void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int state)
+void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
{
uiWidgetBase wtb;
- float rad;
int horizontal;
+ float rad;
short outline = 0;
widget_init(&wtb);
/* determine horizontal/vertical */
horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
-
+
if (horizontal)
rad = 0.5f * BLI_rcti_size_y(rect);
else
@@ -2540,14 +2565,15 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
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 + 1.0f);
+ rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize);
round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs);
wtb1.outline = 0;
widgetbase_draw(&wtb1, wcol);
/* right part of slider, interpolate roundness */
rect1.xmax = rect1.xmin + fac + offs;
- rect1.xmin += floor(offs - 1.0f);
+ rect1.xmin += floor(offs - U.pixelsize);
+
if (rect1.xmax + offs > rect->xmax)
offs *= (rect1.xmax + offs - rect->xmax) / offs;
else
@@ -2577,12 +2603,14 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
uiWidgetBase wtb;
- float col[4];
+ float rad, col[4];
int color_profile = but->block->color_profile;
col[3] = 1.0f;
if (but->rnaprop) {
+ BLI_assert(but->rnaindex == -1);
+
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
color_profile = FALSE;
@@ -2594,7 +2622,8 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+ rad = 0.25f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
ui_get_but_vectorf(but, col);
@@ -2608,7 +2637,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
rect->ymin += SWATCH_KEYED_BORDER;
rect->ymax -= SWATCH_KEYED_BORDER;
- round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+ round_box_edges(&wtb, roundboxalign, rect, rad);
}
if (color_profile)
@@ -2632,12 +2661,14 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
{
if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
uiWidgetBase wtb;
-
+ float rad;
+
widget_init(&wtb);
wtb.outline = 0;
/* rounded */
- round_box_edges(&wtb, UI_CNR_ALL, rect, 10.0f);
+ rad = 0.5f * BLI_rcti_size_y(rect);
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
}
@@ -2646,6 +2677,7 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
if (state & UI_SELECT)
SWAP(short, wcol->shadetop, wcol->shadedown);
@@ -2653,7 +2685,8 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -2663,11 +2696,13 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun
static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
/* decoration */
widget_menu_trias(&wtb.tria1, rect);
@@ -2681,11 +2716,13 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
/* decoration */
widgetbase_draw(&wtb, wcol);
@@ -2696,11 +2733,13 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat
/* silly node link button hacks */
uiWidgetBase wtb;
uiWidgetColors wcol_backup = *wcol;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
wcol->inner[0] += 15;
wcol->inner[1] += 15;
@@ -2718,7 +2757,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int
{
if (state & UI_ACTIVE) {
uiWidgetBase wtb;
- float rad = 0.25f * BLI_rcti_size_y(rect); /* 4.0f */
+ const float rad = 0.2f * U.widget_unit;
widget_init(&wtb);
@@ -2745,12 +2784,14 @@ static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta
static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* rounded, but no outline */
wtb.outline = 0;
- round_box_edges(&wtb, UI_CNR_ALL, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
@@ -2759,6 +2800,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
{
uiWidgetBase wtb;
rcti recttemp = *rect;
+ float rad;
int delta;
widget_init(&wtb);
@@ -2774,7 +2816,8 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
recttemp.ymax -= delta;
/* half rounded */
- round_box_edges(&wtb, UI_CNR_ALL, &recttemp, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
/* decoration */
if (state & UI_SELECT) {
@@ -2791,11 +2834,13 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -2804,6 +2849,7 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
char old_col[3];
widget_init(&wtb);
@@ -2818,7 +2864,8 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(
}
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -2833,12 +2880,14 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(
static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
-
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+
widgetbase_draw(&wtb, wcol);
}
@@ -2846,7 +2895,7 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int
static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
- float rad = 5.0f; /* 0.5f * BLI_rcti_size_y(rect); */
+ const float rad = 0.25f * U.widget_unit;
widget_init(&wtb);
@@ -2859,6 +2908,7 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect)
{
uiWidgetBase wtb;
+ const float rad = 0.25f * U.widget_unit;
unsigned char col[4];
/* state copy! */
@@ -2874,12 +2924,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
UI_GetThemeColor3ubv(TH_BACK, col);
glColor3ubv(col);
- round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, 4.0);
+ round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad);
widgetbase_outline(&wtb);
}
/* outline */
- round_box_edges(&wtb, UI_CNR_ALL, rect, 5.0f);
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
wtb.outline = 1;
wtb.inner = 0;
widgetbase_draw(&wtb, &wt->wcol);
@@ -2887,7 +2937,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
}
-static void widget_disabled(rcti *rect)
+static void widget_disabled(const rcti *rect)
{
float col[4];
@@ -3068,9 +3118,9 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
/* ui_block_position has this correction too, keep in sync */
if (but->flag & UI_BUT_ALIGN_TOP)
- rect->ymax += 1;
+ rect->ymax += U.pixelsize;
if (but->flag & UI_BUT_ALIGN_LEFT)
- rect->xmin -= 1;
+ rect->xmin -= U.pixelsize;
switch (but->flag & UI_BUT_ALIGN) {
case UI_BUT_ALIGN_TOP:
@@ -3181,7 +3231,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case TEX:
wt = widget_type(UI_WTYPE_NAME);
break;
-
+
+ case SEARCH_MENU_UNLINK:
case SEARCH_MENU:
wt = widget_type(UI_WTYPE_NAME);
if (but->block->flag & UI_BLOCK_LOOP)
@@ -3381,7 +3432,7 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
uiWidgetType *wt = widget_type(UI_WTYPE_BOX);
glEnable(GL_BLEND);
- widget_softshadow(rect, UI_CNR_ALL, 5.0f, 8.0f);
+ widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit);
glDisable(GL_BLEND);
wt->state(wt, 0);
@@ -3400,7 +3451,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
rcti _rect = *rect;
char *cpoin;
-
+
wt->state(wt, state);
wt->draw(&wt->wcol, rect, 0, 0);
@@ -3408,7 +3459,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
fstyle->align = UI_STYLE_TEXT_LEFT;
/* text location offset */
- rect->xmin += 5;
+ rect->xmin += 0.25f * UI_UNIT_X;
if (iconid) rect->xmin += UI_DPI_ICON_SIZE;
/* cut string in 2 parts? */
@@ -3433,10 +3484,16 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
*rect = _rect;
if (iconid) {
- int xs = rect->xmin + 4;
- int ys = 1 + (rect->ymin + rect->ymax - UI_DPI_ICON_SIZE) / 2;
+ float height, aspect;
+ int xs = rect->xmin + 0.2f * UI_UNIT_X;
+ int ys = rect->ymin + 0.1f * BLI_rcti_size_y(rect);
+
+ /* icons are 80% of height of button (16 pixels inside 20 height) */
+ height = 0.8f * BLI_rcti_size_y(rect);
+ aspect = ICON_DEFAULT_HEIGHT / height;
+
glEnable(GL_BLEND);
- UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */
+ UI_icon_draw_aspect(xs, ys, iconid, aspect, 1.0f); /* XXX scale weak get from fstyle? */
glDisable(GL_BLEND);
}
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index fa5d5806bb8..672e4ebbcc4 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -86,7 +86,7 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
static char error[4] = {240, 0, 240, 255};
static char alert[4] = {240, 60, 60, 255};
static char headerdesel[4] = {0, 0, 0, 255};
-
+ static char setting = 0;
const char *cp = error;
if (btheme) {
@@ -170,6 +170,16 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
else
cp = ts->button;
break;
+ case TH_LOW_GRAD:
+ cp = ts->gradients.gradient;
+ break;
+ case TH_HIGH_GRAD:
+ cp = ts->gradients.high_gradient;
+ break;
+ case TH_SHOW_BACK_GRAD:
+ cp = &setting;
+ setting = ts->gradients.show_grad;
+ break;
case TH_TEXT:
if (theme_regionid == RGN_TYPE_WINDOW)
cp = ts->text;
@@ -216,13 +226,19 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_HEADER_TEXT_HI:
cp = ts->header_text_hi; break;
- case TH_PANEL:
- cp = ts->panel; break;
- case TH_PANEL_TEXT:
- cp = ts->panel_text; break;
- case TH_PANEL_TEXT_HI:
- cp = ts->panel_text_hi; break;
-
+ case TH_PANEL_HEADER:
+ cp = ts->panelcolors.header; break;
+ case TH_PANEL_BACK:
+ cp = ts->panelcolors.back; break;
+ case TH_PANEL_SHOW_HEADER:
+ cp = &setting;
+ setting = ts->panelcolors.show_header;
+ break;
+ case TH_PANEL_SHOW_BACK:
+ cp = &setting;
+ setting = ts->panelcolors.show_back;
+ break;
+
case TH_BUTBACK:
cp = ts->button; break;
case TH_BUTBACK_TEXT:
@@ -352,8 +368,14 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->syntaxc; break;
case TH_SYNTAX_L:
cp = ts->syntaxl; break;
+ case TH_SYNTAX_D:
+ cp = ts->syntaxd; break;
+ case TH_SYNTAX_R:
+ cp = ts->syntaxr; break;
case TH_SYNTAX_N:
cp = ts->syntaxn; break;
+ case TH_SYNTAX_S:
+ cp = ts->syntaxs; break;
case TH_NODE:
cp = ts->syntaxl; break;
@@ -367,6 +389,10 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->syntaxc; break;
case TH_NODE_FRAME:
cp = ts->movie; break;
+ case TH_NODE_MATTE:
+ cp = ts->syntaxs; break;
+ case TH_NODE_DISTORT:
+ cp = ts->syntaxd; break;
case TH_NODE_CURVING:
cp = &ts->noodle_curving; break;
@@ -401,6 +427,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->console_error; break;
case TH_CONSOLE_CURSOR:
cp = ts->console_cursor; break;
+ case TH_CONSOLE_SELECT:
+ cp = ts->console_select; break;
case TH_HANDLE_VERTEX:
cp = ts->handle_vertex;
@@ -603,9 +631,9 @@ static void ui_theme_init_new_do(ThemeSpace *ts)
rgba_char_args_test_set(ts->header_title, 0, 0, 0, 255);
rgba_char_args_test_set(ts->header_text_hi, 255, 255, 255, 255);
- rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255);
- rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255);
- rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255);
+// rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255);
+// rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255);
+// rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255);
rgba_char_args_test_set(ts->button, 145, 145, 145, 245);
rgba_char_args_test_set(ts->button_title, 0, 0, 0, 255);
@@ -664,6 +692,7 @@ void ui_theme_init_default(void)
ui_widget_color_init(&btheme->tui);
btheme->tui.iconfile[0] = 0;
+ btheme->tui.panel.show_back = FALSE;
btheme->tui.panel.show_header = FALSE;
rgba_char_args_set(btheme->tui.panel.header, 0, 0, 0, 25);
@@ -671,6 +700,9 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255);
rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255);
+ btheme->tui.menu_shadow_fac = 0.5f;
+ btheme->tui.menu_shadow_width = 12;
+
/* Bone Color Sets */
ui_theme_init_boneColorSets(btheme);
@@ -678,13 +710,15 @@ void ui_theme_init_default(void)
ui_theme_init_new(btheme);
/* space view3d */
+ btheme->tv3d.panelcolors.show_back = FALSE;
+ btheme->tv3d.panelcolors.show_header = FALSE;
rgba_char_args_set_fl(btheme->tv3d.back, 0.225, 0.225, 0.225, 1.0);
rgba_char_args_set(btheme->tv3d.text, 0, 0, 0, 255);
rgba_char_args_set(btheme->tv3d.text_hi, 255, 255, 255, 255);
rgba_char_args_set_fl(btheme->tv3d.header, 0.45, 0.45, 0.45, 1.0);
- rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 1.0);
- rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127);
+ rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 0.5);
+// rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127);
rgba_char_args_set(btheme->tv3d.shade1, 160, 160, 160, 100);
rgba_char_args_set(btheme->tv3d.shade2, 0x7f, 0x70, 0x70, 100);
@@ -757,20 +791,23 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255);
rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255);
-
+ rgba_char_args_set(btheme->tv3d.gradients.gradient, 0, 0, 0, 0);
+ rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 58, 58, 58, 255);
+ btheme->tv3d.gradients.show_grad = FALSE;
+
/* space buttons */
/* to have something initialized */
btheme->tbuts = btheme->tv3d;
rgba_char_args_set_fl(btheme->tbuts.back, 0.45, 0.45, 0.45, 1.0);
- rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255);
+// rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255);
/* graph editor */
btheme->tipo = btheme->tv3d;
rgba_char_args_set_fl(btheme->tipo.back, 0.42, 0.42, 0.42, 1.0);
rgba_char_args_set_fl(btheme->tipo.list, 0.4, 0.4, 0.4, 1.0);
rgba_char_args_set(btheme->tipo.grid, 94, 94, 94, 255);
- rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150);
+// rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150);
rgba_char_args_set(btheme->tipo.shade1, 150, 150, 150, 100); /* scrollbars */
rgba_char_args_set(btheme->tipo.shade2, 0x70, 0x70, 0x70, 100);
rgba_char_args_set(btheme->tipo.vertex, 0, 0, 0, 255);
@@ -816,11 +853,11 @@ void ui_theme_init_default(void)
/* to have something initialized */
btheme->tfile = btheme->tv3d;
rgba_char_args_set_fl(btheme->tfile.back, 0.3, 0.3, 0.3, 1);
- rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1);
+// rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1);
rgba_char_args_set_fl(btheme->tfile.list, 0.4, 0.4, 0.4, 1);
rgba_char_args_set(btheme->tfile.text, 250, 250, 250, 255);
rgba_char_args_set(btheme->tfile.text_hi, 15, 15, 15, 255);
- rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */
+// rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */
rgba_char_args_set(btheme->tfile.active, 130, 130, 130, 255); /* selected files */
rgba_char_args_set(btheme->tfile.hilite, 255, 140, 25, 255); /* selected files */
@@ -860,6 +897,7 @@ void ui_theme_init_default(void)
rgba_char_args_set_fl(btheme->tima.preview_stitch_vert, 0.0, 0.0, 1.0, 0.2);
rgba_char_args_set_fl(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0);
rgba_char_args_set_fl(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0);
+ rgba_char_args_set_fl(btheme->tima.preview_stitch_active, 0.886, 0.824, 0.765, 0.140);
/* space text */
btheme->text = btheme->tv3d;
@@ -870,10 +908,13 @@ void ui_theme_init_default(void)
/* syntax highlighting */
rgba_char_args_set(btheme->text.syntaxn, 0, 0, 200, 255); /* Numbers Blue*/
- rgba_char_args_set(btheme->text.syntaxl, 100, 0, 0, 255); /* Strings red */
- rgba_char_args_set(btheme->text.syntaxc, 0, 100, 50, 255); /* Comments greenish */
- rgba_char_args_set(btheme->text.syntaxv, 95, 95, 0, 255); /* Special */
- rgba_char_args_set(btheme->text.syntaxb, 128, 0, 80, 255); /* Builtin, red-purple */
+ rgba_char_args_set(btheme->text.syntaxl, 100, 0, 0, 255); /* Strings Red */
+ rgba_char_args_set(btheme->text.syntaxc, 0, 100, 50, 255); /* Comments Greenish */
+ rgba_char_args_set(btheme->text.syntaxv, 95, 95, 0, 255); /* Special Yellow*/
+ rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */
+ rgba_char_args_set(btheme->text.syntaxr, 140, 60, 0, 255); /* Reserved Orange*/
+ rgba_char_args_set(btheme->text.syntaxb, 128, 0, 80, 255); /* Builtin Red-purple */
+ rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */
/* space oops */
btheme->toops = btheme->tv3d;
@@ -898,6 +939,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tconsole.console_info, 0, 170, 0, 255);
rgba_char_args_set(btheme->tconsole.console_error, 220, 96, 96, 255);
rgba_char_args_set(btheme->tconsole.console_cursor, 220, 96, 96, 255);
+ rgba_char_args_set(btheme->tconsole.console_select, 255, 255, 255, 48);
/* space time */
btheme->ttime = btheme->tv3d;
@@ -1252,6 +1294,12 @@ void UI_ThemeClearColor(int colorid)
glClearColor(col[0], col[1], col[2], 0.0);
}
+int UI_ThemeMenuShadowWidth(void)
+{
+ bTheme *btheme = UI_GetTheme();
+ return (int)(btheme->tui.menu_shadow_width * UI_DPI_FAC);
+}
+
void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3], const char axis)
{
unsigned char col[3];
@@ -1280,7 +1328,6 @@ void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3]
void init_userdef_do_versions(void)
{
Main *bmain = G.main;
-// countall();
/* the UserDef struct is not corrected with do_versions() .... ugh! */
if (U.wheellinescroll == 0) U.wheellinescroll = 3;
@@ -1990,7 +2037,7 @@ void init_userdef_do_versions(void)
if (U.dragthreshold == 0)
U.dragthreshold = 5;
if (U.widget_unit == 0)
- U.widget_unit = (U.dpi * 20 + 36) / 72;
+ U.widget_unit = 20;
if (U.anisotropic_filter <= 0)
U.anisotropic_filter = 1;
@@ -2009,6 +2056,101 @@ void init_userdef_do_versions(void)
if (U.tweak_threshold == 0)
U.tweak_threshold = 10;
+ if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 1)) {
+ bTheme *btheme;
+
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ /* note: the toggle operator for transparent backdrops limits to these spacetypes */
+ if (btheme->tnode.button[3] == 255) {
+ btheme->tv3d.button[3] = 128;
+ btheme->tnode.button[3] = 128;
+ btheme->tima.button[3] = 128;
+ btheme->tseq.button[3] = 128;
+ btheme->tclip.button[3] = 128;
+ }
+ }
+ }
+
+ /* panel header/backdrop supported locally per editor now */
+ if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 2)) {
+ bTheme *btheme;
+
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+
+ /* new color, panel backdrop. Not used anywhere yet, until you enable it */
+ copy_v3_v3_char(btheme->tui.panel.back, btheme->tbuts.button);
+ btheme->tui.panel.back[3] = 128;
+
+ btheme->tbuts.panelcolors = btheme->tui.panel;
+ btheme->tv3d.panelcolors = btheme->tui.panel;
+ btheme->tfile.panelcolors = btheme->tui.panel;
+ btheme->tipo.panelcolors = btheme->tui.panel;
+ btheme->tinfo.panelcolors = btheme->tui.panel;
+ btheme->tact.panelcolors = btheme->tui.panel;
+ btheme->tnla.panelcolors = btheme->tui.panel;
+ btheme->tseq.panelcolors = btheme->tui.panel;
+ btheme->tima.panelcolors = btheme->tui.panel;
+ btheme->text.panelcolors = btheme->tui.panel;
+ btheme->toops.panelcolors = btheme->tui.panel;
+ btheme->ttime.panelcolors = btheme->tui.panel;
+ btheme->tnode.panelcolors = btheme->tui.panel;
+ btheme->tlogic.panelcolors = btheme->tui.panel;
+ btheme->tuserpref.panelcolors = btheme->tui.panel;
+ btheme->tconsole.panelcolors = btheme->tui.panel;
+ btheme->tclip.panelcolors = btheme->tui.panel;
+ }
+ }
+
+ /* NOTE!! from now on use U.versionfile and U.subversionfile */
+ if (U.versionfile < 266) {
+ bTheme *btheme;
+
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ /* rna definition limits fac to 0.01 */
+ if (btheme->tui.menu_shadow_fac == 0.0f) {
+ btheme->tui.menu_shadow_fac = 0.5f;
+ btheme->tui.menu_shadow_width = 12;
+ }
+ }
+ }
+
+ if (U.versionfile < 265 || (U.versionfile == 265 && U.subversionfile < 4)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */
+ rgba_char_args_set(btheme->text.syntaxr, 140, 60, 0, 255); /* Reserved Orange */
+ rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */
+ }
+ }
+
+ if (U.versionfile < 265 || (U.versionfile == 265 && U.subversionfile < 6)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ copy_v4_v4_char(btheme->tv3d.gradients.high_gradient, btheme->tv3d.back);
+ }
+ }
+
+ if (U.versionfile < 265 || (U.versionfile == 265 && U.subversionfile < 9)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ rgba_char_args_test_set(btheme->tnode.syntaxs, 151, 116, 116, 255); /* matte nodes */
+ rgba_char_args_test_set(btheme->tnode.syntaxd, 116, 151, 151, 255); /* distort nodes */
+ }
+ }
+
+ if (U.versionfile < 265 || (U.versionfile == 265 && U.subversionfile < 11)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ rgba_char_args_test_set(btheme->tconsole.console_select, 255, 255, 255, 48);
+ }
+ }
+
+ /* NOTE!! from now on use U.versionfile and U.subversionfile */
+
+
+ if (U.pixelsize == 0.0f)
+ U.pixelsize = 1.0f;
+
/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX space_set_commmandline_options();
/* this timer uses U */
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f1a3f59bc22..ad6428c7e80 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -39,6 +39,7 @@
#include "DNA_userdef_types.h"
#include "BLI_blenlib.h"
+#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -60,6 +61,8 @@
#include "interface_intern.h"
+static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_scrollers);
+
/* *********************************************************************** */
/* XXX still unresolved: scrolls hide/unhide vs region mask handling */
@@ -73,15 +76,15 @@
*/
static int view2d_scroll_mapped(int scroll)
{
- if (scroll & V2D_SCROLL_HORIZONTAL_HIDE)
+ if (scroll & V2D_SCROLL_HORIZONTAL_FULLR)
scroll &= ~(V2D_SCROLL_HORIZONTAL);
- if (scroll & V2D_SCROLL_VERTICAL_HIDE)
+ if (scroll & V2D_SCROLL_VERTICAL_FULLR)
scroll &= ~(V2D_SCROLL_VERTICAL);
return scroll;
}
/* called each time cur changes, to dynamically update masks */
-static void view2d_masks(View2D *v2d)
+static void view2d_masks(View2D *v2d, int check_scrollers)
{
int scroll;
@@ -90,19 +93,26 @@ static void view2d_masks(View2D *v2d)
v2d->mask.xmax = v2d->winx - 1; /* -1 yes! masks are pixels */
v2d->mask.ymax = v2d->winy - 1;
-#if 0
- /* XXX see above */
- v2d->scroll &= ~(V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_VERTICAL_HIDE);
- /* check size if: */
- if (v2d->scroll & V2D_SCROLL_HORIZONTAL)
- if (!(v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL))
- if (BLI_rctf_size_x(&v2d->tot) <= BLI_rcti_size_x(&v2d->cur))
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- if (v2d->scroll & V2D_SCROLL_VERTICAL)
- if (!(v2d->scroll & V2D_SCROLL_SCALE_VERTICAL))
- if (BLI_rctf_size_y(&v2d->tot) <= BLI_rctf_size_y(&v2d->cur))
- v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
-#endif
+ if (check_scrollers) {
+ /* check size if hiding flag is set: */
+ if (v2d->scroll & V2D_SCROLL_HORIZONTAL_HIDE) {
+ if (!(v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL)) {
+ if (BLI_rctf_size_x(&v2d->tot) > BLI_rctf_size_x(&v2d->cur))
+ v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR;
+ else
+ v2d->scroll |= V2D_SCROLL_HORIZONTAL_FULLR;
+ }
+ }
+ if (v2d->scroll & V2D_SCROLL_VERTICAL_HIDE) {
+ if (!(v2d->scroll & V2D_SCROLL_SCALE_VERTICAL)) {
+ if (BLI_rctf_size_y(&v2d->tot) + 0.01f > BLI_rctf_size_y(&v2d->cur))
+ v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR;
+ else
+ v2d->scroll |= V2D_SCROLL_VERTICAL_FULLR;
+ }
+ }
+ }
+
scroll = view2d_scroll_mapped(v2d->scroll);
/* scrollers shrink mask area, but should be based off regionsize
@@ -126,8 +136,8 @@ static void view2d_masks(View2D *v2d)
}
/* horizontal scroller */
- if (scroll & (V2D_SCROLL_BOTTOM | V2D_SCROLL_BOTTOM_O)) {
- /* on bottom edge of region (V2D_SCROLL_BOTTOM_O is outliner, the other is for standard) */
+ if (scroll & (V2D_SCROLL_BOTTOM)) {
+ /* on bottom edge of region */
v2d->hor = v2d->mask;
v2d->hor.ymax = V2D_SCROLL_HEIGHT;
v2d->mask.ymin = v2d->hor.ymax + 1;
@@ -142,8 +152,8 @@ static void view2d_masks(View2D *v2d)
/* adjust vertical scroller if there's a horizontal scroller, to leave corner free */
if (scroll & V2D_SCROLL_VERTICAL) {
/* just set y min/max for vertical scroller to y min/max of mask as appropriate */
- if (scroll & (V2D_SCROLL_BOTTOM | V2D_SCROLL_BOTTOM_O)) {
- /* on bottom edge of region (V2D_SCROLL_BOTTOM_O is outliner, the other is for standard) */
+ if (scroll & (V2D_SCROLL_BOTTOM)) {
+ /* on bottom edge of region */
v2d->vert.ymin = v2d->mask.ymin;
}
else if (scroll & V2D_SCROLL_TOP) {
@@ -152,7 +162,6 @@ static void view2d_masks(View2D *v2d)
}
}
}
-
}
/* Refresh and Validation */
@@ -165,163 +174,173 @@ static void view2d_masks(View2D *v2d)
*/
void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
{
- short tot_changed = 0, init = 0;
+ short tot_changed = 0, do_init;
uiStyle *style = UI_GetStyle();
- /* initialize data if there is a need for such */
- if ((v2d->flag & V2D_IS_INITIALISED) == 0) {
- /* set initialized flag so that View2D doesn't get reinitialised next time again */
- v2d->flag |= V2D_IS_INITIALISED;
-
- init = 1;
+ do_init = (v2d->flag & V2D_IS_INITIALISED) == 0;
- /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
- switch (type) {
- /* 'standard view' - optimum setup for 'standard' view behavior,
- * that should be used new views as basis for their
- * own unique View2D settings, which should be used instead of this in most cases...
+ /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
+ switch (type) {
+ /* 'standard view' - optimum setup for 'standard' view behavior,
+ * that should be used new views as basis for their
+ * own unique View2D settings, which should be used instead of this in most cases...
+ */
+ case V2D_COMMONVIEW_STANDARD:
+ {
+ /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
+ v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM);
+ v2d->minzoom = 0.01f;
+ v2d->maxzoom = 1000.0f;
+
+ /* tot rect and cur should be same size, and aligned using 'standard' OpenGL coordinates for now
+ * - region can resize 'tot' later to fit other data
+ * - keeptot is only within bounds, as strict locking is not that critical
+ * - view is aligned for (0,0) -> (winx-1, winy-1) setup
*/
- case V2D_COMMONVIEW_STANDARD:
- {
- /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
- v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM);
- v2d->minzoom = 0.01f;
- v2d->maxzoom = 1000.0f;
-
- /* tot rect and cur should be same size, and aligned using 'standard' OpenGL coordinates for now
- * - region can resize 'tot' later to fit other data
- * - keeptot is only within bounds, as strict locking is not that critical
- * - view is aligned for (0,0) -> (winx-1, winy-1) setup
- */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_BOUNDS;
-
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_BOUNDS;
+
+ if (do_init) {
v2d->tot.xmin = v2d->tot.ymin = 0.0f;
v2d->tot.xmax = (float)(winx - 1);
v2d->tot.ymax = (float)(winy - 1);
v2d->cur = v2d->tot;
-
- /* scrollers - should we have these by default? */
- /* XXX for now, we don't override this, or set it either! */
}
- break;
+ /* scrollers - should we have these by default? */
+ /* XXX for now, we don't override this, or set it either! */
+ }
+ break;
+
+ /* 'list/channel view' - zoom, aspect ratio, and alignment restrictions are set here */
+ case V2D_COMMONVIEW_LIST:
+ {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
- /* 'list/channel view' - zoom, aspect ratio, and alignment restrictions are set here */
- case V2D_COMMONVIEW_LIST:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
-
- /* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = 1;
-
- /* scroller settings are currently not set here... that is left for regions... */
- }
- break;
-
- /* 'stack view' - practically the same as list/channel view, except is located in the pos y half instead.
- * zoom, aspect ratio, and alignment restrictions are set here */
- case V2D_COMMONVIEW_STACK:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
-
- /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = 1;
-
- /* scroller settings are currently not set here... that is left for regions... */
- }
- break;
+ /* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* scroller settings are currently not set here... that is left for regions... */
+ }
+ break;
+
+ /* 'stack view' - practically the same as list/channel view, except is located in the pos y half instead.
+ * zoom, aspect ratio, and alignment restrictions are set here */
+ case V2D_COMMONVIEW_STACK:
+ {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
+
+ /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* scroller settings are currently not set here... that is left for regions... */
+ }
+ break;
+
+ /* 'header' regions - zoom, aspect ratio, alignment, and panning restrictions are set here */
+ case V2D_COMMONVIEW_HEADER:
+ {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
+
+ if (do_init) {
+ v2d->tot.xmin = 0.0f;
+ v2d->tot.xmax = winx;
+ v2d->tot.ymin = 0.0f;
+ v2d->tot.ymax = winy;
+ v2d->cur = v2d->tot;
- /* 'header' regions - zoom, aspect ratio, alignment, and panning restrictions are set here */
- case V2D_COMMONVIEW_HEADER:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
v2d->min[0] = v2d->max[0] = (float)(winx - 1);
v2d->min[1] = v2d->max[1] = (float)(winy - 1);
-
- /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = 1;
-
- /* panning in y-axis is prohibited */
- v2d->keepofs = V2D_LOCKOFS_Y;
-
- /* absolutely no scrollers allowed */
- v2d->scroll = 0;
-
}
- break;
+ /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* panning in y-axis is prohibited */
+ v2d->keepofs = V2D_LOCKOFS_Y;
+
+ /* absolutely no scrollers allowed */
+ v2d->scroll = 0;
+
+ }
+ break;
+
+ /* panels view, with horizontal/vertical align */
+ case V2D_COMMONVIEW_PANELS_UI:
+ {
- /* panels view, with horizontal/vertical align */
- case V2D_COMMONVIEW_PANELS_UI:
- {
+ /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
+ v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM | V2D_KEEPZOOM);
+ v2d->minzoom = 0.5f;
+ v2d->maxzoom = 2.0f;
+
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ v2d->keeptot = V2D_KEEPTOT_BOUNDS;
+
+ /* note, scroll is being flipped in ED_region_panels() drawing */
+ v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
+ if (do_init) {
float panelzoom = (style) ? style->panelzoom : 1.0f;
+ float scrolw = v2d->scroll & V2D_SCROLL_RIGHT ? V2D_SCROLL_WIDTH : 0.0f;
- /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
- v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM | V2D_KEEPZOOM);
- v2d->minzoom = 0.5f;
- v2d->maxzoom = 2.0f;
- //tot_changed = 1;
-
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- v2d->keeptot = V2D_KEEPTOT_BOUNDS;
-
- v2d->scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE;
-
v2d->tot.xmin = 0.0f;
- v2d->tot.xmax = winx;
+ v2d->tot.xmax = winx - scrolw;
v2d->tot.ymax = 0.0f;
v2d->tot.ymin = -winy;
v2d->cur.xmin = 0.0f;
- /* bad workaround for keeping zoom level with scrollers */
- v2d->cur.xmax = (winx - V2D_SCROLL_WIDTH) * panelzoom;
+ v2d->cur.xmax = (winx) * panelzoom - scrolw;
v2d->cur.ymax = 0.0f;
v2d->cur.ymin = (-winy) * panelzoom;
}
- break;
-
- /* other view types are completely defined using their own settings already */
- default:
- /* we don't do anything here, as settings should be fine, but just make sure that rect */
- break;
}
+ break;
+
+ /* other view types are completely defined using their own settings already */
+ default:
+ /* we don't do anything here, as settings should be fine, but just make sure that rect */
+ break;
}
+ /* set initialized flag so that View2D doesn't get reinitialised next time again */
+ v2d->flag |= V2D_IS_INITIALISED;
+
/* store view size */
v2d->winx = winx;
v2d->winy = winy;
- /* set masks */
- view2d_masks(v2d);
+ /* set masks (always do), but leave scroller scheck to totrect_set */
+ view2d_masks(v2d, 0);
/* set 'tot' rect before setting cur? */
- if (tot_changed)
- UI_view2d_totRect_set_resize(v2d, winx, winy, !init);
+ /* XXX confusing stuff here still - I made this function not check scroller hide - that happens in totrect_set */
+ if (tot_changed)
+ UI_view2d_totRect_set_resize(v2d, winx, winy, !do_init);
else
- UI_view2d_curRect_validate_resize(v2d, !init);
+ ui_view2d_curRect_validate_resize(v2d, !do_init, 0);
+
}
/* Ensure View2D rects remain in a viable configuration
* - cur is not allowed to be: larger than max, smaller than min, or outside of tot
*/
// XXX pre2.5 -> this used to be called test_view2d()
-void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
+static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_scrollers)
{
float totwidth, totheight, curwidth, curheight, width, height;
float winx, winy;
@@ -715,12 +734,12 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
}
/* set masks */
- view2d_masks(v2d);
+ view2d_masks(v2d, mask_scrollers);
}
void UI_view2d_curRect_validate(View2D *v2d)
{
- UI_view2d_curRect_validate_resize(v2d, 0);
+ ui_view2d_curRect_validate_resize(v2d, 0, 1);
}
/* ------------------ */
@@ -844,7 +863,7 @@ void UI_view2d_curRect_reset(View2D *v2d)
/* Change the size of the maximum viewable area (i.e. 'tot' rect) */
void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize)
{
- int scroll = view2d_scroll_mapped(v2d->scroll);
+// int scroll = view2d_scroll_mapped(v2d->scroll);
/* don't do anything if either value is 0 */
width = abs(width);
@@ -852,10 +871,11 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize
/* hrumf! */
/* XXX: there are work arounds for this in the panel and file browse code. */
- if (scroll & V2D_SCROLL_HORIZONTAL)
- width -= V2D_SCROLL_WIDTH;
- if (scroll & V2D_SCROLL_VERTICAL)
- height -= V2D_SCROLL_HEIGHT;
+ /* round to int, because this is called with width + V2D_SCROLL_WIDTH */
+// if (scroll & V2D_SCROLL_HORIZONTAL)
+// width -= (int)V2D_SCROLL_WIDTH;
+// if (scroll & V2D_SCROLL_VERTICAL)
+// height -= (int)V2D_SCROLL_HEIGHT;
if (ELEM(0, width, height)) {
if (G.debug & G_DEBUG)
@@ -902,12 +922,21 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize
}
/* make sure that 'cur' rect is in a valid state as a result of these changes */
- UI_view2d_curRect_validate_resize(v2d, resize);
+ ui_view2d_curRect_validate_resize(v2d, resize, 1);
+
}
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
{
+ int scroll = view2d_scroll_mapped(v2d->scroll);
+
UI_view2d_totRect_set_resize(v2d, width, height, 0);
+
+ /* solve bad recursion... if scroller state changed, mask is different, so you get different rects */
+ if (scroll != view2d_scroll_mapped(v2d->scroll)) {
+ UI_view2d_totRect_set_resize(v2d, width, height, 0);
+ }
+
}
int UI_view2d_tab_set(View2D *v2d, int tab)
@@ -1001,16 +1030,16 @@ void UI_view2d_view_ortho(View2D *v2d)
/* XXX ton: this flag set by outliner, for icons */
if (v2d->flag & V2D_PIXELOFS_X) {
- curmasked.xmin = floorf(curmasked.xmin) - 0.001f;
- curmasked.xmax = floorf(curmasked.xmax) - 0.001f;
+ curmasked.xmin = floorf(curmasked.xmin) - (0.001f + xofs);
+ curmasked.xmax = floorf(curmasked.xmax) - (0.001f + xofs);
}
if (v2d->flag & V2D_PIXELOFS_Y) {
- curmasked.ymin = floorf(curmasked.ymin) - 0.001f;
- curmasked.ymax = floorf(curmasked.ymax) - 0.001f;
+ curmasked.ymin = floorf(curmasked.ymin) - (0.001f + yofs);
+ curmasked.ymax = floorf(curmasked.ymax) - (0.001f + yofs);
}
/* set matrix on all appropriate axes */
- wmOrtho2(curmasked.xmin - xofs, curmasked.xmax - xofs, curmasked.ymin - yofs, curmasked.ymax - yofs);
+ wmOrtho2(curmasked.xmin, curmasked.xmax, curmasked.ymin, curmasked.ymax);
/* XXX is this necessary? */
glLoadIdentity();
@@ -1150,7 +1179,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d,
pixels = (float)BLI_rcti_size_x(&v2d->mask);
if (pixels != 0.0f) {
- grid->dx = (U.v2d_min_gridsize * space) / (seconddiv * pixels);
+ grid->dx = (U.v2d_min_gridsize * UI_DPI_FAC * space) / (seconddiv * pixels);
step_to_grid(&grid->dx, &grid->powerx, xunits);
grid->dx *= seconddiv;
}
@@ -1167,7 +1196,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d,
space = BLI_rctf_size_y(&v2d->cur);
pixels = (float)winy;
- grid->dy = U.v2d_min_gridsize * space / pixels;
+ grid->dy = U.v2d_min_gridsize * UI_DPI_FAC * space / pixels;
step_to_grid(&grid->dy, &grid->powery, yunits);
if (yclamp == V2D_GRID_CLAMP) {
@@ -1212,7 +1241,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec2[1] = v2d->cur.ymax;
/* minor gridlines */
- step = (BLI_rcti_size_x(&v2d->mask) + 1) / U.v2d_min_gridsize;
+ step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
UI_ThemeColor(TH_GRID);
for (a = 0; a < step; a++) {
@@ -1246,7 +1275,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec1[0] = grid->startx;
vec2[0] = v2d->cur.xmax;
- step = (BLI_rcti_size_y(&v2d->mask) + 1) / U.v2d_min_gridsize;
+ step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
UI_ThemeColor(TH_GRID);
for (a = 0; a <= step; a++) {
@@ -1427,6 +1456,7 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
rcti vert, hor;
float fac1, fac2, totsize, scrollsize;
int scroll = view2d_scroll_mapped(v2d->scroll);
+ int smaller;
/* scrollers is allocated here... */
scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
@@ -1435,19 +1465,20 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
hor = v2d->hor;
/* slider rects need to be smaller than region */
- hor.xmin += 4;
- hor.xmax -= 4;
+ smaller = (int)(0.2f * U.widget_unit);
+ hor.xmin += smaller;
+ hor.xmax -= smaller;
if (scroll & V2D_SCROLL_BOTTOM)
- hor.ymin += 4;
+ hor.ymin += smaller;
else
- hor.ymax -= 4;
+ hor.ymax -= smaller;
if (scroll & V2D_SCROLL_LEFT)
- vert.xmin += 4;
+ vert.xmin += smaller;
else
- vert.xmax -= 4;
- vert.ymin += 4;
- vert.ymax -= 4;
+ vert.xmax -= smaller;
+ vert.ymin += smaller;
+ vert.ymax -= smaller;
CLAMP(vert.ymin, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
CLAMP(hor.xmin, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
@@ -1491,15 +1522,6 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
CLAMP(scrollers->hor_min, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
}
- /* check whether sliders can disappear due to the full-range being used */
- if (v2d->keeptot) {
- if ((fac1 <= 0.0f) && (fac2 >= 1.0f)) {
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_FULLR;
- scrollers->horfull = 1;
- }
- else
- v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR;
- }
}
/* vertical scrollers */
@@ -1533,15 +1555,6 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
CLAMP(scrollers->vert_min, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
}
- /* check whether sliders can disappear due to the full-range being used */
- if (v2d->keeptot) {
- if ((fac1 <= 0.0f) && (fac2 >= 1.0f)) {
- v2d->scroll |= V2D_SCROLL_VERTICAL_FULLR;
- scrollers->vertfull = 1;
- }
- else
- v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR;
- }
}
/* grid markings on scrollbars */
@@ -1615,40 +1628,42 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* horizontal scrollbar */
if (scroll & V2D_SCROLL_HORIZONTAL) {
- /* only draw scrollbar when it doesn't fill the entire space */
- if (vs->horfull == 0) {
- bTheme *btheme = UI_GetTheme();
- uiWidgetColors wcol = btheme->tui.wcol_scroll;
- rcti slider;
- int state;
-
- slider.xmin = vs->hor_min;
- slider.xmax = vs->hor_max;
- slider.ymin = hor.ymin;
- slider.ymax = hor.ymax;
-
- state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-
- /* show zoom handles if:
- * - zooming on x-axis is allowed (no scroll otherwise)
- * - slider bubble is large enough (no overdraw confusion)
- * - scale is shown on the scroller
- * (workaround to make sure that button windows don't show these,
- * and only the time-grids with their zoomability can do so)
- */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 &&
- (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) &&
- (BLI_rcti_size_x(&slider) > V2D_SCROLLER_HANDLE_SIZE))
- {
- state |= UI_SCROLL_ARROWS;
- }
-
- UI_ThemeColor(TH_BACK);
+ bTheme *btheme = UI_GetTheme();
+ uiWidgetColors wcol = btheme->tui.wcol_scroll;
+ rcti slider;
+ int state;
+ unsigned char col[4];
+
+ slider.xmin = vs->hor_min;
+ slider.xmax = vs->hor_max;
+ slider.ymin = hor.ymin;
+ slider.ymax = hor.ymax;
+
+ state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
+
+ /* show zoom handles if:
+ * - zooming on x-axis is allowed (no scroll otherwise)
+ * - slider bubble is large enough (no overdraw confusion)
+ * - scale is shown on the scroller
+ * (workaround to make sure that button windows don't show these,
+ * and only the time-grids with their zoomability can do so)
+ */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 &&
+ (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) &&
+ (BLI_rcti_size_x(&slider) > V2D_SCROLLER_HANDLE_SIZE))
+ {
+ state |= UI_SCROLL_ARROWS;
+ }
+
+ /* clean rect behind slider, but not with transparent background */
+ UI_GetThemeColor4ubv(TH_BACK, col);
+ if (col[3] == 255) {
+ glColor3ub(col[0], col[1], col[2]);
glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax);
-
- uiWidgetScrollDraw(&wcol, &hor, &slider, state);
}
+ uiWidgetScrollDraw(&wcol, &hor, &slider, state);
+
/* scale indicators */
if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) {
View2DGrid *grid = vs->grid;
@@ -1680,12 +1695,12 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw numbers in the appropriate range */
if (dfac > 0.0f) {
- float h = 2.0f + (float)(hor.ymin);
+ float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin);
- for (; fac < hor.xmax - 10; fac += dfac, val += grid->dx) {
+ for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) {
/* make prints look nicer for scrollers */
- if (fac < hor.xmin + 10)
+ if (fac < hor.xmin + 0.5f * U.widget_unit)
continue;
switch (vs->xunits) {
@@ -1726,40 +1741,42 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* vertical scrollbar */
if (scroll & V2D_SCROLL_VERTICAL) {
- /* only draw scrollbar when it doesn't fill the entire space */
- if (vs->vertfull == 0) {
- bTheme *btheme = UI_GetTheme();
- uiWidgetColors wcol = btheme->tui.wcol_scroll;
- rcti slider;
- int state;
-
- slider.xmin = vert.xmin;
- slider.xmax = vert.xmax;
- slider.ymin = vs->vert_min;
- slider.ymax = vs->vert_max;
-
- state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-
- /* show zoom handles if:
- * - zooming on y-axis is allowed (no scroll otherwise)
- * - slider bubble is large enough (no overdraw confusion)
- * - scale is shown on the scroller
- * (workaround to make sure that button windows don't show these,
- * and only the time-grids with their zoomability can do so)
- */
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 &&
- (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) &&
- (BLI_rcti_size_y(&slider) > V2D_SCROLLER_HANDLE_SIZE))
- {
- state |= UI_SCROLL_ARROWS;
- }
-
- UI_ThemeColor(TH_BACK);
+ bTheme *btheme = UI_GetTheme();
+ uiWidgetColors wcol = btheme->tui.wcol_scroll;
+ rcti slider;
+ int state;
+ unsigned char col[4];
+
+ slider.xmin = vert.xmin;
+ slider.xmax = vert.xmax;
+ slider.ymin = vs->vert_min;
+ slider.ymax = vs->vert_max;
+
+ state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
+
+ /* show zoom handles if:
+ * - zooming on y-axis is allowed (no scroll otherwise)
+ * - slider bubble is large enough (no overdraw confusion)
+ * - scale is shown on the scroller
+ * (workaround to make sure that button windows don't show these,
+ * and only the time-grids with their zoomability can do so)
+ */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 &&
+ (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) &&
+ (BLI_rcti_size_y(&slider) > V2D_SCROLLER_HANDLE_SIZE))
+ {
+ state |= UI_SCROLL_ARROWS;
+ }
+
+ /* clean rect behind slider, but not with transparent background */
+ UI_GetThemeColor4ubv(TH_BACK, col);
+ if (col[3] == 255) {
+ glColor3ub(col[0], col[1], col[2]);
glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax);
-
- uiWidgetScrollDraw(&wcol, &vert, &slider, state);
}
+ uiWidgetScrollDraw(&wcol, &vert, &slider, state);
+
/* scale indiators */
if ((scroll & V2D_SCROLL_SCALE_VERTICAL) && (vs->grid)) {
@@ -1789,7 +1806,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw vertical steps */
if (dfac > 0.0f) {
- BLF_rotation_default(90.0f);
+ BLF_rotation_default(M_PI / 2);
BLF_enable_default(BLF_ROTATION);
for (; fac < vert.ymax - 10; fac += dfac, val += grid->dy) {
@@ -2047,6 +2064,12 @@ void UI_view2d_getscale(View2D *v2d, float *x, float *y)
if (x) *x = BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur);
if (y) *y = BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur);
}
+/* Same as UI_view2d_getscale() - 1.0f / x, y */
+void UI_view2d_getscale_inverse(View2D *v2d, float *x, float *y)
+{
+ if (x) *x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
+ if (y) *y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
+}
/* Check if mouse is within scrollers
* - Returns appropriate code for match
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 48a1f8bf0f3..7f1140501b5 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -937,7 +937,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
vzd = op->customdata;
v2d = vzd->v2d;
- if (event->type == MOUSEZOOM) {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float dx, dy, fac;
vzd->lastx = event->prevx;
@@ -946,10 +946,19 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* As we have only 1D information (magnify value), feed both axes
* with magnify information that is stored in x axis
*/
- fac = 0.01f * (event->x - event->prevx);
+ fac = 0.01f * (event->prevx - event->x);
dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f;
+ if (event->type == MOUSEPAN)
+ fac = 0.01f * (event->prevy - event->y);
dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f;
+ /* support trackpad zoom to always zoom entirely - the v2d code uses portrait or landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(dx) > fabsf(dy))
+ dy = dx;
+ else
+ dx = dy;
+ }
RNA_float_set(op->ptr, "deltax", dx);
RNA_float_set(op->ptr, "deltay", dy);
@@ -1015,37 +1024,37 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
/* x-axis transform */
dist = BLI_rcti_size_x(&v2d->mask) / 2.0f;
- dx = 1.0f - (fabsf(vzd->lastx - dist) + 2.0f) / (fabsf(event->x - dist) + 2.0f);
+ dx = 1.0f - (fabsf(vzd->lastx - vzd->ar->winrct.xmin - dist) + 2.0f) / (fabsf(event->mval[0] - dist) + 2.0f);
dx *= 0.5f * BLI_rctf_size_x(&v2d->cur);
/* y-axis transform */
dist = BLI_rcti_size_y(&v2d->mask) / 2.0f;
- dy = 1.0f - (fabsf(vzd->lasty - dist) + 2.0f) / (fabsf(event->y - dist) + 2.0f);
+ dy = 1.0f - (fabsf(vzd->lasty - vzd->ar->winrct.ymin - dist) + 2.0f) / (fabsf(event->mval[1] - dist) + 2.0f);
dy *= 0.5f * BLI_rctf_size_y(&v2d->cur);
}
else {
/* 'continuous' or 'dolly' */
- float fac;
+ float fac, zoomfac = 0.001f * v2d->maxzoom;
+
+ /* some view2d's (graph) don't have min/max zoom, or extreme ones */
+ CLAMP (zoomfac, 0.001f, 0.01f);
/* x-axis transform */
- fac = 0.01f * (event->x - vzd->lastx);
+ fac = zoomfac * (event->x - vzd->lastx);
dx = fac * BLI_rctf_size_x(&v2d->cur);
/* y-axis transform */
- fac = 0.01f * (event->y - vzd->lasty);
+ fac = zoomfac * (event->y - vzd->lasty);
dy = fac * BLI_rctf_size_y(&v2d->cur);
-#if 0
- /* continuous zoom shouldn't move that fast... */
- if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop?
- double time = PIL_check_seconds_timer();
- float time_step = (float)(time - vzd->timer_lastdraw);
-
- dx /= (0.1f / time_step);
- dy /= (0.1f / time_step);
-
- vzd->timer_lastdraw = time;
- }
-#endif
+
+ }
+
+ /* support zoom to always zoom entirely - the v2d code uses portrait or landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(dx) > fabsf(dy))
+ dy = dx;
+ else
+ dx = dy;
}
/* set transform amount, and add current deltas to stored total delta (for redo) */
@@ -1755,8 +1764,8 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* zone is also inappropriate if scroller is not visible... */
- if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_HORIZONTAL_FULLR))) ||
- ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_HIDE | V2D_SCROLL_VERTICAL_FULLR))) )
+ if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_FULLR))) ||
+ ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_FULLR))) )
{
/* free customdata initialized */
scroller_activate_exit(C, op);
@@ -1914,6 +1923,7 @@ void UI_view2d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW2D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
@@ -1962,6 +1972,7 @@ void UI_view2d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_reset", HOMEKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/io/CMakeLists.txt b/source/blender/editors/io/CMakeLists.txt
index 7db23041c88..d4ae5b8b29b 100644
--- a/source/blender/editors/io/CMakeLists.txt
+++ b/source/blender/editors/io/CMakeLists.txt
@@ -47,4 +47,8 @@ if(WITH_OPENCOLLADA)
add_definitions(-DWITH_COLLADA)
endif()
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_io "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/io/SConscript b/source/blender/editors/io/SConscript
index d012576637c..b7449ccad79 100644
--- a/source/blender/editors/io/SConscript
+++ b/source/blender/editors/io/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import ('env')
@@ -11,4 +36,7 @@ incs += '../../makesdna ../../makesrna ../../windowmanager ../../collada'
if env['WITH_BF_COLLADA']:
defs += ['WITH_COLLADA']
+if env['WITH_BF_INTERNATIONAL']:
+ defs += ['WITH_INTERNATIONAL']
+
env.BlenderLib ( 'bf_editor_io', sources, Split(incs), defines=defs, libtype=['core','player'], priority=[330,210] )
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index ba93206e63a..7703a8638c9 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -84,6 +84,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int selected;
int include_children;
int include_armatures;
+ int include_shapekeys;
int deform_bones_only;
int include_uv_textures;
@@ -109,6 +110,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
selected = RNA_boolean_get(op->ptr, "selected");
include_children = RNA_boolean_get(op->ptr, "include_children");
include_armatures = RNA_boolean_get(op->ptr, "include_armatures");
+ include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys");
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures");
@@ -130,6 +132,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
selected,
include_children,
include_armatures,
+ include_shapekeys,
deform_bones_only,
active_uv_only,
@@ -176,6 +179,10 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE);
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
+ row = uiLayoutRow(box, FALSE);
+ uiItemR(row, imfptr, "include_shapekeys", 0, NULL, ICON_NONE);
+ uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
+
/* Texture options */
box = uiLayoutBox(layout);
row = uiLayoutRow(box, FALSE);
@@ -266,6 +273,9 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures",
"Export related armatures (even if not selected)");
+ RNA_def_boolean(ot->srna, "include_shapekeys", 1, "Include Shape Keys",
+ "Export all Shape Keys from Mesh Objects");
+
RNA_def_boolean(ot->srna, "deform_bones_only", 0, "Deform Bones only",
"Only export deforming bones with armatures");
@@ -298,18 +308,45 @@ void WM_OT_collada_export(wmOperatorType *ot)
static int wm_collada_import_exec(bContext *C, wmOperator *op)
{
char filename[FILE_MAX];
+ int import_units;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
return OPERATOR_CANCELLED;
}
+ /* Options panel */
+ import_units = RNA_boolean_get(op->ptr, "import_units");
+
RNA_string_get(op->ptr, "filepath", filename);
- if (collada_import(C, filename)) return OPERATOR_FINISHED;
+ if (collada_import(C, filename, import_units)) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)");
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
+{
+ uiLayout *box, *row;
- BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)");
+ /* Import Options: */
+ box = uiLayoutBox(layout);
+ row = uiLayoutRow(box, FALSE);
+ uiItemL(row, IFACE_("Import Data Options:"), ICON_MESH_DATA);
+
+ row = uiLayoutRow(box, FALSE);
+ uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE);
+}
+
+static void wm_collada_import_draw(bContext *UNUSED(C), wmOperator *op)
+{
+ PointerRNA ptr;
- return OPERATOR_FINISHED;
+ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+ uiCollada_importSettings(op->layout, &ptr);
}
void WM_OT_collada_import(wmOperatorType *ot)
@@ -322,7 +359,17 @@ void WM_OT_collada_import(wmOperatorType *ot)
ot->exec = wm_collada_import_exec;
ot->poll = WM_operator_winactive;
+ //ot->flag |= OPTYPE_PRESET;
+
+ ot->ui = wm_collada_import_draw;
+
WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, 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");
+
}
#endif
diff --git a/source/blender/editors/mask/SConscript b/source/blender/editors/mask/SConscript
index 4af000d038d..3200362b580 100644
--- a/source/blender/editors/mask/SConscript
+++ b/source/blender/editors/mask/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index e43c8a2b53b..77abe43bba7 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -720,7 +720,7 @@ static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event
void MASK_OT_add_feather_vertex(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add feather Vertex";
+ ot->name = "Add Feather Vertex";
ot->description = "Add vertex to feather";
ot->idname = "MASK_OT_add_feather_vertex";
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 74cdf4c2a11..af9d3341e61 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -409,7 +409,7 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline
int width, int height)
{
const unsigned int resol = max_ii(BKE_mask_spline_feather_resolution(spline, width, height),
- BKE_mask_spline_resolution(spline, width, height));
+ BKE_mask_spline_resolution(spline, width, height));
unsigned char rgb_tmp[4];
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index 18384ad9de4..cd2995be439 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -324,15 +324,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s
case SPACE_CLIP:
{
SpaceClip *sc = sa->spacedata.first;
- int width, height;
- float zoomx, zoomy, aspx, aspy;
+ float aspx, aspy;
- ED_space_clip_get_size(sc, &width, &height);
- ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
+ UI_view2d_getscale(&ar->v2d, scalex, scaley);
ED_space_clip_get_aspect(sc, &aspx, &aspy);
- *scalex = ((float)width * aspx) * zoomx;
- *scaley = ((float)height * aspy) * zoomy;
+ *scalex *= aspx;
+ *scaley *= aspy;
break;
}
case SPACE_SEQ:
@@ -343,15 +341,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s
case SPACE_IMAGE:
{
SpaceImage *sima = sa->spacedata.first;
- int width, height;
- float zoomx, zoomy, aspx, aspy;
+ float aspx, aspy;
- ED_space_image_get_size(sima, &width, &height);
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ UI_view2d_getscale(&ar->v2d, scalex, scaley);
ED_space_image_get_aspect(sima, &aspx, &aspy);
- *scalex = ((float)width * aspx) * zoomx;
- *scaley = ((float)height * aspy) * zoomy;
+ *scalex *= aspx;
+ *scaley *= aspy;
break;
}
default:
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 35f85f3faee..0a996c11f14 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -36,6 +36,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_main.h"
#include "BKE_mask.h"
#include "DNA_scene_types.h"
@@ -261,9 +262,10 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[
Mask *ED_mask_new(bContext *C, const char *name)
{
ScrArea *sa = CTX_wm_area(C);
+ Main *bmain = CTX_data_main(C);
Mask *mask;
- mask = BKE_mask_new(name);
+ mask = BKE_mask_new(bmain, name);
if (sa && sa->spacedata.first) {
switch (sa->spacetype) {
diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c
index a1f2539ce7c..2a1bdee32f7 100644
--- a/source/blender/editors/mask/mask_relationships.c
+++ b/source/blender/editors/mask/mask_relationships.c
@@ -31,6 +31,7 @@
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -143,8 +144,8 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
if (MASKPOINT_ISSEL_ANY(point)) {
point->parent.id_type = ID_MC;
point->parent.id = &clip->id;
- strcpy(point->parent.parent, tracking_object->name);
- strcpy(point->parent.sub_parent, track->name);
+ BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent));
+ BLI_strncpy(point->parent.sub_parent, track->name, sizeof(point->parent.sub_parent));
copy_v2_v2(point->parent.parent_orig, parmask_pos);
}
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index c51d2cfb2e5..169e7a60fb1 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -48,7 +48,6 @@ set(SRC
editmesh_select.c
editmesh_tools.c
editmesh_utils.c
- editmesh_slide.c
mesh_data.c
mesh_ops.c
meshtools.c
diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript
index 91ffdc91685..11c90a4a922 100644
--- a/source/blender/editors/mesh/SConscript
+++ b/source/blender/editors/mesh/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 4350c005f95..7ac27e038a4 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -27,23 +27,20 @@
* \ingroup edmesh
*/
-#include <math.h>
-#include <string.h>
#include "MEM_guardedalloc.h"
-#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
+#include "BLF_translation.h"
+
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
@@ -61,7 +58,6 @@
#include "WM_types.h"
/* own include */
-#include "mesh_intern.h"
/* copy the face flags, most importantly selection from the mesh to the final derived mesh,
* use in object mode when selecting faces (while painting) */
@@ -75,7 +71,14 @@ void paintface_flush_flags(Object *ob)
int totface, totpoly;
int i;
- if (me == NULL || dm == NULL)
+ if (me == NULL)
+ return;
+
+ /* we could call this directly in all areas that change selection,
+ * since this could become slow for realtime updates (circle-select for eg) */
+ BKE_mesh_flush_select_from_polys(me);
+
+ if (dm == NULL)
return;
/*
@@ -428,7 +431,7 @@ void seam_mark_clear_tface(Scene *scene, short mode)
if (me == 0 || me->totpoly == 0) return;
if (mode == 0)
- mode = pupmenu("Seams %t|Mark Border Seam %x1|Clear Seam %x2");
+ mode = pupmenu(IFACE_("Seams %t|Mark Border Seam %x1|Clear Seam %x2"));
if (mode != 1 && mode != 2)
return;
@@ -483,7 +486,7 @@ int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], in
/* Get the face under the cursor */
me = BKE_mesh_from_object(ob);
- if (!ED_mesh_pick_face(C, me, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE))
+ if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE))
return 0;
if (index >= me->totpoly)
@@ -609,7 +612,14 @@ void paintvert_flush_flags(Object *ob)
int totvert;
int i;
- if (me == NULL || dm == NULL)
+ if (me == NULL)
+ return;
+
+ /* we could call this directly in all areas that change selection,
+ * since this could become slow for realtime updates (circle-select for eg) */
+ BKE_mesh_flush_select_from_verts(me);
+
+ if (dm == NULL)
return;
index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
@@ -852,7 +862,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
if (em) {
if (skip_em_vert_array_init == FALSE) {
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
}
}
@@ -888,11 +898,6 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
last = a;
}
}
- if (em) {
- if (skip_em_vert_array_init == FALSE) {
- EDBM_index_arrays_free(em);
- }
- }
MEM_freeN(topo_pairs);
topo_pairs = NULL;
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 4a425c83d86..a356f9fca7f 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -29,7 +29,6 @@
* \ingroup edmesh
*/
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -39,7 +38,6 @@
#include "BLI_math.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_library.h"
#include "BKE_tessmesh.h"
@@ -58,7 +56,7 @@
/* BMESH_TODO: 'state' is not a good name, should be flipped and called 'was_editmode',
* or at least something more descriptive */
static Object *make_prim_init(bContext *C, const char *idname,
- float *dia, float mat[][4],
+ float *dia, float mat[4][4],
int *state, const float loc[3], const float rot[3], const unsigned int layer)
{
Object *obedit = CTX_data_edit_object(C);
@@ -90,7 +88,7 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
/* only recalc editmode tessface if we are staying in editmode */
- EDBM_update_generic(C, em, !exit_editmode);
+ EDBM_update_generic(em, !exit_editmode, TRUE);
/* userdef */
if (exit_editmode) {
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index a59c491fe13..d7dbe3506b1 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -38,14 +38,13 @@
#include "BLI_blenlib.h"
#include "BLI_array.h"
#include "BLI_math.h"
-#include "BLI_rand.h"
#include "BLI_smallhash.h"
-#include "BLI_scanfill.h"
#include "BLI_memarena.h"
+#include "BLF_translation.h"
+
#include "BKE_DerivedMesh.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BIF_gl.h"
#include "BIF_glutil.h" /* for paint cursor */
@@ -59,7 +58,6 @@
#include "WM_types.h"
#include "DNA_scene_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BKE_tessmesh.h"
#include "UI_resources.h"
@@ -132,7 +130,7 @@ typedef struct KnifePosData {
BMFace *bmface;
int is_space;
- int mval[2]; /* mouse screen position */
+ float mval[2]; /* mouse screen position (may be non-integral if snapped to something) */
} KnifePosData;
/* struct for properties used while drawing */
@@ -208,27 +206,32 @@ typedef struct KnifeTool_OpData {
static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f);
#if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
float r_origin[3], float r_ray[3]);
#endif
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
float r_origin[3], float r_dest[3]);
static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
{
- #define HEADER_LENGTH 190
+ #define HEADER_LENGTH 256
char header[HEADER_LENGTH];
- BLI_snprintf(header, HEADER_LENGTH, "LMB: define cut lines, Return/Spacebar: confirm, Esc or RMB: cancel, E: new cut, Ctrl: midpoint snap (%s), "
- "Shift: ignore snap (%s), C: angle constrain (%s), Z: cut through (%s)",
- kcd->snap_midpoints ? "On" : "Off",
- kcd->ignore_edge_snapping ? "On" : "Off",
- kcd->angle_snapping ? "On" : "Off",
- kcd->cut_through ? "On" : "Off");
+ BLI_snprintf(header, HEADER_LENGTH, IFACE_("LMB: define cut lines, Return/Spacebar: confirm, Esc or RMB: cancel, "
+ "E: new cut, Ctrl: midpoint snap (%s), Shift: ignore snap (%s), "
+ "C: angle constrain (%s), Z: cut through (%s)"),
+ kcd->snap_midpoints ? IFACE_("On") : IFACE_("Off"),
+ kcd->ignore_edge_snapping ? IFACE_("On") : IFACE_("Off"),
+ kcd->angle_snapping ? IFACE_("On") : IFACE_("Off"),
+ kcd->cut_through ? IFACE_("On") : IFACE_("Off"));
ED_area_headerprint(CTX_wm_area(C), header);
}
+BLI_INLINE int round_ftoi(float x)
+{
+ return x > 0.0f ? (int)(x + 0.5f) : (int)(x - 0.5f);
+}
static void knife_project_v3(KnifeTool_OpData *kcd, const float co[3], float sco[3])
{
@@ -242,8 +245,8 @@ static void knife_pos_data_clear(KnifePosData *kpd)
kpd->vert = NULL;
kpd->edge = NULL;
kpd->bmface = NULL;
- kpd->mval[0] = 0;
- kpd->mval[1] = 0;
+ kpd->mval[0] = 0.0f;
+ kpd->mval[1] = 0.0f;
}
static ListBase *knife_empty_list(KnifeTool_OpData *kcd)
@@ -645,6 +648,7 @@ static void knife_get_vert_faces(KnifeTool_OpData *kcd, KnifeVert *kfv, BMFace *
{
BMIter bmiter;
BMFace *f;
+ Ref *r;
if (kfv->isface && facef) {
knife_append_list(kcd, lst, facef);
@@ -654,6 +658,11 @@ static void knife_get_vert_faces(KnifeTool_OpData *kcd, KnifeVert *kfv, BMFace *
knife_append_list(kcd, lst, f);
}
}
+ else {
+ for (r = kfv->faces.first; r; r = r->next) {
+ knife_append_list(kcd, lst, r->ref);
+ }
+ }
}
static void knife_get_edge_faces(KnifeTool_OpData *kcd, KnifeEdge *kfe, ListBase *lst)
@@ -720,7 +729,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
for (r = firstfaces.first; r; r = r->next) {
f = r->ref;
found = 0;
- for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit; j++, lh2++) {
+ for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit && !found; j++, lh2++) {
kfe2 = lh2->kfe;
for (r2 = kfe2->faces.first; r2; r2 = r2->next) {
if (r2->ref == f) {
@@ -750,7 +759,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
for (r = kfe->faces.first; r; r = r->next) {
f = r->ref;
found = 0;
- for (j = i + 1, lh2 = lh + 1; j < kcd->totlinehit; j++, lh2++) {
+ for (j = i + 1, lh2 = lh + 1; j < kcd->totlinehit && !found; j++, lh2++) {
kfe2 = lh2->kfe;
for (r2 = kfe2->faces.first; r2; r2 = r2->next) {
if (r2->ref == f) {
@@ -780,6 +789,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
kcd->totlinehit = 0;
/* set up for next cut */
+ kcd->curr.vert = lastv;
kcd->prev = kcd->curr;
}
@@ -1150,7 +1160,7 @@ static float len_v3_tri_side_max(const float v1[3], const float v2[3], const flo
const float s2 = len_squared_v3v3(v2, v3);
const float s3 = len_squared_v3v3(v3, v1);
- return sqrtf(MAX3(s1, s2, s3));
+ return sqrtf(max_fff(s1, s2, s3));
}
static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
@@ -1319,12 +1329,12 @@ static void knife_bgl_get_mats(KnifeTool_OpData *UNUSED(kcd), bglMats *mats)
//copy_m4_m4(mats->projection, kcd->vc.rv3d->winmat);
}
-/* Calculate maximum excursion (doubled) from (0,0,0) of mesh */
+/* Calculate maximum excursion from (0,0,0) of mesh */
static void calc_ortho_extent(KnifeTool_OpData *kcd)
{
BMIter iter;
BMVert *v;
- BMesh* bm = kcd->em->bm;
+ BMesh *bm = kcd->em->bm;
float max_xyz = 0.0f;
int i;
@@ -1332,7 +1342,19 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
for (i = 0; i < 3; i++)
max_xyz = max_ff(max_xyz, fabs(v->co[i]));
}
- kcd->ortho_extent = 2 * max_xyz;
+ kcd->ortho_extent = max_xyz;
+}
+
+/* Clip the line (v1, v2) to planes perpendicular to it and distances d from
+ * the closest point on the line to the origin */
+static void clip_to_ortho_planes(float v1[3], float v2[3], float d)
+{
+ float closest[3];
+ const float origin[3] = {0.0f, 0.0f, 0.0f};
+
+ closest_to_line_v3(closest, origin, v1, v2);
+ dist_ensure_v3_v3fl(v1, closest, d);
+ dist_ensure_v3_v3fl(v2, closest, d);
}
/* Finds visible (or all, if cutting through) edges that intersects the current screen drag line */
@@ -1379,8 +1401,8 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
if (kcd->is_ortho) {
if (kcd->ortho_extent == 0.0f)
calc_ortho_extent(kcd);
- limit_dist_v3(v1, v3, kcd->ortho_extent + 10.0f);
- limit_dist_v3(v2, v4, kcd->ortho_extent + 10.0f);
+ clip_to_ortho_planes(v1, v3, kcd->ortho_extent + 10.0f);
+ clip_to_ortho_planes(v2, v4, kcd->ortho_extent + 10.0f);
}
BLI_smallhash_init(ehash);
@@ -1412,17 +1434,14 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
/* this works but gives numeric problems [#33400] */
#if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
float r_origin[3], float r_ray[3])
{
bglMats mats;
- float mval[2], imat[3][3];
+ float imat[3][3];
knife_bgl_get_mats(kcd, &mats);
- mval[0] = (float)mval_i[0];
- mval[1] = (float)mval_i[1];
-
/* unproject to find view ray */
ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
@@ -1444,23 +1463,19 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
}
#endif
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
float r_origin[3], float r_origin_ofs[3])
{
bglMats mats;
- float mval[2];
knife_bgl_get_mats(kcd, &mats);
- mval[0] = (float)mval_i[0];
- mval[1] = (float)mval_i[1];
-
/* unproject to find view ray */
ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs);
/* transform into object space */
- invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
+ invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
mul_m4_v3(kcd->ob->imat, r_origin);
mul_m4_v3(kcd->ob->imat, r_origin_ofs);
@@ -1475,7 +1490,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
float ray[3];
/* unproject to find view ray */
- knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+ knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
sub_v3_v3v3(ray, origin_ofs, origin);
f = BMBVH_RayCast(kcd->bmbvh, origin, ray, co, cageco);
@@ -1594,10 +1609,10 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo
dis = dist_to_line_segment_v2(sco, kfe->v1->sco, kfe->v2->sco);
if (dis < curdis && dis < maxdist) {
if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) {
- float labda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco);
+ float lambda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco);
float vec[3];
- interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, labda);
+ interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, lambda);
if (ED_view3d_clipping_test(kcd->vc.rv3d, vec, TRUE) == 0) {
cure = kfe;
@@ -1633,8 +1648,8 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo
/* update mouse coordinates to the snapped-to edge's screen coordinates
* this is important for angle snap, which uses the previous mouse position */
edgesnap = new_knife_vert(kcd, p, cagep);
- kcd->curr.mval[0] = (int)edgesnap->sco[0];
- kcd->curr.mval[1] = (int)edgesnap->sco[1];
+ kcd->curr.mval[0] = edgesnap->sco[0];
+ kcd->curr.mval[1] = edgesnap->sco[1];
}
else {
@@ -1712,8 +1727,8 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
/* update mouse coordinates to the snapped-to vertex's screen coordinates
* this is important for angle snap, which uses the previous mouse position */
- kcd->curr.mval[0] = (int)curv->sco[0];
- kcd->curr.mval[1] = (int)curv->sco[1];
+ kcd->curr.mval[0] = curv->sco[0];
+ kcd->curr.mval[1] = curv->sco[1];
}
return curv;
@@ -1732,48 +1747,56 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
return NULL;
}
+/* update both kcd->curr.mval and kcd->vc.mval to snap to required angle */
static void knife_snap_angle(KnifeTool_OpData *kcd)
{
- int dx, dy;
+ float dx, dy;
float w, abs_tan;
- dx = kcd->vc.mval[0] - kcd->prev.mval[0];
- dy = kcd->vc.mval[1] - kcd->prev.mval[1];
- if (dx == 0 || dy == 0)
+ dx = kcd->curr.mval[0] - kcd->prev.mval[0];
+ dy = kcd->curr.mval[1] - kcd->prev.mval[1];
+ if (dx == 0.0f && dy == 0.0f)
return;
- w = (float)dy / (float)dx;
+ if (dx == 0.0f) {
+ kcd->angle_snapping = ANGLE_90;
+ kcd->curr.mval[0] = kcd->prev.mval[0];
+ }
+
+ w = dy / dx;
abs_tan = fabsf(w);
if (abs_tan <= 0.4142f) { /* tan(22.5 degrees) = 0.4142 */
kcd->angle_snapping = ANGLE_0;
- kcd->vc.mval[1] = kcd->prev.mval[1];
+ kcd->curr.mval[1] = kcd->prev.mval[1];
}
else if (abs_tan < 2.4142f) { /* tan(67.5 degrees) = 2.4142 */
if (w > 0) {
kcd->angle_snapping = ANGLE_45;
- kcd->vc.mval[1] = kcd->prev.mval[1] + dx;
+ kcd->curr.mval[1] = kcd->prev.mval[1] + dx;
}
else {
kcd->angle_snapping = ANGLE_135;
- kcd->vc.mval[1] = kcd->prev.mval[1] - dx;
+ kcd->curr.mval[1] = kcd->prev.mval[1] - dx;
}
}
else {
kcd->angle_snapping = ANGLE_90;
- kcd->vc.mval[0] = kcd->prev.mval[0];
+ kcd->curr.mval[0] = kcd->prev.mval[0];
}
+
+ kcd->vc.mval[0] = round_ftoi(kcd->curr.mval[0]);
+ kcd->vc.mval[1] = round_ftoi(kcd->curr.mval[1]);
}
/* update active knife edge/vert pointers */
static int knife_update_active(KnifeTool_OpData *kcd)
{
+ knife_pos_data_clear(&kcd->curr);
+ kcd->curr.mval[0] = (float)kcd->vc.mval[0];
+ kcd->curr.mval[1] = (float)kcd->vc.mval[1];
if (kcd->angle_snapping != ANGLE_FREE && kcd->mode == MODE_DRAGGING)
knife_snap_angle(kcd);
- knife_pos_data_clear(&kcd->curr);
- kcd->curr.mval[0] = kcd->vc.mval[0];
- kcd->curr.mval[1] = kcd->vc.mval[1];
-
/* XXX knife_snap_angle updates the view coordinate mouse values to constrained angles,
* which current mouse values are set to current mouse values are then used
* for vertex and edge snap detection, without regard to the exact angle constraint */
@@ -1791,7 +1814,7 @@ static int knife_update_active(KnifeTool_OpData *kcd)
float origin[3];
float origin_ofs[3];
- knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+ knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
closest_to_line_v3(kcd->curr.cage, kcd->prev.cage, origin_ofs, origin);
}
@@ -1840,7 +1863,7 @@ static void remerge_faces(KnifeTool_OpData *kcd)
BMOperator bmop;
int idx;
- BMO_op_initf(bm, &bmop, "beautify_fill faces=%ff constrain_edges=%fe", FACE_NEW, BOUNDARY);
+ BMO_op_initf(bm, &bmop, "beautify_fill faces=%ff edges=%Fe", FACE_NEW, BOUNDARY);
BMO_op_exec(bm, &bmop);
BMO_slot_buffer_flag_enable(bm, &bmop, "geom.out", BM_FACE, FACE_NEW);
@@ -2591,10 +2614,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
BMLoop *lnew, *l_iter;
int i;
int nco = BLI_countlist(chain) - 1;
- float (*cos)[3] = NULL;
- KnifeVert **kverts;
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
- BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
+ float (*cos)[3] = BLI_array_alloca(cos, nco);
+ KnifeVert **kverts = BLI_array_alloca(kverts, nco);
kfe = ((Ref *)chain->first)->ref;
v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v;
@@ -2643,9 +2664,6 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
BM_edge_select_set(bm, lnew->e, TRUE);
}
}
-
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(kverts);
}
static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges)
@@ -2835,7 +2853,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
#endif
/* called on tool confirmation */
-static void knifetool_finish(bContext *C, wmOperator *op)
+static void knifetool_finish(wmOperator *op)
{
KnifeTool_OpData *kcd = op->customdata;
@@ -2846,7 +2864,7 @@ static void knifetool_finish(bContext *C, wmOperator *op)
#endif
EDBM_mesh_normals_update(kcd->em);
- EDBM_update_generic(C, kcd->em, TRUE);
+ EDBM_update_generic(kcd->em, TRUE, TRUE);
}
/* copied from paint_image.c */
@@ -2926,11 +2944,11 @@ static void cage_mapped_verts_callback(void *userData, int index, const float co
}
}
-static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval[2])
+static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval_i[2])
{
knife_recalc_projmat(kcd);
- kcd->vc.mval[0] = mval[0];
- kcd->vc.mval[1] = mval[1];
+ kcd->vc.mval[0] = mval_i[0];
+ kcd->vc.mval[1] = mval_i[1];
if (knife_update_active(kcd)) {
ED_region_tag_redraw(kcd->ar);
@@ -3134,7 +3152,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
/* finish */
ED_region_tag_redraw(kcd->ar);
- knifetool_finish(C, op);
+ knifetool_finish(op);
knifetool_exit(C, op);
ED_area_headerprint(CTX_wm_area(C), NULL);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index dec45b7f326..83542915ec2 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -28,46 +28,23 @@
* \ingroup edmesh
*/
-#include <float.h>
-#ifdef _MSC_VER
-# define _USE_MATH_DEFINES
-#endif
-#include <math.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-
-#include "DNA_ID.h"
#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
-#include "DNA_userdef_types.h"
#include "MEM_guardedalloc.h"
-#include "PIL_time.h"
-
#include "BLI_array.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_dynstr.h" /*for WM_operator_pystring */
-#include "BLI_utildefines.h"
-#include "BKE_blender.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
#include "BKE_tessmesh.h"
-#include "BKE_depsgraph.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h" /* for paint cursor */
-
-#include "IMB_imbuf_types.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@@ -78,8 +55,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "UI_interface.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -181,18 +156,17 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed,
static void edgering_sel(RingSelOpData *lcd, int previewlines, int select)
{
BMEditMesh *em = lcd->em;
- BMEdge *startedge = lcd->eed;
- BMEdge *eed, *lasteed;
- BMVert *v[2][2], *lastv1;
+ BMEdge *eed_start = lcd->eed;
+ BMEdge *eed, *eed_last;
+ BMVert *v[2][2], *v_last;
BMWalker walker;
float (*edges)[2][3] = NULL;
BLI_array_declare(edges);
- float co[2][3];
int i, tot = 0;
memset(v, 0, sizeof(v));
- if (!startedge)
+ if (!eed_start)
return;
if (lcd->edges) {
@@ -211,8 +185,7 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, int select)
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- eed = BMW_begin(&walker, startedge);
- for ( ; eed; eed = BMW_step(&walker)) {
+ for (eed = BMW_begin(&walker, eed_start); eed; eed = BMW_step(&walker)) {
BM_edge_select_set(em->bm, eed, TRUE);
}
BMW_end(&walker);
@@ -225,68 +198,57 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, int select)
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- eed = startedge = BMW_begin(&walker, startedge);
- lastv1 = NULL;
- for (lasteed = NULL; eed; eed = BMW_step(&walker)) {
- if (lasteed) {
- if (lastv1) {
+ v_last = NULL;
+ eed_last = NULL;
+
+ for (eed = eed_start = BMW_begin(&walker, eed_start); eed; eed = BMW_step(&walker)) {
+ if (eed_last) {
+ if (v_last) {
v[1][0] = v[0][0];
v[1][1] = v[0][1];
}
else {
- v[1][0] = lasteed->v1;
- v[1][1] = lasteed->v2;
- lastv1 = lasteed->v1;
+ v[1][0] = eed_last->v1;
+ v[1][1] = eed_last->v2;
+ v_last = eed_last->v1;
}
- edgering_find_order(lasteed, eed, lastv1, v);
- lastv1 = v[0][0];
+ edgering_find_order(eed_last, eed, v_last, v);
+ v_last = v[0][0];
BLI_array_grow_items(edges, previewlines);
for (i = 1; i <= previewlines; i++) {
- co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0]) * (i / ((float)previewlines + 1)) + v[0][0]->co[0];
- co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1]) * (i / ((float)previewlines + 1)) + v[0][0]->co[1];
- co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2]) * (i / ((float)previewlines + 1)) + v[0][0]->co[2];
-
- co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0]) * (i / ((float)previewlines + 1)) + v[1][0]->co[0];
- co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1]) * (i / ((float)previewlines + 1)) + v[1][0]->co[1];
- co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2]) * (i / ((float)previewlines + 1)) + v[1][0]->co[2];
-
- copy_v3_v3(edges[tot][0], co[0]);
- copy_v3_v3(edges[tot][1], co[1]);
+ const float fac = (i / ((float)previewlines + 1));
+ interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
+ interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
tot++;
}
}
- lasteed = eed;
+ eed_last = eed;
}
#ifdef BMW_EDGERING_NGON
if (lasteed != startedge && BM_edge_share_face_check(lasteed, startedge)) {
#else
- if (lasteed != startedge && BM_edge_share_quad_check(lasteed, startedge)) {
+ if (eed_last != eed_start && BM_edge_share_quad_check(eed_last, eed_start)) {
#endif
v[1][0] = v[0][0];
v[1][1] = v[0][1];
- edgering_find_order(lasteed, startedge, lastv1, v);
+ edgering_find_order(eed_last, eed_start, v_last, v);
BLI_array_grow_items(edges, previewlines);
for (i = 1; i <= previewlines; i++) {
- if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1])
+ const float fac = (i / ((float)previewlines + 1));
+
+ if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1]) {
continue;
-
- co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0]) * (i / ((float)previewlines + 1)) + v[0][0]->co[0];
- co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1]) * (i / ((float)previewlines + 1)) + v[0][0]->co[1];
- co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2]) * (i / ((float)previewlines + 1)) + v[0][0]->co[2];
+ }
- co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0]) * (i / ((float)previewlines + 1)) + v[1][0]->co[0];
- co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1]) * (i / ((float)previewlines + 1)) + v[1][0]->co[1];
- co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2]) * (i / ((float)previewlines + 1)) + v[1][0]->co[2];
-
- copy_v3_v3(edges[tot][0], co[0]);
- copy_v3_v3(edges[tot][1], co[1]);
+ interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
+ interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
tot++;
}
}
@@ -334,6 +296,9 @@ static void ringsel_finish(bContext *C, wmOperator *op)
SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE,
use_only_quads, 0);
+ /* tessface is already re-recalculated */
+ EDBM_update_generic(em, FALSE, TRUE);
+
/* force edge slide to edge select mode in in face select mode */
if (em->selectmode & SCE_SELECT_FACE) {
if (em->selectmode == SCE_SELECT_FACE)
@@ -345,11 +310,9 @@ static void ringsel_finish(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, CTX_data_scene(C));
}
- else
+ else {
EDBM_selectmode_flush(lcd->em);
-
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, lcd->ob->data);
- DAG_id_tag_update(lcd->ob->data, 0);
+ }
}
else {
/* XXX Is this piece of code ever used now? Simple loop select is now
@@ -450,10 +413,8 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
lcd->eed = edge;
ringsel_find_edge(lcd, 1);
}
- ED_area_headerprint(sa,
- "Select a ring to be cut, "
- "use mouse-wheel or page-up/down for number of cuts, "
- "Hold Alt for smooth");
+ ED_area_headerprint(sa, IFACE_("Select a ring to be cut, use mouse-wheel or page-up/down for number of cuts, "
+ "hold Alt for smooth"));
return OPERATOR_RUNNING_MODAL;
}
@@ -541,7 +502,8 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
ED_region_tag_redraw(lcd->ar);
break;
- case MOUSEMOVE: { /* mouse moved somewhere to select another loop */
+ case MOUSEMOVE: /* mouse moved somewhere to select another loop */
+ {
float dist = 75.0f;
BMEdge *edge;
@@ -581,7 +543,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
if (show_cuts) {
char buf[64];
- BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d, Smooth: %.2f (Alt)", cuts, smoothness);
+ BLI_snprintf(buf, sizeof(buf), IFACE_("Number of Cuts: %d, Smooth: %.2f (Alt)"), cuts, smoothness);
ED_area_headerprint(CTX_wm_area(C), buf);
}
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 2ecc20b2ddb..6cbf5e88cee 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -31,7 +31,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "RNA_define.h"
@@ -41,11 +40,9 @@
#include "BLI_array.h"
#include "BKE_context.h"
-#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
-#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
@@ -63,7 +60,7 @@
* point and would result in the same distance.
*/
#define INSET_DEFAULT 0.00001f
-static float edbm_rip_edgedist(ARegion *ar, float mat[][4],
+static float edbm_rip_edgedist(ARegion *ar, float mat[4][4],
const float co1[3], const float co2[3], const float mvalf[2],
const float inset)
{
@@ -83,7 +80,7 @@ static float edbm_rip_edgedist(ARegion *ar, float mat[][4],
}
#if 0
-static float edbm_rip_linedist(ARegion *ar, float mat[][4],
+static float edbm_rip_linedist(ARegion *ar, float mat[4][4],
const float co1[3], const float co2[3], const float mvalf[2])
{
float vec1[2], vec2[2];
@@ -1044,7 +1041,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 3335f03ac17..85aeb713f05 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -40,9 +40,9 @@
#include "BKE_context.h"
#include "BKE_displist.h"
-#include "BKE_depsgraph.h"
#include "BKE_report.h"
#include "BKE_paint.h"
+#include "BKE_mesh.h"
#include "BKE_tessmesh.h"
#include "IMB_imbuf_types.h"
@@ -56,9 +56,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "ED_util.h"
#include "ED_uvedit.h"
-#include "ED_object.h"
#include "ED_view3d.h"
#include "BIF_gl.h"
@@ -107,21 +105,23 @@ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, int extend)
void EDBM_automerge(Scene *scene, Object *obedit, int update)
{
- BMEditMesh *em;
if ((scene->toolsettings->automerge) &&
(obedit && obedit->type == OB_MESH))
{
- em = BMEdit_FromObject(obedit);
- if (!em)
+ int ok;
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+
+ if (!em) {
return;
+ }
+
+ ok = BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
+ "automerge verts=%hv dist=%f",
+ BM_ELEM_SELECT, scene->toolsettings->doublimit);
- BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
- "automerge verts=%hv dist=%f",
- BM_ELEM_SELECT, scene->toolsettings->doublimit);
- if (update) {
- DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
- BMEdit_RecalcTessellation(em);
+ if (LIKELY(ok) && update) {
+ EDBM_update_generic(em, TRUE, TRUE);
}
}
}
@@ -464,12 +464,12 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float
if (distance < data->dist) {
if (data->vc.rv3d->rflag & RV3D_CLIPPING) {
- float labda = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b);
+ float lambda = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b);
float vec[3];
- vec[0] = eed->v1->co[0] + labda * (eed->v2->co[0] - eed->v1->co[0]);
- vec[1] = eed->v1->co[1] + labda * (eed->v2->co[1] - eed->v1->co[1]);
- vec[2] = eed->v1->co[2] + labda * (eed->v2->co[2] - eed->v1->co[2]);
+ vec[0] = eed->v1->co[0] + lambda * (eed->v2->co[0] - eed->v1->co[0]);
+ vec[1] = eed->v1->co[1] + lambda * (eed->v2->co[1] - eed->v1->co[1]);
+ vec[2] = eed->v1->co[2] + lambda * (eed->v2->co[2] - eed->v1->co[2]);
if (ED_view3d_clipping_test(data->vc.rv3d, vec, TRUE) == 0) {
data->dist = distance;
@@ -573,7 +573,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
data.mval_fl[0] = vc->mval[0];
data.mval_fl[1] = vc->mval[1];
- data.dist = 0x7FFF; /* largest short */
+ data.dist = FLT_MAX;
data.toFace = efa;
mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -725,7 +725,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -767,7 +767,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -812,7 +812,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -985,8 +985,8 @@ static void walker_select(BMEditMesh *em, int walkercode, void *start, int selec
BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- ele = BMW_begin(&walker, start);
- for (; ele; ele = BMW_step(&walker)) {
+
+ for (ele = BMW_begin(&walker, start); ele; ele = BMW_step(&walker)) {
if (!select) {
BM_select_history_remove(bm, ele);
}
@@ -1136,11 +1136,11 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
/* We can't be sure this has already been set... */
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
- if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
length_1 = len_squared_v2v2(mvalf, v1_co);
}
- if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
length_2 = len_squared_v2v2(mvalf, v2_co);
}
#if 0
@@ -1167,7 +1167,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
float co[2], tdist;
BM_face_calc_center_mean(f, cent);
- if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
tdist = len_squared_v2v2(mvalf, co);
if (tdist < best_dist) {
/* printf("Best face: %p (%f)\n", f, tdist);*/
@@ -1352,6 +1352,17 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge
/* note, would pass BM_EDGE except we are looping over all edges anyway */
BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */);
+ switch (scene->toolsettings->edge_mode) {
+ case EDGE_MODE_TAG_CREASE:
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_CREASE);
+ break;
+ case EDGE_MODE_TAG_BEVEL:
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_BWEIGHT);
+ break;
+ default:
+ break;
+ }
+
BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) {
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == FALSE) {
BM_elem_flag_disable(e, BM_ELEM_TAG);
@@ -1431,7 +1442,7 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge
/* ******************* mesh shortest path select, uses prev-selected edge ****************** */
/* since you want to create paths with multiple selects, it doesn't have extend option */
-static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc)
+static int mouse_mesh_shortest_path_edge(ViewContext *vc)
{
BMEditMesh *em = vc->em;
BMEdge *e_dst;
@@ -1470,7 +1481,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc)
BM_select_history_store(em->bm, e_dst);
/* force drawmode for mesh */
- switch (CTX_data_tool_settings(C)->edge_mode) {
+ switch (vc->scene->toolsettings->edge_mode) {
case EDGE_MODE_TAG_SEAM:
me->drawflag |= ME_DRAWSEAMS;
@@ -1487,7 +1498,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc)
break;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return TRUE;
}
@@ -1644,7 +1655,7 @@ static int facetag_shortest_path(Scene *scene, BMesh *bm, BMFace *f_src, BMFace
return 1;
}
-static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc)
+static int mouse_mesh_shortest_path_face(ViewContext *vc)
{
BMEditMesh *em = vc->em;
BMFace *f_dst;
@@ -1678,7 +1689,7 @@ static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc)
BM_active_face_set(em->bm, f_dst);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return TRUE;
}
@@ -1703,7 +1714,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op),
em = vc.em;
if (em->selectmode & SCE_SELECT_EDGE) {
- if (mouse_mesh_shortest_path_edge(C, &vc)) {
+ if (mouse_mesh_shortest_path_edge(&vc)) {
return OPERATOR_FINISHED;
}
else {
@@ -1711,7 +1722,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op),
}
}
else if (em->selectmode & SCE_SELECT_FACE) {
- if (mouse_mesh_shortest_path_face(C, &vc)) {
+ if (mouse_mesh_shortest_path_face(&vc)) {
return OPERATOR_FINISHED;
}
else {
@@ -1747,7 +1758,7 @@ void MESH_OT_select_shortest_path(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/* ************************************************** */
@@ -2251,8 +2262,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- e = BMW_begin(&walker, efa);
- for (; efa; efa = BMW_step(&walker)) {
+ for (efa = BMW_begin(&walker, efa); efa; efa = BMW_step(&walker)) {
BM_face_select_set(bm, efa, sel);
}
BMW_end(&walker);
@@ -2273,8 +2283,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- e = BMW_begin(&walker, eed->v1);
- for (; e; e = BMW_step(&walker)) {
+ for (e = BMW_begin(&walker, eed->v1); e; e = BMW_step(&walker)) {
BM_edge_select_set(bm, e, sel);
}
BMW_end(&walker);
@@ -2345,8 +2354,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- e = BMW_begin(&walker, efa);
- for (; efa; efa = BMW_step(&walker)) {
+ for (efa = BMW_begin(&walker, efa); efa; efa = BMW_step(&walker)) {
BM_face_select_set(bm, efa, TRUE);
}
}
@@ -2374,16 +2382,15 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
- e = BMW_begin(&walker, v);
- for (; e; e = BMW_step(&walker)) {
- BM_vert_select_set(em->bm, e->v1, TRUE);
- BM_vert_select_set(em->bm, e->v2, TRUE);
+ for (e = BMW_begin(&walker, v); e; e = BMW_step(&walker)) {
+ BM_edge_select_set(em->bm, e, true);
}
}
}
BMW_end(&walker);
+
+ EDBM_selectmode_flush(em);
}
- EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
@@ -2628,14 +2635,15 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op)
int nth = RNA_int_get(op->ptr, "nth");
int offset = RNA_int_get(op->ptr, "offset");
- offset = MIN2(nth, offset);
+ /* so input of offset zero ends up being (nth - 1) */
+ offset = (offset + (nth - 1)) % nth;
if (edbm_deselect_nth(em, nth, offset) == 0) {
BKE_report(op->reports, RPT_ERROR, "Mesh has no active vert/edge/face");
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -2646,7 +2654,7 @@ void MESH_OT_select_nth(wmOperatorType *ot)
/* identifiers */
ot->name = "Checker Deselect";
ot->idname = "MESH_OT_select_nth";
- ot->description = "Deselect every Nth element starting from a selected vertex, edge or face";
+ ot->description = "Deselect every Nth element starting from the active vertex, edge or face";
/* api callbacks */
ot->exec = edbm_select_nth_exec;
@@ -2822,6 +2830,9 @@ static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
BMEdge *e;
BMIter iter;
+ if (!RNA_boolean_get(op->ptr, "extend"))
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
/* Selects isolated verts, and edges that do not have 2 neighboring
* faces
*/
@@ -2861,6 +2872,9 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend the selection");
}
static int edbm_select_random_exec(bContext *C, wmOperator *op)
@@ -2925,8 +2939,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
/* props */
RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f,
"Percent", "Percentage of elements to select randomly", 0.f, 100.0f);
- RNA_def_boolean(ot->srna, "extend", 0,
- "Extend Selection", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
static int edbm_select_next_loop_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c
deleted file mode 100644
index 4fbe9c2534f..00000000000
--- a/source/blender/editors/mesh/editmesh_slide.c
+++ /dev/null
@@ -1,793 +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.
- *
- * Contributor(s): Francisco De La Cruz
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/mesh/editmesh_slide.c
- * \ingroup edmesh
- */
-
-/* Takes heavily from editmesh_loopcut.c */
-
-#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_array.h"
-#include "BLI_math.h"
-
-#include "BLF_translation.h"
-
-#include "BKE_context.h"
-#include "BKE_report.h"
-#include "BKE_tessmesh.h"
-
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
-#include "ED_screen.h"
-#include "ED_view3d.h"
-#include "ED_mesh.h"
-#include "ED_space_api.h"
-
-#include "UI_resources.h"
-
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "mesh_intern.h"
-
-#define VTX_SLIDE_SNAP_THRSH 15
-
-/* Cusom VertexSlide Operator data */
-typedef struct VertexSlideOp {
- /* Starting Vertex */
- BMVert *start_vtx;
- BMEdge *sel_edge;
-
- ViewContext *view_context;
- ARegion *active_region;
-
- /* Draw callback handle */
- void *draw_handle;
-
- /* Active Object */
- Object *obj;
-
- /* Are we in slide mode */
- int slide_mode;
- int snap_n_merge;
- int snap_to_end_vtx;
- int snap_to_mid;
-
- /* Snap threshold */
- float snap_threshold;
-
- float distance;
- float interp[3];
-
- /* Edge Frame Count */
- int disk_edges;
-
- /* Edges */
- BMEdge **edge_frame;
-
- /* Slide Frame Endpoints */
- float (*vtx_frame)[3];
-
- /* Mouse Click 2d pos */
- int m_co[2];
-
-} VertexSlideOp;
-
-static void vtx_slide_draw(const bContext *C, ARegion *ar, void *arg);
-static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_update);
-static void vtx_slide_exit(const bContext *C, wmOperator *op);
-static int vtx_slide_set_frame(VertexSlideOp *vso);
-
-static int vtx_slide_init(bContext *C, wmOperator *op)
-{
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BMEdit_FromObject(obedit);
- BMEditSelection *ese;
-
- /* Custom data */
- VertexSlideOp *vso;
-
- const char *header_str = TIP_("Vertex Slide: Hover over an edge and left-click to select slide edge. "
- "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap & Merge");
-
- if (!obedit) {
- BKE_report(op->reports, RPT_ERROR, "Vertex slide error: no object in context");
- return FALSE;
- }
-
- EDBM_selectmode_flush(em);
- ese = em->bm->selected.last;
-
- /* Is there a starting vertex ? */
- if (ese == NULL || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) {
- BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex");
- return FALSE;
- }
-
- vso = MEM_callocN(sizeof(VertexSlideOp), "Vertex Slide Operator");
- vso->view_context = MEM_callocN(sizeof(ViewContext), "Vertex Slide View Context");
-
- op->customdata = vso;
-
- /* Set the start vertex */
- vso->start_vtx = (BMVert *)ese->ele;
-
- vso->sel_edge = NULL;
-
- /* Edges */
- vso->edge_frame = NULL;
-
- vso->vtx_frame = NULL;
-
- vso->disk_edges = 0;
-
- vso->slide_mode = FALSE;
-
- vso->snap_n_merge = FALSE;
-
- vso->snap_to_end_vtx = FALSE;
-
- vso->snap_to_mid = FALSE;
-
- vso->distance = 0.0f;
-
- vso->snap_threshold = 0.2f;
-
- /* Notify the viewport */
- view3d_operator_needs_opengl(C);
-
- /* Set the drawing region */
- vso->active_region = CTX_wm_region(C);
-
- /* Set the draw callback */
- vso->draw_handle = ED_region_draw_cb_activate(vso->active_region->type, vtx_slide_draw, vso, REGION_DRAW_POST_VIEW);
-
- ED_area_headerprint(CTX_wm_area(C), header_str);
-
- em_setup_viewcontext(C, vso->view_context);
-
- /* Set the object */
- vso->obj = obedit;
-
- /* Init frame */
- if (!vtx_slide_set_frame(vso)) {
- BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: cannot find starting vertex!");
- vtx_slide_exit(C, op);
- return FALSE;
- }
-
- /* Add handler for the vertex sliding */
- WM_event_add_modal_handler(C, op);
-
- /* Tag for redraw */
- ED_region_tag_redraw(vso->active_region);
-
- return TRUE;
-}
-
-static void vtx_slide_confirm(bContext *C, wmOperator *op)
-{
- VertexSlideOp *vso = op->customdata;
- BMEditMesh *em = BMEdit_FromObject(vso->obj);
- BMesh *bm = em->bm;
- BMVert *other = NULL;
-
- BMVert *mirr_vtx = NULL;
- BMVert *mirr_vtx_other = NULL;
-
- /* Select new edge */
- BM_edge_select_set(bm, vso->sel_edge, TRUE);
-
- if (vso->snap_n_merge) {
- other = BM_edge_other_vert(vso->sel_edge, vso->start_vtx);
- }
-
- if (((Mesh *)em->ob->data)->editflag & ME_EDIT_MIRROR_X) {
- EDBM_verts_mirror_cache_begin(em, TRUE);
-
- mirr_vtx = EDBM_verts_mirror_get(em, vso->start_vtx);
- if (vso->snap_n_merge) {
- mirr_vtx_other = EDBM_verts_mirror_get(em, other);
- }
- }
-
- /* Invoke operator - warning */
- edbm_vertex_slide_exec_ex(C, op, FALSE);
-
- if (mirr_vtx) {
- mirr_vtx->co[0] = -vso->start_vtx->co[0];
- mirr_vtx->co[1] = vso->start_vtx->co[1];
- mirr_vtx->co[2] = vso->start_vtx->co[2];
- }
-
- if (vso->snap_n_merge) {
- float other_d;
- other_d = len_v3v3(vso->interp, other->co);
-
- /* Only snap if within threshold */
- if (other_d < vso->snap_threshold) {
- BM_vert_select_set(bm, other, TRUE);
- BM_vert_select_set(bm, vso->start_vtx, TRUE);
- EDBM_op_callf(em, op, "pointmerge verts=%hv merge_co=%v", BM_ELEM_SELECT, other->co);
- EDBM_flag_disable_all(em, BM_ELEM_SELECT);
-
- if (mirr_vtx_other) {
- BM_vert_select_set(bm, mirr_vtx, TRUE);
- BM_vert_select_set(bm, mirr_vtx_other, TRUE);
- EDBM_op_callf(em, op, "pointmerge verts=%hv merge_co=%v", BM_ELEM_SELECT, mirr_vtx_other->co);
- EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- }
- }
- else {
- /* Store in historty if not merging */
- BM_select_history_store(em->bm, vso->start_vtx);
- }
- }
- else {
- /* Store edit selection of the active vertex, allows other
- * ops to run without reselecting */
- BM_select_history_store(em->bm, vso->start_vtx);
- }
-
- if (((Mesh *)em->ob->data)->editflag & ME_EDIT_MIRROR_X) {
- EDBM_verts_mirror_cache_end(em);
- }
-
- EDBM_selectmode_flush(em);
-
- /* NC_GEOM | ND_DATA & Retess */
- EDBM_update_generic(C, em, TRUE);
-
- ED_region_tag_redraw(vso->active_region);
-}
-
-static void vtx_slide_exit(const bContext *C, wmOperator *op)
-{
- /* Fetch custom data */
- VertexSlideOp *vso = op->customdata;
-
- /* Clean-up the custom data */
- ED_region_draw_cb_exit(vso->active_region->type, vso->draw_handle);
-
- /* Free Custom Data
- *
- */
- MEM_freeN(vso->view_context);
-
- vso->view_context = NULL;
-
- if (vso->edge_frame) {
- MEM_freeN(vso->edge_frame);
- }
-
- if (vso->vtx_frame) {
- MEM_freeN(vso->vtx_frame);
- }
-
- vso->edge_frame = NULL;
-
- vso->vtx_frame = NULL;
-
- vso->slide_mode = FALSE;
-
- MEM_freeN(vso);
- vso = NULL;
- op->customdata = NULL;
-
- /* Clear the header */
- ED_area_headerprint(CTX_wm_area(C), NULL);
-}
-
-static void vtx_slide_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
-{
- VertexSlideOp *vso = arg;
-
- /* Have an edge to draw */
- if (vso && vso->sel_edge) {
- /* Get 3d view */
- View3D *view3d = CTX_wm_view3d(C);
- const float outline_w = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.8f;
- const float pt_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
-
- int i = 0;
-
- if (view3d && view3d->zbuf)
- glDisable(GL_DEPTH_TEST);
-
- glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT | GL_POINT_BIT);
-
- glPushMatrix();
- glMultMatrixf(vso->obj->obmat);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-
- if (vso->slide_mode && vso->disk_edges > 0) {
- /* Draw intermediate edge frame */
- UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 50, -50);
-
- for (i = 0; i < vso->disk_edges; i++) {
- glBegin(GL_LINES);
- glVertex3fv(vso->vtx_frame[i]);
- glVertex3fv(vso->interp);
- glEnd();
- }
- }
-
- /* Draw selected edge
- * Add color offset and reduce alpha */
- UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 40, -50);
-
- glLineWidth(outline_w);
-
- glBegin(GL_LINES);
- bglVertex3fv(vso->sel_edge->v1->co);
- bglVertex3fv(vso->sel_edge->v2->co);
- glEnd();
-
- if (vso->slide_mode) {
- /* Draw interpolated vertex */
-
- UI_ThemeColorShadeAlpha(TH_FACE_DOT, -80, -50);
-
- glPointSize(pt_size);
-
- bglBegin(GL_POINTS);
- bglVertex3fv(vso->interp);
- bglEnd();
- }
-
- glDisable(GL_BLEND);
- glPopMatrix();
- glPopAttrib();
-
- if (view3d && view3d->zbuf)
- glEnable(GL_DEPTH_TEST);
- }
-}
-
-static BMEdge *vtx_slide_nrst_in_frame(VertexSlideOp *vso, const float mval[2])
-{
- BMEdge *cl_edge = NULL;
- if (vso->disk_edges > 0) {
- int i = 0;
- BMEdge *edge = NULL;
-
- float v1_proj[3], v2_proj[3];
- float min_dist = FLT_MAX;
-
- for (i = 0; i < vso->disk_edges; i++) {
- edge = vso->edge_frame[i];
-
- mul_v3_m4v3(v1_proj, vso->obj->obmat, edge->v1->co);
- mul_v3_m4v3(v2_proj, vso->obj->obmat, edge->v2->co);
-
- /* we could use ED_view3d_project_float_object here, but for now dont since we dont have the context */
- if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
- (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
- {
- const float dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj);
- if (dist < min_dist) {
- min_dist = dist;
- cl_edge = edge;
- }
- }
- }
- }
- return cl_edge;
-}
-
-static void vtx_slide_find_edge(VertexSlideOp *vso, wmEvent *event)
-{
- /* Nearest edge */
- BMEdge *nst_edge = NULL;
-
- const float mval_float[2] = {(float)event->mval[0],
- (float)event->mval[1]};
-
- /* Set mouse coords */
- copy_v2_v2_int(vso->view_context->mval, event->mval);
-
- /* Find nearest edge */
- nst_edge = vtx_slide_nrst_in_frame(vso, mval_float);
-
- if (nst_edge) {
- /* Find a connected edge */
- if (BM_vert_in_edge(nst_edge, vso->start_vtx)) {
-
- /* Save mouse coords */
- copy_v2_v2_int(vso->m_co, event->mval);
-
- /* Set edge */
- vso->sel_edge = nst_edge;
- }
- }
-}
-
-/* Updates the status of the operator - Invoked on mouse movement */
-static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event)
-{
- BMEdge *edge;
-
- /* Find nearest edge */
- edge = vso->sel_edge;
-
- if (edge) {
- float edge_other_proj[3];
- float start_vtx_proj[3];
- float edge_len;
- BMVert *other;
-
- float interp[3];
-
- /* Calculate interpolation value for preview */
- float t_val;
-
- float mval_float[2] = { (float)event->mval[0], (float)event->mval[1]};
- float closest_2d[2];
-
- other = BM_edge_other_vert(edge, vso->start_vtx);
-
- /* Project points onto screen and do interpolation in 2D */
- mul_v3_m4v3(start_vtx_proj, vso->obj->obmat, vso->start_vtx->co);
- mul_v3_m4v3(edge_other_proj, vso->obj->obmat, other->co);
-
- if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) ||
- (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK))
- {
- /* not much we can do here */
- return;
- }
-
- closest_to_line_v2(closest_2d, mval_float, start_vtx_proj, edge_other_proj);
-
- t_val = line_point_factor_v2(closest_2d, start_vtx_proj, edge_other_proj);
-
- /* Set snap threshold to be proportional to edge length */
- edge_len = len_v3v3(start_vtx_proj, edge_other_proj);
-
- if (edge_len <= 0.0f)
- edge_len = VTX_SLIDE_SNAP_THRSH;
-
- edge_len = (BM_edge_calc_length(edge) * VTX_SLIDE_SNAP_THRSH) / edge_len;
-
- vso->snap_threshold = edge_len;
-
- /* Snap to mid */
- if (vso->snap_to_mid) {
- t_val = 0.5f;
- }
-
- /* Interpolate preview vertex 3D */
- interp_v3_v3v3(interp, vso->start_vtx->co, other->co, t_val);
- copy_v3_v3(vso->interp, interp);
-
- vso->distance = t_val;
-
- /* If snapping */
- if (vso->snap_to_end_vtx) {
- int start_at_v1 = edge->v1 == vso->start_vtx;
- float v1_d = len_v3v3(vso->interp, edge->v1->co);
- float v2_d = len_v3v3(vso->interp, edge->v2->co);
-
- if (v1_d > v2_d && v2_d < vso->snap_threshold) {
- copy_v3_v3(vso->interp, edge->v2->co);
-
- if (start_at_v1)
- vso->distance = 1.0f;
- else
- vso->distance = 0.0f;
- }
- if (v2_d > v1_d && v1_d < vso->snap_threshold) {
- copy_v3_v3(vso->interp, edge->v1->co);
- if (start_at_v1)
- vso->distance = 0.0f;
- else
- vso->distance = 1.0f;
- }
- }
- }
-}
-
-/* Sets the outline frame */
-static int vtx_slide_set_frame(VertexSlideOp *vso)
-{
- BMEdge *edge;
- float (*vtx_frame)[3] = NULL;
- BMEdge **edge_frame = NULL;
- BMVert *curr_vert = NULL;
- BLI_array_declare(vtx_frame);
- BLI_array_declare(edge_frame);
- BMIter iter;
- BMVert *sel_vtx = vso->start_vtx;
- int idx = 0;
-
- vso->disk_edges = 0;
-
- if (vso->edge_frame) {
- MEM_freeN(vso->edge_frame);
- vso->edge_frame = NULL;
- }
-
- if (vso->vtx_frame) {
- MEM_freeN(vso->vtx_frame);
- vso->vtx_frame = NULL;
- }
-
- /* Iterate over edges of vertex and copy them */
- BM_ITER_ELEM_INDEX (edge, &iter, sel_vtx, BM_EDGES_OF_VERT, idx) {
- curr_vert = BM_edge_other_vert(edge, sel_vtx);
- if (curr_vert) {
- BLI_array_grow_one(vtx_frame);
-
- copy_v3_v3(vtx_frame[idx], curr_vert->co);
-
- BLI_array_append(edge_frame, edge);
- vso->disk_edges++;
- }
- }
-
- vso->edge_frame = edge_frame;
- vso->vtx_frame = vtx_frame;
-
- /* Set the interp at starting vtx */
- copy_v3_v3(vso->interp, sel_vtx->co);
-
- return vso->disk_edges > 0;
-}
-
-static int edbm_vertex_slide_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- VertexSlideOp *vso = op->customdata;
- char buff[128];
-
- if (!vso)
- return OPERATOR_CANCELLED;
-
- /* Notify the viewport */
- view3d_operator_needs_opengl(C);
-
- switch (event->type) {
- case LEFTSHIFTKEY:
- {
- switch (event->val) {
- case KM_PRESS:
- vso->snap_to_mid = TRUE;
- break;
- case KM_RELEASE:
- vso->snap_to_mid = FALSE;
- break;
- }
-
- break;
- }
- case LEFTCTRLKEY:
- {
- switch (event->val) {
- case KM_PRESS:
- vso->snap_n_merge = TRUE;
- vso->snap_to_end_vtx = TRUE;
- break;
- case KM_RELEASE:
- vso->snap_n_merge = FALSE;
- vso->snap_to_end_vtx = FALSE;
- break;
- }
-
- break;
- }
- case LEFTALTKEY:
- {
- switch (event->val) {
- case KM_PRESS:
- vso->snap_to_end_vtx = TRUE;
- break;
- case KM_RELEASE:
- vso->snap_to_end_vtx = FALSE;
- break;
- }
-
- break;
- }
- case RIGHTMOUSE:
- case ESCKEY:
- {
- /* Enforce redraw */
- ED_region_tag_redraw(vso->active_region);
-
- /* Clean-up */
- vtx_slide_exit(C, op);
-
- return OPERATOR_CANCELLED;
- }
- case LEFTMOUSE:
- {
- if (event->val == KM_PRESS) {
- /* Update mouse coords */
- copy_v2_v2_int(vso->m_co, event->mval);
-
- if (vso->slide_mode) {
- vtx_slide_confirm(C, op);
- /* Clean-up */
- vtx_slide_exit(C, op);
- return OPERATOR_FINISHED;
- }
- else if (vso->sel_edge) {
- vso->slide_mode = TRUE;
- }
- }
-
- ED_region_tag_redraw(vso->active_region);
- break;
-
- }
- case MOUSEMOVE:
- {
- sprintf(buff, "Vertex Slide: %f", vso->distance);
- if (!vso->slide_mode) {
- vtx_slide_find_edge(vso, event);
- }
- else {
- vtx_slide_update(vso, event);
- }
- ED_area_headerprint(CTX_wm_area(C), buff);
- ED_region_tag_redraw(vso->active_region);
- break;
- }
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int edbm_vertex_slide_cancel(bContext *C, wmOperator *op)
-{
- /* Exit the modal */
- vtx_slide_exit(C, op);
-
- return OPERATOR_CANCELLED;
-}
-
-static int edbm_vertex_slide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
-{
- /* Initialize the operator */
- if (vtx_slide_init(C, op))
- return OPERATOR_RUNNING_MODAL;
- else
- return OPERATOR_CANCELLED;
-}
-
-/* Vertex Slide */
-static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_update)
-{
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BMEdit_FromObject(obedit);
- BMesh *bm = em->bm;
- BMVert *start_vert;
- BMOperator bmop;
- BMEditSelection *ese = (BMEditSelection *)em->bm->selected.last;
-
- float factor = 0.0f;
-
- /* Invoked modally? */
- if (op->type->modal == edbm_vertex_slide_modal && op->customdata) {
- VertexSlideOp *vso = (VertexSlideOp *)op->customdata;
-
- if (bm->totedgesel > 1) {
- /* Reset selections */
- EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BM_edge_select_set(bm, vso->sel_edge, TRUE);
- BM_vert_select_set(bm, vso->start_vtx, TRUE);
-
- BM_select_history_store(em->bm, vso->sel_edge);
- BM_select_history_store(em->bm, vso->start_vtx);
- ese = (BMEditSelection *)em->bm->selected.last;
- }
- factor = vso->distance;
- RNA_float_set(op->ptr, "factor", factor);
- }
- else {
- /* Get Properties */
- factor = RNA_float_get(op->ptr, "factor");
- }
-
- /* Is there a starting vertex ? */
- if ((ese == NULL) || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) {
- BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex");
- return OPERATOR_CANCELLED;
- }
-
- start_vert = (BMVert *)ese->ele;
-
- /* Prepare operator */
- if (!EDBM_op_init(em, &bmop, op,
- "slide_vert vert=%e edges=%he factor=%f",
- start_vert, BM_ELEM_SELECT, factor))
- {
- return OPERATOR_CANCELLED;
- }
- /* Execute operator */
- BMO_op_exec(bm, &bmop);
-
- /* Deselect the input edges */
- BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edges", BM_EDGE, BM_ELEM_SELECT, TRUE);
-
- /* Select the output vert */
- BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE);
-
- /* Flush the select buffers */
- EDBM_selectmode_flush(em);
-
- if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
- return OPERATOR_CANCELLED;
- }
-
- if (do_update) {
- /* Update Geometry */
- EDBM_update_generic(C, em, TRUE);
- }
-
- return OPERATOR_FINISHED;
-}
-
-#if 0
-static int edbm_vertex_slide_exec(bContext *C, wmOperator *op)
-{
- return edbm_vertex_slide_exec_ex(C, op, TRUE);
-}
-#endif
-
-void MESH_OT_vert_slide(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Vertex Slide";
- ot->idname = "MESH_OT_vert_slide";
- ot->description = "Vertex slide";
-
- /* api callback */
- ot->invoke = edbm_vertex_slide_invoke;
- ot->modal = edbm_vertex_slide_modal;
- ot->cancel = edbm_vertex_slide_cancel;
- ot->poll = ED_operator_editmesh_region_view3d;
-
- /* ot->exec = edbm_vertex_slide_exec;
- * ot->poll = ED_operator_editmesh; */
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* Properties for vertex slide */
- prop = RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "Distance", -5.0f, 5.0f);
- RNA_def_property_ui_range(prop, -5.0f, 5.0f, 0.1, 4);
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index ad1077156ba..1448b53d997 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -40,18 +40,18 @@
#include "RNA_define.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
-#include "BLI_array.h"
#include "BLI_blenlib.h"
#include "BLI_noise.h"
#include "BLI_math.h"
#include "BLI_rand.h"
+#include "BLF_translation.h"
+
#include "BKE_material.h"
#include "BKE_context.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
-#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_texture.h"
@@ -112,7 +112,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE,
RNA_int_get(op->ptr, "seed"));
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -181,7 +181,7 @@ static int edbm_unsubdivide_exec(bContext *C, wmOperator *op)
}
EDBM_selectmode_flush(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -389,7 +389,7 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
if (ele->head.htype == BM_FACE) {
f = (BMFace *)ele;
add_normal_aligned(nor, f->no);
- };
+ }
}
normalize_v3(nor);
@@ -463,7 +463,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -585,7 +585,7 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
* done.*/
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -616,7 +616,7 @@ static int edbm_extrude_verts_exec(bContext *C, wmOperator *op)
edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -647,7 +647,7 @@ static int edbm_extrude_edges_exec(bContext *C, wmOperator *op)
edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -678,7 +678,7 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op)
edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -906,12 +906,12 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
BM_ELEM_SELECT, min);
}
else {
- float *curs = give_cursor(vc.scene, vc.v3d);
+ const float *curs = give_cursor(vc.scene, vc.v3d);
BMOperator bmop;
BMOIter oiter;
copy_v3_v3(min, curs);
- view3d_get_view_aligned_coordinate(&vc, min, event->mval, 0);
+ view3d_get_view_aligned_coordinate(&vc, min, event->mval, FALSE);
invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
mul_m4_v3(vc.obedit->imat, min); // back in object space
@@ -936,7 +936,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
* done. */
EDBM_mesh_normals_update(vc.em);
- EDBM_update_generic(C, vc.em, TRUE);
+ EDBM_update_generic(vc.em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1001,7 +1001,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1034,7 +1034,7 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "collapse edges=%he", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1062,7 +1062,7 @@ static int edbm_collapse_edge_loop_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "dissolve_edge_loop edges=%he", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1121,7 +1121,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1176,7 +1176,7 @@ static int edbm_mark_seam(bContext *C, wmOperator *op)
}
ED_uvedit_live_unwrap(scene, obedit);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1230,7 +1230,7 @@ static int edbm_mark_sharp(bContext *C, wmOperator *op)
}
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1272,7 +1272,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op)
else {
EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1310,7 +1310,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1349,7 +1349,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1388,7 +1388,7 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1469,7 +1469,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1500,7 +1500,7 @@ static int edbm_hide_exec(bContext *C, wmOperator *op)
EDBM_mesh_hide(em, RNA_boolean_get(op->ptr, "unselected"));
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1530,7 +1530,7 @@ static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op))
EDBM_mesh_reveal(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1563,7 +1563,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "inside"))
EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1645,7 +1645,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
EDBM_verts_mirror_cache_end(em);
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1676,7 +1676,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BMEdit_FromObject(obedit);
int usex = TRUE, usey = TRUE, usez = TRUE, preserve_volume = TRUE;
int i, repeat;
- float lambda;
+ float lambda_factor;
float lambda_border;
BMIter fiter;
BMFace *f;
@@ -1697,7 +1697,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
}
repeat = RNA_int_get(op->ptr, "repeat");
- lambda = RNA_float_get(op->ptr, "lambda");
+ lambda_factor = RNA_float_get(op->ptr, "lambda_factor");
lambda_border = RNA_float_get(op->ptr, "lambda_border");
usex = RNA_boolean_get(op->ptr, "use_x");
usey = RNA_boolean_get(op->ptr, "use_y");
@@ -1708,8 +1708,8 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
for (i = 0; i < repeat; i++) {
if (!EDBM_op_callf(em, op,
- "smooth_laplacian_vert verts=%hv lambda=%f lambda_border=%f use_x=%b use_y=%b use_z=%b preserve_volume=%b",
- BM_ELEM_SELECT, lambda, lambda_border, usex, usey, usez, preserve_volume))
+ "smooth_laplacian_vert verts=%hv lambda_factor=%f lambda_border=%f use_x=%b use_y=%b use_z=%b preserve_volume=%b",
+ BM_ELEM_SELECT, lambda_factor, lambda_border, usex, usey, usez, preserve_volume))
{
return OPERATOR_CANCELLED;
}
@@ -1721,7 +1721,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
EDBM_verts_mirror_cache_end(em);
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1742,13 +1742,13 @@ void MESH_OT_vertices_smooth_laplacian(wmOperatorType *ot)
RNA_def_int(ot->srna, "repeat", 1, 1, 200,
"Number of iterations to smooth the mesh", "", 1, 200);
- RNA_def_float(ot->srna, "lambda", 0.00005f, 0.0000001f, 1000.0f,
+ RNA_def_float(ot->srna, "lambda_factor", 0.00005f, 0.0000001f, 1000.0f,
"Lambda factor", "", 0.0000001f, 1000.0f);
RNA_def_float(ot->srna, "lambda_border", 0.00005f, 0.0000001f, 1000.0f,
"Lambda factor in border", "", 0.0000001f, 1000.0f);
- RNA_def_boolean(ot->srna, "use_x", 1, "Smooth X Axis", "Smooth object along X axis");
- RNA_def_boolean(ot->srna, "use_y", 1, "Smooth Y Axis", "Smooth object along Y axis");
- RNA_def_boolean(ot->srna, "use_z", 1, "Smooth Z Axis", "Smooth object along Z axis");
+ RNA_def_boolean(ot->srna, "use_x", 1, "Smooth X Axis", "Smooth object along X axis");
+ RNA_def_boolean(ot->srna, "use_y", 1, "Smooth Y Axis", "Smooth object along Y axis");
+ RNA_def_boolean(ot->srna, "use_z", 1, "Smooth Z Axis", "Smooth object along Z axis");
RNA_def_boolean(ot->srna, "preserve_volume", 1, "Preserve Volume", "Apply volume preservation after smooth");
}
@@ -1775,7 +1775,7 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op))
mesh_set_smooth_faces(em, 1);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1802,7 +1802,7 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op))
mesh_set_smooth_faces(em, 0);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1845,7 +1845,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1868,7 +1868,7 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1895,7 +1895,7 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
}
/* dependencies graph and notification stuff */
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1919,7 +1919,7 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -2033,7 +2033,8 @@ static int merge_target(BMEditMesh *em, Scene *scene, View3D *v3d, Object *ob,
{
BMIter iter;
BMVert *v;
- float *vco = NULL, co[3], cent[3] = {0.0f, 0.0f, 0.0f};
+ float co[3], cent[3] = {0.0f, 0.0f, 0.0f};
+ const float *vco = NULL;
if (target) {
vco = give_cursor(scene, v3d);
@@ -2104,7 +2105,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op)
if (!status)
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -2221,7 +2222,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
count = totvert_orig - em->bm->totvert;
BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -2328,7 +2329,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -2388,7 +2389,7 @@ static void shape_propagate(BMEditMesh *em, wmOperator *op)
//TAG Mesh Objects that share this data
for (base = scene->base.first; base; base = base->next) {
if (base->object && base->object->data == me) {
- base->object->recalc = OB_RECALC_DATA;
+ DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
#endif
@@ -2403,7 +2404,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op)
shape_propagate(em, op);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -2474,7 +2475,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
}
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -2530,7 +2531,6 @@ static void edbm_blend_from_shape_ui(bContext *C, wmOperator *op)
void MESH_OT_blend_from_shape(wmOperatorType *ot)
{
PropertyRNA *prop;
- static EnumPropertyItem shape_items[] = {{0, NULL, 0, NULL, NULL}};
/* identifiers */
ot->name = "Blend From Shape";
@@ -2547,7 +2547,7 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_enum(ot->srna, "shape", shape_items, 0, "Shape", "Shape key to use for blending");
+ prop = RNA_def_enum(ot->srna, "shape", DummyRNA_NULL_items, 0, "Shape", "Shape key to use for blending");
RNA_def_enum_funcs(prop, shape_itemf);
RNA_def_float(ot->srna, "blend", 1.0f, -FLT_MAX, FLT_MAX, "Blend", "Blending factor", -2.0f, 2.0f);
RNA_def_boolean(ot->srna, "add", 1, "Add", "Add rather than blend between shapes");
@@ -2665,7 +2665,7 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -2930,7 +2930,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
screen_vert_coords = sco = MEM_mallocN(bm->totvert * sizeof(float) * 2, __func__);
BM_ITER_MESH_INDEX (bv, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK) {
copy_v2_fl(*sco, FLT_MAX); /* set error value */
}
BM_elem_index_set(bv, i); /* set_ok */
@@ -2990,7 +2990,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3042,7 +3042,7 @@ static int mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh
CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
- /* DAG_scene_sort(bmain, scene); */ /* normally would call directly after but in this case delay recalc */
+ /* DAG_relations_tag_update(bmain); */ /* normally would call directly after but in this case delay recalc */
assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
ED_base_object_select(base_new, BA_SELECT);
@@ -3192,8 +3192,7 @@ static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh
BMW_FLAG_NOP,
BMW_NIL_LAY);
- e = BMW_begin(&walker, v_seed);
- for (; e; e = BMW_step(&walker)) {
+ for (e = BMW_begin(&walker, v_seed); e; e = BMW_step(&walker)) {
if (!BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { BM_elem_flag_enable(e->v1, BM_ELEM_TAG); tot++; }
if (!BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { BM_elem_flag_enable(e->v2, BM_ELEM_TAG); tot++; }
}
@@ -3232,7 +3231,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
else BLI_assert(0);
if (retval) {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
}
}
else {
@@ -3277,7 +3276,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
if (retval) {
/* delay depsgraph recalc until all objects are duplicated */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
}
@@ -3317,9 +3316,12 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
+ int use_beauty = RNA_boolean_get(op->ptr, "use_beauty");
BMOperator bmop;
- if (!EDBM_op_init(em, &bmop, op, "triangle_fill edges=%he", BM_ELEM_SELECT)) {
+ if (!EDBM_op_init(em, &bmop, op,
+ "triangle_fill edges=%he use_beauty=%b",
+ BM_ELEM_SELECT, use_beauty)) {
return OPERATOR_CANCELLED;
}
@@ -3332,7 +3334,7 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
@@ -3351,6 +3353,8 @@ void MESH_OT_fill(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "use_beauty", true, "Beauty", "Use best triangulation division");
}
static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
@@ -3358,10 +3362,10 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
- if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf", BM_ELEM_SELECT))
+ if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf edges=ae", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3387,12 +3391,24 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
+ BMOperator bmop;
int use_beauty = RNA_boolean_get(op->ptr, "use_beauty");
- if (!EDBM_op_callf(em, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty))
+ EDBM_op_init(em, &bmop, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty);
+ BMO_op_exec(em->bm, &bmop);
+
+ /* now call beauty fill */
+ if (use_beauty) {
+ EDBM_op_callf(em, op,
+ "beautify_fill faces=%S edges=%S",
+ &bmop, "faces.out", &bmop, "edges.out");
+ }
+
+ if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
+ }
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3411,7 +3427,7 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "use_beauty", 1, "Beauty", "Use best triangulation division (currently quads only)");
+ RNA_def_boolean(ot->srna, "use_beauty", 1, "Beauty", "Use best triangulation division");
}
static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
@@ -3433,7 +3449,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3489,7 +3505,7 @@ static int edbm_dissolve_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3561,7 +3577,7 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3584,7 +3600,7 @@ void MESH_OT_dissolve_limited(wmOperatorType *ot)
prop = RNA_def_float_rotation(ot->srna, "angle_limit", 0, NULL, 0.0f, DEG2RADF(180.0f),
"Max Angle", "Angle limit", 0.0f, DEG2RADF(180.0f));
- RNA_def_property_float_default(prop, DEG2RADF(15.0f));
+ RNA_def_property_float_default(prop, DEG2RADF(5.0f));
RNA_def_boolean(ot->srna, "use_dissolve_boundaries", 0, "All Boundaries",
"Dissolve all vertices inbetween face boundaries");
}
@@ -3606,7 +3622,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op)
/* Geometry has changed, need to recalc normals and looptris */
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3665,7 +3681,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3777,7 +3793,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
if (!EDBM_op_init(em, &spinop, op,
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b",
- BM_ELEM_SELECT, cent, axis, dvec, turns * steps, 360.0f * turns, FALSE))
+ BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), FALSE))
{
return OPERATOR_CANCELLED;
}
@@ -3788,7 +3804,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3822,8 +3838,8 @@ void MESH_OT_screw(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 256);
- RNA_def_int(ot->srna, "turns", 1, 0, INT_MAX, "Turns", "Turns", 0, 256);
+ RNA_def_int(ot->srna, "steps", 9, 1, INT_MAX, "Steps", "Steps", 3, 256);
+ RNA_def_int(ot->srna, "turns", 1, 1, INT_MAX, "Turns", "Turns", 1, 256);
RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX,
"Center", "Center in global view space", -FLT_MAX, FLT_MAX);
@@ -3840,6 +3856,9 @@ static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
const int numverts = RNA_int_get(op->ptr, "number");
const int type = RNA_enum_get(op->ptr, "type");
+ if (!RNA_boolean_get(op->ptr, "extend"))
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int select;
@@ -3899,9 +3918,10 @@ void MESH_OT_select_face_by_sides(wmOperatorType *ot)
/* properties */
RNA_def_int(ot->srna, "number", 4, 3, INT_MAX, "Number of Vertices", "", 3, INT_MAX);
RNA_def_enum(ot->srna, "type", type_items, 1, "Type", "Type of comparison to make");
+ RNA_def_boolean(ot->srna, "extend", TRUE, "Extend", "Extend the selection");
}
-static int edbm_select_loose_verts_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_select_loose_verts_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
@@ -3909,6 +3929,9 @@ static int edbm_select_loose_verts_exec(bContext *C, wmOperator *UNUSED(op))
BMEdge *eed;
BMIter iter;
+ if (!RNA_boolean_get(op->ptr, "extend"))
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!eve->e) {
BM_vert_select_set(em->bm, eve, TRUE);
@@ -3940,6 +3963,9 @@ void MESH_OT_select_loose_verts(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
@@ -3948,9 +3974,11 @@ static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BMEdit_FromObject(obedit);
int extend = RNA_boolean_get(op->ptr, "extend");
- EDBM_select_mirrored(obedit, em, extend);
- EDBM_selectmode_flush(em);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ if (em->bm->totvert && em->bm->totvertsel) {
+ EDBM_select_mirrored(obedit, em, extend);
+ EDBM_selectmode_flush(em);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ }
return OPERATOR_FINISHED;
}
@@ -4595,7 +4623,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);
+ externtex(ma->mtex[0], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL);
eve->co[2] += fac * tin;
}
}
@@ -4603,7 +4631,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op)
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -4625,15 +4653,9 @@ void MESH_OT_noise(wmOperatorType *ot)
RNA_def_float(ot->srna, "factor", 0.1f, -FLT_MAX, FLT_MAX, "Factor", "", 0.0f, 1.0f);
}
-#define NEW_BEVEL 1
-
typedef struct {
BMEditMesh *em;
BMBackup mesh_backup;
-#ifndef NEW_BEVEL
- float *weights;
- int li;
-#endif
int mcenter[2];
float initial_length;
float pixel_size; /* use when mouse input is interpreted as spatial distance */
@@ -4646,104 +4668,34 @@ typedef struct {
static void edbm_bevel_update_header(wmOperator *op, bContext *C)
{
-#ifdef NEW_BEVEL
- static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RMB), offset: %s, segments: %d";
-#else
- static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RMB), factor: %s, Use Dist (D): %s: Use Even (E): %s";
- BevelData *opdata = op->customdata;
-#endif
+ const char *str = IFACE_("Confirm: Enter/LClick, Cancel: (Esc/RMB), Offset: %s, Segments: %d");
char msg[HEADER_LENGTH];
ScrArea *sa = CTX_wm_area(C);
if (sa) {
-#ifdef NEW_BEVEL
char offset_str[NUM_STR_REP_LEN];
BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
BLI_snprintf(msg, HEADER_LENGTH, str,
offset_str,
RNA_int_get(op->ptr, "segments")
);
-#else
- char factor_str[NUM_STR_REP_LEN];
- if (hasNumInput(&opdata->num_input))
- outputNumInput(&opdata->num_input, factor_str);
- else
- BLI_snprintf(factor_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "percent"));
- BLI_snprintf(msg, HEADER_LENGTH, str,
- factor_str,
- RNA_boolean_get(op->ptr, "use_dist") ? "On" : "Off",
- RNA_boolean_get(op->ptr, "use_even") ? "On" : "Off"
- );
-#endif
ED_area_headerprint(sa, msg);
}
}
-#ifndef NEW_BEVEL
-static void edbm_bevel_recalc_weights(wmOperator *op)
-{
- float df, s, ftot;
- int i;
- int recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */
- BevelData *opdata = op->customdata;
-
- if (opdata->weights) {
- /* TODO should change to free only when new recursion is greater than old */
- MEM_freeN(opdata->weights);
- }
- opdata->weights = MEM_mallocN(sizeof(float) * recursion, "bevel weights");
-
- /* ugh, stupid math depends somewhat on angles!*/
- /* dfac = 1.0/(float)(recursion + 1); */ /* UNUSED */
- df = 1.0;
- for (i = 0, ftot = 0.0f; i < recursion; i++) {
- s = powf(df, 1.25f);
-
- opdata->weights[i] = s;
- ftot += s;
-
- df *= 2.0f;
- }
-
- mul_vn_fl(opdata->weights, recursion, 1.0f / (float)ftot);
-}
-#endif
-
static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
-#ifdef NEW_BEVEL
BevelData *opdata;
-#else
- BMIter iter;
- BMEdge *eed;
- BevelData *opdata;
- int li;
-#endif
if (em == NULL) {
return 0;
}
op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator");
-
-#ifndef NEW_BEVEL
- BM_data_layer_add(em->bm, &em->bm->edata, CD_PROP_FLT);
- li = CustomData_number_of_layers(&em->bm->edata, CD_PROP_FLT) - 1;
-
- BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
- float d = len_v3v3(eed->v1->co, eed->v2->co);
- float *dv = CustomData_bmesh_get_n(&em->bm->edata, eed->head.data, CD_PROP_FLT, li);
-
- *dv = d;
- }
-
- opdata->li = li;
- opdata->weights = NULL;
-#endif
opdata->em = em;
opdata->is_modal = is_modal;
@@ -4755,21 +4707,18 @@ static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal)
/* avoid the cost of allocating a bm copy */
if (is_modal)
opdata->mesh_backup = EDBM_redo_state_store(em);
-#ifndef NEW_BEVEL
- edbm_bevel_recalc_weights(op);
-#endif
return 1;
}
-static int edbm_bevel_calc(bContext *C, wmOperator *op)
+static int edbm_bevel_calc(wmOperator *op)
{
BevelData *opdata = op->customdata;
BMEditMesh *em = opdata->em;
BMOperator bmop;
-#ifdef NEW_BEVEL
float offset = RNA_float_get(op->ptr, "offset");
int segments = RNA_int_get(op->ptr, "segments");
+ int vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
/* revert to original mesh */
if (opdata->is_modal) {
@@ -4777,8 +4726,8 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op)
}
if (!EDBM_op_init(em, &bmop, op,
- "bevel geom=%hev offset=%f segments=%i",
- BM_ELEM_SELECT, offset, segments))
+ "bevel geom=%hev offset=%f segments=%i vertex_only=%b",
+ BM_ELEM_SELECT, offset, segments, vertex_only))
{
return 0;
}
@@ -4795,39 +4744,10 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op)
/* no need to de-select existing geometry */
if (!EDBM_op_finish(em, &bmop, op, TRUE))
return 0;
-#else
- int i;
-
- float factor = RNA_float_get(op->ptr, "percent") /*, dfac */ /* UNUSED */;
- int recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */
- const int use_even = RNA_boolean_get(op->ptr, "use_even");
- const int use_dist = RNA_boolean_get(op->ptr, "use_dist");
-
- /* revert to original mesh */
- if (opdata->is_modal) {
- EDBM_redo_state_restore(opdata->mesh_backup, em, FALSE);
- }
-
- for (i = 0; i < recursion; i++) {
- float fac = opdata->weights[recursion - i - 1] * factor;
-
-
- if (!EDBM_op_init(em, &bmop, op,
- "bevel geom=%hev percent=%f lengthlayer=%i use_lengths=%b use_even=%b use_dist=%b",
- BM_ELEM_SELECT, fac, opdata->li, TRUE, use_even, use_dist))
- {
- return 0;
- }
-
- BMO_op_exec(em->bm, &bmop);
- if (!EDBM_op_finish(em, &bmop, op, TRUE))
- return 0;
- }
-#endif
EDBM_mesh_normals_update(opdata->em);
- EDBM_update_generic(C, opdata->em, TRUE);
+ EDBM_update_generic(opdata->em, TRUE, TRUE);
return 1;
}
@@ -4841,12 +4761,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op)
if (sa) {
ED_area_headerprint(sa, NULL);
}
-#ifndef NEW_BEVEL
- BM_data_layer_free_n(opdata->em->bm, &opdata->em->bm->edata, CD_PROP_FLT, opdata->li);
- if (opdata->weights)
- MEM_freeN(opdata->weights);
-#endif
if (opdata->is_modal) {
EDBM_redo_state_free(&opdata->mesh_backup, NULL, FALSE);
}
@@ -4859,7 +4774,7 @@ static int edbm_bevel_cancel(bContext *C, wmOperator *op)
BevelData *opdata = op->customdata;
if (opdata->is_modal) {
EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE);
- EDBM_update_generic(C, opdata->em, FALSE);
+ EDBM_update_generic(opdata->em, FALSE, TRUE);
}
edbm_bevel_exit(C, op);
@@ -4877,7 +4792,7 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (!edbm_bevel_calc(C, op)) {
+ if (!edbm_bevel_calc(op)) {
edbm_bevel_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -4914,7 +4829,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
edbm_bevel_update_header(op, C);
- if (!edbm_bevel_calc(C, op)) {
+ if (!edbm_bevel_calc(op)) {
edbm_bevel_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -4927,11 +4842,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
{
BevelData *opdata = op->customdata;
-#ifdef NEW_BEVEL
int use_dist = TRUE;
-#else
- int use_dist = RNA_boolean_get(op->ptr, "use_dist");
-#endif
float mdiff[2];
float factor;
@@ -4949,11 +4860,7 @@ static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
/* Fake shift-transform... */
if (event->shift) {
if (opdata->shift_factor < 0.0f) {
-#ifdef NEW_BEVEL
- opdata->shift_factor = RNA_float_get(op->ptr, "factor");
-#else
- opdata->shift_factor = RNA_float_get(op->ptr, "percent");
-#endif
+ opdata->shift_factor = RNA_float_get(op->ptr, "offset");
}
factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor;
}
@@ -4978,28 +4885,15 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_PRESS) {
/* Try to handle numeric inputs... */
-#ifdef NEW_BEVEL
if (handleNumInput(&opdata->num_input, event)) {
float value = RNA_float_get(op->ptr, "offset");
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
-#else
- if (handleNumInput(&opdata->num_input, event)) {
- float factor = RNA_float_get(op->ptr, "percent");
- applyNumInput(&opdata->num_input, &factor);
- CLAMP(factor, 0.0f, 1.0f);
- RNA_float_set(op->ptr, "percent", factor);
-
- edbm_bevel_calc(C, op);
- edbm_bevel_update_header(op, C);
- return OPERATOR_RUNNING_MODAL;
- }
-#endif
}
switch (event->type) {
@@ -5011,13 +4905,9 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
case MOUSEMOVE:
if (!hasNumInput(&opdata->num_input)) {
const float factor = edbm_bevel_mval_factor(op, event);
-#ifdef NEW_BEVEL
RNA_float_set(op->ptr, "offset", factor);
-#else
- RNA_float_set(op->ptr, "percent", factor);
-#endif
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
}
break;
@@ -5025,11 +4915,10 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case PADENTER:
case RETKEY:
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_exit(C, op);
return OPERATOR_FINISHED;
-#ifdef NEW_BEVEL
case WHEELUPMOUSE: /* change number of segments */
case PAGEUPKEY:
if (event->val == KM_RELEASE)
@@ -5037,7 +4926,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
segments++;
RNA_int_set(op->ptr, "segments", segments);
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
break;
@@ -5048,36 +4937,9 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
segments = max_ii(segments - 1, 1);
RNA_int_set(op->ptr, "segments", segments);
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
break;
-
-#else
- case EKEY:
- if (event->val == KM_PRESS) {
- int use_even = RNA_boolean_get(op->ptr, "use_even");
- RNA_boolean_set(op->ptr, "use_even", !use_even);
-
- edbm_bevel_calc(C, op);
- edbm_bevel_update_header(op, C);
- }
- break;
-
- case DKEY:
- if (event->val == KM_PRESS) {
- int use_dist = RNA_boolean_get(op->ptr, "use_dist");
- RNA_boolean_set(op->ptr, "use_dist", !use_dist);
-
- {
- const float factor = edbm_bevel_mval_factor(op, event);
- RNA_float_set(op->ptr, "percent", factor);
- }
-
- edbm_bevel_calc(C, op);
- edbm_bevel_update_header(op, C);
- }
- break;
-#endif
}
return OPERATOR_RUNNING_MODAL;
@@ -5100,19 +4962,9 @@ void MESH_OT_bevel(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING;
-#ifdef NEW_BEVEL
RNA_def_float(ot->srna, "offset", 0.0f, -FLT_MAX, FLT_MAX, "Offset", "", 0.0f, 1.0f);
RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8);
-#else
- /* take note, used as a factor _and_ a distance depending on 'use_dist' */
- RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f);
- /* XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. */
-/* RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); */
-
- RNA_def_boolean(ot->srna, "use_even", FALSE, "Even", "Calculate evenly spaced bevel");
- RNA_def_boolean(ot->srna, "use_dist", FALSE, "Distance", "Interpret the percent in blender units");
-#endif
-
+ RNA_def_boolean(ot->srna, "vertex_only", FALSE, "Vertex only", "Bevel only vertices");
}
static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
@@ -5140,7 +4992,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
}
@@ -5184,12 +5036,8 @@ static void edbm_inset_update_header(wmOperator *op, bContext *C)
{
InsetData *opdata = op->customdata;
- static const char str[] = "Confirm: Enter/LClick, "
- "Cancel: (Esc/RClick), "
- "thickness: %s, "
- "depth (Ctrl to tweak): %s (%s), "
- "Outset (O): (%s), "
- "Boundary (B): (%s)";
+ const char *str = IFACE_("Confirm: Enter/LClick, Cancel: (Esc/RClick), Thickness: %s, "
+ "Depth (Ctrl to tweak): %s (%s), Outset (O): (%s), Boundary (B): (%s)");
char msg[HEADER_LENGTH];
ScrArea *sa = CTX_wm_area(C);
@@ -5205,9 +5053,9 @@ static void edbm_inset_update_header(wmOperator *op, bContext *C)
BLI_snprintf(msg, HEADER_LENGTH, str,
flts_str,
flts_str + NUM_STR_REP_LEN,
- opdata->modify_depth ? "On" : "Off",
- RNA_boolean_get(op->ptr, "use_outset") ? "On" : "Off",
- RNA_boolean_get(op->ptr, "use_boundary") ? "On" : "Off"
+ opdata->modify_depth ? IFACE_("On") : IFACE_("Off"),
+ RNA_boolean_get(op->ptr, "use_outset") ? IFACE_("On") : IFACE_("Off"),
+ RNA_boolean_get(op->ptr, "use_boundary") ? IFACE_("On") : IFACE_("Off")
);
ED_area_headerprint(sa, msg);
@@ -5263,7 +5111,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op)
opdata = op->customdata;
if (opdata->is_modal) {
EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE);
- EDBM_update_generic(C, opdata->em, FALSE);
+ EDBM_update_generic(opdata->em, FALSE, TRUE);
}
edbm_inset_exit(C, op);
@@ -5273,7 +5121,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int edbm_inset_calc(bContext *C, wmOperator *op)
+static int edbm_inset_calc(wmOperator *op)
{
InsetData *opdata;
BMEditMesh *em;
@@ -5318,7 +5166,7 @@ static int edbm_inset_calc(bContext *C, wmOperator *op)
return 0;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return 1;
}
}
@@ -5327,7 +5175,7 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
{
edbm_inset_init(C, op, FALSE);
- if (!edbm_inset_calc(C, op)) {
+ if (!edbm_inset_calc(op)) {
edbm_inset_exit(C, op);
return OPERATOR_CANCELLED;
}
@@ -5358,7 +5206,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
opdata->initial_length = len_v2(mlen);
opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
- edbm_inset_calc(C, op);
+ edbm_inset_calc(op);
edbm_inset_update_header(op, C);
@@ -5381,7 +5229,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
RNA_float_set(op->ptr, "thickness", amounts[0]);
RNA_float_set(op->ptr, "depth", amounts[1]);
- if (edbm_inset_calc(C, op)) {
+ if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
@@ -5422,7 +5270,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
RNA_float_set(op->ptr, "thickness", amount);
}
- if (edbm_inset_calc(C, op))
+ if (edbm_inset_calc(op))
edbm_inset_update_header(op, C);
else {
edbm_inset_cancel(C, op);
@@ -5434,7 +5282,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case PADENTER:
case RETKEY:
- edbm_inset_calc(C, op);
+ edbm_inset_calc(op);
edbm_inset_exit(C, op);
return OPERATOR_FINISHED;
@@ -5483,7 +5331,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_PRESS) {
int use_outset = RNA_boolean_get(op->ptr, "use_outset");
RNA_boolean_set(op->ptr, "use_outset", !use_outset);
- if (edbm_inset_calc(C, op)) {
+ if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
}
else {
@@ -5496,7 +5344,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_PRESS) {
int use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
RNA_boolean_set(op->ptr, "use_boundary", !use_boundary);
- if (edbm_inset_calc(C, op)) {
+ if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
}
else {
@@ -5581,7 +5429,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
}
@@ -5671,7 +5519,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
EDBM_selectmode_flush(em);
return OPERATOR_FINISHED;
}
@@ -5726,7 +5574,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
EDBM_selectmode_flush(em);
return OPERATOR_FINISHED;
}
@@ -5734,18 +5582,6 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
void MESH_OT_symmetrize(struct wmOperatorType *ot)
{
- static EnumPropertyItem axis_direction_items[] = {
- {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""},
- {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""},
-
- {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""},
- {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""},
-
- {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""},
- {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
/* identifiers */
ot->name = "Symmetrize";
ot->description = "Enforce symmetry (both form and topological) across an axis";
@@ -5758,7 +5594,7 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ot->prop = RNA_def_enum(ot->srna, "direction", axis_direction_items,
+ ot->prop = RNA_def_enum(ot->srna, "direction", symmetrize_direction_items,
BMO_SYMMETRIZE_NEGATIVE_X,
"Direction", "Which sides to copy from and to");
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 2cf63586142..fd90246f791 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -35,15 +35,12 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_bmesh.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_key.h"
-#include "BKE_library.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
@@ -56,7 +53,6 @@
#include "ED_mesh.h"
#include "ED_util.h"
-#include "bmesh.h"
#include "mesh_intern.h"
@@ -140,8 +136,10 @@ void EDBM_mesh_clear(BMEditMesh *em)
/* free tessellation data */
em->tottri = 0;
- if (em->looptris)
+ if (em->looptris) {
MEM_freeN(em->looptris);
+ em->looptris = NULL;
+ }
}
void EDBM_stats_update(BMEditMesh *em)
@@ -391,81 +389,129 @@ void EDBM_mesh_free(BMEditMesh *em)
BMEdit_Free(em);
}
-void EDBM_index_arrays_init(BMEditMesh *tm, int forvert, int foredge, int forface)
+
+void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype)
{
- EDBM_index_arrays_free(tm);
+ /* assume if the array is non-null then its valid and no need to recalc */
+ const char htype_needed = ((em->vert_index ? 0 : BM_VERT) |
+ (em->edge_index ? 0 : BM_EDGE) |
+ (em->face_index ? 0 : BM_FACE)) & htype;
- if (forvert) {
- BMIter iter;
- BMVert *ele;
- int i = 0;
-
- tm->vert_index = MEM_mallocN(sizeof(void **) * tm->bm->totvert, "tm->vert_index");
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
- ele = BM_iter_new(&iter, tm->bm, BM_VERTS_OF_MESH, NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- tm->vert_index[i++] = ele;
+ /* in debug mode double check we didn't need to recalculate */
+ BLI_assert(EDBM_index_arrays_check(em) == TRUE);
+
+ if (htype_needed & BM_VERT) {
+ em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index");
+ }
+ if (htype_needed & BM_EDGE) {
+ em->edge_index = MEM_mallocN(sizeof(void **) * em->bm->totedge, "em->edge_index");
+ }
+ if (htype_needed & BM_FACE) {
+ em->face_index = MEM_mallocN(sizeof(void **) * em->bm->totface, "em->face_index");
+ }
+
+#pragma omp parallel sections if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ if (htype_needed & BM_VERT) {
+ BM_iter_as_array(em->bm, BM_VERTS_OF_MESH, NULL, (void **)em->vert_index, em->bm->totvert);
+ }
+ }
+#pragma omp section
+ {
+ if (htype_needed & BM_EDGE) {
+ BM_iter_as_array(em->bm, BM_EDGES_OF_MESH, NULL, (void **)em->edge_index, em->bm->totedge);
+ }
+ }
+#pragma omp section
+ {
+ if (htype_needed & BM_FACE) {
+ BM_iter_as_array(em->bm, BM_FACES_OF_MESH, NULL, (void **)em->face_index, em->bm->totface);
+ }
}
}
+}
- if (foredge) {
- BMIter iter;
- BMEdge *ele;
- int i = 0;
-
- tm->edge_index = MEM_mallocN(sizeof(void **) * tm->bm->totedge, "tm->edge_index");
+/* use EDBM_index_arrays_ensure where possible to avoid full rebuild */
+void EDBM_index_arrays_init(BMEditMesh *em, const char htype)
+{
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
- ele = BM_iter_new(&iter, tm->bm, BM_EDGES_OF_MESH, NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- tm->edge_index[i++] = ele;
- }
+ /* force recalc */
+ EDBM_index_arrays_free(em);
+ EDBM_index_arrays_ensure(em, htype);
+}
+
+void EDBM_index_arrays_free(BMEditMesh *em)
+{
+ if (em->vert_index) {
+ MEM_freeN(em->vert_index);
+ em->vert_index = NULL;
}
- if (forface) {
- BMIter iter;
- BMFace *ele;
- int i = 0;
-
- tm->face_index = MEM_mallocN(sizeof(void **) * tm->bm->totface, "tm->face_index");
+ if (em->edge_index) {
+ MEM_freeN(em->edge_index);
+ em->edge_index = NULL;
+ }
- ele = BM_iter_new(&iter, tm->bm, BM_FACES_OF_MESH, NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- tm->face_index[i++] = ele;
- }
+ if (em->face_index) {
+ MEM_freeN(em->face_index);
+ em->face_index = NULL;
}
}
-void EDBM_index_arrays_free(BMEditMesh *tm)
+/* debug check only - no need to optimize */
+#ifndef NDEBUG
+int EDBM_index_arrays_check(BMEditMesh *em)
{
- if (tm->vert_index) {
- MEM_freeN(tm->vert_index);
- tm->vert_index = NULL;
+ BMIter iter;
+ BMElem *ele;
+ int i;
+
+ if (em->vert_index) {
+ BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ if (ele != (BMElem *)em->vert_index[i]) {
+ return FALSE;
+ }
+ }
}
- if (tm->edge_index) {
- MEM_freeN(tm->edge_index);
- tm->edge_index = NULL;
+ if (em->edge_index) {
+ BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_EDGES_OF_MESH, i) {
+ if (ele != (BMElem *)em->edge_index[i]) {
+ return FALSE;
+ }
+ }
}
- if (tm->face_index) {
- MEM_freeN(tm->face_index);
- tm->face_index = NULL;
+ if (em->face_index) {
+ BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_FACES_OF_MESH, i) {
+ if (ele != (BMElem *)em->face_index[i]) {
+ return FALSE;
+ }
+ }
}
+
+ return TRUE;
}
+#endif
-BMVert *EDBM_vert_at_index(BMEditMesh *tm, int index)
+BMVert *EDBM_vert_at_index(BMEditMesh *em, int index)
{
- return tm->vert_index && index < tm->bm->totvert ? tm->vert_index[index] : NULL;
+ return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL;
}
-BMEdge *EDBM_edge_at_index(BMEditMesh *tm, int index)
+BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index)
{
- return tm->edge_index && index < tm->bm->totedge ? tm->edge_index[index] : NULL;
+ return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL;
}
-BMFace *EDBM_face_at_index(BMEditMesh *tm, int index)
+BMFace *EDBM_face_at_index(BMEditMesh *em, int index)
{
- return (tm->face_index && index < tm->bm->totface && index >= 0) ? tm->face_index[index] : NULL;
+ return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL;
}
void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode)
@@ -506,7 +552,7 @@ void EDBM_select_more(BMEditMesh *em)
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
BMO_op_finish(em->bm, &bmop);
- EDBM_select_flush(em);
+ EDBM_selectmode_flush(em);
}
void EDBM_select_less(BMEditMesh *em)
@@ -638,8 +684,10 @@ void undo_push_mesh(bContext *C, const char *name)
undo_editmode_push(C, name, getEditMesh, free_undo, undoMesh_to_editbtMesh, editbtMesh_to_undoMesh, NULL);
}
-/* write comment here */
-UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2])
+/**
+ * Return a new UVVertMap from the editmesh
+ */
+UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, bool use_select, const float limit[2])
{
BMVert *ev;
BMFace *efa;
@@ -652,30 +700,25 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
MLoopUV *luv;
unsigned int a;
int totverts, i, totuv;
-
- if (do_face_idx_array)
- EDBM_index_arrays_init(em, 0, 0, 1);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+ BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
totverts = em->bm->totvert;
totuv = 0;
/* generate UvMapVert array */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT)))
+ if ((use_select == false) || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
totuv += efa->len;
+ }
}
if (totuv == 0) {
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
return NULL;
}
vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap");
if (!vmap) {
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
return NULL;
}
@@ -684,14 +727,12 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
if (!vmap->vert || !vmap->buf) {
BKE_mesh_uv_vert_map_free(vmap);
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
return NULL;
}
a = 0;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
+ if ((use_select == false) || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
i = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
buf->tfindex = i;
@@ -726,7 +767,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
/* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa, v->tfindex);
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv = luv->uv;
lastv = NULL;
@@ -738,7 +779,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
/* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
l = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex);
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv2 = luv->uv;
sub_v2_v2v2(uvdiff, uv2, uv);
@@ -762,10 +803,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
vmap->vert[a] = newvlist;
a++;
}
-
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
-
+
return vmap;
}
@@ -799,6 +837,8 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
BMFace **stack;
int stacksize = 0;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
totverts = em->bm->totvert;
@@ -811,8 +851,9 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
/* generate UvElement array */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT)))
+ if (!selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
totuv += efa->len;
+ }
}
if (totuv == 0) {
@@ -837,10 +878,9 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
j = 0;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
island_number[j++] = INVALID_ISLAND;
- if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
+ if (!selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
buf->l = l;
- buf->face = efa;
buf->separate = 0;
buf->island = INVALID_ISLAND;
buf->tfindex = i;
@@ -867,7 +907,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
newvlist = v;
l = v->l;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv = luv->uv;
lastv = NULL;
@@ -877,7 +917,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
next = iterv->next;
l = iterv->l;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv2 = luv->uv;
sub_v2_v2v2(uvdiff, uv2, uv);
@@ -912,7 +952,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
for (i = 0; i < totuv; i++) {
if (element_map->buf[i].island == INVALID_ISLAND) {
element_map->buf[i].island = nislands;
- stack[0] = element_map->buf[i].face;
+ stack[0] = element_map->buf[i].l->f;
island_number[BM_elem_index_get(stack[0])] = nislands;
stacksize = 1;
@@ -926,12 +966,11 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
if (element->separate)
initelement = element;
- if (element->face == efa) {
+ if (element->l->f == efa) {
/* found the uv corresponding to our face and vertex. Now fill it to the buffer */
element->island = nislands;
map[element - element_map->buf] = islandbufsize;
islandbuf[islandbufsize].l = element->l;
- islandbuf[islandbufsize].face = element->face;
islandbuf[islandbufsize].separate = element->separate;
islandbuf[islandbufsize].tfindex = element->tfindex;
islandbuf[islandbufsize].island = nislands;
@@ -941,9 +980,9 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
if (element->separate && element != initelement)
break;
- if (island_number[BM_elem_index_get(element->face)] == INVALID_ISLAND) {
- stack[stacksize++] = element->face;
- island_number[BM_elem_index_get(element->face)] = nislands;
+ if (island_number[BM_elem_index_get(element->l->f)] == INVALID_ISLAND) {
+ stack[stacksize++] = element->l->f;
+ island_number[BM_elem_index_get(element->l->f)] = nislands;
}
}
break;
@@ -1024,7 +1063,7 @@ UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l)
element = map->vert[BM_elem_index_get(l->v)];
for (; element; element = element->next)
- if (element->face == efa)
+ if (element->l->f == efa)
return element;
return NULL;
@@ -1110,10 +1149,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const short use_select)
topo = 1;
}
- if (!em->vert_index) {
- EDBM_index_arrays_init(em, 1, 0, 0);
- em->mirr_free_arrays = 1;
- }
+ EDBM_index_arrays_ensure(em, BM_VERT);
if (!CustomData_get_layer_named(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID)) {
BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
@@ -1205,11 +1241,6 @@ void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v)
void EDBM_verts_mirror_cache_end(BMEditMesh *em)
{
- if (em->mirr_free_arrays) {
- MEM_freeN(em->vert_index);
- em->vert_index = NULL;
- }
-
em->mirror_cdlayer = -1;
}
@@ -1276,14 +1307,15 @@ void EDBM_mesh_reveal(BMEditMesh *em)
int sels[3] = {(em->selectmode & SCE_SELECT_VERTEX),
(em->selectmode & SCE_SELECT_EDGE),
(em->selectmode & SCE_SELECT_FACE), };
-
- BMIter iter;
- BMElem *ele;
int i;
/* Use tag flag to remember what was hidden before all is revealed.
* BM_ELEM_HIDDEN --> BM_ELEM_TAG */
+#pragma omp parallel for schedule(dynamic) if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT)
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
BM_ITER_MESH (ele, &iter, em->bm, iter_types[i]) {
BM_elem_flag_set(ele, BM_ELEM_TAG, BM_elem_flag_test(ele, BM_ELEM_HIDDEN));
}
@@ -1294,6 +1326,9 @@ void EDBM_mesh_reveal(BMEditMesh *em)
/* Select relevant just-revealed elements */
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
if (!sels[i]) {
continue;
}
@@ -1313,14 +1348,22 @@ void EDBM_mesh_reveal(BMEditMesh *em)
/* so many tools call these that we better make it a generic function.
*/
-void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface)
+void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_destructive)
{
Object *ob = em->ob;
/* order of calling isn't important */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, ob->data);
if (do_tessface) {
BMEdit_RecalcTessellation(em);
}
+
+ if (is_destructive) {
+ EDBM_index_arrays_free(em);
+ }
+ else {
+ /* in debug mode double check we didn't need to recalculate */
+ BLI_assert(EDBM_index_arrays_check(em) == TRUE);
+ }
}
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index e9906f852de..0c9a5aab537 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -28,35 +28,23 @@
* \ingroup edmesh
*/
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
#include "MEM_guardedalloc.h"
-#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
-#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_array.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
-#include "BLI_linklist.h"
-#include "BLI_listbase.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
@@ -72,10 +60,9 @@
#include "ED_uvedit.h"
#include "ED_view3d.h"
-#include "RE_render_ext.h"
-
#include "mesh_intern.h"
+
static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot)
{
CustomData *data;
@@ -475,7 +462,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
/* copy data from active vertex color layer */
if (layernum) {
const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL);
- BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
+ BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPCOL, layernum, layernum_dst);
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
@@ -588,13 +575,19 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
- Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
+ Base *base;
Image *ima = NULL;
Mesh *me;
Object *obedit;
int exitmode = 0;
- char name[MAX_ID_NAME - 2];
+ if (v3d == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No 3D View Available");
+ return OPERATOR_CANCELLED;
+ }
+
+ base = ED_view3d_give_base_under_cursor(C, event->mval);
+
/* Check context */
if (base == NULL || base->object->type != OB_MESH) {
BKE_report(op->reports, RPT_ERROR, "Not an object or mesh");
@@ -609,6 +602,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
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);
}
@@ -654,7 +648,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
void MESH_OT_drop_named_image(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Assign Image to UV Map";
+ ot->name = "Drop Image to Mesh UV Map";
ot->description = "Assign Image to active UV Map, or create an UV Map";
ot->idname = "MESH_OT_drop_named_image";
@@ -663,7 +657,7 @@ void MESH_OT_drop_named_image(wmOperatorType *ot)
ot->invoke = drop_named_image_invoke;
/* flags */
- ot->flag = OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign");
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index e335c909e8e..9ea15f93250 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -210,7 +210,6 @@ void MESH_OT_bevel(struct wmOperatorType *ot);
void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
void MESH_OT_inset(struct wmOperatorType *ot);
void MESH_OT_wireframe(struct wmOperatorType *ot);
-void MESH_OT_vert_slide(struct wmOperatorType *ot);
void MESH_OT_convex_hull(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index 83a1261e981..8d5bfe624fd 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -26,31 +26,22 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <math.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_ID.h"
#include "BLI_listbase.h"
-#include "BLI_utildefines.h"
#include "BLI_math_vector.h"
#include "BLI_linklist.h"
#include "BKE_library.h"
#include "BKE_depsgraph.h"
#include "BKE_context.h"
-#include "BKE_main.h"
#include "BKE_mesh.h"
-#include "BKE_modifier.h"
#include "BKE_scene.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
@@ -58,15 +49,15 @@
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "RNA_access.h"
-
#include "WM_api.h"
#include "WM_types.h"
#include "mesh_intern.h"
#include "recast-capi.h"
-static void createVertsTrisData(bContext *C, LinkNode *obs, int *nverts_r, float **verts_r, int *ntris_r, int **tris_r)
+
+static void createVertsTrisData(bContext *C, LinkNode *obs,
+ int *nverts_r, float **verts_r, int *ntris_r, int **tris_r, unsigned int *r_lay)
{
MVert *mvert;
int nfaces = 0, *tri, i, curnverts, basenverts, curnfaces;
@@ -101,6 +92,8 @@ static void createVertsTrisData(bContext *C, LinkNode *obs, int *nverts_r, float
if (mf->v4)
ntris += 1;
}
+
+ *r_lay |= ob->lay;
}
/* create data */
@@ -167,8 +160,9 @@ static void createVertsTrisData(bContext *C, LinkNode *obs, int *nverts_r, float
*tris_r = tris;
}
-static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts, int ntris, int *tris,
- struct recast_polyMesh **pmesh, struct recast_polyMeshDetail **dmesh)
+static bool buildNavMesh(const RecastData *recastParams, int nverts, float *verts, int ntris, int *tris,
+ struct recast_polyMesh **pmesh, struct recast_polyMeshDetail **dmesh,
+ ReportList *reports)
{
float bmin[3], bmax[3];
struct recast_heightfield *solid;
@@ -195,14 +189,20 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
/* Set the area where the navigation will be build. */
recast_calcGridSize(bmin, bmax, recastParams->cellsize, &width, &height);
+ /* zero dimensions cause zero alloc later on [#33758] */
+ if (width <= 0 || height <= 0) {
+ BKE_report(reports, RPT_ERROR, "Object has a width or height of zero");
+ return false;
+ }
+
/* ** Step 2: Rasterize input polygon soup ** */
/* Allocate voxel heightfield where we rasterize our input data to */
solid = recast_newHeightfield();
if (!recast_createHeightfield(solid, width, height, bmin, bmax, recastParams->cellsize, recastParams->cellheight)) {
recast_destroyHeightfield(solid);
-
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to create height field");
+ return false;
}
/* Allocate array that can hold triangle flags */
@@ -225,7 +225,8 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyHeightfield(solid);
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to create compact height field");
+ return false;
}
recast_destroyHeightfield(solid);
@@ -234,21 +235,24 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
if (!recast_erodeWalkableArea(walkableRadius, chf)) {
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to erode walkable area");
+ return false;
}
/* Prepare for region partitioning, by calculating distance field along the walkable surface */
if (!recast_buildDistanceField(chf)) {
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build distance field");
+ return false;
}
/* Partition the walkable surface into simple regions without holes */
if (!recast_buildRegions(chf, 0, minRegionArea, mergeRegionArea)) {
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build regions");
+ return false;
}
/* ** Step 5: Trace and simplify region contours ** */
@@ -259,7 +263,8 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyCompactHeightfield(chf);
recast_destroyContourSet(cset);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build contours");
+ return false;
}
/* ** Step 6: Build polygons mesh from contours ** */
@@ -269,7 +274,8 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyContourSet(cset);
recast_destroyPolyMesh(*pmesh);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build poly mesh");
+ return false;
}
@@ -282,16 +288,18 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyPolyMesh(*pmesh);
recast_destroyPolyMeshDetail(*dmesh);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build poly mesh detail");
+ return false;
}
recast_destroyCompactHeightfield(chf);
recast_destroyContourSet(cset);
- return 1;
+ return true;
}
-static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh, Base *base)
+static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh,
+ Base *base, unsigned int lay)
{
float co[3], rot[3];
BMEditMesh *em;
@@ -312,7 +320,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
if (createob) {
/* create new object */
- obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1);
+ obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, lay);
}
else {
obedit = base->object;
@@ -375,7 +383,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
BM_vert_create(em->bm, co, NULL, 0);
}
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
/* create faces */
for (j = 0; j < trinum; j++) {
@@ -399,8 +407,6 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
polygonIdx = (int *)CustomData_bmesh_get(&em->bm->pdata, newFace->head.data, CD_RECAST);
*polygonIdx = i + 1; /* add 1 to avoid zero idx */
}
-
- EDBM_index_arrays_free(em);
}
recast_destroyPolyMesh(pmesh);
@@ -449,20 +455,23 @@ static int navmesh_create_exec(bContext *C, wmOperator *op)
if (obs) {
struct recast_polyMesh *pmesh = NULL;
struct recast_polyMeshDetail *dmesh = NULL;
+ bool ok;
+ unsigned int lay = 0;
int nverts = 0, ntris = 0;
int *tris = 0;
float *verts = NULL;
- createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris);
+ createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris, &lay);
BLI_linklist_free(obs, NULL);
- buildNavMesh(&scene->gm.recastData, nverts, verts, ntris, tris, &pmesh, &dmesh);
- createRepresentation(C, pmesh, dmesh, navmeshBase);
+ if ((ok = buildNavMesh(&scene->gm.recastData, nverts, verts, ntris, tris, &pmesh, &dmesh, op->reports))) {
+ createRepresentation(C, pmesh, dmesh, navmeshBase, lay);
+ }
MEM_freeN(verts);
MEM_freeN(tris);
- return OPERATOR_FINISHED;
+ return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
else {
BKE_report(op->reports, RPT_ERROR, "No mesh objects found");
@@ -474,7 +483,7 @@ static int navmesh_create_exec(bContext *C, wmOperator *op)
void MESH_OT_navmesh_make(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Create navigation mesh";
+ ot->name = "Create Navigation Mesh";
ot->description = "Create navigation mesh for selected objects";
ot->idname = "MESH_OT_navmesh_make";
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index a413a60412c..884c4a3bee1 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -29,17 +29,11 @@
*/
-#include <stdlib.h>
-#include <math.h>
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BKE_context.h"
#include "RNA_access.h"
@@ -49,7 +43,6 @@
#include "ED_object.h"
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "ED_view3d.h"
#include "mesh_intern.h"
@@ -155,7 +148,6 @@ 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_slide);
WM_operatortype_append(MESH_OT_knife_tool);
WM_operatortype_append(MESH_OT_bevel);
@@ -205,7 +197,7 @@ void ED_operatormacros_mesh(void)
OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MESH_OT_loopcut");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_edge_slide");
- RNA_struct_idprops_unset(otmacro->ptr, "release_confirm");
+ RNA_boolean_set(otmacro->ptr, "release_confirm", false);
ot = WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", "Duplicate mesh and move",
OPTYPE_UNDO | OPTYPE_REGISTER);
@@ -270,10 +262,14 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Mesh", 0, 0);
keymap->poll = ED_operator_editmesh;
- WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_inset", IKEY, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "vertex_only", FALSE);
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "vertex_only", TRUE);
+
/* selecting */
/* standard mouse selection goes via space_view3d */
kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
@@ -367,7 +363,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_vert_connect", JKEY, KM_PRESS, 0, 0);
/* Vertex Slide */
- WM_keymap_add_item(keymap, "MESH_OT_vert_slide", VKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "TRANSFORM_OT_vert_slide", VKEY, KM_PRESS, KM_SHIFT, 0);
/* use KM_CLICK because same key is used for tweaks */
kmi = WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "rotate_source", TRUE);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index c0b6327d740..f983a43f573 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -27,35 +27,24 @@
/** \file blender/editors/mesh/meshtools.c
* \ingroup edmesh
+ *
+ * meshtools.c: no editmode (violated already :), mirror & join),
+ * tools operating on meshes
*/
-
-/*
- * meshtools.c: no editmode (violated already :), tools operating on meshes
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <math.h>
-#include <float.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BLI_rand.h" /* for randome face sorting */
-#include "BLI_threads.h"
#include "BKE_context.h"
@@ -71,7 +60,6 @@
#include "BKE_tessmesh.h"
#include "BKE_multires.h"
-#include "BLO_sys_types.h" // for intptr_t support
#include "ED_mesh.h"
#include "ED_object.h"
@@ -80,10 +68,6 @@
#include "WM_api.h"
#include "WM_types.h"
-/* own include */
-#include "mesh_intern.h"
-#include "uvedit_intern.h"
-
/* * ********************** no editmode!!! *********** */
/*********************** JOIN ***************************/
@@ -518,6 +502,9 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* tessface data removed above, no need to update */
mesh_update_customdata_pointers(me, FALSE);
+
+ /* update normals in case objects with non-uniform scale are joined */
+ ED_mesh_calc_normals(me);
/* old material array */
for (a = 1; a <= ob->totcol; a++) {
@@ -572,7 +559,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
- DAG_scene_sort(bmain, scene); // removed objects, need to rebuild dag before editmode call
+ DAG_relations_tag_update(bmain); // removed objects, need to rebuild dag
#if 0
ED_object_enter_editmode(C, EM_WAITCURSOR);
@@ -1080,7 +1067,7 @@ static float *editmesh_get_mirror_uv(BMEditMesh *em, int axis, float *uv, float
static unsigned int mirror_facehash(const void *ptr)
{
const MFace *mf = ptr;
- int v0, v1;
+ unsigned int v0, v1;
if (mf->v4) {
v0 = MIN4(mf->v1, mf->v2, mf->v3, mf->v4);
@@ -1183,9 +1170,12 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em)
*
* \return boolean TRUE == Found
*/
-int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *index, int size)
+int ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
{
ViewContext vc;
+ Mesh *me = ob->data;
+
+ BLI_assert(me && GS(me->id.name) == ID_ME);
if (!me || me->totpoly == 0)
return 0;
@@ -1215,11 +1205,14 @@ int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *in
* Use when the back buffer stores face index values. but we want a vert.
* This gets the face then finds the closest vertex to mval.
*/
-int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], unsigned int *index, int size)
+int ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
{
unsigned int poly_index;
+ Mesh *me = ob->data;
- if (ED_mesh_pick_face(C, me, mval, &poly_index, size)) {
+ BLI_assert(me && GS(me->id.name) == ID_ME);
+
+ if (ED_mesh_pick_face(C, ob, mval, &poly_index, size)) {
Scene *scene = CTX_data_scene(C);
struct ARegion *ar = CTX_wm_region(C);
@@ -1228,6 +1221,8 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2],
int v_idx_best = -1;
if (dm->getVertCo) {
+ RegionView3D *rv3d = ar->regiondata;
+
/* find the vert closest to 'mval' */
const float mval_f[2] = {(float)mval[0],
(float)mval[1]};
@@ -1235,14 +1230,15 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2],
int fidx;
float len_best = FLT_MAX;
+ ED_view3d_init_mats_rv3d(ob, rv3d);
+
fidx = mp->totloop - 1;
do {
float co[3], sco[2], len;
const int v_idx = me->mloop[mp->loopstart + fidx].v;
dm->getVertCo(dm, v_idx, co);
- mul_m4_v3(ob->obmat, co);
- if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
- len = len_squared_v2v2(mval_f, sco);
+ if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ len = len_manhattan_v2v2(mval_f, sco);
if (len < len_best) {
len_best = len;
v_idx_best = v_idx;
@@ -1268,31 +1264,97 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2],
*
* \return boolean TRUE == Found
*/
-int ED_mesh_pick_vert(bContext *C, Mesh *me, const int mval[2], unsigned int *index, int size)
+typedef struct VertPickData {
+ const MVert *mvert;
+ const float *mval_f; /* [2] */
+ ARegion *ar;
+
+ /* runtime */
+ float len_best;
+ int v_idx_best;
+} VertPickData;
+
+static void ed_mesh_pick_vert__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ VertPickData *data = userData;
+ if ((data->mvert[index].flag & ME_HIDE) == 0) {
+ float sco[2];
+
+ if (ED_view3d_project_float_object(data->ar, co, sco, V3D_PROJ_TEST_CLIP_DEFAULT) == V3D_PROJ_RET_OK) {
+ const float len = len_manhattan_v2v2(data->mval_f, sco);
+ if (len < data->len_best) {
+ data->len_best = len;
+ data->v_idx_best = index;
+ }
+ }
+ }
+}
+int ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size, int use_zbuf)
{
ViewContext vc;
+ Mesh *me = ob->data;
+
+ BLI_assert(me && GS(me->id.name) == ID_ME);
if (!me || me->totvert == 0)
return 0;
view3d_set_viewcontext(C, &vc);
- if (size > 0) {
- /* sample rect to increase chances of selecting, so that when clicking
- * on an face in the backbuf, we can still select a vert */
+ if (use_zbuf) {
+ if (size > 0) {
+ /* sample rect to increase chances of selecting, so that when clicking
+ * on an face in the backbuf, we can still select a vert */
- float dummy_dist;
- *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL);
+ float dummy_dist;
+ *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL);
+ }
+ else {
+ /* sample only on the exact position */
+ *index = view3d_sample_backbuf(&vc, mval[0], mval[1]);
+ }
+
+ if ((*index) <= 0 || (*index) > (unsigned int)me->totvert)
+ return 0;
+
+ (*index)--;
}
else {
- /* sample only on the exact position */
- *index = view3d_sample_backbuf(&vc, mval[0], mval[1]);
- }
+ /* derived mesh to find deformed locations */
+ DerivedMesh *dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH);
+ ARegion *ar = vc.ar;
+ RegionView3D *rv3d = ar->regiondata;
- if ((*index) <= 0 || (*index) > (unsigned int)me->totvert)
- return 0;
+ /* find the vert closest to 'mval' */
+ const float mval_f[2] = {(float)mval[0],
+ (float)mval[1]};
- (*index)--;
+ VertPickData data = {0};
+
+ ED_view3d_init_mats_rv3d(ob, rv3d);
+
+ if (dm == NULL) {
+ return 0;
+ }
+
+ /* setup data */
+ data.mvert = me->mvert;
+ data.ar = ar;
+ data.mval_f = mval_f;
+ data.len_best = FLT_MAX;
+ data.v_idx_best = -1;
+
+ dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data);
+
+ dm->release(dm);
+
+ if (data.v_idx_best == -1) {
+ return 0;
+ }
+
+ *index = data.v_idx_best;
+ }
return 1;
}
diff --git a/source/blender/editors/metaball/SConscript b/source/blender/editors/metaball/SConscript
index b1a1ce935db..7083eff863e 100644
--- a/source/blender/editors/metaball/SConscript
+++ b/source/blender/editors/metaball/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 8633a7a9b38..6c056df5a38 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -586,3 +586,27 @@ void undo_push_mball(bContext *C, const char *name)
undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL);
}
+/* matrix is 4x4 */
+void ED_mball_transform(MetaBall *mb, float *mat)
+{
+ MetaElem *me;
+ float quat[4];
+ const float scale = mat4_to_scale((float (*)[4])mat);
+ const float scale_sqrt = sqrtf(scale);
+
+ mat4_to_quat(quat, (float (*)[4])mat);
+
+ for (me = mb->elems.first; me; me = me->next) {
+ mul_m4_v3((float (*)[4])mat, &me->x);
+ mul_qt_qtqt(me->quat, quat, me->quat);
+ me->rad *= scale;
+ /* hrmf, probably elems shouldn't be
+ * treating scale differently - campbell */
+ if (!MB_TYPE_SIZE_SQUARED(me->type)) {
+ mul_v3_fl(&me->expx, scale);
+ }
+ else {
+ mul_v3_fl(&me->expx, scale_sqrt);
+ }
+ }
+}
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index e98654f589a..f91d57424a1 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -28,10 +28,6 @@
* \ingroup edmeta
*/
-
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "RNA_access.h"
#include "ED_mball.h"
@@ -40,6 +36,9 @@
#include "BLI_utildefines.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "mball_intern.h"
void ED_operatortypes_metaball(void)
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 05c042a4182..a92b25c6c85 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -20,6 +20,7 @@
set(INC
../include
+ ../../blenfont
../../blenkernel
../../blenlib
../../blenloader
@@ -66,4 +67,8 @@ if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
endif()
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_object "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript
index b53ea549853..203d7dff768 100644
--- a/source/blender/editors/object/SConscript
+++ b/source/blender/editors/object/SConscript
@@ -1,9 +1,35 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenfont ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc ../../blenloader'
incs += ' ../../makesrna ../../python ../../ikplugin ../../bmesh'
incs += ' ../../render/extern/include ../../gpu' # for object_bake.c
@@ -24,4 +50,7 @@ if env['WITH_BF_PYTHON']:
if env['WITH_BF_GAMEENGINE']:
defs.append('WITH_GAMEENGINE')
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
env.BlenderLib ( 'bf_editors_object', sources, Split(incs), defs, libtype=['core'], priority=[35] )
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 7c4a547debc..2d1e39107d7 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -67,6 +67,7 @@
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_group.h"
+#include "BKE_image.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -146,7 +147,7 @@ void ED_object_location_from_view(bContext *C, float loc[3])
{
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- float *cursor;
+ const float *cursor;
cursor = give_cursor(scene, v3d);
@@ -186,7 +187,7 @@ 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],
+ const float loc[3], const float rot[3], float primmat[4][4],
int apply_diameter)
{
Scene *scene = CTX_data_scene(C);
@@ -381,7 +382,7 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa
ED_object_base_init_transform(C, BASACT, loc, rot);
DAG_id_type_tag(bmain, ID_OB);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
if (ob->data) {
ED_render_id_flush_update(bmain, ob->data);
}
@@ -469,7 +470,7 @@ static int effector_add_exec(bContext *C, wmOperator *op)
ob->pd = object_add_collision_fields(type);
- DAG_scene_sort(CTX_data_main(C), CTX_data_scene(C));
+ DAG_relations_tag_update(CTX_data_main(C));
return OPERATOR_FINISHED;
}
@@ -735,6 +736,83 @@ void OBJECT_OT_empty_add(wmOperatorType *ot)
ED_object_add_generic_props(ot, FALSE);
}
+static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ Base *base = NULL;
+ 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");
+ return OPERATOR_CANCELLED;
+ }
+
+ base = ED_view3d_give_base_under_cursor(C, event->mval);
+
+ /* if empty under cursor, then set object */
+ if (base && base->object->type == OB_EMPTY) {
+ ob = base->object;
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, CTX_data_scene(C));
+ }
+ else {
+ /* add new empty */
+ unsigned int layer;
+ float rot[3];
+
+ if (!ED_object_add_generic_get_opts(C, op, NULL, rot, NULL, &layer, NULL))
+ return OPERATOR_CANCELLED;
+
+ ob = ED_object_add_type(C, OB_EMPTY, NULL, rot, FALSE, layer);
+ ob->empty_drawtype = OB_EMPTY_IMAGE;
+
+ /* add under the mouse */
+ ED_object_location_from_view(C, ob->loc);
+ ED_view3d_cursor3d_position(C, ob->loc, event->mval);
+ }
+
+ ob->data = ima;
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_drop_named_image(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Add Empty Image/Drop Image To Empty";
+ ot->description = "Add an empty image type to scene with data";
+ ot->idname = "OBJECT_OT_drop_named_image";
+
+ /* api callbacks */
+ ot->invoke = empty_drop_named_image_invoke;
+ ot->poll = ED_operator_objectmode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_string(ot->srna, "filepath", "", FILE_MAX, "Filepath", "Path to image file");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna, "name", "", 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);
+}
+
/********************* Add Lamp Operator ********************/
static const char *get_lamp_defname(int type)
@@ -802,10 +880,25 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot)
static int group_instance_add_exec(bContext *C, wmOperator *op)
{
- Group *group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
-
+ Group *group;
unsigned int layer;
float loc[3], rot[3];
+
+ if (RNA_struct_property_is_set(op->ptr, "name")) {
+ char name[MAX_ID_NAME - 2];
+
+ RNA_string_get(op->ptr, "name", name);
+ group = (Group *)BKE_libblock_find_name(ID_GR, name);
+
+ if (0 == RNA_struct_property_is_set(op->ptr, "location")) {
+ wmEvent *event = CTX_wm_window(C)->eventstate;
+ ED_object_location_from_view(C, loc);
+ ED_view3d_cursor3d_position(C, loc, event->mval);
+ RNA_float_set_array(op->ptr, "location", loc);
+ }
+ }
+ else
+ group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL))
return OPERATOR_CANCELLED;
@@ -820,9 +913,9 @@ static int group_instance_add_exec(bContext *C, wmOperator *op)
id_lib_extern(&group->id);
/* works without this except if you try render right after, see: 22027 */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
return OPERATOR_FINISHED;
}
@@ -847,6 +940,7 @@ void OBJECT_OT_group_instance_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
+ RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME - 2, "Name", "Group name to add");
ot->prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
RNA_def_enum_funcs(ot->prop, RNA_group_itemf);
ED_object_add_generic_props(ot, FALSE);
@@ -925,7 +1019,7 @@ static void object_delete_check_glsl_update(Object *ob)
void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base)
{
DAG_id_type_tag(bmain, ID_OB);
- BLI_remlink(&scene->base, base);
+ BKE_scene_base_unlink(scene, base);
object_delete_check_glsl_update(base->object);
BKE_libblock_free_us(&bmain->object, base->object);
if (scene->basact == base) scene->basact = NULL;
@@ -936,6 +1030,8 @@ static int object_delete_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win;
const short use_global = RNA_boolean_get(op->ptr, "use_global");
if (CTX_data_edit_object(C))
@@ -967,11 +1063,20 @@ static int object_delete_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
-
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
+ /* delete has to handle all open scenes */
+ flag_listbase_ids(&bmain->scene, LIB_DOIT, 1);
+ for (win = wm->windows.first; win; win = win->next) {
+ scene = win->screen->scene;
+
+ if (scene->id.flag & LIB_DOIT) {
+ scene->id.flag &= ~LIB_DOIT;
+
+ DAG_relations_tag_update(bmain);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
+ }
+ }
return OPERATOR_FINISHED;
}
@@ -1232,8 +1337,7 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE, scene);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
@@ -1297,7 +1401,7 @@ static Base *duplibase_for_convert(Scene *scene, Base *base, Object *ob)
}
obn = BKE_object_copy(ob);
- obn->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
basen = MEM_mallocN(sizeof(Base), "duplibase");
*basen = *base;
@@ -1399,7 +1503,7 @@ static int convert_exec(bContext *C, wmOperator *op)
}
else {
newob = ob;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
/* make new mesh data from the original copy */
@@ -1464,7 +1568,7 @@ static int convert_exec(bContext *C, wmOperator *op)
for (ob1 = bmain->object.first; ob1; ob1 = ob1->id.next) {
if (ob1->data == ob->data) {
ob1->type = OB_CURVE;
- ob1->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob1->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
}
@@ -1530,7 +1634,7 @@ static int convert_exec(bContext *C, wmOperator *op)
mb = newob->data;
mb->id.us--;
- newob->data = BKE_mesh_add("Mesh");
+ newob->data = BKE_mesh_add(bmain, "Mesh");
newob->type = OB_MESH;
me = newob->data;
@@ -1595,7 +1699,7 @@ static int convert_exec(bContext *C, wmOperator *op)
}
/* delete object should renew depsgraph */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
// XXX ED_object_enter_editmode(C, 0);
@@ -1611,7 +1715,7 @@ static int convert_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT->object);
}
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -1663,14 +1767,18 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
}
else {
obn = BKE_object_copy(ob);
- obn->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
basen = MEM_mallocN(sizeof(Base), "duplibase");
*basen = *base;
BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */
basen->object = obn;
- if (basen->flag & OB_FROMGROUP) {
+ /* 1) duplis should end up in same group as the original
+ * 2) Rigid Body sim participants MUST always be part of a group...
+ */
+ // XXX: is 2) really a good measure here?
+ if ((basen->flag & OB_FROMGROUP) || ob->rigidbody_object || ob->rigidbody_constraint) {
Group *group;
for (group = bmain->group.first; group; group = group->id.next) {
if (object_in_group(ob, group))
@@ -1784,7 +1892,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
}
break;
case OB_ARMATURE:
- obn->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obn->id, OB_RECALC_DATA);
if (obn->pose)
obn->pose->flag |= POSE_RECALC;
if (dupflag & USER_DUP_ARM) {
@@ -1874,7 +1982,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
/* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */
/* leaves selection of base/object unaltered.
* note: don't call this within a loop since clear_* funcs loop over the entire database.
- * note: caller must do DAG_scene_sort(bmain, scene);
+ * note: caller must do DAG_relations_tag_update(bmain);
* this is not done automatic since we may duplicate many objects in a batch */
Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag)
{
@@ -1895,7 +2003,7 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag
BKE_object_relink(ob);
set_sca_new_poins_ob(ob);
- /* DAG_scene_sort(bmain, scene); */ /* caller must do */
+ /* DAG_relations_tag_update(bmain); */ /* caller must do */
if (ob->data) {
ED_render_id_flush_update(bmain, ob->data);
@@ -1939,8 +2047,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
copy_object_set_idnew(C, dupflag);
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -1973,6 +2080,8 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
static int add_named_exec(bContext *C, wmOperator *op)
{
+ wmWindow *win = CTX_wm_window(C);
+ wmEvent *event = win ? win->eventstate : NULL;
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Base *basen, *base;
@@ -2004,13 +2113,19 @@ static int add_named_exec(bContext *C, wmOperator *op)
basen->lay = basen->object->lay = scene->lay;
- ED_object_location_from_view(C, basen->object->loc);
+ if (event) {
+ 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, basen->object->loc);
+ ED_view3d_cursor3d_position(C, basen->object->loc, mval);
+ }
+
ED_base_object_activate(C, basen);
copy_object_set_idnew(C, dupflag);
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
MEM_freeN(base);
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index e144c38a350..a680230fb32 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -64,6 +64,7 @@
#include "RE_pipeline.h"
#include "RE_shader_ext.h"
+#include "RE_multires_bake.h"
#include "PIL_time.h"
@@ -88,6 +89,7 @@ typedef struct MultiresBakerJobData {
struct MultiresBakerJobData *next, *prev;
DerivedMesh *lores_dm, *hires_dm;
int simple, lvl, tot_lvl;
+ ListBase images;
} MultiresBakerJobData;
/* data passing to multires-baker job */
@@ -95,829 +97,13 @@ typedef struct {
ListBase data;
int bake_clear, bake_filter;
short mode, use_lores_mesh;
+ int number_of_rays;
+ float bias;
+ int raytrace_structure;
+ int octree_resolution;
+ int threads;
} MultiresBakeJob;
-/* data passing to multires baker */
-typedef struct {
- DerivedMesh *lores_dm, *hires_dm;
- int simple, lvl, tot_lvl, bake_filter;
- short mode, use_lores_mesh;
-
- int tot_obj, tot_image;
- ListBase image;
-
- int baked_objects, baked_faces;
-
- short *stop;
- short *do_update;
- float *progress;
-} MultiresBakeRender;
-
-typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float tangmat[3][3], const int x, const int y);
-
-typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
-typedef void (*MApplyBakeData)(void *bake_data);
-typedef void (*MFreeBakeData)(void *bake_data);
-
-typedef struct {
- MVert *mvert;
- MFace *mface;
- MTFace *mtface;
- float *pvtangent;
- float *precomputed_normals;
- int w, h;
- int face_index;
- int i0, i1, i2;
- DerivedMesh *lores_dm, *hires_dm;
- int lvl;
- void *bake_data;
- ImBuf *ibuf;
- MPassKnownData pass_data;
-} MResolvePixelData;
-
-typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
-
-typedef struct {
- int w, h;
- char *texels;
- const MResolvePixelData *data;
- MFlushPixel flush_pixel;
-} MBakeRast;
-
-typedef struct {
- float *heights;
- float height_min, height_max;
- Image *ima;
- DerivedMesh *ssdm;
- const int *orig_index_mf_to_mpoly;
- const int *orig_index_mp_to_orig;
-} MHeightBakeData;
-
-typedef struct {
- const int *orig_index_mf_to_mpoly;
- const int *orig_index_mp_to_orig;
-} MNormalBakeData;
-
-static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
-{
- unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2,
- data->mface[face_num].v3, data->mface[face_num].v4};
- const int smoothnormal = (data->mface[face_num].flag & ME_SMOOTH);
-
- if (!smoothnormal) { /* flat */
- if (data->precomputed_normals) {
- copy_v3_v3(norm, &data->precomputed_normals[3 * face_num]);
- }
- else {
- float nor[3];
- float *p0, *p1, *p2;
- const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3;
-
- p0 = data->mvert[indices[0]].co;
- p1 = data->mvert[indices[1]].co;
- p2 = data->mvert[indices[2]].co;
-
- if (iGetNrVerts == 4) {
- float *p3 = data->mvert[indices[3]].co;
- normal_quad_v3(nor, p0, p1, p2, p3);
- }
- else {
- normal_tri_v3(nor, p0, p1, p2);
- }
-
- copy_v3_v3(norm, nor);
- }
- }
- else {
- short *no = data->mvert[indices[vert_index]].no;
-
- normal_short_to_float_v3(norm, no);
- normalize_v3(norm);
- }
-}
-
-static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
-{
- memset(bake_rast, 0, sizeof(MBakeRast));
-
- bake_rast->texels = ibuf->userdata;
- bake_rast->w = ibuf->x;
- bake_rast->h = ibuf->y;
- bake_rast->data = data;
- bake_rast->flush_pixel = flush_pixel;
-}
-
-static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
-{
- float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
- float *st0, *st1, *st2;
- float *tang0, *tang1, *tang2;
- float no0[3], no1[3], no2[3];
- float fUV[2], from_tang[3][3], to_tang[3][3];
- float u, v, w, sign;
- int r;
-
- const int i0 = data->i0;
- const int i1 = data->i1;
- const int i2 = data->i2;
-
- st0 = data->mtface[data->face_index].uv[i0];
- st1 = data->mtface[data->face_index].uv[i1];
- st2 = data->mtface[data->face_index].uv[i2];
-
- tang0 = data->pvtangent + data->face_index * 16 + i0 * 4;
- tang1 = data->pvtangent + data->face_index * 16 + i1 * 4;
- tang2 = data->pvtangent + data->face_index * 16 + i2 * 4;
-
- multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */
- multiresbake_get_normal(data, no1, data->face_index, i1);
- multiresbake_get_normal(data, no2, data->face_index, i2);
-
- resolve_tri_uv(fUV, st, st0, st1, st2);
-
- u = fUV[0];
- v = fUV[1];
- w = 1 - u - v;
-
- /* the sign is the same at all face vertices for any non degenerate face.
- * Just in case we clamp the interpolated value though. */
- sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f;
-
- /* this sequence of math is designed specifically as is with great care
- * to be compatible with our shader. Please don't change without good reason. */
- for (r = 0; r < 3; r++) {
- from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w;
- from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w;
- }
-
- cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */
- mul_v3_fl(from_tang[1], sign);
- invert_m3_m3(to_tang, from_tang);
- /* sequence end */
-
- data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
- data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
-}
-
-static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
-{
- const int w = bake_rast->w;
- const int h = bake_rast->h;
-
- if (x >= 0 && x < w && y >= 0 && y < h) {
- if ((bake_rast->texels[y * w + x]) == 0) {
- flush_pixel(bake_rast->data, x, y);
- bake_rast->texels[y * w + x] = FILTER_MASK_USED;
- }
- }
-}
-
-static void rasterize_half(const MBakeRast *bake_rast,
- const float s0_s, const float t0_s, const float s1_s, const float t1_s,
- const float s0_l, const float t0_l, const float s1_l, const float t1_l,
- const int y0_in, const int y1_in, const int is_mid_right)
-{
- const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0;
- const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0;
- const int w = bake_rast->w;
- const int h = bake_rast->h;
- int y, y0, y1;
-
- if (y1_in <= 0 || y0_in >= h)
- return;
-
- y0 = y0_in < 0 ? 0 : y0_in;
- y1 = y1_in >= h ? h : y1_in;
-
- for (y = y0; y < y1; y++) {
- /*-b(x-x0) + a(y-y0) = 0 */
- int iXl, iXr, x;
- float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s;
- float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l;
-
- if (is_mid_right != 0)
- SWAP(float, x_l, x_r);
-
- iXl = (int)ceilf(x_l);
- iXr = (int)ceilf(x_r);
-
- if (iXr > 0 && iXl < w) {
- iXl = iXl < 0 ? 0 : iXl;
- iXr = iXr >= w ? w : iXr;
-
- for (x = iXl; x < iXr; x++)
- set_rast_triangle(bake_rast, x, y);
- }
- }
-}
-
-static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
-{
- const int w = bake_rast->w;
- const int h = bake_rast->h;
- float slo = st0_in[0] * w - 0.5f;
- float tlo = st0_in[1] * h - 0.5f;
- float smi = st1_in[0] * w - 0.5f;
- float tmi = st1_in[1] * h - 0.5f;
- float shi = st2_in[0] * w - 0.5f;
- float thi = st2_in[1] * h - 0.5f;
- int is_mid_right = 0, ylo, yhi, yhi_beg;
-
- /* skip degenerates */
- if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi))
- return;
-
- /* sort by T */
- if (tlo > tmi && tlo > thi) {
- SWAP(float, shi, slo);
- SWAP(float, thi, tlo);
- }
- else if (tmi > thi) {
- SWAP(float, shi, smi);
- SWAP(float, thi, tmi);
- }
-
- if (tlo > tmi) {
- SWAP(float, slo, smi);
- SWAP(float, tlo, tmi);
- }
-
- /* check if mid point is to the left or to the right of the lo-hi edge */
- is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0;
- ylo = (int) ceilf(tlo);
- yhi_beg = (int) ceilf(tmi);
- yhi = (int) ceilf(thi);
-
- /*if (fTmi>ceilf(fTlo))*/
- rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
- rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
-}
-
-static int multiresbake_test_break(MultiresBakeRender *bkr)
-{
- if (!bkr->stop) {
- /* this means baker is executed outside from job system */
- return 0;
- }
-
- return G.is_break;
-}
-
-static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData passKnownData,
- MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
-{
- DerivedMesh *dm = bkr->lores_dm;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- const int lvl = bkr->lvl;
- const int tot_face = dm->getNumTessFaces(dm);
- MVert *mvert = dm->getVertArray(dm);
- MFace *mface = dm->getTessFaceArray(dm);
- MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
- float *pvtangent = NULL;
-
- if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
- DM_add_tangent_layer(dm);
-
- pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT);
-
- if (tot_face > 0) { /* sanity check */
- int f = 0;
- MBakeRast bake_rast;
- MResolvePixelData data = {NULL};
-
- data.mface = mface;
- data.mvert = mvert;
- data.mtface = mtface;
- data.pvtangent = pvtangent;
- data.precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */
- data.w = ibuf->x;
- data.h = ibuf->y;
- data.lores_dm = dm;
- data.hires_dm = bkr->hires_dm;
- data.lvl = lvl;
- data.pass_data = passKnownData;
-
- if (initBakeData)
- data.bake_data = initBakeData(bkr, ima);
-
- init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);
-
- for (f = 0; f < tot_face; f++) {
- MTFace *mtfate = &mtface[f];
- int verts[3][2], nr_tris, t;
-
- if (multiresbake_test_break(bkr))
- break;
-
- if (mtfate->tpage != ima)
- continue;
-
- data.face_index = f;
- data.ibuf = ibuf;
-
- /* might support other forms of diagonal splits later on such as
- * split by shortest diagonal.*/
- verts[0][0] = 0;
- verts[1][0] = 1;
- verts[2][0] = 2;
-
- verts[0][1] = 0;
- verts[1][1] = 2;
- verts[2][1] = 3;
-
- nr_tris = mface[f].v4 != 0 ? 2 : 1;
- for (t = 0; t < nr_tris; t++) {
- data.i0 = verts[0][t];
- data.i1 = verts[1][t];
- data.i2 = verts[2][t];
-
- bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
- }
-
- bkr->baked_faces++;
-
- if (bkr->do_update)
- *bkr->do_update = TRUE;
-
- if (bkr->progress)
- *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
- }
-
- if (applyBakeData)
- applyBakeData(data.bake_data);
-
- if (freeBakeData)
- freeBakeData(data.bake_data);
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-}
-
-/* mode = 0: interpolate normals,
- * mode = 1: interpolate coord */
-static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
-{
- int x0, x1, y0, y1;
- float u, v;
- float data[4][3];
-
- x0 = (int) crn_x;
- x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1);
-
- y0 = (int) crn_y;
- y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1);
-
- u = crn_x - x0;
- v = crn_y - y0;
-
- if (mode == 0) {
- copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0));
- copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0));
- copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1));
- copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1));
- }
- else {
- copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0));
- copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0));
- copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1));
- copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
- }
-
- interp_bilinear_quad_v3(data, u, v, res);
-}
-
-static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,
- const int *index_mf_to_mpoly, const int *index_mp_to_orig,
- const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
-{
- MFace mface;
- CCGElem **grid_data;
- CCGKey key;
- float crn_x, crn_y;
- int grid_size, S, face_side;
- int *grid_offset, g_index;
-
- lodm->getTessFace(lodm, face_index, &mface);
-
- grid_size = hidm->getGridSize(hidm);
- grid_data = hidm->getGridData(hidm);
- grid_offset = hidm->getGridOffset(hidm);
- hidm->getGridKey(hidm, &key);
-
- face_side = (grid_size << 1) - 1;
-
- if (lvl == 0) {
- g_index = grid_offset[face_index];
- S = mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y);
- }
- else {
- int side = (1 << (lvl - 1)) + 1;
- int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index);
- int loc_offs = face_index % (1 << (2 * lvl));
- int cell_index = loc_offs % ((side - 1) * (side - 1));
- int cell_side = (grid_size - 1) / (side - 1);
- int row = cell_index / (side - 1);
- int col = cell_index % (side - 1);
-
- S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[grid_index];
- g_index = grid_offset[grid_index];
-
- crn_y = (row * cell_side) + u * cell_side;
- crn_x = (col * cell_side) + v * cell_side;
- }
-
- CLAMP(crn_x, 0.0f, grid_size);
- CLAMP(crn_y, 0.0f, grid_size);
-
- if (n != NULL)
- interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n);
-
- if (co != NULL)
- interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co);
-}
-
-/* mode = 0: interpolate normals,
- * mode = 1: interpolate coord */
-static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
-{
- float data[4][3];
-
- if (mode == 0) {
- dm->getVertNo(dm, mface->v1, data[0]);
- dm->getVertNo(dm, mface->v2, data[1]);
- dm->getVertNo(dm, mface->v3, data[2]);
- dm->getVertNo(dm, mface->v4, data[3]);
- }
- else {
- dm->getVertCo(dm, mface->v1, data[0]);
- dm->getVertCo(dm, mface->v2, data[1]);
- dm->getVertCo(dm, mface->v3, data[2]);
- dm->getVertCo(dm, mface->v4, data[3]);
- }
-
- interp_bilinear_quad_v3(data, u, v, res);
-}
-
-/* mode = 0: interpolate normals,
- * mode = 1: interpolate coord */
-static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
-{
- float data[3][3];
-
- if (mode == 0) {
- dm->getVertNo(dm, mface->v1, data[0]);
- dm->getVertNo(dm, mface->v2, data[1]);
- dm->getVertNo(dm, mface->v3, data[2]);
- }
- else {
- dm->getVertCo(dm, mface->v1, data[0]);
- dm->getVertCo(dm, mface->v2, data[1]);
- dm->getVertCo(dm, mface->v3, data[2]);
- }
-
- interp_barycentric_tri_v3(data, u, v, res);
-}
-
-static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
-{
- MHeightBakeData *height_data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- DerivedMesh *lodm = bkr->lores_dm;
-
- height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
-
- height_data->ima = ima;
- height_data->heights = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights");
- height_data->height_max = -FLT_MAX;
- height_data->height_min = FLT_MAX;
-
- if (!bkr->use_lores_mesh) {
- SubsurfModifierData smd = {{NULL}};
- int ss_lvl = bkr->tot_lvl - bkr->lvl;
-
- CLAMP(ss_lvl, 0, 6);
-
- if (ss_lvl > 0) {
- smd.levels = smd.renderLevels = ss_lvl;
- smd.flags |= eSubsurfModifierFlag_SubsurfUv;
-
- if (bkr->simple)
- smd.subdivType = ME_SIMPLE_SUBSURF;
-
- height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0);
- }
- }
-
- height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
- height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
- return (void *)height_data;
-}
-
-static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
-{
- MNormalBakeData *normal_data;
- DerivedMesh *lodm = bkr->lores_dm;
-
- normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
-
- normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
- normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
-
- return (void *)normal_data;
-}
-
-static void free_normal_data(void *bake_data)
-{
- MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
-
- MEM_freeN(normal_data);
-}
-
-static void apply_heights_data(void *bake_data)
-{
- MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL);
- int x, y, i;
- float height, *heights = height_data->heights;
- float min = height_data->height_min, max = height_data->height_max;
-
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- i = ibuf->x * y + x;
-
- if (((char *)ibuf->userdata)[i] != FILTER_MASK_USED)
- continue;
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + i * 4;
-
- if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
- else height = 0;
-
- rrgbf[0] = rrgbf[1] = rrgbf[2] = height;
- }
- else {
- char *rrgb = (char *)ibuf->rect + i * 4;
-
- if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
- else height = 0;
-
- rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(height);
- }
- }
- }
-
- ibuf->userflags = IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID;
-
- BKE_image_release_ibuf(height_data->ima, ibuf, NULL);
-}
-
-static void free_heights_data(void *bake_data)
-{
- MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
-
- if (height_data->ssdm)
- height_data->ssdm->release(height_data->ssdm);
-
- MEM_freeN(height_data->heights);
- MEM_freeN(height_data);
-}
-
-/* MultiresBake callback for heights baking
- * general idea:
- * - find coord of point with specified UV in hi-res mesh (let's call it p1)
- * - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
- * mesh to make texture smoother) let's call this point p0 and n.
- * - height wound be dot(n, p1-p0) */
-static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float UNUSED(tangmat[3][3]), const int x, const int y)
-{
- MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
- MFace mface;
- MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
- float uv[2], *st0, *st1, *st2, *st3;
- int pixel = ibuf->x * y + x;
- float vec[3], p0[3], p1[3], n[3], len;
-
- lores_dm->getTessFace(lores_dm, face_index, &mface);
-
- st0 = mtface[face_index].uv[0];
- st1 = mtface[face_index].uv[1];
- st2 = mtface[face_index].uv[2];
-
- if (mface.v4) {
- st3 = mtface[face_index].uv[3];
- resolve_quad_uv(uv, st, st0, st1, st2, st3);
- }
- else
- resolve_tri_uv(uv, st, st0, st1, st2);
-
- CLAMP(uv[0], 0.0f, 1.0f);
- CLAMP(uv[1], 0.0f, 1.0f);
-
- get_ccgdm_data(lores_dm, hires_dm,
- height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
- lvl, face_index, uv[0], uv[1], p1, 0);
-
- if (height_data->ssdm) {
- get_ccgdm_data(lores_dm, height_data->ssdm,
- height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
- 0, face_index, uv[0], uv[1], p0, n);
- }
- else {
- lores_dm->getTessFace(lores_dm, face_index, &mface);
-
- if (mface.v4) {
- interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
- interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
- }
- else {
- interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
- interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
- }
- }
-
- sub_v3_v3v3(vec, p1, p0);
- len = dot_v3v3(n, vec);
-
- height_data->heights[pixel] = len;
- if (len < height_data->height_min) height_data->height_min = len;
- if (len > height_data->height_max) height_data->height_max = len;
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + pixel * 4;
- rrgbf[3] = 1.0f;
-
- ibuf->userflags = IB_RECT_INVALID;
- }
- else {
- char *rrgb = (char *)ibuf->rect + pixel * 4;
- rrgb[3] = 255;
- }
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-}
-
-/* MultiresBake callback for normals' baking
- * general idea:
- * - find coord and normal of point with specified UV in hi-res mesh
- * - multiply it by tangmat
- * - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
-static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float tangmat[3][3], const int x, const int y)
-{
- MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
- MFace mface;
- MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
- float uv[2], *st0, *st1, *st2, *st3;
- int pixel = ibuf->x * y + x;
- float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
-
- lores_dm->getTessFace(lores_dm, face_index, &mface);
-
- st0 = mtface[face_index].uv[0];
- st1 = mtface[face_index].uv[1];
- st2 = mtface[face_index].uv[2];
-
- if (mface.v4) {
- st3 = mtface[face_index].uv[3];
- resolve_quad_uv(uv, st, st0, st1, st2, st3);
- }
- else
- resolve_tri_uv(uv, st, st0, st1, st2);
-
- CLAMP(uv[0], 0.0f, 1.0f);
- CLAMP(uv[1], 0.0f, 1.0f);
-
- get_ccgdm_data(lores_dm, hires_dm,
- normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig,
- lvl, face_index, uv[0], uv[1], NULL, n);
-
- mul_v3_m3v3(vec, tangmat, n);
- normalize_v3(vec);
- mul_v3_fl(vec, 0.5);
- add_v3_v3(vec, tmp);
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + pixel * 4;
- rrgbf[0] = vec[0];
- rrgbf[1] = vec[1];
- rrgbf[2] = vec[2];
- rrgbf[3] = 1.0f;
-
- ibuf->userflags = IB_RECT_INVALID;
- }
- else {
- unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
- rgb_float_to_uchar(rrgb, vec);
- rrgb[3] = 255;
- }
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-}
-
-static void count_images(MultiresBakeRender *bkr)
-{
- int a, totface;
- DerivedMesh *dm = bkr->lores_dm;
- MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
-
- bkr->image.first = bkr->image.last = NULL;
- bkr->tot_image = 0;
-
- totface = dm->getNumTessFaces(dm);
-
- for (a = 0; a < totface; a++)
- mtface[a].tpage->id.flag &= ~LIB_DOIT;
-
- for (a = 0; a < totface; a++) {
- Image *ima = mtface[a].tpage;
- if ((ima->id.flag & LIB_DOIT) == 0) {
- LinkData *data = BLI_genericNodeN(ima);
- BLI_addtail(&bkr->image, data);
- bkr->tot_image++;
- ima->id.flag |= LIB_DOIT;
- }
- }
-
- for (a = 0; a < totface; a++)
- mtface[a].tpage->id.flag &= ~LIB_DOIT;
-}
-
-static void bake_images(MultiresBakeRender *bkr)
-{
- LinkData *link;
-
- for (link = bkr->image.first; link; link = link->next) {
- Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
-
- if (ibuf->x > 0 && ibuf->y > 0) {
- ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
-
- switch (bkr->mode) {
- case RE_BAKE_NORMALS:
- do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
- break;
- case RE_BAKE_DISPLACEMENT:
- do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
- apply_heights_data, free_heights_data);
- break;
- }
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
- ima->id.flag |= LIB_DOIT;
- }
-}
-
-static void finish_images(MultiresBakeRender *bkr)
-{
- LinkData *link;
-
- for (link = bkr->image.first; link; link = link->next) {
- Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
-
- if (ibuf->x <= 0 || ibuf->y <= 0)
- continue;
-
- RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
-
- ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
-
- if (ibuf->rect_float)
- ibuf->userflags |= IB_RECT_INVALID;
-
- if (ibuf->mipmap[0]) {
- ibuf->userflags |= IB_MIPMAP_INVALID;
- imb_freemipmapImBuf(ibuf);
- }
-
- if (ibuf->userdata) {
- MEM_freeN(ibuf->userdata);
- ibuf->userdata = NULL;
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
-}
-
-static void multiresbake_start(MultiresBakeRender *bkr)
-{
- count_images(bkr);
- bake_images(bkr);
- finish_images(bkr);
-}
-
static int multiresbake_check(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@@ -1023,6 +209,9 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
if (*lvl == 0) {
DerivedMesh *tmp_dm = CDDM_from_mesh(me, ob);
+
+ DM_set_only_copy(tmp_dm, CD_MASK_BAREMESH | CD_MASK_MTFACE);
+
dm = CDDM_copy(tmp_dm);
tmp_dm->release(tmp_dm);
}
@@ -1030,6 +219,8 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
MultiresModifierData tmp_mmd = *mmd;
DerivedMesh *cddm = CDDM_from_mesh(me, ob);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH | CD_MASK_MTFACE);
+
tmp_mmd.lvl = *lvl;
tmp_mmd.sculptlvl = *lvl;
dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
@@ -1047,6 +238,14 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
DerivedMesh *cddm = CDDM_from_mesh(me, ob);
DerivedMesh *dm;
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+
+ /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data,
+ * but we really need BAREMESH only to save lots of memory
+ */
+ CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH);
+ CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH);
+
*lvl = mmd->totlvl;
*simple = mmd->simple;
@@ -1058,11 +257,18 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
return dm;
}
-static void clear_images(MTFace *mtface, int totface)
+typedef enum ClearFlag {
+ CLEAR_NORMAL = 1
+} ClearFlag;
+
+
+static void clear_images(MTFace *mtface, int totface, ClearFlag flag)
{
int a;
const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
+ const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
for (a = 0; a < totface; a++)
mtface[a].tpage->id.flag &= ~LIB_DOIT;
@@ -1073,7 +279,11 @@ static void clear_images(MTFace *mtface, int totface)
if ((ima->id.flag & LIB_DOIT) == 0) {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+ if (flag == CLEAR_NORMAL)
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
+ else
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+
ima->id.flag |= LIB_DOIT;
BKE_image_release_ibuf(ima, ibuf, NULL);
@@ -1101,7 +311,10 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
ob = base->object;
me = (Mesh *)ob->data;
- clear_images(me->mtface, me->totface);
+ if (scene->r.bake_mode == RE_BAKE_NORMALS && scene->r.bake_normal_space == R_BAKE_SPACE_TANGENT)
+ clear_images(me->mtface, me->totface, CLEAR_NORMAL);
+ else
+ clear_images(me->mtface, me->totface, 0);
}
CTX_DATA_END;
}
@@ -1118,16 +331,17 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
bkr.bake_filter = scene->r.bake_filter;
bkr.mode = scene->r.bake_mode;
bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
+ bkr.bias = scene->r.bake_biasdist;
+ bkr.number_of_rays = scene->r.bake_samples;
+ bkr.raytrace_structure = scene->r.raytrace_structure;
+ bkr.octree_resolution = scene->r.ocres;
+ bkr.threads = scene->r.mode & R_FIXED_THREADS ? scene->r.threads : 0;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
- bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
-
- if (!bkr.lores_dm)
- continue;
-
bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
+ bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
- multiresbake_start(&bkr);
+ RE_multires_bake_images(&bkr);
BLI_freelistN(&bkr.image);
@@ -1155,24 +369,27 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
bkj->mode = scene->r.bake_mode;
bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR;
+ bkj->bias = scene->r.bake_biasdist;
+ bkj->number_of_rays = scene->r.bake_samples;
+ bkj->raytrace_structure = scene->r.raytrace_structure;
+ bkj->octree_resolution = scene->r.ocres;
+ bkj->threads = scene->r.mode & R_FIXED_THREADS ? scene->r.threads : 0;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
MultiresBakerJobData *data;
- DerivedMesh *lores_dm;
int lvl;
+
ob = base->object;
multires_force_update(ob);
- lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
- if (!lores_dm)
- continue;
-
data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
- data->lores_dm = lores_dm;
- data->lvl = lvl;
+
+ /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
+ data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
+ data->lvl = lvl;
BLI_addtail(&bkj->data, data);
}
@@ -1192,7 +409,10 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
DerivedMesh *dm = data->lores_dm;
MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
- clear_images(mtface, dm->getNumTessFaces(dm));
+ if (bkj->mode == RE_BAKE_NORMALS)
+ clear_images(mtface, dm->getNumTessFaces(dm), CLEAR_NORMAL);
+ else
+ clear_images(mtface, dm->getNumTessFaces(dm), 0);
}
}
@@ -1219,9 +439,15 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
bkr.do_update = do_update;
bkr.progress = progress;
- multiresbake_start(&bkr);
+ bkr.bias = bkj->bias;
+ bkr.number_of_rays = bkj->number_of_rays;
+ bkr.raytrace_structure = bkj->raytrace_structure;
+ bkr.octree_resolution = bkj->octree_resolution;
+ bkr.threads = bkj->threads;
- BLI_freelistN(&bkr.image);
+ RE_multires_bake_images(&bkr);
+
+ data->images = bkr.image;
baked_objects++;
}
@@ -1231,12 +457,22 @@ static void multiresbake_freejob(void *bkv)
{
MultiresBakeJob *bkj = bkv;
MultiresBakerJobData *data, *next;
+ LinkData *link;
data = bkj->data.first;
while (data) {
next = data->next;
data->lores_dm->release(data->lores_dm);
data->hires_dm->release(data->hires_dm);
+
+ /* delete here, since this delete will be called from main thread */
+ for (link = data->images.first; link; link = link->next) {
+ Image *ima = (Image *)link->data;
+ GPU_free_image(ima);
+ }
+
+ BLI_freelistN(&data->images);
+
MEM_freeN(data);
data = next;
}
@@ -1391,7 +627,12 @@ static void finish_bake_internal(BakeRender *bkr)
/* freed when baking is done, but if its canceled we need to free here */
if (ibuf) {
if (ibuf->userdata) {
- MEM_freeN(ibuf->userdata);
+ BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata;
+ if (userdata->mask_buffer)
+ MEM_freeN(userdata->mask_buffer);
+ if (userdata->displacement_buffer)
+ MEM_freeN(userdata->displacement_buffer);
+ MEM_freeN(userdata);
ibuf->userdata = NULL;
}
}
@@ -1472,7 +713,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEven
static int is_multires_bake(Scene *scene)
{
- if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT))
+ if (ELEM3(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO))
return scene->r.bake_flag & R_BAKE_MULTIRES;
return 0;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index f78e1203bc4..1bed7d7dd11 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -40,6 +40,8 @@
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_anim_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
@@ -141,7 +143,7 @@ ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **pchan_r
/* single constraint */
bConstraint *get_active_constraint(Object *ob)
{
- return constraints_get_active(get_active_constraints(ob));
+ return BKE_constraints_get_active(get_active_constraints(ob));
}
/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
@@ -225,7 +227,7 @@ static void update_pyconstraint_cb(void *arg1, void *arg2)
/* helper function for add_constriant - sets the last target for the active constraint */
static void set_constraint_nth_target(bConstraint *con, Object *target, const char subtarget[], int index)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
int num_targets, i;
@@ -297,7 +299,7 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
/* Check all constraints - is constraint valid? */
if (conlist) {
for (curcon = conlist->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -610,7 +612,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
list = get_active_constraints(ob);
}
- con = constraints_findByName(list, constraint_name);
+ con = BKE_constraints_findByName(list, constraint_name);
//if (G.debug & G_DEBUG)
//printf("constraint found = %p, %s\n", (void *)con, (con)?con->name:"<Not found>");
@@ -718,81 +720,87 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
/* ------------- Child-Of Constraint ------------------ */
-static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, float invmat[4][4])
+static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, float invmat[4][4], const int owner)
{
- bConstraint *lastcon = NULL;
- bPoseChannel *pchan = NULL;
-
/* nullify inverse matrix first */
unit_m4(invmat);
- /* try to find a pose channel - assume that this is the constraint owner */
- /* TODO: get from context instead? */
- if (ob && ob->pose)
- pchan = BKE_pose_channel_active(ob);
-
- /* calculate/set inverse matrix:
- * We just calculate all transform-stack eval up to but not including this constraint.
- * This is because inverse should just inverse correct for just the constraint's influence
- * when it gets applied; that is, at the time of application, we don't know anything about
- * what follows.
- */
- if (pchan) {
- float imat[4][4], tmat[4][4];
- float pmat[4][4];
-
- /* 1. calculate posemat where inverse doesn't exist yet (inverse was cleared above),
- * to use as baseline ("pmat") to derive delta from. This extra calc saves users
- * from having pressing "Clear Inverse" first
- */
- BKE_pose_where_is(scene, ob);
- copy_m4_m4(pmat, pchan->pose_mat);
-
- /* 2. knock out constraints starting from this one */
- lastcon = pchan->constraints.last;
- pchan->constraints.last = con->prev;
-
- if (con->prev) {
- /* new end must not point to this one, else this chain cutting is useless */
- con->prev->next = NULL;
- }
- else {
- /* constraint was first */
- pchan->constraints.first = NULL;
- }
-
- /* 3. solve pose without disabled constraints */
- BKE_pose_where_is(scene, ob);
-
- /* 4. determine effect of constraint by removing the newly calculated
- * pchan->pose_mat from the original pchan->pose_mat, thus determining
- * the effect of the constraint
- */
- invert_m4_m4(imat, pchan->pose_mat);
- mult_m4_m4m4(tmat, pmat, imat);
- invert_m4_m4(invmat, tmat);
-
- /* 5. restore constraints */
- pchan->constraints.last = lastcon;
-
- if (con->prev) {
- /* hook up prev to this one again */
- con->prev->next = con;
- }
- else {
- /* set as first again */
- pchan->constraints.first = con;
+ if (owner == EDIT_CONSTRAINT_OWNER_BONE) {
+ bPoseChannel *pchan;
+ /* try to find a pose channel - assume that this is the constraint owner */
+ /* TODO: get from context instead? */
+ if (ob && ob->pose && (pchan = BKE_pose_channel_active(ob))) {
+ bConstraint *con_last;
+ /* calculate/set inverse matrix:
+ * We just calculate all transform-stack eval up to but not including this constraint.
+ * This is because inverse should just inverse correct for just the constraint's influence
+ * when it gets applied; that is, at the time of application, we don't know anything about
+ * what follows.
+ */
+ float imat[4][4], tmat[4][4];
+ float pmat[4][4];
+
+ /* make sure we passed the correct constraint */
+ BLI_assert(BLI_findindex(&pchan->constraints, con) != -1);
+
+ /* 1. calculate posemat where inverse doesn't exist yet (inverse was cleared above),
+ * to use as baseline ("pmat") to derive delta from. This extra calc saves users
+ * from having pressing "Clear Inverse" first
+ */
+ BKE_pose_where_is(scene, ob);
+ copy_m4_m4(pmat, pchan->pose_mat);
+
+ /* 2. knock out constraints starting from this one */
+ con_last = pchan->constraints.last;
+ pchan->constraints.last = con->prev;
+
+ if (con->prev) {
+ /* new end must not point to this one, else this chain cutting is useless */
+ con->prev->next = NULL;
+ }
+ else {
+ /* constraint was first */
+ pchan->constraints.first = NULL;
+ }
+
+ /* 3. solve pose without disabled constraints */
+ BKE_pose_where_is(scene, ob);
+
+ /* 4. determine effect of constraint by removing the newly calculated
+ * pchan->pose_mat from the original pchan->pose_mat, thus determining
+ * the effect of the constraint
+ */
+ invert_m4_m4(imat, pchan->pose_mat);
+ mult_m4_m4m4(tmat, pmat, imat);
+ invert_m4_m4(invmat, tmat);
+
+ /* 5. restore constraints */
+ pchan->constraints.last = con_last;
+
+ if (con->prev) {
+ /* hook up prev to this one again */
+ con->prev->next = con;
+ }
+ else {
+ /* set as first again */
+ pchan->constraints.first = con;
+ }
+
+ /* 6. recalculate pose with new inv-mat applied */
+ BKE_pose_where_is(scene, ob);
}
-
- /* 6. recalculate pose with new inv-mat applied */
- BKE_pose_where_is(scene, ob);
}
- else if (ob) {
- Object workob;
-
- /* use BKE_object_workob_calc_parent to find inverse - just like for normal parenting */
- BKE_object_workob_calc_parent(scene, ob, &workob);
- invert_m4_m4(invmat, workob.obmat);
+ if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) {
+ if (ob) {
+ Object workob;
+
+ /* make sure we passed the correct constraint */
+ BLI_assert(BLI_findindex(&ob->constraints, con) != -1);
+
+ /* use BKE_object_workob_calc_parent to find inverse - just like for normal parenting */
+ BKE_object_workob_calc_parent(scene, ob, &workob);
+ invert_m4_m4(invmat, workob.obmat);
+ }
}
}
@@ -803,6 +811,7 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
+ const int owner = RNA_enum_get(op->ptr, "owner");
/* despite 3 layers of checks, we may still not be able to find a constraint */
if (data == NULL) {
@@ -811,7 +820,7 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- child_get_inverse_matrix(scene, ob, con, data->invmat);
+ child_get_inverse_matrix(scene, ob, con, data->invmat, owner);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
@@ -1024,6 +1033,7 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL;
+ const int owner = RNA_enum_get(op->ptr, "owner");
/* despite 3 layers of checks, we may still not be able to find a constraint */
if (data == NULL) {
@@ -1032,7 +1042,7 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- child_get_inverse_matrix(scene, ob, con, data->invmat);
+ child_get_inverse_matrix(scene, ob, con, data->invmat, owner);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
@@ -1123,7 +1133,7 @@ void ED_object_constraint_set_active(Object *ob, bConstraint *con)
if ((lb && con) && (con->flag & CONSTRAINT_ACTIVE))
return;
- constraints_set_active(lb, con);
+ BKE_constraints_set_active(lb, con);
}
void ED_object_constraint_update(Object *ob)
@@ -1138,12 +1148,12 @@ void ED_object_constraint_update(Object *ob)
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
-void ED_object_constraint_dependency_update(Main *bmain, Scene *scene, Object *ob)
+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
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
static int constraint_poll(bContext *C)
@@ -1162,9 +1172,9 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
const short is_ik = ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK);
/* free the constraint */
- if (remove_constraint(lb, con)) {
+ if (BKE_remove_constraint(lb, con)) {
/* there's no active constraint now, so make sure this is the case */
- constraints_set_active(lb, NULL);
+ BKE_constraints_set_active(lb, NULL);
ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */
@@ -1302,19 +1312,18 @@ void CONSTRAINT_OT_move_up(wmOperatorType *ot)
static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
/* free constraints for all selected bones */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
- free_constraints(&pchan->constraints);
+ BKE_free_constraints(&pchan->constraints);
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_SPLINEIK | PCHAN_HAS_CONST);
}
CTX_DATA_END;
/* force depsgraph to get recalculated since relationships removed */
- DAG_scene_sort(bmain, scene); /* sort order of objects */
+ DAG_relations_tag_update(bmain);
/* note, calling BIK_clear_data() isn't needed here */
@@ -1341,18 +1350,17 @@ void POSE_OT_constraints_clear(wmOperatorType *ot)
static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
/* do freeing */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
- free_constraints(&ob->constraints);
+ BKE_free_constraints(&ob->constraints);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
/* force depsgraph to get recalculated since relationships removed */
- DAG_scene_sort(bmain, scene); /* sort order of objects */
+ DAG_relations_tag_update(bmain);
/* do updates */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL);
@@ -1377,7 +1385,6 @@ void OBJECT_OT_constraints_clear(wmOperatorType *ot)
static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
bPoseChannel *pchan = CTX_data_active_pose_bone(C);
/* don't do anything if bone doesn't exist or doesn't have any constraints */
@@ -1391,7 +1398,7 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
{
/* if we're not handling the object we're copying from, copy all constraints over */
if (pchan != chan) {
- copy_constraints(&chan->constraints, &pchan->constraints, TRUE);
+ BKE_copy_constraints(&chan->constraints, &pchan->constraints, TRUE);
/* update flags (need to add here, not just copy) */
chan->constflag |= pchan->constflag;
}
@@ -1399,7 +1406,7 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* force depsgraph to get recalculated since new relationships added */
- DAG_scene_sort(bmain, scene); /* sort order of objects/bones */
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL);
@@ -1424,7 +1431,6 @@ void POSE_OT_constraints_copy(wmOperatorType *ot)
static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
Object *obact = ED_object_active_context(C);
/* copy all constraints from active object to all selected objects */
@@ -1432,14 +1438,14 @@ static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
/* if we're not handling the object we're copying from, copy all constraints over */
if (obact != ob) {
- copy_constraints(&ob->constraints, &obact->constraints, TRUE);
+ BKE_copy_constraints(&ob->constraints, &obact->constraints, TRUE);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
CTX_DATA_END;
/* force depsgraph to get recalculated since new relationships added */
- DAG_scene_sort(bmain, scene); /* sort order of objects */
+ DAG_relations_tag_update(bmain);
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_ADDED, NULL);
@@ -1607,7 +1613,6 @@ static short get_new_constraint_target(bContext *C, int con_type, Object **tar_o
static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, short setTarget)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
bPoseChannel *pchan;
bConstraint *con;
@@ -1642,9 +1647,9 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
/* create a new constraint of the type requried, and add it to the active/given constraints list */
if (pchan)
- con = add_pose_constraint(ob, pchan, NULL, type);
+ con = BKE_add_pose_constraint(ob, pchan, NULL, type);
else
- con = add_ob_constraint(ob, NULL, type);
+ con = BKE_add_ob_constraint(ob, NULL, type);
/* get the first selected object/bone, and make that the target
* - apart from the buttons-window add buttons, we shouldn't add in this way
@@ -1701,7 +1706,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
/* force depsgraph to get recalculated since new relationships added */
- DAG_scene_sort(bmain, scene); /* sort order of objects */
+ DAG_relations_tag_update(bmain);
if ((ob->type == OB_ARMATURE) && (pchan)) {
ob->pose->flag |= POSE_RECALC; /* sort pose channels */
@@ -1870,7 +1875,7 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
}
/* prepare popup menu to choose targetting options */
- pup = uiPupMenuBegin(C, "Add IK", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Add IK"), ICON_NONE);
layout = uiPupMenuLayout(pup);
/* the type of targets we'll set determines the menu entries to show... */
@@ -1879,14 +1884,14 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
* - the only thing that matters is that we want a target...
*/
if (tar_pchan)
- uiItemBooleanO(layout, "To Active Bone", ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
+ uiItemBooleanO(layout, IFACE_("To Active Bone"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
else
- uiItemBooleanO(layout, "To Active Object", ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
+ uiItemBooleanO(layout, IFACE_("To Active Object"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
}
else {
/* we have a choice of adding to a new empty, or not setting any target (targetless IK) */
- uiItemBooleanO(layout, "To New Empty Object", ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
- uiItemBooleanO(layout, "Without Targets", ICON_NONE, "POSE_OT_ik_add", "with_targets", 0);
+ uiItemBooleanO(layout, IFACE_("To New Empty Object"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
+ uiItemBooleanO(layout, IFACE_("Without Targets"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 0);
}
/* finish building the menu, and process it (should result in calling self again) */
@@ -1940,7 +1945,7 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
for (con = pchan->constraints.first; con; con = next) {
next = con->next;
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
- remove_constraint(&pchan->constraints, con);
+ BKE_remove_constraint(&pchan->constraints, con);
}
}
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index d39e34824b9..b94c9e940dc 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -150,7 +150,7 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op))
}
if (changed) {
DAG_id_type_tag(bmain, ID_OB);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
@@ -207,7 +207,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op)
if (changed) {
DAG_id_type_tag(bmain, ID_OB);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
@@ -376,7 +376,7 @@ void ED_object_exit_editmode(bContext *C, int flag)
scene->obedit = NULL; // XXX for context
/* flag object caches as outdated */
- BKE_ptcache_ids_from_object(&pidlist, obedit, NULL, 0);
+ BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
for (pid = pidlist.first; pid; pid = pid->next) {
if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
pid->cache->flag |= PTCACHE_OUTDATED;
@@ -429,6 +429,10 @@ void ED_object_enter_editmode(bContext *C, int flag)
ob = base->object;
+ /* this checks actual object->data, for cases when other scenes have it in editmode context */
+ if ( BKE_object_is_in_editmode(ob) )
+ return;
+
if (BKE_object_obdata_is_libdata(ob)) {
error_libdata();
return;
@@ -767,7 +771,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
Base *base;
Curve *cu, *cu1;
Nurb *nu;
- int do_scene_sort = FALSE;
+ bool do_depgraph_update = false;
if (scene->id.lib) return;
@@ -794,7 +798,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
for (base = FIRSTBASE; base; base = base->next) {
if (base != BASACT) {
if (TESTBASELIB(v3d, base)) {
- base->object->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
if (event == 1) { /* loc */
copy_v3_v3(base->object->loc, ob->loc);
@@ -893,7 +897,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family));
- base->object->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
else if (event == 19) { /* bevel settings */
@@ -909,7 +913,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
cu1->ext1 = cu->ext1;
cu1->ext2 = cu->ext2;
- base->object->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
else if (event == 25) { /* curve resolution */
@@ -928,7 +932,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
nu = nu->next;
}
- base->object->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
else if (event == 21) {
@@ -944,15 +948,15 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
}
modifier_copyData(md, tmd);
- base->object->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
}
else if (event == 22) {
/* Copy the constraint channels over */
- copy_constraints(&base->object->constraints, &ob->constraints, TRUE);
+ BKE_copy_constraints(&base->object->constraints, &ob->constraints, TRUE);
- do_scene_sort = TRUE;
+ do_depgraph_update = true;
}
else if (event == 23) {
base->object->softflag = ob->softflag;
@@ -1004,10 +1008,8 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
}
}
- if (do_scene_sort)
- DAG_scene_sort(bmain, scene);
-
- DAG_ids_flush_update(bmain, 0);
+ if (do_depgraph_update)
+ DAG_relations_tag_update(bmain);
}
static void UNUSED_FUNCTION(copy_attr_menu) (Main * bmain, Scene * scene, View3D * v3d)
@@ -1147,7 +1149,7 @@ static int object_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *U
/* show popup dialog to allow editing of range... */
/* FIXME: hardcoded dimensions here are just arbitrary */
- return WM_operator_props_dialog_popup(C, op, 200, 200);
+ return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
}
/* Calculate/recalculate whole paths (avs.path_sf to avs.path_ef) */
@@ -1672,10 +1674,6 @@ static EnumPropertyItem game_properties_copy_operations[] = {
{0, NULL, 0, NULL, NULL}
};
-static EnumPropertyItem gameprops_items[] = {
- {0, NULL, 0, NULL, NULL}
-};
-
static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
Object *ob = ED_object_active_context(C);
@@ -1685,7 +1683,7 @@ static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), P
int a, totitem = 0;
if (!ob)
- return gameprops_items;
+ return DummyRNA_NULL_items;
for (a = 1, prop = ob->prop.first; prop; prop = prop->next, a++) {
tmp.value = a;
@@ -1756,7 +1754,7 @@ void OBJECT_OT_game_property_copy(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_enum(ot->srna, "operation", game_properties_copy_operations, 3, "Operation", "");
- prop = RNA_def_enum(ot->srna, "property", gameprops_items, 0, "Property", "Properties to copy");
+ prop = RNA_def_enum(ot->srna, "property", DummyRNA_NULL_items, 0, "Property", "Properties to copy");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
RNA_def_enum_funcs(prop, gameprops_itemf);
ot->prop = prop;
@@ -1864,9 +1862,7 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op))
ob_iter->max_vel = ob->max_vel;
ob_iter->obstacleRad = ob->obstacleRad;
ob_iter->mass = ob->mass;
- ob_iter->anisotropicFriction[0] = ob->anisotropicFriction[0];
- ob_iter->anisotropicFriction[1] = ob->anisotropicFriction[1];
- ob_iter->anisotropicFriction[2] = ob->anisotropicFriction[2];
+ copy_v3_v3(ob_iter->anisotropicFriction, ob->anisotropicFriction);
ob_iter->collision_boundtype = ob->collision_boundtype;
ob_iter->margin = ob->margin;
ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft);
@@ -1874,6 +1870,9 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op))
ob_iter->restrictflag |= OB_RESTRICT_RENDER;
else
ob_iter->restrictflag &= ~OB_RESTRICT_RENDER;
+
+ ob_iter->col_group = ob->col_group;
+ ob_iter->col_mask = ob->col_mask;
}
}
CTX_DATA_END;
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index a3bf27a19d6..3112bb21091 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -137,7 +137,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
}
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -197,7 +197,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
if (!ok) BKE_report(op->reports, RPT_ERROR, "Active object contains no groups");
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -229,7 +229,7 @@ static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op))
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -269,7 +269,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -311,15 +311,15 @@ static int group_create_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "name", name);
- group = add_group(name);
+ group = add_group(bmain, name);
- CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
+ CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
add_to_group(group, base->object, scene, base);
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -348,12 +348,13 @@ static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
+ Main *bmain = CTX_data_main(C);
Group *group;
if (ob == NULL)
return OPERATOR_CANCELLED;
- group = add_group("Group");
+ group = add_group(bmain, "Group");
add_to_group(group, ob, scene, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index caeff1e82a7..43736909c40 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -386,6 +386,31 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
}
}
+static void object_hook_from_context(bContext *C, PointerRNA *ptr, const int num,
+ Object **r_ob, HookModifierData **r_hmd)
+{
+ Object *ob;
+ HookModifierData *hmd;
+
+ if (ptr->data) { /* if modifier context is available, use that */
+ ob = ptr->id.data;
+ hmd = ptr->data;
+ }
+ else { /* use the provided property */
+ ob = CTX_data_edit_object(C);
+ hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
+ }
+
+ if (ob && hmd && (hmd->modifier.type == eModifierType_Hook)) {
+ *r_ob = ob;
+ *r_hmd = hmd;
+ }
+ else {
+ *r_ob = NULL;
+ *r_hmd = NULL;
+ }
+}
+
static void object_hook_select(Object *ob, HookModifierData *hmd)
{
if (hmd->indexar == NULL)
@@ -491,7 +516,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL,
NULL, NULL, NULL, NULL, NULL);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
return TRUE;
}
@@ -533,7 +558,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
}
}
-void OBJECT_OT_hook_add_selobj(wmOperatorType *ot)
+void OBJECT_OT_hook_add_selob(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Hook to Selected Object";
@@ -567,7 +592,7 @@ static int object_add_hook_newob_exec(bContext *C, wmOperator *op)
}
}
-void OBJECT_OT_hook_add_newobj(wmOperatorType *ot)
+void OBJECT_OT_hook_add_newob(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Hook to New Object";
@@ -663,16 +688,9 @@ static int object_hook_reset_exec(bContext *C, wmOperator *op)
int num = RNA_enum_get(op->ptr, "modifier");
Object *ob = NULL;
HookModifierData *hmd = NULL;
-
- if (ptr.data) { /* if modifier context is available, use that */
- ob = ptr.id.data;
- hmd = ptr.data;
- }
- else { /* use the provided property */
- ob = CTX_data_edit_object(C);
- hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
- }
- if (!ob || !hmd) {
+
+ object_hook_from_context(C, &ptr, num, &ob, &hmd);
+ if (hmd == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
@@ -732,15 +750,8 @@ static int object_hook_recenter_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
float bmat[3][3], imat[3][3];
- if (ptr.data) { /* if modifier context is available, use that */
- ob = ptr.id.data;
- hmd = ptr.data;
- }
- else { /* use the provided property */
- ob = CTX_data_edit_object(C);
- hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
- }
- if (!ob || !hmd) {
+ object_hook_from_context(C, &ptr, num, &ob, &hmd);
+ if (hmd == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
@@ -790,15 +801,8 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op)
char name[MAX_NAME];
int *indexar, tot;
- if (ptr.data) { /* if modifier context is available, use that */
- ob = ptr.id.data;
- hmd = ptr.data;
- }
- else { /* use the provided property */
- ob = CTX_data_edit_object(C);
- hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
- }
- if (!ob || !hmd) {
+ object_hook_from_context(C, &ptr, num, &ob, &hmd);
+ if (hmd == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
@@ -852,15 +856,8 @@ static int object_hook_select_exec(bContext *C, wmOperator *op)
Object *ob = NULL;
HookModifierData *hmd = NULL;
- if (ptr.data) { /* if modifier context is available, use that */
- ob = ptr.id.data;
- hmd = ptr.data;
- }
- else { /* use the provided property */
- ob = CTX_data_edit_object(C);
- hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
- }
- if (!ob || !hmd) {
+ object_hook_from_context(C, &ptr, num, &ob, &hmd);
+ if (hmd == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 0be9c92897e..a302aa65fd0 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -113,6 +113,7 @@ void OBJECT_OT_metaball_add(struct wmOperatorType *ot);
void OBJECT_OT_text_add(struct wmOperatorType *ot);
void OBJECT_OT_armature_add(struct wmOperatorType *ot);
void OBJECT_OT_empty_add(struct wmOperatorType *ot);
+void OBJECT_OT_drop_named_image(struct wmOperatorType *ot);
void OBJECT_OT_lamp_add(struct wmOperatorType *ot);
void OBJECT_OT_effector_add(struct wmOperatorType *ot);
void OBJECT_OT_camera_add(struct wmOperatorType *ot);
@@ -127,8 +128,8 @@ void OBJECT_OT_join_shapes(struct wmOperatorType *ot);
void OBJECT_OT_convert(struct wmOperatorType *ot);
/* object_hook.c */
-void OBJECT_OT_hook_add_selobj(struct wmOperatorType *ot);
-void OBJECT_OT_hook_add_newobj(struct wmOperatorType *ot);
+void OBJECT_OT_hook_add_selob(struct wmOperatorType *ot);
+void OBJECT_OT_hook_add_newob(struct wmOperatorType *ot);
void OBJECT_OT_hook_remove(struct wmOperatorType *ot);
void OBJECT_OT_hook_select(struct wmOperatorType *ot);
void OBJECT_OT_hook_assign(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index 4aa2e825954..c9eae776ac7 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -52,7 +52,7 @@
#include "BKE_depsgraph.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
-#include "BKE_mesh.h"
+#include "BKE_deform.h"
#include "ED_lattice.h"
#include "ED_object.h"
@@ -77,7 +77,7 @@ void free_editLatt(Object *ob)
if (editlt->def)
MEM_freeN(editlt->def);
if (editlt->dvert)
- free_dverts(editlt->dvert, editlt->pntsu * editlt->pntsv * editlt->pntsw);
+ BKE_defvert_array_free(editlt->dvert, editlt->pntsu * editlt->pntsv * editlt->pntsw);
MEM_freeN(editlt);
MEM_freeN(lt->editlatt);
@@ -104,7 +104,7 @@ void make_editLatt(Object *obedit)
if (lt->dvert) {
int tot = lt->pntsu * lt->pntsv * lt->pntsw;
lt->editlatt->latt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- copy_dverts(lt->editlatt->latt->dvert, lt->dvert, tot);
+ BKE_defvert_array_copy(lt->editlatt->latt->dvert, lt->dvert, tot);
}
if (lt->key) lt->editlatt->shapenr = obedit->shapenr;
@@ -156,7 +156,7 @@ void load_editLatt(Object *obedit)
}
if (lt->dvert) {
- free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
lt->dvert = NULL;
}
@@ -164,7 +164,7 @@ void load_editLatt(Object *obedit)
tot = lt->pntsu * lt->pntsv * lt->pntsw;
lt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- copy_dverts(lt->dvert, editlt->dvert, tot);
+ BKE_defvert_array_copy(lt->dvert, editlt->dvert, tot);
}
}
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 7d3d6861418..8d29813e2ac 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -151,10 +151,10 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
ob->pd = object_add_collision_fields(0);
ob->pd->deflect = 1;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
else if (type == eModifierType_Surface)
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
else if (type == eModifierType_Multires) {
/* set totlvl from existing MDISPS layer if object already had it */
multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
@@ -330,7 +330,7 @@ static int object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
return 1;
}
-int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
+int ED_object_modifier_remove(ReportList *reports, Main *bmain, Object *ob, ModifierData *md)
{
int sort_depsgraph = 0;
int ok;
@@ -343,15 +343,12 @@ int ED_object_modifier_remove(ReportList *reports, Main *bmain, Scene *scene, Ob
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
-
- /* sorting has to be done after the update so that dynamic systems can react properly */
- if (sort_depsgraph)
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
return 1;
}
-void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
+void ED_object_modifier_clear(Main *bmain, Object *ob)
{
ModifierData *md = ob->modifiers.first;
int sort_depsgraph = 0;
@@ -370,10 +367,7 @@ void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
-
- /* sorting has to be done after the update so that dynamic systems can react properly */
- if (sort_depsgraph)
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
@@ -391,7 +385,7 @@ int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md
}
BLI_remlink(&ob->modifiers, md);
- BLI_insertlink(&ob->modifiers, md->prev->prev, md);
+ BLI_insertlinkbefore(&ob->modifiers, md->prev, md);
}
return 1;
@@ -412,7 +406,7 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *
}
BLI_remlink(&ob->modifiers, md);
- BLI_insertlink(&ob->modifiers, md->next, md);
+ BLI_insertlinkafter(&ob->modifiers, md->next, md);
}
return 1;
@@ -522,7 +516,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
}
}
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
return 1;
}
@@ -728,7 +722,7 @@ int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierDat
nmd = modifier_new(md->type);
modifier_copyData(md, nmd);
- BLI_insertlink(&ob->modifiers, md, nmd);
+ BLI_insertlinkafter(&ob->modifiers, md, nmd);
modifier_unique_name(&ob->modifiers, nmd);
return 1;
@@ -884,7 +878,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int mode_orig = ob ? ob->mode : 0;
- if (!ob || !md || !ED_object_modifier_remove(op->reports, bmain, scene, ob, md))
+ if (!ob || !md || !ED_object_modifier_remove(op->reports, bmain, ob, md))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -1196,6 +1190,11 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ if (ob->mode & OB_MODE_SCULPT) {
+ /* ensure that grid paint mask layer is created */
+ ED_sculpt_mask_layers_ensure(ob, mmd);
+ }
return OPERATOR_FINISHED;
}
@@ -1826,7 +1825,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
arm_md->object = arm_ob;
arm_md->deformflag = ARM_DEF_VGROUP | ARM_DEF_QUATERNION;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index d19277d20a2..e5aaaffade8 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -114,6 +114,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_text_add);
WM_operatortype_append(OBJECT_OT_armature_add);
WM_operatortype_append(OBJECT_OT_empty_add);
+ WM_operatortype_append(OBJECT_OT_drop_named_image);
WM_operatortype_append(OBJECT_OT_lamp_add);
WM_operatortype_append(OBJECT_OT_camera_add);
WM_operatortype_append(OBJECT_OT_speaker_add);
@@ -217,8 +218,8 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_group_link);
WM_operatortype_append(OBJECT_OT_group_remove);
- WM_operatortype_append(OBJECT_OT_hook_add_selobj);
- WM_operatortype_append(OBJECT_OT_hook_add_newobj);
+ WM_operatortype_append(OBJECT_OT_hook_add_selob);
+ WM_operatortype_append(OBJECT_OT_hook_add_newob);
WM_operatortype_append(OBJECT_OT_hook_remove);
WM_operatortype_append(OBJECT_OT_hook_select);
WM_operatortype_append(OBJECT_OT_hook_assign);
@@ -252,15 +253,6 @@ void ED_operatormacros_object(void)
RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
}
- /* XXX */
- ot = WM_operatortype_append_macro("OBJECT_OT_add_named_cursor", "Add Named At Cursor",
- "Add named object at cursor", OPTYPE_UNDO | OPTYPE_REGISTER);
- if (ot) {
- RNA_def_string(ot->srna, "name", "Cube", MAX_ID_NAME - 2, "Name", "Object name to add");
-
- WM_operatortype_macro_define(ot, "VIEW3D_OT_cursor3d");
- WM_operatortype_macro_define(ot, "OBJECT_OT_add_named");
- }
}
static int object_mode_poll(bContext *C)
@@ -403,6 +395,12 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_all", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0);
WM_keymap_verify_item(keymap, "GROUP_OT_objects_add_active", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);
+
+ kmi = WM_keymap_add_item(keymap, "RIGIDBODY_OT_objects_add", RKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "type", 0); /* active */
+ kmi = WM_keymap_add_item(keymap, "RIGIDBODY_OT_objects_add", RKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "type", 1); /* passive */
+ WM_keymap_add_item(keymap, "RIGIDBODY_OT_objects_remove", RKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_object_specials", WKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 0988a196fb1..f9dde043607 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -35,6 +35,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
#include "DNA_constraint_types.h"
#include "DNA_group_types.h"
@@ -55,6 +56,8 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_action.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
@@ -220,7 +223,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obedit) {
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
par = obedit->parent;
while (par) {
@@ -257,7 +260,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT, NULL);
@@ -301,7 +304,7 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
else if (ob->id.lib) {
- uiPopupMenu *pup = uiPupMenuBegin(C, "OK?", ICON_QUESTION);
+ uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("OK?"), ICON_QUESTION);
uiLayout *layout = uiPupMenuLayout(pup);
/* create operator menu item with relevant properties filled in */
@@ -354,14 +357,14 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
/* remove base, leave user count of object, it gets linked in BKE_object_make_proxy */
if (gob == NULL) {
- BLI_remlink(&scene->base, oldbase);
+ BKE_scene_base_unlink(scene, oldbase);
MEM_freeN(oldbase);
}
BKE_object_make_proxy(newob, ob, gob);
/* depsgraph flushes are needed for the new data */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(&newob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob);
}
@@ -509,14 +512,13 @@ void ED_object_parent_clear(Object *ob, int type)
break;
}
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
/* note, poll should check for editable scene */
static int parent_clear_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
int type = RNA_enum_get(op->ptr, "type");
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
@@ -525,8 +527,7 @@ static int parent_clear_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
return OPERATOR_FINISHED;
@@ -578,6 +579,7 @@ EnumPropertyItem prop_make_parent_types[] = {
{PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""},
{PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""},
{PAR_BONE, "BONE", 0, "Bone", ""},
+ {PAR_BONE_RELATIVE, "BONE_RELATIVE", 0, "Bone Relative", ""},
{PAR_CURVE, "CURVE", 0, "Curve Deform", ""},
{PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""},
{PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""},
@@ -593,7 +595,7 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
bPoseChannel *pchan = NULL;
int pararm = ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO);
- par->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&par->id, OB_RECALC_OB);
/* preconditions */
if (partype == PAR_FOLLOW || partype == PAR_PATH_CONST) {
@@ -624,7 +626,7 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
partype = PAR_OBJECT;
}
}
- else if (partype == PAR_BONE) {
+ else if (ELEM(partype, PAR_BONE, PAR_BONE_RELATIVE)) {
pchan = BKE_pose_channel_active(par);
if (pchan == NULL) {
@@ -705,8 +707,16 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
}
}
}
- else if (partype == PAR_BONE)
+ else if (partype == PAR_BONE) {
+ ob->partype = PARBONE; /* note, dna define, not operator property */
+ if (pchan->bone)
+ pchan->bone->flag &= ~BONE_RELATIVE_PARENTING;
+ }
+ else if (partype == PAR_BONE_RELATIVE) {
ob->partype = PARBONE; /* note, dna define, not operator property */
+ if (pchan->bone)
+ pchan->bone->flag |= BONE_RELATIVE_PARENTING;
+ }
else
ob->partype = PAROBJECT; /* note, dna define, not operator property */
@@ -716,12 +726,12 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
bFollowPathConstraint *data;
float cmat[4][4], vec[3];
- con = add_ob_constraint(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
+ con = BKE_add_ob_constraint(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
data = con->data;
data->tar = par;
- get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
+ BKE_get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
sub_v3_v3v3(vec, ob->obmat[3], cmat[3]);
ob->loc[0] = vec[0];
@@ -750,7 +760,7 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
invert_m4_m4(ob->parentinv, workob.obmat);
}
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
}
}
@@ -779,8 +789,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
if (!ok)
return OPERATOR_CANCELLED;
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
@@ -791,7 +800,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
{
Object *ob = ED_object_active_context(C);
- uiPopupMenu *pup = uiPupMenuBegin(C, "Set Parent To", ICON_NONE);
+ uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_parent_set", TRUE);
@@ -800,11 +809,12 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSE
#if 0
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_OBJECT);
#else
- opptr = uiItemFullO_ptr(layout, ot, "Object", ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
+ opptr = uiItemFullO_ptr(layout, ot, IFACE_("Object"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "type", PAR_OBJECT);
RNA_boolean_set(&opptr, "keep_transform", FALSE);
- opptr = uiItemFullO_ptr(layout, ot, "Object (Keep Transform)", ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
+ opptr = uiItemFullO_ptr(layout, ot, IFACE_("Object (Keep Transform)"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT,
+ UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "type", PAR_OBJECT);
RNA_boolean_set(&opptr, "keep_transform", TRUE);
#endif
@@ -815,6 +825,7 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSE
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_ARMATURE_ENVELOPE);
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_ARMATURE_AUTO);
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_BONE);
+ uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_BONE_RELATIVE);
}
else if (ob->type == OB_CURVE) {
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_CURVE);
@@ -889,7 +900,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Object *par = ED_object_active_context(C);
- par->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&par->id, OB_RECALC_OB);
/* context iterator */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
@@ -904,7 +915,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op)
memset(ob->loc, 0, 3 * sizeof(float));
/* set recalc flags */
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
/* set parenting type for object - object only... */
ob->parent = par;
@@ -914,8 +925,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_scene_sort(bmain, CTX_data_scene(C));
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
@@ -941,7 +951,6 @@ void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot)
static int object_slow_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
@@ -951,13 +960,12 @@ static int object_slow_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
ob->partype -= PARSLOW;
BKE_object_where_is_calc(scene, ob);
ob->partype |= PARSLOW;
- ob->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
}
CTX_DATA_END;
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SCENE, scene);
return OPERATOR_FINISHED;
@@ -984,7 +992,6 @@ void OBJECT_OT_slow_parent_clear(wmOperatorType *ot)
static int object_slow_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
@@ -992,12 +999,11 @@ static int object_slow_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
if (ob->parent)
ob->partype |= PARSLOW;
- ob->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SCENE, scene);
return OPERATOR_FINISHED;
@@ -1032,7 +1038,6 @@ static EnumPropertyItem prop_clear_track_types[] = {
static int object_track_clear_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
int type = RNA_enum_get(op->ptr, "type");
if (CTX_data_edit_object(C)) {
@@ -1045,13 +1050,13 @@ static int object_track_clear_exec(bContext *C, wmOperator *op)
/* remove track-object for old track */
ob->track = NULL;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* also remove all tracking constraints */
for (con = ob->constraints.last; con; con = pcon) {
pcon = con->prev;
if (ELEM3(con->type, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_DAMPTRACK))
- remove_constraint(&ob->constraints, con);
+ BKE_remove_constraint(&ob->constraints, con);
}
if (type == 1)
@@ -1059,8 +1064,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_ids_flush_update(bmain, 0);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
@@ -1069,7 +1073,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op)
void OBJECT_OT_track_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Clear track";
+ ot->name = "Clear Track";
ot->description = "Clear tracking constraint or flag from object";
ot->idname = "OBJECT_OT_track_clear";
@@ -1097,7 +1101,6 @@ static EnumPropertyItem prop_make_track_types[] = {
static int track_set_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
Object *obact = ED_object_active_context(C);
int type = RNA_enum_get(op->ptr, "type");
@@ -1109,11 +1112,11 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK);
+ con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK);
data = con->data;
data->tar = obact;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* Lamp, Camera and Speaker track differently by default */
if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER)
@@ -1129,11 +1132,11 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
+ con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
data = con->data;
data->tar = obact;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* Lamp, Camera and Speaker track differently by default */
if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) {
@@ -1151,11 +1154,11 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK);
+ con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK);
data = con->data;
data->tar = obact;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* Lamp, Camera and Speaker track differently by default */
if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) {
@@ -1167,8 +1170,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
@@ -1283,7 +1285,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
}
@@ -1346,7 +1348,6 @@ Base *ED_object_scene_link(Scene *scene, Object *ob)
static int make_links_scene_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
if (scene_to == NULL) {
@@ -1370,8 +1371,6 @@ static int make_links_scene_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_ids_flush_update(bmain, 0);
-
/* redraw the 3D view because the object center points are colored differently */
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
@@ -1462,7 +1461,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
/* if amount of material indices changed: */
test_object_materials(ob_dst->data);
- ob_dst->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
break;
case MAKE_LINKS_MATERIALS:
/* new approach, using functions from kernel */
@@ -1501,7 +1500,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
break;
case MAKE_LINKS_MODIFIERS:
BKE_object_link_modifiers(ob_dst, ob_src);
- ob_dst->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
break;
case MAKE_LINKS_FONTS:
{
@@ -1521,7 +1520,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
cu_dst->vfontbi = cu_src->vfontbi;
id_us_plus((ID *)cu_dst->vfontbi);
- ob_dst->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
break;
}
}
@@ -1540,10 +1539,9 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
}
}
- DAG_scene_sort(bmain, scene);
-
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+
return OPERATOR_FINISHED;
}
@@ -1692,7 +1690,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, int flag)
id = ob->data;
if (id && id->us > 1 && id->lib == NULL) {
- ob->recalc = OB_RECALC_DATA;
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
BKE_copy_animdata_id_action(id);
@@ -1728,7 +1726,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, int flag)
ob->data = BKE_lattice_copy(ob->data);
break;
case OB_ARMATURE:
- ob->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
ob->data = BKE_armature_copy(ob->data);
BKE_pose_rebuild(ob, ob->data);
break;
@@ -1764,7 +1762,7 @@ static void single_object_action_users(Scene *scene, int flag)
for (base = FIRSTBASE; base; base = base->next) {
ob = base->object;
if (ob->id.lib == NULL && (flag == 0 || (base->flag & SELECT)) ) {
- ob->recalc = OB_RECALC_DATA;
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
BKE_copy_animdata_id_action(&ob->id);
}
}
@@ -2134,7 +2132,6 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot)
static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- Main *bmain = CTX_data_main(C);
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
Material *ma;
char name[MAX_ID_NAME - 2];
@@ -2146,7 +2143,6 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *even
assign_material(base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF);
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
@@ -2168,7 +2164,7 @@ void OBJECT_OT_drop_named_material(wmOperatorType *ot)
ot->poll = ED_operator_objectmode;
/* flags */
- ot->flag = OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
RNA_def_string(ot->srna, "name", "Material", MAX_ID_NAME - 2, "Name", "Material name to assign");
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 2aa737d204d..baa0199baf7 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -42,6 +42,7 @@
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_armature_types.h"
+#include "DNA_lamp_types.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
@@ -49,6 +50,8 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_group.h"
#include "BKE_main.h"
@@ -525,6 +528,8 @@ static EnumPropertyItem prop_select_grouped_types[] = {
{10, "COLOR", 0, "Color", "Object Color"},
{11, "PROPERTIES", 0, "Properties", "Game Properties"},
{12, "KEYINGSET", 0, "Keying Set", "Objects included in active Keying Set"},
+ {13, "LAMP_TYPE", 0, "Lamp Type", "Matching lamp types"},
+ {14, "PASS_INDEX", 0, "Pass Index", "Matching object pass index"},
{0, NULL, 0, NULL, NULL}
};
@@ -603,7 +608,7 @@ static short select_grouped_group(bContext *C, Object *ob) /* Select objects in
}
/* build the menu. */
- pup = uiPupMenuBegin(C, "Select Group", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Select Group"), ICON_NONE);
layout = uiPupMenuLayout(pup);
for (i = 0; i < group_count; i++) {
@@ -656,7 +661,39 @@ static short select_grouped_siblings(bContext *C, Object *ob)
CTX_DATA_END;
return changed;
}
+static short select_similar_lamps(bContext *C, Object *ob)
+{
+ Lamp *la = ob->data;
+
+ short changed = 0;
+
+ CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
+ {
+ if (base->object->type == OB_LAMP) {
+ Lamp *la_test = base->object->data;
+ if ((la->type == la_test->type) && !(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
+static short select_similar_pass_index(bContext *C, Object *ob)
+{
+ char changed = 0;
+ CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
+ {
+ if ((base->object->index == ob->index) && !(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
static short select_grouped_type(bContext *C, Object *ob)
{
short changed = 0;
@@ -803,7 +840,12 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active object");
return OPERATOR_CANCELLED;
}
-
+
+ if (nr == 13 && ob->type != OB_LAMP) {
+ BKE_report(op->reports, RPT_ERROR, "Active object must be a lamp");
+ return OPERATOR_CANCELLED;
+ }
+
if (nr == 1) changed |= select_grouped_children(C, ob, 1);
else if (nr == 2) changed |= select_grouped_children(C, ob, 0);
else if (nr == 3) changed |= select_grouped_parent(C);
@@ -816,7 +858,9 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
else if (nr == 10) changed |= select_grouped_color(C, ob);
else if (nr == 11) changed |= select_grouped_gameprops(C, ob);
else if (nr == 12) changed |= select_grouped_keyingset(C, ob);
-
+ else if (nr == 13) changed |= select_similar_lamps(C, ob);
+ else if (nr == 14) changed |= select_similar_pass_index(C, ob);
+
if (changed) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 900bf57b509..01dcac2d1b4 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -57,6 +57,7 @@
#include "BKE_tessmesh.h"
#include "BKE_multires.h"
#include "BKE_armature.h"
+#include "BKE_lattice.h"
#include "RNA_define.h"
#include "RNA_access.h"
@@ -66,6 +67,7 @@
#include "ED_armature.h"
#include "ED_keyframing.h"
+#include "ED_mball.h"
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
@@ -211,7 +213,6 @@ static void object_clear_scale(Object *ob)
static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
void (*clear_func)(Object *), const char default_ksName[])
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks;
@@ -242,8 +243,6 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
CTX_DATA_END;
/* this is needed so children are also updated */
- DAG_ids_flush_update(bmain, 0);
-
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
@@ -316,7 +315,6 @@ void OBJECT_OT_scale_clear(wmOperatorType *ot)
static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
float *v1, *v3;
float mat[3][3];
@@ -336,8 +334,6 @@ static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op))
}
CTX_DATA_END;
- DAG_ids_flush_update(bmain, 0);
-
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
@@ -406,6 +402,12 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
change = 0;
}
}
+ else if (ob->type == OB_MBALL) {
+ if (ID_REAL_USERS(ob->data) > 1) {
+ BKE_report(reports, RPT_ERROR, "Cannot apply to a multi user metaball, doing nothing");
+ change = 0;
+ }
+ }
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu;
@@ -416,7 +418,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
cu = ob->data;
- if (!(cu->flag & CU_3D) && (apply_rot || apply_loc)) {
+ if (((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) && (apply_rot || apply_loc)) {
BKE_report(reports, RPT_ERROR,
"Neither rotation nor location could be applied to a 2D curve, doing nothing");
change = 0;
@@ -447,7 +449,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
float tmat[3][3], timat[3][3];
/* simple rotation matrix */
- BKE_object_rot_to_mat3(ob, rsmat);
+ BKE_object_rot_to_mat3(ob, rsmat, TRUE);
/* correct for scale, note mul_m3_m3m3 has swapped args! */
BKE_object_scale_to_mat3(ob, tmat);
@@ -515,6 +517,10 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
bp++;
}
}
+ else if (ob->type == OB_MBALL) {
+ MetaBall *mb = ob->data;
+ ED_mball_transform(mb, (float *)mat);
+ }
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
@@ -699,9 +705,11 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
}
else {
if (around == V3D_CENTROID) {
- const float total_div = 1.0f / (float)em->bm->totvert;
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- madd_v3_v3fl(cent, eve->co, total_div);
+ if (em->bm->totvert) {
+ const float total_div = 1.0f / (float)em->bm->totvert;
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ madd_v3_v3fl(cent, eve->co, total_div);
+ }
}
}
else {
@@ -899,6 +907,20 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
break;
}
}
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = ob->data;
+
+ if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ else if (around == V3D_CENTROID) { BKE_lattice_center_median(lt, cent); }
+ else { BKE_lattice_center_bounds(lt, cent); }
+
+ negate_v3_v3(cent_neg, cent);
+ BKE_lattice_translate(lt, cent_neg, 1);
+
+ tot_change++;
+ lt->id.flag |= LIB_DOIT;
+ do_inverse_offset = TRUE;
+ }
/* offset other selected objects */
if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
@@ -963,7 +985,6 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
DAG_id_tag_update(&tob->id, OB_RECALC_OB | OB_RECALC_DATA);
if (tot_change) {
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 1b135c0686e..87ff42ef4db 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -65,6 +65,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -81,13 +82,14 @@ 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 int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const short use_vert_sel);
static int vertex_group_use_vert_sel(Object *ob)
{
if (ob->mode == OB_MODE_EDIT) {
return TRUE;
}
- else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) {
+ else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) {
return TRUE;
}
else {
@@ -182,6 +184,29 @@ int ED_vgroup_data_create(ID *id)
}
}
+/**
+ * Removes out of range MDeformWeights
+ */
+void ED_vgroup_data_clamp_range(ID *id, const int total)
+{
+ MDeformVert **dvert_arr;
+ int dvert_tot;
+
+ if (ED_vgroup_give_parray(id, &dvert_arr, &dvert_tot, false)) {
+ int i;
+ for (i = 0; i < dvert_tot; i++) {
+ MDeformVert *dv = dvert_arr[i];
+ int j;
+ for (j = 0; j < dv->totweight; j++) {
+ if (dv->dw[j].def_nr >= total) {
+ defvert_remove_group(dv, &dv->dw[j]);
+ j--;
+ }
+ }
+ }
+ }
+}
+
static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const short use_vert_sel)
{
*dvert_tot = 0;
@@ -400,26 +425,34 @@ typedef enum WT_ReplaceMode {
} 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"},
+ {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"},
+ {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"},
+ {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}
};
-/*copy weight*/
+/* Copy weight.*/
static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode)
{
switch (replace_mode) {
@@ -439,7 +472,9 @@ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src,
}
}
-/* could be exposed externally */
+/* 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 int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene,
WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op)
{
@@ -457,53 +492,52 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
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);
- /* create new and overwrite vertex group on destination without data */
+ /* Ensure vertex group on target.*/
if (!defgroup_find_name(ob_dst, dg_src->name)) {
- ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
ED_vgroup_add_name(ob_dst, dg_src->name);
}
- /* get destination deformgroup */
+ /* Get destination deformgroup.*/
dg_dst = defgroup_find_name(ob_dst, dg_src->name);
- /* get meshes */
+ /* Get meshes.*/
dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH);
me_dst = ob_dst->data;
me_src = ob_src->data;
- /* sanity check */
+ /* Sanity check.*/
if (!me_src->dvert) {
BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)");
return 0;
}
- /* create data in memory when nothing there */
+ /* Create data in memory when nothing there.*/
if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data);
- /* get vertex group arrays */
+ /* Get vertex group arrays.*/
ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel);
- /* get indexes of vertex groups */
+ /* 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 */
+ /* Get vertices.*/
mv_dst = me_dst->mvert;
mv_src = dmesh_src->getVertArray(dmesh_src);
- /* prepare transformation matrix */
+ /* Prepare transformation matrix.*/
invert_m4_m4(ob_src->imat, ob_src->obmat);
mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
- /* clear weights */
+ /* 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 */
+ /* Remove vertex from group.*/
if (dw_dst) defvert_remove_group(*dv_dst, dw_dst);
}
}
@@ -511,7 +545,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
switch (method) {
case WT_BY_INDEX:
- /* check if indices are matching, delete and return if not */
+ /* 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)
{
@@ -523,14 +557,15 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
return 0;
}
- /* 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++) {
+ /* 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 */
+ /* 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);
@@ -540,29 +575,30 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
break;
case WT_BY_NEAREST_VERTEX:
- /* make node tree */
+ /* Make node tree.*/
bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6);
- /* loop trough vertices */
+ /* 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 */
+ /* Reset nearest.*/
nearest.dist = FLT_MAX;
- /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ /* It is faster to start searching at the top of the tree instead of previous search result.*/
nearest.index = -1;
- /* transform into target space */
+ /* Transform into target space.*/
mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
- /* node tree accelerated search for closest vetex */
+ /* 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. Existing target weights are overwritten prior to this in relevant cases. */
+ /* 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);
@@ -570,105 +606,108 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
}
}
- /* free memory */
+ /* Free memory.*/
free_bvhtree_from_mesh(&tree_mesh_vertices_src);
break;
case WT_BY_NEAREST_FACE:
- /* get faces */
+ /* Get faces.*/
DM_ensure_tessface(dmesh_src);
mface_src = dmesh_src->getTessFaceArray(dmesh_src);
- /* make node tree */
+ /* Make node tree.*/
bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
- /* loop through the vertices */
+ /* 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 */
+ /* Reset nearest.*/
nearest.dist = FLT_MAX;
- /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ /* It is faster to start searching at the top of the tree instead of previous search result.*/
nearest.index = -1;
- /* transform into target space */
+ /* Transform into target space.*/
mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
- /* node tree accelerated search for closest face */
+ /* 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 */
+ /* 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*/
+ /* Interpolate weights over face.*/
f_index = mf->v4 ? 3 : 2;
if (f_index == 3) {
- interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co);
+ interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co,
+ mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co);
}
else {
- interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co);
+ interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co,
+ mv_src[mf->v3].co, NULL, tmp_co);
}
- /* get weights from face*/
+ /* Get weights from face.*/
weight = 0;
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. Existing target weights are overwritten prior to this in relevant cases. */
+ /* 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) {
dw_dst = defvert_verify_index(*dv_dst, index_dst);
vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode);
}
}
- /* free memory */
+ /* Free memory.*/
free_bvhtree_from_mesh(&tree_mesh_faces_src);
break;
case WT_BY_NEAREST_VERTEX_IN_FACE:
- /* get faces */
+ /* Get faces.*/
DM_ensure_tessface(dmesh_src);
mface_src = dmesh_src->getTessFaceArray(dmesh_src);
- /* make node tree */
+ /* Make node tree.*/
bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
- /* loop through the vertices */
+ /* 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 */
+ /* Reset nearest.*/
nearest.dist = FLT_MAX;
- /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ /* It is faster to start searching at the top of the tree instead of previous search result.*/
nearest.index = -1;
- /* transform into target space */
+ /* Transform into target space.*/
mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
- /* node tree accelerated search for closest face */
+ /* 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 */
+ /* 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 */
+ /* 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;
@@ -680,7 +719,8 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
}
}
- /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+ /* 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);
@@ -688,7 +728,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
}
}
- /* free memory */
+ /* Free memory.*/
free_bvhtree_from_mesh(&tree_mesh_faces_src);
break;
@@ -697,7 +737,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
break;
}
- /*free memory*/
+ /* 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);
@@ -1394,7 +1434,7 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength,
Mesh *me = ob->data;
MVert *mvert = me->mvert;
int *verts = NULL;
- if (!(me->editflag & ME_EDIT_VERT_SEL))
+ if (!(me->editflag & ME_EDIT_PAINT_VERT_SEL))
return;
for (i = 0; i < me->totvert && mvert; i++, mvert++) {
if (mvert->flag & SELECT) {
@@ -1516,16 +1556,30 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
}
}
+enum {
+ VGROUP_TOGGLE,
+ VGROUP_LOCK,
+ VGROUP_UNLOCK,
+ VGROUP_INVERT
+};
+
+static EnumPropertyItem vgroup_lock_actions[] = {
+ {VGROUP_TOGGLE, "TOGGLE", 0, "Toggle", "Unlock all vertex groups if there is at least one locked group, lock all in other case"},
+ {VGROUP_LOCK, "LOCK", 0, "Lock", "Lock all vertex groups"},
+ {VGROUP_UNLOCK, "UNLOCK", 0, "Unlock", "Unlock all vertex groups"},
+ {VGROUP_INVERT, "INVERT", 0, "Invert", "Invert the lock state of all vertex groups"},
+ {0, NULL, 0, NULL, NULL}
+};
static void vgroup_lock_all(Object *ob, int action)
{
bDeformGroup *dg;
- if (action == SEL_TOGGLE) {
- action = SEL_SELECT;
+ if (action == VGROUP_TOGGLE) {
+ action = VGROUP_LOCK;
for (dg = ob->defbase.first; dg; dg = dg->next) {
if (dg->flag & DG_LOCK_WEIGHT) {
- action = SEL_DESELECT;
+ action = VGROUP_UNLOCK;
break;
}
}
@@ -1533,13 +1587,13 @@ static void vgroup_lock_all(Object *ob, int action)
for (dg = ob->defbase.first; dg; dg = dg->next) {
switch (action) {
- case SEL_SELECT:
+ case VGROUP_LOCK:
dg->flag |= DG_LOCK_WEIGHT;
break;
- case SEL_DESELECT:
+ case VGROUP_UNLOCK:
dg->flag &= ~DG_LOCK_WEIGHT;
break;
- case SEL_INVERT:
+ case VGROUP_INVERT:
dg->flag ^= DG_LOCK_WEIGHT;
break;
}
@@ -2041,7 +2095,7 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v
/* object mode / weight paint */
MVert *mv, *mv_mirr;
int vidx, vidx_mirr;
- const int use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
if (me->dvert == NULL) {
goto cleanup;
@@ -2695,7 +2749,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
/* identifiers */
ot->name = "Remove from Vertex Group";
ot->idname = "OBJECT_OT_vertex_group_remove_from";
- ot->description = "Remove the selected vertices from the active vertex group";
+ ot->description = "Remove the selected vertices from active or all vertex group(s)";
/* api callbacks */
ot->poll = vertex_group_poll_edit_or_wpaint_vert_select;
@@ -2963,7 +3017,7 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_select_all(ot);
+ RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", "Lock action to execute on vertex groups");
}
static int vertex_group_invert_exec(bContext *C, wmOperator *op)
@@ -3097,7 +3151,7 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, 1.0, "Limit", "Remove weights under this limit", 0.001f, 0.99f);
+ RNA_def_float(ot->srna, "limit", 0.0f, 0.0f, 1.0, "Limit", "Remove weights under this limit", 0.0f, 0.99f);
RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Clean all vertex groups");
RNA_def_boolean(ot->srna, "keep_single", FALSE, "Keep Single",
"Keep verts assigned to at least one group when cleaning");
@@ -3274,7 +3328,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
WT_Method method = RNA_enum_get(op->ptr, "WT_method");
WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode");
- /* Macro to loop through selected objects and perform operation depending on function, option and method */
+ /* Macro to loop through selected objects and perform operation depending on function, option and method.*/
CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects)
{
@@ -3282,8 +3336,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
switch (vertex_group_mode) {
case WT_REPLACE_ACTIVE_VERTEX_GROUP:
- if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
- BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1),
+ if (!ed_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1),
scene, method, replace_mode, op))
{
fail++;
@@ -3292,9 +3345,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
case WT_REPLACE_ALL_VERTEX_GROUPS:
for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) {
- if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
- dg_src, scene, method, replace_mode, op))
- {
+ if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) {
fail++;
}
}
@@ -3307,7 +3358,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
}
}
- /* Event notifiers for correct display of data */
+ /* Event notifiers for correct display of data.*/
DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data);
@@ -3325,28 +3376,24 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
/* transfers weight from active to selected */
void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot)
{
- /* identifiers */
+ /* 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 */
+ /* API callbacks.*/
ot->poll = vertex_group_poll;
ot->exec = vertex_group_transfer_weight_exec;
- /* flags */
+ /* Flags.*/
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
+ /* Properties.*/
ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", "");
ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", "");
ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", "");
}
-static EnumPropertyItem vgroup_items[] = {
- {0, NULL, 0, NULL, NULL}
-};
-
static int set_active_group_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3370,7 +3417,7 @@ static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *UNUSED(ptr), Prop
int a, totitem = 0;
if (!ob)
- return vgroup_items;
+ return DummyRNA_NULL_items;
for (a = 0, def = ob->defbase.first; def; def = def->next, a++) {
tmp.value = a;
@@ -3404,7 +3451,7 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active");
+ prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "Vertex group to set as active");
RNA_def_enum_funcs(prop, vgroup_itemf);
ot->prop = prop;
}
diff --git a/source/blender/editors/physics/CMakeLists.txt b/source/blender/editors/physics/CMakeLists.txt
index da12a26e747..29d8aec4224 100644
--- a/source/blender/editors/physics/CMakeLists.txt
+++ b/source/blender/editors/physics/CMakeLists.txt
@@ -43,6 +43,9 @@ set(SRC
physics_fluid.c
physics_ops.c
physics_pointcache.c
+ rigidbody_constraint.c
+ rigidbody_object.c
+ rigidbody_world.c
physics_intern.h
)
@@ -59,4 +62,11 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_BULLET)
+ list(APPEND INC
+ ../../../../intern/rigidbody
+ )
+ add_definitions(-DWITH_BULLET)
+endif()
+
blender_add_lib(bf_editor_physics "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript
index fffe05d6a0d..7916ea24bde 100644
--- a/source/blender/editors/physics/SConscript
+++ b/source/blender/editors/physics/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
@@ -7,6 +33,7 @@ incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../gpu ../../blenloader ../../bmesh'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
+incs += ' #/intern/rigidbody'
defs = []
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index c51b3ca4c43..48316cfccb7 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -172,8 +172,8 @@ static int type_toggle_exec(bContext *C, wmOperator *op)
/* update dependency */
DAG_id_tag_update(&cObject->id, OB_RECALC_DATA);
+ DAG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, cObject);
- DAG_scene_sort(CTX_data_main(C), scene);
return OPERATOR_FINISHED;
}
@@ -304,7 +304,9 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf
if (blender_test_break()) return 0;
/* Update progress bar cursor */
- WM_cursor_time(win, (int)progress);
+ if (!G.background) {
+ WM_cursor_time(win, (int)progress);
+ }
/* calculate a frame */
scene->r.cfra = (int)frame;
@@ -346,6 +348,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf
*/
static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op)
{
+ wmWindow *win = CTX_wm_window(C);
DynamicPaintModifierData *pmd = NULL;
DynamicPaintCanvasSettings *canvas;
Object *ob = ED_object_context(C);
@@ -379,7 +382,9 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op)
status = dynamicPaint_bakeImageSequence(C, surface, ob);
/* Clear bake */
canvas->flags &= ~MOD_DPAINT_BAKING;
- WM_cursor_restore(CTX_wm_window(C));
+ if (!G.background) {
+ WM_cursor_restore(win);
+ }
dynamicPaint_freeSurfaceData(surface);
/* Bake was successful:
diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c
index dc309ec3c31..8a5f623c533 100644
--- a/source/blender/editors/physics/particle_boids.c
+++ b/source/blender/editors/physics/particle_boids.c
@@ -100,7 +100,6 @@ void BOID_OT_rule_add(wmOperatorType *ot)
static int rule_del_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings);
ParticleSettings *part = ptr.data;
BoidRule *rule;
@@ -123,7 +122,7 @@ static int rule_del_exec(bContext *C, wmOperator *UNUSED(op))
if (rule)
rule->flag |= BOIDRULE_CURRENT;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
return OPERATOR_FINISHED;
@@ -158,7 +157,7 @@ static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op))
for (rule = state->rules.first; rule; rule=rule->next) {
if (rule->flag & BOIDRULE_CURRENT && rule->prev) {
BLI_remlink(&state->rules, rule);
- BLI_insertlink(&state->rules, rule->prev->prev, rule);
+ BLI_insertlinkbefore(&state->rules, rule->prev, rule);
DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
break;
@@ -194,7 +193,7 @@ static int rule_move_down_exec(bContext *C, wmOperator *UNUSED(op))
for (rule = state->rules.first; rule; rule=rule->next) {
if (rule->flag & BOIDRULE_CURRENT && rule->next) {
BLI_remlink(&state->rules, rule);
- BLI_insertlink(&state->rules, rule->next, rule);
+ BLI_insertlinkafter(&state->rules, rule->next, rule);
DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
break;
@@ -254,7 +253,6 @@ void BOID_OT_state_add(wmOperatorType *ot)
static int state_del_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings);
ParticleSettings *part = ptr.data;
BoidState *state;
@@ -280,7 +278,7 @@ static int state_del_exec(bContext *C, wmOperator *UNUSED(op))
state->flag |= BOIDSTATE_CURRENT;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
return OPERATOR_FINISHED;
@@ -316,7 +314,7 @@ static int state_move_up_exec(bContext *C, wmOperator *UNUSED(op))
for (state = boids->states.first; state; state=state->next) {
if (state->flag & BOIDSTATE_CURRENT && state->prev) {
BLI_remlink(&boids->states, state);
- BLI_insertlink(&boids->states, state->prev->prev, state);
+ BLI_insertlinkbefore(&boids->states, state->prev, state);
break;
}
}
@@ -351,7 +349,7 @@ static int state_move_down_exec(bContext *C, wmOperator *UNUSED(op))
for (state = boids->states.first; state; state=state->next) {
if (state->flag & BOIDSTATE_CURRENT && state->next) {
BLI_remlink(&boids->states, state);
- BLI_insertlink(&boids->states, state->next, state);
+ BLI_insertlinkafter(&boids->states, state->next, state);
DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
break;
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index f5754297e9f..31079de275e 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -53,10 +53,9 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_depsgraph.h"
-
#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_mesh.h"
@@ -193,6 +192,16 @@ ParticleEditSettings *PE_settings(Scene *scene)
return scene->toolsettings ? &scene->toolsettings->particle : NULL;
}
+static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *brush)
+{
+ // here we can enable unified brush size, needs more work...
+ // UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ // float size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
+
+ return brush->size * U.pixelsize;
+}
+
+
/* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set
*
* note: this function runs on poll, therefor it can runs many times a second
@@ -412,7 +421,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
/* used to calculate here but all callers have the screen_co already, so pass as arg */
#if 0
if (ED_view3d_project_int_global(data->vc.ar, co, screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK)
{
return 0;
}
@@ -516,7 +525,7 @@ static int point_is_selected(PTCacheEditPoint *point)
typedef void (*ForPointFunc)(PEData *data, int point_index);
typedef void (*ForKeyFunc)(PEData *data, int point_index, int key_index);
-typedef void (*ForKeyMatFunc)(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key);
+typedef void (*ForKeyMatFunc)(PEData *data, float mat[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key);
static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest)
{
@@ -1103,7 +1112,7 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys)
mul_v3_fl(vec, 0.25);
}
else
- mul_v3_fl(vec, 0.3333f);
+ mul_v3_fl(vec, 1.0f / 3.0f);
normalize_v3(nor);
@@ -1995,7 +2004,7 @@ static int rekey_exec(bContext *C, wmOperator *op)
PE_set_data(C, &data);
data.dval= 1.0f / (float)(data.totrekey-1);
- data.totrekey= RNA_int_get(op->ptr, "keys");
+ data.totrekey= RNA_int_get(op->ptr, "keys_number");
foreach_selected_point(&data, rekey_particle);
@@ -2022,7 +2031,7 @@ void PARTICLE_OT_rekey(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- RNA_def_int(ot->srna, "keys", 2, 2, INT_MAX, "Number of Keys", "", 2, 100);
+ RNA_def_int(ot->srna, "keys_number", 2, 2, INT_MAX, "Number of Keys", "", 2, 100);
}
static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float path_time)
@@ -2500,7 +2509,8 @@ void PARTICLE_OT_weight_set(wmOperatorType *ot)
static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
{
- ParticleEditSettings *pset= PE_settings(CTX_data_scene(C));
+ Scene *scene = CTX_data_scene(C);
+ ParticleEditSettings *pset= PE_settings(scene);
ParticleBrushData *brush;
if (pset->brushtype < 0)
@@ -2516,7 +2526,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
glColor4ub(255, 255, 255, 128);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
+ glutil_draw_lined_arc(0.0, M_PI*2.0, pe_brush_size_get(scene, brush), 40);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
@@ -2766,7 +2776,7 @@ void PARTICLE_OT_mirror(wmOperatorType *ot)
/************************* brush edit callbacks ********************/
-static void brush_comb(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key)
+static void brush_comb(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key)
{
ParticleEditSettings *pset= PE_settings(data->scene);
float cvec[3], fac;
@@ -2802,7 +2812,7 @@ static void brush_cut(PEData *data, int pa_index)
if (edit->points[pa_index].flag & PEP_HIDE)
return;
- if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK)
+ if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK)
return;
rad2= data->rad * data->rad;
@@ -2827,7 +2837,7 @@ static void brush_cut(PEData *data, int pa_index)
/* calculate path time closest to root that was inside the circle */
for (k=1, key++; k<=keys; k++, key++) {
- if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) ||
+ if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK) ||
key_test_depth(data, key->co, screen_co) == 0)
{
x0 = (float)screen_co[0];
@@ -3038,7 +3048,7 @@ static void brush_puff(PEData *data, int point_index)
}
-static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNUSED(imat[][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key))
+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 */
if (key_index) {
@@ -3052,7 +3062,7 @@ static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNU
}
}
-static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key)
+static void brush_smooth_get(PEData *data, float mat[4][4], float UNUSED(imat[4][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key)
{
if (key_index) {
float dvec[3];
@@ -3064,7 +3074,7 @@ static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4
}
}
-static void brush_smooth_do(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key)
+static void brush_smooth_do(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key)
{
float vec[3], dvec[3];
@@ -3244,7 +3254,7 @@ static int brush_add(PEData *data, short number)
ParticleEditSettings *pset= PE_settings(scene);
int i, k, n= 0, totpart= psys->totpart;
float mco[2];
- short dmx= 0, dmy= 0;
+ float dmx, dmy;
float co1[3], co2[3], min_d, imat[4][4];
float framestep, timestep;
short size= pset->brush[PE_BRUSH_ADD].size;
@@ -3272,12 +3282,19 @@ static int brush_add(PEData *data, short number)
for (i=0; i<number; i++) {
if (number>1) {
- dmx=dmy=size;
- while (dmx*dmx+dmy*dmy>size2) {
- dmx=(short)((2.0f*BLI_frand()-1.0f)*size);
- dmy=(short)((2.0f*BLI_frand()-1.0f)*size);
+ dmx = size;
+ dmy = size;
+
+ /* rejection sampling to get points in circle */
+ while (dmx*dmx + dmy*dmy > size2) {
+ dmx= (2.0f*BLI_frand() - 1.0f)*size;
+ dmy= (2.0f*BLI_frand() - 1.0f)*size;
}
}
+ else {
+ dmx = 0.0f;
+ dmy = 0.0f;
+ }
mco[0] = data->mval[0] + dmx;
mco[1] = data->mval[1] + dmy;
@@ -3297,8 +3314,8 @@ static int brush_add(PEData *data, short number)
int newtotpart=totpart+n;
float hairmat[4][4], cur_co[3];
KDTree *tree=0;
- ParticleData *pa, *new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new");
- PTCacheEditPoint *point, *new_points= MEM_callocN(newtotpart*sizeof(PTCacheEditPoint), "PTCacheEditPoint array new");
+ ParticleData *pa, *new_pars = MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new");
+ PTCacheEditPoint *point, *new_points = MEM_callocN(newtotpart*sizeof(PTCacheEditPoint), "PTCacheEditPoint array new");
PTCacheEditKey *key;
HairKey *hkey;
@@ -3333,8 +3350,8 @@ static int brush_add(PEData *data, short number)
edit->totpoint= psys->totpart= newtotpart;
/* create new elements */
- pa= psys->particles + totpart;
- point= edit->points + totpart;
+ pa = psys->particles + totpart;
+ point = edit->points + totpart;
for (i=totpart; i<newtotpart; i++, pa++, point++) {
memcpy(pa, add_pars + i - totpart, sizeof(ParticleData));
@@ -3380,8 +3397,14 @@ static int brush_add(PEData *data, short number)
weight[w] = 0.0f;
}
- for (w=0; w<maxw; w++)
- weight[w] /= totw;
+ if (totw > 0.0f) {
+ for (w=0; w<maxw; w++)
+ weight[w] /= totw;
+ }
+ else {
+ for (w=0; w<maxw; w++)
+ weight[w] = 1.0f/maxw;
+ }
ppa= psys->particles+ptn[0].index;
@@ -3393,7 +3416,7 @@ static int brush_add(PEData *data, short number)
psys_get_particle_on_path(&sim, ptn[0].index, key3, 0);
mul_v3_fl(key3[0].co, weight[0]);
- /* TODO: interpolatint the weight would be nicer */
+ /* TODO: interpolating the weight would be nicer */
thkey->weight= (ppa->hair+MIN2(k, ppa->totkey-1))->weight;
if (maxw>1) {
@@ -3466,11 +3489,16 @@ static int brush_edit_init(bContext *C, wmOperator *op)
PTCacheEdit *edit= PE_get_current(scene, ob);
ARegion *ar= CTX_wm_region(C);
BrushEdit *bedit;
-
+ float min[3], max[3];
+
if (pset->brushtype < 0)
return 0;
- initgrabz(ar->regiondata, ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2]);
+ /* set the 'distance factor' for grabbing (used in comb etc) */
+ INIT_MINMAX(min, max);
+ PE_minmax(scene, min, max);
+ mid_v3_v3v3(min, min, max);
+ initgrabz(ar->regiondata, min[0], min[1], min[2]);
bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit");
bedit->first= 1;
@@ -3535,7 +3563,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
selected= (short)count_selected_keys(scene, edit);
dmax = max_ff(fabsf(dx), fabsf(dy));
- tot_steps = dmax/(0.2f * brush->size) + 1;
+ tot_steps = dmax/(0.2f * pe_brush_size_get(scene, brush)) + 1;
dx /= (float)tot_steps;
dy /= (float)tot_steps;
@@ -3549,7 +3577,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
const float mval_f[2] = {dx, dy};
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.combfac= (brush->strength - 0.5f) * 2.0f;
if (data.combfac < 0.0f)
@@ -3569,7 +3597,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
if (edit->psys && edit->pathcache) {
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.cutfac= brush->strength;
if (selected)
@@ -3590,7 +3618,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.growfac= brush->strength / 50.0f;
if (brush->invert ^ flip)
@@ -3609,7 +3637,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
if (edit->psys) {
data.dm= psmd->dm;
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.select= selected;
data.pufffac= (brush->strength - 0.5f) * 2.0f;
@@ -3642,7 +3670,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
case PE_BRUSH_SMOOTH:
{
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.vec[0] = data.vec[1] = data.vec[2] = 0.0f;
data.tot= 0;
@@ -3665,7 +3693,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
if (edit->psys) {
data.dm= psmd->dm;
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.weightfac = brush->strength; /* note that this will never be zero */
@@ -4123,7 +4151,7 @@ int PE_minmax(Scene *scene, float min[3], float max[3])
BKE_object_minmax(ob, min, max, TRUE);
ok= 1;
}
-
+
return ok;
}
@@ -4132,8 +4160,8 @@ int PE_minmax(Scene *scene, float min[3], float max[3])
/* initialize needed data for bake edit */
static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
{
- PTCacheEdit *edit= (psys)? psys->edit : cache->edit;
- ParticleSystemModifierData *psmd= (psys)? psys_get_modifier(ob, psys): NULL;
+ PTCacheEdit *edit;
+ ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL;
POINT_P; KEY_K;
ParticleData *pa = NULL;
HairKey *hkey;
@@ -4149,6 +4177,8 @@ static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache,
if (psys == NULL && (cache && cache->mem_cache.first == NULL))
return;
+ edit = (psys) ? psys->edit : cache->edit;
+
if (!edit) {
totpoint = psys ? psys->totpart : (int)((PTCacheMem *)cache->mem_cache.first)->totpoint;
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 221aad2161c..5fd2a0806e9 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -49,6 +49,7 @@
#include "BKE_main.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
+#include "BKE_report.h"
#include "RNA_access.h"
@@ -150,7 +151,6 @@ static int psys_poll(bContext *C)
static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
Main *bmain= CTX_data_main(C);
ParticleSystem *psys;
ParticleSettings *part = NULL;
@@ -176,7 +176,7 @@ static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op))
psys_check_boid_data(psys);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
@@ -204,7 +204,6 @@ void PARTICLE_OT_new(wmOperatorType *ot)
static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= ptr.data;
Object *ob = ptr.id.data;
@@ -225,7 +224,7 @@ static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
BLI_addtail(&psys->targets, pt);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
@@ -250,7 +249,6 @@ void PARTICLE_OT_new_target(wmOperatorType *ot)
static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= ptr.data;
Object *ob = ptr.id.data;
@@ -274,7 +272,7 @@ static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
if (pt)
pt->flag |= PTARGET_CURRENT;
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
@@ -312,7 +310,7 @@ static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op))
for (; pt; pt=pt->next) {
if (pt->flag & PTARGET_CURRENT && pt->prev) {
BLI_remlink(&psys->targets, pt);
- BLI_insertlink(&psys->targets, pt->prev->prev, pt);
+ BLI_insertlinkbefore(&psys->targets, pt->prev, pt);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
@@ -350,7 +348,7 @@ static int target_move_down_exec(bContext *C, wmOperator *UNUSED(op))
for (; pt; pt=pt->next) {
if (pt->flag & PTARGET_CURRENT && pt->next) {
BLI_remlink(&psys->targets, pt);
- BLI_insertlink(&psys->targets, pt->next, pt);
+ BLI_insertlinkafter(&psys->targets, pt->next, pt);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
@@ -389,7 +387,7 @@ static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op))
for (dw=part->dupliweights.first; dw; dw=dw->next) {
if (dw->flag & PART_DUPLIW_CURRENT && dw->prev) {
BLI_remlink(&part->dupliweights, dw);
- BLI_insertlink(&part->dupliweights, dw->prev->prev, dw);
+ BLI_insertlinkbefore(&part->dupliweights, dw->prev, dw);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
break;
@@ -511,7 +509,7 @@ static int dupliob_move_down_exec(bContext *C, wmOperator *UNUSED(op))
for (dw=part->dupliweights.first; dw; dw=dw->next) {
if (dw->flag & PART_DUPLIW_CURRENT && dw->next) {
BLI_remlink(&part->dupliweights, dw);
- BLI_insertlink(&part->dupliweights, dw->next, dw);
+ BLI_insertlinkafter(&part->dupliweights, dw->next, dw);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
break;
@@ -625,7 +623,7 @@ 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 void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+static int connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
ParticleData *pa;
@@ -642,8 +640,8 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
float hairmat[4][4], imat[4][4];
float v[4][3], vec[3];
- if (!psys || !psys->part || psys->part->type != PART_HAIR)
- return;
+ if (!psys || !psys->part || psys->part->type != PART_HAIR || !psmd->dm)
+ return FALSE;
edit= psys->edit;
point= edit ? edit->points : NULL;
@@ -724,6 +722,8 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
psys->flag &= ~PSYS_GLOBAL_HAIR;
PE_update_object(scene, ob, 0);
+
+ return TRUE;
}
static int connect_hair_exec(bContext *C, wmOperator *op)
@@ -733,18 +733,24 @@ static int connect_hair_exec(bContext *C, wmOperator *op)
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= NULL;
int all = RNA_boolean_get(op->ptr, "all");
+ int any_connected = FALSE;
if (!ob)
return OPERATOR_CANCELLED;
if (all) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
- connect_hair(scene, ob, psys);
+ any_connected |= connect_hair(scene, ob, psys);
}
}
else {
psys = ptr.data;
- connect_hair(scene, ob, psys);
+ any_connected |= connect_hair(scene, ob, psys);
+ }
+
+ if (!any_connected) {
+ BKE_report(op->reports, RPT_ERROR, "Can't disconnect hair if particle system modifier is disabled");
+ return OPERATOR_CANCELLED;
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 5304c64c2a9..fc55b2b5915 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -127,7 +127,7 @@ static float get_fluid_size_m(Scene *scene, Object *domainob, FluidsimSettings *
float longest_axis;
BKE_object_dimensions_get(domainob, dim);
- longest_axis = MAX3(dim[0], dim[1], dim[2]);
+ longest_axis = max_fff(dim[0], dim[1], dim[2]);
return longest_axis * scene->unit.scale_length;
}
@@ -142,7 +142,7 @@ static int fluid_is_animated_mesh(FluidsimSettings *fss)
#if 0
/* helper function */
-void fluidsimGetGeometryObjFilename(Object *ob, char *dst) { //, char *srcname)
+void fluidsimGetGeometryObjFilename(Object *ob, char *dst) //, char *srcname)
{
//BLI_snprintf(dst, FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name);
BLI_snprintf(dst, FILE_MAXFILE, "fluidcfgdata_%s.bobj.gz", ob->id.name);
@@ -237,7 +237,7 @@ static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *chann
{
int i;
- channels->timeAtFrame = MEM_callocN((channels->length+1)*sizeof(float), "timeAtFrame channel");
+ channels->timeAtFrame = MEM_callocN((channels->length + 1) * sizeof(float), "timeAtFrame channel");
channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1
@@ -267,7 +267,7 @@ static void set_vertex_channel(float *channel, float time, struct Scene *scene,
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
float *verts;
int *tris=NULL, numVerts=0, numTris=0;
- int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+ int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd);
int framesize = (3*fobj->numVerts) + 1;
int j;
@@ -388,7 +388,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
if (fluid_is_animated_mesh(fluidmd->fss)) {
float *verts=NULL;
- int *tris=NULL, modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+ int *tris=NULL, modifierIndex = BLI_findindex(&ob->modifiers, (ModifierData *)fluidmd);
initElbeemMesh(scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex);
fobj->VertexCache = MEM_callocN(length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache");
@@ -491,7 +491,7 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length)
for (fobj=fobjects->first; fobj; fobj=fobj->next) {
Object *ob = fobj->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
- int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+ int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd);
float *verts=NULL;
int *tris=NULL;
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index 75779cf6102..77ce5a334e6 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -105,5 +105,23 @@ void PTCACHE_OT_bake_from_cache(struct wmOperatorType *ot);
void PTCACHE_OT_add(struct wmOperatorType *ot);
void PTCACHE_OT_remove(struct wmOperatorType *ot);
-#endif /* __PHYSICS_INTERN_H__ */
+/* rigidbody_object.c */
+void RIGIDBODY_OT_object_add(struct wmOperatorType *ot);
+void RIGIDBODY_OT_object_remove(struct wmOperatorType *ot);
+
+void RIGIDBODY_OT_objects_add(struct wmOperatorType *ot);
+void RIGIDBODY_OT_objects_remove(struct wmOperatorType *ot);
+
+void RIGIDBODY_OT_shape_change(struct wmOperatorType *ot);
+void RIGIDBODY_OT_mass_calculate(struct wmOperatorType *ot);
+/* rigidbody_constraint.c */
+void RIGIDBODY_OT_constraint_add(struct wmOperatorType *ot);
+void RIGIDBODY_OT_constraint_remove(struct wmOperatorType *ot);
+
+/*rigidbody_world.c */
+void RIGIDBODY_OT_world_add(struct wmOperatorType *ot);
+void RIGIDBODY_OT_world_remove(struct wmOperatorType *ot);
+void RIGIDBODY_OT_world_export(struct wmOperatorType *ot);
+
+#endif /* __PHYSICS_INTERN_H__ */
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index fb99d296a54..51a66886c6e 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -86,6 +86,22 @@ static void operatortypes_particle(void)
WM_operatortype_append(PARTICLE_OT_dupliob_remove);
WM_operatortype_append(PARTICLE_OT_dupliob_move_up);
WM_operatortype_append(PARTICLE_OT_dupliob_move_down);
+
+ WM_operatortype_append(RIGIDBODY_OT_object_add);
+ WM_operatortype_append(RIGIDBODY_OT_object_remove);
+
+ WM_operatortype_append(RIGIDBODY_OT_objects_add);
+ WM_operatortype_append(RIGIDBODY_OT_objects_remove);
+
+ WM_operatortype_append(RIGIDBODY_OT_shape_change);
+ WM_operatortype_append(RIGIDBODY_OT_mass_calculate);
+
+ WM_operatortype_append(RIGIDBODY_OT_constraint_add);
+ WM_operatortype_append(RIGIDBODY_OT_constraint_remove);
+
+ WM_operatortype_append(RIGIDBODY_OT_world_add);
+ WM_operatortype_append(RIGIDBODY_OT_world_remove);
+// WM_operatortype_append(RIGIDBODY_OT_world_export);
}
static void keymap_particle(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index bbce94b6215..b9742c9968f 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -90,6 +90,20 @@ static void bake_console_progress_end(void *UNUSED(arg))
printf("\rbake: done!\n");
}
+static void ptcache_free_bake(PointCache *cache)
+{
+ if (cache->edit) {
+ if (!cache->edit->edited || 1) {// XXX okee("Lose changes done in particle mode?")) {
+ PE_free_ptcache_edit(cache->edit);
+ cache->edit = NULL;
+ cache->flag &= ~PTCACHE_BAKED;
+ }
+ }
+ else {
+ cache->flag &= ~PTCACHE_BAKED;
+ }
+}
+
static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -139,7 +153,7 @@ static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
for (pid=pidlist.first; pid; pid=pid->next) {
- pid->cache->flag &= ~PTCACHE_BAKED;
+ ptcache_free_bake(pid->cache);
}
BLI_freelistN(&pidlist);
@@ -241,15 +255,7 @@ static int ptcache_free_bake_exec(bContext *C, wmOperator *UNUSED(op))
PointCache *cache= ptr.data;
Object *ob= ptr.id.data;
- if (cache->edit) {
- if (!cache->edit->edited || 1) {// XXX okee("Lose changes done in particle mode?")) {
- PE_free_ptcache_edit(cache->edit);
- cache->edit = NULL;
- cache->flag &= ~PTCACHE_BAKED;
- }
- }
- else
- cache->flag &= ~PTCACHE_BAKED;
+ ptcache_free_bake(cache);
WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
new file mode 100644
index 00000000000..b3f92d3de46
--- /dev/null
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -0,0 +1,199 @@
+/*
+ * ***** 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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file rigidbody_constraint.c
+ * \ingroup editor_physics
+ * \brief Rigid Body constraint editing operators
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
+#include "DNA_rigidbody_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_group.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#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"
+
+#include "ED_physics.h"
+#include "ED_screen.h"
+
+#include "physics_intern.h"
+
+/* ********************************************** */
+/* Helper API's for RigidBody Constraint Editing */
+
+static int ED_operator_rigidbody_con_active_poll(bContext *C)
+{
+ if (ED_operator_object_active_editable(C)) {
+ Object *ob = CTX_data_active_object(C);
+ return (ob && ob->rigidbody_constraint);
+ }
+ else
+ return 0;
+}
+
+
+void ED_rigidbody_con_add(wmOperator *op, Scene *scene, Object *ob, int type)
+{
+ RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+
+ /* check that object doesn't already have a constraint */
+ if (ob->rigidbody_constraint) {
+ BKE_reportf(op->reports, RPT_INFO, "Object '%s' already has a Rigid Body Constraint", ob->id.name + 2);
+ return;
+ }
+ /* create constraint group if it doesn't already exits */
+ if (rbw->constraints == NULL) {
+ rbw->constraints = add_group(G.main, "RigidBodyConstraints");
+ }
+ /* make rigidbody constraint settings */
+ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type);
+ ob->rigidbody_constraint->flag |= RBC_FLAG_NEEDS_VALIDATE;
+
+ /* add constraint to rigid body constraint group */
+ add_to_group(rbw->constraints, ob, scene, NULL);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+}
+
+void ED_rigidbody_con_remove(Scene *scene, Object *ob)
+{
+ RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+
+ BKE_rigidbody_remove_constraint(scene, ob);
+ if (rbw)
+ rem_from_group(rbw->constraints, ob, scene, NULL);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+}
+
+/* ********************************************** */
+/* Active Object Add/Remove Operators */
+
+/* ************ Add Rigid Body Constraint ************** */
+
+static int rigidbody_con_add_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+ Object *ob = (scene) ? OBACT : NULL;
+ int type = RNA_enum_get(op->ptr, "type");
+
+ /* sanity checks */
+ if (ELEM(NULL, scene, rbw)) {
+ BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to add Rigid Body Constraint to");
+ return OPERATOR_CANCELLED;
+ }
+ /* apply to active object */
+ ED_rigidbody_con_add(op, scene, ob, type);
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_constraint_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_constraint_add";
+ ot->name = "Add Rigid Body Constraint";
+ ot->description = "Add Rigid Body Constraint to active object";
+
+ /* callbacks */
+ ot->exec = rigidbody_con_add_exec;
+ ot->poll = ED_operator_object_active_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_con_type_items, RBC_TYPE_FIXED, "Rigid Body Constraint Type", "");
+}
+
+/* ************ Remove Rigid Body Constraint ************** */
+
+static int rigidbody_con_remove_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = (scene) ? OBACT : NULL;
+
+ /* sanity checks */
+ if (scene == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* apply to active object */
+ if (ELEM(NULL, ob, ob->rigidbody_constraint)) {
+ BKE_report(op->reports, RPT_ERROR, "Object has no Rigid Body Constraint to remove");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ ED_rigidbody_con_remove(scene, ob);
+ }
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_constraint_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_constraint_remove";
+ ot->name = "Remove Rigid Body Constraint";
+ ot->description = "Remove Rigid Body Constraint from Object";
+
+ /* callbacks */
+ ot->exec = rigidbody_con_remove_exec;
+ ot->poll = ED_operator_rigidbody_con_active_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
new file mode 100644
index 00000000000..6bcdf6e07aa
--- /dev/null
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -0,0 +1,621 @@
+/*
+ * ***** 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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file rigidbody_object.c
+ * \ingroup editor_physics
+ * \brief Rigid Body object editing operators
+ */
+
+#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 "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_group.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#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"
+
+#include "ED_physics.h"
+#include "ED_screen.h"
+
+#include "physics_intern.h"
+
+/* ********************************************** */
+/* Helper API's for RigidBody Objects Editing */
+
+static int ED_operator_rigidbody_active_poll(bContext *C)
+{
+ if (ED_operator_object_active_editable(C)) {
+ Object *ob = CTX_data_active_object(C);
+ return (ob && ob->rigidbody_object);
+ }
+ else
+ return 0;
+}
+
+static int ED_operator_rigidbody_add_poll(bContext *C)
+{
+ if (ED_operator_object_active_editable(C)) {
+ Object *ob = CTX_data_active_object(C);
+ return (ob && ob->type == OB_MESH);
+ }
+ else
+ return 0;
+}
+
+/* ----------------- */
+
+void ED_rigidbody_ob_add(wmOperator *op, Scene *scene, Object *ob, int type)
+{
+ RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+
+ if (ob->type != OB_MESH) {
+ BKE_report(op->reports, RPT_ERROR, "Can't add Rigid Body to non mesh object");
+ return;
+ }
+ if (((Mesh *)ob->data)->totpoly == 0) {
+ BKE_report(op->reports, RPT_ERROR, "Can't create Rigid Body from mesh with no polygons");
+ return;
+ }
+
+ /* Add rigid body world and group if they don't exist for convenience */
+ if (rbw == NULL) {
+ rbw = BKE_rigidbody_create_world(scene);
+ BKE_rigidbody_validate_sim_world(scene, rbw, false);
+ scene->rigidbody_world = rbw;
+ }
+ if (rbw->group == NULL) {
+ rbw->group = add_group(G.main, "RigidBodyWorld");
+ }
+
+ /* make rigidbody object settings */
+ if (ob->rigidbody_object == NULL) {
+ ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, type);
+ }
+ ob->rigidbody_object->type = type;
+ ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
+
+ /* add object to rigid body group */
+ add_to_group(rbw->group, ob, scene, NULL);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+}
+
+void ED_rigidbody_ob_remove(Scene *scene, Object *ob)
+{
+ RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+
+ BKE_rigidbody_remove_object(scene, ob);
+ if (rbw)
+ rem_from_group(rbw->group, ob, scene, NULL);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+}
+
+/* ********************************************** */
+/* Active Object Add/Remove Operators */
+
+/* ************ Add Rigid Body ************** */
+
+static int rigidbody_ob_add_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = (scene) ? OBACT : NULL;
+ int type = RNA_enum_get(op->ptr, "type");
+
+ /* apply to active object */
+ ED_rigidbody_ob_add(op, scene, ob, type);
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_object_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_object_add";
+ ot->name = "Add Rigid Body";
+ ot->description = "Add active object as Rigid Body";
+
+ /* callbacks */
+ ot->exec = rigidbody_ob_add_exec;
+ ot->poll = ED_operator_rigidbody_add_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_ob_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", "");
+}
+
+/* ************ Remove Rigid Body ************** */
+
+static int rigidbody_ob_remove_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = (scene) ? OBACT : NULL;
+
+ /* sanity checks */
+ if (scene == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* apply to active object */
+ if (ELEM(NULL, ob, ob->rigidbody_object)) {
+ BKE_report(op->reports, RPT_ERROR, "Object has no Rigid Body settings to remove");
+ return OPERATOR_CANCELLED;
+ }
+ else
+ ED_rigidbody_ob_remove(scene, ob);
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_object_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_object_remove";
+ ot->name = "Remove Rigid Body";
+ ot->description = "Remove Rigid Body settings from Object";
+
+ /* callbacks */
+ ot->exec = rigidbody_ob_remove_exec;
+ ot->poll = ED_operator_rigidbody_active_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ********************************************** */
+/* Selected Object Add/Remove Operators */
+
+/* ************ Add Rigid Bodies ************** */
+
+static int rigidbody_obs_add_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ int type = RNA_enum_get(op->ptr, "type");
+
+ /* sanity check */
+ if (scene == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No Scene to add Rigid Bodies to");
+ return OPERATOR_CANCELLED;
+ }
+ /* create rigid body objects and add them to the world's group */
+ CTX_DATA_BEGIN(C, Object *, ob, selected_objects) {
+ ED_rigidbody_ob_add(op, scene, ob, type);
+ }
+ CTX_DATA_END;
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_objects_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_objects_add";
+ ot->name = "Add Rigid Bodies";
+ ot->description = "Add selected objects as Rigid Bodies";
+
+ /* callbacks */
+ ot->exec = rigidbody_obs_add_exec;
+ ot->poll = ED_operator_rigidbody_add_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_ob_type_items, RBO_TYPE_ACTIVE, "Rigid Body Type", "");
+}
+
+/* ************ Remove Rigid Bodies ************** */
+
+static int rigidbody_obs_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+
+ /* sanity checks */
+ if (scene == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* apply this to all selected objects... */
+ CTX_DATA_BEGIN(C, Object *, ob, selected_objects)
+ {
+ if (ob->rigidbody_object) {
+ ED_rigidbody_ob_remove(scene, ob);
+ }
+ }
+ CTX_DATA_END;
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_objects_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_objects_remove";
+ ot->name = "Remove Rigid Bodies";
+ ot->description = "Remove selected objects from Rigid Body simulation";
+
+ /* callbacks */
+ ot->exec = rigidbody_obs_remove_exec;
+ ot->poll = ED_operator_rigidbody_active_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ********************************************** */
+/* Utility Operators */
+
+/* ************ Change Collision Shapes ************** */
+
+static int rigidbody_obs_shape_change_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ int shape = RNA_enum_get(op->ptr, "type");
+
+ /* sanity checks */
+ if (scene == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* apply this to all selected objects... */
+ CTX_DATA_BEGIN(C, Object *, ob, selected_objects)
+ {
+ if (ob->rigidbody_object) {
+ PointerRNA ptr;
+
+ /* use RNA-system to change the property and perform all necessary changes */
+ RNA_pointer_create(&ob->id, &RNA_RigidBodyObject, ob->rigidbody_object, &ptr);
+ RNA_enum_set(&ptr, "collision_shape", shape);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+ }
+ }
+ CTX_DATA_END;
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_shape_change(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_shape_change";
+ ot->name = "Change Collision Shape";
+ ot->description = "Change collision shapes for selected Rigid Body Objects";
+
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = rigidbody_obs_shape_change_exec;
+ ot->poll = ED_operator_rigidbody_active_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", rigidbody_ob_shape_items, RB_SHAPE_TRIMESH, "Rigid Body Shape", "");
+}
+
+/* ************ Calculate Mass ************** */
+
+/* Entry in material density table */
+typedef struct rbMaterialDensityItem {
+ const char *name; /* Name of material */
+ float density; /* Density (kg/m^3) */
+} rbMaterialDensityItem;
+
+/* Preset density values for materials (kg/m^3)
+ * Selected values obtained from:
+ * 1) http://www.jaredzone.info/2010/09/densities.html
+ * 2) http://www.avlandesign.com/density_construction.htm
+ * 3) http://www.avlandesign.com/density_metal.htm
+ */
+static rbMaterialDensityItem RB_MATERIAL_DENSITY_TABLE[] = {
+ {"Air", 1.0f}, /* not quite; adapted from 1.43 for oxygen for use as default */
+ {"Acrylic", 1400.0f},
+ {"Asphalt (Crushed)", 721.0f},
+ {"Bark", 240.0f},
+ {"Beans (Cocoa)", 593.0f},
+ {"Beans (Soy)", 721.0f},
+ {"Brick (Pressed)", 2400.0f},
+ {"Brick (Common)", 2000.0f},
+ {"Brick (Soft)", 1600.0f},
+ {"Brass", 8216.0f},
+ {"Bronze", 8860.0f},
+ {"Carbon (Solid)", 2146.0f},
+ {"Cardboard", 689.0f},
+ {"Cast Iron", 7150.0f},
+ //{"Cement", 1442.0f},
+ {"Chalk (Solid)", 2499.0f},
+ //{"Coffee (Fresh/Roast)", ~500},
+ {"Concrete", 2320.0f},
+ {"Charcoal", 208.0f},
+ {"Cork", 240.0f},
+ {"Copper", 8933.0f},
+ {"Garbage", 481.0f},
+ {"Glass (Broken)", 1940.0f},
+ {"Glass (Solid)", 2190.0f},
+ {"Gold", 19282.0f},
+ {"Granite (Broken)", 1650.0f},
+ {"Granite (Solid)", 2691.0f},
+ {"Gravel", 2780.0f},
+ {"Ice (Crushed)", 593.0f},
+ {"Ice (Solid)", 919.0f},
+ {"Iron", 7874.0f},
+ {"Lead", 11342.0f},
+ {"Limestone (Broken)", 1554.0f},
+ {"Limestone (Solid)", 2611.0f},
+ {"Marble (Broken)", 1570.0f},
+ {"Marble (Solid)", 2563.0f},
+ {"Paper", 1201.0f},
+ {"Peanuts (Shelled)", 641.0f},
+ {"Peanuts (Not Shelled)", 272.0f},
+ {"Plaster", 849.0f},
+ {"Plastic", 1200.0f},
+ {"Polystyrene", 1050.0f},
+ {"Rubber", 1522.0f},
+ {"Silver", 10501.0f},
+ {"Steel", 7860.0f},
+ {"Stone", 2515.0f},
+ {"Stone (Crushed)", 1602.0f},
+ {"Timber", 610.0f}
+};
+static const int NUM_RB_MATERIAL_PRESETS = sizeof(RB_MATERIAL_DENSITY_TABLE) / sizeof(rbMaterialDensityItem);
+
+
+/* dynamically generate list of items
+ * - Although there is a runtime cost, this has a lower maintenance cost
+ * in the long run than other two-list solutions...
+ */
+static EnumPropertyItem *rigidbody_materials_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
+{
+ EnumPropertyItem item_tmp = {0};
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+ int i = 0;
+
+ /* add each preset to the list */
+ for (i = 0; i < NUM_RB_MATERIAL_PRESETS; i++) {
+ rbMaterialDensityItem *preset = &RB_MATERIAL_DENSITY_TABLE[i];
+
+ item_tmp.identifier = item_tmp.name = preset->name;
+ item_tmp.value = i;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+ }
+
+ /* add special "custom" entry to the end of the list */
+ {
+ item_tmp.identifier = item_tmp.name = "Custom";
+ item_tmp.value = -1;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+
+/* ------------------------------------------ */
+
+/* helper function to calculate volume of rigidbody object */
+// TODO: allow a parameter to specify method used to calculate this?
+static float calc_rigidbody_ob_volume(Object *ob)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ float size[3] = {1.0f, 1.0f, 1.0f};
+ float radius = 1.0f;
+ float height = 1.0f;
+
+ float volume = 0.0f;
+
+ /* if automatically determining dimensions, use the Object's boundbox
+ * - assume that all quadrics are standing upright on local z-axis
+ * - assume even distribution of mass around the Object's pivot
+ * (i.e. Object pivot is centralised in boundbox)
+ * - boundbox gives full width
+ */
+ // XXX: all dimensions are auto-determined now... later can add stored settings for this
+ BKE_object_dimensions_get(ob, size);
+
+ if (ELEM3(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
+ /* take radius as largest x/y dimension, and height as z-dimension */
+ radius = MAX2(size[0], size[1]) * 0.5f;
+ height = size[2];
+ }
+ else if (rbo->shape == RB_SHAPE_SPHERE) {
+ /* take radius to the the largest dimension to try and encompass everything */
+ radius = max_fff(size[0], size[1], size[2]) * 0.5f;
+ }
+
+ /* calculate volume as appropriate */
+ switch (rbo->shape) {
+ case RB_SHAPE_BOX:
+ volume = size[0] * size[1] * size[2];
+ break;
+
+ case RB_SHAPE_SPHERE:
+ volume = 4.0f / 3.0f * (float)M_PI * radius * radius * radius;
+ break;
+
+ /* for now, assume that capsule is close enough to a cylinder... */
+ case RB_SHAPE_CAPSULE:
+ case RB_SHAPE_CYLINDER:
+ volume = (float)M_PI * radius * radius * height;
+ break;
+
+ case RB_SHAPE_CONE:
+ volume = (float)M_PI / 3.0f * radius * radius * height;
+ break;
+
+ /* for now, all mesh shapes are just treated as boxes...
+ * NOTE: this may overestimate the volume, but other methods are overkill
+ */
+ case RB_SHAPE_CONVEXH:
+ case RB_SHAPE_TRIMESH:
+ volume = size[0] * size[1] * size[2];
+ break;
+
+#if 0 // XXX: not defined yet
+ case RB_SHAPE_COMPOUND:
+ volume = 0.0f;
+ break;
+#endif
+ }
+
+ /* return the volume calculated */
+ return volume;
+}
+
+/* ------------------------------------------ */
+
+static int rigidbody_obs_calc_mass_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ int material = RNA_enum_get(op->ptr, "material");
+ float density;
+
+ /* sanity checks */
+ if (scene == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* get density (kg/m^3) to apply */
+ if (material >= 0) {
+ /* get density from table, and store in props for later repeating */
+ if (material >= NUM_RB_MATERIAL_PRESETS)
+ material = 0;
+
+ density = RB_MATERIAL_DENSITY_TABLE[material].density;
+ RNA_float_set(op->ptr, "density", density);
+ }
+ else {
+ /* custom - grab from whatever value is set */
+ density = RNA_float_get(op->ptr, "density");
+ }
+
+ /* apply this to all selected objects (with rigidbodies)... */
+ CTX_DATA_BEGIN(C, Object *, ob, selected_objects)
+ {
+ if (ob->rigidbody_object) {
+ PointerRNA ptr;
+
+ float volume; /* m^3 */
+ float mass; /* kg */
+
+ /* mass is calculated from the approximate volume of the object,
+ * and the density of the material we're simulating
+ */
+ volume = calc_rigidbody_ob_volume(ob);
+ mass = volume * density;
+
+ /* use RNA-system to change the property and perform all necessary changes */
+ RNA_pointer_create(&ob->id, &RNA_RigidBodyObject, ob->rigidbody_object, &ptr);
+ RNA_float_set(&ptr, "mass", mass);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+ }
+ }
+ CTX_DATA_END;
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_mass_calculate(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_mass_calculate";
+ ot->name = "Calculate Mass";
+ ot->description = "Automatically calculate mass values for Rigid Body Objects based on volume";
+
+ /* callbacks */
+ ot->invoke = WM_menu_invoke; // XXX
+ ot->exec = rigidbody_obs_calc_mass_exec;
+ ot->poll = ED_operator_rigidbody_active_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = prop = RNA_def_enum(ot->srna, "material",
+ DummyRNA_DEFAULT_items, 0,
+ "Material Preset",
+ "Type of material that objects are made of (determines material density)");
+ RNA_def_enum_funcs(prop, rigidbody_materials_itemf);
+
+ RNA_def_float(ot->srna, "density", 1.0, FLT_MIN, FLT_MAX,
+ "Density",
+ "Custom density value (kg/m^3) to use instead of material preset",
+ 1.0f, 2500.0f);
+}
+
+/* ********************************************** */
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
new file mode 100644
index 00000000000..babe32c74b2
--- /dev/null
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -0,0 +1,210 @@
+/*
+ * ***** 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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file rigidbody_world.c
+ * \ingroup editor_physics
+ * \brief Rigid Body world editing operators
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "DNA_object_types.h"
+#include "DNA_rigidbody_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+
+#ifdef WITH_BULLET
+# include "RBI_api.h"
+#endif
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_group.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+#include "BKE_rigidbody.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_physics.h"
+#include "ED_screen.h"
+
+#include "physics_intern.h"
+
+/* ********************************************** */
+/* API */
+
+/* check if there is an active rigid body world */
+static int ED_rigidbody_world_active_poll(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ return (scene && scene->rigidbody_world);
+}
+static int ED_rigidbody_world_add_poll(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ return (scene && scene->rigidbody_world == NULL);
+}
+
+/* ********************************************** */
+/* OPERATORS - Management */
+
+/* ********** Add RigidBody World **************** */
+
+static int rigidbody_world_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ RigidBodyWorld *rbw;
+
+ rbw = BKE_rigidbody_create_world(scene);
+// BKE_rigidbody_validate_sim_world(scene, rbw, false);
+ scene->rigidbody_world = rbw;
+
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_world_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_world_add";
+ ot->name = "Add Rigid Body World";
+ ot->description = "Add Rigid Body simulation world to the current scene";
+
+ /* callbacks */
+ ot->exec = rigidbody_world_add_exec;
+ ot->poll = ED_rigidbody_world_add_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ********** Remove RigidBody World ************* */
+
+static int rigidbody_world_remove_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+
+ /* sanity checks */
+ if (ELEM(NULL, scene, rbw)) {
+ BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to remove");
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_rigidbody_free_world(rbw);
+ scene->rigidbody_world = NULL;
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void RIGIDBODY_OT_world_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_world_remove";
+ ot->name = "Remove Rigid Body World";
+ ot->description = "Remove Rigid Body simulation world from the current scene";
+
+ /* callbacks */
+ ot->exec = rigidbody_world_remove_exec;
+ ot->poll = ED_rigidbody_world_active_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ********************************************** */
+/* UTILITY OPERATORS */
+
+/* ********** Export RigidBody World ************* */
+
+static int rigidbody_world_export_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ char path[FILE_MAX];
+
+ /* sanity checks */
+ if ELEM(NULL, scene, rbw) {
+ BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to export");
+ return OPERATOR_CANCELLED;
+ }
+ if (rbw->physics_world == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Rigid Body World has no associated physics data to export");
+ return OPERATOR_CANCELLED;
+ }
+
+ RNA_string_get(op->ptr, "filepath", path);
+#ifdef WITH_BULLET
+ RB_dworld_export(rbw->physics_world, path);
+#endif
+ return OPERATOR_FINISHED;
+}
+
+static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+{
+ if (!RNA_struct_property_is_set(op->ptr, "relative_path"))
+ RNA_boolean_set(op->ptr, "relative_path", (U.flag & USER_RELPATHS));
+
+ if (RNA_struct_property_is_set(op->ptr, "filepath"))
+ return rigidbody_world_export_exec(C, op);
+
+ // TODO: use the actual rigidbody world's name + .bullet instead of this temp crap
+ RNA_string_set(op->ptr, "filepath", "rigidbodyworld_export.bullet");
+ WM_event_add_fileselect(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void RIGIDBODY_OT_world_export(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "RIGIDBODY_OT_world_export";
+ ot->name = "Export Rigid Body World";
+ ot->description = "Export Rigid Body world to simulator's own fileformat (i.e. '.bullet' for Bullet Physics)";
+
+ /* callbacks */
+ ot->invoke = rigidbody_world_export_invoke;
+ ot->exec = rigidbody_world_export_exec;
+ ot->poll = ED_rigidbody_world_active_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot, FOLDERFILE, FILE_SPECIAL, FILE_SAVE, FILE_RELPATH, FILE_DEFAULTDISPLAY);
+}
diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript
index 0b19ecdab8e..c05b542aea8 100644
--- a/source/blender/editors/render/SConscript
+++ b/source/blender/editors/render/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index f8154f4abda..deb6eaf2c22 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -73,6 +73,7 @@
#include "render_intern.h"
/* Render Callbacks */
+static int render_break(void *rjv);
/* called inside thread! */
void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volatile rcti *renrect)
@@ -210,7 +211,7 @@ static int screen_render_exec(bContext *C, wmOperator *op)
lay = (v3d) ? v3d->lay : scene->lay;
G.is_break = FALSE;
- RE_test_break_cb(re, NULL, (int (*)(void *))blender_test_break);
+ RE_test_break_cb(re, NULL, render_break);
ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
@@ -443,6 +444,15 @@ static int render_breakjob(void *rjv)
return 0;
}
+/* for exec() when there is no render job
+ * note: this wont check for the escape key being pressed, but doing so isnt threadsafe */
+static int render_break(void *UNUSED(rjv))
+{
+ if (G.is_break)
+ return 1;
+ return 0;
+}
+
/* runs in thread, no cursor setting here works. careful with notifiers too (malloc conflicts) */
/* maybe need a way to get job send notifer? */
static void render_drawlock(void *UNUSED(rjv), int lock)
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 73f8abdf15f..ea18f2c8fbb 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -43,6 +43,7 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_world_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -192,7 +193,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
}
if ((scene->r.mode & R_OSA) == 0) {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf);
}
else {
@@ -206,7 +207,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
BLI_jitter_init(jit_ofs[0], scene->r.osa);
/* first sample buffer, also initializes 'rv3d->persmat' */
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer);
/* skip the first sample */
@@ -216,7 +217,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
(jit_ofs[j][0] * 2.0f) / sizex,
(jit_ofs[j][1] * 2.0f) / sizey);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp);
add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float));
}
@@ -232,7 +233,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
else {
/* shouldnt suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
- ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, TRUE, FALSE, err_out);
+ ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
+ IB_rectfloat, OB_SOLID, FALSE, TRUE, R_ALPHAPREMUL, err_out);
camera = scene->camera;
if (ibuf_view) {
@@ -243,7 +245,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
}
}
-
+
+ if (scene->r.alphamode == R_ADDSKY) {
+ float sky_color[3];
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+ IMB_alpha_under_color_float(rr->rectf, sizex, sizey, sky_color);
+ }
+
/* note on color management:
*
* OpenGL renders into sRGB colors, but render buffers are expected to be
@@ -256,7 +264,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* sequencer has got tricker ocnversion happened above */
IMB_buffer_float_from_float(rr->rectf, rr->rectf,
- 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, FALSE,
+ 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, TRUE,
oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
}
@@ -281,7 +289,7 @@ 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.imtype, scene->r.scemode & R_EXTENSION, FALSE);
+ BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, 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);
@@ -505,7 +513,7 @@ static int 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.imtype, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
printf("skipping existing frame \"%s\"\n", name);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index a864fe306b3..dfc80e4cf51 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -84,6 +84,8 @@
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
+#include "GPU_extensions.h"
+
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -95,6 +97,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_datafiles.h"
#include "ED_render.h"
#include "ED_view3d.h"
@@ -166,7 +169,8 @@ typedef struct ShaderPreview {
int sizex, sizey;
unsigned int *pr_rect;
int pr_method;
-
+
+ Main *pr_main;
} ShaderPreview;
typedef struct IconPreviewSize {
@@ -185,23 +189,33 @@ typedef struct IconPreview {
/* *************************** Preview for buttons *********************** */
static Main *pr_main = NULL;
+static Main *pr_main_cycles = NULL;
-void ED_preview_init_dbase(void)
-{
#ifndef WITH_HEADLESS
- BlendFileData *bfd;
- extern int datatoc_preview_blend_size;
- extern char datatoc_preview_blend[];
+static Main *load_main_from_memory(char *blend, int blend_size)
+{
const int fileflags = G.fileflags;
-
+ Main *bmain = NULL;
+ BlendFileData *bfd;
+
G.fileflags |= G_FILE_NO_UI;
- bfd = BLO_read_from_memory(datatoc_preview_blend, datatoc_preview_blend_size, NULL);
+ bfd = BLO_read_from_memory(blend, blend_size, NULL);
if (bfd) {
- pr_main = bfd->main;
-
+ bmain = bfd->main;
+
MEM_freeN(bfd);
}
G.fileflags = fileflags;
+
+ return bmain;
+}
+#endif
+
+void ED_preview_init_dbase(void)
+{
+#ifndef WITH_HEADLESS
+ pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
+ pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size);
#endif
}
@@ -209,6 +223,9 @@ void ED_preview_free_dbase(void)
{
if (pr_main)
free_main(pr_main);
+
+ if (pr_main_cycles)
+ free_main(pr_main_cycles);
}
static int preview_mat_has_sss(Material *mat, bNodeTree *ntree)
@@ -237,7 +254,7 @@ static int preview_mat_has_sss(Material *mat, bNodeTree *ntree)
return 0;
}
-static Scene *preview_get_scene(void)
+static Scene *preview_get_scene(Main *pr_main)
{
if (pr_main == NULL) return NULL;
@@ -251,8 +268,9 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
{
Scene *sce;
Base *base;
+ Main *pr_main = sp->pr_main;
- sce = preview_get_scene();
+ sce = preview_get_scene(pr_main);
if (sce) {
/* this flag tells render to not execute depsgraph or ipos etc */
@@ -280,11 +298,6 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sce->r.tiley = sce->r.ysch / 4;
}
- /* exception: don't apply render part of display transform for texture previews or icons */
- if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) {
- BKE_scene_disable_color_management(sce);
- }
-
if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO)
sce->r.alphamode = R_ALPHAPREMUL;
else
@@ -302,50 +315,56 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sp->matcopy = mat;
BLI_addtail(&pr_main->mat, mat);
- init_render_material(mat, 0, NULL); /* call that retrieves mode_l */
- end_render_material(mat);
-
- /* un-useful option */
- if (sp->pr_method == PR_ICON_RENDER)
- mat->shade_flag &= ~MA_OBCOLOR;
-
- /* turn on raytracing if needed */
- if (mat->mode_l & MA_RAYMIRROR)
- sce->r.mode |= R_RAYTRACE;
- if (mat->material_type == MA_TYPE_VOLUME)
- sce->r.mode |= R_RAYTRACE;
- if ((mat->mode_l & MA_RAYTRANSP) && (mat->mode_l & MA_TRANSP))
- sce->r.mode |= R_RAYTRACE;
- if (preview_mat_has_sss(mat, NULL))
- sce->r.mode |= R_SSS;
-
- /* turn off fake shadows if needed */
- /* this only works in a specific case where the preview.blend contains
- * an object starting with 'c' which has a material linked to it (not the obdata)
- * and that material has a fake shadow texture in the active texture slot */
- for (base = sce->base.first; base; base = base->next) {
- if (base->object->id.name[2] == 'c') {
- Material *shadmat = give_current_material(base->object, base->object->actcol);
- if (shadmat) {
- if (mat->mode & MA_SHADBUF) shadmat->septex = 0;
- else shadmat->septex |= 1;
+ if (!BKE_scene_use_new_shading_nodes(scene)) {
+ init_render_material(mat, 0, NULL); /* call that retrieves mode_l */
+ end_render_material(mat);
+
+ /* un-useful option */
+ if (sp->pr_method == PR_ICON_RENDER)
+ mat->shade_flag &= ~MA_OBCOLOR;
+
+ /* turn on raytracing if needed */
+ if (mat->mode_l & MA_RAYMIRROR)
+ sce->r.mode |= R_RAYTRACE;
+ if (mat->material_type == MA_TYPE_VOLUME)
+ sce->r.mode |= R_RAYTRACE;
+ if ((mat->mode_l & MA_RAYTRANSP) && (mat->mode_l & MA_TRANSP))
+ sce->r.mode |= R_RAYTRACE;
+ if (preview_mat_has_sss(mat, NULL))
+ sce->r.mode |= R_SSS;
+
+ /* turn off fake shadows if needed */
+ /* this only works in a specific case where the preview.blend contains
+ * an object starting with 'c' which has a material linked to it (not the obdata)
+ * and that material has a fake shadow texture in the active texture slot */
+ for (base = sce->base.first; base; base = base->next) {
+ if (base->object->id.name[2] == 'c') {
+ Material *shadmat = give_current_material(base->object, base->object->actcol);
+ if (shadmat) {
+ if (mat->mode & MA_SHADBUF) shadmat->septex = 0;
+ else shadmat->septex |= 1;
+ }
}
}
- }
-
- /* turn off bounce lights for volume,
- * doesn't make much visual difference and slows it down too */
- if (mat->material_type == MA_TYPE_VOLUME) {
- 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) {
- base->object->restrictflag |= OB_RESTRICT_RENDER;
+
+ /* turn off bounce lights for volume,
+ * doesn't make much visual difference and slows it down too */
+ if (mat->material_type == MA_TYPE_VOLUME) {
+ 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) {
+ base->object->restrictflag |= OB_RESTRICT_RENDER;
+ }
}
}
}
}
-
+ else {
+ /* use current scene world to light sphere */
+ if (mat->pr_type == MA_SPHERE_A)
+ sce->world = scene->world;
+ }
if (sp->pr_method == PR_ICON_RENDER) {
if (mat->material_type == MA_TYPE_HALO) {
@@ -435,19 +454,21 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sp->lampcopy = la;
BLI_addtail(&pr_main->lamp, la);
}
-
- if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) {
- sce->lay = 1 << MA_ATMOS;
- sce->world = scene->world;
- sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2);
- }
- else {
- sce->lay = 1 << MA_LAMP;
- sce->world = NULL;
- sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2);
+
+ sce->lay = 1 << MA_LAMP;
+
+ if (!BKE_scene_use_new_shading_nodes(scene)) {
+ if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) {
+ sce->lay = 1 << MA_ATMOS;
+ sce->world = scene->world;
+ sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2);
+ }
+ else {
+ sce->world = NULL;
+ sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2);
+ }
}
- sce->r.mode &= ~R_SHADOW;
-
+
for (base = sce->base.first; base; base = base->next) {
if (base->object->id.name[2] == 'p') {
if (base->object->type == OB_LAMP)
@@ -488,24 +509,15 @@ 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 */
-static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int first, rcti *rect, rcti *newrect)
+static int ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect)
{
Render *re;
RenderResult rres;
char name[32];
- int do_gamma_correct = FALSE, do_predivide = FALSE;
int offx = 0;
int newx = BLI_rcti_size_x(rect);
int newy = BLI_rcti_size_y(rect);
- if (id && GS(id->name) != ID_TE) {
- /* exception: don't color manage texture previews - show the raw values */
- if (sce) {
- do_gamma_correct = TRUE;
- do_predivide = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE;
- }
- }
-
if (!split || first) sprintf(name, "Preview %p", (void *)sa);
else sprintf(name, "SecondPreview %p", (void *)sa);
@@ -520,8 +532,10 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
}
}
+ /* test if something rendered ok */
re = RE_GetRender(name);
RE_AcquireResultImage(re, &rres);
+ RE_ReleaseResultImage(re);
if (rres.rectf) {
@@ -531,40 +545,20 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
newrect->ymax = max_ii(newrect->ymax, rect->ymin + rres.recty);
if (rres.rectx && rres.recty) {
- /* temporary conversion to byte for drawing */
+ 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;
- int dither = 0;
- unsigned char *rect_byte;
-
- rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
-
- if (do_gamma_correct) {
- IMB_display_buffer_transform_apply(rect_byte, rres.rectf, rres.rectx, rres.recty, 4,
- &sce->view_settings, &sce->display_settings, do_predivide);
-
- }
- else {
- /* OCIO_TODO: currently seems an exception for textures (came fro mlegacish time),
- * but is it indeed expected behavior, or textures should be
- * color managed as well?
- */
- IMB_buffer_byte_from_float(rect_byte, rres.rectf,
- 4, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, do_predivide,
- rres.rectx, rres.recty, rres.rectx, rres.rectx);
- }
-
+
+ RE_ResultGet32(re, (unsigned int *)rect_byte);
glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte);
-
+
MEM_freeN(rect_byte);
+
+ return 1;
}
-
- RE_ReleaseResultImage(re);
- return 1;
}
}
- RE_ReleaseResultImage(re);
return 0;
}
@@ -572,7 +566,6 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
{
if (idp) {
ScrArea *sa = CTX_wm_area(C);
- Scene *sce = CTX_data_scene(C);
ID *id = (ID *)idp;
ID *parent = (ID *)parentp;
MTex *slot = (MTex *)slotp;
@@ -588,11 +581,11 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
newrect.ymax = rect->ymin;
if (parent) {
- ok = ed_preview_draw_rect(sa, sce, id, 1, 1, rect, &newrect);
- ok &= ed_preview_draw_rect(sa, sce, parent, 1, 0, rect, &newrect);
+ ok = ed_preview_draw_rect(sa, 1, 1, rect, &newrect);
+ ok &= ed_preview_draw_rect(sa, 1, 0, rect, &newrect);
}
else
- ok = ed_preview_draw_rect(sa, sce, id, 0, 0, rect, &newrect);
+ ok = ed_preview_draw_rect(sa, 0, 0, rect, &newrect);
if (ok)
*rect = newrect;
@@ -670,6 +663,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
short idtype = GS(id->name);
char name[32];
int sizex;
+ Main *pr_main = sp->pr_main;
/* in case of split preview, use border render */
if (split) {
@@ -679,7 +673,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
else sizex = sp->sizex;
/* we have to set preview variables first */
- sce = preview_get_scene();
+ sce = preview_get_scene(pr_main);
if (sce) {
sce->r.xsch = sizex;
sce->r.ysch = sp->sizey;
@@ -743,7 +737,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
else {
/* validate owner */
//if (ri->rect == NULL)
- // ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
+ // ri->rect= MEM_mallocN(sizeof(int) * ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
//RE_ResultGet32(re, ri->rect);
}
@@ -780,6 +774,7 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
static void shader_preview_free(void *customdata)
{
ShaderPreview *sp = customdata;
+ Main *pr_main = sp->pr_main;
if (sp->matcopy) {
struct IDProperty *properties;
@@ -917,7 +912,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
ShaderPreview *sp = customdata;
ID *id = sp->id;
short idtype = GS(id->name);
-
+
if (idtype == ID_IM) {
Image *ima = (Image *)id;
ImBuf *ibuf = NULL;
@@ -935,8 +930,10 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
* already there. Very expensive for large images. Need to find a way to
* only get existing ibuf */
ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
- if (ibuf == NULL || ibuf->rect == NULL)
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return;
+ }
icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
@@ -1028,6 +1025,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
sp->pr_method = PR_ICON_RENDER;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
+ sp->pr_main = pr_main;
common_preview_startjob(sp, stop, do_update, progress);
shader_preview_free(sp);
@@ -1040,8 +1038,27 @@ static void icon_preview_endjob(void *customdata)
{
IconPreview *ip = customdata;
- if (ip->id && GS(ip->id->name) == ID_BR)
- WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
+ if (ip->id) {
+
+ if (GS(ip->id->name) == ID_BR)
+ WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
+#if 0
+ if (GS(ip->id->name) == ID_MA) {
+ Material *ma = (Material *)ip->id;
+ PreviewImage *prv_img = ma->preview;
+ int i;
+
+ /* signal to gpu texture */
+ for (i = 0; i < NUM_ICON_SIZES; ++i) {
+ if (prv_img->gputexture[i]) {
+ GPU_texture_free(prv_img->gputexture[i]);
+ prv_img->gputexture[i] = NULL;
+ WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ip->id);
+ }
+ }
+ }
+#endif
+ }
}
static void icon_preview_free(void *customdata)
@@ -1077,7 +1094,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
/* setup job */
WM_jobs_customdata_set(wm_job, ip, icon_preview_free);
- WM_jobs_timer(wm_job, 0.25, NC_MATERIAL, NC_MATERIAL);
+ WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob);
WM_jobs_start(CTX_wm_manager(C), wm_job);
@@ -1088,13 +1105,18 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
Object *ob = CTX_data_active_object(C);
wmJob *wm_job;
ShaderPreview *sp;
+ Scene *scene = CTX_data_scene(C);
+
+ /* node previews not supported for cycles */
+ if (BKE_scene_use_new_shading_nodes(scene) && method == PR_NODE_RENDER)
+ return;
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Shader Preview",
WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
sp = MEM_callocN(sizeof(ShaderPreview), "shader preview");
/* customdata for preview thread */
- sp->scene = CTX_data_scene(C);
+ sp->scene = scene;
sp->owner = owner;
sp->sizex = sizex;
sp->sizey = sizey;
@@ -1102,6 +1124,14 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
sp->id = id;
sp->parent = parent;
sp->slot = slot;
+
+ /* hardcoded preview .blend for cycles/internal, this should be solved
+ * once with custom preview .blend path for external engines */
+ if (BKE_scene_use_new_shading_nodes(scene))
+ sp->pr_main = pr_main_cycles;
+ else
+ sp->pr_main = pr_main;
+
if (ob && ob->totcol) copy_v4_v4(sp->col, ob->col);
else sp->col[0] = sp->col[1] = sp->col[2] = sp->col[3] = 1.0f;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index eef5e705ce7..e00db9b5850 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -367,6 +367,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
+ Main *bmain = CTX_data_main(C);
PointerRNA ptr, idptr;
PropertyRNA *prop;
@@ -375,7 +376,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
ma = BKE_material_copy(ma);
}
else {
- ma = BKE_material_add("Material");
+ ma = BKE_material_add(bmain, "Material");
if (BKE_scene_use_new_shading_nodes(scene)) {
ED_node_shader_default(scene, &ma->id);
@@ -420,6 +421,7 @@ void MATERIAL_OT_new(wmOperatorType *ot)
static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
{
Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
+ Main *bmain = CTX_data_main(C);
PointerRNA ptr, idptr;
PropertyRNA *prop;
@@ -427,7 +429,7 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
if (tex)
tex = BKE_texture_copy(tex);
else
- tex = add_texture("Texture");
+ tex = add_texture(bmain, "Texture");
/* hook into UI */
uiIDContextProperty(C, &ptr, &prop);
@@ -467,6 +469,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
+ Main *bmain = CTX_data_main(C);
PointerRNA ptr, idptr;
PropertyRNA *prop;
@@ -475,7 +478,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
wo = BKE_world_copy(wo);
}
else {
- wo = add_world("World");
+ wo = add_world(bmain, "World");
if (BKE_scene_use_new_shading_nodes(scene)) {
ED_node_shader_default(scene, &wo->id);
@@ -688,7 +691,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, imtype);
+ BKE_add_image_extension(path, &scene->r.im_format);
}
WM_cursor_wait(1);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 1ed1cbb2c6b..16d7923baff 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -33,6 +33,7 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -46,6 +47,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -56,6 +58,7 @@
#include "BKE_world.h"
#include "GPU_material.h"
+#include "GPU_buffers.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -232,6 +235,9 @@ static int nodes_use_material(bNodeTree *ntree, Material *ma)
static void material_changed(Main *bmain, Material *ma)
{
Material *parent;
+ Object *ob;
+ Scene *scene;
+ int texture_draw = FALSE;
/* icons */
BKE_icon_changed(BKE_icon_getid(&ma->id));
@@ -254,6 +260,33 @@ static void material_changed(Main *bmain, Material *ma)
if (parent->gpumaterial.first)
GPU_material_free(parent);
}
+
+ /* find if we have a scene with textured display */
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
+ if (scene->customdata_mask & CD_MASK_MTFACE) {
+ texture_draw = TRUE;
+ break;
+ }
+ }
+
+ /* find textured objects */
+ if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ DerivedMesh *dm = ob->derivedFinal;
+ Material ***material = give_matarar(ob);
+ short a, *totmaterial = give_totcolp(ob);
+
+ if (dm && totmaterial && material) {
+ for (a = 0; a < *totmaterial; a++) {
+ if ((*material)[a] == ma) {
+ GPU_drawobject_free(dm);
+ break;
+ }
+ }
+ }
+ }
+ }
+
}
static void lamp_changed(Main *bmain, Lamp *la)
@@ -277,28 +310,33 @@ static void lamp_changed(Main *bmain, Lamp *la)
GPU_material_free(&defmaterial);
}
+static int material_uses_texture(Material *ma, Tex *tex)
+{
+ if (mtex_use_tex(ma->mtex, MAX_MTEX, tex))
+ return TRUE;
+ else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex))
+ return TRUE;
+
+ return FALSE;
+}
+
static void texture_changed(Main *bmain, Tex *tex)
{
Material *ma;
Lamp *la;
World *wo;
Scene *scene;
+ Object *ob;
bNode *node;
+ int texture_draw = FALSE;
/* icons */
BKE_icon_changed(BKE_icon_getid(&tex->id));
/* find materials */
for (ma = bmain->mat.first; ma; ma = ma->id.next) {
- if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) {
- /* pass */
- }
- else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) {
- /* pass */
- }
- else {
+ if (!material_uses_texture(ma, tex))
continue;
- }
BKE_icon_changed(BKE_icon_getid(&ma->id));
@@ -342,6 +380,34 @@ static void texture_changed(Main *bmain, Tex *tex)
ED_node_changed_update(&scene->id, node);
}
}
+
+ if (scene->customdata_mask & CD_MASK_MTFACE)
+ texture_draw = TRUE;
+ }
+
+ /* find textured objects */
+ if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ DerivedMesh *dm = ob->derivedFinal;
+ Material ***material = give_matarar(ob);
+ short a, *totmaterial = give_totcolp(ob);
+
+ if (dm && totmaterial && material) {
+ for (a = 0; a < *totmaterial; a++) {
+ Material *ma;
+
+ if (ob->matbits && ob->matbits[a])
+ ma = ob->mat[a];
+ else
+ ma = (*material)[a];
+
+ if (ma && material_uses_texture(ma, tex)) {
+ GPU_drawobject_free(dm);
+ break;
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 5ec7f4d05b6..8b2ac740e47 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -35,6 +35,7 @@
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_blender.h"
#include "BKE_context.h"
@@ -151,9 +152,10 @@ void render_view_open(bContext *C, int mx, int my)
if (sizex < 320) sizex = 320;
if (sizey < 256) sizey = 256;
- /* XXX some magic to calculate postition */
- rect.xmin = mx + win->posx - sizex / 2;
- rect.ymin = my + win->posy - sizey / 2;
+ /* some magic to calculate postition */
+ /* pixelsize: mouse coords are in U.pixelsize units :/ */
+ rect.xmin = (mx / U.pixelsize) + win->posx - sizex / 2;
+ rect.ymin = (my / U.pixelsize) + win->posy - sizey / 2;
rect.xmax = rect.xmin + sizex;
rect.ymax = rect.ymin + sizey;
@@ -287,7 +289,10 @@ static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
/* is there another window showing result? */
for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) {
- if (win->screen->temp || (win == winshow && winshow != wincur)) {
+ bScreen *sc = win->screen;
+ if ((sc->temp && ((ScrArea *)sc->areabase.first)->spacetype == SPACE_IMAGE) ||
+ (win == winshow && winshow != wincur))
+ {
wm_window_raise(win);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript
index 0e894a13d28..c0a14ce5377 100644
--- a/source/blender/editors/screen/SConscript
+++ b/source/blender/editors/screen/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f30e0abb4f3..1b7cd4a6d20 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -235,8 +235,8 @@ static void region_draw_azone_icon(AZone *az)
static void draw_azone_plus(float x1, float y1, float x2, float y2)
{
- float width = 2.0f;
- float pad = 4.0f;
+ float width = 0.1f * U.widget_unit;
+ float pad = 0.2f * U.widget_unit;
glRectf((x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad);
glRectf(x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f);
@@ -395,47 +395,14 @@ void ED_area_overdraw(bContext *C)
}
-/* get scissor rect, checking overlapping regions */
-void region_scissor_winrct(ARegion *ar, rcti *winrct)
-{
- *winrct = ar->winrct;
-
- if (ELEM(ar->alignment, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT))
- return;
-
- while (ar->prev) {
- ar = ar->prev;
-
- if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) {
- if (ar->flag & RGN_FLAG_HIDDEN) {
- /* pass */
- }
- else if (ar->alignment & RGN_SPLIT_PREV) {
- /* pass */
- }
- else if (ar->alignment == RGN_OVERLAP_LEFT) {
- winrct->xmin = ar->winrct.xmax + 1;
- }
- else if (ar->alignment == RGN_OVERLAP_RIGHT) {
- winrct->xmax = ar->winrct.xmin - 1;
- }
- else break;
- }
- }
-}
-
/* only exported for WM */
/* makes region ready for drawing, sets pixelspace */
void ED_region_set(const bContext *C, ARegion *ar)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
- rcti winrct;
- /* checks other overlapping regions */
- region_scissor_winrct(ar, &winrct);
-
- ar->drawrct = winrct;
+ ar->drawrct = ar->winrct;
/* note; this sets state, so we can use wmOrtho and friends */
wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct);
@@ -452,24 +419,20 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
ARegionType *at = ar->type;
- rcti winrct;
/* see BKE_spacedata_draw_locks() */
if (at->do_lock)
return;
- /* checks other overlapping regions */
- region_scissor_winrct(ar, &winrct);
-
/* if no partial draw rect set, full rect */
if (ar->drawrct.xmin == ar->drawrct.xmax)
- ar->drawrct = winrct;
+ ar->drawrct = ar->winrct;
else {
/* extra clip for safety (intersect the rects, could use API func) */
- ar->drawrct.xmin = max_ii(winrct.xmin, ar->drawrct.xmin);
- ar->drawrct.ymin = max_ii(winrct.ymin, ar->drawrct.ymin);
- ar->drawrct.xmax = min_ii(winrct.xmax, ar->drawrct.xmax);
- ar->drawrct.ymax = min_ii(winrct.ymax, ar->drawrct.ymax);
+ ar->drawrct.xmin = max_ii(ar->winrct.xmin, ar->drawrct.xmin);
+ ar->drawrct.ymin = max_ii(ar->winrct.ymin, ar->drawrct.ymin);
+ ar->drawrct.xmax = min_ii(ar->winrct.xmax, ar->drawrct.xmax);
+ ar->drawrct.ymax = min_ii(ar->winrct.ymax, ar->drawrct.ymax);
}
/* note; this sets state, so we can use wmOrtho and friends */
@@ -483,7 +446,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
glClear(GL_COLOR_BUFFER_BIT);
UI_ThemeColor(TH_TEXT);
- BLF_draw_default(20, 8, 0.0f, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_draw_default(UI_UNIT_X, 0.4f * UI_UNIT_Y, 0.0f, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX);
}
else if (at->draw) {
at->draw(C, ar);
@@ -500,7 +463,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
uiFreeInactiveBlocks(C, &ar->uiblocks);
if (sa)
- region_draw_emboss(ar, &winrct);
+ region_draw_emboss(ar, &ar->winrct);
}
/* **********************************
@@ -611,8 +574,8 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa)
az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
BLI_addtail(&(sa->actionzones), az);
az->type = AZONE_AREA;
- az->x1 = sa->totrct.xmin - 1;
- az->y1 = sa->totrct.ymin - 1;
+ az->x1 = sa->totrct.xmin;
+ az->y1 = sa->totrct.ymin;
az->x2 = sa->totrct.xmin + (AZONESPOT - 1);
az->y2 = sa->totrct.ymin + (AZONESPOT - 1);
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
@@ -627,8 +590,8 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa)
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-#define AZONEPAD_EDGE 4
-#define AZONEPAD_ICON 9
+#define AZONEPAD_EDGE (0.2f * U.widget_unit)
+#define AZONEPAD_ICON (0.45f * U.widget_unit)
static void region_azone_edge(AZone *az, ARegion *ar)
{
switch (az->edge) {
@@ -720,8 +683,8 @@ static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar)
}
}
-#define AZONEPAD_TAB_PLUSW 14
-#define AZONEPAD_TAB_PLUSH 14
+#define AZONEPAD_TAB_PLUSW (0.7f * U.widget_unit)
+#define AZONEPAD_TAB_PLUSH (0.7f * U.widget_unit)
/* region already made zero sized, in shape of edge */
static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
@@ -736,28 +699,28 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0;
- az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW;
az->y1 = ar->winrct.ymax - add;
- az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW;
az->y2 = ar->winrct.ymax - add + AZONEPAD_TAB_PLUSH;
break;
case AE_BOTTOM_TO_TOPLEFT:
- az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW;
az->y1 = ar->winrct.ymin - AZONEPAD_TAB_PLUSH;
- az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW;
az->y2 = ar->winrct.ymin;
break;
case AE_LEFT_TO_TOPRIGHT:
az->x1 = ar->winrct.xmin - AZONEPAD_TAB_PLUSH;
- az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW;
az->x2 = ar->winrct.xmin;
- az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW;
break;
case AE_RIGHT_TO_TOPLEFT:
az->x1 = ar->winrct.xmax - 1;
- az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW;
az->x2 = ar->winrct.xmax - 1 + AZONEPAD_TAB_PLUSH;
- az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW;
break;
}
/* rect needed for mouse pointer test */
@@ -765,8 +728,8 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
}
-#define AZONEPAD_TABW 18
-#define AZONEPAD_TABH 7
+#define AZONEPAD_TABW (0.9f * U.widget_unit)
+#define AZONEPAD_TABH (0.35f * U.widget_unit)
/* region already made zero sized, in shape of edge */
static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar)
@@ -809,8 +772,8 @@ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar)
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-#define AZONEPAD_TRIAW 16
-#define AZONEPAD_TRIAH 9
+#define AZONEPAD_TRIAW (0.8f * U.widget_unit)
+#define AZONEPAD_TRIAH (0.45f * U.widget_unit)
/* region already made zero sized, in shape of edge */
@@ -892,9 +855,9 @@ static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment)
region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT);
else if (alignment == RGN_ALIGN_BOTTOM)
region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT);
- else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT))
+ else if (alignment == RGN_ALIGN_RIGHT)
region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT);
- else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT))
+ else if (alignment == RGN_ALIGN_LEFT)
region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT);
}
@@ -909,7 +872,58 @@ static int rct_fits(rcti *rect, char dir, int size)
}
}
-static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int quad)
+/* *************************************************************** */
+
+/* ar should be overlapping */
+/* function checks if some overlapping region was defined before - on same place */
+static void region_overlap_fix(ScrArea *sa, ARegion *ar)
+{
+ ARegion *ar1 = ar->prev;
+
+ /* find overlapping previous region on same place */
+ while (ar1) {
+ if (ar1->overlap) {
+ if ((ar1->alignment & RGN_SPLIT_PREV) == 0)
+ if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL))
+ break;
+ }
+ ar1 = ar1->prev;
+ }
+
+ /* translate or close */
+ if (ar1) {
+ int align1 = ar1->alignment & ~RGN_SPLIT_PREV;
+
+ if (align1 == RGN_ALIGN_LEFT) {
+ if (ar->winrct.xmax + ar1->winx > sa->winx - U.widget_unit)
+ ar->flag |= RGN_FLAG_TOO_SMALL;
+ else
+ BLI_rcti_translate(&ar->winrct, ar1->winx, 0);
+ }
+ else if (align1 == RGN_ALIGN_RIGHT) {
+ if (ar->winrct.xmin - ar1->winx < U.widget_unit)
+ ar->flag |= RGN_FLAG_TOO_SMALL;
+ else
+ BLI_rcti_translate(&ar->winrct, -ar1->winx, 0);
+ }
+ }
+
+
+
+}
+
+/* overlapping regions only in the following restricted cases */
+static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar)
+{
+ if (U.uiflag2 & USER_REGION_OVERLAP)
+ if (WM_is_draw_triple(win))
+ if (ELEM4(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP))
+ if (ELEM3(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS))
+ return 1;
+ return 0;
+}
+
+static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, int quad)
{
rcti *remainder_prev = remainder;
int prefsizex, prefsizey;
@@ -928,22 +942,26 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
alignment = ar->alignment & ~RGN_SPLIT_PREV;
+ /* set here, assuming userpref switching forces to call this again */
+ ar->overlap = region_is_overlap(win, sa, ar);
+
/* clear state flags first */
ar->flag &= ~RGN_FLAG_TOO_SMALL;
/* user errors */
if (ar->next == NULL && alignment != RGN_ALIGN_QSPLIT)
alignment = RGN_ALIGN_NONE;
- /* prefsize, for header we stick to exception */
- prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex;
+ /* prefsize, for header we stick to exception (prevent dpi rounding error) */
+ prefsizex = UI_DPI_FAC * (ar->sizex > 1 ? ar->sizex + 0.5f : ar->type->prefsizex);
+
if (ar->regiontype == RGN_TYPE_HEADER) {
- prefsizey = ar->type->prefsizey;
+ prefsizey = ED_area_headersize();
}
else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) {
prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2);
}
else {
- prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey;
+ prefsizey = UI_DPI_FAC * (ar->sizey > 1 ? ar->sizey + 0.5f : ar->type->prefsizey);
}
@@ -985,7 +1003,7 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
}
}
}
- else if (ELEM4(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) {
+ else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
if (rct_fits(remainder, 'h', prefsizex) < 0) {
ar->flag |= RGN_FLAG_TOO_SMALL;
@@ -998,14 +1016,14 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
ar->winrct = *remainder;
- if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) {
+ if (alignment == RGN_ALIGN_RIGHT) {
ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1;
- if (alignment == RGN_ALIGN_RIGHT)
+ if (ar->overlap == 0)
remainder->xmax = ar->winrct.xmin - 1;
}
else {
ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1;
- if (alignment == RGN_ALIGN_LEFT)
+ if (ar->overlap == 0)
remainder->xmin = ar->winrct.xmax + 1;
}
}
@@ -1082,6 +1100,15 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
+ /* if region opened normally, we store this for hide/reveal usage */
+ /* prevent rounding errors for UI_DPI_FAC mult and divide */
+ if (ar->winx > 1) ar->sizex = (ar->winx + 0.5f) / UI_DPI_FAC;
+ if (ar->winy > 1) ar->sizey = (ar->winy + 0.5f) / UI_DPI_FAC;
+
+ /* exception for multiple overlapping regions on same spot */
+ if (ar->overlap)
+ region_overlap_fix(sa, ar);
+
/* set winrect for azones */
if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) {
ar->winrct = *remainder;
@@ -1090,9 +1117,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
ar->winrct.ymin = ar->winrct.ymax;
else if (alignment == RGN_ALIGN_BOTTOM)
ar->winrct.ymax = ar->winrct.ymin;
- else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT))
+ else if (alignment == RGN_ALIGN_RIGHT)
ar->winrct.xmin = ar->winrct.xmax;
- else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT))
+ else if (alignment == RGN_ALIGN_LEFT)
ar->winrct.xmax = ar->winrct.xmin;
else /* prevent winrct to be valid */
ar->winrct.xmax = ar->winrct.xmin;
@@ -1121,12 +1148,12 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
region_azone_add(sa, ar, alignment);
}
- region_rect_recursive(sa, ar->next, remainder, quad);
+ region_rect_recursive(win, sa, ar->next, remainder, quad);
}
static void area_calc_totrct(ScrArea *sa, int sizex, int sizey)
{
- short rt = 0; // CLAMPIS(G.debug_value, 0, 16);
+ short rt = U.pixelsize > 1.0f ? 1 : 0;
if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + 1 + rt;
else sa->totrct.xmin = sa->v1->vec.x;
@@ -1229,14 +1256,14 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype);
/* area sizes */
- area_calc_totrct(sa, win->sizex, win->sizey);
+ area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win));
/* clear all azones, add the area triange widgets */
area_azone_initialize(win->screen, sa);
/* region rect sizes */
rect = sa->totrct;
- region_rect_recursive(sa, sa->regionbase.first, &rect, 0);
+ region_rect_recursive(win, sa, sa->regionbase.first, &rect, 0);
/* default area handlers */
ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag);
@@ -1273,22 +1300,38 @@ void ED_region_init(bContext *C, ARegion *ar)
ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
+ /* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */
+ BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+
/* UI convention */
wmOrtho2(-0.01f, ar->winx - 0.01f, -0.01f, ar->winy - 0.01f);
glLoadIdentity();
}
-void ED_region_toggle_hidden(bContext *C, ARegion *ar)
+/* for quick toggle, can skip fades */
+void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade)
{
ScrArea *sa = CTX_wm_area(C);
-
+
ar->flag ^= RGN_FLAG_HIDDEN;
+
+ if (do_fade && ar->overlap) {
+ /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */
+ region_blend_start(C, sa, ar);
+ }
+ else {
+ if (ar->flag & RGN_FLAG_HIDDEN)
+ WM_event_remove_handlers(C, &ar->handlers);
+
+ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
+ ED_area_tag_redraw(sa);
+ }
+}
- if (ar->flag & RGN_FLAG_HIDDEN)
- WM_event_remove_handlers(C, &ar->handlers);
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
+/* exported to all editors, uses fading default */
+void ED_region_toggle_hidden(bContext *C, ARegion *ar)
+{
+ region_toggle_hidden(C, ar, 1);
}
/* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
@@ -1441,7 +1484,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa)
{
SpaceLink *sl = (sa) ? sa->spacedata.first : CTX_wm_space_data(C);
- if (sl->next) {
+ if (sl && sl->next) {
/* workaround for case of double prevspace, render window
* with a file browser on top of it */
if (sl->next->spacetype == SPACE_FILE && sl->next->next)
@@ -1515,22 +1558,22 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
{
ScrArea *sa = CTX_wm_area(C);
uiBut *but;
- int xco = 8;
+ int xco = 0.4 * U.widget_unit;
but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D,
- editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y,
+ editortype_pup(), xco, yco, 1.5 * U.widget_unit, U.widget_unit,
&(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0,
TIP_("Display current editor type (click for a menu of available types)"));
uiButSetFunc(but, spacefunc, NULL, NULL);
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- return xco + UI_UNIT_X + 14;
+ return xco + 1.7 * U.widget_unit;
}
int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
{
ScrArea *sa = CTX_wm_area(C);
- int xco = 8;
+ int xco = 0.4 * U.widget_unit;
uiBut *but;
if (!sa->full)
@@ -1541,23 +1584,23 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
if (sa->flag & HEADER_NO_PULLDOWN) {
but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_RIGHT,
- xco, yco, UI_UNIT_X, UI_UNIT_Y - 2,
+ xco, yco, U.widget_unit, U.widget_unit * 0.9f,
&(sa->flag), 0, 0, 0, 0,
- "Show pulldown menus");
+ TIP_("Show pulldown menus"));
}
else {
but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_DOWN,
- xco, yco, UI_UNIT_X, UI_UNIT_Y - 2,
+ xco, yco, U.widget_unit, U.widget_unit * 0.9f,
&(sa->flag), 0, 0, 0, 0,
- "Hide pulldown menus");
+ TIP_("Hide pulldown menus"));
}
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
uiBlockSetEmboss(block, UI_EMBOSS);
- return xco + UI_UNIT_X;
+ return xco + U.widget_unit;
}
/************************ standard UI regions ************************/
@@ -1565,127 +1608,162 @@ int ED_area_header_standardbuttons(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_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiBlock *block;
PanelType *pt;
Panel *panel;
View2D *v2d = &ar->v2d;
View2DScrollers *scrollers;
int x, y, xco, yco, w, em, triangle, open, newcontext = 0;
+ int redo;
+ int scroll;
if (contextnr >= 0)
newcontext = UI_view2d_tab_set(v2d, contextnr);
-
+
+ /* before setting the view */
if (vertical) {
- w = BLI_rctf_size_x(&v2d->cur);
- em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ /* only allow scrolling in vertical direction */
+ v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y;
+ v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X);
+ v2d->scroll &= ~(V2D_SCROLL_BOTTOM);
+ v2d->scroll |= (V2D_SCROLL_RIGHT);
}
else {
- w = UI_PANEL_WIDTH;
- em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ /* for now, allow scrolling in both directions (since layouts are optimized for vertical,
+ * they often don't fit in horizontal layout)
+ */
+ v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
+ v2d->scroll |= (V2D_SCROLL_BOTTOM);
+ v2d->scroll &= ~(V2D_SCROLL_RIGHT);
}
- /* create panels */
- uiBeginPanels(C, ar);
+ scroll = v2d->scroll;
+
+ /* sortof hack - but we cannot predict the height of panels, until it's being generated */
+ /* the layout engine works with fixed width (from v2d->cur), which is being set at end of the loop */
+ /* in case scroller settings (hide flags) differ from previous, the whole loop gets done again */
+ for (redo = 2; redo > 0; redo--) {
+
+ if (vertical) {
+ w = BLI_rctf_size_x(&v2d->cur);
+ em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ }
+ else {
+ w = UI_PANEL_WIDTH;
+ em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ }
+
+ /* create panels */
+ uiBeginPanels(C, ar);
+
+ /* set view2d view matrix - uiBeginBlock() stores it */
+ UI_view2d_view_ortho(v2d);
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(v2d);
+ for (pt = ar->type->paneltypes.first; pt; pt = pt->next) {
+ /* verify context */
+ if (context)
+ if (pt->context[0] && strcmp(context, pt->context) != 0)
+ continue;
- for (pt = ar->type->paneltypes.first; pt; pt = pt->next) {
- /* verify context */
- if (context)
- if (pt->context[0] && strcmp(context, pt->context) != 0)
- continue;
+ /* draw panel */
+ if (pt->draw && (!pt->poll || pt->poll(C, pt))) {
+ block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
+ panel = uiBeginPanel(sa, ar, block, pt, &open);
- /* draw panel */
- if (pt->draw && (!pt->poll || pt->poll(C, pt))) {
- block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
- panel = uiBeginPanel(sa, ar, block, pt, &open);
+ /* bad fixed values */
+ triangle = (int)(UI_UNIT_Y * 1.1f);
- /* 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, style);
- 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 + style->panelspace + 2, UI_UNIT_Y, 1, style);
+ pt->draw_header(C, panel);
- pt->draw_header(C, panel);
+ uiBlockLayoutResolve(block, &xco, &yco);
+ panel->labelofs = xco - triangle;
+ panel->layout = NULL;
+ }
+ else {
+ panel->labelofs = 0;
+ }
- uiBlockLayoutResolve(block, &xco, &yco);
- panel->labelofs = xco - triangle;
- panel->layout = NULL;
- }
- else {
- panel->labelofs = 0;
- }
+ if (open) {
+ short panelContext;
+
+ /* panel context can either be toolbar region or normal panels region */
+ if (ar->regiontype == RGN_TYPE_TOOLS)
+ panelContext = UI_LAYOUT_TOOLBAR;
+ else
+ panelContext = UI_LAYOUT_PANEL;
+
+ panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext,
+ style->panelspace, 0, w - 2 * style->panelspace, em, style);
- if (open) {
- short panelContext;
-
- /* panel context can either be toolbar region or normal panels region */
- if (ar->regiontype == RGN_TYPE_TOOLS)
- panelContext = UI_LAYOUT_TOOLBAR;
- else
- panelContext = UI_LAYOUT_PANEL;
-
- panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext,
- style->panelspace, 0, w - 2 * style->panelspace, em, style);
+ pt->draw(C, panel);
- pt->draw(C, panel);
+ uiBlockLayoutResolve(block, &xco, &yco);
+ panel->layout = NULL;
- uiBlockLayoutResolve(block, &xco, &yco);
- panel->layout = NULL;
+ yco -= 2 * style->panelspace;
+ uiEndPanel(block, w, -yco);
+ }
+ else {
+ yco = 0;
+ uiEndPanel(block, w, 0);
+ }
- yco -= 2 * style->panelspace;
- uiEndPanel(block, w, -yco);
- }
- else {
- yco = 0;
- uiEndPanel(block, w, 0);
+ uiEndBlock(C, block);
}
+ }
- uiEndBlock(C, block);
+ /* align panels and return size */
+ uiEndPanels(C, ar, &x, &y);
+
+ /* before setting the view */
+ if (vertical) {
+ /* we always keep the scroll offset - so the total view gets increased with the scrolled away part */
+ if (v2d->cur.ymax < - 0.001f)
+ y = min_ii(y, v2d->cur.ymin);
+
+ y = -y;
}
+ else {
+ /* don't jump back when panels close or hide */
+ if (!newcontext)
+ x = max_ii(x, v2d->cur.xmax);
+ y = -y;
+ }
+
+ /* this also changes the 'cur' */
+ UI_view2d_totRect_set(v2d, x, y);
+
+ if (scroll != v2d->scroll) {
+ /* Note: this code scales fine, but because of rounding differences, positions of elements
+ * flip +1 or -1 pixel compared to redoing the entire layout again.
+ * Leaving in commented code for future tests */
+ /* uiScalePanels(ar, BLI_rctf_size_x(&v2d->cur));
+ break; */
+ }
+ else break;
}
-
- /* align panels and return size */
- uiEndPanels(C, ar, &x, &y);
-
- /* clear */
- UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
- glClear(GL_COLOR_BUFFER_BIT);
- /* before setting the view */
- if (vertical) {
- /* only allow scrolling in vertical direction */
- v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y;
- v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X);
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE;
-
- /* ensure tot is set correctly, to keep views on bottons, with sliders */
- y = min_ii(y, v2d->cur.ymin);
- y = -y;
+
+ /* clear */
+ if (ar->overlap) {
+ /* view should be in pixelspace */
+ UI_view2d_view_restore(C);
+ glEnable(GL_BLEND);
+ UI_ThemeColor4((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
+ glRecti(0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+ glDisable(GL_BLEND);
}
else {
- /* for now, allow scrolling in both directions (since layouts are optimized for vertical,
- * they often don't fit in horizontal layout)
- */
- v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
- //v2d->keepofs |= V2D_LOCKOFS_Y|V2D_KEEPOFS_X;
- //v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_KEEPOFS_Y);
- v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
- v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_HIDE;
-
- /* don't jump back when panels close or hide */
- if (!newcontext)
- x = max_ii(x, v2d->cur.xmax);
- y = -y;
+ UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
+ glClear(GL_COLOR_BUFFER_BIT);
}
-
- /* +V2D_SCROLL_HEIGHT is workaround to set the actual height */
- UI_view2d_totRect_set(v2d, x + V2D_SCROLL_WIDTH, y + V2D_SCROLL_HEIGHT);
+
/* set the view */
UI_view2d_view_ortho(v2d);
@@ -1705,17 +1783,6 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
- /* XXX quick hacks for files saved with 2.5 already (i.e. the builtin defaults file)
- * scrollbars for button regions */
- ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
- ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- ar->v2d.scroll &= ~V2D_SCROLL_VERTICAL_HIDE;
- ar->v2d.keepzoom |= V2D_KEEPZOOM;
-
- /* correctly initialized User-Prefs? */
- if (!(ar->v2d.align & V2D_ALIGN_NO_POS_Y))
- ar->v2d.flag &= ~V2D_IS_INITIALISED;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
@@ -1725,7 +1792,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
void ED_region_header(const bContext *C, ARegion *ar)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiBlock *block;
uiLayout *layout;
HeaderType *ht;
@@ -1740,8 +1807,8 @@ void ED_region_header(const bContext *C, ARegion *ar)
/* set view2d view matrix for scrolling (without scrollers) */
UI_view2d_view_ortho(&ar->v2d);
- xco = maxco = 8;
- yco = headery - 4;
+ xco = maxco = 0.4f * UI_UNIT_X;
+ yco = headery - floor(0.2f * UI_UNIT_Y);
/* draw all headers types */
for (ht = ar->type->headertypes.first; ht; ht = ht->next) {
@@ -1778,35 +1845,30 @@ void ED_region_header(const bContext *C, ARegion *ar)
void ED_region_header_init(ARegion *ar)
{
+ ar->v2d.flag &= ~V2D_IS_INITIALISED;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
}
/* UI_UNIT_Y is defined as U variable now, depending dpi */
int ED_area_headersize(void)
{
- return UI_UNIT_Y + 6;
+ return (int)(1.3f * UI_UNIT_Y);
}
void ED_region_info_draw(ARegion *ar, const char *text, int block, float alpha)
{
- const int header_height = 18;
- uiStyle *style = UI_GetStyle();
+ const int header_height = UI_UNIT_Y;
+ uiStyle *style = UI_GetStyleDraw();
int fontid = style->widget.uifont_id;
rcti rect;
- BLF_size(fontid, 11.0f, 72);
-
/* background box */
- rect = ar->winrct;
- rect.xmin = 0;
+ ED_region_visible_rect(ar, &rect);
rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height;
- if (block) {
- rect.xmax = BLI_rcti_size_x(&ar->winrct);
- }
- else {
- rect.xmax = rect.xmin + BLF_width(fontid, text) + 24;
- }
+ /* box fill entire width or just around text */
+ if (!block)
+ rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, text) + 1.2f * U.widget_unit);
rect.ymax = BLI_rcti_size_y(&ar->winrct);
@@ -1818,8 +1880,13 @@ void ED_region_info_draw(ARegion *ar, const char *text, int block, float alpha)
/* text */
UI_ThemeColor(TH_TEXT_HI);
- BLF_position(fontid, 12, rect.ymin + 5, 0.0f);
+ BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ BLF_enable(fontid, BLF_CLIPPING);
+ BLF_position(fontid, rect.xmin + 0.6f * U.widget_unit, rect.ymin + 0.3f * U.widget_unit, 0.0f);
+
BLF_draw(fontid, text, BLF_DRAW_STR_DUMMY_MAX);
+
+ BLF_disable(fontid, BLF_CLIPPING);
}
void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
@@ -1881,3 +1948,34 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
}
glEnd();
}
+
+/* If the area has overlapping regions, it returns visible rect for Region *ar */
+/* rect gets returned in local region coordinates */
+void ED_region_visible_rect(ARegion *ar, rcti *rect)
+{
+ ARegion *arn = ar;
+
+ /* allow function to be called without area */
+ while (arn->prev)
+ arn = arn->prev;
+
+ *rect = ar->winrct;
+
+ /* check if a region overlaps with the current one */
+ for (; arn; arn = arn->next) {
+ if (ar != arn && arn->overlap) {
+ if (BLI_rcti_isect(rect, &arn->winrct, NULL)) {
+
+ /* overlap left, also check 1 pixel offset (2 regions on one side) */
+ if (ABS(rect->xmin - arn->winrct.xmin) < 2)
+ rect->xmin = arn->winrct.xmax;
+
+ /* overlap right */
+ if (ABS(rect->xmax - arn->winrct.xmax) < 2)
+ rect->xmax = arn->winrct.xmin;
+ }
+ }
+ }
+ BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
+}
+
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index ce2d045dc80..105c2dc88d1 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -33,16 +33,17 @@
#include "MEM_guardedalloc.h"
+#include "DNA_userdef_types.h"
#include "DNA_vec_types.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
-
-#include "BKE_colortools.h"
-
#include "BLI_math.h"
#include "BLI_threads.h"
+#include "BKE_blender.h"
+#include "BKE_colortools.h"
+
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -54,7 +55,7 @@
/* ******************************************** */
/* defined in BIF_gl.h */
-GLubyte stipple_halftone[128] = {
+const GLubyte stipple_halftone[128] = {
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
@@ -81,7 +82,7 @@ GLubyte stipple_halftone[128] = {
* 00000000 */
-GLubyte stipple_quarttone[128] = {
+const GLubyte stipple_quarttone[128] = {
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
@@ -92,7 +93,7 @@ GLubyte stipple_quarttone[128] = {
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0};
-GLubyte stipple_diag_stripes_pos[128] = {
+const GLubyte stipple_diag_stripes_pos[128] = {
0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
@@ -111,7 +112,7 @@ GLubyte stipple_diag_stripes_pos[128] = {
0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f};
-GLubyte stipple_diag_stripes_neg[128] = {
+const GLubyte stipple_diag_stripes_neg[128] = {
0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
@@ -292,7 +293,10 @@ void setlinestyle(int nr)
else {
glEnable(GL_LINE_STIPPLE);
- glLineStipple(nr, 0xAAAA);
+ if (U.pixelsize > 1.0f)
+ glLineStipple(nr, 0xCCCC);
+ else
+ glLineStipple(nr, 0xAAAA);
}
}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 60aad14efcf..7c22dff1b01 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -263,6 +263,9 @@ int scredge_is_horizontal(ScrEdge *se)
ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
{
ScrEdge *se;
+ int safety = U.widget_unit / 10;
+
+ if (safety < 2) safety = 2;
for (se = sc->edgebase.first; se; se = se->next) {
if (scredge_is_horizontal(se)) {
@@ -270,7 +273,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
min = MIN2(se->v1->vec.x, se->v2->vec.x);
max = MAX2(se->v1->vec.x, se->v2->vec.x);
- if (abs(my - se->v1->vec.y) <= 2 && mx >= min && mx <= max)
+ if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max)
return se;
}
else {
@@ -278,7 +281,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
min = MIN2(se->v1->vec.y, se->v2->vec.y);
max = MAX2(se->v1->vec.y, se->v2->vec.y);
- if (abs(mx - se->v1->vec.x) <= 2 && my >= min && my <= max)
+ if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max)
return se;
}
}
@@ -428,9 +431,9 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name)
sc->winid = win->winid;
sv1 = screen_addvert(sc, 0, 0);
- sv2 = screen_addvert(sc, 0, win->sizey - 1);
- sv3 = screen_addvert(sc, win->sizex - 1, win->sizey - 1);
- sv4 = screen_addvert(sc, win->sizex - 1, 0);
+ sv2 = screen_addvert(sc, 0, WM_window_pixels_y(win) - 1);
+ sv3 = screen_addvert(sc, WM_window_pixels_x(win) - 1, WM_window_pixels_y(win) - 1);
+ sv4 = screen_addvert(sc, WM_window_pixels_x(win) - 1, 0);
screen_addedge(sc, sv1, sv2);
screen_addedge(sc, sv2, sv3);
@@ -628,7 +631,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
float facx, facy, tempf, min[2], max[2];
/* calculate size */
- min[0] = min[1] = 10000.0f;
+ min[0] = min[1] = 20000.0f;
max[0] = max[1] = 0.0f;
for (sv = sc->vertbase.first; sv; sv = sv->next) {
@@ -676,7 +679,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
/* make each window at least ED_area_headersize() high */
for (sa = sc->areabase.first; sa; sa = sa->next) {
- int headery = ED_area_headersize() + 1;
+ int headery = ED_area_headersize() + U.pixelsize;
if (sa->v1->vec.y + headery > sa->v2->vec.y) {
/* lower edge */
@@ -907,18 +910,18 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center)
short y1 = sa->v1->vec.y;
short x2 = sa->v3->vec.x;
short y2 = sa->v3->vec.y;
- short a, rt;
-
- rt = 0; // CLAMPIS(G.debug_value, 0, 16);
if (center == 0) {
- cpack(0x505050);
- for (a = -rt; a <= rt; a++)
- if (a != 0)
- drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, a);
+ if (U.pixelsize > 1.0f) {
+
+ glColor3ub(0x50, 0x50, 0x50);
+ glLineWidth(1.5f * U.pixelsize);
+ drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0);
+ glLineWidth(1.0f);
+ }
}
else {
- cpack(0x0);
+ glColor3ub(0, 0, 0);
drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0);
}
}
@@ -1002,10 +1005,10 @@ void ED_screen_draw(wmWindow *win)
if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa;
if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa;
if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa;
- drawscredge_area(sa, win->sizex, win->sizey, 0);
+ drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 0);
}
for (sa = win->screen->areabase.first; sa; sa = sa->next)
- drawscredge_area(sa, win->sizex, win->sizey, 1);
+ drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 1);
/* blended join arrow */
if (sa1 && sa2) {
@@ -1078,20 +1081,20 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
rcti winrct;
winrct.xmin = 0;
- winrct.xmax = win->sizex - 1;
+ winrct.xmax = WM_window_pixels_x(win) - 1;
winrct.ymin = 0;
- winrct.ymax = win->sizey - 1;
+ winrct.ymax = WM_window_pixels_y(win) - 1;
+
+ /* header size depends on DPI, let's verify */
+ screen_refresh_headersizes();
- screen_test_scale(win->screen, win->sizex, win->sizey);
+ screen_test_scale(win->screen, WM_window_pixels_x(win), WM_window_pixels_y(win));
if (win->screen->mainwin == 0)
win->screen->mainwin = wm_subwindow_open(win, &winrct);
else
wm_subwindow_position(win, win->screen->mainwin, &winrct);
- /* header size depends on DPI, let's verify */
- screen_refresh_headersizes();
-
for (sa = win->screen->areabase.first; sa; sa = sa->next) {
/* set spacetype and region callbacks, calls init() */
/* sets subwindows for regions, adds handlers */
@@ -1142,6 +1145,9 @@ void ED_region_exit(bContext *C, ARegion *ar)
MEM_freeN(ar->headerstr);
ar->headerstr = NULL;
+ if (ar->regiontimer)
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ar->regiontimer);
+
CTX_wm_region_set(C, prevar);
}
@@ -1262,9 +1268,12 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
break;
}
if (sa) {
+ /* make overlap active when mouse over */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x))
+ if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
scr->subwinactive = ar->swinid;
+ break;
+ }
}
}
else
@@ -1293,6 +1302,7 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
screen_cursor_set(win, event);
}
else {
+ /* notifier invokes freeing the buttons... causing a bit too much redraws */
if (oldswin != scr->subwinactive) {
region_cursor_set(win, scr->subwinactive, TRUE);
WM_event_add_notifier(C, NC_SCREEN | ND_SUBWINACTIVE, scr);
@@ -1327,13 +1337,14 @@ int ED_screen_area_active(const bContext *C)
/* Do NOT call in area/region queues! */
void ED_screen_set(bContext *C, bScreen *sc)
{
+ Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
bScreen *oldscreen = CTX_wm_screen(C);
ID *id;
/* validate screen, it's called with notifier reference */
- for (id = CTX_data_main(C)->screen.first; id; id = id->next)
+ for (id = bmain->screen.first; id; id = id->next)
if (sc == (bScreen *)id)
break;
if (id == NULL)
@@ -1345,7 +1356,7 @@ void ED_screen_set(bContext *C, bScreen *sc)
if (sc->full) { /* find associated full */
bScreen *sc1;
- for (sc1 = CTX_data_main(C)->screen.first; sc1; sc1 = sc1->id.next) {
+ for (sc1 = bmain->screen.first; sc1; sc1 = sc1->id.next) {
ScrArea *sa = sc1->areabase.first;
if (sa->full == sc) {
sc = sc1;
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 86d99777e98..b811fc46188 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -35,10 +35,11 @@
struct wmWindow;
struct Scene;
-#define AZONESPOT 12
+#define AZONESPOT (0.6f * U.widget_unit)
/* area.c */
void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space);
+void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade);
/* screen_edit.c */
ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2);
@@ -57,12 +58,16 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my);
struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]);
/* screen_context.c */
-int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result);
+int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result);
extern const char *screen_context_dir[]; /* doc access */
/* screendump.c */
-void SCREEN_OT_screenshot(struct wmOperatorType *ot);
-void SCREEN_OT_screencast(struct wmOperatorType *ot);
+void SCREEN_OT_screenshot(struct wmOperatorType *ot);
+void SCREEN_OT_screencast(struct wmOperatorType *ot);
+
+/* screen_ops.c */
+void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar);
+
#endif /* __SCREEN_INTERN_H__ */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 67d4af916aa..12a7a33c893 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -140,9 +140,11 @@ static int screen_active_editable(bContext *C)
/* when mouse is over area-edge */
int ED_operator_screen_mainwinactive(bContext *C)
{
+ bScreen *screen;
if (CTX_wm_window(C) == NULL) return 0;
- if (CTX_wm_screen(C) == NULL) return 0;
- if (CTX_wm_screen(C)->subwinactive != CTX_wm_screen(C)->mainwin) return 0;
+ screen = CTX_wm_screen(C);
+ if (screen == NULL) return 0;
+ if (screen->subwinactive != screen->mainwin) return 0;
return 1;
}
@@ -358,7 +360,7 @@ int ED_operator_editarmature(bContext *C)
/**
* \brief check for pose mode (no mixed modes)
*
- * We wan't to enable most pose operations in weight paint mode,
+ * We want to enable most pose operations in weight paint mode,
* when it comes to transforming bones, but managing bomes layers/groups
* can be left for pose mode only. (not weight paint mode)
*/
@@ -727,7 +729,7 @@ static int actionzone_cancel(bContext *UNUSED(C), wmOperator *op)
static void SCREEN_OT_actionzone(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Handle area action zones";
+ ot->name = "Handle Area Action Zones";
ot->description = "Handle area action zones for mouse actions/gestures";
ot->idname = "SCREEN_OT_actionzone";
@@ -849,7 +851,7 @@ static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event)
static void SCREEN_OT_area_swap(wmOperatorType *ot)
{
- ot->name = "Swap areas";
+ ot->name = "Swap Areas";
ot->description = "Swap selected areas screen positions";
ot->idname = "SCREEN_OT_area_swap";
@@ -965,7 +967,7 @@ typedef struct sAreaMoveData {
static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller)
{
ScrArea *sa;
- int areaminy = ED_area_headersize() + 1;
+ int areaminy = ED_area_headersize() + U.pixelsize; // pixelsize is used as area divider
/* we check all areas and test for free space with MINSIZE */
*bigger = *smaller = 100000;
@@ -975,18 +977,18 @@ static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller
int y1 = sa->v2->vec.y - sa->v1->vec.y - areaminy;
/* if top or down edge selected, test height */
- if (sa->v1->flag && sa->v4->flag)
+ if (sa->v1->editflag && sa->v4->editflag)
*bigger = min_ii(*bigger, y1);
- else if (sa->v2->flag && sa->v3->flag)
+ else if (sa->v2->editflag && sa->v3->editflag)
*smaller = min_ii(*smaller, y1);
}
else {
int x1 = sa->v4->vec.x - sa->v1->vec.x - AREAMINX;
/* if left or right edge selected, test width */
- if (sa->v1->flag && sa->v2->flag)
+ if (sa->v1->editflag && sa->v2->editflag)
*bigger = min_ii(*bigger, x1);
- else if (sa->v3->flag && sa->v4->flag)
+ else if (sa->v3->editflag && sa->v4->editflag)
*smaller = min_ii(*smaller, x1);
}
}
@@ -999,6 +1001,7 @@ static int area_move_init(bContext *C, wmOperator *op)
bScreen *sc = CTX_wm_screen(C);
ScrEdge *actedge;
sAreaMoveData *md;
+ ScrVert *v1;
int x, y;
/* required properties */
@@ -1017,7 +1020,9 @@ static int area_move_init(bContext *C, wmOperator *op)
else md->origval = actedge->v1->vec.x;
select_connected_scredge(sc, actedge);
- /* now all vertices with 'flag==1' are the ones that can be moved. */
+ /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */
+ for (v1 = sc->vertbase.first; v1; v1 = v1->next)
+ v1->editflag = v1->flag;
area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller);
@@ -1036,27 +1041,27 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int
delta = CLAMPIS(delta, -smaller, bigger);
for (v1 = sc->vertbase.first; v1; v1 = v1->next) {
- if (v1->flag) {
+ if (v1->editflag) {
/* that way a nice AREAGRID */
- if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < win->sizex - 1) {
+ if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < WM_window_pixels_x(win) - 1) {
v1->vec.x = origval + delta;
if (delta != bigger && delta != -smaller) v1->vec.x -= (v1->vec.x % AREAGRID);
}
- if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < win->sizey - 1) {
+ if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < WM_window_pixels_y(win) - 1) {
v1->vec.y = origval + delta;
v1->vec.y += AREAGRID - 1;
v1->vec.y -= (v1->vec.y % AREAGRID);
/* prevent too small top header */
- if (v1->vec.y > win->sizey - areaminy)
- v1->vec.y = win->sizey - areaminy;
+ if (v1->vec.y > WM_window_pixels_y(win) - areaminy)
+ v1->vec.y = WM_window_pixels_y(win) - areaminy;
}
}
}
for (sa = sc->areabase.first; sa; sa = sa->next) {
- if (sa->v1->flag || sa->v2->flag || sa->v3->flag || sa->v4->flag)
+ if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag)
ED_area_tag_redraw(sa);
}
@@ -1164,7 +1169,7 @@ static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event)
static void SCREEN_OT_area_move(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Move area edges";
+ ot->name = "Move Area Edges";
ot->description = "Move selected area edges";
ot->idname = "SCREEN_OT_area_move";
@@ -1334,10 +1339,10 @@ static int area_split_apply(bContext *C, wmOperator *op)
/* select newly created edge, prepare for moving edge */
for (sv = sc->vertbase.first; sv; sv = sv->next)
- sv->flag = 0;
+ sv->editflag = 0;
- sd->nedge->v1->flag = 1;
- sd->nedge->v2->flag = 1;
+ sd->nedge->v1->editflag = 1;
+ sd->nedge->v2->editflag = 1;
if (dir == 'h') sd->origval = sd->nedge->v1->vec.y;
else sd->origval = sd->nedge->v1->vec.x;
@@ -1720,9 +1725,9 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* if not set we do now, otherwise it uses type */
if (rmd->ar->sizex == 0)
- rmd->ar->sizex = rmd->ar->type->prefsizex;
+ rmd->ar->sizex = rmd->ar->winx;
if (rmd->ar->sizey == 0)
- rmd->ar->sizey = rmd->ar->type->prefsizey;
+ rmd->ar->sizey = rmd->ar->winy;
/* now copy to regionmovedata */
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
@@ -1734,7 +1739,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* limit headers to standard height for now */
if (rmd->ar->regiontype == RGN_TYPE_HEADER)
- maxsize = rmd->ar->type->prefsizey;
+ maxsize = ED_area_headersize();
else
maxsize = 1000;
@@ -1754,7 +1759,7 @@ static int region_scale_get_maxsize(RegionMoveData *rmd)
int maxsize = 0;
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
- return rmd->sa->winx - UI_UNIT_X;
+ return (int) ( (rmd->sa->winx / UI_DPI_FAC) - UI_UNIT_X);
}
if (rmd->ar->regiontype == RGN_TYPE_TOOL_PROPS) {
@@ -1786,7 +1791,7 @@ static void region_scale_validate_size(RegionMoveData *rmd)
static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd)
{
- ED_region_toggle_hidden(C, rmd->ar);
+ region_toggle_hidden(C, rmd->ar, 0);
region_scale_validate_size(rmd);
}
@@ -1803,6 +1808,9 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
delta = event->x - rmd->origx;
if (rmd->edge == AE_LEFT_TO_TOPRIGHT) delta = -delta;
+ /* region sizes now get multiplied */
+ delta /= UI_DPI_FAC;
+
rmd->ar->sizex = rmd->origval + delta;
CLAMP(rmd->ar->sizex, 0, rmd->maxsize);
@@ -1819,6 +1827,9 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
delta = event->y - rmd->origy;
if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) delta = -delta;
+ /* region sizes now get multiplied */
+ delta /= UI_DPI_FAC;
+
rmd->ar->sizey = rmd->origval + delta;
CLAMP(rmd->ar->sizey, 0, rmd->maxsize);
@@ -2557,7 +2568,7 @@ static int spacedata_cleanup(bContext *C, wmOperator *op)
static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Clean-up space-data";
+ ot->name = "Clean-up Space-data";
ot->description = "Remove unused settings for invisible editors";
ot->idname = "SCREEN_OT_spacedata_cleanup";
@@ -2797,7 +2808,6 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot)
}
-
/* ************** region flip operator ***************************** */
/* flip a region alignment */
@@ -2953,7 +2963,7 @@ static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *U
uiPopupMenu *pup;
uiLayout *layout;
- pup = uiPupMenuBegin(C, N_("Header"), ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Header"), ICON_NONE);
layout = uiPupMenuLayout(pup);
ED_screens_header_tools_menu_create(C, layout, NULL);
@@ -3358,7 +3368,7 @@ static int border_select_do(bContext *C, wmOperator *op)
static void SCREEN_OT_border_select(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Border select";
+ ot->name = "Border Select";
ot->idname = "SCREEN_OT_border_select";
/* api callbacks */
@@ -3413,6 +3423,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
{
+ wmWindow *win = CTX_wm_window(C);
rcti rect;
int sizex, sizey;
@@ -3420,8 +3431,9 @@ static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *ev
sizey = 480;
/* some magic to calculate postition */
- rect.xmin = event->x + CTX_wm_window(C)->posx - sizex / 2;
- rect.ymin = event->y + CTX_wm_window(C)->posy - sizey / 2;
+ /* pixelsize: mouse coords are in U.pixelsize units :/ */
+ rect.xmin = (event->x / U.pixelsize) + win->posx - sizex / 2;
+ rect.ymin = (event->y / U.pixelsize) + win->posy - sizey / 2;
rect.xmax = rect.xmin + sizex;
rect.ymax = rect.ymin + sizey;
@@ -3506,7 +3518,7 @@ static int scene_new_exec(bContext *C, wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
if (type == SCE_COPY_NEW) {
- newscene = BKE_scene_add("Scene");
+ newscene = BKE_scene_add(bmain, "Scene");
}
else { /* different kinds of copying */
newscene = BKE_scene_copy(scene, type);
@@ -3583,6 +3595,149 @@ static void SCENE_OT_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* ***************** region alpha blending ***************** */
+
+/* implementation note: a disappearing region needs at least 1 last draw with 100% backbuffer
+ * texture over it- then triple buffer will clear it entirely.
+ * This because flag RGN_HIDDEN is set in end - region doesnt draw at all then */
+
+typedef struct RegionAlphaInfo {
+ ScrArea *sa;
+ ARegion *ar, *child_ar; /* other region */
+ int hidden;
+} RegionAlphaInfo;
+
+#define TIMEOUT 0.2f
+#define TIMESTEP 0.04f
+
+float ED_region_blend_factor(ARegion *ar)
+{
+ /* check parent too */
+ if (ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) {
+ ar = ar->prev;
+ }
+
+ if (ar->regiontimer) {
+ RegionAlphaInfo *rgi = ar->regiontimer->customdata;
+ float alpha;
+
+ alpha = (float)ar->regiontimer->duration / TIMEOUT;
+ /* makes sure the blend out works 100% - without area redraws */
+ if (rgi->hidden) alpha = 0.9f - TIMESTEP - alpha;
+
+ CLAMP(alpha, 0.0f, 1.0f);
+ return alpha;
+ }
+ return 1.0f;
+}
+
+/* assumes region has running region-blend timer */
+static void region_blend_end(bContext *C, ARegion *ar, int is_running)
+{
+ RegionAlphaInfo *rgi = ar->regiontimer->customdata;
+
+ /* always send redraw */
+ ED_region_tag_redraw(ar);
+ if (rgi->child_ar)
+ ED_region_tag_redraw(rgi->child_ar);
+
+ /* if running timer was hiding, the flag toggle went wrong */
+ if (is_running) {
+ if (rgi->hidden)
+ rgi->ar->flag &= ~RGN_FLAG_HIDDEN;
+ }
+ else {
+ if (rgi->hidden) {
+ rgi->ar->flag |= rgi->hidden;
+ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->sa);
+ }
+ /* area decoration needs redraw in end */
+ ED_area_tag_redraw(rgi->sa);
+ }
+ WM_event_remove_timer(CTX_wm_manager(C), NULL, ar->regiontimer); /* frees rgi */
+ ar->regiontimer = NULL;
+
+}
+/* assumes that *ar itself is not a splitted version from previous region */
+void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ RegionAlphaInfo *rgi;
+
+ /* end running timer */
+ if (ar->regiontimer) {
+
+ region_blend_end(C, ar, 1);
+ }
+ rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo");
+
+ rgi->hidden = ar->flag & RGN_FLAG_HIDDEN;
+ rgi->sa = sa;
+ rgi->ar = ar;
+ ar->flag &= ~RGN_FLAG_HIDDEN;
+
+ /* blend in, reinitialize regions because it got unhidden */
+ if (rgi->hidden == 0)
+ ED_area_initialize(wm, win, sa);
+ else
+ WM_event_remove_handlers(C, &ar->handlers);
+
+ if (ar->next) {
+ if (ar->next->alignment & RGN_SPLIT_PREV) {
+ rgi->child_ar = ar->next;
+ }
+ }
+
+ /* new timer */
+ ar->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP);
+ ar->regiontimer->customdata = rgi;
+
+}
+
+/* timer runs in win->handlers, so it cannot use context to find area/region */
+static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+ RegionAlphaInfo *rgi;
+ wmTimer *timer = event->customdata;
+
+ /* event type is TIMERREGION, but we better check */
+ if (event->type != TIMERREGION || timer == NULL)
+ return OPERATOR_PASS_THROUGH;
+
+ rgi = timer->customdata;
+
+ /* always send redraws */
+ ED_region_tag_redraw(rgi->ar);
+ if (rgi->child_ar)
+ ED_region_tag_redraw(rgi->child_ar);
+
+ /* end timer? */
+ if (rgi->ar->regiontimer->duration > (double)TIMEOUT) {
+ region_blend_end(C, rgi->ar, 0);
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+ }
+
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+}
+
+static void SCREEN_OT_region_blend(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Region Alpha";
+ ot->idname = "SCREEN_OT_region_blend";
+ ot->description = "Blend in and out overlapping region";
+
+ /* api callbacks */
+ ot->invoke = region_blend_invoke;
+
+ /* flags */
+ ot->flag = 0;
+
+ /* properties */
+}
+
+
/* **************** Assigning operatortypes to global list, adding handlers **************** */
@@ -3615,6 +3770,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_screenshot);
WM_operatortype_append(SCREEN_OT_screencast);
WM_operatortype_append(SCREEN_OT_userpref_show);
+ WM_operatortype_append(SCREEN_OT_region_blend);
/*frame changes*/
WM_operatortype_append(SCREEN_OT_frame_offset);
@@ -3717,6 +3873,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* standard timers */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0);
+ WM_keymap_add_item(keymap, "SCREEN_OT_region_blend", TIMERREGION, KM_ANY, KM_ANY, 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index ca85daadf3b..1f7fee313b3 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -86,8 +86,8 @@ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy)
x = 0;
y = 0;
- *dumpsx = win->sizex;
- *dumpsy = win->sizey;
+ *dumpsx = WM_window_pixels_x(win);
+ *dumpsy = WM_window_pixels_y(win);
if (*dumpsx && *dumpsy) {
@@ -223,7 +223,7 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)
static int screenshot_check(bContext *UNUSED(C), wmOperator *op)
{
ScreenshotData *scd = op->customdata;
- return WM_operator_filesel_ensure_ext_imtype(op, scd->im_format.imtype);
+ return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format);
}
static int screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
@@ -272,7 +272,8 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
- RNA_def_boolean(ot->srna, "full", 1, "Full Screen", "Screenshot the whole Blender window");
+ RNA_def_boolean(ot->srna, "full", 1, "Full Screen",
+ "Capture the whole window (otherwise only capture the active area)");
}
/* *************** screenshot movie job ************************* */
@@ -361,7 +362,7 @@ 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.imtype, rd.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, &rd.im_format, rd.scemode & R_EXTENSION, TRUE);
ibuf->rect = sj->dumprect;
ok = BKE_imbuf_write(ibuf, name, &rd.im_format);
@@ -457,8 +458,8 @@ static int screencast_exec(bContext *C, wmOperator *op)
wmWindow *win = CTX_wm_window(C);
sj->x = 0;
sj->y = 0;
- sj->dumpsx = win->sizex;
- sj->dumpsy = win->sizey;
+ sj->dumpsx = WM_window_pixels_x(win);
+ sj->dumpsy = WM_window_pixels_y(win);
}
else {
ScrArea *curarea = CTX_wm_area(C);
@@ -500,5 +501,6 @@ void SCREEN_OT_screencast(wmOperatorType *ot)
ot->flag = 0;
RNA_def_property(ot->srna, "filepath", PROP_STRING, PROP_FILEPATH);
- RNA_def_boolean(ot->srna, "full", 1, "Full Screen", "Screencast the whole Blender window");
+ RNA_def_boolean(ot->srna, "full", 1, "Full Screen",
+ "Capture the whole window (otherwise only capture the active area)");
}
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index ae72dce1415..5bed31e2e52 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
paint_cursor.c
paint_hide.c
paint_image.c
+ paint_image_2d.c
paint_mask.c
paint_ops.c
paint_stroke.c
diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript
index 21439e6c6b2..6767e06f65b 100644
--- a/source/blender/editors/sculpt_paint/SConscript
+++ b/source/blender/editors/sculpt_paint/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 5e23a144408..ffea5af74a3 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -43,6 +43,7 @@
#include "BKE_brush.h"
#include "BKE_context.h"
+#include "BKE_image.h"
#include "BKE_paint.h"
#include "WM_api.h"
@@ -116,7 +117,7 @@ static void make_snap(Snapshot *snap, Brush *brush, ViewContext *vc)
snap->winy = vc->ar->winy;
}
-static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
+static int load_tex(Brush *br, ViewContext *vc)
{
static GLuint overlay_texture = 0;
static int init = 0;
@@ -130,10 +131,6 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
int size;
int j;
int refresh;
-
-#ifndef _OPENMP
- (void)sd; /* quied unused warning */
-#endif
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0;
@@ -147,6 +144,8 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
!same_snap(&snap, br, vc);
if (refresh) {
+ struct ImagePool *pool = NULL;
+
if (br->mtex.tex && br->mtex.tex->preview)
tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0];
@@ -186,7 +185,10 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
- #pragma omp parallel for schedule(static) if (sd->flags & SCULPT_USE_OPENMP)
+ if (br->mtex.tex)
+ pool = BKE_image_pool_new();
+
+ #pragma omp parallel for schedule(static)
for (j = 0; j < size; j++) {
int i;
float y;
@@ -236,7 +238,7 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
x += br->mtex.ofs[0];
y += br->mtex.ofs[1];
- avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y) : 1;
+ avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y, pool) : 1;
avg += br->texture_sample_bias;
@@ -251,6 +253,9 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
}
}
+ if (pool)
+ BKE_image_pool_free(pool);
+
if (!overlay_texture)
glGenTextures(1, &overlay_texture);
}
@@ -376,7 +381,7 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
/* Draw an overlay that shows what effect the brush's texture will
* have on brush strength */
/* TODO: sculpt only for now */
-static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
+static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
ViewContext *vc, int x, int y)
{
rctf quad;
@@ -401,7 +406,7 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
GL_VIEWPORT_BIT |
GL_TEXTURE_BIT);
- if (load_tex(sd, brush, vc)) {
+ if (load_tex(brush, vc)) {
glEnable(GL_BLEND);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@@ -416,24 +421,24 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
/* brush rotation */
glTranslatef(0.5, 0.5, 0);
glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ?
- sd->last_angle : sd->special_rotation),
+ ups->last_angle : ups->special_rotation),
0.0, 0.0, 1.0);
glTranslatef(-0.5f, -0.5f, 0);
/* scale based on tablet pressure */
- if (sd->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
+ if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
glTranslatef(0.5f, 0.5f, 0);
- glScalef(1.0f / sd->pressure_value, 1.0f / sd->pressure_value, 1);
+ glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
glTranslatef(-0.5f, -0.5f, 0);
}
- if (sd->draw_anchored) {
- const float *aim = sd->anchored_initial_mouse;
+ if (ups->draw_anchored) {
+ const float *aim = ups->anchored_initial_mouse;
const rcti *win = &vc->ar->winrct;
- quad.xmin = aim[0] - sd->anchored_size - win->xmin;
- quad.ymin = aim[1] - sd->anchored_size - win->ymin;
- quad.xmax = aim[0] + sd->anchored_size - win->xmin;
- quad.ymax = aim[1] + sd->anchored_size - win->ymin;
+ quad.xmin = aim[0] - ups->anchored_size - win->xmin;
+ quad.ymin = aim[1] - ups->anchored_size - win->ymin;
+ quad.xmax = aim[0] + ups->anchored_size - win->xmin;
+ quad.ymax = aim[1] + ups->anchored_size - win->ymin;
}
else {
const int radius = BKE_brush_size_get(vc->scene, brush);
@@ -476,7 +481,7 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
/* Special actions taken when paint cursor goes over mesh */
/* TODO: sculpt only for now */
-static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc,
+static void paint_cursor_on_hit(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc,
const float location[3])
{
float unprojected_radius, projected_radius;
@@ -484,8 +489,8 @@ static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc,
/* update the brush's cached 3D radius */
if (!BKE_brush_use_locked_size(vc->scene, brush)) {
/* get 2D brush radius */
- if (sd->draw_anchored)
- projected_radius = sd->anchored_size;
+ if (ups->draw_anchored)
+ projected_radius = ups->anchored_size;
else {
if (brush->flag & BRUSH_ANCHORED)
projected_radius = 8;
@@ -498,8 +503,8 @@ static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc,
projected_radius);
/* scale 3D brush radius by pressure */
- if (sd->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush))
- unprojected_radius *= sd->pressure_value;
+ if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush))
+ unprojected_radius *= ups->pressure_value;
/* set cached value in either Brush or UnifiedPaintSettings */
BKE_brush_unprojected_radius_set(vc->scene, brush, unprojected_radius);
@@ -509,6 +514,7 @@ static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc,
static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
{
Scene *scene = CTX_data_scene(C);
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
Paint *paint = paint_get_active_from_context(C);
Brush *brush = paint_brush(paint);
ViewContext vc;
@@ -534,7 +540,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* TODO: as sculpt and other paint modes are unified, this
* special mode of drawing will go away */
if (vc.obact->sculpt) {
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
float location[3];
int pixel_radius, hit;
@@ -547,14 +552,14 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
const float v = 1 - u;
const float r = 20;
- const float dx = sd->last_x - x;
- const float dy = sd->last_y - y;
+ const float dx = ups->last_x - x;
+ const float dy = ups->last_y - y;
if (dx * dx + dy * dy >= r * r) {
- sd->last_angle = atan2(dx, dy);
+ ups->last_angle = atan2(dx, dy);
- sd->last_x = u * sd->last_x + v * x;
- sd->last_y = u * sd->last_y + v * y;
+ ups->last_x = u * ups->last_x + v * x;
+ ups->last_y = u * ups->last_y + v * y;
}
}
@@ -562,7 +567,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location);
/* draw overlay */
- paint_draw_alpha_overlay(sd, brush, &vc, x, y);
+ paint_draw_alpha_overlay(ups, brush, &vc, x, y);
if (BKE_brush_use_locked_size(scene, brush))
BKE_brush_size_set(scene, brush, pixel_radius);
@@ -581,12 +586,12 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* only do if brush is over the mesh */
if (hit)
- paint_cursor_on_hit(sd, brush, &vc, location);
+ paint_cursor_on_hit(ups, brush, &vc, location);
- if (sd->draw_anchored) {
- final_radius = sd->anchored_size;
- translation[0] = sd->anchored_initial_mouse[0] - vc.ar->winrct.xmin;
- translation[1] = sd->anchored_initial_mouse[1] - vc.ar->winrct.ymin;
+ if (ups->draw_anchored) {
+ final_radius = ups->anchored_size;
+ translation[0] = ups->anchored_initial_mouse[0] - vc.ar->winrct.xmin;
+ translation[1] = ups->anchored_initial_mouse[1] - vc.ar->winrct.ymin;
}
}
@@ -599,6 +604,14 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* draw brush outline */
glTranslatef(translation[0], translation[1], 0);
+
+ /* draw an inner brush */
+ if (ups->draw_pressure && BKE_brush_use_size_pressure(scene, brush)) {
+ /* inner at full alpha */
+ glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius * ups->pressure_value, 40);
+ /* outer at half alpha */
+ glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha * 0.5f);
+ }
glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius, 40);
glTranslatef(-translation[0], -translation[1], 0);
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index bdd73cd6db3..d50261a3b98 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -37,7 +37,6 @@
#include "BLI_bitmap.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
@@ -45,6 +44,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
@@ -112,8 +112,8 @@ static void partialvis_update_mesh(Object *ob,
int *vert_indices;
int any_changed = 0, any_visible = 0, totvert, i;
- BLI_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
- BLI_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
+ BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
+ BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
@@ -136,8 +136,8 @@ static void partialvis_update_mesh(Object *ob,
}
if (any_changed) {
- BLI_pbvh_node_mark_rebuild_draw(node);
- BLI_pbvh_node_fully_hidden_set(node, !any_visible);
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, !any_visible);
}
}
@@ -157,11 +157,11 @@ static void partialvis_update_grids(Object *ob,
int *grid_indices, totgrid, any_changed, i;
/* get PBVH data */
- BLI_pbvh_node_get_grids(pbvh, node,
+ BKE_pbvh_node_get_grids(pbvh, node,
&grid_indices, &totgrid, NULL, NULL,
&grids, NULL);
- grid_hidden = BLI_pbvh_grid_hidden(pbvh);
- BLI_pbvh_get_grid_key(pbvh, &key);
+ grid_hidden = BKE_pbvh_grid_hidden(pbvh);
+ BKE_pbvh_get_grid_key(pbvh, &key);
sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
@@ -226,12 +226,81 @@ static void partialvis_update_grids(Object *ob,
/* mark updates if anything was hidden/shown */
if (any_changed) {
- BLI_pbvh_node_mark_rebuild_draw(node);
- BLI_pbvh_node_fully_hidden_set(node, !any_visible);
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, !any_visible);
multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED);
}
}
+static void partialvis_update_bmesh_verts(BMesh *bm,
+ GHash *verts,
+ PartialVisAction action,
+ PartialVisArea area,
+ float planes[4][4],
+ int *any_changed,
+ int *any_visible)
+{
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ float *vmask = CustomData_bmesh_get(&bm->vdata,
+ v->head.data,
+ CD_PAINT_MASK);
+
+ /* hide vertex if in the hide volume */
+ if (is_effected(area, planes, v->co, *vmask)) {
+ if (action == PARTIALVIS_HIDE)
+ BM_elem_flag_enable(v, BM_ELEM_HIDDEN);
+ else
+ BM_elem_flag_disable(v, BM_ELEM_HIDDEN);
+ (*any_changed) = TRUE;
+ }
+
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
+ (*any_visible) = TRUE;
+ }
+}
+
+static void partialvis_update_bmesh(Object *ob,
+ PBVH *pbvh,
+ PBVHNode *node,
+ PartialVisAction action,
+ PartialVisArea area,
+ float planes[4][4])
+{
+ BMesh *bm;
+ GHash *unique, *other;
+ int any_changed = 0, any_visible = 0;
+
+ bm = BKE_pbvh_get_bmesh(pbvh);
+ unique = BKE_pbvh_bmesh_node_unique_verts(node);
+ other = BKE_pbvh_bmesh_node_other_verts(node);
+
+ sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
+
+ partialvis_update_bmesh_verts(bm,
+ unique,
+ action,
+ area,
+ planes,
+ &any_changed,
+ &any_visible);
+
+ partialvis_update_bmesh_verts(bm,
+ other,
+ action,
+ area,
+ planes,
+ &any_changed,
+ &any_visible);
+
+ if (any_changed) {
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, !any_visible);
+ }
+}
+
static void rect_from_props(rcti *rect, PointerRNA *ptr)
{
rect->xmin = RNA_int_get(ptr, "xmin");
@@ -265,22 +334,22 @@ static void get_pbvh_nodes(PBVH *pbvh,
float clip_planes[4][4],
PartialVisArea mode)
{
- BLI_pbvh_SearchCallback cb = NULL;
+ BKE_pbvh_SearchCallback cb = NULL;
/* select search callback */
switch (mode) {
case PARTIALVIS_INSIDE:
- cb = BLI_pbvh_node_planes_contain_AABB;
+ cb = BKE_pbvh_node_planes_contain_AABB;
break;
case PARTIALVIS_OUTSIDE:
- cb = BLI_pbvh_node_planes_exclude_AABB;
+ cb = BKE_pbvh_node_planes_exclude_AABB;
break;
case PARTIALVIS_ALL:
case PARTIALVIS_MASKED:
break;
}
- BLI_pbvh_search_gather(pbvh, cb, clip_planes, nodes, totnode);
+ BKE_pbvh_search_gather(pbvh, cb, clip_planes, nodes, totnode);
}
static int hide_show_exec(bContext *C, wmOperator *op)
@@ -310,7 +379,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
ob->sculpt->pbvh = pbvh;
get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area);
- pbvh_type = BLI_pbvh_type(pbvh);
+ pbvh_type = BKE_pbvh_type(pbvh);
/* start undo */
switch (action) {
@@ -330,6 +399,9 @@ static int hide_show_exec(bContext *C, wmOperator *op)
case PBVH_GRIDS:
partialvis_update_grids(ob, pbvh, nodes[i], action, area, clip_planes);
break;
+ case PBVH_BMESH:
+ partialvis_update_bmesh(ob, pbvh, nodes[i], action, area, clip_planes);
+ break;
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index b704414c321..edeb66d9281 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -42,7 +42,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_dynstr.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
#include "BLI_threads.h"
@@ -54,13 +53,9 @@
#include "IMB_imbuf_types.h"
#include "DNA_brush_types.h"
-#include "DNA_camera_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_texture_types.h"
#include "BKE_camera.h"
#include "BKE_context.h"
@@ -77,8 +72,7 @@
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_global.h"
-#include "BKE_deform.h"
+#include "BKE_colortools.h"
#include "BKE_tessmesh.h"
@@ -102,7 +96,6 @@
#include "RNA_enum_types.h"
#include "GPU_draw.h"
-#include "GPU_extensions.h"
#include "IMB_colormanagement.h"
@@ -147,7 +140,7 @@ BLI_INLINE unsigned char f_to_char(const float val)
#define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
#define IMAPAINT_TILE_NUMBER(size) (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
-static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
+static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
typedef struct ImagePaintState {
@@ -323,7 +316,7 @@ typedef struct ProjPaintState {
float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
short is_ortho;
- short is_airbrush; /* only to avoid using (ps.brush->flag & BRUSH_AIRBRUSH) */
+ bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */
short is_texbrush; /* only to avoid running */
#ifndef PROJ_DEBUG_NOSEAMBLEED
float seam_bleed_px;
@@ -362,7 +355,7 @@ typedef union pixelStore {
typedef struct ProjPixel {
float projCoSS[2]; /* the floating point screen projection of this pixel */
-
+ float worldCoSS[3];
/* Only used when the airbrush is disabled.
* Store the max mask value to avoid painting over an area with a lower opacity
* with an advantage that we can avoid touching the pixel at all, if the
@@ -911,7 +904,7 @@ 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 dosn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
+ * and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4])
{
MFace *mf;
@@ -1533,6 +1526,7 @@ static int project_paint_pixel_sizeof(const short tool)
}
}
+
/* run this function when we know a bucket's, face's pixel can be initialized,
* return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
static ProjPixel *project_paint_uvpixel_init(
@@ -1544,6 +1538,7 @@ static ProjPixel *project_paint_uvpixel_init(
const int face_index,
const int image_index,
const float pixelScreenCo[4],
+ const float world_spaceCo[3],
const int side,
const float w[3])
{
@@ -1572,6 +1567,10 @@ static ProjPixel *project_paint_uvpixel_init(
}
/* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
+ if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
+ copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
+ }
+
copy_v2_v2(projPixel->projCoSS, pixelScreenCo);
projPixel->x_px = x_px;
@@ -2381,6 +2380,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
float pixelScreenCo[4];
+ bool do_3d_mapping = ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D;
rcti bounds_px; /* ispace bounds */
/* vars for getting uvspace bounds */
@@ -2456,7 +2456,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
v1coSS = ps->screenCoords[(*(&mf->v1 + i1))];
v2coSS = ps->screenCoords[(*(&mf->v1 + i2))];
v3coSS = ps->screenCoords[(*(&mf->v1 + i3))];
-
+
/* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
project_bucket_clip_face(
is_ortho, bucket_bounds,
@@ -2508,9 +2508,9 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
/* a pity we need to get the worldspace pixel location here */
- if (do_clip) {
+ if (do_clip || do_3d_mapping) {
interp_v3_v3v3v3(wco, ps->dm_mvert[(*(&mf->v1 + i1))].co, ps->dm_mvert[(*(&mf->v1 + i2))].co, ps->dm_mvert[(*(&mf->v1 + i3))].co, w);
- if (ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2521,13 +2521,13 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if ((ps->do_occlude == FALSE) ||
!project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
{
-
mask = project_paint_uvpixel_mask(ps, face_index, side, w);
-
+
if (mask > 0.0f) {
BLI_linklist_prepend_arena(
bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index,
+ image_index, pixelScreenCo, wco, side, w),
arena
);
}
@@ -2732,11 +2732,11 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
}
/* a pity we need to get the worldspace pixel location here */
- if (do_clip) {
+ if (do_clip || do_3d_mapping) {
if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
- if (ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2746,7 +2746,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if (mask > 0.0f) {
BLI_linklist_prepend_arena(
bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, wco, side, w),
arena
);
}
@@ -3344,7 +3344,7 @@ static void project_paint_begin(ProjPaintState *ps)
tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
- if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_MASK) == 0 || mf->flag & ME_FACE_SEL)) {
+ if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
@@ -3656,7 +3656,7 @@ static int project_image_refresh_tagged(ProjPaintState *ps)
pr = &(projIma->partRedrawRect[i]);
if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
imapaintpartial = *pr;
- imapaint_image_update(NULL, NULL, projIma->ima, projIma->ibuf, 1); /*last 1 is for texpaint*/
+ imapaint_image_update(NULL, projIma->ima, projIma->ibuf, 1); /*last 1 is for texpaint*/
redraw = 1;
}
}
@@ -3756,6 +3756,8 @@ typedef struct ProjectHandle {
/* thread settings */
int thread_index;
+
+ struct ImagePool *pool;
} ProjectHandle;
static void blend_color_mix(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
@@ -3807,7 +3809,7 @@ static void blend_color_mix_accum_float(float cp[4], const float cp1[4], const u
static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
{
- if (ps->is_airbrush == 0 && mask < 1.0f) {
+ if (ps->do_masking && mask < 1.0f) {
projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * 255), ps->blend);
blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
}
@@ -3818,7 +3820,7 @@ static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, floa
static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
{
- if (ps->is_airbrush == 0 && mask < 1.0f) {
+ if (ps->do_masking && mask < 1.0f) {
IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, ps->blend);
blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
}
@@ -3953,7 +3955,7 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const
rgba_ub[3] = 255;
}
- if (ps->is_airbrush == 0 && mask < 1.0f) {
+ if (ps->do_masking && mask < 1.0f) {
projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha * 255), ps->blend);
blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
}
@@ -3985,7 +3987,7 @@ static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, flo
rgba[3] = 1.0;
}
- if (ps->is_airbrush == 0 && mask < 1.0f) {
+ if (ps->do_masking && mask < 1.0f) {
IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, ps->blend);
blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
}
@@ -4005,10 +4007,12 @@ static void *do_projectpaint_thread(void *ph_v)
const float *lastpos = ((ProjectHandle *)ph_v)->prevmval;
const float *pos = ((ProjectHandle *)ph_v)->mval;
const int thread_index = ((ProjectHandle *)ph_v)->thread_index;
+ struct ImagePool *pool = ((ProjectHandle *)ph_v)->pool;
/* Done with args from ProjectHandle */
LinkNode *node;
ProjPixel *projPixel;
+ Brush *brush = ps->brush;
int last_index = -1;
ProjPaintImage *last_projIma = NULL;
@@ -4028,10 +4032,10 @@ static void *do_projectpaint_thread(void *ph_v)
float co[2];
float mask = 1.0f; /* airbrush wont use mask */
unsigned short mask_short;
- const float radius = (float)BKE_brush_size_get(ps->scene, ps->brush);
+ const float radius = (float)BKE_brush_size_get(ps->scene, brush);
const float radius_squared = radius * radius; /* avoid a square root with every dist comparison */
- short lock_alpha = ELEM(ps->brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : ps->brush->flag & BRUSH_LOCK_ALPHA;
+ short lock_alpha = ELEM(brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : brush->flag & BRUSH_LOCK_ALPHA;
LinkNode *smearPixels = NULL;
LinkNode *smearPixels_f = NULL;
@@ -4112,23 +4116,36 @@ static void *do_projectpaint_thread(void *ph_v)
/*if (dist < radius) {*/ /* correct but uses a sqrtf */
if (dist_nosqrt <= radius_squared) {
+ float samplecos[3];
dist = sqrtf(dist_nosqrt);
falloff = BKE_brush_curve_strength_clamp(ps->brush, dist, radius);
+ if (ps->is_texbrush) {
+ MTex *mtex = &brush->mtex;
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ sub_v2_v2v2(samplecos, projPixel->projCoSS, pos);
+ }
+ /* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D)
+ copy_v3_v3(samplecos, projPixel->worldCoSS);
+ else
+ copy_v3_v3(samplecos, projPixel->projCoSS);
+ }
+
if (falloff > 0.0f) {
if (ps->is_texbrush) {
/* note, for clone and smear, we only use the alpha, could be a special function */
- BKE_brush_sample_tex(ps->scene, ps->brush, projPixel->projCoSS, rgba, thread_index);
+ BKE_brush_sample_tex(ps->scene, brush, samplecos, rgba, thread_index, pool);
alpha = rgba[3];
}
else {
alpha = 1.0f;
}
- if (ps->is_airbrush) {
+ if (!ps->do_masking) {
/* for an aurbrush there is no real mask, so just multiply the alpha by it */
- alpha *= falloff * BKE_brush_alpha_get(ps->scene, ps->brush);
+ alpha *= falloff * BKE_brush_alpha_get(ps->scene, brush);
mask = ((float)projPixel->mask) / 65535.0f;
}
else {
@@ -4136,7 +4153,7 @@ static void *do_projectpaint_thread(void *ph_v)
falloff = 1.0f - falloff;
falloff = 1.0f - (falloff * falloff);
- mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, ps->brush) * falloff));
+ mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, brush) * falloff));
if (mask_short > projPixel->mask_max) {
mask = ((float)mask_short) / 65535.0f;
projPixel->mask_max = mask_short;
@@ -4255,6 +4272,8 @@ static int project_paint_op(void *state, ImBuf *UNUSED(ibufb), const float lastp
ListBase threads;
int a, i;
+ struct ImagePool *pool;
+
if (!project_bucket_iter_init(ps, pos)) {
return 0;
}
@@ -4262,6 +4281,8 @@ static int project_paint_op(void *state, ImBuf *UNUSED(ibufb), const float lastp
if (ps->thread_tot > 1)
BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot);
+ pool = BKE_image_pool_new();
+
/* get the threads running */
for (a = 0; a < ps->thread_tot; a++) {
@@ -4285,6 +4306,8 @@ static int project_paint_op(void *state, ImBuf *UNUSED(ibufb), const float lastp
memcpy(handles[a].projImages[i].partRedrawRect, ps->projImages[i].partRedrawRect, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
}
+ handles[a].pool = pool;
+
if (ps->thread_tot > 1)
BLI_insert_thread(&threads, &handles[a]);
}
@@ -4295,6 +4318,8 @@ static int project_paint_op(void *state, ImBuf *UNUSED(ibufb), const float lastp
do_projectpaint_thread(&handles[0]);
+ BKE_image_pool_free(pool);
+
/* move threaded bounds back into ps->projectPartialRedraws */
for (i = 0; i < ps->image_tot; i++) {
int touch = 0;
@@ -4322,7 +4347,7 @@ static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, c
pos[1] = (float)(mval_i[1]);
// we may want to use this later
- // BKE_brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
+ // BKE_brush_painter_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
if (BKE_brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps, 0)) {
return 1;
@@ -4392,16 +4417,13 @@ static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w,
IMB_freeImBuf(tmpibuf);
}
-static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
+static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
{
- if (scene) {
- IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect, ibuf->x, 0, 0,
- &scene->view_settings, &scene->display_settings,
- imapaintpartial.x1, imapaintpartial.y1,
- imapaintpartial.x2, imapaintpartial.y2, FALSE);
- }
- else {
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ if (imapaintpartial.x1 != imapaintpartial.x2 &&
+ imapaintpartial.y1 != imapaintpartial.y2)
+ {
+ IMB_partial_display_buffer_update_delayed(ibuf, imapaintpartial.x1, imapaintpartial.y1,
+ imapaintpartial.x2, imapaintpartial.y2);
}
if (ibuf->mipmap[0])
@@ -4721,6 +4743,7 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_release_ibuf(s->image, s->canvas, NULL);
return 0;
}
@@ -4764,7 +4787,7 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
*/
if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) {
if (update)
- imapaint_image_update(s->scene, s->sima, image, ibuf, texpaint);
+ imapaint_image_update(s->sima, image, ibuf, texpaint);
BKE_image_release_ibuf(image, ibuf, NULL);
return 1;
}
@@ -4962,7 +4985,6 @@ typedef struct PaintOperation {
int first;
int prevmouse[2];
- float prev_pressure; /* need this since we don't get tablet events for pressure change */
int orig_brush_size;
double starttime;
@@ -4994,21 +5016,29 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
- Brush *brush = paint_brush(&settings->imapaint.paint);
/* brush */
- ps->brush = brush;
- ps->tool = brush->imagepaint_tool;
- ps->blend = brush->blend;
+ ps->brush = paint_brush(&settings->imapaint.paint);
+ if (ps->brush) {
+ Brush *brush = ps->brush;
+ ps->tool = brush->imagepaint_tool;
+ ps->blend = brush->blend;
+
+ /* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */
+ ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW ||
+ brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) ? false : true;
+ ps->is_texbrush = (brush->mtex.tex) ? 1 : 0;
+ }
+ else {
+ /* brush may be NULL*/
+ ps->do_masking = false;
+ ps->is_texbrush = false;
+ }
- /* sizeof ProjPixel, since we alloc this a _lot_ */
+ /* sizeof(ProjPixel), since we alloc this a _lot_ */
ps->pixel_sizeof = project_paint_pixel_sizeof(ps->tool);
BLI_assert(ps->pixel_sizeof >= sizeof(ProjPixel));
- ps->is_airbrush = (brush->flag & BRUSH_AIRBRUSH) ? 1 : 0;
- ps->is_texbrush = (brush->mtex.tex) ? 1 : 0;
-
-
/* these can be NULL */
ps->v3d = CTX_wm_view3d(C);
ps->rv3d = CTX_wm_region_view3d(C);
@@ -5104,7 +5134,7 @@ static int texture_paint_init(bContext *C, wmOperator *op)
}
pop->s.ob = ob;
- pop->s.do_facesel = (me->editflag & ME_EDIT_PAINT_MASK) != 0;
+ pop->s.do_facesel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
/* for non prohect paint we need */
/* fill in derived mesh */
@@ -5142,15 +5172,16 @@ static int texture_paint_init(bContext *C, wmOperator *op)
return 0;
}
}
-
- paint_brush_init_tex(pop->s.brush);
-
+
/* note, if we have no UVs on the derived mesh, then we must return here */
if (pop->mode == PAINT_MODE_3D_PROJECT) {
/* initialize all data from the context */
project_state_init(C, OBACT, &pop->ps);
-
+
+ /* needed so multiple threads don't try to initialize the brush at once (can leak memory) */
+ curvemapping_initialize(pop->ps.brush->curve);
+
paint_brush_init_tex(pop->ps.brush);
pop->ps.source = PROJ_SRC_VIEW;
@@ -5168,6 +5199,9 @@ static int texture_paint_init(bContext *C, wmOperator *op)
if (pop->ps.dm == NULL)
return 0;
}
+ else {
+ paint_brush_init_tex(pop->s.brush);
+ }
settings->imapaint.flag |= IMAGEPAINT_DRAWING;
undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
@@ -5176,6 +5210,11 @@ static int texture_paint_init(bContext *C, wmOperator *op)
/* create painter */
pop->painter = BKE_brush_painter_new(scene, pop->s.brush);
+ {
+ UnifiedPaintSettings *ups = &settings->unified_paint_settings;
+ ups->draw_pressure = true;
+ }
+
return 1;
}
@@ -5237,8 +5276,6 @@ static void paint_exit(bContext *C, wmOperator *op)
if (pop->restore_projection)
settings->imapaint.flag &= ~IMAGEPAINT_PROJECT_DISABLE;
- paint_brush_exit_tex(pop->s.brush);
-
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
imapaint_canvas_free(&pop->s);
BKE_brush_painter_free(pop->painter);
@@ -5250,6 +5287,8 @@ static void paint_exit(bContext *C, wmOperator *op)
project_paint_end(&pop->ps);
}
else {
+ paint_brush_exit_tex(pop->s.brush);
+
/* non projection 3d paint, could move into own function of more needs adding */
if (pop->s.dm_release)
pop->s.dm->release(pop->s.dm);
@@ -5264,6 +5303,11 @@ static void paint_exit(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted: %s", pop->s.warnpackedfile);
MEM_freeN(pop);
+
+ {
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ ups->draw_pressure = false;
+ }
}
static int paint_exec(bContext *C, wmOperator *op)
@@ -5288,7 +5332,6 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
{
const Scene *scene = CTX_data_scene(C);
PaintOperation *pop = op->customdata;
- wmTabletData *wmtab;
PointerRNA itemptr;
float pressure, mousef[2];
double time;
@@ -5299,16 +5342,17 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
tablet = 0;
pop->s.blend = pop->s.brush->blend;
- if (event->custom == EVT_DATA_TABLET) {
- wmtab = event->customdata;
+ if (event->tablet_data) {
+ wmTabletData *wmtab = event->tablet_data;
tablet = (wmtab->Active != EVT_TABLET_NONE);
pressure = wmtab->Pressure;
if (wmtab->Active == EVT_TABLET_ERASER)
pop->s.blend = IMB_BLEND_ERASE_ALPHA;
}
- else { /* otherwise airbrush becomes 1.0 pressure instantly */
- pressure = pop->prev_pressure ? pop->prev_pressure : 1.0f;
+ else {
+ BLI_assert(fabsf(WM_cursor_pressure(CTX_wm_window(C))) == 1.0f);
+ pressure = 1.0f;
}
if (pop->first) {
@@ -5341,7 +5385,10 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
/* apply */
paint_apply(C, op, &itemptr);
- pop->prev_pressure = pressure;
+ {
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ ups->pressure_value = pressure;
+ }
}
static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
@@ -5352,7 +5399,7 @@ static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
MEM_freeN(op->customdata);
return OPERATOR_CANCELLED;
}
-
+
paint_apply_event(C, op, event);
pop = op->customdata;
@@ -5482,6 +5529,16 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
+ {
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ /* hrmf, duplicate paint_draw_cursor logic here */
+ if (ups->draw_pressure && BKE_brush_use_size_pressure(scene, brush)) {
+ /* inner at full alpha */
+ glutil_draw_lined_arc(0, (float)(M_PI * 2.0), size * ups->pressure_value, 40);
+ /* outer at half alpha */
+ glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha * 0.5f);
+ }
+ }
glutil_draw_lined_arc(0, (float)(M_PI * 2.0), size, 40);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
@@ -5705,7 +5762,7 @@ static int image_paint_sample_color_poll(bContext *C)
if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
Mesh *me = BKE_mesh_from_object(obact);
if (me) {
- return !(me->editflag & ME_EDIT_PAINT_MASK);
+ return !(me->editflag & ME_EDIT_PAINT_FACE_SEL);
}
}
}
@@ -5956,7 +6013,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
/* override */
ps.is_texbrush = 0;
- ps.is_airbrush = 1;
+ 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 */
@@ -6041,7 +6098,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (w > maxsize) w = maxsize;
if (h > maxsize) h = maxsize;
- ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, FALSE, err_out);
+ ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
new file mode 100644
index 00000000000..84250853f38
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -0,0 +1,560 @@
+/*
+ * ***** 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 blender/editors/sculpt_paint/paint_image_2d.c
+ * \ingroup bke
+ */
+//#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_brush.h"
+
+#include "BLI_math.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "RE_shader_ext.h"
+
+ /* Brush Painting for 2D image editor */
+
+typedef struct BrushPainterCache {
+ short enabled;
+
+ int size; /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
+ short flt; /* need float imbuf? */
+ short texonly; /* no alpha, color or fallof, only texture in imbuf */
+
+ int lastsize;
+ float lastalpha;
+ float lastjitter;
+
+ ImBuf *ibuf;
+ ImBuf *texibuf;
+ ImBuf *maskibuf;
+} BrushPainterCache;
+
+struct BrushPainter {
+ Scene *scene;
+ Brush *brush;
+
+ float lastmousepos[2]; /* mouse position of last paint call */
+
+ float accumdistance; /* accumulated distance of brush since last paint op */
+ float lastpaintpos[2]; /* position of last paint op */
+ float startpaintpos[2]; /* position of first paint */
+
+ double accumtime; /* accumulated time since last paint op (airbrush) */
+ double lasttime; /* time of last update */
+
+ float lastpressure;
+
+ short firsttouch; /* first paint op */
+
+ float startsize;
+ float startalpha;
+ float startjitter;
+ float startspacing;
+
+ BrushPainterCache cache;
+};
+
+BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
+{
+ BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
+
+ painter->brush = brush;
+ painter->scene = scene;
+ painter->firsttouch = 1;
+ painter->cache.lastsize = -1; /* force ibuf create in refresh */
+
+ painter->startsize = BKE_brush_size_get(scene, brush);
+ painter->startalpha = BKE_brush_alpha_get(scene, brush);
+ painter->startjitter = brush->jitter;
+ painter->startspacing = brush->spacing;
+
+ return painter;
+}
+
+
+static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
+{
+ if (BKE_brush_use_alpha_pressure(painter->scene, brush))
+ BKE_brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
+ if (BKE_brush_use_size_pressure(painter->scene, brush))
+ BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
+ if (brush->flag & BRUSH_JITTER_PRESSURE)
+ brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
+ if (brush->flag & BRUSH_SPACING_PRESSURE)
+ brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
+}
+
+
+void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
+{
+ if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
+ ((painter->cache.texonly != texonly) && texonly))
+ {
+ if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
+ if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
+ painter->cache.ibuf = painter->cache.maskibuf = NULL;
+ painter->cache.lastsize = -1; /* force ibuf create in refresh */
+ }
+
+ if (painter->cache.flt != flt) {
+ if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
+ painter->cache.texibuf = NULL;
+ painter->cache.lastsize = -1; /* force ibuf create in refresh */
+ }
+
+ painter->cache.size = size;
+ painter->cache.flt = flt;
+ painter->cache.texonly = texonly;
+ painter->cache.enabled = 1;
+}
+
+void BKE_brush_painter_free(BrushPainter *painter)
+{
+ Brush *brush = painter->brush;
+
+ BKE_brush_size_set(painter->scene, brush, painter->startsize);
+ BKE_brush_alpha_set(painter->scene, brush, painter->startalpha);
+ brush->jitter = painter->startjitter;
+ brush->spacing = painter->startspacing;
+
+ if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
+ if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
+ if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
+ MEM_freeN(painter);
+}
+
+static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
+ int x, int y, int w, int h, int xt, int yt,
+ const float pos[2])
+{
+ Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ ImBuf *ibuf, *maskibuf, *texibuf;
+ float *bf, *mf, *tf, *otf = NULL, xoff, yoff, xy[2], rgba[4];
+ unsigned char *b, *m, *t, *ot = NULL;
+ int dotexold, origx = x, origy = y;
+ const int radius = BKE_brush_size_get(painter->scene, brush);
+
+ xoff = -radius + 0.5f;
+ yoff = -radius + 0.5f;
+ xoff += (int)pos[0] - (int)painter->startpaintpos[0];
+ yoff += (int)pos[1] - (int)painter->startpaintpos[1];
+
+ ibuf = painter->cache.ibuf;
+ texibuf = painter->cache.texibuf;
+ maskibuf = painter->cache.maskibuf;
+
+ dotexold = (oldtexibuf != NULL);
+
+ /* not sure if it's actually needed or it's a mistake in coords/sizes
+ * calculation in brush_painter_fixed_tex_partial_update(), but without this
+ * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
+ w = min_ii(w, ibuf->x);
+ h = min_ii(h, ibuf->y);
+
+ if (painter->cache.flt) {
+ for (; y < h; y++) {
+ bf = ibuf->rect_float + (y * ibuf->x + origx) * 4;
+ tf = texibuf->rect_float + (y * texibuf->x + origx) * 4;
+ mf = maskibuf->rect_float + (y * maskibuf->x + origx) * 4;
+
+ if (dotexold)
+ otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
+
+ for (x = origx; x < w; x++, bf += 4, mf += 4, tf += 4) {
+ if (dotexold) {
+ copy_v4_v4(tf, otf);
+ otf += 4;
+ }
+ else {
+ xy[0] = x + xoff;
+ xy[1] = y + yoff;
+
+ BKE_brush_sample_tex_2D(scene, brush, xy, tf, 0);
+ }
+
+ bf[0] = tf[0] * mf[0];
+ bf[1] = tf[1] * mf[1];
+ bf[2] = tf[2] * mf[2];
+ bf[3] = tf[3] * mf[3];
+ }
+ }
+ }
+ else {
+ for (; y < h; y++) {
+ b = (unsigned char *)ibuf->rect + (y * ibuf->x + origx) * 4;
+ t = (unsigned char *)texibuf->rect + (y * texibuf->x + origx) * 4;
+ m = (unsigned char *)maskibuf->rect + (y * maskibuf->x + origx) * 4;
+
+ if (dotexold)
+ ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
+
+ for (x = origx; x < w; x++, b += 4, m += 4, t += 4) {
+ if (dotexold) {
+ t[0] = ot[0];
+ t[1] = ot[1];
+ t[2] = ot[2];
+ t[3] = ot[3];
+ ot += 4;
+ }
+ else {
+ xy[0] = x + xoff;
+ xy[1] = y + yoff;
+
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
+ rgba_float_to_uchar(t, rgba);
+ }
+
+ b[0] = t[0] * m[0] / 255;
+ b[1] = t[1] * m[1] / 255;
+ b[2] = t[2] * m[2] / 255;
+ b[3] = t[3] * m[3] / 255;
+ }
+ }
+ }
+}
+
+static void brush_painter_tiled_tex_partial_update(BrushPainter *painter, const float pos[2])
+{
+ const Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ BrushPainterCache *cache = &painter->cache;
+ ImBuf *oldtexibuf, *ibuf;
+ int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
+ const int diameter = 2 * BKE_brush_size_get(scene, brush);
+
+ imbflag = (cache->flt) ? IB_rectfloat : IB_rect;
+ if (!cache->ibuf)
+ cache->ibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
+ ibuf = cache->ibuf;
+
+ oldtexibuf = cache->texibuf;
+ cache->texibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
+ if (oldtexibuf) {
+ srcx = srcy = 0;
+ destx = (int)painter->lastpaintpos[0] - (int)pos[0];
+ desty = (int)painter->lastpaintpos[1] - (int)pos[1];
+ w = oldtexibuf->x;
+ h = oldtexibuf->y;
+
+ IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
+ }
+ else {
+ srcx = srcy = 0;
+ destx = desty = 0;
+ w = h = 0;
+ }
+
+ x1 = destx;
+ y1 = desty;
+ x2 = destx + w;
+ y2 = desty + h;
+
+ /* blend existing texture in new position */
+ if ((x1 < x2) && (y1 < y2))
+ brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
+
+ if (oldtexibuf)
+ IMB_freeImBuf(oldtexibuf);
+
+ /* sample texture in new areas */
+ if ((0 < x1) && (0 < ibuf->y))
+ brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
+ if ((x2 < ibuf->x) && (0 < ibuf->y))
+ brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
+ if ((x1 < x2) && (0 < y1))
+ brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
+ if ((x1 < x2) && (y2 < ibuf->y))
+ brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
+}
+
+static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
+{
+ const Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ BrushPainterCache *cache = &painter->cache;
+ MTex *mtex = &brush->mtex;
+ int size;
+ short flt;
+ const int diameter = 2 * BKE_brush_size_get(scene, brush);
+ const float alpha = BKE_brush_alpha_get(scene, brush);
+ const bool do_tiled = ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_3D);
+
+ if (diameter != cache->lastsize ||
+ alpha != cache->lastalpha ||
+ brush->jitter != cache->lastjitter)
+ {
+ if (cache->ibuf) {
+ IMB_freeImBuf(cache->ibuf);
+ cache->ibuf = NULL;
+ }
+ if (cache->maskibuf) {
+ IMB_freeImBuf(cache->maskibuf);
+ cache->maskibuf = NULL;
+ }
+
+ flt = cache->flt;
+ size = (cache->size) ? cache->size : diameter;
+
+ if (do_tiled) {
+ BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
+ brush_painter_tiled_tex_partial_update(painter, pos);
+ }
+ else
+ BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
+
+ cache->lastsize = diameter;
+ cache->lastalpha = alpha;
+ cache->lastjitter = brush->jitter;
+ }
+ else if (do_tiled && mtex && mtex->tex) {
+ int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
+ int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
+
+ if ((dx != 0) || (dy != 0))
+ brush_painter_tiled_tex_partial_update(painter, pos);
+ }
+}
+
+void BKE_brush_painter_break_stroke(BrushPainter *painter)
+{
+ painter->firsttouch = 1;
+}
+
+
+int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
+ void *user, int use_color_correction)
+{
+ Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ int totpaintops = 0;
+
+ if (pressure == 0.0f) {
+ if (painter->lastpressure) // XXX - hack, operator misses
+ pressure = painter->lastpressure;
+ else
+ pressure = 1.0f; /* zero pressure == not using tablet */
+ }
+ if (painter->firsttouch) {
+ /* paint exactly once on first touch */
+ painter->startpaintpos[0] = pos[0];
+ painter->startpaintpos[1] = pos[1];
+
+ brush_pressure_apply(painter, brush, pressure);
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, pos, use_color_correction);
+ totpaintops += func(user, painter->cache.ibuf, pos, pos);
+
+ painter->lasttime = time;
+ painter->firsttouch = 0;
+ painter->lastpaintpos[0] = pos[0];
+ painter->lastpaintpos[1] = pos[1];
+ }
+#if 0
+ else if (painter->brush->flag & BRUSH_AIRBRUSH) {
+ float spacing, step, paintpos[2], dmousepos[2], len;
+ double starttime, curtime = time;
+
+ /* compute brush spacing adapted to brush size */
+ spacing = brush->rate; //radius*brush->spacing * 0.01f;
+
+ /* setup starting time, direction vector and accumulated time */
+ starttime = painter->accumtime;
+ sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
+ len = normalize_v2(dmousepos);
+ painter->accumtime += curtime - painter->lasttime;
+
+ /* do paint op over unpainted time distance */
+ while (painter->accumtime >= spacing) {
+ step = (spacing - starttime) * len;
+ paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
+ paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter);
+ totpaintops += func(user, painter->cache.ibuf,
+ painter->lastpaintpos, paintpos);
+
+ painter->lastpaintpos[0] = paintpos[0];
+ painter->lastpaintpos[1] = paintpos[1];
+ painter->accumtime -= spacing;
+ starttime -= spacing;
+ }
+
+ painter->lasttime = curtime;
+ }
+#endif
+ else {
+ float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
+ float t, len, press;
+ const int radius = BKE_brush_size_get(scene, brush);
+
+ /* compute brush spacing adapted to brush radius, spacing may depend
+ * on pressure, so update it */
+ brush_pressure_apply(painter, brush, painter->lastpressure);
+ spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
+
+ /* setup starting distance, direction vector and accumulated distance */
+ startdistance = painter->accumdistance;
+ sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
+ len = normalize_v2(dmousepos);
+ painter->accumdistance += len;
+
+ if (brush->flag & BRUSH_SPACE) {
+ /* do paint op over unpainted distance */
+ while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
+ step = spacing - startdistance;
+ paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
+ paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
+
+ t = step / len;
+ press = (1.0f - t) * painter->lastpressure + t * pressure;
+ brush_pressure_apply(painter, brush, press);
+ spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
+
+ BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+
+ totpaintops +=
+ func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
+
+ painter->lastpaintpos[0] = paintpos[0];
+ painter->lastpaintpos[1] = paintpos[1];
+ painter->accumdistance -= spacing;
+ startdistance -= spacing;
+ }
+ }
+ else {
+ BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+
+ totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
+
+ painter->lastpaintpos[0] = pos[0];
+ painter->lastpaintpos[1] = pos[1];
+ painter->accumdistance = 0;
+ }
+
+ /* do airbrush paint ops, based on the number of paint ops left over
+ * from regular painting. this is a temporary solution until we have
+ * accurate time stamps for mouse move events */
+ if (brush->flag & BRUSH_AIRBRUSH) {
+ double curtime = time;
+ double painttime = brush->rate * totpaintops;
+
+ painter->accumtime += curtime - painter->lasttime;
+ if (painter->accumtime <= painttime)
+ painter->accumtime = 0.0;
+ else
+ painter->accumtime -= painttime;
+
+ while (painter->accumtime >= (double)brush->rate) {
+ brush_pressure_apply(painter, brush, pressure);
+
+ BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+
+ totpaintops +=
+ func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
+ painter->accumtime -= (double)brush->rate;
+ }
+
+ painter->lasttime = curtime;
+ }
+ }
+
+ painter->lastmousepos[0] = pos[0];
+ painter->lastmousepos[1] = pos[1];
+ painter->lastpressure = pressure;
+
+ BKE_brush_alpha_set(scene, brush, painter->startalpha);
+ BKE_brush_size_set(scene, brush, painter->startsize);
+ brush->jitter = painter->startjitter;
+ brush->spacing = painter->startspacing;
+
+ return totpaintops;
+}
+
+
+/* TODO: should probably be unified with BrushPainter stuff? */
+unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
+{
+ unsigned int *texcache = NULL;
+ MTex *mtex = &br->mtex;
+ TexResult texres = {0};
+ int hasrgb, ix, iy;
+ int side = half_side * 2;
+
+ if (mtex->tex) {
+ float x, y, step = 2.0 / side, co[3];
+
+ texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
+
+ /*do normalized cannonical view coords for texture*/
+ for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
+ for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
+ co[0] = x;
+ co[1] = y;
+ co[2] = 0.0f;
+
+ /* This is copied from displace modifier code */
+ hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL);
+
+ /* if the texture gave an RGB value, we assume it didn't give a valid
+ * intensity, so calculate one (formula from do_material_tex).
+ * if the texture didn't give an RGB value, copy the intensity across
+ */
+ if (hasrgb & TEX_RGB)
+ texres.tin = rgb_to_grayscale(&texres.tr);
+
+ ((char *)texcache)[(iy * side + ix) * 4] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 1] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 2] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
+ }
+ }
+ }
+
+ return texcache;
+}
+
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 162e2fa15d6..faa9ce00da8 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -36,6 +36,7 @@ struct ARegion;
struct bContext;
struct bglMats;
struct Brush;
+struct ImagePool;
struct ListBase;
struct Mesh;
struct Object;
@@ -61,7 +62,8 @@ struct PaintStroke *paint_stroke_new(struct bContext *C,
StrokeUpdateStep update_step, StrokeDone done, int event_type);
void paint_stroke_data_free(struct wmOperator *op);
-int paint_space_stroke_enabled(struct Brush *br);
+bool paint_space_stroke_enabled(struct Brush *br);
+bool paint_supports_dynamic_size(struct Brush *br);
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf);
int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
@@ -89,6 +91,12 @@ void PAINT_OT_weight_from_bones(struct wmOperatorType *ot);
void PAINT_OT_weight_sample(struct wmOperatorType *ot);
void PAINT_OT_weight_sample_group(struct wmOperatorType *ot);
+enum {
+ WPAINT_GRADIENT_TYPE_LINEAR,
+ WPAINT_GRADIENT_TYPE_RADIAL
+};
+void PAINT_OT_weight_gradient(struct wmOperatorType *ot);
+
void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
@@ -133,7 +141,7 @@ void paint_calc_redraw_planes(float planes[4][4],
void projectf(struct bglMats *mats, const float v[3], float p[2]);
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius);
-float paint_get_tex_pixel(struct Brush *br, float u, float v);
+float paint_get_tex_pixel(struct Brush *br, float u, float v, struct ImagePool *pool);
int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface);
void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 697d7c63d1f..3cf67667f39 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -38,8 +38,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BLI_pbvh.h"
-
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
@@ -97,7 +96,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
pbvh = dm->getPBVH(ob, dm);
ob->sculpt->pbvh = pbvh;
- BLI_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
sculpt_undo_push_begin("Mask flood fill");
@@ -106,12 +105,12 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
- BLI_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) {
+ BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) {
mask_flood_fill_set_elem(vi.mask, mode, value);
- } BLI_pbvh_vertex_iter_end;
+ } BKE_pbvh_vertex_iter_end;
- BLI_pbvh_node_mark_update(nodes[i]);
- if (BLI_pbvh_type(pbvh) == PBVH_GRIDS)
+ BKE_pbvh_node_mark_update(nodes[i]);
+ if (BKE_pbvh_type(pbvh) == PBVH_GRIDS)
multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
}
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 40dcb92f087..ba33ad22f92 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -62,11 +62,12 @@ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op))
/*int type = RNA_enum_get(op->ptr, "type");*/
Paint *paint = paint_get_active_from_context(C);
struct Brush *br = paint_brush(paint);
+ Main *bmain = CTX_data_main(C);
if (br)
br = BKE_brush_copy(br);
else
- br = BKE_brush_add("Brush");
+ br = BKE_brush_add(bmain, "Brush");
paint_brush_set(paint, br);
@@ -272,7 +273,7 @@ static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool,
brush = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode);
if (!brush && brush_tool(brush_orig, tool_offset) != tool && create_missing) {
- brush = BKE_brush_add(tool_name);
+ brush = BKE_brush_add(bmain, tool_name);
brush_tool_set(brush, tool_offset, tool);
brush->ob_mode = ob_mode;
brush->toggle_brush = brush_orig;
@@ -475,6 +476,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_weight_paint);
WM_operatortype_append(PAINT_OT_weight_set);
WM_operatortype_append(PAINT_OT_weight_from_bones);
+ WM_operatortype_append(PAINT_OT_weight_gradient);
WM_operatortype_append(PAINT_OT_weight_sample);
WM_operatortype_append(PAINT_OT_weight_sample_group);
@@ -647,6 +649,17 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "PAINT_OT_mask_flood_fill", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "mode", PAINT_MASK_INVERT);
+ /* Toggle dynamic topology */
+ WM_keymap_add_item(keymap, "SCULPT_OT_dynamic_topology_toggle", DKEY, KM_PRESS, KM_CTRL, 0);
+
+ /* Dynamic-topology detail size
+ *
+ * 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");
+
/* multires switch */
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0);
RNA_int_set(kmi->ptr, "level", 1);
@@ -669,6 +682,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_FLATTEN, TKEY, KM_SHIFT);
keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_CLAY, CKEY, 0);
keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_CREASE, CKEY, KM_SHIFT);
+ keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_SNAKE_HOOK, KKEY, 0);
kmi = keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_MASK, MKEY, 0);
RNA_boolean_set(kmi->ptr, "toggle", 1);
RNA_boolean_set(kmi->ptr, "create_missing", 1);
@@ -707,8 +721,11 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0);
/* these keys are from 2.4x but could be changed */
- WM_keymap_verify_item(keymap, "PAINT_OT_weight_sample", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
- WM_keymap_verify_item(keymap, "PAINT_OT_weight_sample_group", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_verify_item(keymap, "PAINT_OT_weight_sample", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_verify_item(keymap, "PAINT_OT_weight_sample_group", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
+
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_gradient", LEFTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "type", WPAINT_GRADIENT_TYPE_LINEAR);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_gradient", LEFTMOUSE, KM_PRESS, KM_ALT | KM_CTRL, 0)->ptr, "type", WPAINT_GRADIENT_TYPE_RADIAL);
WM_keymap_add_item(keymap,
"PAINT_OT_weight_set", KKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 9ebeb61a7bb..5d9313485d2 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -125,8 +125,8 @@ static float event_tablet_data(wmEvent *event, int *pen_flip)
int erasor = 0;
float pressure = 1;
- if (event->custom == EVT_DATA_TABLET) {
- wmTabletData *wmtab = event->customdata;
+ if (event->tablet_data) {
+ wmTabletData *wmtab = event->tablet_data;
erasor = (wmtab->Active == EVT_TABLET_ERASER);
pressure = (wmtab->Active != EVT_TABLET_NONE) ? wmtab->Pressure : 1;
@@ -324,10 +324,15 @@ static void stroke_done(struct bContext *C, struct wmOperator *op)
}
/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
-int paint_space_stroke_enabled(Brush *br)
+bool paint_space_stroke_enabled(Brush *br)
{
- return (br->flag & BRUSH_SPACE) &&
- !(br->flag & BRUSH_ANCHORED) &&
+ return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br);
+}
+
+/* return true if the brush size can change during paint (normally used for pressure) */
+bool paint_supports_dynamic_size(Brush *br)
+{
+ return !(br->flag & BRUSH_ANCHORED) &&
!ELEM4(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK);
}
@@ -416,6 +421,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
if (!stroke->stroke_started) {
copy_v2_v2(stroke->last_mouse_position, sample_average.mouse);
stroke->stroke_started = stroke->test_start(C, op, sample_average.mouse);
+ BLI_assert((stroke->stroke_started & ~1) == 0); /* 0/1 */
if (stroke->stroke_started) {
stroke->smooth_stroke_cursor =
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index cb4b6346c2a..4f156276aac 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -173,13 +173,13 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3],
return len_v3(delta) / scale;
}
-float paint_get_tex_pixel(Brush *br, float u, float v)
+float paint_get_tex_pixel(Brush *br, float u, float v, struct ImagePool *pool)
{
TexResult texres = {0};
float co[3] = {u, v, 0.0f};
int hasrgb;
- hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres);
+ hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres, pool);
if (hasrgb & TEX_RGB)
texres.tin = rgb_to_grayscale(&texres.tr) * texres.ta;
@@ -189,7 +189,7 @@ float paint_get_tex_pixel(Brush *br, float u, float v)
/* 3D Paint */
-static void imapaint_project(Object *ob, float model[][4], float proj[][4], const float co[3], float pco[4])
+static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4])
{
copy_v3_v3(pco, co);
pco[3] = 1.0f;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 94b00101dc2..0277e1e11dc 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -224,7 +224,7 @@ static void do_shared_vertex_tesscol(Mesh *me)
{
/* if no mcol: do not do */
/* if tface: only the involved faces, otherwise all */
- const int use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK);
+ const int use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
MFace *mface;
int a;
short *scolmain, *scol;
@@ -284,7 +284,7 @@ static void do_shared_vertex_tesscol(Mesh *me)
static void do_shared_vertexcol(Mesh *me, int do_tessface)
{
- const int use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK);
+ const int use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
MPoly *mp;
float (*scol)[4];
int i, j, has_shared = 0;
@@ -346,7 +346,7 @@ static void make_vertexcol(Object *ob) /* single ob */
if (me->edit_btmesh) return;
/* copies from shadedisplist to mcol */
- if (!me->mloopcol) {
+ if (!me->mloopcol && me->totloop) {
if (!me->mcol) {
CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
}
@@ -372,42 +372,49 @@ static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, vgroup_active);
if (defgroup) {
- bDeformGroup *curdef;
int mirrdef;
char name[MAXBONENAME];
flip_side_name(name, defgroup->name, FALSE);
-
- if (strcmp(name, defgroup->name) != 0) {
- for (curdef = ob->defbase.first, mirrdef = 0; curdef; curdef = curdef->next, mirrdef++) {
- if (!strcmp(curdef->name, name)) {
- break;
- }
- }
-
- if (curdef == NULL) {
- int olddef = ob->actdef; /* tsk, ED_vgroup_add sets the active defgroup */
- curdef = ED_vgroup_add_name(ob, name);
- ob->actdef = olddef;
- }
-
- /* curdef should never be NULL unless this is
- * a lamp and ED_vgroup_add_name fails */
- if (curdef) {
- return mirrdef;
+ mirrdef = defgroup_name_index(ob, name);
+ if (mirrdef == -1) {
+ int olddef = ob->actdef; /* tsk, ED_vgroup_add sets the active defgroup */
+ if (ED_vgroup_add_name(ob, name)) {
+ mirrdef = BLI_countlist(&ob->defbase) - 1;
}
+ ob->actdef = olddef;
}
+
+ /* curdef should never be NULL unless this is
+ * a lamp and ED_vgroup_add_name fails */
+ return mirrdef;
}
return -1;
}
-static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot)
+static void free_vpaint_prev(VPaint *vp)
{
if (vp->vpaint_prev) {
MEM_freeN(vp->vpaint_prev);
vp->vpaint_prev = NULL;
+ vp->tot = 0;
+ }
+}
+
+static void free_wpaint_prev(VPaint *vp)
+{
+ if (vp->wpaint_prev) {
+ BKE_defvert_array_free(vp->wpaint_prev, vp->tot);
+ vp->wpaint_prev = NULL;
+ vp->tot = 0;
}
+}
+
+static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot)
+{
+ free_vpaint_prev(vp);
+
vp->tot = tot;
if (lcol == NULL || tot == 0) return;
@@ -419,20 +426,16 @@ static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot)
static void copy_wpaint_prev(VPaint *wp, MDeformVert *dverts, int dcount)
{
- if (wp->wpaint_prev) {
- free_dverts(wp->wpaint_prev, wp->tot);
- wp->wpaint_prev = NULL;
- }
+ free_wpaint_prev(wp);
if (dverts && dcount) {
wp->wpaint_prev = MEM_mallocN(sizeof(MDeformVert) * dcount, "wpaint prev");
wp->tot = dcount;
- copy_dverts(wp->wpaint_prev, dverts, dcount);
+ BKE_defvert_array_copy(wp->wpaint_prev, dverts, dcount);
}
}
-
void vpaint_fill(Object *ob, unsigned int paintcol)
{
Mesh *me;
@@ -447,7 +450,7 @@ void vpaint_fill(Object *ob, unsigned int paintcol)
if (!me->mloopcol) return; /* possible we can't make mcol's */
- selected = (me->editflag & ME_EDIT_PAINT_MASK);
+ selected = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
mp = me->mpoly;
for (i = 0; i < me->totpoly; i++, mp++) {
@@ -657,11 +660,11 @@ BLI_INLINE unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
cp = (unsigned char *)&col;
temp = cp1[0] - ((fac * cp2[0]) / 255);
- cp1[0] = (temp < 0) ? 0 : temp;
+ cp[0] = (temp < 0) ? 0 : temp;
temp = cp1[1] - ((fac * cp2[1]) / 255);
- cp1[1] = (temp < 0) ? 0 : temp;
+ cp[1] = (temp < 0) ? 0 : temp;
temp = cp1[2] - ((fac * cp2[2]) / 255);
- cp1[2] = (temp < 0) ? 0 : temp;
+ cp[2] = (temp < 0) ? 0 : temp;
cp[3] = 255;
return col;
@@ -851,12 +854,15 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x
}
/* whats _dl mean? */
-static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_nor[3],
+static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float co[3],
const float mval[2], const float brush_size_pressure)
{
float vertco[2];
- if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc->ar,
+ co, vertco,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
float delta[2];
float dist_squared;
@@ -873,24 +879,23 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n
}
static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
- float vpimat[][3], const float *vert_nor,
+ float vpimat[3][3], const DMCoNo *v_co_no,
const float mval[2],
const float brush_size_pressure, const float brush_alpha_pressure)
{
- float strength = calc_vp_strength_dl(vp, vc, vert_nor, mval, brush_size_pressure);
+ float strength = calc_vp_strength_dl(vp, vc, v_co_no->co, mval, brush_size_pressure);
if (strength > 0.0f) {
float alpha = brush_alpha_pressure * strength;
if (vp->flag & VP_NORMALS) {
float dvec[3];
- const float *no = vert_nor + 3;
/* transpose ! */
- dvec[2] = dot_v3v3(vpimat[2], no);
+ dvec[2] = dot_v3v3(vpimat[2], v_co_no->no);
if (dvec[2] > 0.0f) {
- dvec[0] = dot_v3v3(vpimat[0], no);
- dvec[1] = dot_v3v3(vpimat[1], no);
+ dvec[0] = dot_v3v3(vpimat[0], v_co_no->no);
+ dvec[1] = dot_v3v3(vpimat[1], v_co_no->no);
alpha *= dvec[2] / len_v3(dvec);
}
@@ -908,7 +913,8 @@ static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
BLI_INLINE float wval_blend(const float weight, const float paintval, const float alpha)
{
- return (paintval * alpha) + (weight * (1.0f - alpha));
+ const float talpha = min_ff(alpha, 1.0f); /* blending with values over 1 doesn't make sense */
+ return (paintval * talpha) + (weight * (1.0f - talpha));
}
BLI_INLINE float wval_add(const float weight, const float paintval, const float alpha)
{
@@ -1019,22 +1025,23 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
me = BKE_mesh_from_object(vc.obact);
if (me && me->dvert && vc.v3d && vc.rv3d) {
- const int use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int v_idx_best = -1;
unsigned int index;
view3d_operator_needs_opengl(C);
+ ED_view3d_init_mats_rv3d(vc.obact, vc.rv3d);
if (use_vert_sel) {
- if (ED_mesh_pick_vert(C, me, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) {
+ if (ED_mesh_pick_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) {
v_idx_best = index;
}
}
else {
- if (ED_mesh_pick_face_vert(C, me, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
+ if (ED_mesh_pick_face_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
v_idx_best = index;
}
- else if (ED_mesh_pick_face(C, me, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
+ else if (ED_mesh_pick_face(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
/* this relies on knowning the internal worksings of ED_mesh_pick_face_vert() */
BKE_report(op->reports, RPT_WARNING, "The modifier used does not support deformed locations");
}
@@ -1104,7 +1111,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
if (me && me->dvert && vc.v3d && vc.rv3d && vc.obact->defbase.first) {
const int defbase_tot = BLI_countlist(&vc.obact->defbase);
- const int use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups");
int found = FALSE;
unsigned int index;
@@ -1113,15 +1120,16 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
win->eventstate->y - vc.ar->winrct.ymin};
view3d_operator_needs_opengl(C);
+ ED_view3d_init_mats_rv3d(vc.obact, vc.rv3d);
if (use_vert_sel) {
- if (ED_mesh_pick_vert(C, me, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) {
+ if (ED_mesh_pick_vert(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) {
MDeformVert *dvert = &me->dvert[index];
found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups);
}
}
else {
- if (ED_mesh_pick_face(C, me, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
+ if (ED_mesh_pick_face(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
MPoly *mp = &me->mpoly[index];
unsigned int fidx = mp->totloop - 1;
@@ -1994,6 +2002,13 @@ static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */
else {
mesh_octree_table(NULL, NULL, NULL, 'e');
mesh_mirrtopo_table(NULL, 'e');
+
+ if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
+ BKE_mesh_flush_select_from_verts(me);
+ }
+ else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
}
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
@@ -2038,34 +2053,30 @@ struct WPaintData {
int *indexar;
int vgroup_active;
int vgroup_mirror;
- float *vertexcosnos;
+ DMCoNo *vertexcosnos;
float wpimat[3][3];
-
+
/* variables for auto normalize */
const char *vgroup_validmap; /* stores if vgroups tie to deforming bones or not */
const char *lock_flags;
int defbase_tot;
};
-static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNUSED(mouse[2]))
+/* ensure we have data on wpaint start, add if needed */
+static int wpaint_ensure_data(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- struct PaintStroke *stroke = op->customdata;
- ToolSettings *ts = scene->toolsettings;
- VPaint *wp = ts->wpaint;
Object *ob = CTX_data_active_object(C);
- struct WPaintData *wpd;
- Mesh *me;
+ Mesh *me = BKE_mesh_from_object(ob);
- float mat[4][4], imat[4][4];
-
if (scene->obedit) {
return FALSE;
}
-
- me = BKE_mesh_from_object(ob);
- if (me == NULL || me->totpoly == 0) return OPERATOR_PASS_THROUGH;
-
+
+ if (me == NULL || me->totpoly == 0) {
+ return FALSE;
+ }
+
/* if nothing was added yet, we make dverts and a vertex deform group */
if (!me->dvert) {
ED_vgroup_data_create(&me->id);
@@ -2104,6 +2115,25 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU
return FALSE;
}
+ return TRUE;
+}
+
+static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNUSED(mouse[2]))
+{
+ Scene *scene = CTX_data_scene(C);
+ struct PaintStroke *stroke = op->customdata;
+ ToolSettings *ts = scene->toolsettings;
+ VPaint *wp = ts->wpaint;
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = BKE_mesh_from_object(ob);
+ struct WPaintData *wpd;
+
+ float mat[4][4], imat[4][4];
+
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return FALSE;
+ }
+
{
/* check if we are attempting to paint onto a locked vertex group,
* and other options disallow it from doing anything useful */
@@ -2145,6 +2175,11 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU
if (me->editflag & ME_EDIT_MIRROR_X) {
wpd->vgroup_mirror = wpaint_mirror_vgroup_ensure(ob, wpd->vgroup_active);
}
+
+ {
+ UnifiedPaintSettings *ups = &ts->unified_paint_settings;
+ ups->draw_pressure = true;
+ }
return TRUE;
}
@@ -2166,7 +2201,15 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
unsigned int index, totindex;
float alpha;
float mval[2];
- int use_vert_sel;
+ bool use_vert_sel;
+ bool use_face_sel;
+ bool use_depth;
+
+ MDeformWeight *(*dw_func)(MDeformVert *, const int) =
+ (brush->vertexpaint_tool == PAINT_BLEND_BLUR) ?
+ ((wp->flag & VP_ONLYVGROUP) ?
+ (MDeformWeight *(*)(MDeformVert *, const int))defvert_find_index :
+ defvert_verify_index) : NULL;
const float pressure = RNA_float_get(itemptr, "pressure");
const float brush_size_pressure = BKE_brush_size_get(scene, brush) * (BKE_brush_use_size_pressure(scene, brush) ? pressure : 1.0f);
@@ -2183,14 +2226,15 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
ED_region_tag_redraw(CTX_wm_region(C));
return;
}
-
+
vc = &wpd->vc;
ob = vc->obact;
me = ob->data;
indexar = wpd->indexar;
view3d_operator_needs_opengl(C);
-
+ ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+
/* load projection matrix */
mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
@@ -2223,32 +2267,39 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
swap_m4m4(wpd->vc.rv3d->persmat, mat);
- use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
+ use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
+ use_depth = (vc->v3d->flag & V3D_ZBUF_SELECT);
/* which faces are involved */
- if (wp->flag & VP_AREA) {
- /* Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell */
- me->editflag &= ~ME_EDIT_VERT_SEL;
- totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
- me->editflag |= use_vert_sel ? ME_EDIT_VERT_SEL : 0;
- }
- else {
- indexar[0] = view3d_sample_backbuf(vc, mval[0], mval[1]);
- if (indexar[0]) totindex = 1;
- else totindex = 0;
- }
+ if (use_depth) {
+ if (wp->flag & VP_AREA) {
+ /* Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell */
+ me->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
+ totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
+ me->editflag |= use_vert_sel ? ME_EDIT_PAINT_VERT_SEL : 0;
+ }
+ else {
+ indexar[0] = view3d_sample_backbuf(vc, mval[0], mval[1]);
+ if (indexar[0]) totindex = 1;
+ else totindex = 0;
+ }
- if ((me->editflag & ME_EDIT_PAINT_MASK) && me->mpoly) {
- for (index = 0; index < totindex; index++) {
- if (indexar[index] && indexar[index] <= me->totpoly) {
- MPoly *mpoly = ((MPoly *)me->mpoly) + (indexar[index] - 1);
-
- if ((mpoly->flag & ME_FACE_SEL) == 0) {
- indexar[index] = 0;
+ if (use_face_sel && me->mpoly) {
+ for (index = 0; index < totindex; index++) {
+ if (indexar[index] && indexar[index] <= me->totpoly) {
+ MPoly *mpoly = ((MPoly *)me->mpoly) + (indexar[index] - 1);
+
+ if ((mpoly->flag & ME_FACE_SEL) == 0) {
+ indexar[index] = 0;
+ }
}
}
}
}
+ else {
+ indexar = NULL;
+ }
/* make sure each vertex gets treated only once */
/* and calculate filter weight */
@@ -2257,80 +2308,126 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
paintweight = 0.0f;
else
paintweight = BKE_brush_weight_get(scene, brush);
-
- for (index = 0; index < totindex; index++) {
- if (indexar[index] && indexar[index] <= me->totpoly) {
- MPoly *mpoly = me->mpoly + (indexar[index] - 1);
- MLoop *ml = me->mloop + mpoly->loopstart;
- int i;
- if (use_vert_sel) {
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- me->dvert[ml->v].flag = (me->mvert[ml->v].flag & SELECT);
+#define WP_BLUR_ACCUM(v_idx_var) \
+ { \
+ const unsigned int vidx = v_idx_var; \
+ const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure); \
+ if (fac > 0.0f) { \
+ MDeformWeight *dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); \
+ paintweight += dw ? (dw->weight * fac) : 0.0f; \
+ totw += fac; \
+ } \
+ } (void)0
+
+
+ if (use_depth) {
+ for (index = 0; index < totindex; index++) {
+ if (indexar[index] && indexar[index] <= me->totpoly) {
+ MPoly *mpoly = me->mpoly + (indexar[index] - 1);
+ MLoop *ml = me->mloop + mpoly->loopstart;
+ int i;
+
+ if (use_vert_sel) {
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ me->dvert[ml->v].flag = (me->mvert[ml->v].flag & SELECT);
+ }
}
- }
- else {
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- me->dvert[ml->v].flag = 1;
+ else {
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ me->dvert[ml->v].flag = 1;
+ }
}
- }
-
- if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
- MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int);
-
- if (wp->flag & VP_ONLYVGROUP)
- dw_func = (MDeformWeight *(*)(MDeformVert *, const int))defvert_find_index;
- else
- dw_func = defvert_verify_index;
-
- ml = me->mloop + mpoly->loopstart;
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- unsigned int vidx = ml->v;
- const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos + 6 * vidx, mval, brush_size_pressure);
- if (fac > 0.0f) {
- dw = dw_func(&me->dvert[vidx], wpi.vgroup_active);
- paintweight += dw ? (dw->weight * fac) : 0.0f;
- totw += fac;
+
+ if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
+ ml = me->mloop + mpoly->loopstart;
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ WP_BLUR_ACCUM(ml->v);
}
}
}
}
}
-
+ else {
+ const unsigned int totvert = me->totvert;
+ unsigned int i;
+
+ /* in the case of face selection we need to flush */
+ if (use_vert_sel || use_face_sel) {
+ for (i = 0; i < totvert; i++) {
+ me->dvert[i].flag = me->mvert[i].flag & SELECT;
+ }
+ }
+ else {
+ for (i = 0; i < totvert; i++) {
+ me->dvert[i].flag = SELECT;
+ }
+ }
+
+ if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
+ for (i = 0; i < totvert; i++) {
+ WP_BLUR_ACCUM(i);
+ }
+ }
+ }
+
+#undef WP_BLUR_ACCUM
+
+
if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
paintweight /= totw;
}
- for (index = 0; index < totindex; index++) {
+#define WP_PAINT(v_idx_var) \
+ { \
+ unsigned int vidx = v_idx_var; \
+ if (me->dvert[vidx].flag) { \
+ alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
+ mval, brush_size_pressure, brush_alpha_pressure); \
+ if (alpha) { \
+ do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \
+ } \
+ me->dvert[vidx].flag = 0; \
+ } \
+ } (void)0
+
+ if (use_depth) {
+ for (index = 0; index < totindex; index++) {
- if (indexar[index] && indexar[index] <= me->totpoly) {
- MPoly *mpoly = me->mpoly + (indexar[index] - 1);
- MLoop *ml = me->mloop + mpoly->loopstart;
- int i;
-
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- unsigned int vidx = ml->v;
-
- if (me->dvert[vidx].flag) {
- alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos + 6 * vidx,
- mval, brush_size_pressure, brush_alpha_pressure);
- if (alpha) {
- do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight);
- }
- me->dvert[vidx].flag = 0;
+ if (indexar[index] && indexar[index] <= me->totpoly) {
+ MPoly *mpoly = me->mpoly + (indexar[index] - 1);
+ MLoop *ml = me->mloop + mpoly->loopstart;
+ int i;
+
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ WP_PAINT(ml->v);
}
}
}
}
+ else {
+ const unsigned int totvert = me->totvert;
+ unsigned int i;
+
+ for (i = 0; i < totvert; i++) {
+ WP_PAINT(i);
+ }
+ }
+#undef WP_PAINT
/* *** free wpi members */
MEM_freeN((void *)wpi.defbase_sel);
- /* *** don't freeing wpi members */
+ /* *** done freeing wpi members */
swap_m4m4(vc->rv3d->persmat, mat);
-
+
+ {
+ UnifiedPaintSettings *ups = &ts->unified_paint_settings;
+ ups->pressure_value = pressure;
+ }
+
DAG_id_tag_update(ob->data, 0);
ED_region_tag_redraw(vc->ar);
}
@@ -2371,7 +2468,12 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
}
}
}
-
+
+ {
+ UnifiedPaintSettings *ups = &ts->unified_paint_settings;
+ ups->draw_pressure = false;
+ }
+
DAG_id_tag_update(ob->data, 0);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -2424,7 +2526,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
}
-static int weight_paint_set_exec(bContext *C, wmOperator *UNUSED(op))
+static int weight_paint_set_exec(bContext *C, wmOperator *op)
{
struct Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
@@ -2432,6 +2534,10 @@ static int weight_paint_set_exec(bContext *C, wmOperator *UNUSED(op))
Brush *brush = paint_brush(&ts->wpaint->paint);
float vgroup_weight = BKE_brush_weight_get(scene, brush);
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return OPERATOR_CANCELLED;
+ }
+
wpaint_fill(scene->toolsettings->wpaint, obact, vgroup_weight);
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
return OPERATOR_FINISHED;
@@ -2477,6 +2583,10 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
if (ob->mode & OB_MODE_VERTEX_PAINT) {
ob->mode &= ~OB_MODE_VERTEX_PAINT;
+
+ if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
}
else {
ob->mode |= OB_MODE_VERTEX_PAINT;
@@ -2492,9 +2602,8 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
BKE_paint_init(&vp->paint, PAINT_CURSOR_VERTEX_PAINT);
}
- if (me)
- /* update modifier stack for mapping requirements */
- DAG_id_tag_update(&me->id, 0);
+ /* update modifier stack for mapping requirements */
+ DAG_id_tag_update(&me->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
@@ -2548,7 +2657,7 @@ typedef struct VPaintData {
ViewContext vc;
unsigned int paintcol;
int *indexar;
- float *vertexcosnos;
+ DMCoNo *vertexcosnos;
float vpimat[3][3];
/* modify 'me->mcol' directly, since the derived mesh is drawing from this array,
@@ -2644,16 +2753,20 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
invert_m4_m4(imat, mat);
copy_m3_m4(vpd->vpimat, imat);
+ {
+ UnifiedPaintSettings *ups = &ts->unified_paint_settings;
+ ups->draw_pressure = true;
+ }
+
return 1;
}
-static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob,
+static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
const unsigned int index, const float mval[2],
const float brush_size_pressure, const float brush_alpha_pressure)
{
ViewContext *vc = &vpd->vc;
Brush *brush = paint_brush(&vp->paint);
- Mesh *me = BKE_mesh_from_object(ob);
MPoly *mpoly = &me->mpoly[index];
MFace *mf;
MCol *mc;
@@ -2696,7 +2809,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob,
ml = me->mloop + mpoly->loopstart;
for (i = 0; i < mpoly->totloop; i++, ml++) {
alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat,
- vpd->vertexcosnos + 6 * ml->v, mval,
+ &vpd->vertexcosnos[ml->v], mval,
brush_size_pressure, brush_alpha_pressure);
if (alpha > 0.0f) {
const int alpha_i = (int)(alpha * 255.0f);
@@ -2754,7 +2867,8 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
RNA_float_get_array(itemptr, "mouse", mval);
view3d_operator_needs_opengl(C);
-
+ ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+
/* load projection matrix */
mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
@@ -2772,7 +2886,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
else totindex = 0;
}
- if ((me->editflag & ME_EDIT_PAINT_MASK) && me->mpoly) {
+ if ((me->editflag & ME_EDIT_PAINT_FACE_SEL) && me->mpoly) {
for (index = 0; index < totindex; index++) {
if (indexar[index] && indexar[index] <= me->totpoly) {
MPoly *mpoly = ((MPoly *)me->mpoly) + (indexar[index] - 1);
@@ -2787,7 +2901,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
for (index = 0; index < totindex; index++) {
if (indexar[index] && indexar[index] <= me->totpoly) {
- vpaint_paint_poly(vp, vpd, ob, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure);
+ vpaint_paint_poly(vp, vpd, me, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure);
}
}
@@ -2799,6 +2913,11 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
do_shared_vertexcol(me, do_tessface);
}
+ {
+ UnifiedPaintSettings *ups = &ts->unified_paint_settings;
+ ups->pressure_value = pressure;
+ }
+
ED_region_tag_redraw(vc->ar);
if (vpd->use_fast_update == FALSE) {
@@ -2830,6 +2949,11 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
BLI_memarena_free(vpd->polyfacemap_arena);
}
+ {
+ UnifiedPaintSettings *ups = &ts->unified_paint_settings;
+ ups->draw_pressure = false;
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
MEM_freeN(vpd);
@@ -2929,3 +3053,275 @@ void PAINT_OT_weight_from_bones(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "Method to use for assigning weights");
}
+
+/* *** VGroups Gradient *** */
+typedef struct DMGradient_vertStore {
+ float sco[2];
+ float weight_orig;
+ enum {
+ VGRAD_STORE_NOP = 0,
+ VGRAD_STORE_DW_EXIST = (1 << 0)
+ } flag;
+} DMGradient_vertStore;
+
+typedef struct DMGradient_userData {
+ struct ARegion *ar;
+ Scene *scene;
+ Mesh *me;
+ Brush *brush;
+ const float *sco_start; /* [2] */
+ const float *sco_end; /* [2] */
+ float sco_line_div; /* store (1.0f / len_v2v2(sco_start, sco_end)) */
+ int def_nr;
+ short is_init;
+ DMGradient_vertStore *vert_cache;
+
+ /* options */
+ short use_select;
+ short type;
+ float weightpaint;
+} DMGradient_userData;
+
+static void gradientVert__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ DMGradient_userData *grad_data = userData;
+ Mesh *me = grad_data->me;
+
+ if (grad_data->use_select == FALSE || (me->mvert[index].flag & SELECT)) {
+ DMGradient_vertStore *vs = &grad_data->vert_cache[index];
+
+ /* run first pass only, could be split into its own mapFunc
+ * the screen coords of the verts need to be cached because
+ * updating the mesh may move them about (entering feedback loop) */
+ if (grad_data->is_init) {
+ if (ED_view3d_project_float_object(grad_data->ar,
+ co, vs->sco,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
+ /* ok */
+ MDeformVert *dv = &me->dvert[index];
+ MDeformWeight *dw;
+ dw = defvert_find_index(dv, grad_data->def_nr);
+ if (dw) {
+ vs->weight_orig = dw->weight;
+ vs->flag = VGRAD_STORE_DW_EXIST;
+ }
+ else {
+ vs->weight_orig = 0.0f;
+ vs->flag = VGRAD_STORE_NOP;
+ }
+ }
+ else {
+ /* no go */
+ copy_v2_fl(vs->sco, FLT_MAX);
+ }
+ }
+ /* end init */
+
+ if (vs->sco[0] != FLT_MAX) {
+ float alpha;
+
+ if (grad_data->type == WPAINT_GRADIENT_TYPE_LINEAR) {
+ alpha = line_point_factor_v2(vs->sco, grad_data->sco_start, grad_data->sco_end);
+ }
+ else {
+ BLI_assert(grad_data->type == WPAINT_GRADIENT_TYPE_RADIAL);
+ alpha = len_v2v2(grad_data->sco_start, vs->sco) * grad_data->sco_line_div;
+ }
+ /* no need to clamp 'alpha' yet */
+
+ /* adjust weight */
+ alpha = BKE_brush_curve_strength_clamp(grad_data->brush, alpha, 1.0f);
+
+ if (alpha != 0.0f) {
+ MDeformVert *dv = &me->dvert[index];
+ MDeformWeight *dw = defvert_verify_index(dv, grad_data->def_nr);
+ // dw->weight = alpha; // testing
+ int tool = grad_data->brush->vertexpaint_tool;
+ float testw;
+
+ /* init if we just added */
+ testw = wpaint_blend_tool(tool, vs->weight_orig, grad_data->weightpaint, alpha * grad_data->brush->alpha);
+ CLAMP(testw, 0.0f, 1.0f);
+ dw->weight = testw;
+ }
+ else {
+ MDeformVert *dv = &me->dvert[index];
+ if (vs->flag & VGRAD_STORE_DW_EXIST) {
+ /* normally we NULL check, but in this case we know it exists */
+ MDeformWeight *dw = defvert_find_index(dv, grad_data->def_nr);
+ dw->weight = vs->weight_orig;
+ }
+ else {
+ /* wasn't originally existing, remove */
+ MDeformWeight *dw = defvert_find_index(dv, grad_data->def_nr);
+ if (dw) {
+ defvert_remove_group(dv, dw);
+ }
+ }
+ }
+ }
+ }
+}
+
+static int paint_weight_gradient_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int ret = WM_gesture_straightline_modal(C, op, event);
+
+ if (ret & OPERATOR_RUNNING_MODAL) {
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { /* XXX, hardcoded */
+ /* generally crap! redo! */
+ WM_gesture_straightline_cancel(C, op);
+ ret &= ~OPERATOR_RUNNING_MODAL;
+ ret |= OPERATOR_FINISHED;
+ }
+ }
+
+ if (ret & OPERATOR_CANCELLED) {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ VPaint *wp = ts->wpaint;
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+ if (wp->wpaint_prev) {
+ BKE_defvert_array_free_elems(me->dvert, me->totvert);
+ BKE_defvert_array_copy(me->dvert, wp->wpaint_prev, me->totvert);
+ free_wpaint_prev(wp);
+ }
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ else if (ret & OPERATOR_FINISHED) {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ VPaint *wp = ts->wpaint;
+ free_wpaint_prev(wp);
+ }
+
+ return ret;
+}
+
+static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
+{
+ wmGesture *gesture = op->customdata;
+ DMGradient_vertStore *vert_cache;
+ struct ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+ int x_start = RNA_int_get(op->ptr, "xstart");
+ int y_start = RNA_int_get(op->ptr, "ystart");
+ int x_end = RNA_int_get(op->ptr, "xend");
+ int y_end = RNA_int_get(op->ptr, "yend");
+ float sco_start[2] = {x_start, y_start};
+ float sco_end[2] = {x_end, y_end};
+ const bool is_interactive = (gesture != NULL);
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
+
+ DMGradient_userData data = {0};
+
+ if (is_interactive) {
+ if (gesture->userdata == NULL) {
+ VPaint *wp = scene->toolsettings->wpaint;
+
+ gesture->userdata = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert, __func__);
+ data.is_init = true;
+
+ copy_wpaint_prev(wp, me->dvert, me->totvert);
+
+ /* on init only, convert face -> vert sel */
+ if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
+ }
+
+ vert_cache = gesture->userdata;
+ }
+ else {
+ data.is_init = true;
+ vert_cache = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert, __func__);
+ }
+
+ data.ar = ar;
+ data.scene = scene;
+ data.me = ob->data;
+ data.sco_start = sco_start;
+ data.sco_end = sco_end;
+ data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end);
+ data.def_nr = ob->actdef - 1;
+ data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL));
+ data.vert_cache = vert_cache;
+ data.type = RNA_enum_get(op->ptr, "type");
+
+ {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ VPaint *wp = ts->wpaint;
+ struct Brush *brush = paint_brush(&wp->paint);
+ data.brush = brush;
+ data.weightpaint = BKE_brush_weight_get(scene, brush);
+ }
+
+ dm->foreachMappedVert(dm, gradientVert__mapFunc, &data);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ if (is_interactive == false) {
+ MEM_freeN(vert_cache);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int ret;
+
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ret = WM_gesture_straightline_invoke(C, op, event);
+ if (ret & OPERATOR_RUNNING_MODAL) {
+ struct ARegion *ar = CTX_wm_region(C);
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) { /* TODO, hardcoded, extend WM_gesture_straightline_ */
+ wmGesture *gesture = op->customdata;
+ gesture->mode = 1;
+ }
+ }
+ }
+ return ret;
+}
+
+void PAINT_OT_weight_gradient(wmOperatorType *ot)
+{
+ /* defined in DNA_space_types.h */
+ static EnumPropertyItem gradient_types[] = {
+ {WPAINT_GRADIENT_TYPE_LINEAR, "LINEAR", 0, "Linear", ""},
+ {WPAINT_GRADIENT_TYPE_RADIAL, "RADIAL", 0, "Radial", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Weight Gradient";
+ ot->idname = "PAINT_OT_weight_gradient";
+ ot->description = "Sample a line and show it in Scope panels";
+
+ /* api callbacks */
+ ot->invoke = paint_weight_gradient_invoke;
+ ot->modal = paint_weight_gradient_modal;
+ ot->exec = paint_weight_gradient_exec;
+ ot->poll = weight_paint_poll;
+ ot->cancel = WM_gesture_straightline_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ prop = RNA_def_enum(ot->srna, "type", gradient_types, 0, "Type", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT);
+}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e2ed7776b7e..342671698d2 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -40,7 +40,6 @@
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
-#include "BLI_pbvh.h"
#include "BLI_threads.h"
#include "BLI_rand.h"
@@ -51,11 +50,13 @@
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
+#include "BKE_pbvh.h"
#include "BKE_brush.h"
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
@@ -65,6 +66,7 @@
#include "BKE_report.h"
#include "BKE_lattice.h" /* for armature_deform_verts */
#include "BKE_node.h"
+#include "BKE_object.h"
#include "BKE_subsurf.h"
#include "BIF_glutil.h"
@@ -86,6 +88,8 @@
#include "GPU_buffers.h"
+#include "bmesh.h"
+
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -98,8 +102,13 @@ void ED_sculpt_force_update(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (ob && (ob->mode & OB_MODE_SCULPT))
+ if (ob && (ob->mode & OB_MODE_SCULPT)) {
multires_force_update(ob);
+
+ /* Set reorder=false so that saving the file doesn't reorder
+ * the BMesh's elements */
+ sculptsession_bm_to_me(ob, FALSE);
+ }
}
float *ED_sculpt_get_last_stroke(struct Object *ob)
@@ -129,6 +138,11 @@ MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob)
Mesh *me = (Mesh *)ob->data;
ModifierData *md;
+ if (ob->sculpt && ob->sculpt->bm) {
+ /* can't combine multires and dynamic topology */
+ return NULL;
+ }
+
if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
/* multires can't work without displacement layer */
return NULL;
@@ -172,7 +186,8 @@ static int sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
Mesh *me = (Mesh *)ob->data;
MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
- if (mmd) return 0;
+ if (mmd || ob->sculpt->bm)
+ return 0;
/* 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)
@@ -281,12 +296,130 @@ typedef struct StrokeCache {
rcti previous_r; /* previous redraw rectangle */
} StrokeCache;
+/************** Access to original unmodified vertex data *************/
+
+typedef struct {
+ BMLog *bm_log;
+
+ SculptUndoNode *unode;
+ float (*coords)[3];
+ short (*normals)[3];
+ float *vmasks;
+
+ /* Original coordinate, normal, and mask */
+ const float *co;
+ float mask;
+ short no[3];
+} SculptOrigVertData;
+
+
+/* Initialize a SculptOrigVertData for accessing original vertex data;
+ * handles BMesh, mesh, and multires */
+static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
+ Object *ob,
+ SculptUndoNode *unode)
+{
+ SculptSession *ss = ob->sculpt;
+ BMesh *bm = ss->bm;
+
+ memset(data, 0, sizeof(*data));
+ data->unode = unode;
+
+ if (bm) {
+ data->bm_log = ss->bm_log;
+ }
+ else {
+ data->coords = data->unode->co;
+ data->normals = data->unode->no;
+ data->vmasks = data->unode->mask;
+ }
+}
+
+/* Initialize a SculptOrigVertData for accessing original vertex data;
+ * handles BMesh, mesh, and multires */
+static void sculpt_orig_vert_data_init(SculptOrigVertData *data,
+ Object *ob,
+ PBVHNode *node)
+{
+ SculptUndoNode *unode;
+ unode = sculpt_undo_push_node(ob, node, SCULPT_UNDO_COORDS);
+ sculpt_orig_vert_data_unode_init(data, ob, unode);
+
+}
+
+/* Update a SculptOrigVertData for a particular vertex from the PBVH
+ * iterator */
+static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data,
+ PBVHVertexIter *iter)
+{
+ if (orig_data->unode->type == SCULPT_UNDO_COORDS) {
+ if (orig_data->coords) {
+ orig_data->co = orig_data->coords[iter->i];
+ }
+ else {
+ orig_data->co = BM_log_original_vert_co(orig_data->bm_log, iter->bm_vert);
+ }
+
+ if (orig_data->normals) {
+ copy_v3_v3_short(orig_data->no, orig_data->normals[iter->i]);
+ }
+ else {
+ /* TODO: log doesn't store normals yet */
+ normal_float_to_short_v3(orig_data->no, iter->bm_vert->no);
+ }
+ }
+ else if (orig_data->unode->type == SCULPT_UNDO_MASK) {
+ if (orig_data->vmasks) {
+ orig_data->mask = orig_data->vmasks[iter->i];
+ }
+ else {
+ orig_data->mask = BM_log_original_mask(orig_data->bm_log, iter->bm_vert);
+ }
+ }
+}
+
+/**********************************************************************/
+
+/* Returns true if the stroke will use dynamic topology, false
+ otherwise.
+
+ Factors: some brushes like grab cannot do dynamic topology.
+ Others, like smooth, are better without. Same goes for alt-
+ key smoothing. */
+static int sculpt_stroke_dynamic_topology(const SculptSession *ss,
+ const Brush *brush)
+{
+ return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) &&
+
+ (!ss->cache || (!ss->cache->alt_smooth)) &&
+
+ /* Requires mesh restore, which doesn't work with
+ * dynamic-topology */
+ !(brush->flag & BRUSH_ANCHORED) &&
+ !(brush->flag & BRUSH_RESTORE_MESH) &&
+
+ (!ELEM6(brush->sculpt_tool,
+ /* These brushes, as currently coded, cannot
+ * support dynamic topology */
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_LAYER,
+
+ /* These brushes could handle dynamic topology,
+ * but user feedback indicates it's better not
+ * to */
+ SCULPT_TOOL_SMOOTH,
+ SCULPT_TOOL_MASK)));
+}
/*** paint mesh ***/
-static void paint_mesh_restore_co(Sculpt *sd, SculptSession *ss)
+static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
+ const Brush *brush = paint_brush(&sd->paint);
int i;
PBVHNode **nodes;
@@ -296,31 +429,47 @@ static void paint_mesh_restore_co(Sculpt *sd, SculptSession *ss)
(void)sd; /* quied unused warning */
#endif
- BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
- #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
+ /* Disable OpenMP when dynamic-topology is enabled. Otherwise, new
+ * entries might be inserted by sculpt_undo_push_node() into the
+ * GHash used internally by BM_log_original_vert_co() by a
+ * different thread. [#33787] */
+ #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP && !ss->bm)
for (n = 0; n < totnode; n++) {
SculptUndoNode *unode;
-
- unode = sculpt_undo_get_node(nodes[n]);
+ SculptUndoType type = (brush->sculpt_tool == SCULPT_TOOL_MASK ?
+ SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
+
+ if (ss->bm) {
+ unode = sculpt_undo_push_node(ob, nodes[n], type);
+ }
+ else {
+ unode = sculpt_undo_get_node(nodes[n]);
+ }
if (unode) {
PBVHVertexIter vd;
+ SculptOrigVertData orig_data;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ sculpt_orig_vert_data_unode_init(&orig_data, ob, unode);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (unode->type == SCULPT_UNDO_COORDS) {
- copy_v3_v3(vd.co, unode->co[vd.i]);
- if (vd.no) copy_v3_v3_short(vd.no, unode->no[vd.i]);
- else normal_short_to_float_v3(vd.fno, unode->no[vd.i]);
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
+ copy_v3_v3(vd.co, orig_data.co);
+ if (vd.no) copy_v3_v3_short(vd.no, orig_data.no);
+ else normal_short_to_float_v3(vd.fno, orig_data.no);
}
- else if (unode->type == SCULPT_UNDO_MASK) {
- *vd.mask = unode->mask[vd.i];
+ else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
+ *vd.mask = orig_data.mask;
}
if (vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
- BLI_pbvh_node_mark_update(nodes[n]);
+ BKE_pbvh_node_mark_update(nodes[n]);
}
}
@@ -347,7 +496,7 @@ static int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
if (!pbvh)
return 0;
- BLI_pbvh_redraw_BB(pbvh, bb_min, bb_max);
+ BKE_pbvh_redraw_BB(pbvh, bb_min, bb_max);
/* convert 3D bounding box to screen space */
if (!paint_convert_bb_to_rect(rect,
@@ -387,7 +536,7 @@ void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar,
/* clear redraw flag from nodes */
if (pbvh)
- BLI_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL);
+ BKE_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL);
}
/************************ Brush Testing *******************/
@@ -405,7 +554,7 @@ static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test)
test->dist = 0.0f; /* just for initialize */
}
-static int sculpt_brush_test(SculptBrushTest *test, float co[3])
+static int sculpt_brush_test(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
@@ -418,7 +567,7 @@ static int sculpt_brush_test(SculptBrushTest *test, float co[3])
}
}
-static int sculpt_brush_test_sq(SculptBrushTest *test, float co[3])
+static int sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
@@ -510,7 +659,6 @@ static int sculpt_brush_test_cyl(SculptBrushTest *test, float co[3], float locat
/* ===== Sculpting =====
*
*/
-
static float overlapped_curve(Brush *br, float x)
{
@@ -734,7 +882,8 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather)
}
/* Return a multiplier for brush strength on a particular vertex. */
-static float tex_strength(SculptSession *ss, Brush *br, float point[3],
+static float tex_strength(SculptSession *ss, Brush *br,
+ const float point[3],
const float len,
const float sculpt_normal[3],
const short vno[3],
@@ -753,7 +902,7 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3],
/* Get strength by feeding the vertex
* location directly into a texture */
externtex(mtex, point, &avg,
- &jnk, &jnk, &jnk, &jnk, 0);
+ &jnk, &jnk, &jnk, &jnk, 0, ss->tex_pool);
}
else if (ss->texcache) {
float rotation = -mtex->rot;
@@ -839,7 +988,7 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3],
x += br->mtex.ofs[0];
y += br->mtex.ofs[1];
- avg = paint_get_tex_pixel(br, x, y);
+ avg = paint_get_tex_pixel(br, x, y, ss->tex_pool);
}
avg += br->texture_sample_bias;
@@ -871,9 +1020,9 @@ static int sculpt_search_sphere_cb(PBVHNode *node, void *data_v)
int i;
if (data->original)
- BLI_pbvh_node_get_original_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
else
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
for (i = 0; i < 3; ++i) {
if (bb_min[i] > center[i])
@@ -926,6 +1075,11 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
original = (paint_brush(&sd->paint)->sculpt_tool == SCULPT_TOOL_GRAB ?
TRUE : ss->cache->original);
+ /* In general the original coords are not available with dynamic
+ * topology */
+ if (ss->bm)
+ original = FALSE;
+
(void)sd; /* unused w/o openmp */
zero_v3(an);
@@ -942,7 +1096,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
sculpt_brush_test_init(ss, &test);
if (original) {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, unode->co[vd.i])) {
float fno[3];
@@ -951,10 +1105,10 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno);
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, vd.co)) {
if (vd.no) {
@@ -968,7 +1122,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
#pragma omp critical
@@ -1210,6 +1364,71 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert)
return vmask[vert];
}
+/* Same logic as neighbor_average(), but for bmesh rather than mesh */
+static void bmesh_neighbor_average(float avg[3], BMVert *v)
+{
+ const int vfcount = BM_vert_face_count(v);
+
+ zero_v3(avg);
+
+ /* Don't modify corner vertices */
+ if (vfcount > 1) {
+ BMIter liter;
+ BMLoop *l;
+ int i, total = 0;
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ BMVert *adj_v[3] = {l->prev->v, v, l->next->v};
+
+ for (i = 0; i < 3; i++) {
+ if (vfcount != 2 || BM_vert_face_count(adj_v[i]) <= 2) {
+ add_v3_v3(avg, adj_v[i]->co);
+ total++;
+ }
+ }
+ }
+
+ if (total > 0) {
+ mul_v3_fl(avg, 1.0f / total);
+ return;
+ }
+ }
+
+ copy_v3_v3(avg, v->co);
+}
+
+/* Same logic as neighbor_average_mask(), but for bmesh rather than mesh */
+static float bmesh_neighbor_average_mask(BMesh *bm, BMVert *v)
+{
+ BMIter liter;
+ BMLoop *l;
+ float avg = 0;
+ int i, total = 0;
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ BMVert *adj_v[3] = {l->prev->v, v, l->next->v};
+
+ for (i = 0; i < 3; i++) {
+ BMVert *v2 = adj_v[i];
+ float *vmask = CustomData_bmesh_get(&bm->vdata,
+ v2->head.data,
+ CD_PAINT_MASK);
+ avg += (*vmask);
+ total++;
+ }
+ }
+
+ if (total > 0) {
+ return avg / (float)total;
+ }
+ else {
+ float *vmask = CustomData_bmesh_get(&bm->vdata,
+ v->head.data,
+ CD_PAINT_MASK);
+ return (*vmask);
+ }
+}
+
static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask)
{
Brush *brush = paint_brush(&sd->paint);
@@ -1220,7 +1439,7 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1248,7 +1467,48 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void do_bmesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask)
+{
+ Brush *brush = paint_brush(&sd->paint);
+ PBVHVertexIter vd;
+ SculptBrushTest test;
+
+ CLAMP(bstrength, 0.0f, 1.0f);
+
+ sculpt_brush_test_init(ss, &test);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test(&test, vd.co)) {
+ const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
+ ss->cache->view_normal, vd.no, vd.fno,
+ smooth_mask ? 0 : *vd.mask);
+ if (smooth_mask) {
+ float val = bmesh_neighbor_average_mask(ss->bm, vd.bm_vert) - *vd.mask;
+ val *= fade * bstrength;
+ *vd.mask += val;
+ CLAMP(*vd.mask, 0, 1);
+ }
+ else {
+ float avg[3], val[3];
+
+ bmesh_neighbor_average(avg, vd.bm_vert);
+ sub_v3_v3v3(val, avg, vd.co);
+ mul_v3_fl(val, fade);
+
+ add_v3_v3(val, vd.co);
+
+ sculpt_clip(sd, ss, vd.co, val);
+ }
+
+ if (vd.mvert)
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
}
static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
@@ -1269,9 +1529,9 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
CLAMP(bstrength, 0.0f, 1.0f);
- BLI_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid,
+ BKE_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid,
NULL, &gridsize, &griddata, &gridadj);
- BLI_pbvh_get_grid_key(ss->pbvh, &key);
+ BKE_pbvh_get_grid_key(ss->pbvh, &key);
thread_num = 0;
#ifdef _OPENMP
@@ -1405,7 +1665,7 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode,
SculptSession *ss = ob->sculpt;
const int max_iterations = 4;
const float fract = 1.0f / max_iterations;
- PBVHType type = BLI_pbvh_type(ss->pbvh);
+ PBVHType type = BKE_pbvh_type(ss->pbvh);
int iteration, n, count;
float last;
@@ -1433,6 +1693,9 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode,
do_mesh_smooth_brush(sd, ss, nodes[n], strength,
smooth_mask);
break;
+ case PBVH_BMESH:
+ do_bmesh_smooth_brush(sd, ss, nodes[n], strength, smooth_mask);
+ break;
}
}
@@ -1462,7 +1725,7 @@ static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
float fade = tex_strength(ss, brush, vd.co, test.dist,
@@ -1474,7 +1737,7 @@ static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
if (vd.mvert)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
}
@@ -1514,11 +1777,11 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
/* offset vertex */
@@ -1532,7 +1795,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1570,11 +1833,11 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
/* offset vertex */
@@ -1597,7 +1860,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1614,11 +1877,11 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1633,7 +1896,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1659,25 +1922,26 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- SculptUndoNode *unode;
SculptBrushTest test;
- float (*origco)[3];
- short (*origno)[3];
+ SculptOrigVertData orig_data;
float (*proxy)[3];
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- origno = unode->no;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
- const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
- ss->cache->sculpt_normal_symm, origno[vd.i],
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
+ const float fade = bstrength * tex_strength(ss, brush,
+ orig_data.co,
+ test.dist,
+ ss->cache->sculpt_normal_symm,
+ orig_data.no,
NULL, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -1686,7 +1950,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1710,11 +1974,11 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1727,7 +1991,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1759,11 +2023,11 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1776,7 +2040,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1797,26 +2061,27 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- SculptUndoNode *unode;
SculptBrushTest test;
- float (*origco)[3];
- short (*origno)[3];
+ SculptOrigVertData orig_data;
float (*proxy)[3];
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- origno = unode->no;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
- const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
+ const float fade = bstrength * tex_strength(ss, brush,
+ orig_data.co,
+ test.dist,
ss->cache->sculpt_normal_symm,
- origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f);
+ orig_data.no,
+ NULL, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], cono, fade);
@@ -1824,7 +2089,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1850,36 +2115,37 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- SculptUndoNode *unode;
SculptBrushTest test;
- float (*origco)[3];
- short (*origno)[3];
+ SculptOrigVertData orig_data;
float (*proxy)[3];
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- origno = unode->no;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
- const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
+ const float fade = bstrength * tex_strength(ss, brush,
+ orig_data.co,
+ test.dist,
ss->cache->sculpt_normal_symm,
- origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f);
+ orig_data.no,
+ NULL, vd.mask ? *vd.mask : 0.0f);
- mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]);
- sub_v3_v3(proxy[vd.i], origco[vd.i]);
+ mul_v3_m4v3(proxy[vd.i], m, orig_data.co);
+ sub_v3_v3(proxy[vd.i], orig_data.co);
mul_v3_fl(proxy[vd.i], fade);
if (vd.mvert)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1901,25 +2167,25 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
- SculptUndoNode *unode;
- float (*origco)[3], *layer_disp;
+ SculptOrigVertData orig_data;
+ float *layer_disp;
/* XXX: layer brush needs conversion to proxy but its more complicated */
- /* proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */
+ /* proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- if (!unode->layer_disp) {
- #pragma omp critical
- unode->layer_disp = MEM_callocN(sizeof(float) * unode->totvert, "layer disp");
- }
-
- layer_disp = unode->layer_disp;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
+ #pragma omp critical
+ {
+ layer_disp = BKE_pbvh_node_layer_disp_get(ss->pbvh, nodes[n]);
+ }
+
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
ss->cache->sculpt_normal_symm,
vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
@@ -1941,7 +2207,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
add_v3_v3(val, ss->layer_co[index]);
}
else {
- add_v3_v3(val, origco[vd.i]);
+ add_v3_v3(val, orig_data.co);
}
sculpt_clip(sd, ss, vd.co, val);
@@ -1950,7 +2216,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1967,11 +2233,11 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1989,7 +2255,7 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2016,24 +2282,24 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
sculpt_brush_test_init(ss, &test);
if (ss->cache->original) {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, unode->co[vd.i])) {
add_v3_v3(private_fc, unode->co[vd.i]);
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, vd.co)) {
add_v3_v3(private_fc, vd.co);
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
#pragma omp critical
@@ -2082,8 +2348,8 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob,
unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
sculpt_brush_test_init(ss, &test);
- if (ss->cache->original) {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ if (ss->cache->original && unode->co) {
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, unode->co[vd.i])) {
/* for area normal */
@@ -2097,10 +2363,10 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob,
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, vd.co)) {
/* for area normal */
@@ -2119,7 +2385,7 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob,
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
#pragma omp critical
@@ -2301,11 +2567,11 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
float intr[3];
@@ -2326,7 +2592,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2373,11 +2639,11 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (plane_point_side_flip(vd.co, an, fc, flip)) {
@@ -2401,7 +2667,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2475,11 +2741,11 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_cube(&test, vd.co, mat)) {
if (plane_point_side_flip(vd.co, sn, fc, flip)) {
@@ -2503,7 +2769,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2539,11 +2805,11 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (plane_point_side(vd.co, an, fc)) {
@@ -2567,7 +2833,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2603,11 +2869,11 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (!plane_point_side(vd.co, an, fc)) {
@@ -2631,7 +2897,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2688,6 +2954,65 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
BKE_key_convert_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)
+{
+ SculptSession *ss = ob->sculpt;
+ SculptSearchSphereData data;
+ PBVHNode **nodes = NULL;
+ float radius;
+ int n, totnode;
+
+ /* Build a list of all nodes that are potentially within the
+ * brush's area of influence */
+ data.ss = ss;
+ data.sd = sd;
+
+ radius = ss->cache->radius * 1.25f;
+
+ data.radius_squared = radius * radius;
+ data.original = ELEM4(brush->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_LAYER);
+
+ BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
+
+ /* Only act if some verts are inside the brush area */
+ if (totnode) {
+ PBVHTopologyUpdateMode mode = PBVH_Subdivide;
+
+ if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) ||
+ (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY))
+ {
+ mode |= PBVH_Collapse;
+ }
+
+ for (n = 0; n < totnode; n++) {
+ sculpt_undo_push_node(ob, nodes[n],
+ brush->sculpt_tool == SCULPT_TOOL_MASK ?
+ SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
+ BKE_pbvh_node_mark_update(nodes[n]);
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_node_mark_topology_update(nodes[n]);
+ BKE_pbvh_bmesh_node_save_orig(nodes[n]);
+ }
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_bmesh_update_topology(ss->pbvh, mode,
+ ss->cache->location,
+ ss->cache->radius);
+ }
+
+ MEM_freeN(nodes);
+ }
+}
+
static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
{
SculptSession *ss = ob->sculpt;
@@ -2704,7 +3029,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
SCULPT_TOOL_ROTATE,
SCULPT_TOOL_THUMB,
SCULPT_TOOL_LAYER);
- BLI_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
/* Only act if some verts are inside the brush area */
if (totnode) {
@@ -2713,7 +3038,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
sculpt_undo_push_node(ob, nodes[n],
brush->sculpt_tool == SCULPT_TOOL_MASK ?
SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
- BLI_pbvh_node_mark_update(nodes[n]);
+ BKE_pbvh_node_mark_update(nodes[n]);
}
if (brush_needs_sculpt_normal(brush))
@@ -2821,7 +3146,7 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
PBVHNode **nodes;
int totnode, n;
- BLI_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
+ BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER)) {
/* these brushes start from original coordinates */
@@ -2833,20 +3158,27 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
PBVHVertexIter vd;
PBVHProxyNode *proxies;
int proxy_count;
- float (*orco)[3];
+ float (*orco)[3] = NULL;
- if (use_orco)
+ if (use_orco && !ss->bm)
orco = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS)->co;
- BLI_pbvh_node_get_proxies(nodes[n], &proxies, &proxy_count);
+ BKE_pbvh_node_get_proxies(nodes[n], &proxies, &proxy_count);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
float val[3];
int p;
- if (use_orco)
- copy_v3_v3(val, orco[vd.i]);
+ if (use_orco) {
+ if (ss->bm) {
+ copy_v3_v3(val,
+ BM_log_original_vert_co(ss->bm_log,
+ vd.bm_vert));
+ }
+ else
+ copy_v3_v3(val, orco[vd.i]);
+ }
else
copy_v3_v3(val, vd.co);
@@ -2858,9 +3190,9 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
if (ss->modifiers_active)
sculpt_flush_pbvhvert_deform(ob, &vd);
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
- BLI_pbvh_node_free_proxies(nodes[n]);
+ BKE_pbvh_node_free_proxies(nodes[n]);
}
}
@@ -2877,7 +3209,7 @@ static void sculpt_update_keyblock(Object *ob)
/* Keyblock update happens after handling deformation caused by modifiers,
* so ss->orig_cos would be updated with new stroke */
if (ss->orig_cos) vertCos = ss->orig_cos;
- else vertCos = BLI_pbvh_get_vertCos(ss->pbvh);
+ else vertCos = BKE_pbvh_get_vertCos(ss->pbvh);
if (vertCos) {
sculpt_vertcos_to_key(ob, ss->kb, vertCos);
@@ -2905,13 +3237,13 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
if (ss->kb)
vertCos = MEM_callocN(sizeof(*vertCos) * me->totvert, "flushStrokeDeofrm keyVerts");
- BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
sculpt_flush_pbvhvert_deform(ob, &vd);
@@ -2920,7 +3252,7 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
copy_v3_v3(vertCos[index], ss->orig_cos[index]);
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
if (vertCos) {
@@ -2978,7 +3310,10 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
}
+typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush);
+
static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush,
+ BrushActionFunc action,
const char symm, const int axis,
const float feather)
{
@@ -2989,7 +3324,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);
- do_brush_action(sd, ob, brush);
+ action(sd, ob, brush);
}
}
@@ -3006,7 +3341,8 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
multires_stitch_grids(ob);
}
-static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
+static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
+ BrushActionFunc action)
{
Brush *brush = paint_brush(&sd->paint);
SculptSession *ss = ob->sculpt;
@@ -3017,7 +3353,6 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
float feather = calc_symmetry_feather(sd, ss->cache);
cache->bstrength = brush_strength(sd, cache, feather);
-
cache->symmetry = symm;
/* symm is a bit combination of XYZ - 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
@@ -3027,23 +3362,13 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
cache->radial_symmetry_pass = 0;
calc_brushdata_symm(sd, cache, i, 0, 0, feather);
- do_brush_action(sd, ob, brush);
+ action(sd, ob, brush);
- do_radial_symmetry(sd, ob, brush, i, 'X', feather);
- do_radial_symmetry(sd, ob, brush, i, 'Y', feather);
- do_radial_symmetry(sd, ob, brush, i, 'Z', feather);
+ 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);
}
}
-
- sculpt_combine_proxies(sd, ob);
-
- /* hack to fix noise texture tearing mesh */
- sculpt_fix_noise_tear(sd, ob);
-
- if (ss->modifiers_active)
- sculpt_flush_stroke_deform(sd, ob);
-
- cache->first_time = 0;
}
static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
@@ -3056,11 +3381,17 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
ss->texcache = NULL;
}
+ if (ss->tex_pool) {
+ BKE_image_pool_free(ss->tex_pool);
+ ss->tex_pool = NULL;
+ }
+
/* Need to allocate a bigger buffer for bigger brush size */
ss->texcache_side = 2 * radius;
if (!ss->texcache || ss->texcache_side > ss->texcache_actual) {
ss->texcache = BKE_brush_gen_texture_cache(brush, radius);
ss->texcache_actual = ss->texcache_side;
+ ss->tex_pool = BKE_image_pool_new();
}
}
@@ -3142,7 +3473,7 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
ss->orig_cos = (ss->kb) ? BKE_key_convert_to_vertcos(ob, ss->kb) : mesh_getVertexCos(me, NULL);
crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
- BLI_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
for (a = 0; a < me->totvert; ++a) {
invert_m3(ss->deform_imats[a]);
@@ -3152,12 +3483,12 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
else free_sculptsession_deformMats(ss);
/* if pbvh is deformed, key block is already applied to it */
- if (ss->kb && !BLI_pbvh_isDeformed(ss->pbvh)) {
+ if (ss->kb && !BKE_pbvh_isDeformed(ss->pbvh)) {
float (*vertCos)[3] = BKE_key_convert_to_vertcos(ob, ss->kb);
if (vertCos) {
/* apply shape keys coordinates to PBVH */
- BLI_pbvh_apply_vertCos(ss->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
MEM_freeN(vertCos);
}
}
@@ -3220,6 +3551,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
return "Rotate Brush";
case SCULPT_TOOL_MASK:
return "Mask Brush";
+ case SCULPT_TOOL_SIMPLIFY:
+ return "Simplify Brush";
}
return "Sculpting";
@@ -3291,7 +3624,7 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
if (ss->multires) {
int i, gridsize, array_mem_size;
- BLI_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL,
+ BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL,
&gridsize, NULL, NULL);
array_mem_size = cache->num_threads * sizeof(void *);
@@ -3336,6 +3669,7 @@ static void sculpt_omp_done(SculptSession *ss)
static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mouse[2])
{
StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
Brush *brush = paint_brush(&sd->paint);
ViewContext *vc = paint_stroke_view_context(op->customdata);
Object *ob = CTX_data_active_object(C);
@@ -3406,8 +3740,9 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
ED_view3d_global_to_vector(cache->vc->rv3d, cache->vc->rv3d->twmat[3], cache->true_view_normal);
/* Initialize layer brush displacements and persistent coords */
if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
- /* not supported yet for multires */
- if (!ss->multires && !ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
+ /* not supported yet for multires or dynamic topology */
+ if (!ss->multires && !ss->bm && !ss->layer_co &&
+ (brush->flag & BRUSH_PERSISTENT)) {
if (!ss->layer_co)
ss->layer_co = MEM_mallocN(sizeof(float) * 3 * ss->totvert,
"sculpt mesh vertices copy");
@@ -3443,7 +3778,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
}
}
- cache->special_rotation = (brush->flag & BRUSH_RAKE) ? sd->last_angle : 0;
+ cache->special_rotation = (brush->flag & BRUSH_RAKE) ? ups->last_angle : 0;
cache->first_time = 1;
@@ -3452,7 +3787,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
sculpt_omp_start(sd, ss);
}
-static void sculpt_update_brush_delta(Sculpt *sd, Object *ob, Brush *brush)
+static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Brush *brush)
{
SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
@@ -3517,17 +3852,17 @@ static void sculpt_update_brush_delta(Sculpt *sd, Object *ob, Brush *brush)
copy_v3_v3(cache->old_grab_location, grab_location);
if (tool == SCULPT_TOOL_GRAB)
- copy_v3_v3(sd->anchored_location, cache->true_location);
+ copy_v3_v3(ups->anchored_location, cache->true_location);
else if (tool == SCULPT_TOOL_THUMB)
- copy_v3_v3(sd->anchored_location, cache->orig_grab_location);
+ copy_v3_v3(ups->anchored_location, cache->orig_grab_location);
if (ELEM(tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB)) {
/* location stays the same for finding vertices in brush radius */
copy_v3_v3(cache->true_location, cache->orig_grab_location);
- sd->draw_anchored = 1;
- copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse);
- sd->anchored_size = cache->pixel_radius;
+ ups->draw_anchored = 1;
+ copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
+ ups->anchored_size = cache->pixel_radius;
}
}
}
@@ -3538,6 +3873,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
PointerRNA *ptr)
{
Scene *scene = CTX_data_scene(C);
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
Brush *brush = paint_brush(&sd->paint);
@@ -3561,13 +3897,14 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
* brush coord/pressure/etc.
* It's more an events design issue, which doesn't split coordinate/pressure/angle
* changing events. We should avoid this after events system re-design */
- if (paint_space_stroke_enabled(brush) || cache->first_time)
+ if (paint_supports_dynamic_size(brush) || cache->first_time) {
cache->pressure = RNA_float_get(ptr, "pressure");
+ }
/* Truly temporary data that isn't stored in properties */
- sd->draw_pressure = 1;
- sd->pressure_value = cache->pressure;
+ ups->draw_pressure = 1;
+ ups->pressure_value = cache->pressure;
cache->previous_pixel_radius = cache->pixel_radius;
cache->pixel_radius = BKE_brush_size_get(scene, brush);
@@ -3584,12 +3921,13 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
}
}
- if (BKE_brush_use_size_pressure(scene, brush)) {
+ if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush)) {
cache->pixel_radius *= cache->pressure;
cache->radius = cache->initial_radius * cache->pressure;
}
- else
+ else {
cache->radius = cache->initial_radius;
+ }
cache->radius_squared = cache->radius * cache->radius;
@@ -3613,7 +3951,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
const float dx = cache->mouse[0] - cache->initial_mouse[0];
const float dy = cache->mouse[1] - cache->initial_mouse[1];
- sd->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy);
+ ups->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy);
cache->special_rotation = atan2(dx, dy) + M_PI;
@@ -3625,27 +3963,27 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
halfway[1] = dy * 0.5f + cache->initial_mouse[1];
if (sculpt_stroke_get_location(C, out, halfway)) {
- copy_v3_v3(sd->anchored_location, out);
- copy_v2_v2(sd->anchored_initial_mouse, halfway);
+ copy_v3_v3(ups->anchored_location, out);
+ copy_v2_v2(ups->anchored_initial_mouse, halfway);
copy_v2_v2(cache->tex_mouse, halfway);
- copy_v3_v3(cache->true_location, sd->anchored_location);
- sd->anchored_size /= 2.0f;
+ copy_v3_v3(cache->true_location, ups->anchored_location);
+ ups->anchored_size /= 2.0f;
cache->pixel_radius /= 2.0f;
hit = 1;
}
}
if (!hit)
- copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse);
+ copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
cache->radius = paint_calc_object_space_radius(paint_stroke_view_context(stroke),
cache->true_location,
cache->pixel_radius);
cache->radius_squared = cache->radius * cache->radius;
- copy_v3_v3(sd->anchored_location, cache->true_location);
+ copy_v3_v3(ups->anchored_location, cache->true_location);
- sd->draw_anchored = 1;
+ ups->draw_anchored = 1;
}
else if (brush->flag & BRUSH_RAKE) {
const float u = 0.5f;
@@ -3666,7 +4004,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
}
}
- sculpt_update_brush_delta(sd, ob, brush);
+ sculpt_update_brush_delta(ups, ob, brush);
if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
const float dx = cache->mouse[0] - cache->initial_mouse[0];
@@ -3674,13 +4012,13 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
cache->vertex_rotation = -atan2f(dx, dy) * cache->bstrength;
- sd->draw_anchored = 1;
- copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse);
- copy_v3_v3(sd->anchored_location, cache->true_location);
- sd->anchored_size = cache->pixel_radius;
+ ups->draw_anchored = 1;
+ copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
+ copy_v3_v3(ups->anchored_location, cache->true_location);
+ ups->anchored_size = cache->pixel_radius;
}
- sd->special_rotation = cache->special_rotation;
+ ups->special_rotation = cache->special_rotation;
}
/* Returns true iff any of the smoothing modes are active (currently
@@ -3721,17 +4059,26 @@ typedef struct {
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BLI_pbvh_node_get_tmin(node) < *tmin) {
+ if (BKE_pbvh_node_get_tmin(node) < *tmin) {
SculptRaycastData *srd = data_v;
float (*origco)[3] = NULL;
+ int use_origco = FALSE;
if (srd->original && srd->ss->cache) {
- /* intersect with coordinates from before we started stroke */
- SculptUndoNode *unode = sculpt_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = TRUE;
+ }
+ else {
+ /* intersect with coordinates from before we started stroke */
+ SculptUndoNode *unode = sculpt_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? TRUE : FALSE;
+ }
}
- if (BLI_pbvh_node_raycast(srd->ss->pbvh, node, origco, srd->ray_start, srd->ray_normal, &srd->dist)) {
+ if (BKE_pbvh_node_raycast(srd->ss->pbvh, node, origco, use_origco,
+ srd->ray_start, srd->ray_normal, &srd->dist))
+ {
srd->hit = 1;
*tmin = srd->dist;
}
@@ -3780,7 +4127,7 @@ int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
srd.dist = dist;
srd.hit = 0;
srd.original = (cache) ? cache->original : 0;
- BLI_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd,
+ BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd,
ray_start, ray_normal, srd.original);
copy_v3_v3(out, ray_normal);
@@ -3829,8 +4176,9 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
return 1;
}
-static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss)
+static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
/* Restore the mesh before continuing with anchored stroke */
@@ -3839,7 +4187,18 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss)
BKE_brush_use_size_pressure(ss->cache->vc->scene, brush)) ||
(brush->flag & BRUSH_RESTORE_MESH))
{
- paint_mesh_restore_co(sd, ss);
+ paint_mesh_restore_co(sd, ob);
+ }
+}
+
+/* Copy the PBVH bounding box into the object's bounding box */
+static void sculpt_update_object_bounding_box(Object *ob)
+{
+ if (ob->bb) {
+ float bb_min[3], bb_max[3];
+
+ BKE_pbvh_bounding_box(ob->sculpt->pbvh, bb_min, bb_max);
+ BKE_boundbox_init_from_minmax(ob->bb, bb_min, bb_max);
}
}
@@ -3862,7 +4221,12 @@ static void sculpt_flush_update(bContext *C)
else {
rcti r;
- BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL);
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL);
+ /* Update the object's bounding box too so that the object
+ * doesn't get incorrectly clipped during drawing in
+ * draw_mesh_object(). [#33790] */
+ sculpt_update_object_bounding_box(ob);
+
if (sculpt_get_redraw_rect(ar, CTX_wm_region_view3d(C), ob, &r)) {
if (ss->cache)
ss->cache->previous_r = r;
@@ -3917,11 +4281,33 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
+ const Brush *brush = paint_brush(&sd->paint);
sculpt_stroke_modifiers_check(C, ob);
sculpt_update_cache_variants(C, sd, ob, stroke, itemptr);
- sculpt_restore_mesh(sd, ss);
- do_symmetrical_brush_actions(sd, ob);
+ sculpt_restore_mesh(sd, ob);
+
+ BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
+ (ss->cache->radius /
+ (float)ss->cache->pixel_radius) *
+ (float)sd->detail_size);
+
+ if (sculpt_stroke_dynamic_topology(ss, brush)) {
+ do_symmetrical_brush_actions(sd, ob, sculpt_topology_update);
+ }
+
+ if (paint_brush(&sd->paint)->sculpt_tool != SCULPT_TOOL_SIMPLIFY)
+ do_symmetrical_brush_actions(sd, ob, do_brush_action);
+
+ sculpt_combine_proxies(sd, ob);
+
+ /* hack to fix noise texture tearing mesh */
+ sculpt_fix_noise_tear(sd, ob);
+
+ if (ss->modifiers_active)
+ sculpt_flush_stroke_deform(sd, ob);
+
+ ss->cache->first_time = FALSE;
/* Cleanup */
sculpt_flush_update(C);
@@ -3938,6 +4324,7 @@ static void sculpt_brush_exit_tex(Sculpt *sd)
static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke))
{
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
@@ -3945,9 +4332,9 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_omp_done(ss);
/* reset values used to draw brush after completing the stroke */
- sd->draw_anchored = 0;
- sd->draw_pressure = 0;
- sd->special_rotation = 0;
+ ups->draw_anchored = 0;
+ ups->draw_pressure = 0;
+ ups->special_rotation = 0;
/* Finished */
if (ss->cache) {
@@ -3980,7 +4367,10 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_undo_push_end();
- BLI_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH)
+ BKE_pbvh_bmesh_after_stroke(ss->pbvh);
/* optimization: if there is locked key and active modifiers present in */
/* the stack, keyblock is updating at each step. otherwise we could update */
@@ -4055,7 +4445,7 @@ static int sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
if (ss->cache) {
- paint_mesh_restore_co(sd, ss);
+ paint_mesh_restore_co(sd, ob);
}
paint_stroke_cancel(C, op);
@@ -4137,6 +4527,269 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/************************** Dynamic Topology **************************/
+
+static void sculpt_dynamic_topology_triangulate(BMesh *bm)
+{
+ BM_mesh_triangulate(bm, false, false, NULL, NULL);
+}
+
+void sculpt_pbvh_clear(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ DerivedMesh *dm = ob->derivedFinal;
+
+ /* Clear out any existing DM and PBVH */
+ if (ss->pbvh)
+ BKE_pbvh_free(ss->pbvh);
+ ss->pbvh = NULL;
+ if (dm)
+ dm->getPBVH(NULL, dm);
+ BKE_object_free_display(ob);
+}
+
+void sculpt_update_after_dynamic_topology_toggle(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ Sculpt *sd = scene->toolsettings->sculpt;
+
+ /* Create the PBVH */
+ sculpt_update_mesh_elements(scene, sd, ob, FALSE, FALSE);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+}
+
+void sculpt_dynamic_topology_enable(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Mesh *me = ob->data;
+
+ sculpt_pbvh_clear(ob);
+
+ ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
+ SCULPT_DYNTOPO_SMOOTH_SHADING);
+
+ /* Create triangles-only BMesh */
+ ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
+
+ BM_mesh_bm_from_me(ss->bm, me, TRUE, ob->shapenr);
+ BM_mesh_normals_update(ss->bm, false);
+ sculpt_dynamic_topology_triangulate(ss->bm);
+ BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
+ BM_mesh_normals_update(ss->bm, TRUE);
+
+ /* Enable dynamic topology */
+ me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
+
+ /* Enable logging for undo/redo */
+ ss->bm_log = BM_log_create(ss->bm);
+
+ /* Refresh */
+ sculpt_update_after_dynamic_topology_toggle(C);
+}
+
+/* Free the sculpt BMesh and BMLog
+ *
+ * If 'unode' is given, the BMesh's data is copied out to the unode
+ * before the BMesh is deleted so that it can be restored from */
+void sculpt_dynamic_topology_disable(bContext *C,
+ SculptUndoNode *unode)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Mesh *me = ob->data;
+
+ sculpt_pbvh_clear(ob);
+
+ if (unode) {
+ /* Free all existing custom data */
+ CustomData_free(&me->vdata, me->totvert);
+ CustomData_free(&me->edata, me->totedge);
+ CustomData_free(&me->fdata, me->totface);
+ CustomData_free(&me->ldata, me->totloop);
+ CustomData_free(&me->pdata, me->totpoly);
+
+ /* Copy over stored custom data */
+ me->totvert = unode->bm_enter_totvert;
+ me->totloop = unode->bm_enter_totloop;
+ me->totpoly = unode->bm_enter_totpoly;
+ me->totedge = unode->bm_enter_totedge;
+ me->totface = 0;
+ CustomData_copy(&unode->bm_enter_vdata, &me->vdata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totvert);
+ CustomData_copy(&unode->bm_enter_edata, &me->edata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totedge);
+ CustomData_copy(&unode->bm_enter_ldata, &me->ldata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totloop);
+ CustomData_copy(&unode->bm_enter_pdata, &me->pdata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totpoly);
+
+ mesh_update_customdata_pointers(me, FALSE);
+ }
+ else {
+ sculptsession_bm_to_me(ob, TRUE);
+ }
+
+ BM_mesh_free(ss->bm);
+
+ /* Clear data */
+ me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
+ ss->bm = NULL;
+ BM_log_free(ss->bm_log);
+ ss->bm_log = NULL;
+
+ /* Refresh */
+ sculpt_update_after_dynamic_topology_toggle(C);
+}
+
+static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->bm) {
+ sculpt_undo_push_begin("Dynamic topology disable");
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
+ sculpt_dynamic_topology_disable(C, NULL);
+ }
+ else {
+ sculpt_undo_push_begin("Dynamic topology enable");
+ sculpt_dynamic_topology_enable(C);
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+ }
+ sculpt_undo_push_end();
+
+ return OPERATOR_FINISHED;
+}
+
+static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op,
+ wmEvent *UNUSED(event))
+{
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+ SculptSession *ss = ob->sculpt;
+ const char *msg = "Dynamic-topology sculpting will not preserve"
+ "vertex colors, UVs, or other customdata";
+
+ if (!ss->bm) {
+ int i;
+
+ for (i = 0; i < CD_NUMTYPES; i++) {
+ if (!ELEM7(i, CD_MVERT, CD_MEDGE, CD_MFACE,
+ CD_MLOOP, CD_MPOLY, CD_PAINT_MASK,
+ CD_ORIGINDEX) &&
+ (CustomData_has_layer(&me->vdata, i) ||
+ CustomData_has_layer(&me->edata, i) ||
+ CustomData_has_layer(&me->fdata, i)))
+ {
+ /* The mesh has customdata that will be lost, let the
+ * user confirm this is OK */
+ return WM_operator_confirm_message(C, op, msg);
+ }
+ }
+ }
+
+ return sculpt_dynamic_topology_toggle_exec(C, op);
+}
+
+static void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Dynamic Topology Toggle";
+ ot->idname = "SCULPT_OT_dynamic_topology_toggle";
+ ot->description = "Dynamic topology alters the mesh topology while sculpting";
+
+ /* api callbacks */
+ ot->invoke = sculpt_dynamic_topology_toggle_invoke;
+ ot->exec = sculpt_dynamic_topology_toggle_exec;
+ ot->poll = sculpt_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/************************* SCULPT_OT_optimize *************************/
+
+static int sculpt_optimize_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ sculpt_pbvh_clear(ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int sculpt_and_dynamic_topology_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+
+ return sculpt_mode_poll(C) && ob->sculpt->bm;
+}
+
+/* The BVH gets less optimal more quickly with dynamic topology than
+ * regular sculpting. There is no doubt more clever stuff we can do to
+ * optimize it on the fly, but for now this gives the user a nicer way
+ * to recalculate it than toggling modes. */
+static void SCULPT_OT_optimize(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Optimize";
+ ot->idname = "SCULPT_OT_optimize";
+ ot->description = "Recalculate the sculpt BVH to improve performance";
+
+ /* api callbacks */
+ ot->exec = sculpt_optimize_exec;
+ ot->poll = sculpt_and_dynamic_topology_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/********************* Dynamic topology symmetrize ********************/
+
+static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+ const Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss = ob->sculpt;
+
+ /* To simplify undo for symmetrize, all BMesh elements are logged
+ * as deleted, then after symmetrize operation all BMesh elements
+ * are logged as added (as opposed to attempting to store just the
+ * parts that symmetrize modifies) */
+ sculpt_undo_push_begin("Dynamic topology symmetrize");
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_SYMMETRIZE);
+ BM_log_before_all_removed(ss->bm, ss->bm_log);
+
+ /* Symmetrize and re-triangulate */
+ BMO_op_callf(ss->bm, BMO_FLAG_DEFAULTS,
+ "symmetrize input=%avef direction=%i",
+ sd->symmetrize_direction);
+ sculpt_dynamic_topology_triangulate(ss->bm);
+
+ /* Finish undo */
+ BM_log_all_added(ss->bm, ss->bm_log);
+ sculpt_undo_push_end();
+
+ /* Redraw */
+ sculpt_pbvh_clear(ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_symmetrize(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Symmetrize";
+ ot->idname = "SCULPT_OT_symmetrize";
+
+ /* api callbacks */
+ ot->exec = sculpt_symmetrize_exec;
+ ot->poll = sculpt_and_dynamic_topology_poll;
+}
+
/**** Toggle operator for turning sculpt mode on or off ****/
static void sculpt_init_session(Scene *scene, Object *ob)
@@ -4222,6 +4875,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
int flush_recalc = 0;
@@ -4234,9 +4888,16 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
if (mmd)
multires_force_update(ob);
- if (flush_recalc)
+ if (flush_recalc || (ob->sculpt && ob->sculpt->bm))
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
+ /* Dynamic topology must be disabled before exiting sculpt
+ * mode to ensure the undo stack stays in a consistent
+ * state */
+ sculpt_dynamic_topology_toggle_exec(C, NULL);
+ }
+
/* Leave sculptmode */
ob->mode &= ~OB_MODE_SCULPT;
@@ -4246,6 +4907,12 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
/* Enter sculptmode */
ob->mode |= OB_MODE_SCULPT;
+ /* Remove dynamic-topology flag; this will be enabled if the
+ * file was saved with dynamic topology on, but we don't
+ * automatically re-enter dynamic-topology mode when loading a
+ * file. */
+ me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
+
if (flush_recalc)
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -4257,6 +4924,9 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
ts->sculpt->flags |= SCULPT_SYMM_X;
}
+ if (!ts->sculpt->detail_size)
+ ts->sculpt->detail_size = 30;
+
/* Create sculpt mode session data */
if (ob->sculpt)
free_sculptsession(ob);
@@ -4271,7 +4941,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
}
BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT);
-
+
paint_cursor_start(C, sculpt_poll);
}
@@ -4299,4 +4969,7 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_brush_stroke);
WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
WM_operatortype_append(SCULPT_OT_set_persistent_base);
+ WM_operatortype_append(SCULPT_OT_dynamic_topology_toggle);
+ WM_operatortype_append(SCULPT_OT_optimize);
+ WM_operatortype_append(SCULPT_OT_symmetrize);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index acb906e4a91..fa1bdd6ca82 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -38,7 +38,7 @@
#include "DNA_key_types.h"
#include "BLI_bitmap.h"
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
struct bContext;
struct Brush;
@@ -49,6 +49,7 @@ struct Object;
struct Scene;
struct Sculpt;
struct SculptStroke;
+struct SculptUndoNode;
/* Interface */
struct MultiresModifierData *sculpt_multires_active(struct Scene *scene, struct Object *ob);
@@ -67,12 +68,22 @@ void free_sculptsession_deformMats(struct SculptSession *ss);
/* Stroke */
int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]);
+/* Dynamic topology */
+void sculpt_pbvh_clear(Object *ob);
+void sculpt_update_after_dynamic_topology_toggle(bContext *C);
+void sculpt_dynamic_topology_enable(struct bContext *C);
+void sculpt_dynamic_topology_disable(struct bContext *C,
+ struct SculptUndoNode *unode);
+
/* Undo */
typedef enum {
SCULPT_UNDO_COORDS,
SCULPT_UNDO_HIDDEN,
- SCULPT_UNDO_MASK
+ SCULPT_UNDO_MASK,
+ SCULPT_UNDO_DYNTOPO_BEGIN,
+ SCULPT_UNDO_DYNTOPO_END,
+ SCULPT_UNDO_DYNTOPO_SYMMETRIZE,
} SculptUndoType;
typedef struct SculptUndoNode {
@@ -101,8 +112,17 @@ typedef struct SculptUndoNode {
int *grids; /* to restore into right location */
BLI_bitmap *grid_hidden;
- /* layer brush */
- float *layer_disp;
+ /* bmesh */
+ struct BMLogEntry *bm_entry;
+ int applied;
+ CustomData bm_enter_vdata;
+ CustomData bm_enter_edata;
+ CustomData bm_enter_ldata;
+ CustomData bm_enter_pdata;
+ int bm_enter_totvert;
+ int bm_enter_totedge;
+ int bm_enter_totloop;
+ int bm_enter_totpoly;
/* shape keys */
char shapeName[sizeof(((KeyBlock *)0))->name];
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 1b3fd24ae22..c828e8c8651 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -65,6 +65,7 @@
#include "GPU_buffers.h"
#include "ED_sculpt.h"
+#include "bmesh.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -72,10 +73,10 @@
static void update_cb(PBVHNode *node, void *rebuild)
{
- BLI_pbvh_node_mark_update(node);
+ BKE_pbvh_node_mark_update(node);
if (*((int *)rebuild))
- BLI_pbvh_node_mark_rebuild_draw(node);
- BLI_pbvh_node_fully_hidden_set(node, 0);
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, 0);
}
static void sculpt_undo_restore_deformed(const SculptSession *ss,
@@ -142,7 +143,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
/* pbvh uses it's own mvert array, so coords should be */
/* propagated to pbvh here */
- BLI_pbvh_apply_vertCos(ss->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
MEM_freeN(vertCos);
}
@@ -261,6 +262,111 @@ static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode
return 1;
}
+static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ if (unode->applied) {
+ BM_log_undo(ss->bm, ss->bm_log);
+ unode->applied = FALSE;
+ }
+ else {
+ BM_log_redo(ss->bm, ss->bm_log);
+ unode->applied = TRUE;
+ }
+
+ /* A bit lame, but for now just recreate the PBVH. The alternative
+ * is to store changes to the PBVH in the undo stack. */
+ sculpt_pbvh_clear(ob);
+}
+
+/* Create empty sculpt BMesh and enable logging */
+static void sculpt_undo_bmesh_enable(Object *ob,
+ SculptUndoNode *unode)
+{
+ SculptSession *ss = ob->sculpt;
+ Mesh *me = ob->data;
+
+ sculpt_pbvh_clear(ob);
+
+ /* Create empty BMesh and enable logging */
+ ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
+ BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
+ me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
+
+ /* Restore the BMLog using saved entries */
+ ss->bm_log = BM_log_from_existing_entries_create(ss->bm,
+ unode->bm_entry);
+}
+
+static void sculpt_undo_bmesh_restore_begin(bContext *C,
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ if (unode->applied) {
+ sculpt_dynamic_topology_disable(C, unode);
+ unode->applied = FALSE;
+ }
+ else {
+ sculpt_undo_bmesh_enable(ob, unode);
+
+ /* Restore the mesh from the first log entry */
+ BM_log_redo(ss->bm, ss->bm_log);
+
+ unode->applied = TRUE;
+ }
+}
+
+static void sculpt_undo_bmesh_restore_end(bContext *C,
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ if (unode->applied) {
+ sculpt_undo_bmesh_enable(ob, unode);
+
+ /* Restore the mesh from the last log entry */
+ BM_log_undo(ss->bm, ss->bm_log);
+
+ unode->applied = FALSE;
+ }
+ else {
+ /* Disable dynamic topology sculpting */
+ sculpt_dynamic_topology_disable(C, NULL);
+ unode->applied = TRUE;
+ }
+}
+
+/* Handle all dynamic-topology updates
+ *
+ * Returns TRUE if this was a dynamic-topology undo step, otherwise
+ * returns FALSE to indicate the non-dyntopo code should run. */
+static int sculpt_undo_bmesh_restore(bContext *C,
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ switch (unode->type) {
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ sculpt_undo_bmesh_restore_begin(C, unode, ob, ss);
+ return TRUE;
+
+ case SCULPT_UNDO_DYNTOPO_END:
+ sculpt_undo_bmesh_restore_end(C, unode, ob, ss);
+ return TRUE;
+
+ default:
+ if (ss->bm_log) {
+ sculpt_undo_bmesh_restore_generic(unode, ob, ss);
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
static void sculpt_undo_restore(bContext *C, ListBase *lb)
{
Scene *scene = CTX_data_scene(C);
@@ -289,6 +395,9 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
/* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */
dm = mesh_get_derived_final(scene, ob, 0);
+ if (lb->first && sculpt_undo_bmesh_restore(C, lb->first, ob, ss))
+ return;
+
for (unode = lb->first; unode; unode = unode->next) {
if (!(strcmp(unode->idname, ob->id.name) == 0))
continue;
@@ -306,9 +415,6 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
continue;
}
}
- else {
- continue;
- }
switch (unode->type) {
case SCULPT_UNDO_COORDS:
@@ -323,6 +429,12 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
if (sculpt_undo_restore_mask(C, dm, unode))
update = TRUE;
break;
+
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ BLI_assert(!"Dynamic topology should've already been handled");
+ break;
}
}
@@ -331,8 +443,8 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
/* we update all nodes still, should be more clever, but also
* needs to work correct when exiting/entering sculpt mode and
* the nodes get recreated, though in that case it could do all */
- BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
- BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
+ BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
if ((mmd = sculpt_multires_active(scene, ob))) {
if (rebuild)
@@ -374,8 +486,6 @@ static void sculpt_undo_free(ListBase *lb)
MEM_freeN(unode->index);
if (unode->grids)
MEM_freeN(unode->grids);
- if (unode->layer_disp)
- MEM_freeN(unode->layer_disp);
if (unode->orig_co)
MEM_freeN(unode->orig_co);
if (unode->vert_hidden)
@@ -389,6 +499,17 @@ static void sculpt_undo_free(ListBase *lb)
}
if (unode->mask)
MEM_freeN(unode->mask);
+ if (unode->bm_entry) {
+ BM_log_entry_drop(unode->bm_entry);
+ }
+ if (unode->bm_enter_totvert)
+ CustomData_free(&unode->bm_enter_vdata, unode->bm_enter_totvert);
+ if (unode->bm_enter_totedge)
+ CustomData_free(&unode->bm_enter_edata, unode->bm_enter_totedge);
+ if (unode->bm_enter_totloop)
+ CustomData_free(&unode->bm_enter_ldata, unode->bm_enter_totloop);
+ if (unode->bm_enter_totpoly)
+ CustomData_free(&unode->bm_enter_pdata, unode->bm_enter_totpoly);
}
}
@@ -410,9 +531,9 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh,
BLI_bitmap *grid_hidden;
int i, *grid_indices, totgrid;
- grid_hidden = BLI_pbvh_grid_hidden(pbvh);
+ grid_hidden = BKE_pbvh_grid_hidden(pbvh);
- BLI_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
+ BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
NULL, NULL, NULL, NULL);
unode->grid_hidden = MEM_mapallocN(sizeof(BLI_bitmap) * totgrid,
@@ -439,11 +560,13 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
unode->type = type;
unode->node = node;
- BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
- BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
- &maxgrid, &gridsize, NULL, NULL);
+ if (node) {
+ BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
+ BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
+ &maxgrid, &gridsize, NULL, NULL);
- unode->totvert = totvert;
+ unode->totvert = totvert;
+ }
/* we will use this while sculpting, is mapalloc slow to access then? */
@@ -468,6 +591,11 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
unode->mask = MEM_mapallocN(sizeof(float) * allvert, "SculptUndoNode.mask");
undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float) * sizeof(int)) * allvert);
break;
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ BLI_assert(!"Dynamic topology should've already been handled");
+ break;
}
BLI_addtail(lb, unode);
@@ -496,7 +624,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
SculptSession *ss = ob->sculpt;
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
{
copy_v3_v3(unode->co[vd.i], vd.co);
if (vd.no) copy_v3_v3_short(unode->no[vd.i], vd.no);
@@ -505,7 +633,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
if (ss->modifiers_active)
copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
@@ -521,8 +649,8 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
int *vert_indices, allvert;
int i;
- BLI_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
- BLI_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
+ BKE_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
+ BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
for (i = 0; i < allvert; i++) {
BLI_BITMAP_MODIFY(unode->vert_hidden, i,
mvert[vert_indices[i]].flag & ME_HIDE);
@@ -535,11 +663,85 @@ static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
SculptSession *ss = ob->sculpt;
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
{
unode->mask[vd.i] = *vd.mask;
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
+}
+
+static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
+ PBVHNode *node,
+ SculptUndoType type)
+{
+ ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
+ SculptUndoNode *unode = lb->first;
+ SculptSession *ss = ob->sculpt;
+ PBVHVertexIter vd;
+
+ if (!lb->first) {
+ unode = MEM_callocN(sizeof(*unode), AT);
+
+ BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
+ unode->type = type;
+ unode->applied = TRUE;
+
+ if (type == SCULPT_UNDO_DYNTOPO_END) {
+ unode->bm_entry = BM_log_entry_add(ss->bm_log);
+ BM_log_before_all_removed(ss->bm, ss->bm_log);
+ }
+ else if (type == SCULPT_UNDO_DYNTOPO_BEGIN) {
+ Mesh *me = ob->data;
+
+ /* Store a copy of the mesh's current vertices, loops, and
+ * polys. A full copy like this is needed because entering
+ * dynamic-topology immediately does topological edits
+ * (converting polys to triangles) that the BMLog can't
+ * fully restore from */
+ CustomData_copy(&me->vdata, &unode->bm_enter_vdata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totvert);
+ CustomData_copy(&me->edata, &unode->bm_enter_edata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totedge);
+ CustomData_copy(&me->ldata, &unode->bm_enter_ldata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totloop);
+ CustomData_copy(&me->pdata, &unode->bm_enter_pdata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totpoly);
+ unode->bm_enter_totvert = me->totvert;
+ unode->bm_enter_totedge = me->totedge;
+ unode->bm_enter_totloop = me->totloop;
+ unode->bm_enter_totpoly = me->totpoly;
+
+ unode->bm_entry = BM_log_entry_add(ss->bm_log);
+ BM_log_all_added(ss->bm, ss->bm_log);
+ }
+ else {
+ unode->bm_entry = BM_log_entry_add(ss->bm_log);
+ }
+
+ BLI_addtail(lb, unode);
+ }
+
+ if (node) {
+ switch (type) {
+ case SCULPT_UNDO_COORDS:
+ case SCULPT_UNDO_HIDDEN:
+ case SCULPT_UNDO_MASK:
+ /* Before any vertex values get modified, ensure their
+ * original positions are logged */
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
+ BM_log_vert_before_modified(ss->bm, ss->bm_log, vd.bm_vert);
+ }
+ BKE_pbvh_vertex_iter_end;
+ break;
+
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ break;
+ }
+ }
+
+ return unode;
}
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
@@ -551,7 +753,18 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
/* list is manipulated by multiple threads, so we lock */
BLI_lock_thread(LOCK_CUSTOM1);
- if ((unode = sculpt_undo_get_node(node))) {
+ if (ss->bm ||
+ ELEM(type,
+ SCULPT_UNDO_DYNTOPO_BEGIN,
+ SCULPT_UNDO_DYNTOPO_END))
+ {
+ /* Dynamic topology stores only one undo node per stroke,
+ * regardless of the number of PBVH nodes modified */
+ unode = sculpt_undo_bmesh_push(ob, node, type);
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return unode;
+ }
+ else if ((unode = sculpt_undo_get_node(node))) {
BLI_unlock_thread(LOCK_CUSTOM1);
return unode;
}
@@ -564,14 +777,14 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
if (unode->grids) {
int totgrid, *grids;
- BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
+ BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
NULL, NULL, NULL, NULL);
memcpy(unode->grids, grids, sizeof(int) * totgrid);
}
else {
int *vert_indices, allvert;
- BLI_pbvh_node_num_verts(ss->pbvh, node, NULL, &allvert);
- BLI_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
+ BKE_pbvh_node_num_verts(ss->pbvh, node, NULL, &allvert);
+ BKE_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
memcpy(unode->index, vert_indices, sizeof(int) * unode->totvert);
}
@@ -585,6 +798,11 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
case SCULPT_UNDO_MASK:
sculpt_undo_store_mask(ob, unode);
break;
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ BLI_assert(!"Dynamic topology should've already been handled");
+ break;
}
/* store active shape key */
@@ -612,10 +830,8 @@ void sculpt_undo_push_end(void)
unode->no = NULL;
}
- if (unode->layer_disp) {
- MEM_freeN(unode->layer_disp);
- unode->layer_disp = NULL;
- }
+ if (unode->node)
+ BKE_pbvh_node_layer_disp_free(unode->node);
}
undo_paint_push_end(UNDO_PAINT_MESH);
diff --git a/source/blender/editors/sound/SConscript b/source/blender/editors/sound/SConscript
index e17bccdadd9..1eaf9c2e945 100644
--- a/source/blender/editors/sound/SConscript
+++ b/source/blender/editors/sound/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index aaa1328f9f6..eb138bfeeef 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -264,7 +264,7 @@ static void SOUND_OT_update_animation_flags(wmOperatorType *ot)
*/
/* identifiers */
- ot->name = "Update animation";
+ ot->name = "Update Animation";
ot->description = "Update animation flags";
ot->idname = "SOUND_OT_update_animation_flags";
@@ -300,7 +300,7 @@ static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
static void SOUND_OT_bake_animation(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Update animation cache";
+ ot->name = "Update Animation Cache";
ot->description = "Update the audio animation cache";
ot->idname = "SOUND_OT_bake_animation";
diff --git a/source/blender/editors/space_action/SConscript b/source/blender/editors/space_action/SConscript
index 0fee8ff68ab..abaf6154a42 100644
--- a/source/blender/editors/space_action/SConscript
+++ b/source/blender/editors/space_action/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 9bd7d2a44ca..4b1954c8889 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -82,13 +82,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* Update max-extent of channels here (taking into account scrollers):
- * - this is done to allow the channel list to be scrollable, but must be done here
- * to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
- * start of list offset, and the second is as a correction for the scrollers.
- */
- height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT * 2));
+ height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT));
if (height > BLI_rcti_size_y(&v2d->mask)) {
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
@@ -199,13 +193,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* Update max-extent of channels here (taking into account scrollers):
- * - this is done to allow the channel list to be scrollable, but must be done here
- * to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
- * start of list offset, and the second is as a correction for the scrollers.
- */
- height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT * 2));
+ height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT));
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index a80d425b90a..7e99e6c065d 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -53,6 +53,7 @@
#include "BKE_action.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_nla.h"
#include "BKE_context.h"
#include "BKE_report.h"
@@ -104,8 +105,10 @@ static int act_new_exec(bContext *C, wmOperator *UNUSED(op))
action = BKE_action_copy(oldact);
}
else {
+ Main *bmain = CTX_data_main(C);
+
/* just make a new (empty) action */
- action = add_empty_action("Action");
+ action = add_empty_action(bmain, "Action");
}
/* when creating new ID blocks, use is already 1 (fake user),
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index d0f76c21019..964a6a20c37 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -259,12 +259,35 @@ static void borderselect_action(bAnimContext *ac, rcti rect, short mode, short s
!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
{
/* loop over data selecting */
- if (ale->type == ANIMTYPE_GPLAYER)
- ED_gplayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode);
- else if (ale->type == ANIMTYPE_MASKLAYER)
- ED_masklayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode);
- else
- ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
+ switch (ale->type) {
+ case ANIMTYPE_GPDATABLOCK:
+ {
+ bGPdata *gpd = ale->data;
+ bGPDlayer *gpl;
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ ED_gplayer_frames_select_border(gpl, rectf.xmin, rectf.xmax, selectmode);
+ }
+ break;
+ }
+ case ANIMTYPE_GPLAYER:
+ ED_gplayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ break;
+ case ANIMTYPE_MASKDATABLOCK:
+ {
+ Mask *mask = ale->data;
+ MaskLayer *masklay;
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ ED_masklayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ }
+ break;
+ }
+ case ANIMTYPE_MASKLAYER:
+ ED_masklayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ break;
+ default:
+ ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
+ break;
+ }
}
/* set minimum extent to be the maximum of the next channel */
@@ -944,6 +967,7 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s
else if (ale->type == ANIMTYPE_MASKLAYER)
ED_mask_select_frame(ale->data, selx, select_mode);
}
+ BLI_freelistN(&anim_data);
}
else {
ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index c5f3ccee101..e0ca589c1fb 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -219,6 +219,9 @@ static void action_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ /* ensure the 2d view sync works - main region has bottom scroller */
+ ar->v2d.scroll = V2D_SCROLL_BOTTOM;
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
@@ -231,7 +234,6 @@ static void action_channel_area_draw(const bContext *C, ARegion *ar)
/* draw entirely, view changes should be handled here */
bAnimContext ac;
View2D *v2d = &ar->v2d;
- View2DScrollers *scrollers;
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
@@ -247,10 +249,7 @@ static void action_channel_area_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
- /* scrollers */
- scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
- UI_view2d_scrollers_draw(C, v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ /* no scrollers here */
}
diff --git a/source/blender/editors/space_api/SConscript b/source/blender/editors/space_api/SConscript
index 9b818b074ba..a07be054011 100644
--- a/source/blender/editors/space_api/SConscript
+++ b/source/blender/editors/space_api/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript
index 92579b6dedf..5250a1264a4 100644
--- a/source/blender/editors/space_buttons/SConscript
+++ b/source/blender/editors/space_buttons/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 2a5b64cd6ed..0bdae9e32f4 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -36,6 +36,8 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_armature_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
@@ -1028,7 +1030,8 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
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, 0, 0, 0, 0, "Follow context or keep fixed datablock displayed");
+ but = uiDefIconButBitC(block, ICONTOG, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag,
+ 0, 0, 0, 0, IFACE_("Follow context or keep fixed datablock displayed"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
uiButSetFunc(but, pin_cb, NULL, NULL);
@@ -1068,7 +1071,7 @@ void buttons_context_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype buttons panel context");
strcpy(pt->idname, "BUTTONS_PT_context");
- strcpy(pt->label, "Context");
+ strcpy(pt->label, N_("Context")); /* XXX C panels are not available through RNA (bpy.types)! */
pt->draw = buttons_panel_context;
pt->flag = PNL_NO_HEADER;
BLI_addtail(&art->paneltypes, pt);
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index ebba7d92819..ae7026a634f 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -97,14 +97,15 @@ static void do_buttons_buttons(bContext *C, void *UNUSED(arg), int event)
sbuts->mainbuser = sbuts->mainb;
}
-#define BUT_UNIT_X (UI_UNIT_X + 2)
+#define BUT_UNIT_X (UI_UNIT_X + 2 * U.pixelsize)
void buttons_header_buttons(const bContext *C, ARegion *ar)
{
SpaceButs *sbuts = CTX_wm_space_buts(C);
uiBlock *block;
uiBut *but;
- int xco, yco = 2;
+ int headery = ED_area_headersize();
+ int xco, yco = 0.5f * (headery - UI_UNIT_Y);
buttons_context_compute(C, sbuts);
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index d40426a5bc9..8b6682ff1c9 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -40,6 +40,8 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -70,7 +72,7 @@ static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(e
RNA_pointer_create(&sc->id, &RNA_SpaceProperties, sbuts, &ptr);
- pup = uiPupMenuBegin(C, "Align", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Align"), ICON_NONE);
layout = uiPupMenuLayout(pup);
uiItemsEnumR(layout, &ptr, "align");
uiPupMenuEnd(C, pup);
@@ -112,14 +114,22 @@ static int file_browse_exec(bContext *C, wmOperator *op)
/* add slash for directories, important for some properties */
if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
char name[FILE_MAX];
-
+ int is_relative = RNA_boolean_get(op->ptr, "relative_path");
id = fbo->ptr.id.data;
BLI_strncpy(path, str, FILE_MAX);
BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name);
if (BLI_is_dir(path)) {
- str = MEM_reallocN(str, strlen(str) + 2);
+ if (is_relative) {
+ BLI_strncpy(path, str, FILE_MAX);
+ BLI_path_rel(path, G.main->name);
+ str = MEM_reallocN(str, strlen(path) + 2);
+ BLI_strncpy(str, path, FILE_MAX);
+ }
+ else {
+ str = MEM_reallocN(str, strlen(str) + 2);
+ }
BLI_add_slash(str);
}
else
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index abfefba02b9..16d194d0929 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -37,6 +37,8 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_brush_types.h"
#include "DNA_ID.h"
#include "DNA_lamp_types.h"
@@ -358,7 +360,17 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS
}
/* create button */
- BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name);
+ if (user->prop) {
+ PointerRNA texptr = RNA_property_pointer_get(&user->ptr, user->prop);
+ Tex *tex = texptr.data;
+
+ if (tex)
+ BLI_snprintf(name, UI_MAX_NAME_STR, " %s - %s", user->name, tex->id.name + 2);
+ else
+ BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name);
+ }
+ 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,
NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -387,7 +399,7 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C)
user = ct->user;
if (!user) {
- uiItemL(layout, "No textures in context.", ICON_NONE);
+ uiItemL(layout, IFACE_("No textures in context"), ICON_NONE);
return;
}
diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt
index 75e3d8d5685..e09a8b41262 100644
--- a/source/blender/editors/space_clip/CMakeLists.txt
+++ b/source/blender/editors/space_clip/CMakeLists.txt
@@ -57,4 +57,8 @@ set(SRC
clip_intern.h
)
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_space_clip "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript
index c9c82aea68e..c65a076186f 100644
--- a/source/blender/editors/space_clip/SConscript
+++ b/source/blender/editors/space_clip/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
@@ -6,4 +32,7 @@ defs = []
incs = '../include ../../blenkernel ../../blenloader ../../blenfont ../../blenlib ../../imbuf ../../makesdna'
incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include ../../gpu'
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] )
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 969b0e25928..9409ce42d3a 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -43,6 +43,8 @@
#include "BLI_listbase.h"
#include "BLI_rect.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_screen.h"
@@ -78,6 +80,7 @@ void ED_clip_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil");
strcpy(pt->idname, "CLIP_PT_gpencil");
strcpy(pt->label, "Grease Pencil");
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
pt->flag |= PNL_DEFAULT_CLOSED;
pt->poll = clip_grease_pencil_panel_poll;
@@ -123,7 +126,7 @@ void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
row = uiLayoutRow(layout, FALSE);
block = uiLayoutGetBlock(row);
- uiDefBut(block, LABEL, 0, "File Path:", 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
row = uiLayoutRow(layout, FALSE);
split = uiLayoutSplit(row, 0.0f, FALSE);
@@ -166,16 +169,16 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname)
scopesptr = RNA_property_pointer_get(ptr, prop);
scopes = (MovieClipScopes *)scopesptr.data;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 120;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 6.0f * UI_UNIT_Y;
block = uiLayoutAbsoluteBlock(layout);
scopes->track_preview_height =
- (scopes->track_preview_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->track_preview_height;
+ (scopes->track_preview_height <= 20) ? 20 : scopes->track_preview_height;
uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect),
- scopes->track_preview_height, scopes, 0, 0, 0, 0, "");
+ scopes->track_preview_height * UI_DPI_FAC, scopes, 0, 0, 0, 0, "");
}
/********************* Marker Template ************************/
@@ -386,11 +389,11 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
block = uiLayoutGetBlock(layout);
if (cb->marker_flag & MARKER_DISABLED)
- tip = "Marker is disabled at current frame";
+ tip = TIP_("Marker is disabled at current frame");
else
- tip = "Marker is enabled at current frame";
+ tip = TIP_("Marker is enabled at current frame");
- bt = uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20,
+ bt = uiDefIconButBitI(block, TOGN, 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);
}
@@ -404,7 +407,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, "Track is locked", 0, 0, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, IFACE_("Track is locked"), 0, 0, UI_UNIT_X * 15.0f, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
return;
}
@@ -433,12 +436,12 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
uiBlockSetNFunc(block, marker_update_cb, cb, NULL);
if (cb->marker_flag & MARKER_DISABLED)
- tip = "Marker is disabled at current frame";
+ tip = TIP_("Marker is disabled at current frame");
else
- tip = "Marker is enabled at current frame";
+ tip = TIP_("Marker is enabled at current frame");
- uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, "Enabled", 10, 190, 145, 19, &cb->marker_flag,
- 0, 0, 0, 0, tip);
+ uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, IFACE_("Enabled"), 10, 190, 145, 19,
+ &cb->marker_flag, 0, 0, 0, 0, tip);
col = uiLayoutColumn(layout, TRUE);
uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0);
@@ -446,33 +449,34 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
block = uiLayoutAbsoluteBlock(col);
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0],
- -10 * width, 10.0 * width, step, digits, "X-position of marker at frame in screen coordinates");
- uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1],
- -10 * height, 10.0 * height, step, digits, "Y-position of marker at frame in screen coordinates");
-
- uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0],
- -10 * width, 10.0 * width, step, digits, "X-offset to parenting point");
- uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1],
- -10 * height, 10.0 * height, step, digits, "Y-offset to parenting point");
-
- uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f,
- 10.0 * width, step, digits, "Width of marker's pattern in screen coordinates");
- uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f,
- 10.0 * height, step, digits, "Height of marker's pattern in screen coordinates");
-
- uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0],
- -width, width, step, digits, "X-position of search at frame relative to marker's position");
- uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1],
- -height, height, step, digits, "X-position of search at frame relative to marker's position");
- uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f,
- 10.0 * width, step, digits, "Width of marker's search in screen soordinates");
- uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f,
- 10.0 * height, step, digits, "Height of marker's search in screen soordinates");
+ uiDefBut(block, LABEL, 0, IFACE_("Position:"), 0, 190, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_POS, IFACE_("X:"), 10, 171, 145, 19, &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:"), 165, 171, 145, 19, &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, 152, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_OFFSET, IFACE_("X:"), 10, 133, 145, 19, &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:"), 165, 133, 145, 19, &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, 114, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_PAT_DIM, IFACE_("Width:"), 10, 95, 300, 19, &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:"), 10, 76, 300, 19, &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, 57, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_SEARCH_POS, IFACE_("X:"), 10, 38, 145, 19, &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:"), 165, 38, 145, 19, &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:"), 10, 19, 300, 19, &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:"), 10, 0, 300, 19, &cb->marker_search[1], 3.0f,
+ 10.0 * height, step, digits, TIP_("Height of marker's search in screen coordinates"));
uiBlockEndAlign(block);
}
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index cc1b8d444bc..b1be9217819 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -145,6 +145,31 @@ static void draw_keyframe_shape(float x, float y, float xscale, float yscale, sh
glPopMatrix();
}
+static void clip_draw_dopesheet_background(ARegion *ar, MovieClip *clip)
+{
+ View2D *v2d = &ar->v2d;
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingDopesheetCoverageSegment *coverage_segment;
+
+ for (coverage_segment = dopesheet->coverage_segments.first;
+ coverage_segment;
+ coverage_segment = coverage_segment->next)
+ {
+ if (coverage_segment->coverage < TRACKING_COVERAGE_OK) {
+ int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, coverage_segment->start_frame);
+ int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, coverage_segment->end_frame);
+
+ if (coverage_segment->coverage == TRACKING_COVERAGE_BAD)
+ glColor4f(1.0f, 0.0f, 0.0f, 0.07f);
+ else
+ glColor4f(1.0f, 1.0f, 0.0f, 0.07f);
+
+ glRectf(start_frame, v2d->cur.ymin, end_frame, v2d->cur.ymax);
+ }
+ }
+}
+
void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -159,7 +184,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
MovieTrackingDopesheetChannel *channel;
float y, xscale, yscale;
float strip[4], selected_strip[4];
- float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2);
+ float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
@@ -179,6 +204,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
glEnable(GL_BLEND);
+ clip_draw_dopesheet_background(ar, clip);
+
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float) (y - CHANNEL_HEIGHT_HALF);
float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF);
@@ -272,7 +299,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
tracking = &clip->tracking;
dopesheet = &tracking->dopesheet;
- height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2);
+ height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);
if (height > BLI_rcti_size_y(&v2d->mask)) {
/* don't use totrect set, as the width stays the same
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 9cf389c4508..56f2998b047 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -103,11 +103,11 @@ static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int wid
if (width == 1) {
glBegin(GL_LINES);
glVertex2i(x, 0);
- glVertex2i(x, height);
+ glVertex2i(x, height * UI_DPI_FAC);
glEnd();
}
else {
- glRecti(x, 0, x + width, height);
+ glRecti(x, 0, x + width, height * UI_DPI_FAC);
}
}
@@ -125,7 +125,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
/* cache background */
glColor4ub(128, 128, 255, 64);
- glRecti(0, 0, ar->winx, 8);
+ glRecti(0, 0, ar->winx, 8 * UI_DPI_FAC);
/* cached segments -- could be usefu lto debug caching strategies */
BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
@@ -138,7 +138,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
x1 = (points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
x2 = (points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
- glRecti(x1, 0, x2, 8);
+ glRecti(x1, 0, x2, 8 * UI_DPI_FAC);
}
}
@@ -175,7 +175,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
else
glColor4ub(255, 255, 0, 96);
- glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4);
+ glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC);
}
}
}
@@ -203,7 +203,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
}
if (!ok)
- glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8);
+ glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC);
}
}
@@ -213,9 +213,9 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;
UI_ThemeColor(TH_CFRAME);
- glRecti(x, 0, x + ceilf(framelen), 8);
+ glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
- clip_draw_curfra_label(sc->user.framenr, x, 8.0f);
+ clip_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
/* solver keyframes */
glColor4ub(175, 255, 0, 255);
@@ -796,11 +796,11 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
dy = 6.0f / height / sc->zoom;
side = get_shortest_pattern_side(marker);
- patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f);
- patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f);
+ patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC;
+ patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC;
- searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f);
- searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f);
+ searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC;
+ searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC;
px[0] = 1.0f / sc->zoom / width / sc->scale;
px[1] = 1.0f / sc->zoom / height / sc->scale;
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 1a62af39600..728110dfeee 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -33,12 +33,6 @@
#include "MEM_guardedalloc.h"
-#include "BKE_main.h"
-#include "BKE_mask.h"
-#include "BKE_movieclip.h"
-#include "BKE_context.h"
-#include "BKE_tracking.h"
-
#include "DNA_mask_types.h"
#include "DNA_object_types.h" /* SELECT */
@@ -47,6 +41,13 @@
#include "BLI_string.h"
#include "BLI_rect.h"
+#include "BKE_main.h"
+#include "BKE_mask.h"
+#include "BKE_movieclip.h"
+#include "BKE_context.h"
+#include "BKE_tracking.h"
+#include "BKE_library.h"
+
#include "GPU_extensions.h"
#include "IMB_imbuf_types.h"
@@ -81,7 +82,7 @@ int ED_space_clip_view_clip_poll(bContext *C)
{
SpaceClip *sc = CTX_wm_space_clip(C);
- if (sc && sc->clip) {
+ if (sc) {
return sc->view == SC_VIEW_CLIP;
}
@@ -524,8 +525,7 @@ void ED_space_clip_set_clip(bContext *C, bScreen *screen, SpaceClip *sc, MovieCl
old_clip = sc->clip;
sc->clip = clip;
- if (sc->clip && sc->clip->id.us == 0)
- sc->clip->id.us = 1;
+ id_us_ensure_real((ID *)sc->clip);
if (screen && sc->view == SC_VIEW_CLIP) {
ScrArea *area;
@@ -561,9 +561,7 @@ void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask)
{
sc->mask_info.mask = mask;
- if (sc->mask_info.mask && sc->mask_info.mask->id.us == 0) {
- sc->mask_info.mask->id.us = 1;
- }
+ id_us_ensure_real((ID *)sc->mask_info.mask);
if (C) {
WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask);
@@ -620,7 +618,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsign
context->last_texture = glaGetOneInteger(GL_TEXTURE_2D);
/* image texture need to be rebinded if displaying another image buffer
- * assuming displaying happens of footage frames only on which painting doesn't heppen.
+ * assuming displaying happens of footage frames only on which painting doesn't happen.
* so not changed image buffer pointer means unchanged image content */
need_rebind |= context->texture_ibuf != ibuf;
need_rebind |= context->display_buffer != display_buffer;
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index d33f77c1064..432032e9dbf 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -43,10 +43,10 @@ struct SpaceClip;
struct wmOperatorType;
/* channel heights */
-#define CHANNEL_FIRST -UI_UNIT_Y
-#define CHANNEL_HEIGHT UI_UNIT_Y
-#define CHANNEL_HEIGHT_HALF (UI_UNIT_Y / 2.0f)
-#define CHANNEL_SKIP 2
+#define CHANNEL_FIRST (-0.8f * U.widget_unit)
+#define CHANNEL_HEIGHT (0.8f * U.widget_unit)
+#define CHANNEL_HEIGHT_HALF (0.4f * U.widget_unit)
+#define CHANNEL_SKIP (0.1f * U.widget_unit)
#define CHANNEL_STEP (CHANNEL_HEIGHT + CHANNEL_SKIP)
#define CHANNEL_PAD 4
@@ -54,7 +54,7 @@ struct wmOperatorType;
/* extra padding for lengths (to go under scrollers) */
#define EXTRA_SCROLL_PAD 100.0f
-#define STRIP_HEIGHT_HALF 5
+#define STRIP_HEIGHT_HALF (0.25f * UI_UNIT_Y)
/* internal exports only */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 4e53f34359e..dfb69be6f18 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -160,6 +160,7 @@ static int open_exec(bContext *C, wmOperator *op)
{
SpaceClip *sc = CTX_wm_space_clip(C);
bScreen *screen = CTX_wm_screen(C);
+ Main *bmain = CTX_data_main(C);
PropertyPointerRNA *pprop;
PointerRNA idptr;
MovieClip *clip = NULL;
@@ -191,7 +192,7 @@ static int open_exec(bContext *C, wmOperator *op)
errno = 0;
- clip = BKE_movieclip_file_add(str);
+ clip = BKE_movieclip_file_add(bmain, str);
if (!clip) {
if (op->customdata)
@@ -382,8 +383,8 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
SpaceClip *sc = CTX_wm_space_clip(C);
float offset[2];
- offset[0] = (event->x - event->prevx) / sc->zoom;
- offset[1] = (event->y - event->prevy) / sc->zoom;
+ offset[0] = (event->prevx - event->x) / sc->zoom;
+ offset[1] = (event->prevy - event->y) / sc->zoom;
RNA_float_set_array(op->ptr, "offset", offset);
@@ -515,10 +516,10 @@ static int view_zoom_exec(bContext *C, wmOperator *op)
static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if (event->type == MOUSEZOOM) {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float delta, factor;
- delta = event->x - event->prevx + event->y - event->prevy;
+ delta = event->prevx - event->x + event->prevy - event->y;
if (U.uiflag & USER_ZOOM_INVERT)
delta *= -1;
@@ -908,7 +909,7 @@ static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
void CLIP_OT_change_frame(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Change frame";
+ ot->name = "Change Frame";
ot->idname = "CLIP_OT_change_frame";
ot->description = "Interactively change the current frame number";
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
index 1bdf5214192..7543988b5aa 100644
--- a/source/blender/editors/space_clip/clip_toolbar.c
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -33,11 +33,15 @@
#include "DNA_windowmanager_types.h"
+#include "RNA_access.h"
+
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -197,16 +201,16 @@ static void clip_panel_operator_redo_header(const bContext *C, Panel *pa)
wmOperator *op = WM_operator_last_redo(C);
if (op)
- BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname));
+ BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
else
- BLI_strncpy(pa->drawname, "Operator", sizeof(pa->drawname));
+ BLI_strncpy(pa->drawname, IFACE_("Operator"), sizeof(pa->drawname));
}
static void clip_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOperator *op)
{
if (op->type->flag & OPTYPE_MACRO) {
for (op = op->macro.first; op; op = op->next) {
- uiItemL(pa->layout, op->type->name, ICON_NONE);
+ uiItemL(pa->layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
clip_panel_operator_redo_operator(C, pa, op);
}
}
@@ -219,23 +223,32 @@ static void clip_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOp
static void clip_panel_operator_redo(const bContext *C, Panel *pa)
{
wmOperator *op = WM_operator_last_redo(C);
- uiBlock *block;
+ ARegion *ar;
+ ARegion *ar1;
if (op == NULL)
return;
- if (WM_operator_poll((bContext *)C, op->type) == 0)
- return;
+ /* keep in sync with logic in ED_undo_operator_repeat() */
+ ar = CTX_wm_region(C);
+ ar1 = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW);
+ if (ar1)
+ CTX_wm_region_set((bContext *)C, ar1);
- block = uiLayoutGetBlock(pa->layout);
+ if (WM_operator_poll((bContext *)C, op->type)) {
+ uiBlock *block = uiLayoutGetBlock(pa->layout);
- if (!WM_operator_check_ui_enabled(C, op->type->name))
- uiLayoutSetEnabled(pa->layout, FALSE);
+ if (!WM_operator_check_ui_enabled(C, op->type->name))
+ 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);
+ /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
+ uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
+
+ clip_panel_operator_redo_operator(C, pa, op);
+ }
- clip_panel_operator_redo_operator(C, pa, op);
+ /* set region back */
+ CTX_wm_region_set((bContext *)C, ar);
}
void ED_clip_tool_props_register(ARegionType *art)
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 77e2a1bb3d3..f0c0e7b72fd 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -246,7 +246,7 @@ static SpaceLink *clip_new(const bContext *C)
sc = MEM_callocN(sizeof(SpaceClip), "initclip");
sc->spacetype = SPACE_CLIP;
sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | SC_MANUAL_CALIBRATION |
- SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES;
+ SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL;
sc->zoom = 1.0f;
sc->path_length = 20;
sc->scopes.track_preview_height = 120;
@@ -587,14 +587,20 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
+ /* ctrl now works as well, shift + numpad works as arrow keys on Windows */
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 4.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 2.0f);
RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
+
RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
@@ -1146,14 +1152,18 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
}
- /* Grease Pencil */
- clip_draw_grease_pencil((bContext *)C, 1);
+ if (sc->flag & SC_SHOW_GPENCIL) {
+ /* Grease Pencil */
+ clip_draw_grease_pencil((bContext *)C, TRUE);
+ }
/* reset view matrix */
UI_view2d_view_restore(C);
- /* draw Grease Pencil - screen space only */
- clip_draw_grease_pencil((bContext *)C, 0);
+ if (sc->flag & SC_SHOW_GPENCIL) {
+ /* draw Grease Pencil - screen space only */
+ clip_draw_grease_pencil((bContext *)C, FALSE);
+ }
}
static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn)
@@ -1272,6 +1282,9 @@ static void clip_channels_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ /* ensure the 2d view sync works - main region has bottom scroller */
+ ar->v2d.scroll = V2D_SCROLL_BOTTOM;
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
keymap = WM_keymap_find(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
@@ -1283,7 +1296,6 @@ static void clip_channels_area_draw(const bContext *C, ARegion *ar)
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
View2D *v2d = &ar->v2d;
- View2DScrollers *scrollers;
if (clip)
BKE_tracking_dopesheet_update(&clip->tracking);
@@ -1299,11 +1311,6 @@ static void clip_channels_area_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
-
- /* scrollers */
- scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
- UI_view2d_scrollers_draw(C, v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
}
static void clip_channels_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index a29524de36d..77ed197c1d7 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1105,7 +1105,7 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo
{
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
int framenr = tmj->sfra;
- //double t = PIL_check_seconds_timer();
+ // double t = PIL_check_seconds_timer();
while (framenr != tmj->efra) {
if (tmj->delay > 0) {
@@ -1141,7 +1141,7 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo
break;
}
- //printf("Tracking time: %lf\n", PIL_check_seconds_timer()-t);
+ // printf("Tracking time: %lf\n", PIL_check_seconds_timer()-t);
}
static void track_markers_updatejob(void *tmv)
@@ -1801,7 +1801,7 @@ static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat
int found = FALSE;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (!cti)
continue;
@@ -1832,7 +1832,7 @@ static Object *object_solver_camera(Scene *scene, Object *ob)
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (!cti)
continue;
@@ -2025,7 +2025,7 @@ static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingOb
if (!flip) {
float lmat[4][4], ilmat[4][4], rmat[3][3];
- BKE_object_rot_to_mat3(ob, rmat);
+ BKE_object_rot_to_mat3(ob, rmat, TRUE);
invert_m3(rmat);
mul_m4_m4m3(mat, mat, rmat);
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index b8e162bfb17..bec50130230 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -123,10 +123,10 @@ static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack *
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
- epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0],
- fabsf(pat_min[0]), fabsf(pat_max[0])) / 2;
- epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1],
- fabsf(pat_min[1]), fabsf(pat_max[1])) / 2;
+ epsx = min_ffff(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0],
+ fabsf(pat_min[0]), fabsf(pat_max[0])) / 2;
+ epsy = min_ffff(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1],
+ fabsf(pat_min[1]), fabsf(pat_max[1])) / 2;
epsx = max_ff(epsx, 2.0f / width);
epsy = max_ff(epsy, 2.0f / height);
@@ -166,7 +166,7 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
d3 = dist_squared_to_line_segment_v2(p, v3, v4);
d4 = dist_squared_to_line_segment_v2(p, v4, v1);
- return sqrtf(MIN4(d1, d2, d3, d4));
+ return sqrtf(min_ffff(d1, d2, d3, d4));
}
static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
@@ -181,7 +181,7 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
d3 = dist_squared_to_line_segment_v2(p, v3, v4);
d4 = dist_squared_to_line_segment_v2(p, v4, v1);
- return sqrtf(MIN4(d1, d2, d3, d4));
+ return sqrtf(min_ffff(d1, d2, d3, d4));
}
static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2])
@@ -210,7 +210,7 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas
d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max);
/* choose minimal distance. useful for cases of overlapped markers. */
- dist = MIN3(d1, d2, d3);
+ dist = min_fff(d1, d2, d3);
if (track == NULL || dist < mindist) {
track = cur;
diff --git a/source/blender/editors/space_console/SConscript b/source/blender/editors/space_console/SConscript
index f246f08d7ac..3e2c9d6dfdf 100644
--- a/source/blender/editors/space_console/SConscript
+++ b/source/blender/editors/space_console/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index a215b476094..73747239255 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -50,7 +50,9 @@
#include "ED_datafiles.h"
#include "ED_types.h"
+#include "UI_interface.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "console_intern.h"
@@ -79,9 +81,9 @@ typedef struct ConsoleDrawContext {
int cwidth;
int lheight;
int console_width;
- int winx;
int ymin, ymax;
#if 0 /* used by textview, may use later */
+ int winx;
int *xy; // [2]
int *sel; // [2]
int *pos_pick; /* bottom of view == 0, top of file == combine chars, end of line is lower then start. */
@@ -111,15 +113,12 @@ void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dumm
}
#define CONSOLE_DRAW_MARGIN 4
-#define CONSOLE_DRAW_SCROLL 16
-
-
/* console textview callbacks */
static int console_textview_begin(TextViewContext *tvc)
{
SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
- tvc->lheight = sc->lheight;
+ tvc->lheight = sc->lheight * UI_DPI_FAC;
tvc->sel_start = sc->sel_start;
tvc->sel_end = sc->sel_end;
@@ -159,9 +158,9 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
if (tvc->iter_index == 0) {
const SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
const ConsoleLine *cl = (ConsoleLine *)sc->history.last;
- const int prompt_len = strlen(sc->prompt);
- const int cursor_loc = cl->cursor + prompt_len;
- const int line_len = cl->len + prompt_len;
+ const int prompt_len = BLI_strlen_utf8(sc->prompt);
+ const int cursor_loc = BLI_strnlen_utf8(cl->line, cl->cursor) + prompt_len;
+ const int line_len = BLI_strlen_utf8(cl->line) + prompt_len;
int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN};
int pen[2];
xy[1] += tvc->lheight / 6;
@@ -194,8 +193,13 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
return TVC_LINE_FG;
}
+static void console_textview_const_colors(TextViewContext *UNUSED(tvc), unsigned char bg_sel[4])
+{
+ UI_GetThemeColor4ubv(TH_CONSOLE_SELECT, bg_sel);
+}
-static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw, int mval[2], void **mouse_pick, int *pos_pick)
+static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw,
+ int mval[2], void **mouse_pick, int *pos_pick)
{
ConsoleLine cl_dummy = {NULL};
int ret = 0;
@@ -210,6 +214,7 @@ static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar,
tvc.step = console_textview_step;
tvc.line_get = console_textview_line_get;
tvc.line_color = console_textview_line_color;
+ tvc.const_colors = console_textview_const_colors;
tvc.arg1 = sc;
tvc.arg2 = NULL;
@@ -217,10 +222,10 @@ static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar,
/* view */
tvc.sel_start = sc->sel_start;
tvc.sel_end = sc->sel_end;
- tvc.lheight = sc->lheight;
+ tvc.lheight = sc->lheight * UI_DPI_FAC;
tvc.ymin = v2d->cur.ymin;
tvc.ymax = v2d->cur.ymax;
- tvc.winx = ar->winx;
+ tvc.winx = ar->winx - V2D_SCROLL_WIDTH;
console_scrollback_prompt_begin(sc, &cl_dummy);
ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
@@ -242,13 +247,13 @@ int console_textview_height(struct SpaceConsole *sc, ARegion *ar)
return console_textview_main__internal(sc, ar, 0, mval, NULL, NULL);
}
-int console_char_pick(struct SpaceConsole *sc, ARegion *ar, int mval[2])
+int console_char_pick(struct SpaceConsole *sc, ARegion *ar, const int mval[2])
{
int pos_pick = 0;
void *mouse_pick = NULL;
int mval_clamp[2];
- mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN));
+ mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - CONSOLE_DRAW_MARGIN);
mval_clamp[1] = CLAMPIS(mval[1], CONSOLE_DRAW_MARGIN, ar->winy - CONSOLE_DRAW_MARGIN);
console_textview_main__internal(sc, ar, 0, mval_clamp, &mouse_pick, &pos_pick);
diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h
index 3d30dcad710..1e79e4b9714 100644
--- a/source/blender/editors/space_console/console_intern.h
+++ b/source/blender/editors/space_console/console_intern.h
@@ -37,7 +37,7 @@ struct bContext;
/* console_draw.c */
void console_textview_main(struct SpaceConsole *sc, struct ARegion *ar);
int console_textview_height(struct SpaceConsole *sc, struct ARegion *ar); /* needed to calculate the scrollbar */
-int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, int mval[2]);
+int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, const int mval[2]);
void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy);
void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy);
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 36716aeab95..1242d123a41 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -34,11 +34,12 @@
#include "DNA_userdef_types.h"
+#include "BLI_utildefines.h"
#include "BLI_listbase.h"
#include "BLI_string_cursor_utf8.h"
+#include "BLI_string_utf8.h"
#include "BLI_string.h"
#include "BLI_dynstr.h"
-#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BKE_context.h"
@@ -283,28 +284,28 @@ static int console_move_exec(bContext *C, wmOperator *op)
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_PREV,
- STRCUR_JUMP_ALL);
+ STRCUR_JUMP_ALL, true);
done = console_line_cursor_set(ci, pos);
break;
case LINE_END:
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_NEXT,
- STRCUR_JUMP_ALL);
+ STRCUR_JUMP_ALL, true);
done = console_line_cursor_set(ci, pos);
break;
case PREV_CHAR:
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_PREV,
- STRCUR_JUMP_NONE);
+ STRCUR_JUMP_NONE, true);
done = console_line_cursor_set(ci, pos);
break;
case NEXT_CHAR:
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_NEXT,
- STRCUR_JUMP_NONE);
+ STRCUR_JUMP_NONE, true);
done = console_line_cursor_set(ci, pos);
break;
@@ -314,14 +315,14 @@ static int console_move_exec(bContext *C, wmOperator *op)
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_PREV,
- STRCUR_JUMP_DELIM);
+ STRCUR_JUMP_DELIM, true);
done = console_line_cursor_set(ci, pos);
break;
case NEXT_WORD:
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_NEXT,
- STRCUR_JUMP_DELIM);
+ STRCUR_JUMP_DELIM, true);
done = console_line_cursor_set(ci, pos);
break;
}
@@ -393,15 +394,26 @@ static int console_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
// if (!RNA_struct_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */
if (!RNA_string_length(op->ptr, "text")) {
- /* if alt/ctrl/super are pressed pass through */
- if (event->ctrl || event->oskey) {
+ /* if alt/ctrl/super are pressed pass through except for utf8 character event
+ * (when input method are used for utf8 inputs, the user may assign key event
+ * including alt/ctrl/super like ctrl+m to commit utf8 string. in such case,
+ * the modifiers in the utf8 character event make no sense.) */
+ if ((event->ctrl || event->oskey) && !event->utf8_buf[0]) {
return OPERATOR_PASS_THROUGH;
}
else {
- char str[2];
- str[0] = event->ascii;
- str[1] = '\0';
-
+ char str[BLI_UTF8_MAX + 1];
+ size_t len;
+
+ if (event->utf8_buf[0]) {
+ len = BLI_str_utf8_size_safe(event->utf8_buf);
+ memcpy(str, event->utf8_buf, len);
+ }
+ else {
+ /* in theory, ghost can set value to extended ascii here */
+ len = BLI_str_utf8_from_unicode(event->ascii, str);
+ }
+ str[len] = '\0';
RNA_string_set(op->ptr, "text", str);
}
}
@@ -550,7 +562,7 @@ static int console_delete_exec(bContext *C, wmOperator *op)
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_NEXT,
- (type == DEL_NEXT_CHAR) ? STRCUR_JUMP_NONE : STRCUR_JUMP_DELIM);
+ (type == DEL_NEXT_CHAR) ? STRCUR_JUMP_NONE : STRCUR_JUMP_DELIM, true);
stride = pos - ci->cursor;
if (stride) {
memmove(ci->line + ci->cursor, ci->line + ci->cursor + stride, (ci->len - ci->cursor) + 1);
@@ -566,7 +578,7 @@ static int console_delete_exec(bContext *C, wmOperator *op)
pos = ci->cursor;
BLI_str_cursor_step_utf8(ci->line, ci->len,
&pos, STRCUR_DIR_PREV,
- (type == DEL_PREV_CHAR) ? STRCUR_JUMP_NONE : STRCUR_JUMP_DELIM);
+ (type == DEL_PREV_CHAR) ? STRCUR_JUMP_NONE : STRCUR_JUMP_DELIM, true);
stride = ci->cursor - pos;
if (stride) {
ci->cursor -= stride; /* same as above */
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index be8febdab23..eed269ff70f 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -174,7 +174,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
ID *id = drag->poin;
/* copy drag path to properties */
- text = RNA_path_from_ID_python(id);
+ text = RNA_path_full_ID_py(id);
RNA_string_set(drop->ptr, "text", text);
MEM_freeN(text);
}
diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript
index b387d489805..c3f8c6667f7 100644
--- a/source/blender/editors/space_file/SConscript
+++ b/source/blender/editors/space_file/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index fb438ae45fb..afe32ec0b85 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -321,8 +321,7 @@ void file_calc_previews(const bContext *C, ARegion *ar)
View2D *v2d = &ar->v2d;
ED_fileselect_init_layout(sfile, ar);
- /* +SCROLL_HEIGHT is bad hack to work around issue in UI_view2d_totRect_set */
- UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height + V2D_SCROLL_HEIGHT);
+ UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
}
static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, short dropshadow)
@@ -336,7 +335,9 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int
float scale;
int ex, ey;
- if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) {
+ 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;
@@ -349,10 +350,11 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int
}
}
else {
- scaledx = (float)imb->x;
- scaledy = (float)imb->y;
- scale = 1.0;
+ 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;
@@ -462,7 +464,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
int i;
short is_icon;
short align;
-
+ int column_space = 0.6f * UI_UNIT_X;
numfiles = filelist_numfiles(files);
@@ -493,7 +495,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
for (i = offset; (i < numfiles) && (i < offset + numfiles_layout); i++) {
ED_fileselect_layout_tilepos(layout, i, &sx, &sy);
- sx += (int)(v2d->tot.xmin + 2.0f);
+ sx += (int)(v2d->tot.xmin + 0.1f * UI_UNIT_X);
sy = (int)(v2d->tot.ymax - sy);
file = filelist_file(files, i);
@@ -522,13 +524,13 @@ void file_draw_list(const bContext *C, ARegion *ar)
}
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);
- sx += ICON_DEFAULT_WIDTH_SCALE + 4;
+ sx += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
}
UI_ThemeColor4(TH_TEXT);
if (file->selflag & EDITING_FILE) {
- uiBut *but = uiDefBut(block, TEX, 1, "", sx, sy - layout->tile_h - 3,
+ 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 */
@@ -544,39 +546,39 @@ void file_draw_list(const bContext *C, ARegion *ar)
}
if (params->display == FILE_SHORTDISPLAY) {
- sx += (int)layout->column_widths[COLUMN_NAME] + 12;
+ sx += (int)layout->column_widths[COLUMN_NAME] + column_space;
if (!(file->type & S_IFDIR)) {
file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align);
- sx += (int)layout->column_widths[COLUMN_SIZE] + 12;
+ sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
}
}
else if (params->display == FILE_LONGDISPLAY) {
- sx += (int)layout->column_widths[COLUMN_NAME] + 12;
+ sx += (int)layout->column_widths[COLUMN_NAME] + column_space;
#ifndef WIN32
/* rwx rwx rwx */
file_draw_string(sx, sy, file->mode1, layout->column_widths[COLUMN_MODE1], layout->tile_h, align);
- sx += layout->column_widths[COLUMN_MODE1] + 12;
+ sx += layout->column_widths[COLUMN_MODE1] + column_space;
file_draw_string(sx, sy, file->mode2, layout->column_widths[COLUMN_MODE2], layout->tile_h, align);
- sx += layout->column_widths[COLUMN_MODE2] + 12;
+ sx += layout->column_widths[COLUMN_MODE2] + column_space;
file_draw_string(sx, sy, file->mode3, layout->column_widths[COLUMN_MODE3], layout->tile_h, align);
- sx += layout->column_widths[COLUMN_MODE3] + 12;
+ sx += layout->column_widths[COLUMN_MODE3] + column_space;
file_draw_string(sx, sy, file->owner, layout->column_widths[COLUMN_OWNER], layout->tile_h, align);
- sx += layout->column_widths[COLUMN_OWNER] + 12;
+ sx += layout->column_widths[COLUMN_OWNER] + column_space;
#endif
file_draw_string(sx, sy, file->date, layout->column_widths[COLUMN_DATE], layout->tile_h, align);
- sx += (int)layout->column_widths[COLUMN_DATE] + 12;
+ sx += (int)layout->column_widths[COLUMN_DATE] + column_space;
file_draw_string(sx, sy, file->time, layout->column_widths[COLUMN_TIME], layout->tile_h, align);
- sx += (int)layout->column_widths[COLUMN_TIME] + 12;
+ sx += (int)layout->column_widths[COLUMN_TIME] + column_space;
if (!(file->type & S_IFDIR)) {
file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align);
- sx += (int)layout->column_widths[COLUMN_SIZE] + 12;
+ sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
}
}
}
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 763b18788de..9349abb4d8b 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -28,6 +28,8 @@
* \ingroup spfile
*/
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -35,9 +37,6 @@
#include "BKE_report.h"
#include "BKE_main.h"
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 778a3f4df3e..3c6f6358171 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -95,7 +95,7 @@ FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile)
}
/**
- * \note RNA_struct_property_is_set_ex is used here because we wan't
+ * \note RNA_struct_property_is_set_ex is used here because we want
* the previously used settings to be used here rather then overriding them */
short ED_fileselect_set_params(SpaceFile *sfile)
{
@@ -244,9 +244,11 @@ short ED_fileselect_set_params(SpaceFile *sfile)
params->display = FILE_SHORTDISPLAY;
params->filter = 0;
params->filter_glob[0] = '\0';
- params->sort = FILE_SORT_ALPHA;
}
+ /* operator has no setting for this */
+ params->sort = FILE_SORT_ALPHA;
+
/* initialize the list with previous folders */
if (!sfile->folders_prev)
@@ -498,12 +500,12 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
layout->textheight = textheight;
if (params->display == FILE_IMGDISPLAY) {
- layout->prv_w = 96;
- layout->prv_h = 96;
- layout->tile_border_x = 6;
- layout->tile_border_y = 6;
- layout->prv_border_x = 6;
- layout->prv_border_y = 6;
+ layout->prv_w = 4.8f * UI_UNIT_X;
+ layout->prv_h = 4.8f * UI_UNIT_Y;
+ layout->tile_border_x = 0.3f * UI_UNIT_X;
+ layout->tile_border_y = 0.3f * UI_UNIT_X;
+ layout->prv_border_x = 0.3f * UI_UNIT_X;
+ layout->prv_border_y = 0.3f * UI_UNIT_Y;
layout->tile_w = layout->prv_w + 2 * layout->prv_border_x;
layout->tile_h = layout->prv_h + 2 * layout->prv_border_y + textheight;
layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x);
@@ -518,10 +520,13 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
layout->flag = FILE_LAYOUT_VER;
}
else {
+ int column_space = 0.6f * UI_UNIT_X;
+ int column_icon_space = 0.2f * UI_UNIT_X;
+
layout->prv_w = 0;
layout->prv_h = 0;
- layout->tile_border_x = 8;
- layout->tile_border_y = 2;
+ layout->tile_border_x = 0.4f * UI_UNIT_X;
+ layout->tile_border_y = 0.1f * UI_UNIT_Y;
layout->prv_border_x = 0;
layout->prv_border_y = 0;
layout->tile_h = textheight * 3 / 2;
@@ -531,22 +536,22 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
column_widths(sfile->files, layout);
if (params->display == FILE_SHORTDISPLAY) {
- maxlen = ICON_DEFAULT_WIDTH_SCALE + 4 +
- (int)layout->column_widths[COLUMN_NAME] + 12 +
- (int)layout->column_widths[COLUMN_SIZE] + 12;
+ maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space +
+ (int)layout->column_widths[COLUMN_NAME] + column_space +
+ (int)layout->column_widths[COLUMN_SIZE] + column_space;
}
else {
- maxlen = ICON_DEFAULT_WIDTH_SCALE + 4 +
- (int)layout->column_widths[COLUMN_NAME] + 12 +
+ maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space +
+ (int)layout->column_widths[COLUMN_NAME] + column_space +
#ifndef WIN32
- (int)layout->column_widths[COLUMN_MODE1] + 12 +
- (int)layout->column_widths[COLUMN_MODE2] + 12 +
- (int)layout->column_widths[COLUMN_MODE3] + 12 +
- (int)layout->column_widths[COLUMN_OWNER] + 12 +
+ (int)layout->column_widths[COLUMN_MODE1] + column_space +
+ (int)layout->column_widths[COLUMN_MODE2] + column_space +
+ (int)layout->column_widths[COLUMN_MODE3] + column_space +
+ (int)layout->column_widths[COLUMN_OWNER] + column_space +
#endif
- (int)layout->column_widths[COLUMN_DATE] + 12 +
- (int)layout->column_widths[COLUMN_TIME] + 12 +
- (int)layout->column_widths[COLUMN_SIZE] + 12;
+ (int)layout->column_widths[COLUMN_DATE] + column_space +
+ (int)layout->column_widths[COLUMN_TIME] + column_space +
+ (int)layout->column_widths[COLUMN_SIZE] + column_space;
}
layout->tile_w = maxlen;
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index a5647c06b92..5f1f9a3ab22 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -350,7 +350,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
#else
#ifdef __APPLE__
{
-#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
+#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040)
OSErr err = noErr;
int i;
const char *home;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index be037a0d5ba..0a4b922bb38 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -478,6 +478,7 @@ static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
ED_region_panels_init(wm, ar);
/* own keymaps */
@@ -533,7 +534,7 @@ static void file_ui_area_draw(const bContext *C, ARegion *ar)
{
float col[3];
/* clear */
- UI_GetThemeColor3fv(TH_PANEL, col);
+ UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
diff --git a/source/blender/editors/space_graph/SConscript b/source/blender/editors/space_graph/SConscript
index 83239a5480a..84ac27a8962 100644
--- a/source/blender/editors/space_graph/SConscript
+++ b/source/blender/editors/space_graph/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 483348db18e..ab16a9d55e6 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -383,10 +383,7 @@ static void do_graph_region_driver_buttons(bContext *C, void *UNUSED(arg), int e
case B_IPO_DEPCHANGE:
{
/* rebuild depsgraph for the new deps */
- DAG_scene_sort(bmain, scene);
-
- /* force an update of depsgraph */
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
}
break;
}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index f665b979559..256c90a1f1a 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -516,7 +516,7 @@ 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;
+ samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize);
if (samplefreq < 0.00001f) samplefreq = 0.00001f;
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 21b0ed99f0b..b92430ce0e9 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -217,7 +217,6 @@ void GRAPH_OT_previewrange_set(wmOperatorType *ot)
static int graphkeys_viewall(bContext *C, const short do_sel_only, const short include_handles)
{
bAnimContext ac;
- float extra;
rctf cur_new;
/* get editor data */
@@ -230,13 +229,7 @@ static int graphkeys_viewall(bContext *C, const short do_sel_only, const short i
&cur_new.ymin, &cur_new.ymax,
do_sel_only, include_handles);
- extra = 0.1f * BLI_rctf_size_x(&cur_new);
- cur_new.xmin -= extra;
- cur_new.xmax += extra;
-
- extra = 0.1f * BLI_rctf_size_y(&cur_new);
- cur_new.ymin -= extra;
- cur_new.ymax += extra;
+ BLI_rctf_scale(&cur_new, 1.1f);
UI_view2d_smooth_view(C, ac.ar, &cur_new);
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index fa7c6bd472a..734c0e6c479 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -309,6 +309,12 @@ static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ /* make sure we keep the hide flags */
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP); /* prevent any noise of past */
+ ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript
index 737da4aac74..6e7c5982d6e 100644
--- a/source/blender/editors/space_image/SConscript
+++ b/source/blender/editors/space_image/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 0a3db59096a..01364fcacf0 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -219,7 +219,7 @@ static void preview_cb(ScrArea *sa, struct uiBlock *block)
BLI_rcti_translate(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin);
calc_image_view(sima, 'p');
-// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax);
+// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax);
/* map to image space coordinates */
mval[0] = disprect->xmin; mval[1] = disprect->ymin;
areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin);
@@ -236,7 +236,7 @@ static void preview_cb(ScrArea *sa, struct uiBlock *block)
CLAMP(disprect->xmax, 0, winx);
CLAMP(disprect->ymin, 0, winy);
CLAMP(disprect->ymax, 0, winy);
-// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax);
+// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax);
}
@@ -498,17 +498,17 @@ static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr,
}
/* decrease, increase arrows */
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0, 0, 17, 20, NULL, 0, 0, 0, 0, TIP_("Previous Layer"));
+ 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, 18, 20, NULL, 0, 0, 0, 0, TIP_("Next Layer"));
+ 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);
uiblock_layer_pass_buttons(row, rr, iuser, 230 * dpi_fac, render_slot);
/* decrease, increase arrows */
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0, 0, 17, 20, NULL, 0, 0, 0, 0, TIP_("Previous Pass"));
+ 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, 18, 20, NULL, 0, 0, 0, 0, TIP_("Next Pass"));
+ 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);
uiBlockEndAlign(block);
@@ -674,6 +674,24 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (ima->source != IMA_SRC_GENERATED) {
if (compact == 0) { /* background image view doesnt need these */
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ int has_alpha = TRUE;
+
+ if (ibuf) {
+ int imtype = BKE_ftype_to_imtype(ibuf->ftype);
+ char valid_channels = BKE_imtype_valid_channels(imtype);
+
+ has_alpha = valid_channels & IMA_CHAN_FLAG_ALPHA;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+
+ if (has_alpha) {
+ col = uiLayoutColumn(layout, FALSE);
+ uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE);
+ uiItemR(col, &imaptr, "alpha_mode", 0, "Alpha", ICON_NONE);
+ }
+
uiItemS(layout);
split = uiLayoutSplit(layout, 0.0f, FALSE);
@@ -694,10 +712,6 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
row = uiLayoutRow(col, FALSE);
uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields"));
uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
- row = uiLayoutRow(layout, FALSE);
- uiItemR(row, &imaptr, "use_premultiply", 0, NULL, ICON_NONE);
- uiItemR(row, &imaptr, "use_color_unpremultiply", 0, NULL, ICON_NONE);
}
}
@@ -770,6 +784,8 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
R_IMF_CHAN_DEPTH_32)) == 0)
{
row = uiLayoutRow(col, FALSE);
+
+ uiItemL(row, IFACE_("Color Depth:"), ICON_NONE);
uiItemR(row, imfptr, "color_depth", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
@@ -796,6 +812,8 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
}
if (imf->imtype == R_IMF_IMTYPE_JP2) {
+ uiItemR(col, imfptr, "jpeg2k_codec", 0, NULL, ICON_NONE);
+
row = uiLayoutRow(col, FALSE);
uiItemR(row, imfptr, "use_jpeg2k_cinema_preset", 0, NULL, ICON_NONE);
uiItemR(row, imfptr, "use_jpeg2k_cinema_48", 0, NULL, ICON_NONE);
@@ -858,6 +876,7 @@ void image_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil");
strcpy(pt->idname, "IMAGE_PT_gpencil");
strcpy(pt->label, "Grease Pencil");
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
BLI_addtail(&art->paneltypes, pt);
}
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index d565e6f9e9a..cae71885b87 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -75,13 +75,15 @@
#include "WM_types.h"
#include "RE_pipeline.h"
+#include "RE_engine.h"
#include "image_intern.h"
-static void draw_render_info(Scene *scene, Image *ima, ARegion *ar)
+static void draw_render_info(Scene *scene, Image *ima, ARegion *ar, float zoomx, float zoomy)
{
RenderResult *rr;
-
+ Render *re = RE_GetRender(scene->id.name);
+
rr = BKE_image_acquire_renderresult(scene, ima);
if (rr && rr->text) {
@@ -89,6 +91,73 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar)
}
BKE_image_release_renderresult(scene, ima);
+
+ if (re) {
+ int total_tiles;
+ rcti *tiles;
+
+ RE_engine_get_current_tiles(re, &total_tiles, &tiles);
+
+ if (total_tiles) {
+ int i, x, y;
+ rcti *tile;
+
+ /* find window pixel coordinates of origin */
+ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0.0f);
+ glScalef(zoomx, zoomy, 1.0f);
+
+ if (scene->r.mode & R_BORDER) {
+ glTranslatef((int)(-scene->r.border.xmin * scene->r.xsch * scene->r.size / 100.0f),
+ (int)(-scene->r.border.ymin * scene->r.ysch * scene->r.size / 100.0f),
+ 0.0f);
+ }
+
+ UI_ThemeColor(TH_FACE_SELECT);
+
+ for (i = 0, tile = tiles; i < total_tiles; i++, tile++) {
+ float delta_x = 4.0f * UI_DPI_FAC / zoomx;
+ float delta_y = 4.0f * UI_DPI_FAC / zoomy;
+
+ delta_x = min_ff(delta_x, tile->xmax - tile->xmin);
+ delta_y = min_ff(delta_y, tile->ymax - tile->ymin);
+
+ /* left bottom corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmin, tile->ymin + delta_y);
+ glVertex2f(tile->xmin, tile->ymin);
+ glVertex2f(tile->xmin + delta_x, tile->ymin);
+ glEnd();
+
+ /* left top corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmin, tile->ymax - delta_y);
+ glVertex2f(tile->xmin, tile->ymax);
+ glVertex2f(tile->xmin + delta_x, tile->ymax);
+ glEnd();
+
+ /* right bottom corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmax - delta_x, tile->ymin);
+ glVertex2f(tile->xmax, tile->ymin);
+ glVertex2f(tile->xmax, tile->ymin + delta_y);
+ glEnd();
+
+ /* right top corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmax - delta_x, tile->ymax);
+ glVertex2f(tile->xmax, tile->ymax);
+ glVertex2f(tile->xmax, tile->ymax - delta_y);
+ glEnd();
+ }
+
+ MEM_freeN(tiles);
+
+ glPopMatrix();
+ }
+ }
}
/* used by node view too */
@@ -116,29 +185,28 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
/* noisy, high contrast make impossible to read if lower alpha is used. */
glColor4ub(0, 0, 0, 190);
- glRecti(0.0, 0.0, BLI_rcti_size_x(&ar->winrct) + 1, 20);
+ glRecti(0.0, 0.0, BLI_rcti_size_x(&ar->winrct) + 1, UI_UNIT_Y);
glDisable(GL_BLEND);
- BLF_size(blf_mono_font, 11, 72);
+ BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi);
glColor3ub(255, 255, 255);
BLI_snprintf(str, sizeof(str), "X:%-4d Y:%-4d |", x, y);
- // UI_DrawString(6, 6, str); // works ok but fixed width is nicer.
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_Y, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
if (zp) {
glColor3ub(255, 255, 255);
BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff));
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
}
if (zpf) {
glColor3ub(255, 255, 255);
BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
}
@@ -146,34 +214,34 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
if (channels >= 3) {
glColor3ubv(red);
if (fp)
- BLI_snprintf(str, sizeof(str), " R:%-.4f", fp[0]);
+ BLI_snprintf(str, sizeof(str), " R:%-.5f", fp[0]);
else if (cp)
BLI_snprintf(str, sizeof(str), " R:%-3d", cp[0]);
else
BLI_snprintf(str, sizeof(str), " R:-");
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
glColor3ubv(green);
if (fp)
- BLI_snprintf(str, sizeof(str), " G:%-.4f", fp[1]);
+ BLI_snprintf(str, sizeof(str), " G:%-.5f", fp[1]);
else if (cp)
BLI_snprintf(str, sizeof(str), " G:%-3d", cp[1]);
else
BLI_snprintf(str, sizeof(str), " G:-");
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
glColor3ubv(blue);
if (fp)
- BLI_snprintf(str, sizeof(str), " B:%-.4f", fp[2]);
+ BLI_snprintf(str, sizeof(str), " B:%-.5f", fp[2]);
else if (cp)
BLI_snprintf(str, sizeof(str), " B:%-3d", cp[2]);
else
BLI_snprintf(str, sizeof(str), " B:-");
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
@@ -185,7 +253,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
BLI_snprintf(str, sizeof(str), " A:%-3d", cp[3]);
else
BLI_snprintf(str, sizeof(str), "- ");
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
}
@@ -199,7 +267,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
IMB_colormanagement_pixel_to_display_space_v4(pixel, fp, &scene->view_settings, &scene->display_settings);
BLI_snprintf(str, sizeof(str), " | CM R:%-.4f G:%-.4f B:%-.4f", pixel[0], pixel[1], pixel[2]);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
}
@@ -257,24 +325,24 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
glDisable(GL_BLEND);
glColor3fv(finalcol);
- dx += 5;
+ dx += 0.25f * UI_UNIT_X;
glBegin(GL_QUADS);
- glVertex2f(dx, 3);
- glVertex2f(dx, 17);
- glVertex2f(dx + 30, 17);
- glVertex2f(dx + 30, 3);
+ glVertex2f(dx, 0.15f * UI_UNIT_Y);
+ glVertex2f(dx, 0.85f * UI_UNIT_Y);
+ glVertex2f(dx + 1.5f * UI_UNIT_X, 0.85 * UI_UNIT_Y);
+ glVertex2f(dx + 1.5f * UI_UNIT_X, 0.15f * UI_UNIT_Y);
glEnd();
/* draw outline */
glColor3ub(128, 128, 128);
glBegin(GL_LINE_LOOP);
- glVertex2f(dx, 3);
- glVertex2f(dx, 17);
- glVertex2f(dx + 30, 17);
- glVertex2f(dx + 30, 3);
+ glVertex2f(dx, 0.15f * UI_UNIT_Y);
+ glVertex2f(dx, 0.85f * UI_UNIT_Y);
+ glVertex2f(dx + 1.5f * UI_UNIT_X, 0.85f * UI_UNIT_Y);
+ glVertex2f(dx + 1.5f * UI_UNIT_X, 0.15f * UI_UNIT_Y);
glEnd();
- dx += 35;
+ dx += 1.75f * UI_UNIT_X;
glColor3ub(255, 255, 255);
if (channels == 1) {
@@ -288,12 +356,12 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
}
BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
BLI_snprintf(str, sizeof(str), " L:%-.4f", lum);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
}
@@ -308,22 +376,22 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
}
BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
BLI_snprintf(str, sizeof(str), " S:%-.4f", sat);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
BLI_snprintf(str, sizeof(str), " V:%-.4f", val);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
BLI_snprintf(str, sizeof(str), " L:%-.4f", lum);
- BLF_position(blf_mono_font, dx, 6, 0);
+ BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str);
}
@@ -356,11 +424,11 @@ static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, fl
MEM_freeN(trectf);
/* ogl trick below is slower... (on ATI 9600) */
// glColorMask(1, 0, 0, 0);
-// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+3);
+// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf + 3);
// glColorMask(0, 1, 0, 0);
-// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+2);
+// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf + 2);
// glColorMask(0, 0, 1, 0);
-// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+1);
+// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf + 1);
// glColorMask(1, 1, 1, 1);
}
@@ -446,10 +514,10 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
void *cache_handle;
if (sima->flag & SI_USE_ALPHA) {
- fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
-
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
}
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
@@ -518,8 +586,8 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
sima->curtile = ima->xrep * ima->yrep - 1;
/* retrieve part of image buffer */
- dx = ibuf->x / ima->xrep;
- dy = ibuf->y / ima->yrep;
+ dx = max_ii(ibuf->x / ima->xrep, 1);
+ dy = max_ii(ibuf->y / ima->yrep, 1);
sx = (sima->curtile % ima->xrep) * dx;
sy = (sima->curtile / ima->xrep) * dy;
rect = get_part_from_buffer((unsigned int *)display_buffer, ibuf->x, sx, sy, sx + dx, sy + dy);
@@ -762,7 +830,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
show_render = (show_viewer && ima->type == IMA_TYPE_R_RESULT);
if (show_viewer) {
- /* use locked draw for drawing viewer image buffer since the conpositor
+ /* use locked draw for drawing viewer image buffer since the compositor
* is running in separated thread and compositor could free this buffers.
* other images are not modifying in such a way so they does not require
* lock (sergey)
@@ -786,7 +854,6 @@ void draw_image_main(const bContext *C, ARegion *ar)
if (sima->mode == SI_MODE_PAINT)
draw_image_paint_helpers(C, ar, scene, zoomx, zoomy);
-
/* XXX integrate this code */
#if 0
if (ibuf) {
@@ -812,5 +879,5 @@ void draw_image_main(const bContext *C, ARegion *ar)
/* render info */
if (ima && show_render)
- draw_render_info(scene, ima, ar);
+ draw_render_info(scene, ima, ar, zoomx, zoomy);
}
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index c4e2230e7a7..34207e16f1c 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -40,6 +40,7 @@
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_tessmesh.h"
+#include "BKE_library.h"
#include "IMB_imbuf_types.h"
@@ -78,8 +79,7 @@ void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *i
if (sima->image)
BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
- if (sima->image && ID_REAL_USERS(sima->image) <= 0)
- sima->image->id.us = max_ii(sima->image->id.us, 0) + 1;
+ id_us_ensure_real((ID *)sima->image);
if (obedit)
WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data);
@@ -97,8 +97,7 @@ void ED_space_image_set_mask(bContext *C, SpaceImage *sima, Mask *mask)
sima->mask_info.mask = mask;
/* weak, but same as image/space */
- if (sima->mask_info.mask && ID_REAL_USERS(sima->mask_info.mask) <= 0)
- sima->mask_info.mask->id.us = max_ii(sima->mask_info.mask->id.us, 0) + 1;
+ id_us_ensure_real((ID *)sima->mask_info.mask);
if (C) {
WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask);
@@ -194,9 +193,7 @@ void ED_space_image_get_size_fl(SpaceImage *sima, float size[2])
void ED_space_image_get_aspect(SpaceImage *sima, float *aspx, float *aspy)
{
Image *ima = sima->image;
- if ((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
- (ima->aspx == 0.0f || ima->aspy == 0.0f))
- {
+ if ((ima == NULL) || (ima->aspx == 0.0f || ima->aspy == 0.0f)) {
*aspx = *aspy = 1.0;
}
else {
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 0d0fdc6be1c..61dd457f2af 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -299,8 +299,8 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
SpaceImage *sima = CTX_wm_space_image(C);
float offset[2];
- offset[0] = (event->x - event->prevx) / sima->zoom;
- offset[1] = (event->y - event->prevy) / sima->zoom;
+ offset[0] = (event->prevx - event->x) / sima->zoom;
+ offset[1] = (event->prevy - event->y) / sima->zoom;
RNA_float_set_array(op->ptr, "offset", offset);
image_view_pan_exec(C, op);
@@ -457,14 +457,14 @@ enum {
static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if (event->type == MOUSEZOOM) {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
float delta, factor, location[2];
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
- delta = event->x - event->prevx + event->y - event->prevy;
+ delta = event->prevx - event->x + event->prevy - event->y;
if (U.uiflag & USER_ZOOM_INVERT)
delta *= -1;
@@ -1084,7 +1084,7 @@ void IMAGE_OT_match_movie_length(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Match Movie Length";
- ot->description = "Set image's users length to the one of this video";
+ ot->description = "Set image's user's length to the one of this video";
ot->idname = "IMAGE_OT_match_movie_length";
/* api callbacks */
@@ -1109,6 +1109,11 @@ static int image_replace_exec(bContext *C, wmOperator *op)
/* we cant do much if the str is longer then FILE_MAX :/ */
BLI_strncpy(sima->image->name, str, sizeof(sima->image->name));
+ if (sima->image->source == IMA_SRC_GENERATED) {
+ sima->image->source = IMA_SRC_FILE;
+ BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_SRC_CHANGE);
+ }
+
if (BLI_testextensie_array(str, imb_ext_movie))
sima->image->source = IMA_SRC_MOVIE;
else
@@ -1217,7 +1222,7 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
simopts->im_format.imtype = R_IMF_IMTYPE_PNG;
}
else {
- simopts->im_format.imtype = BKE_ftype_to_imtype(ibuf->ftype);
+ BKE_imbuf_to_image_format(&simopts->im_format, ibuf);
}
//simopts->subimtype = scene->r.subimtype; /* XXX - this is lame, we need to make these available too! */
simopts->im_format.quality = ibuf->ftype & 0xff;
@@ -1434,7 +1439,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
static int image_save_as_check(bContext *UNUSED(C), wmOperator *op)
{
ImageFormatData *imf = op->customdata;
- return WM_operator_filesel_ensure_ext_imtype(op, imf->imtype);
+ return WM_operator_filesel_ensure_ext_imtype(op, imf);
}
static int image_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
@@ -1559,6 +1564,7 @@ static int image_save_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SaveImageOptions simopts;
+ save_image_options_defaults(&simopts);
if (save_image_options_init(&simopts, sima, scene, FALSE) == 0)
return OPERATOR_CANCELLED;
save_image_options_from_op(&simopts, op);
@@ -1710,6 +1716,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
Scene *scene;
Object *obedit;
Image *ima;
+ Main *bmain;
PointerRNA ptr, idptr;
PropertyRNA *prop;
char name[MAX_ID_NAME - 2];
@@ -1720,6 +1727,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
sima = CTX_wm_space_image(C);
scene = CTX_data_scene(C);
obedit = CTX_data_edit_object(C);
+ bmain = CTX_data_main(C);
RNA_string_get(op->ptr, "name", name);
width = RNA_int_get(op->ptr, "width");
@@ -1729,15 +1737,10 @@ static int image_new_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "color", color);
alpha = RNA_boolean_get(op->ptr, "alpha");
- if (!floatbuf) {
- /* OCIO_TODO: perhaps we need to convert to display space, not just to sRGB */
- linearrgb_to_srgb_v3_v3(color, color);
- }
-
if (!alpha)
color[3] = 1.0f;
- ima = BKE_image_add_generated(width, height, name, alpha ? 32 : 24, floatbuf, gen_type, color);
+ ima = BKE_image_add_generated(bmain, width, height, name, alpha ? 32 : 24, floatbuf, gen_type, color);
if (!ima)
return OPERATOR_CANCELLED;
@@ -1774,7 +1777,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
/* XXX Note: the WM_operator_props_dialog_popup() doesn't work for uiIDContextProperty(), image is not being that way */
static int image_new_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
- return WM_operator_props_dialog_popup(C, op, 300, 100);
+ return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, 5 * UI_UNIT_Y);
}
@@ -1800,6 +1803,7 @@ void IMAGE_OT_new(wmOperatorType *ot)
RNA_def_int(ot->srna, "width", 1024, 1, INT_MAX, "Width", "Image width", 1, 16384);
RNA_def_int(ot->srna, "height", 1024, 1, INT_MAX, "Height", "Image height", 1, 16384);
prop = RNA_def_float_color(ot->srna, "color", 4, NULL, 0.0f, FLT_MAX, "Color", "Default fill color", 0.0f, 1.0f);
+ RNA_def_property_subtype(prop, PROP_COLOR_GAMMA);
RNA_def_property_float_array_default(prop, default_color);
RNA_def_boolean(ot->srna, "alpha", 1, "Alpha", "Create an image with an alpha channel");
RNA_def_enum(ot->srna, "generated_type", image_generated_type_items, IMA_GENTYPE_BLANK,
@@ -1955,9 +1959,10 @@ static int image_pack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
- pup = uiPupMenuBegin(C, "OK", ICON_QUESTION);
+ pup = uiPupMenuBegin(C, IFACE_("OK"), ICON_QUESTION);
layout = uiPupMenuLayout(pup);
- uiItemBooleanO(layout, "Can't pack edited image from disk. Pack as internal PNG?", ICON_NONE, op->idname, "as_png", 1);
+ uiItemBooleanO(layout, IFACE_("Can't pack edited image from disk, pack as internal PNG?"), ICON_NONE,
+ op->idname, "as_png", 1);
uiPupMenuEnd(C, pup);
BKE_image_release_ibuf(ima, ibuf, NULL);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index ea696772957..ca8270ba0f5 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -38,6 +38,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_threads.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -151,6 +152,7 @@ static SpaceLink *image_new(const bContext *UNUSED(C))
simage->spacetype = SPACE_IMAGE;
simage->zoom = 1.0f;
simage->lock = TRUE;
+ simage->flag = SI_SHOW_GPENCIL | SI_USE_ALPHA;
simage->iuser.ok = TRUE;
simage->iuser.fie_ima = 2;
@@ -291,10 +293,16 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0);
+ /* ctrl now works as well, shift + numpad works as arrow keys on Windows */
+ RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 4.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 2.0f);
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
+
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
@@ -669,22 +677,41 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
- /* Grease Pencil too (in addition to UV's) */
- draw_image_grease_pencil((bContext *)C, 1);
+ if (sima->flag & SI_SHOW_GPENCIL) {
+ /* Grease Pencil too (in addition to UV's) */
+ draw_image_grease_pencil((bContext *)C, TRUE);
+ }
/* sample line */
draw_image_sample_line(sima);
UI_view2d_view_restore(C);
- /* draw Grease Pencil - screen space only */
- draw_image_grease_pencil((bContext *)C, 0);
+ if (sima->flag & SI_SHOW_GPENCIL) {
+ /* draw Grease Pencil - screen space only */
+ draw_image_grease_pencil((bContext *)C, FALSE);
+ }
if (mask) {
- int width, height;
+ Image *image = ED_space_image(sima);
+ int width, height, show_viewer;
float aspx, aspy;
+
+ show_viewer = (image && image->source == IMA_SRC_VIEWER);
+
+ if (show_viewer) {
+ /* ED_space_image_get* will acquire image buffer which requires
+ * lock here by the same reason why lock is needed in draw_image_main
+ */
+ BLI_lock_thread(LOCK_DRAW_IMAGE);
+ }
+
ED_space_image_get_size(sima, &width, &height);
ED_space_image_get_aspect(sima, &aspx, &aspy);
+
+ if (show_viewer)
+ BLI_unlock_thread(LOCK_DRAW_IMAGE);
+
ED_mask_draw_region(mask, ar,
sima->mask_info.draw_flag, sima->mask_info.draw_type,
width, height,
@@ -723,6 +750,7 @@ static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
ED_region_panels_init(wm, ar);
keymap = WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
@@ -762,6 +790,7 @@ static void image_scope_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
ED_region_panels_init(wm, ar);
keymap = WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript
index e4746aefa0c..bacc28161d3 100644
--- a/source/blender/editors/space_info/SConscript
+++ b/source/blender/editors/space_info/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 5830c4574df..a748c303b5d 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -56,6 +56,8 @@
#include "ED_types.h"
#include "UI_resources.h"
+#include "UI_interface.h"
+#include "UI_view2d.h"
#include "info_intern.h"
#include "../space_info/textview.h"
@@ -139,7 +141,7 @@ static int report_textview_begin(TextViewContext *tvc)
// SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
ReportList *reports = (ReportList *)tvc->arg2;
- tvc->lheight = 14; //sc->lheight;
+ tvc->lheight = 14 * UI_DPI_FAC; //sc->lheight;
tvc->sel_start = 0;
tvc->sel_end = 0;
@@ -249,7 +251,8 @@ static int report_textview_line_color(struct TextViewContext *tvc, unsigned char
#undef USE_INFO_NEWLINE
-static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports, int draw, int mval[2], void **mouse_pick, int *pos_pick)
+static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, ReportList *reports,
+ int draw, int mval[2], void **mouse_pick, int *pos_pick)
{
int ret = 0;
@@ -262,6 +265,7 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re
tvc.step = report_textview_step;
tvc.line_get = report_textview_line_get;
tvc.line_color = report_textview_line_color;
+ tvc.const_colors = NULL;
tvc.arg1 = sinfo;
tvc.arg2 = reports;
@@ -269,10 +273,10 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re
/* view */
tvc.sel_start = 0;
tvc.sel_end = 0;
- tvc.lheight = 14; //sc->lheight;
+ tvc.lheight = 14 * UI_DPI_FAC; //sc->lheight;
tvc.ymin = v2d->cur.ymin;
tvc.ymax = v2d->cur.ymax;
- tvc.winx = ar->winx;
+ tvc.winx = ar->winx - V2D_SCROLL_WIDTH;
ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h
index 80018e849d3..b5426fe15e1 100644
--- a/source/blender/editors/space_info/info_intern.h
+++ b/source/blender/editors/space_info/info_intern.h
@@ -39,11 +39,16 @@ struct ReportList;
void FILE_OT_pack_all(struct wmOperatorType *ot);
void FILE_OT_unpack_all(struct wmOperatorType *ot);
+void FILE_OT_unpack_item(struct wmOperatorType *ot);
+void FILE_OT_pack_libraries(struct wmOperatorType *ot);
+void FILE_OT_unpack_libraries(struct wmOperatorType *ot);
+
void FILE_OT_make_paths_relative(struct wmOperatorType *ot);
void FILE_OT_make_paths_absolute(struct wmOperatorType *ot);
void FILE_OT_report_missing_files(struct wmOperatorType *ot);
void FILE_OT_find_missing_files(struct wmOperatorType *ot);
+
void INFO_OT_reports_display_update(struct wmOperatorType *ot);
/* info_draw.c */
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 48b5eaf7b44..04f6a5152e6 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -40,15 +40,19 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_bpath.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
+#include "BKE_bpath.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
+#include "BKE_screen.h"
#include "WM_api.h"
@@ -66,15 +70,70 @@
#include "info_intern.h"
+/********************* pack blend file libararies operator *********************/
+
+static int pack_libraries_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+
+ packLibraries(bmain, op->reports);
+
+ return OPERATOR_FINISHED;
+}
+
+void FILE_OT_pack_libraries(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Pack Blender Libraries";
+ ot->idname = "FILE_OT_pack_libraries";
+ ot->description = "Pack all used Blender library files into the current .blend";
+
+ /* api callbacks */
+ ot->exec = pack_libraries_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int unpack_libraries_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+
+ unpackLibraries(bmain, op->reports);
+
+ return OPERATOR_FINISHED;
+}
+
+static int unpack_libraries_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ return WM_operator_confirm_message(C, op, "Unpack Blender Libraries - creates directories, all new paths should work");
+}
+
+void FILE_OT_unpack_libraries(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Unpack Blender Libraries";
+ ot->idname = "FILE_OT_unpack_libraries";
+ ot->description = "Unpack all used Blender library files from this .blend file";
+
+ /* api callbacks */
+ ot->invoke = unpack_libraries_invoke;
+ ot->exec = unpack_libraries_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+
/********************* pack all operator *********************/
static int pack_all_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
-
+
packAll(bmain, op->reports);
G.fileflags |= G_AUTOPACK;
-
+
return OPERATOR_FINISHED;
}
@@ -83,7 +142,7 @@ static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
Main *bmain = CTX_data_main(C);
Image *ima;
ImBuf *ibuf;
-
+
// first check for dirty images
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->ibufs.first) { /* XXX FIX */
@@ -93,16 +152,16 @@ static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
BKE_image_release_ibuf(ima, ibuf, NULL);
break;
}
-
+
BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
-
+
if (ima) {
uiPupMenuOkee(C, "FILE_OT_pack_all", "Some images are painted on. These changes will be lost. Continue?");
return OPERATOR_CANCELLED;
}
-
+
return pack_all_exec(C, op);
}
@@ -116,11 +175,12 @@ void FILE_OT_pack_all(wmOperatorType *ot)
/* api callbacks */
ot->exec = pack_all_exec;
ot->invoke = pack_all_invoke;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
/********************* unpack all operator *********************/
static const EnumPropertyItem unpack_all_method_items[] = {
@@ -160,9 +220,9 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)
}
if (count == 1)
- strcpy(title, "Unpack 1 file");
+ strcpy(title, IFACE_("Unpack 1 File"));
else
- BLI_snprintf(title, sizeof(title), "Unpack %d files", count);
+ BLI_snprintf(title, sizeof(title), IFACE_("Unpack %d Files"), count);
pup = uiPupMenuBegin(C, title, ICON_NONE);
layout = uiPupMenuLayout(pup);
@@ -193,6 +253,78 @@ void FILE_OT_unpack_all(wmOperatorType *ot)
RNA_def_enum(ot->srna, "method", unpack_all_method_items, PF_USE_LOCAL, "Method", "How to unpack");
}
+/********************* unpack single item operator *********************/
+
+static const EnumPropertyItem unpack_item_method_items[] = {
+ {PF_USE_LOCAL, "USE_LOCAL", 0, "Use file from current directory (create when necessary)", ""},
+ {PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write file to current directory (overwrite existing file)", ""},
+ {PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use file in original location (create when necessary)", ""},
+ {PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write file to original location (overwrite existing file)", ""},
+ /* {PF_ASK, "ASK", 0, "Ask for each file", ""}, */
+ {0, NULL, 0, NULL, NULL}};
+
+
+static int unpack_item_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ ID *id;
+ char idname[MAX_ID_NAME - 2];
+ int type = RNA_int_get(op->ptr, "id_type");
+ int method = RNA_enum_get(op->ptr, "method");
+
+ RNA_string_get(op->ptr, "id_name", idname);
+ id = BKE_libblock_find_name(type, idname);
+
+ if (id == NULL) {
+ BKE_report(op->reports, RPT_WARNING, "No packed file");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (method != PF_KEEP)
+ BKE_unpack_id(bmain, id, op->reports, method); /* XXX PF_ASK can't work here */
+
+ G.fileflags &= ~G_AUTOPACK;
+
+ return OPERATOR_FINISHED;
+}
+
+static int unpack_item_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ pup = uiPupMenuBegin(C, IFACE_("Unpack"), ICON_NONE);
+ layout = uiPupMenuLayout(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);
+
+ return OPERATOR_CANCELLED;
+}
+
+void FILE_OT_unpack_item(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Unpack Item";
+ ot->idname = "FILE_OT_unpack_item";
+ ot->description = "Unpack this file to an external file";
+
+ /* api callbacks */
+ ot->exec = unpack_item_exec;
+ ot->invoke = unpack_item_invoke;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "method", unpack_item_method_items, PF_USE_LOCAL, "Method", "How to unpack");
+ RNA_def_string(ot->srna, "id_name", "", BKE_ST_MAXNAME, "ID name", "Name of ID block to unpack");
+ RNA_def_int(ot->srna, "id_type", ID_IM, 0, INT_MAX, "ID Type", "Identifier type of ID block", 0, INT_MAX);
+}
+
+
/********************* make paths relative operator *********************/
static int make_paths_relative_exec(bContext *C, wmOperator *op)
@@ -204,7 +336,7 @@ static int make_paths_relative_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BLI_bpath_relative_convert(bmain, bmain->name, op->reports);
+ BKE_bpath_relative_convert(bmain, bmain->name, op->reports);
/* redraw everything so any changed paths register */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -237,7 +369,7 @@ static int make_paths_absolute_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BLI_bpath_absolute_convert(bmain, bmain->name, op->reports);
+ BKE_bpath_absolute_convert(bmain, bmain->name, op->reports);
/* redraw everything so any changed paths register */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -266,7 +398,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
/* run the missing file check */
- BLI_bpath_missing_files_check(bmain, op->reports);
+ BKE_bpath_missing_files_check(bmain, op->reports);
return OPERATOR_FINISHED;
}
@@ -291,7 +423,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
const char *searchpath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0);
- BLI_bpath_missing_files_find(bmain, searchpath, op->reports);
+ BKE_bpath_missing_files_find(bmain, searchpath, op->reports);
MEM_freeN((void *)searchpath);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 049a50f89fc..3050563e538 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -62,7 +62,7 @@ int info_report_mask(SpaceInfo *UNUSED(sinfo))
return report_mask;
#endif
- return RPT_DEBUG_ALL | RPT_INFO_ALL | RPT_OPERATOR_ALL | RPT_WARNING_ALL | RPT_ERROR_ALL;
+ return RPT_DEBUG_ALL | RPT_INFO_ALL | RPT_OPERATOR_ALL | RPT_PROPERTY_ALL | RPT_WARNING_ALL | RPT_ERROR_ALL;
}
// TODO, get this working again!
@@ -77,7 +77,10 @@ static int report_replay_exec(bContext *C, wmOperator *UNUSED(op))
sc->type = CONSOLE_TYPE_PYTHON;
for (report = reports->list.last; report; report = report->prev) {
- if ((report->type & report_mask) && (report->type & RPT_OPERATOR_ALL) && (report->flag & SELECT)) {
+ if ((report->type & report_mask) &&
+ (report->type & RPT_OPERATOR_ALL | RPT_PROPERTY_ALL) &&
+ (report->flag & SELECT))
+ {
console_history_add_str(sc, report->message, 0);
WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL);
@@ -145,7 +148,7 @@ static int select_report_pick_invoke(bContext *C, wmOperator *op, wmEvent *event
void INFO_OT_select_pick(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Select report";
+ ot->name = "Select Report";
ot->description = "Select reports by index";
ot->idname = "INFO_OT_select_pick";
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 5e5e0c87feb..976769752f9 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -39,6 +39,9 @@
#include "DNA_scene_types.h"
#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BLF_translation.h"
#include "BKE_anim.h"
#include "BKE_blender.h"
@@ -47,6 +50,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
+#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_tessmesh.h"
@@ -62,7 +66,7 @@ typedef struct SceneStats {
int totbone, totbonesel;
int totobj, totobjsel;
int totlamp, totlampsel;
- int tottri, totmesh, totcurve;
+ int tottri, totmesh;
char infostr[512];
} SceneStats;
@@ -74,7 +78,7 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
{
/* we assume derivedmesh is already built, this strictly does stats now. */
DerivedMesh *dm = ob->derivedFinal;
- int totvert, totedge, totface;
+ int totvert, totedge, totface, totloop;
stats->totmesh += totob;
@@ -82,10 +86,12 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
totface = dm->getNumPolys(dm);
+ totloop = dm->getNumLoops(dm);
stats->totvert += totvert * totob;
stats->totedge += totedge * totob;
stats->totface += totface * totob;
+ stats->tottri += poly_to_tri_count(totface, totloop) * totob;
if (sel) {
stats->totvertsel += totvert;
@@ -103,40 +109,23 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
case OB_SURF:
case OB_CURVE:
case OB_FONT:
- {
- int tot = 0, totf = 0;
-
- stats->totcurve += totob;
-
- if (ob->disp.first)
- BKE_displist_count(&ob->disp, &tot, &totf);
-
- tot *= totob;
- totf *= totob;
-
- stats->totvert += tot;
- stats->totface += totf;
-
- if (sel) {
- stats->totvertsel += tot;
- stats->totfacesel += totf;
- }
- break;
- }
case OB_MBALL:
{
- int tot = 0, totf = 0;
+ int totv = 0, totf = 0, tottri = 0;
- BKE_displist_count(&ob->disp, &tot, &totf);
+ if (ob->disp.first)
+ BKE_displist_count(&ob->disp, &totv, &totf, &tottri);
- tot *= totob;
- totf *= totob;
+ totv *= totob;
+ totf *= totob;
+ tottri *= totob;
- stats->totvert += tot;
+ stats->totvert += totv;
stats->totface += totf;
+ stats->tottri += tottri;
if (sel) {
- stats->totvertsel += tot;
+ stats->totvertsel += totv;
stats->totfacesel += totf;
}
break;
@@ -179,8 +168,11 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
if (ebo->flag & BONE_SELECTED) stats->totbonesel++;
/* if this is a connected child and it's parent is being moved, remove our root */
- if ((ebo->flag & BONE_CONNECTED) && (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL))
+ if ((ebo->flag & BONE_CONNECTED) && (ebo->flag & BONE_ROOTSEL) &&
+ ebo->parent && (ebo->parent->flag & BONE_TIPSEL))
+ {
stats->totvertsel--;
+ }
stats->totvert += 2;
}
@@ -260,6 +252,12 @@ static void stats_object_pose(Object *ob, SceneStats *stats)
}
}
+static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
+{
+ stats->totvert = ob->sculpt->bm->totvert;
+ stats->tottri = ob->sculpt->bm->totface;
+}
+
static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
{
if (base->flag & SELECT) stats->totobjsel++;
@@ -319,6 +317,12 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
}
}
+static int stats_is_object_dynamic_topology_sculpt(Object *ob)
+{
+ return (ob && (ob->mode & OB_MODE_SCULPT) &&
+ ob->sculpt && ob->sculpt->bm);
+}
+
/* Statistics displayed in info header. Called regularly on scene changes. */
static void stats_update(Scene *scene)
{
@@ -334,6 +338,10 @@ static void stats_update(Scene *scene)
/* Pose Mode */
stats_object_pose(ob, &stats);
}
+ else if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ /* Dynamic-topology sculpt mode */
+ stats_object_sculpt_dynamic_topology(ob, &stats);
+ }
else {
/* Objects */
for (base = scene->base.first; base; base = base->next)
@@ -359,9 +367,9 @@ static void stats_string(Scene *scene)
mmap_in_use = MEM_get_mapped_memory_in_use();
/* get memory statistics */
- s = memstr + sprintf(memstr, " | Mem:%.2fM", (double)((mem_in_use - mmap_in_use) >> 10) / 1024.0);
+ s = memstr + sprintf(memstr, IFACE_(" | Mem:%.2fM"), (double)((mem_in_use - mmap_in_use) >> 10) / 1024.0);
if (mmap_in_use)
- sprintf(s, " (%.2fM)", (double)((mmap_in_use) >> 10) / 1024.0);
+ sprintf(s, IFACE_(" (%.2fM)"), (double)((mmap_in_use) >> 10) / 1024.0);
s = stats->infostr;
@@ -369,28 +377,34 @@ static void stats_string(Scene *scene)
if (scene->obedit) {
if (BKE_keyblock_from_object(scene->obedit))
- s += sprintf(s, "(Key) ");
+ s += sprintf(s, IFACE_("(Key) "));
if (scene->obedit->type == OB_MESH) {
- s += sprintf(s, "Verts:%d/%d | Edges:%d/%d | Faces:%d/%d | Tris:%d",
- stats->totvertsel, stats->totvert, stats->totedgesel, stats->totedge, stats->totfacesel, stats->totface, stats->tottri);
+ s += sprintf(s, IFACE_("Verts:%d/%d | Edges:%d/%d | Faces:%d/%d | Tris:%d"),
+ stats->totvertsel, stats->totvert, stats->totedgesel, stats->totedge, stats->totfacesel,
+ stats->totface, stats->tottri);
}
else if (scene->obedit->type == OB_ARMATURE) {
- s += sprintf(s, "Verts:%d/%d | Bones:%d/%d", stats->totvertsel, stats->totvert, stats->totbonesel, stats->totbone);
+ s += sprintf(s, IFACE_("Verts:%d/%d | Bones:%d/%d"), stats->totvertsel, stats->totvert, stats->totbonesel,
+ stats->totbone);
}
else {
- s += sprintf(s, "Verts:%d/%d", stats->totvertsel, stats->totvert);
+ s += sprintf(s, IFACE_("Verts:%d/%d"), stats->totvertsel, stats->totvert);
}
strcat(s, memstr);
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- s += sprintf(s, "Bones:%d/%d %s",
+ s += sprintf(s, IFACE_("Bones:%d/%d %s"),
stats->totbonesel, stats->totbone, memstr);
}
+ else if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ s += sprintf(s, IFACE_("Verts:%d | Tris:%d"), stats->totvert, stats->tottri);
+ }
else {
- s += sprintf(s, "Verts:%d | Faces:%d | Objects:%d/%d | Lamps:%d/%d%s",
- stats->totvert, stats->totface, stats->totobjsel, stats->totobj, stats->totlampsel, stats->totlamp, memstr);
+ s += sprintf(s, IFACE_("Verts:%d | Faces:%d | Tris:%d | Objects:%d/%d | Lamps:%d/%d%s"),
+ stats->totvert, stats->totface, stats->tottri, stats->totobjsel, stats->totobj, stats->totlampsel,
+ stats->totlamp, memstr);
}
if (ob)
@@ -413,4 +427,3 @@ const char *ED_info_stats_string(Scene *scene)
return scene->stats->infostr;
}
-
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index cba0a808d63..1577ac338e7 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -178,7 +178,11 @@ static void info_main_area_draw(const bContext *C, ARegion *ar)
static void info_operatortypes(void)
{
WM_operatortype_append(FILE_OT_pack_all);
+ WM_operatortype_append(FILE_OT_pack_libraries);
WM_operatortype_append(FILE_OT_unpack_all);
+ WM_operatortype_append(FILE_OT_unpack_item);
+ WM_operatortype_append(FILE_OT_unpack_libraries);
+
WM_operatortype_append(FILE_OT_make_paths_relative);
WM_operatortype_append(FILE_OT_make_paths_absolute);
WM_operatortype_append(FILE_OT_report_missing_files);
@@ -272,7 +276,7 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn)
static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
{
struct RecentFile *recent;
- char file [FILE_MAX];
+ char file[FILE_MAX];
uiLayout *layout = menu->layout;
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
if (G.recent_files.first) {
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index f454b1dbe7d..66f4904c340 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -45,7 +45,8 @@
static void console_font_begin(TextViewContext *sc)
{
- BLF_size(blf_mono_font, sc->lheight - 2, 72);
+ /* 0.875 is based on: 16 pixels lines get 14 pixel text */
+ BLF_size(blf_mono_font, 0.875 * sc->lheight, 72);
}
typedef struct ConsoleDrawContext {
@@ -61,32 +62,35 @@ typedef struct ConsoleDrawContext {
int draw;
} ConsoleDrawContext;
-static void console_draw_sel(int sel[2], int xy[2], int str_len_draw, int cwidth, int lheight)
+BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step)
+{
+ cdc->sel[0] += step;
+ cdc->sel[1] += step;
+}
+
+static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight,
+ const unsigned char bg_sel[4])
{
if (sel[0] <= str_len_draw && sel[1] >= 0) {
- int sta = max_ii(sel[0], 0);
- int end = min_ii(sel[1], str_len_draw);
+ const int sta = max_ii(sel[0], 0);
+ const int end = min_ii(sel[1], str_len_draw);
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_halftone);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(255, 255, 255, 96);
+ glColor4ubv(bg_sel);
glRecti(xy[0] + (cwidth * sta), xy[1] - 2 + lheight, xy[0] + (cwidth * end), xy[1] - 2);
- glDisable(GL_POLYGON_STIPPLE);
glDisable(GL_BLEND);
}
}
-
/* return 0 if the last line is off the screen
* should be able to use this for any string type */
-static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str_len, unsigned char *fg, unsigned char *bg)
+static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const int str_len,
+ const unsigned char fg[3], const unsigned char bg[3], const unsigned char bg_sel[4])
{
-#define STEP_SEL(value) cdc->sel[0] += (value); cdc->sel[1] += (value)
int rct_ofs = cdc->lheight / 4;
int tot_lines = (str_len / cdc->console_width) + 1; /* total number of lines for wrapping */
int y_next = (str_len > cdc->console_width) ? cdc->xy[1] + cdc->lheight * tot_lines : cdc->xy[1] + cdc->lheight;
@@ -101,7 +105,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
/* wrap */
if (str_len > cdc->console_width)
- ofs += (cdc->console_width * ((int)((((float)(y_next - cdc->mval[1]) / (float)(y_next - cdc->xy[1])) * tot_lines))));
+ ofs += cdc->console_width * ((int)((((float)(y_next - cdc->mval[1]) /
+ (float)(y_next - cdc->xy[1])) * tot_lines)));
CLAMP(ofs, 0, str_len);
*cdc->pos_pick += str_len - ofs;
@@ -120,7 +125,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
/* adjust selection even if not drawing */
if (cdc->sel[0] != cdc->sel[1]) {
- STEP_SEL(-(str_len + 1));
+ console_step_sel(cdc, -(str_len + 1));
}
return 1;
@@ -149,10 +154,10 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
BLF_draw(mono, line_stride, str_len - initial_offset);
if (cdc->sel[0] != cdc->sel[1]) {
- STEP_SEL(-initial_offset);
+ console_step_sel(cdc, -initial_offset);
// glColor4ub(255, 0, 0, 96); // debug
- console_draw_sel(cdc->sel, cdc->xy, str_len % cdc->console_width, cdc->cwidth, cdc->lheight);
- STEP_SEL(cdc->console_width);
+ console_draw_sel(cdc->sel, cdc->xy, str_len % cdc->console_width, cdc->cwidth, cdc->lheight, bg_sel);
+ console_step_sel(cdc, cdc->console_width);
glColor3ubv(fg);
}
@@ -166,8 +171,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
if (cdc->sel[0] != cdc->sel[1]) {
// glColor4ub(0, 255, 0, 96); // debug
- console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->lheight);
- STEP_SEL(cdc->console_width);
+ console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->lheight, bg_sel);
+ console_step_sel(cdc, cdc->console_width);
glColor3ubv(fg);
}
@@ -179,7 +184,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
}
copy_v2_v2_int(cdc->sel, sel_orig);
- STEP_SEL(-(str_len + 1));
+ console_step_sel(cdc, -(str_len + 1));
}
else { /* simple, no wrap */
@@ -200,8 +205,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
isel[1] = str_len - cdc->sel[0];
// glColor4ub(255, 255, 0, 96); // debug
- console_draw_sel(isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight);
- STEP_SEL(-(str_len + 1));
+ console_draw_sel(isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight, bg_sel);
+ console_step_sel(cdc, -(str_len + 1));
}
cdc->xy[1] += cdc->lheight;
@@ -211,13 +216,11 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
}
return 1;
-#undef STEP_SEL
}
#define CONSOLE_DRAW_MARGIN 4
-#define CONSOLE_DRAW_SCROLL 16
-int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick)
+int textview_draw(TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick)
{
ConsoleDrawContext cdc = {0};
@@ -241,9 +244,10 @@ int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick
cdc.cwidth = (int)BLF_fixed_width(mono);
assert(cdc.cwidth > 0);
cdc.lheight = tvc->lheight;
- cdc.console_width = (tvc->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth;
+ /* note, scroll bar must be already subtracted () */
+ cdc.console_width = (tvc->winx - (CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth;
CLAMP(cdc.console_width, 1, INT_MAX); /* avoid divide by zero on small windows */
- cdc.winx = tvc->winx - (CONSOLE_DRAW_MARGIN + CONSOLE_DRAW_SCROLL);
+ cdc.winx = tvc->winx - CONSOLE_DRAW_MARGIN;
cdc.ymin = tvc->ymin;
cdc.ymax = tvc->ymax;
cdc.xy = xy;
@@ -263,6 +267,11 @@ int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick
}
if (tvc->begin(tvc)) {
+ unsigned char bg_sel[4] = {0};
+
+ if (draw && tvc->const_colors) {
+ tvc->const_colors(tvc, bg_sel);
+ }
do {
const char *ext_line;
@@ -276,7 +285,11 @@ int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick
tvc->line_get(tvc, &ext_line, &ext_len);
- if (!console_draw_string(&cdc, ext_line, ext_len, (color_flag & TVC_LINE_FG) ? fg : NULL, (color_flag & TVC_LINE_BG) ? bg : NULL)) {
+ if (!console_draw_string(&cdc, ext_line, ext_len,
+ (color_flag & TVC_LINE_FG) ? fg : NULL,
+ (color_flag & TVC_LINE_BG) ? bg : NULL,
+ bg_sel))
+ {
/* when drawing, if we pass v2d->cur.ymax, then quit */
if (draw) {
break; /* past the y limits */
diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h
index 33fbe556245..653c9b83a50 100644
--- a/source/blender/editors/space_info/textview.h
+++ b/source/blender/editors/space_info/textview.h
@@ -46,6 +46,7 @@ typedef struct TextViewContext {
int (*step)(struct TextViewContext *tvc);
int (*line_get)(struct TextViewContext *tvc, const char **, int *);
int (*line_color)(struct TextViewContext *tvc, unsigned char fg[3], unsigned char bg[3]);
+ void (*const_colors)(struct TextViewContext *tvc, unsigned char bg_sel[4]); /* constant theme colors */
void *iter;
int iter_index;
int iter_char; /* char intex, used for multi-line report display */
@@ -54,7 +55,7 @@ typedef struct TextViewContext {
} TextViewContext;
-int textview_draw(struct TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick);
+int textview_draw(struct TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick);
#define TVC_LINE_FG (1<<0)
#define TVC_LINE_BG (1<<1)
diff --git a/source/blender/editors/space_logic/SConscript b/source/blender/editors/space_logic/SConscript
index e63d88ea5de..e5a19b7f30b 100644
--- a/source/blender/editors/space_logic/SConscript
+++ b/source/blender/editors/space_logic/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c
index e898a1baf74..a55da0e3b2c 100644
--- a/source/blender/editors/space_logic/logic_buttons.c
+++ b/source/blender/editors/space_logic/logic_buttons.c
@@ -145,7 +145,7 @@ void LOGIC_OT_links_cut(wmOperatorType *ot)
{
PropertyRNA *prop;
- ot->name = "Cut links";
+ ot->name = "Cut Links";
ot->idname = "LOGIC_OT_links_cut";
ot->description = "Remove logic brick connections";
diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c
index 74be7c46d26..2313885dbaf 100644
--- a/source/blender/editors/space_logic/logic_ops.c
+++ b/source/blender/editors/space_logic/logic_ops.c
@@ -54,6 +54,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "UI_view2d.h"
+
#include "logic_intern.h"
// temporary new includes for texface functions
@@ -328,8 +330,10 @@ static void LOGIC_OT_sensor_add(wmOperatorType *ot)
/* properties */
ot->prop = prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, SENS_ALWAYS, "Type", "Type of sensor to add");
RNA_def_enum_funcs(prop, rna_Sensor_type_itemf);
- RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Sensor to add");
- RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Sensor to");
+ prop = RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Sensor to add");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Sensor to");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************* Add/Remove Controller Operator ************* */
@@ -427,6 +431,8 @@ static int controller_add_exec(bContext *C, wmOperator *op)
static void LOGIC_OT_controller_add(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Add Controller";
ot->description = "Add a controller to the active object";
@@ -442,8 +448,10 @@ static void LOGIC_OT_controller_add(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", controller_type_items, CONT_LOGIC_AND, "Type", "Type of controller to add");
- RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Controller to add");
- RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Controller to");
+ prop = RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Controller to add");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Controller to");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************* Add/Remove Actuator Operator ************* */
@@ -545,8 +553,10 @@ static void LOGIC_OT_actuator_add(wmOperatorType *ot)
/* properties */
ot->prop = prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, CONT_LOGIC_AND, "Type", "Type of actuator to add");
RNA_def_enum_funcs(prop, rna_Actuator_type_itemf);
- RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Actuator to add");
- RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Actuator to");
+ prop = RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the Actuator to add");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna, "object", "", MAX_NAME, "Object", "Name of the Object to add the Actuator to");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************* Move Logic Bricks Operator ************* */
@@ -723,6 +733,39 @@ static void LOGIC_OT_texface_convert(wmOperatorType *ot)
}
+/* ************************ view ********************* */
+
+static int logic_view_all_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ ARegion *ar = CTX_wm_region(C);
+ rctf cur_new = ar->v2d.tot;
+ float aspect = BLI_rctf_size_y(&ar->v2d.cur) / BLI_rctf_size_x(&ar->v2d.cur);
+
+ /* force the view2d code to zoom to width, not height */
+ cur_new.ymin = cur_new.ymax - BLI_rctf_size_x(&cur_new) * aspect;
+
+ UI_view2d_smooth_view(C, ar, &cur_new);
+
+ return OPERATOR_FINISHED;
+}
+
+static void LOGIC_OT_view_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "View All";
+ ot->idname = "LOGIC_OT_view_all";
+ ot->description = "Resize view so you can see all logic bricks";
+
+ /* api callbacks */
+ ot->exec = logic_view_all_exec;
+ ot->poll = ED_operator_logic_active;
+
+ /* flags */
+ ot->flag = 0;
+}
+
+/* ************************* */
+
void ED_operatortypes_logic(void)
{
WM_operatortype_append(LOGIC_OT_sensor_remove);
@@ -735,4 +778,5 @@ void ED_operatortypes_logic(void)
WM_operatortype_append(LOGIC_OT_actuator_add);
WM_operatortype_append(LOGIC_OT_actuator_move);
WM_operatortype_append(LOGIC_OT_texface_convert);
+ WM_operatortype_append(LOGIC_OT_view_all);
}
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 5a8a7cef119..fa7e888f8d7 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -1006,7 +1006,7 @@ static void draw_sensor_actuator(uiLayout *layout, PointerRNA *ptr)
static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
{
- bSensor *sens = (bSensor*)ptr->data;
+ bSensor *sens = (bSensor *)ptr->data;
bArmatureSensor *as = (bArmatureSensor *) sens->data;
Object *ob = (Object *)ptr->id.data;
PointerRNA pose_ptr, pchan_ptr;
@@ -1476,7 +1476,7 @@ static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr)
{
- bActuator *act = (bActuator*)ptr->data;
+ bActuator *act = (bActuator *)ptr->data;
bArmatureActuator *aa = (bArmatureActuator *) act->data;
Object *ob = (Object *)ptr->id.data;
bConstraint *constraint = NULL;
@@ -1860,6 +1860,25 @@ static void draw_actuator_motion(uiLayout *layout, PointerRNA *ptr)
uiItemR(col, ptr, "integral_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "derivate_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
break;
+ case ACT_OBJECT_CHARACTER:
+ split = uiLayoutSplit(layout, 0.9, FALSE);
+ row = uiLayoutRow(split, FALSE);
+ uiItemR(row, ptr, "offset_location", 0, NULL, ICON_NONE);
+ row = uiLayoutRow(split, TRUE);
+ uiItemR(row, ptr, "use_local_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
+ uiItemR(row, ptr, "use_add_character_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
+
+ split = uiLayoutSplit(layout, 0.9, FALSE);
+ row = uiLayoutRow(split, FALSE);
+ uiItemR(row, ptr, "offset_rotation", 0, NULL, ICON_NONE);
+ uiItemR(split, ptr, "use_local_rotation", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
+
+ split = uiLayoutSplit(layout, 0.9, FALSE);
+ row = uiLayoutRow(split, FALSE);
+ split = uiLayoutSplit(row, 0.7, FALSE);
+ uiItemL(split, "", ICON_NONE); /*Just use this for some spacing */
+ uiItemR(split, ptr, "use_character_jump", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
+ break;
}
}
@@ -2226,6 +2245,7 @@ void logic_buttons(bContext *C, ARegion *ar)
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);
/* loop over all objects and set visible/linked flags for the logic bricks */
for (a=0; a<count; a++) {
@@ -2270,11 +2290,11 @@ void logic_buttons(bContext *C, ARegion *ar)
/* ****************** Controllers ****************** */
- xco= 420; yco= -10; width= 300;
+ 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, UI_GetStyle());
row = uiLayoutRow(layout, TRUE);
- uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
+ uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
uiItemR(row, &logic_ptr, "show_controllers_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
uiItemR(row, &logic_ptr, "show_controllers_active_object", 0, IFACE_("Act"), ICON_NONE);
@@ -2301,7 +2321,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-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers"));
+ 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"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2377,11 +2397,11 @@ void logic_buttons(bContext *C, ARegion *ar)
/* ****************** Sensors ****************** */
- xco= 10; yco= -10; width= 340;
+ 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, UI_GetStyle());
row = uiLayoutRow(layout, TRUE);
- uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
+ 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 */
uiItemR(row, &logic_ptr, "show_sensors_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
uiItemR(row, &logic_ptr, "show_sensors_active_object", 0, IFACE_("Act"), ICON_NONE);
@@ -2398,7 +2418,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-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors"));
+ 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"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2446,11 +2466,11 @@ void logic_buttons(bContext *C, ARegion *ar)
/* ****************** Actuators ****************** */
- xco= 800; yco= -10; width= 340;
+ 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, UI_GetStyle());
row = uiLayoutRow(layout, TRUE);
- uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
+ 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 */
uiItemR(row, &logic_ptr, "show_actuators_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
uiItemR(row, &logic_ptr, "show_actuators_active_object", 0, IFACE_("Act"), ICON_NONE);
@@ -2469,7 +2489,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-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators"));
+ 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"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2516,7 +2536,7 @@ void logic_buttons(bContext *C, ARegion *ar)
uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */
height = MIN2(height, yco);
- UI_view2d_totRect_set(&ar->v2d, 1150, height);
+ UI_view2d_totRect_set(&ar->v2d, 57.5f * U.widget_unit, height - U.widget_unit);
/* set the view */
UI_view2d_view_ortho(&ar->v2d);
diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c
index 4cd53215697..3f3c81f2bfa 100644
--- a/source/blender/editors/space_logic/space_logic.c
+++ b/source/blender/editors/space_logic/space_logic.c
@@ -148,7 +148,7 @@ static SpaceLink *logic_new(const bContext *C)
/* not spacelink itself */
static void logic_free(SpaceLink *UNUSED(sl))
{
-// Spacelogic *slogic= (SpaceLogic*) sl;
+// Spacelogic *slogic= (SpaceLogic *) sl;
// if (slogic->gpd)
// XXX BKE_gpencil_free(slogic->gpd);
@@ -183,7 +183,7 @@ static void logic_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "LOGIC_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_menu(keymap, "LOGIC_MT_logicbricks_add", AKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "VIEW2D_OT_reset", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "LOGIC_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
}
diff --git a/source/blender/editors/space_nla/SConscript b/source/blender/editors/space_nla/SConscript
index ee010e6856f..18c6392eee9 100644
--- a/source/blender/editors/space_nla/SConscript
+++ b/source/blender/editors/space_nla/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index d75946c4317..eb7de072043 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -308,7 +308,7 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
/* strip extents */
column = uiLayoutColumn(layout, TRUE);
- uiItemL(column, "Strip Extents:", ICON_NONE);
+ uiItemL(column, IFACE_("Strip Extents:"), ICON_NONE);
uiItemR(column, &strip_ptr, "frame_start", 0, NULL, ICON_NONE);
uiItemR(column, &strip_ptr, "frame_end", 0, NULL, ICON_NONE);
@@ -343,7 +343,7 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
/* settings */
column = uiLayoutColumn(layout, TRUE);
uiLayoutSetActive(column, !(RNA_boolean_get(&strip_ptr, "use_animated_influence") || RNA_boolean_get(&strip_ptr, "use_animated_time")));
- uiItemL(column, "Playback Settings:", ICON_NONE);
+ uiItemL(column, IFACE_("Playback Settings:"), ICON_NONE);
uiItemR(column, &strip_ptr, "mute", 0, NULL, ICON_NONE);
uiItemR(column, &strip_ptr, "use_reverse", 0, NULL, ICON_NONE);
}
@@ -373,15 +373,15 @@ static void nla_panel_actclip(const bContext *C, Panel *pa)
/* action extents */
// XXX custom names were used here (to avoid the prefixes)... probably not necessary in future?
column = uiLayoutColumn(layout, TRUE);
- uiItemL(column, "Action Extents:", ICON_NONE);
- uiItemR(column, &strip_ptr, "action_frame_start", 0, "Start Frame", ICON_NONE);
- uiItemR(column, &strip_ptr, "action_frame_end", 0, "End Frame", ICON_NONE);
+ uiItemL(column, IFACE_("Action Extents:"), ICON_NONE);
+ uiItemR(column, &strip_ptr, "action_frame_start", 0, IFACE_("Start Frame"), ICON_NONE);
+ uiItemR(column, &strip_ptr, "action_frame_end", 0, IFACE_("End Frame"), ICON_NONE);
uiItemO(column, NULL, ICON_NONE, "NLA_OT_action_sync_length");
/* action usage */
column = uiLayoutColumn(layout, TRUE);
uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_time") == FALSE);
- uiItemL(column, "Playback Settings:", ICON_NONE);
+ uiItemL(column, IFACE_("Playback Settings:"), ICON_NONE);
uiItemR(column, &strip_ptr, "scale", 0, NULL, ICON_NONE);
uiItemR(column, &strip_ptr, "repeat", 0, NULL, ICON_NONE);
}
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index fd999bf2476..acfb4a51b14 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -632,7 +632,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
for (ale = anim_data->first; ale; ale = ale->next) {
const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
- const float ydatac = (float)(y - 7);
+ const float ydatac = (float)(y - 0.35f * U.widget_unit);
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
@@ -716,7 +716,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
if (ale->id) {
/* special exception for textures */
if (GS(ale->id->name) == ID_TE) {
- offset = 14;
+ offset = 0.7f * U.widget_unit;
indent = 1;
}
/* special exception for nodetrees */
@@ -727,7 +727,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
case NTREE_SHADER:
{
/* same as for textures */
- offset = 14;
+ offset = 0.7f * U.widget_unit;
indent = 1;
}
break;
@@ -735,19 +735,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
case NTREE_TEXTURE:
{
/* even more */
- offset = 21;
+ offset = U.widget_unit;
indent = 1;
}
break;
default:
/* normal will do */
- offset = 14;
+ offset = 0.7f * U.widget_unit;
break;
}
}
else {
- offset = 14;
+ offset = 0.7f * U.widget_unit;
}
}
else {
@@ -779,7 +779,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
glColor4f(color[0], color[1], color[2], alpha);
}
- offset += 7 * indent;
+ offset += 0.35f * U.widget_unit * indent;
/* only on top two corners, to show that this channel sits on top of the preceding ones */
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
@@ -797,7 +797,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
UI_ThemeColorShade(TH_HEADER, ((nonSolo == 0) ? 20 : -20));
indent += group;
- offset += 7 * indent;
+ offset += 0.35f * U.widget_unit * indent;
glBegin(GL_QUADS);
glVertex2f(x + offset, yminc);
glVertex2f(x + offset, ymaxc);
@@ -809,14 +809,14 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
/* draw expand/collapse triangle */
if (expand > 0) {
UI_icon_draw(x + offset, ydatac, expand);
- offset += 17;
+ offset += 0.85f * U.widget_unit;
}
/* draw special icon indicating certain data-types */
if (special > -1) {
/* for normal channels */
UI_icon_draw(x + offset, ydatac, special);
- offset += 17;
+ offset += 0.85f * U.widget_unit;
}
glDisable(GL_BLEND);
@@ -837,19 +837,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
/* draw protect 'lock' */
if (protect > -1) {
- offset = 16;
+ offset = 0.8f * U.widget_unit;
UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, protect);
}
/* draw mute 'eye' */
if (mute > -1) {
- offset += 16;
+ offset += 0.8f * U.widget_unit;
UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, mute);
}
/* draw NLA-action line 'status-icons' - only when there's an action */
if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) {
- offset += 16;
+ offset += 0.8f * U.widget_unit;
/* now draw some indicator icons */
if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
@@ -862,7 +862,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
fdrawline((float)(v2d->cur.xmax - offset), yminc,
(float)(v2d->cur.xmax - offset), ymaxc);
- offset += 16;
+ offset += 0.8f * U.widget_unit;
/* 'tweaking action' indicator - not a button */
UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, ICON_EDIT);
@@ -870,11 +870,11 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
else {
/* XXX firstly draw a little rect to help identify that it's different from the toggles */
glBegin(GL_LINE_LOOP);
- glVertex2f((float)v2d->cur.xmax - offset - 1, y - 7);
- glVertex2f((float)v2d->cur.xmax - offset - 1, y + 9);
- glVertex2f((float)v2d->cur.xmax - 1, y + 9);
- glVertex2f((float)v2d->cur.xmax - 1, y - 7);
- glEnd(); // GL_LINES
+ glVertex2f((float)v2d->cur.xmax - offset - 1, y - 0.35f * U.widget_unit);
+ glVertex2f((float)v2d->cur.xmax - offset - 1, y + 0.45f * U.widget_unit);
+ glVertex2f((float)v2d->cur.xmax - 1, y + 0.45f * U.widget_unit);
+ glVertex2f((float)v2d->cur.xmax - 1, y - 0.35f * U.widget_unit);
+ glEnd();
/* 'push down' icon for normal active-actions */
UI_icon_draw((float)v2d->cur.xmax - offset, ydatac, ICON_FREEZE);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 3740c3fae5e..484eb47fa8e 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -44,6 +44,8 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_action.h"
#include "BKE_fcurve.h"
#include "BKE_nla.h"
@@ -1951,7 +1953,7 @@ static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
uiLayout *layout;
int i;
- pup = uiPupMenuBegin(C, "Add F-Modifier", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Add F-Modifier"), ICON_NONE);
layout = uiPupMenuLayout(pup);
/* start from 1 to skip the 'Invalid' modifier type */
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index 996c6fb530f..3803f899ccc 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SRC
node_relationships.c
node_select.c
node_templates.c
+ node_toolbar.c
node_view.c
space_node.c
diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript
index 7e311b1329d..70837fa766a 100644
--- a/source/blender/editors/space_node/SConscript
+++ b/source/blender/editors/space_node/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 92edac356e6..b211bca4c0a 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -123,10 +123,10 @@ static void node_socket_button_string(const bContext *C, uiBlock *block,
float slen;
UI_ThemeColor(TH_TEXT);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect; /* XXX, check for dpis */
while (slen > (width * 0.5f) && *ui_name) {
ui_name = BLI_str_find_next_char_utf8(ui_name, NULL);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect;
}
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr);
@@ -208,7 +208,7 @@ static void node_socket_button_color(const bContext *C, uiBlock *block,
bt = uiDefButR(block, COLOR, B_NODE_EXEC, "",
x, y + 2, (labelw > 0 ? 40 : width), NODE_DY - 2,
- &ptr, "default_value", 0, 0, 0, -1, -1, NULL);
+ &ptr, "default_value", -1, 0, 0, -1, -1, NULL);
if (node)
uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node);
@@ -229,19 +229,18 @@ static void node_draw_input_default(const bContext *C, uiBlock *block,
node_socket_button_label(C, block, ntree, node, sock, IFACE_(name), x, y, width);
}
-static void node_draw_output_default(const bContext *C, uiBlock *block,
+static void node_draw_output_default(const bContext *UNUSED(C), uiBlock *block,
bNodeTree *UNUSED(ntree), bNode *node, bNodeSocket *sock,
const char *name, int UNUSED(x), int UNUSED(y), int UNUSED(width))
{
- SpaceNode *snode = CTX_wm_space_node(C);
const char *ui_name = IFACE_(name);
float slen;
UI_ThemeColor(TH_TEXT);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
- while (slen > node->width && *ui_name) {
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) ;
+ while (slen > NODE_WIDTH(node) && *ui_name) {
ui_name = BLI_str_find_next_char_utf8(ui_name, NULL);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X);
}
if (*ui_name) {
@@ -400,8 +399,8 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNodeTree *ntree = (bNodeTree*)ptr->id.data;
- bNode *node = (bNode*)ptr->data;
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
bNodeSocket *sock = node->outputs.first; /* first socket stores normal */
PointerRNA sockptr;
@@ -509,14 +508,14 @@ static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode)
bNodeSocket *sock, *gsock;
float locx, locy;
rctf *rect = &gnode->totr;
- const float dpi_fac = UI_DPI_ICON_FAC;
+ const float dpi_fac = UI_DPI_FAC;
const float node_group_frame = NODE_GROUP_FRAME * dpi_fac;
const float group_header = 26 * dpi_fac;
int counter;
int dy;
/* get "global" coords */
- nodeToView(gnode, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(gnode, 0.0f, 0.0f, &locx, &locy);
/* center them, is a bit of abuse of locx and locy though */
node_update_nodetree(C, ngroup, locx, locy);
@@ -688,7 +687,7 @@ static void draw_group_socket_name(SpaceNode *snode, bNode *gnode, bNodeSocket *
static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *ntree, bNode *gnode,
bNodeSocket *sock, bNodeSocket *gsock, int index, int in_out)
{
- const float dpi_fac = UI_DPI_ICON_FAC;
+ const float dpi_fac = 1.0f;
bNodeTree *ngroup = (bNodeTree *)gnode->id;
bNodeSocketType *stype = ntreeGetSocketType(gsock ? gsock->type : sock->type);
uiBut *bt;
@@ -800,7 +799,7 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN
uiLayout *layout;
PointerRNA ptr;
rctf rect = gnode->totr;
- const float dpi_fac = UI_DPI_ICON_FAC;
+ const float dpi_fac = 1.0f;
const float node_group_frame = NODE_GROUP_FRAME * dpi_fac;
const float group_header = 26 * dpi_fac;
@@ -925,7 +924,7 @@ static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
*/
static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
{
- const float margin = 30.0f;
+ const float margin = 1.5f * U.widget_unit;
NodeFrame *data = (NodeFrame *)node->storage;
int bbinit;
bNode *tnode;
@@ -933,8 +932,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode
float xmax, ymax;
/* init rect from current frame size */
- nodeToView(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
- nodeToView(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
+ node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
+ node_to_view(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
/* frame can be resized manually only if shrinking is disabled or no children are attached */
data->flag |= NODE_FRAME_RESIZEABLE;
@@ -963,8 +962,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode
}
/* now adjust the frame size from view-space bounding box */
- nodeFromView(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
- nodeFromView(node, rect.xmax, rect.ymin, &xmax, &ymax);
+ node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
+ node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax);
node->width = xmax - node->offsetx;
node->height = -ymax + node->offsety;
@@ -1101,7 +1100,7 @@ static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntr
float size = NODE_REROUTE_SIZE;
/* get "global" coords */
- nodeToView(node, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(node, 0.0f, 0.0f, &locx, &locy);
/* reroute node has exactly one input and one output, both in the same place */
nsock = node->outputs.first;
@@ -1122,8 +1121,10 @@ static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntr
static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(snode), bNodeTree *ntree, bNode *node)
{
bNodeSocket *sock;
-#if 0 /* UNUSED */
+ char showname[128]; /* 128 used below */
rctf *rct = &node->totr;
+
+#if 0 /* UNUSED */
float size = NODE_REROUTE_SIZE;
#endif
float socket_size = NODE_SOCKSIZE;
@@ -1164,6 +1165,15 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
}
#endif
+ if (node->label[0] != '\0') {
+ /* draw title (node label) */
+ BLI_strncpy(showname, node->label, sizeof(showname));
+ uiDefBut(node->block, LABEL, 0, showname,
+ (int)(rct->xmin - NODE_DYS), (int)(rct->ymax),
+ (short)512, (short)NODE_DY,
+ NULL, 0, 0, 0, 0, NULL);
+ }
+
/* only draw input socket. as they all are placed on the same position.
* highlight also if node itself is selected, since we don't display the node body separately!
*/
@@ -1351,7 +1361,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
- node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr);
+ node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr);
}
static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1933,9 +1943,9 @@ static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), Po
static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "type", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE);
- switch (RNA_enum_get(ptr, "type")) {
+ switch (RNA_enum_get(ptr, "mode")) {
case CMP_NODE_DILATEERODE_DISTANCE_THRESH:
uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE);
break;
@@ -1973,7 +1983,7 @@ static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED
uiLayout *col, *row;
col = uiLayoutColumn(layout, TRUE);
-
+
uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
row = uiLayoutRow(layout, FALSE);
uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -2153,12 +2163,12 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C
active_index = RNA_int_get(ptr, "active_input_index");
/* using different collection properties if multilayer format is enabled */
if (multilayer) {
- uiTemplateList(col, C, ptr, "layer_slots", ptr, "active_input_index", NULL, 0, 0, 0);
+ uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "layer_slots", ptr, "active_input_index", 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, ptr, "file_slots", ptr, "active_input_index", NULL, 0, 0, 0);
+ uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "file_slots", ptr, "active_input_index", 0, 0, 0);
RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"),
active_index, &active_input_ptr);
}
@@ -2369,6 +2379,12 @@ static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, Pointe
uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
}
+static void node_composit_buts_translate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "use_relative", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "wrap_axis", 0, NULL, ICON_NONE);
+}
+
static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
@@ -2638,10 +2654,21 @@ static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C)
uiItemR(layout, ptr, "mask_type", 0, NULL, ICON_NONE);
}
+static void node_composit_buts_composite(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
+}
+
+static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
+}
+
static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
+ uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "tile_order", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "tile_order") == 0) {
col = uiLayoutColumn(layout, TRUE);
@@ -2921,6 +2948,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_TRANSFORM:
ntype->uifunc = node_composit_buts_transform;
break;
+ case CMP_NODE_TRANSLATE:
+ ntype->uifunc = node_composit_buts_translate;
+ break;
case CMP_NODE_MOVIEDISTORTION:
ntype->uifunc = node_composit_buts_moviedistortion;
break;
@@ -2946,10 +2976,13 @@ static void node_composit_set_butfunc(bNodeType *ntype)
ntype->uifunc = node_composit_buts_bokehblur;
break;
case CMP_NODE_VIEWER:
- ntype->uifunc = NULL;
+ ntype->uifunc = node_composit_buts_viewer;
ntype->uifuncbut = node_composit_buts_viewer_but;
ntype->uibackdropfunc = node_composit_backdrop_viewer;
break;
+ case CMP_NODE_COMPOSITE:
+ ntype->uifunc = node_composit_buts_composite;
+ break;
case CMP_NODE_MASK:
ntype->uifunc = node_composit_buts_mask;
break;
@@ -3272,7 +3305,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
}
else {
glPixelZoom(snode->zoom, snode->zoom);
-
+
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
glPixelZoom(1.0f, 1.0f);
@@ -3417,10 +3450,10 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa
vec[2][0] = vec[3][0] - dist;
vec[2][1] = vec[3][1];
}
- if (v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
+ if (v2d && min_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
/* clipped */
}
- else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
+ else if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
/* clipped */
}
else {
@@ -3532,7 +3565,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
glDisable(GL_LINE_SMOOTH);
/* restore previuos linewidth */
- glLineWidth(linew);
+ glLineWidth(1.0f);
}
}
@@ -3618,7 +3651,7 @@ void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link,
glDisable(GL_LINE_SMOOTH);
/* restore previuos linewidth */
- glLineWidth(linew);
+ glLineWidth(1.0f);
}
#endif
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 96ac716f383..22631568d03 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -76,10 +76,14 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene,
if (node) {
node_select(node);
+ /* node location is mapped */
+ locx /= UI_DPI_FAC;
+ locy /= UI_DPI_FAC;
+
gnode = node_tree_get_editgroup(snode->nodetree);
// arbitrary y offset of 60 so its visible
if (gnode) {
- nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy);
+ node_from_view(gnode, locx, locy + 60.0f, &node->locx, &node->locy);
}
else {
node->locx = locx;
@@ -203,7 +207,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi
}
add_v2_v2(insert_point, socklink->point);
- ++num_links;
+ num_links++;
}
socklink = socklink->next;
}
@@ -215,7 +219,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi
mul_v2_fl(insert_point, 1.0f / num_links);
if (gnode) {
- nodeFromView(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy);
+ node_from_view(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy);
}
else {
reroute_node->locx = insert_point[0];
@@ -301,7 +305,7 @@ void NODE_OT_add_reroute(wmOperatorType *ot)
{
PropertyRNA *prop;
- ot->name = "Add reroute";
+ ot->name = "Add Reroute";
ot->idname = "NODE_OT_add_reroute";
ot->invoke = WM_gesture_lines_invoke;
@@ -437,6 +441,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode;
bNodeTree *ntree;
+ Main *bmain;
PointerRNA ptr, idptr;
PropertyRNA *prop;
int treetype;
@@ -444,6 +449,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
/* retrieve state */
snode = CTX_wm_space_node(C);
+ bmain = CTX_data_main(C);
if (RNA_struct_property_is_set(op->ptr, "type"))
treetype = RNA_enum_get(op->ptr, "type");
@@ -453,7 +459,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
if (RNA_struct_property_is_set(op->ptr, "name"))
RNA_string_get(op->ptr, "name", treename);
- ntree = ntreeAddTree(treename, treetype, 0);
+ ntree = ntreeAddTree(bmain, treename, treetype, 0);
if (!ntree)
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index da077d93641..300328f5fd4 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -184,6 +184,7 @@ void node_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil");
strcpy(pt->idname, "NODE_PT_gpencil");
strcpy(pt->label, "Grease Pencil");
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
pt->poll = active_nodetree_poll;
BLI_addtail(&art->paneltypes, pt);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 72461cfb2a8..34f7799d47c 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -278,6 +278,21 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
}
}
+void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry)
+{
+ nodeToView(node, x, y, rx, ry);
+ *rx *= UI_DPI_FAC;
+ *ry *= UI_DPI_FAC;
+}
+
+void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry)
+{
+ x /= UI_DPI_FAC;
+ y /= UI_DPI_FAC;
+ nodeFromView(node, x, y, rx, ry);
+}
+
+
/* based on settings in node, sets drawing rect info. each redraw! */
static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
{
@@ -289,7 +304,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
int buty;
/* get "global" coords */
- nodeToView(node, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(node, 0.0f, 0.0f, &locx, &locy);
dy = locy;
/* header */
@@ -302,14 +317,14 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* output sockets */
for (nsock = node->outputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
- nsock->locx = locx + node->width;
+ nsock->locx = locx + NODE_WIDTH(node);
nsock->locy = dy - NODE_DYS;
dy -= NODE_DY;
}
}
node->prvr.xmin = locx + NODE_DYS;
- node->prvr.xmax = locx + node->width - NODE_DYS;
+ node->prvr.xmax = locx + NODE_WIDTH(node) - NODE_DYS;
/* preview rect? */
if (node->flag & NODE_PREVIEW) {
@@ -323,12 +338,13 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
node->prvr.ymax = dy;
if (aspect <= 1.0f)
- node->prvr.ymin = dy - aspect * (node->width - NODE_DY);
+ node->prvr.ymin = dy - aspect * (NODE_WIDTH(node) - NODE_DY);
else {
/* width correction of image */
- float dx = (node->width - NODE_DYS) - (node->width - NODE_DYS) / aspect;
+ /* XXX huh? (ton) */
+ float dx = (NODE_WIDTH(node) - NODE_DYS) - (NODE_WIDTH(node) - NODE_DYS) / aspect;
- node->prvr.ymin = dy - (node->width - NODE_DY);
+ node->prvr.ymin = dy - (NODE_WIDTH(node) - NODE_DY);
node->prvr.xmin += 0.5f * dx;
node->prvr.xmax -= 0.5f * dx;
@@ -343,7 +359,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
else {
float oldh = BLI_rctf_size_y(&node->prvr);
if (oldh == 0.0f)
- oldh = 0.6f * node->width - NODE_DY;
+ oldh = 0.6f * NODE_WIDTH(node) - NODE_DY;
dy -= NODE_DYS / 2;
node->prvr.ymax = dy;
node->prvr.ymin = dy - oldh;
@@ -352,26 +368,28 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
}
/* buttons rect? */
- if ((node->flag & NODE_OPTIONS) && node->typeinfo->uifunc) {
+ /* TODO: NODE_OPTION shall be cleaned up */
+ if (/*(node->flag & NODE_OPTIONS) && */node->typeinfo->uifunc) {
dy -= NODE_DYS / 2;
/* set this for uifunc() that don't use layout engine yet */
node->butr.xmin = 0;
- node->butr.xmax = node->width - 2 * NODE_DYS;
+ node->butr.xmax = NODE_WIDTH(node) - 2 * NODE_DYS;
node->butr.ymin = 0;
node->butr.ymax = 0;
RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
+
layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
- locx + NODE_DYS, dy, node->butr.xmax, NODE_DY, UI_GetStyle());
+ locx + NODE_DYS, dy, node->butr.xmax, 0, UI_GetStyle());
uiLayoutSetContextPointer(layout, "node", &ptr);
node->typeinfo->uifunc(layout, (bContext *)C, &ptr);
uiBlockEndAlign(node->block);
uiBlockLayoutResolve(node->block, NULL, &buty);
-
+
dy = buty - NODE_DYS / 2;
}
@@ -389,7 +407,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
dy -= NODE_DYS / 2;
node->totr.xmin = locx;
- node->totr.xmax = locx + node->width;
+ node->totr.xmax = locx + NODE_WIDTH(node);
node->totr.ymax = locy;
node->totr.ymin = min_ff(dy, locy - 2 * NODE_DY);
@@ -412,7 +430,7 @@ static void node_update_hidden(bNode *node)
int totin = 0, totout = 0, tot;
/* get "global" coords */
- nodeToView(node, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(node, 0.0f, 0.0f, &locx, &locy);
/* calculate minimal radius */
for (nsock = node->inputs.first; nsock; nsock = nsock->next)
@@ -437,8 +455,8 @@ static void node_update_hidden(bNode *node)
for (nsock = node->outputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
- nsock->locx = node->totr.xmax - hiddenrad + (float)sin(rad) * hiddenrad;
- nsock->locy = node->totr.ymin + hiddenrad + (float)cos(rad) * hiddenrad;
+ nsock->locx = node->totr.xmax - hiddenrad + sinf(rad) * hiddenrad;
+ nsock->locy = node->totr.ymin + hiddenrad + cosf(rad) * hiddenrad;
rad += drad;
}
}
@@ -448,8 +466,8 @@ static void node_update_hidden(bNode *node)
for (nsock = node->inputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
- nsock->locx = node->totr.xmin + hiddenrad + (float)sin(rad) * hiddenrad;
- nsock->locy = node->totr.ymin + hiddenrad + (float)cos(rad) * hiddenrad;
+ nsock->locx = node->totr.xmin + hiddenrad + sinf(rad) * hiddenrad;
+ nsock->locy = node->totr.ymin + hiddenrad + cosf(rad) * hiddenrad;
rad += drad;
}
}
@@ -484,21 +502,18 @@ int node_tweak_area_default(bNode *node, int x, int y)
int node_get_colorid(bNode *node)
{
- if (node->typeinfo->nclass == NODE_CLASS_INPUT)
- return TH_NODE_IN_OUT;
- if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
- if (node->flag & NODE_DO_OUTPUT)
- return TH_NODE_IN_OUT;
- else
- return TH_NODE;
+ switch (node->typeinfo->nclass) {
+ case NODE_CLASS_INPUT: return TH_NODE_IN_OUT;
+ case NODE_CLASS_OUTPUT: return (node->flag & NODE_DO_OUTPUT) ? TH_NODE_IN_OUT : TH_NODE;
+ case NODE_CLASS_CONVERTOR: return TH_NODE_CONVERTOR;
+ case NODE_CLASS_OP_COLOR:
+ case NODE_CLASS_OP_VECTOR:
+ case NODE_CLASS_OP_FILTER: return TH_NODE_OPERATOR;
+ case NODE_CLASS_GROUP: return TH_NODE_GROUP;
+ case NODE_CLASS_MATTE: return TH_NODE_MATTE;
+ case NODE_CLASS_DISTORT: return TH_NODE_DISTORT;
+ default: return TH_NODE;
}
- if (node->typeinfo->nclass == NODE_CLASS_CONVERTOR)
- return TH_NODE_CONVERTOR;
- if (ELEM3(node->typeinfo->nclass, NODE_CLASS_OP_COLOR, NODE_CLASS_OP_VECTOR, NODE_CLASS_OP_FILTER))
- return TH_NODE_OPERATOR;
- if (node->typeinfo->nclass == NODE_CLASS_GROUP)
- return TH_NODE_GROUP;
- return TH_NODE;
}
/* note: in cmp_util.c is similar code, for node_compo_pass_on()
@@ -687,6 +702,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
if (node->flag & NODE_MUTED)
UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
+
#ifdef WITH_COMPOSITOR
if (ntree->type == NTREE_COMPOSIT && (snode->flag & SNODE_SHOW_HIGHLIGHT)) {
@@ -700,7 +716,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
uiRoundBox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
/* show/hide icons */
- iconofs = rct->xmax - 7.0f;
+ iconofs = rct->xmax - 0.35f * U.widget_unit;
/* preview */
if (node->typeinfo->flag & NODE_PREVIEW) {
@@ -742,13 +758,13 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* 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, "",
- rct->xmin + 10.0f - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2,
+ 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);
/* custom draw function for this button */
- UI_DrawTriIcon(rct->xmin + 10.0f, rct->ymax - NODE_DY / 2.0f, 'v');
+ UI_DrawTriIcon(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 */
@@ -765,7 +781,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
uiDefBut(node->block, LABEL, 0, showname,
- (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(rct->ymax - NODE_DY),
+ (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, "");
@@ -781,6 +797,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* outline active and selected emphasis */
if (node->flag & SELECT) {
+
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
@@ -788,6 +805,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
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);
@@ -808,8 +826,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT);
node->typeinfo->drawinputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name),
- sock->locx + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS,
- node->width - NODE_DY);
+ sock->locx + (NODE_DYS), sock->locy - NODE_DYS,
+ NODE_WIDTH(node) - NODE_DY);
}
/* socket outputs */
@@ -820,8 +838,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT);
node->typeinfo->drawoutputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name),
- sock->locx - node->width + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS,
- node->width - NODE_DY);
+ sock->locx - NODE_WIDTH(node) + (NODE_DYS), sock->locy - NODE_DYS,
+ NODE_WIDTH(node) - NODE_DY);
}
/* preview */
@@ -843,7 +861,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
rctf *rct = &node->totr;
float dx, centy = BLI_rctf_cent_y(rct);
float hiddenrad = BLI_rctf_size_y(rct) / 2.0f;
- float socket_size = NODE_SOCKSIZE * UI_DPI_ICON_FAC;
+ float socket_size = NODE_SOCKSIZE;
int color_id = node_get_colorid(node);
char showname[128]; /* 128 is used below */
@@ -920,7 +938,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
uiDefBut(node->block, LABEL, 0, showname,
- (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(centy - 10),
+ (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, "");
}
@@ -1011,7 +1029,7 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree, float offsetx, fl
/* update nodes front to back, so children sizes get updated before parents */
for (node = ntree->nodes.last; node; node = node->prev) {
- /* XXX little hack */
+ /* XXX little hack (not used anyore?) */
node->locx += offsetx;
node->locy += offsety;
@@ -1082,7 +1100,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLinkDrag *nldrag;
LinkData *linkdata;
-
+
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
@@ -1098,11 +1116,10 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
/* aspect+font, set each time */
snode->aspect = BLI_rctf_size_x(&v2d->cur) / (float)ar->winx;
- snode->aspect_sqrt = sqrtf(snode->aspect);
// XXX snode->curfont = uiSetCurFont_ext(snode->aspect);
/* grid */
- UI_view2d_multi_grid_draw(v2d, 25.0f, 5, 2);
+ UI_view2d_multi_grid_draw(v2d, U.widget_unit, 5, 2);
/* backdrop */
draw_nodespace_back_pix(C, ar, snode);
@@ -1156,16 +1173,22 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
- /* draw grease-pencil ('canvas' strokes) */
- if (snode->nodetree)
- draw_gpencil_view2d(C, 1);
+ if (snode->flag & SNODE_SHOW_GPENCIL) {
+ /* draw grease-pencil ('canvas' strokes) */
+ if (snode->nodetree) {
+ draw_gpencil_view2d(C, TRUE);
+ }
+ }
/* reset view matrix */
UI_view2d_view_restore(C);
- /* draw grease-pencil (screen strokes, and also paintbuffer) */
- if (snode->nodetree)
- draw_gpencil_view2d(C, 0);
+ if (snode->flag & SNODE_SHOW_GPENCIL) {
+ /* draw grease-pencil (screen strokes, and also paintbuffer) */
+ if (snode->nodetree) {
+ draw_gpencil_view2d(C, FALSE);
+ }
+ }
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index f757345bdcb..fb4e4f62e52 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -328,7 +328,7 @@ void ED_node_shader_default(Scene *scene, ID *id)
int output_type, shader_type;
float color[3], strength = 1.0f;
- ntree = ntreeAddTree("Shader Nodetree", NTREE_SHADER, 0);
+ ntree = ntreeAddTree(G.main, "Shader Nodetree", NTREE_SHADER, 0);
switch (GS(id->name)) {
case ID_MA:
@@ -424,7 +424,7 @@ void ED_node_composit_default(Scene *sce)
return;
}
- sce->nodetree = ntreeAddTree("Compositing Nodetree", NTREE_COMPOSIT, 0);
+ sce->nodetree = ntreeAddTree(G.main, "Compositing Nodetree", NTREE_COMPOSIT, 0);
sce->nodetree->chunksize = 256;
sce->nodetree->edit_quality = NTREE_QUALITY_HIGH;
@@ -468,7 +468,7 @@ void ED_node_texture_default(Tex *tx)
return;
}
- tx->nodetree = ntreeAddTree("Texture Nodetree", NTREE_TEXTURE, 0);
+ tx->nodetree = ntreeAddTree(G.main, "Texture Nodetree", NTREE_TEXTURE, 0);
ntemp.type = TEX_NODE_OUTPUT;
out = nodeAddNode(tx->nodetree, &ntemp);
@@ -550,6 +550,12 @@ void snode_set_context(SpaceNode *snode, Scene *scene)
snode->id = snode->from = NULL;
if (snode->treetype == NTREE_SHADER) {
+ /* we use this to signal warnings, when node shaders are drawn in wrong render engine */
+ if (BKE_scene_use_new_shading_nodes(scene))
+ snode->flag |= SNODE_NEW_SHADERS;
+ else
+ snode->flag &= ~SNODE_NEW_SHADERS;
+
/* need active object, or we allow pinning... */
if (snode->shaderfrom == SNODE_SHADER_OBJECT) {
if (ob) {
@@ -874,8 +880,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
case MOUSEMOVE:
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
- dx = mx - nsw->mxstart;
- dy = my - nsw->mystart;
+ dx = (mx - nsw->mxstart) / UI_DPI_FAC;
+ dy = (my - nsw->mystart) / UI_DPI_FAC;
if (node) {
if (node->flag & NODE_HIDDEN) {
@@ -894,8 +900,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
}
}
else {
- float widthmin = UI_DPI_FAC * node->typeinfo->minwidth;
- float widthmax = UI_DPI_FAC * node->typeinfo->maxwidth;
+ float widthmin = node->typeinfo->minwidth;
+ float widthmax = node->typeinfo->maxwidth;
if (nsw->directions & NODE_RESIZE_RIGHT) {
node->width = nsw->oldwidth + dx;
CLAMP(node->width, widthmin, widthmax);
@@ -1743,7 +1749,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
void NODE_OT_delete_reconnect(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Delete with reconnect";
+ ot->name = "Delete with Reconnect";
ot->description = "Delete nodes; will reconnect nodes as if deletion was muted";
ot->idname = "NODE_OT_delete_reconnect";
@@ -1967,7 +1973,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
/* get group node offset */
if (gnode)
- nodeToView(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y);
+ node_to_view(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y);
for (node = ntree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
@@ -2025,7 +2031,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
void NODE_OT_clipboard_copy(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Copy to clipboard";
+ ot->name = "Copy to Clipboard";
ot->description = "Copies selected nodes to the clipboard";
ot->idname = "NODE_OT_clipboard_copy";
@@ -2080,7 +2086,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* get group node offset */
if (gnode) {
- nodeToView(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]);
+ node_to_view(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]);
}
else {
zero_v2(gnode_center);
@@ -2146,7 +2152,7 @@ static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, wmEvent *eve
void NODE_OT_clipboard_paste(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Paste from clipboard";
+ ot->name = "Paste from Clipboard";
ot->description = "Pastes nodes from the clipboard to the active node tree";
ot->idname = "NODE_OT_clipboard_paste";
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 4dd9c89375d..7b7b98f132c 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -42,6 +42,8 @@
#include "BLI_rect.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_action.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
@@ -457,8 +459,10 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
/* ensure unique node name in the nodee tree */
nodeUniqueName(ntree, node);
- node->locx += gnode->locx;
- node->locy += gnode->locy;
+ if (!node->parent) {
+ node->locx += gnode->locx;
+ node->locy += gnode->locy;
+ }
node->flag |= NODE_SELECT;
}
@@ -673,8 +677,10 @@ static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make
/* ensure unique node name in the node tree */
nodeUniqueName(ntree, newnode);
- newnode->locx += gnode->locx;
- newnode->locy += gnode->locy;
+ if (!newnode->parent) {
+ newnode->locx += gnode->locx;
+ newnode->locy += gnode->locy;
+ }
}
else {
/* ensure valid parent pointers, detach if child stays inside the group */
@@ -785,7 +791,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
{
- uiPopupMenu *pup = uiPupMenuBegin(C, "Separate", ICON_NONE);
+ uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
@@ -865,12 +871,14 @@ static int node_group_make_test(bNodeTree *ntree, bNode *gnode)
static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max)
{
bNode *node;
+ float loc[2];
INIT_MINMAX2(min, max);
for (node = ntree->nodes.first; node; node = node->next) {
if (node == gnode)
continue;
if (node->flag & NODE_SELECT) {
- minmax_v2v2_v2(min, max, &node->locx);
+ nodeToView(node, 0.0f, 0.0f, &loc[0], &loc[1]);
+ minmax_v2v2_v2(min, max, loc);
}
}
}
@@ -921,8 +929,10 @@ static int node_group_make_insert_selected(bNodeTree *ntree, bNode *gnode)
/* ensure unique node name in the ngroup */
nodeUniqueName(ngroup, node);
- node->locx -= 0.5f * (min[0] + max[0]);
- node->locy -= 0.5f * (min[1] + max[1]);
+ if (!node->parent) {
+ node->locx -= 0.5f * (min[0] + max[0]);
+ node->locy -= 0.5f * (min[1] + max[1]);
+ }
}
else {
/* if the parent is to be inserted but not the child, detach properly */
@@ -1039,7 +1049,7 @@ static bNode *node_group_make_from_selected(bNodeTree *ntree)
node_get_selected_minmax(ntree, NULL, min, max);
/* new nodetree */
- ngroup = ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);
+ ngroup = ntreeAddTree(G.main, "NodeGroup", ntree->type, NODE_GROUP);
/* make group node */
ntemp.type = NODE_GROUP;
@@ -1140,7 +1150,7 @@ static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *act = nodeGetActive(snode->edittree);
- uiPopupMenu *pup = uiPupMenuBegin(C, "Make Group", ICON_NONE);
+ uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Group"), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c
index e82917feb21..f26b6ff0f54 100644
--- a/source/blender/editors/space_node/node_header.c
+++ b/source/blender/editors/space_node/node_header.c
@@ -136,7 +136,7 @@ static void do_node_add_group(bContext *C, void *UNUSED(arg), int event)
ntemp.type = -event;
switch (ntemp.type) {
case NODE_GROUP:
- ntemp.ngroup = ntreeAddTree("Group", snode->treetype, ntemp.type);
+ ntemp.ngroup = ntreeAddTree(bmain, "Group", snode->treetype, ntemp.type);
break;
default:
ntemp.ngroup = NULL;
@@ -234,7 +234,7 @@ static void node_menu_add(const bContext *C, Menu *menu)
uiLayoutSetActive(layout, FALSE);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
- uiItemO(layout, "Search ...", 0, "NODE_OT_add_search");
+ uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Search ..."), 0, "NODE_OT_add_search");
if (ntreetype && ntreetype->foreach_nodeclass)
ntreetype->foreach_nodeclass(scene, layout, node_menu_add_foreach_cb);
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 45509e02226..e8dd1cf1528 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -48,6 +48,7 @@ struct bNode;
struct bNodeSocket;
struct bNodeLink;
struct Main;
+struct wmKeyConfig;
/* temp data to pass on to modal */
typedef struct bNodeLinkDrag {
@@ -63,6 +64,7 @@ typedef struct bNodeLinkDrag {
/* space_node.c */
ARegion *node_has_buttons_region(ScrArea *sa);
+ARegion *node_has_tools_region(ScrArea *sa);
/* node_header.c */
void node_menus_register(void);
@@ -81,14 +83,21 @@ void node_draw_nodetree(const struct bContext *C, struct ARegion *ar, struct Spa
void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode);
+ /* DPI scaled coords */
+void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry);
+void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry);
/* node_buttons.c */
void node_buttons_register(struct ARegionType *art);
void NODE_OT_properties(struct wmOperatorType *ot);
+/* node_toolbar.c */
+void node_toolbar_register(struct ARegionType *art);
+void NODE_OT_toolbar(struct wmOperatorType *ot);
+
/* node_ops.c */
void node_operatortypes(void);
-void node_keymap(wmKeyConfig *keyconf);
+void node_keymap(struct wmKeyConfig *keyconf);
/* node_select.c */
void node_select(struct bNode *node);
@@ -103,14 +112,14 @@ int node_select_same_type_np(struct SpaceNode *snode, int dir);
void node_select_single(struct bContext *C, struct bNode *node);
void NODE_OT_select(struct wmOperatorType *ot);
-void NODE_OT_select_all(wmOperatorType *ot);
-void NODE_OT_select_linked_to(wmOperatorType *ot);
-void NODE_OT_select_linked_from(wmOperatorType *ot);
+void NODE_OT_select_all(struct wmOperatorType *ot);
+void NODE_OT_select_linked_to(struct wmOperatorType *ot);
+void NODE_OT_select_linked_from(struct wmOperatorType *ot);
void NODE_OT_select_border(struct wmOperatorType *ot);
void NODE_OT_select_lasso(struct wmOperatorType *ot);
void NODE_OT_select_same_type(struct wmOperatorType *ot);
-void NODE_OT_select_same_type_next(wmOperatorType *ot);
-void NODE_OT_select_same_type_prev(wmOperatorType *ot);
+void NODE_OT_select_same_type_next(struct wmOperatorType *ot);
+void NODE_OT_select_same_type_prev(struct wmOperatorType *ot);
/* node_view.c */
void NODE_OT_view_all(struct wmOperatorType *ot);
@@ -118,14 +127,14 @@ void NODE_OT_view_selected(struct wmOperatorType *ot);
void NODE_OT_backimage_move(struct wmOperatorType *ot);
void NODE_OT_backimage_zoom(struct wmOperatorType *ot);
-void NODE_OT_backimage_sample(wmOperatorType *ot);
+void NODE_OT_backimage_sample(struct wmOperatorType *ot);
/* drawnode.c */
-void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link);
-void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3);
-int node_link_bezier_points(View2D * v2d, SpaceNode * snode, bNodeLink * link, float coord_array[][2], int resol);
+void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link);
+void node_draw_link_bezier(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3);
+int node_link_bezier_points(struct View2D * v2d, struct SpaceNode * snode, struct bNodeLink * link, float coord_array[][2], int resol);
// void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 );
-void draw_nodespace_back_pix(const struct bContext *C, ARegion *ar, SpaceNode *snode);
+void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode);
/* node_add.c */
@@ -167,10 +176,10 @@ void NODE_OT_link_viewer(struct wmOperatorType *ot);
/* node_edit.c */
void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype);
-void snode_notify(bContext *C, SpaceNode *snode);
-void snode_dag_update(bContext *C, SpaceNode *snode);
-void snode_set_context(SpaceNode *snode, Scene *scene);
-void snode_make_group_editable(SpaceNode *snode, bNode *gnode);
+void snode_notify(struct bContext *C, struct SpaceNode *snode);
+void snode_dag_update(struct bContext *C, struct SpaceNode *snode);
+void snode_set_context(struct SpaceNode *snode, Scene *scene);
+void snode_make_group_editable(struct SpaceNode *snode, struct bNode *gnode);
bNode *node_tree_get_editgroup(bNodeTree *ntree);
void snode_update(struct SpaceNode *snode, struct bNode *node);
@@ -179,7 +188,7 @@ int composite_node_active(struct bContext *C);
int node_has_hidden_sockets(bNode *node);
void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set);
-int node_render_changed_exec(bContext *, wmOperator *);
+int node_render_changed_exec(bContext *, struct wmOperator *);
int node_find_indicated_socket(struct SpaceNode *snode, struct bNode **nodep, struct bNodeSocket **sockp, int in_out);
void NODE_OT_duplicate(struct wmOperatorType *ot);
@@ -212,13 +221,14 @@ extern const char *node_context_dir[];
// XXXXXX
-// XXX from BSE_node.h
-#define HIDDEN_RAD 15.0f
-#define BASIS_RAD 8.0f
+// nodes draw without dpi - the view zoom is flexible
+#define HIDDEN_RAD (0.75f * U.widget_unit)
+#define BASIS_RAD (0.4f * U.widget_unit)
#define NODE_DYS (U.widget_unit / 2)
#define NODE_DY U.widget_unit
-#define NODE_MARGIN_X 15
-#define NODE_SOCKSIZE 5
+#define NODE_WIDTH(node) (node->width * UI_DPI_FAC)
+#define NODE_MARGIN_X (0.75f * U.widget_unit)
+#define NODE_SOCKSIZE (0.25f * U.widget_unit)
#define NODE_LINK_RESOL 12
// XXX button events (butspace)
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 64e5f67a348..8adccd9e6c4 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -49,6 +49,7 @@
void node_operatortypes(void)
{
WM_operatortype_append(NODE_OT_properties);
+ WM_operatortype_append(NODE_OT_toolbar);
WM_operatortype_append(NODE_OT_select);
WM_operatortype_append(NODE_OT_select_all);
@@ -204,6 +205,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Node Generic", SPACE_NODE, 0);
WM_keymap_add_item(keymap, "NODE_OT_properties", NKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_toolbar", TKEY, KM_PRESS, 0, 0);
/* Main Area only ----------------- */
keymap = WM_keymap_find(keyconf, "Node Editor", SPACE_NODE, 0);
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 7fa48c48ad6..8d7eef22822 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -876,7 +876,7 @@ void NODE_OT_links_cut(wmOperatorType *ot)
{
PropertyRNA *prop;
- ot->name = "Cut links";
+ ot->name = "Cut Links";
ot->idname = "NODE_OT_links_cut";
ot->description = "Use the mouse to cut (remove) some links";
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index a3efa15c54a..7d2b80d50ba 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -30,14 +30,14 @@
#include "DNA_node_types.h"
-#include "BKE_context.h"
-#include "BKE_main.h"
-#include "BKE_node.h"
-
#include "BLI_rect.h"
#include "BLI_lasso.h"
#include "BLI_utildefines.h"
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+
#include "ED_node.h" /* own include */
#include "ED_screen.h"
#include "ED_types.h"
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 23f4e948794..ca85415cb5a 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -30,6 +30,7 @@
#include "DNA_node_types.h"
#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -52,6 +53,8 @@
#include "ED_util.h"
+#include "node_intern.h"
+
/************************* Node Socket Manipulation **************************/
static void node_tag_recursive(bNode *node)
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c
new file mode 100644
index 00000000000..86da4009b17
--- /dev/null
+++ b/source/blender/editors/space_node/node_toolbar.c
@@ -0,0 +1,92 @@
+/*
+ * ***** 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) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_node/node_toolbar.c
+ * \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 */
+
+
+/* ******************* node toolbar registration ************** */
+
+void node_toolbar_register(ARegionType *UNUSED(art))
+{
+}
+
+/* ********** operator to open/close toolshelf region */
+
+static int node_toolbar(bContext *C, wmOperator *UNUSED(op))
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = node_has_tools_region(sa);
+
+ if (ar)
+ ED_region_toggle_hidden(C, ar);
+
+ return OPERATOR_FINISHED;
+}
+
+/* non-standard poll operator which doesn't care if there are any nodes */
+static int node_toolbar_poll(bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ return (sa && (sa->spacetype == SPACE_NODE));
+}
+
+void NODE_OT_toolbar(wmOperatorType *ot)
+{
+ ot->name = "Tool Shelf";
+ ot->description = "Toggles tool shelf display";
+ ot->idname = "NODE_OT_toolbar";
+
+ ot->exec = node_toolbar;
+ ot->poll = node_toolbar_poll;
+
+ /* flags */
+ ot->flag = 0;
+}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index f386657c460..a69e73c1489 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -69,12 +69,15 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons
bNode *node;
rctf cur_new;
float oldwidth, oldheight, width, height;
+ float oldasp, asp;
int tot = 0;
int has_frame = FALSE;
oldwidth = BLI_rctf_size_x(&ar->v2d.cur);
oldheight = BLI_rctf_size_y(&ar->v2d.cur);
+ oldasp = oldwidth / oldheight;
+
BLI_rctf_init_minmax(&cur_new);
if (snode->edittree) {
@@ -93,6 +96,7 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons
if (tot) {
width = BLI_rctf_size_x(&cur_new);
height = BLI_rctf_size_y(&cur_new);
+ asp = width / height;
/* for single non-frame nodes, don't zoom in, just pan view,
* but do allow zooming out, this allows for big nodes to be zoomed out */
@@ -104,18 +108,19 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons
BLI_rctf_resize(&cur_new, oldwidth, oldheight);
}
else {
- if (width > height) {
- float newheight;
- newheight = oldheight * width / oldwidth;
- cur_new.ymin = cur_new.ymin - newheight / 4;
- cur_new.ymax = cur_new.ymax + newheight / 4;
+ if (oldasp < asp) {
+ const float height_new = width / oldasp;
+ cur_new.ymin = cur_new.ymin - height_new / 2.0f;
+ cur_new.ymax = cur_new.ymax + height_new / 2.0f;
}
else {
- float newwidth;
- newwidth = oldwidth * height / oldheight;
- cur_new.xmin = cur_new.xmin - newwidth / 4;
- cur_new.xmax = cur_new.xmax + newwidth / 4;
+ const float width_new = height * oldasp;
+ cur_new.xmin = cur_new.xmin - width_new / 2.0f;
+ cur_new.xmax = cur_new.xmax + width_new / 2.0f;
}
+
+ /* add some padding */
+ BLI_rctf_scale(&cur_new, 1.1f);
}
UI_view2d_smooth_view(C, ar, &cur_new);
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index f7e0d51ea03..264bea5f871 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -85,6 +85,30 @@ ARegion *node_has_buttons_region(ScrArea *sa)
return arnew;
}
+ARegion *node_has_tools_region(ScrArea *sa)
+{
+ ARegion *ar, *arnew;
+
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
+ if (ar) return ar;
+
+ /* add subdiv level; after header */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+
+ /* is error! */
+ if (ar == NULL) return NULL;
+
+ arnew = MEM_callocN(sizeof(ARegion), "node tools");
+
+ BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+ arnew->regiontype = RGN_TYPE_TOOLS;
+ arnew->alignment = RGN_ALIGN_LEFT;
+
+ arnew->flag = RGN_FLAG_HIDDEN;
+
+ return arnew;
+}
+
/* ******************** default callbacks for node space ***************** */
static SpaceLink *node_new(const bContext *UNUSED(C))
@@ -95,6 +119,8 @@ static SpaceLink *node_new(const bContext *UNUSED(C))
snode = MEM_callocN(sizeof(SpaceNode), "initnode");
snode->spacetype = SPACE_NODE;
+ snode->flag = SNODE_SHOW_GPENCIL | SNODE_USE_ALPHA;
+
/* backdrop */
snode->zoom = 1.0f;
@@ -118,15 +144,12 @@ static SpaceLink *node_new(const bContext *UNUSED(C))
BLI_addtail(&snode->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.tot.xmin = -256.0f;
- ar->v2d.tot.ymin = -256.0f;
- ar->v2d.tot.xmax = 768.0f;
- ar->v2d.tot.ymax = 768.0f;
+ ar->v2d.tot.xmin = -12.8f * U.widget_unit;
+ ar->v2d.tot.ymin = -12.8f * U.widget_unit;
+ ar->v2d.tot.xmax = 38.4f * U.widget_unit;
+ ar->v2d.tot.ymax = 38.4f * U.widget_unit;
- ar->v2d.cur.xmin = -256.0f;
- ar->v2d.cur.ymin = -256.0f;
- ar->v2d.cur.xmax = 768.0f;
- ar->v2d.cur.ymax = 768.0f;
+ ar->v2d.cur = ar->v2d.tot;
ar->v2d.min[0] = 1.0f;
ar->v2d.min[1] = 1.0f;
@@ -342,6 +365,22 @@ static void node_buttons_area_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, 1, NULL, -1);
}
+/* add handlers, stuff you only do once or on area/region changes */
+static void node_toolbar_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ wmKeyMap *keymap;
+
+ ED_region_panels_init(wm, ar);
+
+ keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+}
+
+static void node_toolbar_area_draw(const bContext *C, ARegion *ar)
+{
+ ED_region_panels(C, ar, 1, NULL, -1);
+}
+
static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
{
SpaceNode *snode = sa->spacedata.first;
@@ -459,6 +498,7 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn)
case NC_SCENE:
case NC_MATERIAL:
case NC_TEXTURE:
+ case NC_WORLD:
case NC_NODE:
ED_region_tag_redraw(ar);
break;
@@ -570,6 +610,19 @@ void ED_spacetype_node(void)
node_buttons_register(art);
+ /* regions: toolbar */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
+ art->regionid = RGN_TYPE_TOOLS;
+ art->prefsizex = 160; /* XXX */
+ art->prefsizey = 50; /* XXX */
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
+ art->listener = node_region_listener;
+ art->init = node_toolbar_area_init;
+ art->draw = node_toolbar_area_draw;
+ BLI_addhead(&st->regiontypes, art);
+
+ node_toolbar_register(art);
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_outliner/SConscript b/source/blender/editors/space_outliner/SConscript
index a6f2e3c2a5d..1bb71941a43 100644
--- a/source/blender/editors/space_outliner/SConscript
+++ b/source/blender/editors/space_outliner/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index d37cb4be8fa..cacbc6d6268 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -421,17 +421,17 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide_select", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide_render", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
@@ -445,15 +445,21 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
+ bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -463,7 +469,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -476,13 +483,18 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, layflag, 0, 0, 0, 0, "Render this Pass");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ layflag, 0, 0, 0, 0, "Render this Pass");
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
layflag++; /* is lay_xor */
- if (ELEM8(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))
+ if (ELEM8(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,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ }
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -493,11 +505,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
}
else if (tselem->type == TSE_POSE_CHANNEL) {
@@ -506,11 +520,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
}
else if (tselem->type == TSE_EBONE) {
@@ -518,11 +534,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL);
}
}
@@ -535,7 +553,7 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex)
{
View2D *v2d = &ar->v2d;
- float miny = v2d->cur.ymin - V2D_SCROLL_HEIGHT;
+ float miny = v2d->cur.ymin;
if (miny < v2d->tot.ymin) miny = v2d->tot.ymin;
UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
@@ -832,7 +850,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
/* rna property */
if (kmi->ptr && kmi->ptr->data) {
- uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->oskey, 0, 0, 0, 0, ""); xstart += butw2;
+ uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, ""); xstart += butw2;
}
(void)xstart;
@@ -893,7 +911,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
struct DrawIconArg {
uiBlock *block;
ID *id;
- int xmax, x, y;
+ float xmax, x, y, xb, yb;
float alpha;
};
@@ -902,13 +920,11 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
/* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */
if (arg->x >= arg->xmax) {
glEnable(GL_BLEND);
- UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f, arg->alpha);
+ UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_FAC, arg->alpha);
glDisable(GL_BLEND);
}
else {
- /* XXX investigate: button placement of icons is way different than UI_icon_draw? */
- float ufac = UI_UNIT_X / 20.0f;
- uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->x - 3.0f * ufac, arg->y, UI_UNIT_X - 4.0f * ufac, UI_UNIT_Y - 4.0f * ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
+ uiBut *but = uiDefIconBut(arg->block, 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);
@@ -919,15 +935,24 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha)
{
struct DrawIconArg arg;
+ float aspect;
+
+ /* icons tiny bit away from text */
+ x -= 0.15f * UI_UNIT_Y;
/* make function calls a bit compacter */
arg.block = block;
arg.id = tselem->id;
arg.xmax = xmax;
- arg.x = x;
- arg.y = y;
+ arg.xb = x; /* for ui buttons */
+ arg.yb = y;
arg.alpha = alpha;
+ /* placement of icons, copied from interface_widgets.c */
+ aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
+ arg.x = x = x + 4.0f * aspect;
+ arg.y = y = y + 0.1f * UI_UNIT_Y;
+
if (tselem->type) {
switch (tselem->type) {
case TSE_ANIM_DATA:
@@ -989,6 +1014,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
case eModifierType_Array:
UI_icon_draw(x, y, ICON_MOD_ARRAY); break;
case eModifierType_UVProject:
+ case eModifierType_UVWarp: /* TODO, get own icon */
UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break;
case eModifierType_Displace:
UI_icon_draw(x, y, ICON_MOD_DISPLACE); break;
@@ -1040,7 +1066,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
UI_icon_draw(x, y, ICON_MOD_SKIN); break;
case eModifierType_Triangulate:
UI_icon_draw(x, y, ICON_MOD_TRIANGULATE); break;
-
+ case eModifierType_MeshCache:
+ UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; /* XXX, needs own icon */
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:
@@ -1220,11 +1247,11 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
uiSetRoundBox(UI_CNR_ALL);
glColor4ub(255, 255, 255, 100);
- uiRoundBox((float) *offsx - 0.5f * ufac,
- (float)ys - 1.0f * ufac,
- (float)*offsx + UI_UNIT_Y - 3.0f * ufac,
- (float)ys + UI_UNIT_Y - 3.0f * ufac,
- (float)UI_UNIT_Y / 2.0f - 2.0f * ufac);
+ 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);
glEnable(GL_BLEND); /* roundbox disables */
}
@@ -1270,6 +1297,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) {
int xmax = ar->v2d.cur.xmax;
+ unsigned char alpha = 128;
/* icons can be ui buts, we don't want it to overlap with restrict */
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
@@ -1286,16 +1314,17 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
{
char col[4];
UI_GetThemeColorType4ubv(TH_MATCH, SPACE_OUTLINER, col);
- col[3] = 100;
+ col[3] = alpha;
glColor4ubv((GLubyte *)col);
glRecti(startx, *starty + 1, ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
}
/* colors for active/selected data */
if (tselem->type == 0) {
+
if (te->idcode == ID_SCE) {
if (tselem->id == (ID *)scene) {
- glColor4ub(255, 255, 255, 100);
+ glColor4ub(255, 255, 255, alpha);
active = 2;
}
}
@@ -1304,7 +1333,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if (group_select_flag(gr)) {
char col[4];
UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
- col[3] = 100;
+ col[3] = alpha;
glColor4ubv((GLubyte *)col);
active = 2;
@@ -1322,14 +1351,14 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if (ob == OBACT) {
if (ob->flag & SELECT) {
UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col);
- col[3] = 100;
+ col[3] = alpha;
}
active = 1; /* means it draws white text */
}
else if (ob->flag & SELECT) {
UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
- col[3] = 100;
+ col[3] = alpha;
}
glColor4ubv((GLubyte *)col);
@@ -1337,29 +1366,29 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
}
else if (scene->obedit && scene->obedit->data == tselem->id) {
- glColor4ub(255, 255, 255, 100);
+ glColor4ub(255, 255, 255, alpha);
active = 2;
}
else {
if (tree_element_active(C, scene, soops, te, 0)) {
- glColor4ub(220, 220, 255, 100);
+ glColor4ub(220, 220, 255, alpha);
active = 2;
}
}
}
else {
if (tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active = 2;
- glColor4ub(220, 220, 255, 100);
+ glColor4ub(220, 220, 255, alpha);
}
/* active circle */
if (active) {
uiSetRoundBox(UI_CNR_ALL);
- uiRoundBox((float)startx + UI_UNIT_Y - 1.5f * ufac,
- (float)*starty + 2.0f * ufac,
- (float)startx + 2.0f * UI_UNIT_Y - 4.0f * ufac,
+ 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 - 2.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
@@ -1384,8 +1413,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
/* datatype icon */
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) {
- // icons a bit higher
- tselem_draw_icon(block, xmax, (float)startx + offsx - 0.5f * ufac, (float)*starty + 2.0f * ufac, tselem, te, 1.0f);
+
+ tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, 1.0f);
offsx += UI_UNIT_X;
}
@@ -1425,12 +1454,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
/* divider */
UI_ThemeColorShade(TH_BACK, -40);
- glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4);
+ glRecti(tempx - 10.0f * ufac,
+ *starty + 4.0f * ufac,
+ tempx - 8.0f * ufac,
+ *starty + UI_UNIT_Y - 4.0f * ufac);
glEnable(GL_BLEND);
glPixelTransferf(GL_ALPHA_SCALE, 0.5);
- outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty + 2);
+ outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty);
glPixelTransferf(GL_ALPHA_SCALE, 1.0);
glDisable(GL_BLEND);
@@ -1502,13 +1534,13 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
/* selection status */
if (TSELEM_OPEN(tselem, soops))
if (tselem->type == TSE_RNA_STRUCT)
- glRecti(0, *starty + 1, (int)ar->v2d.cur.xmax + V2D_SCROLL_WIDTH, *starty + UI_UNIT_Y - 1);
+ glRecti(0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
*starty -= UI_UNIT_Y;
if (TSELEM_OPEN(tselem, soops)) {
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
if (tselem->type == TSE_RNA_STRUCT)
- fdrawline(0, (float)*starty + UI_UNIT_Y, ar->v2d.cur.xmax + V2D_SCROLL_WIDTH, (float)*starty + UI_UNIT_Y);
+ fdrawline(0, (float)*starty + UI_UNIT_Y, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
}
}
}
@@ -1577,7 +1609,7 @@ static void outliner_back(ARegion *ar)
ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
while (ystart + 2 * UI_UNIT_Y > ar->v2d.cur.ymin) {
- glRecti(0, ystart, (int)ar->v2d.cur.xmax + V2D_SCROLL_WIDTH, ystart + UI_UNIT_Y);
+ glRecti(0, ystart, (int)ar->v2d.cur.xmax, ystart + UI_UNIT_Y);
ystart -= 2 * UI_UNIT_Y;
}
}
@@ -1588,10 +1620,8 @@ static void outliner_draw_restrictcols(ARegion *ar)
/* background underneath */
UI_ThemeColor(TH_BACK);
- glRecti((int)ar->v2d.cur.xmax - OL_TOGW,
- (int)ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT - 1,
- (int)ar->v2d.cur.xmax + V2D_SCROLL_WIDTH,
- (int)ar->v2d.cur.ymax);
+ glRecti((int)(ar->v2d.cur.xmax - OL_TOGW),
+ (int)(ar->v2d.cur.ymin - 1), (int)ar->v2d.cur.xmax, (int)ar->v2d.cur.ymax);
UI_ThemeColorShade(TH_BACK, 6);
ystart = (int)ar->v2d.tot.ymax;
@@ -1605,38 +1635,38 @@ static void outliner_draw_restrictcols(ARegion *ar)
UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
/* view */
- fdrawline(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX,
- ar->v2d.cur.ymax,
- ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX,
- ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT);
+ sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)ar->v2d.cur.ymax,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)ar->v2d.cur.ymin);
/* render */
- fdrawline(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX,
- ar->v2d.cur.ymax,
- ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX,
- ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT);
+ sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ (int)ar->v2d.cur.ymax,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ (int)ar->v2d.cur.ymin);
/* render */
- fdrawline(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX,
- ar->v2d.cur.ymax,
- ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX,
- ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT);
+ sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ (int)ar->v2d.cur.ymax,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ (int)ar->v2d.cur.ymin);
}
/* ****************************************************** */
/* Main Entrypoint - Draw contents of Outliner editor */
-
+
void draw_outliner(const bContext *C)
{
- Main *mainvar = CTX_data_main(C);
+ Main *mainvar = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
SpaceOops *soops = CTX_wm_space_outliner(C);
uiBlock *block;
int sizey = 0, sizex = 0, sizex_rna = 0;
-
- outliner_build_tree(mainvar, scene, soops); // always
+
+ outliner_build_tree(mainvar, scene, soops); // always
/* get extents of data */
outliner_height(soops, &soops->tree, &sizey);
@@ -1647,7 +1677,7 @@ void draw_outliner(const bContext *C)
* (OL_RNA_COL_X), whichever is wider...
* - column 2 is fixed at OL_RNA_COL_SIZEX
*
- * (*) XXX max width for now is a fixed factor of UI_UNIT_X*(max_indention+100)
+ * (*) XXX max width for now is a fixed factor of (UI_UNIT_X * (max_indention + 100))
*/
/* get actual width of column 1 */
@@ -1669,11 +1699,9 @@ void draw_outliner(const bContext *C)
// XXX this isn't that great yet...
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
sizex += OL_TOGW * 3;
+
}
- /* tweak to display last line (when list bigger than window) */
- sizey += V2D_SCROLL_HEIGHT;
-
/* adds vertical offset */
sizey += OL_Y_OFFSET;
@@ -1709,7 +1737,7 @@ void draw_outliner(const bContext *C)
uiEndBlock(C, block);
uiDrawBlock(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 d11a8ed6369..9a1b3628196 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -183,8 +183,8 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem, ReportList *reports)
{
- /* can't rename rna datablocks entries */
- if (ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
+ /* can't rename rna datablocks entries or listbases */
+ if (ELEM4(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE)) {
/* do nothing */;
}
else if (ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE,
@@ -1309,8 +1309,8 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
* 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);
+ break;
}
- break;
case KEYINGSET_EDITMODE_REMOVE:
{
/* find the relevant path, then remove it from the KeyingSet */
@@ -1322,8 +1322,8 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
ks->active_path = 0;
}
+ break;
}
- break;
}
/* free path, since it had to be generated */
@@ -1432,8 +1432,7 @@ static int parent_drop_exec(bContext *C, wmOperator *op)
ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, FALSE, FALSE);
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
@@ -1522,8 +1521,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) {
if (ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, FALSE, FALSE)) {
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
}
@@ -1637,7 +1635,7 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object");
@@ -1706,8 +1704,7 @@ static int parent_clear_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type"));
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
return OPERATOR_FINISHED;
@@ -1726,7 +1723,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object");
@@ -1795,8 +1792,7 @@ static int scene_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
ED_base_object_select(base, BA_SELECT);
}
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
@@ -1819,7 +1815,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
/* properties */
RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object");
@@ -1828,7 +1824,6 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot)
static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- Main *bmain = CTX_data_main(C);
Material *ma = NULL;
Object *ob = NULL;
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -1860,7 +1855,6 @@ static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
assign_material(ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
@@ -1883,7 +1877,7 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ 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 65de2a27568..63452de18d0 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -103,6 +103,7 @@ typedef struct TreeElement {
#define TSE_NLA_TRACK 33
#define TSE_KEYMAP 34
#define TSE_KEYMAP_ITEM 35
+#define TSE_ID_BASE 36
/* button events */
#define OL_NAMEBUTTON 1
@@ -115,8 +116,8 @@ typedef struct TreeElement {
/* size constants */
#define OL_Y_OFFSET 2
-#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 3)
-#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 2)
+#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 3.0f)
+#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 2.0f)
#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X
#define OL_TOGW OL_TOG_RESTRICT_VIEWX
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 0b585e1272b..fa337ba7af1 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -336,7 +336,8 @@ static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops
tep = te->parent;
if (tep) {
tselem = TREESTORE(tep);
- sce = (Scene *)tselem->id;
+ if (tselem->type == 0)
+ sce = (Scene *)tselem->id;
}
if (set) { // make new scene active
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 3b83279e09d..303782f3fbd 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -619,7 +619,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
* cleanup tree here to prevent such cases. */
outliner_cleanup_tree(soops);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
str = "Delete Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
@@ -712,10 +712,8 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op)
if (event == 3) { /* instance */
- Main *bmain = CTX_data_main(C);
-
/* works without this except if you try render right after, see: 22027 */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(CTX_data_main(C));
}
ED_undo_push(C, prop_group_op_types[event].name);
@@ -764,7 +762,7 @@ static EnumPropertyItem prop_id_op_types[] = {
{OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
{OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
{OUTLINER_IDOP_FAKE_ADD, "ADD_FAKE", 0, "Add Fake User",
- "Ensure datablock gets saved even if it isn't in use (e.g. for motion and material libraries)"},
+ "Ensure datablock gets saved even if it isn't in use (e.g. for motion and material libraries)"},
{OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""},
{OUTLINER_IDOP_RENAME, "RENAME", 0, "Rename", ""},
{OUTLINER_IDOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
@@ -1110,14 +1108,8 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
/* update dependencies */
if (updateDeps) {
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
-
/* rebuild depsgraph for the new deps */
- DAG_scene_sort(bmain, scene);
-
- /* force an update of depsgraph */
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(CTX_data_main(C));
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index e6910280da4..f723fbedc7b 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -66,8 +66,10 @@
#include "BKE_fcurve.h"
#include "BKE_main.h"
+#include "BKE_library.h"
#include "BKE_modifier.h"
#include "BKE_sequencer.h"
+#include "BKE_idcode.h"
#include "ED_armature.h"
#include "ED_screen.h"
@@ -593,6 +595,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0);
}
+
// can be inlined if necessary
static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, ID *id)
{
@@ -785,6 +788,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
}
// TODO: this function needs to be split up! It's getting a bit too large...
+// Note: "ID" is not always a real ID
static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv,
TreeElement *parent, short type, short index)
{
@@ -798,7 +802,13 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (!id) id = ((PointerRNA *)idv)->data;
}
- if (id == NULL) return NULL;
+ /* One exception */
+ if (type == TSE_ID_BASE) {
+ /* pass */
+ }
+ else if (id == NULL) {
+ return NULL;
+ }
te = MEM_callocN(sizeof(TreeElement), "tree elem");
/* add to the visual tree */
@@ -822,14 +832,24 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else if (type == TSE_ANIM_DATA) {
/* pass */
}
+ else if (type == TSE_ID_BASE) {
+ /* pass */
+ }
else {
- te->name = id->name + 2; // default, can be overridden by Library or non-ID data
+ /* do here too, for blend file viewer, own ID_LI then shows file name */
+ if (GS(id->name) == ID_LI)
+ te->name = ((Library *)id)->name;
+ else
+ te->name = id->name + 2; // default, can be overridden by Library or non-ID data
te->idcode = GS(id->name);
}
if (type == 0) {
+ TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
+
/* ID datablock */
- outliner_add_id_contents(soops, te, tselem, id);
+ if (tsepar == NULL || tsepar->type != TSE_ID_BASE)
+ outliner_add_id_contents(soops, te, tselem, id);
}
else if (type == TSE_ANIM_DATA) {
IdAdtTemplate *iat = (IdAdtTemplate *)idv;
@@ -1194,8 +1214,8 @@ typedef struct tTreeSort {
short idcode;
} tTreeSort;
-/* alphabetical comparator */
-static int treesort_alpha(const void *v1, const void *v2)
+/* alphabetical comparator, tryping to put objects first */
+static int treesort_alpha_ob(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
int comp;
@@ -1216,6 +1236,20 @@ static int treesort_alpha(const void *v1, const void *v2)
return 0;
}
+/* alphabetical comparator */
+static int treesort_alpha(const void *v1, const void *v2)
+{
+ const tTreeSort *x1 = v1, *x2 = v2;
+ int comp;
+
+ comp = strcmp(x1->name, x2->name);
+
+ if (comp > 0) return 1;
+ else if (comp < 0) return -1;
+ return 0;
+}
+
+
/* this is nice option for later? doesnt look too useful... */
#if 0
static int treesort_obtype_alpha(const void *v1, const void *v2)
@@ -1254,8 +1288,8 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
if (te == NULL) return;
tselem = TREESTORE(te);
- /* sorting rules; only object lists or deformgroups */
- if ((tselem->type == TSE_DEFGROUP) || (tselem->type == 0 && te->idcode == ID_OB)) {
+ /* sorting rules; only object lists, ID lists, or deformgroups */
+ if ( ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) {
/* count first */
for (te = lb->first; te; te = te->next) totelem++;
@@ -1270,15 +1304,27 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
tp->te = te;
tp->name = te->name;
tp->idcode = te->idcode;
- if (tselem->type && tselem->type != TSE_DEFGROUP) tp->idcode = 0; // don't sort this
+
+ if (tselem->type && tselem->type != TSE_DEFGROUP)
+ tp->idcode = 0; // don't sort this
+ if (tselem->type == TSE_ID_BASE)
+ tp->idcode = 1; // do sort this
+
tp->id = tselem->id;
}
- /* keep beginning of list */
- for (tp = tear, skip = 0; skip < totelem; skip++, tp++)
- if (tp->idcode) break;
- if (skip < totelem)
- qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha);
+ /* just sort alphabetically */
+ if (tear->idcode == 1) {
+ qsort(tear, totelem, sizeof(tTreeSort), treesort_alpha);
+ }
+ else {
+ /* keep beginning of list */
+ for (tp = tear, skip = 0; skip < totelem; skip++, tp++)
+ if (tp->idcode) break;
+
+ if (skip < totelem)
+ qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha_ob);
+ }
lb->first = lb->last = NULL;
tp = tear;
@@ -1384,6 +1430,42 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
return (lb->first != NULL);
}
+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 */
@@ -1418,17 +1500,31 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
if (soops->outlinevis == SO_LIBRARIES) {
Library *lib;
+ /* current file first - mainvar provides tselem with unique pointer - not used */
+ ten = outliner_add_element(soops, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0);
+ ten->name = "Current File";
+
+ tselem = TREESTORE(ten);
+ if (!tselem->used)
+ tselem->flag &= ~TSE_CLOSED;
+
+ outliner_add_library_contents(mainvar, soops, ten, NULL);
+
for (lib = mainvar->library.first; lib; lib = lib->id.next) {
ten = outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0);
lib->id.newid = (ID *)ten;
+
+ outliner_add_library_contents(mainvar, soops, ten, lib);
+
}
/* make hierarchy */
ten = soops->tree.first;
+ ten = ten->next; /* first one is main */
while (ten) {
TreeElement *nten = ten->next, *par;
tselem = TREESTORE(ten);
lib = (Library *)tselem->id;
- if (lib->parent) {
+ if (lib && lib->parent) {
BLI_remlink(&soops->tree, ten);
par = (TreeElement *)lib->parent->id.newid;
BLI_addtail(&par->subtree, ten);
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index ecc09a35670..4bf88376b74 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -67,6 +67,17 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
ListBase *lb;
wmKeyMap *keymap;
+ /* make sure we keep the hide flags */
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP); /* prevent any noise of past */
+ ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
+ ar->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ ar->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
+ ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
@@ -410,12 +421,6 @@ static SpaceLink *outliner_new(const bContext *UNUSED(C))
BLI_addtail(&soutliner->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM_O);
- ar->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- ar->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
- ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
-
return (SpaceLink *)soutliner;
}
diff --git a/source/blender/editors/space_script/SConscript b/source/blender/editors/space_script/SConscript
index c30e204f6f4..eff603a3e2d 100644
--- a/source/blender/editors/space_script/SConscript
+++ b/source/blender/editors/space_script/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c
index 4e6783e1862..96008004ee4 100644
--- a/source/blender/editors/space_script/script_edit.c
+++ b/source/blender/editors/space_script/script_edit.c
@@ -71,7 +71,7 @@ static int run_pyfile_exec(bContext *C, wmOperator *op)
void SCRIPT_OT_python_file_run(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Run python file";
+ ot->name = "Run Python File";
ot->description = "Run Python file";
ot->idname = "SCRIPT_OT_python_file_run";
ot->flag = OPTYPE_UNDO;
diff --git a/source/blender/editors/space_sequencer/SConscript b/source/blender/editors/space_sequencer/SConscript
index bc72786fc5f..060c7892bd1 100644
--- a/source/blender/editors/space_sequencer/SConscript
+++ b/source/blender/editors/space_sequencer/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 8155f9d645e..29a6a1f6d50 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -49,6 +49,8 @@
#include "DNA_mask_types.h"
#include "DNA_userdef_types.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -400,6 +402,7 @@ void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot)
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
prop = RNA_def_enum(ot->srna, "clip", DummyRNA_NULL_items, 0, "Clip", "");
RNA_def_enum_funcs(prop, RNA_movieclip_itemf);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_MOVIECLIP);
ot->prop = prop;
}
@@ -859,9 +862,9 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
* the other strips. */
if (!RNA_struct_property_is_set(op->ptr, "channel")) {
if (seq->seq1) {
- int chan = MAX3(seq->seq1 ? seq->seq1->machine : 0,
- seq->seq2 ? seq->seq2->machine : 0,
- seq->seq3 ? seq->seq3->machine : 0);
+ int chan = max_iii(seq->seq1 ? seq->seq1->machine : 0,
+ seq->seq2 ? seq->seq2->machine : 0,
+ seq->seq3 ? seq->seq3->machine : 0);
if (chan < MAXSEQ)
seq->machine = chan;
}
@@ -871,7 +874,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
- BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */
+ BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); /* runs BKE_sequence_calc */
/* not sure if this is needed with update_changed_seq_and_deps.
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index 7dbcabedccc..21128408a97 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -41,6 +41,7 @@
#include "ED_screen.h"
#include "ED_gpencil.h"
+#include "ED_sequencer.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -51,6 +52,14 @@
/* **************************** buttons ********************************* */
+static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt))
+{
+ SpaceSeq *sseq = CTX_wm_space_seq(C);
+
+ /* don't show the gpencil if we are not showing the image */
+ return ED_space_sequencer_check_show_imbuf(sseq);
+}
+
void sequencer_buttons_register(ARegionType *art)
{
PanelType *pt;
@@ -58,7 +67,9 @@ void sequencer_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil");
strcpy(pt->idname, "SEQUENCER_PT_gpencil");
strcpy(pt->label, N_("Grease Pencil"));
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
+ pt->poll = sequencer_grease_pencil_panel_poll;
BLI_addtail(&art->paneltypes, pt);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 1a84efa0b50..249ba986fd3 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -62,6 +62,7 @@
#include "ED_gpencil.h"
#include "ED_markers.h"
#include "ED_mask.h"
+#include "ED_sequencer.h"
#include "ED_types.h"
#include "ED_space_api.h"
@@ -921,12 +922,20 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
GLuint last_texid;
unsigned char *display_buffer;
void *cache_handle = NULL;
+ const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
- if (G.is_rendering == FALSE) {
+ if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
/* stop all running jobs, except screen one. currently previews frustrate Render
* needed to make so sequencer's rendering doesn't conflict with compositor
*/
WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE);
+
+ if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
+ /* in case of final rendering used for preview, kill all previews,
+ * otherwise threading conflict will happen in rendering module
+ */
+ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW);
+ }
}
render_size = sseq->render_size;
@@ -1049,6 +1058,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
glBegin(GL_QUADS);
if (draw_overlay) {
@@ -1080,6 +1093,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glEnd();
glBindTexture(GL_TEXTURE_2D, last_texid);
glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
glDeleteTextures(1, &texid);
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
@@ -1125,8 +1139,12 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
setlinestyle(0);
}
- /* draw grease-pencil (image aligned) */
- draw_gpencil_2dimage(C);
+ if (sseq->flag & SEQ_SHOW_GPENCIL) {
+ if (is_imbuf) {
+ /* draw grease-pencil (image aligned) */
+ draw_gpencil_2dimage(C);
+ }
+ }
if (!scope)
IMB_freeImBuf(ibuf);
@@ -1134,9 +1152,12 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
/* ortho at pixel level */
UI_view2d_view_restore(C);
- /* draw grease-pencil (screen aligned) */
- draw_gpencil_view2d(C, 0);
-
+ if (sseq->flag & SEQ_SHOW_GPENCIL) {
+ if (is_imbuf) {
+ /* draw grease-pencil (screen aligned) */
+ draw_gpencil_view2d(C, 0);
+ }
+ }
/* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not,
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index e7f77db3b9e..7be2d51a3c0 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -496,6 +496,13 @@ int ED_space_sequencer_maskedit_poll(bContext *C)
return FALSE;
}
+/* are we displaying the seq output (not channels or histogram)*/
+int ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
+{
+ return (ELEM(sseq->view, SEQ_VIEW_PREVIEW, 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);
@@ -810,18 +817,23 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
/* like duplicate, but only duplicate and cut overlapping strips,
- * strips to the left of the cutframe are ignored and strips to the right are moved into the new list */
-static int cut_seq_list(Scene *scene, ListBase *old, ListBase *new, int cutframe,
+ * strips to the left of the cutframe are ignored and strips to the right
+ * are moved to the end of slist
+ * we have to work on the same slist (not using a seperate list), since
+ * otherwise dupli_seq can't check for duplicate names properly and
+ * may generate strips with the same name (which will mess up animdata)
+ */
+
+static int cut_seq_list(Scene *scene, ListBase *slist, int cutframe,
Sequence * (*cut_seq)(Scene *, Sequence *, int))
{
- int did_something = FALSE;
Sequence *seq, *seq_next_iter;
+ Sequence *seq_first_new = NULL;
- seq = old->first;
-
- while (seq) {
+ seq = slist->first;
+
+ while (seq && seq != seq_first_new) {
seq_next_iter = seq->next; /* we need this because we may remove seq */
-
seq->tmp = NULL;
if (seq->flag & SELECT) {
if (cutframe > seq->startdisp &&
@@ -829,22 +841,29 @@ static int cut_seq_list(Scene *scene, ListBase *old, ListBase *new, int cutframe
{
Sequence *seqn = cut_seq(scene, seq, cutframe);
if (seqn) {
- BLI_addtail(new, seqn);
+ BLI_addtail(slist, seqn);
+ if (seq_first_new == NULL) {
+ seq_first_new = seqn;
+ }
}
- did_something = TRUE;
}
else if (seq->enddisp <= cutframe) {
/* do nothing */
}
else if (seq->startdisp >= cutframe) {
- /* move into new list */
- BLI_remlink(old, seq);
- BLI_addtail(new, seq);
+ /* move to tail */
+ BLI_remlink(slist, seq);
+ BLI_addtail(slist, seq);
+
+ if (seq_first_new == NULL) {
+ seq_first_new = seq;
+ }
}
}
seq = seq_next_iter;
}
- return did_something;
+
+ return (seq_first_new != NULL);
}
static int insert_gap(Scene *scene, int gap, int cfra)
@@ -918,7 +937,7 @@ static void set_filter_seq(Scene *scene)
if (seq->type == SEQ_TYPE_MOVIE) {
seq->flag |= SEQ_FILTERY;
reload_sequence_new_file(scene, seq, FALSE);
- calc_sequence(scene, seq);
+ BKE_sequence_calc(scene, seq);
}
}
@@ -1117,7 +1136,7 @@ static int sequencer_snap_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(ev
void SEQUENCER_OT_snap(struct wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Snap strips";
+ ot->name = "Snap Strips";
ot->idname = "SEQUENCER_OT_snap";
ot->description = "Frame where selected strips will be snapped";
@@ -1481,25 +1500,21 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op)
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
int cut_side, cut_hard, cut_frame;
- ListBase newlist;
int changed;
cut_frame = RNA_int_get(op->ptr, "frame");
cut_hard = RNA_enum_get(op->ptr, "type");
cut_side = RNA_enum_get(op->ptr, "side");
- newlist.first = newlist.last = NULL;
-
if (cut_hard == SEQ_CUT_HARD) {
- changed = cut_seq_list(scene, ed->seqbasep, &newlist, cut_frame, cut_seq_hard);
+ changed = cut_seq_list(scene, ed->seqbasep, cut_frame, cut_seq_hard);
}
else {
- changed = cut_seq_list(scene, ed->seqbasep, &newlist, cut_frame, cut_seq_soft);
+ changed = cut_seq_list(scene, ed->seqbasep, cut_frame, cut_seq_soft);
}
- if (newlist.first) { /* got new strips ? */
+ if (changed) { /* got new strips ? */
Sequence *seq;
- BLI_movelisttolist(ed->seqbasep, &newlist);
if (cut_side != SEQ_SIDE_BOTH) {
SEQP_BEGIN (ed, seq)
@@ -1899,6 +1914,9 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
for (seq = ed->seqbasep->first; seq; seq = seq->next)
BKE_sequence_calc(scene, seq);
+ if (BKE_sequence_test_overlap(ed->seqbasep, ms->parseq))
+ BKE_sequence_base_shuffle(ed->seqbasep, ms->parseq, scene);
+
BKE_sequencer_active_set(scene, ms->parseq);
ms->parseq->flag |= SELECT;
@@ -2453,9 +2471,15 @@ void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
{
int gap = seqb->startdisp - seqa->enddisp;
- seqb->start = (seqb->start - seqb->startdisp) + seqa->startdisp;
+ int seq_a_start;
+ int seq_b_start;
+
+ seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp;
+ BKE_sequence_translate(scene, seqb, seq_b_start - seqb->start);
BKE_sequence_calc(scene, seqb);
- seqa->start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
+
+ seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
+ BKE_sequence_translate(scene, seqa, seq_a_start - seqa->start);
BKE_sequence_calc(scene, seqa);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c
index a4a485b34c6..51df21e509a 100644
--- a/source/blender/editors/space_sequencer/sequencer_modifier.c
+++ b/source/blender/editors/space_sequencer/sequencer_modifier.c
@@ -180,13 +180,13 @@ static int strip_modifier_move_exec(bContext *C, wmOperator *op)
if (direction == SEQ_MODIFIER_MOVE_UP) {
if (smd->prev) {
BLI_remlink(&seq->modifiers, smd);
- BLI_insertlink(&seq->modifiers, smd->prev->prev, smd);
+ BLI_insertlinkbefore(&seq->modifiers, smd->prev, smd);
}
}
else if (direction == SEQ_MODIFIER_MOVE_DOWN) {
if (smd->next) {
BLI_remlink(&seq->modifiers, smd);
- BLI_insertlink(&seq->modifiers, smd->next, smd);
+ BLI_insertlinkafter(&seq->modifiers, smd->next, smd);
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 192f45ac918..0d1ecb76d0e 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -704,7 +704,7 @@ static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEv
void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Select pick linked";
+ ot->name = "Select Pick Linked";
ot->idname = "SEQUENCER_OT_select_linked_pick";
ot->description = "Select a chain of linked strips nearest to the mouse pointer";
@@ -739,7 +739,7 @@ static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
void SEQUENCER_OT_select_linked(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Select linked";
+ ot->name = "Select Linked";
ot->idname = "SEQUENCER_OT_select_linked";
ot->description = "Select all strips adjacent to the current selection";
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index e8d47016608..d541e1d6c07 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -120,6 +120,8 @@ static SpaceLink *sequencer_new(const bContext *C)
sseq->chanshown = 0;
sseq->view = SEQ_VIEW_SEQUENCE;
sseq->mainb = SEQ_DRAW_IMG_IMBUF;
+ sseq->flag = SEQ_SHOW_GPENCIL;
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for sequencer");
diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt
index 9cc407f0604..1a6b8eaa753 100644
--- a/source/blender/editors/space_text/CMakeLists.txt
+++ b/source/blender/editors/space_text/CMakeLists.txt
@@ -36,11 +36,16 @@ set(INC_SYS
set(SRC
space_text.c
+ text_autocomplete.c
text_draw.c
+ text_format.c
+ text_format_lua.c
+ text_format_osl.c
+ text_format_py.c
text_header.c
text_ops.c
- text_python.c
+ text_format.h
text_intern.h
)
diff --git a/source/blender/editors/space_text/SConscript b/source/blender/editors/space_text/SConscript
index 373564520c8..4b6d9fbd693 100644
--- a/source/blender/editors/space_text/SConscript
+++ b/source/blender/editors/space_text/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index d74e32620af..ff9d1329721 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -30,17 +30,12 @@
#include <string.h>
-#include <stdio.h>
#include "DNA_text_types.h"
-#include "DNA_object_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_rand.h"
-#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -61,7 +56,8 @@
#include "RNA_access.h"
-#include "text_intern.h" // own include
+#include "text_format.h"
+#include "text_intern.h" /* own include */
/* ******************** default callbacks for text space ***************** */
@@ -227,6 +223,8 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_to_3d_object);
WM_operatortype_append(TEXT_OT_resolve_conflict);
+
+ WM_operatortype_append(TEXT_OT_autocomplete);
}
static void text_keymap(struct wmKeyConfig *keyconf)
@@ -234,6 +232,12 @@ static void text_keymap(struct wmKeyConfig *keyconf)
wmKeyMap *keymap;
wmKeyMapItem *kmi;
+ keymap = WM_keymap_find(keyconf, "Text Generic", SPACE_TEXT, 0);
+ WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_CTRL, 0);
+#ifdef __APPLE__
+ WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_OSKEY, 0);
+#endif
+
keymap = WM_keymap_find(keyconf, "Text", SPACE_TEXT, 0);
#ifdef __APPLE__
@@ -258,7 +262,6 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
- WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_find_set_selected", EKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0);
@@ -280,7 +283,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", TRUE);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
@@ -307,7 +310,6 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0);
@@ -379,6 +381,8 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_line_break", PADENTER, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "TEXT_MT_toolbox", RIGHTMOUSE, KM_PRESS, KM_ANY, 0);
+
+ WM_keymap_add_item(keymap, "TEXT_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_line_number", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
@@ -413,6 +417,8 @@ static void text_main_area_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
/* own keymap */
+ keymap = WM_keymap_find(wm->defaultconf, "Text Generic", SPACE_TEXT, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
keymap = WM_keymap_find(wm->defaultconf, "Text", SPACE_TEXT, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -496,6 +502,11 @@ static void text_header_area_draw(const bContext *C, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void text_properties_area_init(wmWindowManager *wm, ARegion *ar)
{
+ wmKeyMap *keymap;
+
+ keymap = WM_keymap_find(wm->defaultconf, "Text Generic", SPACE_TEXT, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+
ED_region_panels_init(wm, ar);
}
@@ -556,5 +567,10 @@ void ED_spacetype_text(void)
BLI_addhead(&st->regiontypes, art);
BKE_spacetype_register(st);
+
+ /* register formatters */
+ ED_text_format_register_py();
+ ED_text_format_register_osl();
+ ED_text_format_register_lua();
}
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
new file mode 100644
index 00000000000..7c18b5c283a
--- /dev/null
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -0,0 +1,557 @@
+/*
+ * ***** 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 blender/editors/space_text/text_autocomplete.c
+ * \ingroup sptext
+ */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_text_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+
+#include "BKE_context.h"
+#include "BKE_text.h"
+#include "BKE_screen.h"
+#include "BKE_suggestions.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "UI_interface.h"
+
+#include "text_format.h"
+#include "text_intern.h" /* own include */
+
+
+/* -------------------------------------------------------------------- */
+/* Public API */
+
+int text_do_suggest_select(SpaceText *st, ARegion *ar)
+{
+ SuggItem *item, *first, *last /* , *sel */ /* UNUSED */;
+ TextLine *tmp;
+ int l, x, y, w, h, i;
+ int tgti, *top;
+ int mval[2] = {0, 0};
+
+ if (!st || !st->text) return 0;
+ if (!texttool_text_is_active(st->text)) return 0;
+
+ first = texttool_suggest_first();
+ last = texttool_suggest_last();
+ /* sel = texttool_suggest_selected(); */ /* UNUSED */
+ top = texttool_suggest_top();
+
+ if (!last || !first)
+ return 0;
+
+ /* Count the visible lines to the cursor */
+ for (tmp = st->text->curl, l = -st->top; tmp; tmp = tmp->prev, l++) ;
+ if (l < 0) return 0;
+
+ text_update_character_width(st);
+
+ if (st->showlinenrs) {
+ x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET + TEXTXLOC - 4;
+ }
+ else {
+ x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
+ }
+ y = ar->winy - st->lheight_dpi * l - 2;
+
+ w = SUGG_LIST_WIDTH * st->cwidth + U.widget_unit;
+ h = SUGG_LIST_SIZE * st->lheight_dpi + 0.4f * U.widget_unit;
+
+ // XXX getmouseco_areawin(mval);
+
+ if (mval[0] < x || x + w < mval[0] || mval[1] < y - h || y < mval[1])
+ return 0;
+
+ /* Work out which of the items is at the top of the visible list */
+ for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ;
+
+ /* Work out the target item index in the visible list */
+ tgti = (y - mval[1] - 4) / st->lheight_dpi;
+ if (tgti < 0 || tgti > SUGG_LIST_SIZE)
+ return 1;
+
+ for (i = tgti; i > 0 && item->next; i--, item = item->next) ;
+ if (item)
+ texttool_suggest_select(item);
+ return 1;
+}
+
+void text_pop_suggest_list(void)
+{
+ SuggItem *item, *sel;
+ int *top, i;
+
+ item = texttool_suggest_first();
+ sel = texttool_suggest_selected();
+ top = texttool_suggest_top();
+
+ i = 0;
+ while (item && item != sel) {
+ item = item->next;
+ i++;
+ }
+ if (i > *top + SUGG_LIST_SIZE - 1)
+ *top = i - SUGG_LIST_SIZE + 1;
+ else if (i < *top)
+ *top = i;
+}
+
+/* -------------------------------------------------------------------- */
+/* Private API */
+
+static void text_autocomplete_free(bContext *C, wmOperator *op);
+
+static GHash *text_autocomplete_build(Text *text)
+{
+ GHash *gh;
+ int seek_len = 0;
+ const char *seek;
+ texttool_text_clear();
+
+ texttool_text_set_active(text);
+
+ /* first get the word we're at */
+ {
+ const int i = text_find_identifier_start(text->curl->line, text->curc);
+ seek_len = text->curc - i;
+ seek = text->curl->line + i;
+
+ // BLI_strncpy(seek, seek_ptr, seek_len);
+ }
+
+ /* now walk over entire doc and suggest words */
+ {
+ TextLine *linep;
+
+ gh = BLI_ghash_str_new(__func__);
+
+ for (linep = text->lines.first; linep; linep = linep->next) {
+ size_t i_start = 0;
+ size_t i_end = 0;
+ size_t i_pos = 0;
+
+ while (i_start < linep->len) {
+ /* seek identifier beginning */
+ i_pos = i_start;
+ while ((i_start < linep->len) &&
+ (!text_check_identifier_nodigit_unicode(BLI_str_utf8_as_unicode_and_size_safe(&linep->line[i_start], &i_pos))))
+ {
+ i_start = i_pos;
+ }
+ i_pos = i_end = i_start;
+ while ((i_end < linep->len) &&
+ (text_check_identifier_unicode(BLI_str_utf8_as_unicode_and_size_safe(&linep->line[i_end], &i_pos))))
+ {
+ i_end = i_pos;
+ }
+
+ if ((i_start != i_end) &&
+ /* check we're at the beginning of a line or that the previous char is not an identifier
+ * this prevents digits from being added */
+ ((i_start < 1) || !text_check_identifier_unicode(BLI_str_utf8_as_unicode(&linep->line[i_start - 1]))))
+ {
+ char *str_sub = &linep->line[i_start];
+ const int choice_len = i_end - i_start;
+
+ if ((choice_len > seek_len) &&
+ (seek_len == 0 || strncmp(seek, str_sub, seek_len) == 0) &&
+ (seek != str_sub))
+ {
+ // printf("Adding: %s\n", s);
+ char str_sub_last = str_sub[choice_len];
+ str_sub[choice_len] = '\0';
+ if (!BLI_ghash_lookup(gh, str_sub)) {
+ char *str_dup = BLI_strdupn(str_sub, choice_len);
+ BLI_ghash_insert(gh, str_dup, str_dup); /* A 'set' would make more sense here */
+ }
+ str_sub[choice_len] = str_sub_last;
+ }
+ }
+ if (i_end != i_start) {
+ i_start = i_end;
+ }
+ else {
+ /* highly unlikely, but prevent eternal loop */
+ i_start++;
+ }
+ }
+ }
+
+ {
+ GHashIterator *iter = BLI_ghashIterator_new(gh);
+
+ /* get the formatter for highlighting */
+ TextFormatType *tft;
+ tft = ED_text_format_get(text);
+
+ for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ const char *s = BLI_ghashIterator_getValue(iter);
+ texttool_suggest_add(s, tft->format_identifier(s));
+ }
+ BLI_ghashIterator_free(iter);
+
+ }
+ }
+
+ texttool_suggest_prefix(seek, seek_len);
+
+ return gh;
+}
+
+/* -- */
+
+static void get_suggest_prefix(Text *text, int offset)
+{
+ int i, len;
+ char *line;
+
+ if (!text) return;
+ if (!texttool_text_is_active(text)) return;
+
+ line = text->curl->line;
+ i = text_find_identifier_start(line, text->curc + offset);
+ len = text->curc - i + offset;
+ texttool_suggest_prefix(line + i, len);
+}
+
+static void confirm_suggestion(Text *text)
+{
+ SuggItem *sel;
+ int i, over = 0;
+ const char *line;
+
+ if (!text) return;
+ if (!texttool_text_is_active(text)) return;
+
+ sel = texttool_suggest_selected();
+ if (!sel) return;
+
+ line = text->curl->line;
+ i = text_find_identifier_start(line, text->curc /* - skipleft */);
+ over = text->curc - i;
+
+// for (i = 0; i < skipleft; i++)
+// txt_move_left(text, 0);
+ for (i = 0; i < over; i++)
+ txt_move_left(text, 1);
+
+ txt_insert_buf(text, sel->name);
+
+// for (i = 0; i < skipleft; i++)
+// txt_move_right(text, 0);
+
+ texttool_text_clear();
+}
+
+/* -- */
+
+
+static int text_autocomplete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ SpaceText *st = CTX_wm_space_text(C);
+ Text *text = CTX_data_edit_text(C);
+
+ st->doplugins = TRUE;
+ op->customdata = text_autocomplete_build(text);
+
+ if (texttool_suggest_first()) {
+
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ if (texttool_suggest_first() == texttool_suggest_last()) {
+ confirm_suggestion(st->text);
+ text_update_line_edited(st->text->curl);
+ text_autocomplete_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
+ else {
+ text_autocomplete_free(C, op);
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int doc_scroll = 0;
+
+static int text_autocomplete_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceText *st = CTX_wm_space_text(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+
+ int draw = 0, tools = 0, swallow = 0, scroll = 1;
+ Text *text = CTX_data_edit_text(C);
+ int retval = OPERATOR_RUNNING_MODAL;
+
+ (void)text;
+
+ if (st->doplugins && texttool_text_is_active(st->text)) {
+ if (texttool_suggest_first()) tools |= TOOL_SUGG_LIST;
+ if (texttool_docs_get()) tools |= TOOL_DOCUMENT;
+ }
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ if (event->val == KM_PRESS) {
+ if (text_do_suggest_select(st, ar))
+ swallow = 1;
+ else {
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ retval = OPERATOR_FINISHED;
+ }
+ draw = 1;
+ }
+ break;
+ case MIDDLEMOUSE:
+ if (event->val == KM_PRESS) {
+ if (text_do_suggest_select(st, ar)) {
+ confirm_suggestion(st->text);
+ text_update_line_edited(st->text->curl);
+ swallow = 1;
+ }
+ else {
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ retval = OPERATOR_FINISHED;
+ }
+ draw = 1;
+ }
+ break;
+ case ESCKEY:
+ if (event->val == KM_PRESS) {
+ draw = swallow = 1;
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
+ else if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ else draw = swallow = 0;
+ retval = OPERATOR_CANCELLED;
+ }
+ break;
+ case RETKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_SUGG_LIST) {
+ confirm_suggestion(st->text);
+ text_update_line_edited(st->text->curl);
+ swallow = 1;
+ draw = 1;
+ }
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
+ retval = OPERATOR_FINISHED;
+ }
+ break;
+ case LEFTARROWKEY:
+ case BACKSPACEKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_SUGG_LIST) {
+ if (event->ctrl) {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ else {
+ /* Work out which char we are about to delete/pass */
+ if (st->text->curl && st->text->curc > 0) {
+ char ch = st->text->curl->line[st->text->curc - 1];
+ if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
+ get_suggest_prefix(st->text, -1);
+ text_pop_suggest_list();
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ }
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ }
+ break;
+ case RIGHTARROWKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_SUGG_LIST) {
+ if (event->ctrl) {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ else {
+ /* Work out which char we are about to pass */
+ if (st->text->curl && st->text->curc < st->text->curl->len) {
+ char ch = st->text->curl->line[st->text->curc + 1];
+ if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
+ get_suggest_prefix(st->text, 1);
+ text_pop_suggest_list();
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ }
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ }
+ break;
+ case PAGEDOWNKEY:
+ scroll = SUGG_LIST_SIZE - 1;
+ case WHEELDOWNMOUSE:
+ case DOWNARROWKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_DOCUMENT) {
+ doc_scroll++;
+ swallow = 1;
+ draw = 1;
+ }
+ else if (tools & TOOL_SUGG_LIST) {
+ SuggItem *sel = texttool_suggest_selected();
+ if (!sel) {
+ texttool_suggest_select(texttool_suggest_first());
+ }
+ else {
+ while (sel && sel != texttool_suggest_last() && sel->next && scroll--) {
+ texttool_suggest_select(sel->next);
+ sel = sel->next;
+ }
+ }
+ text_pop_suggest_list();
+ swallow = 1;
+ draw = 1;
+ }
+ }
+ break;
+ case PAGEUPKEY:
+ scroll = SUGG_LIST_SIZE - 1;
+ case WHEELUPMOUSE:
+ case UPARROWKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_DOCUMENT) {
+ if (doc_scroll > 0) doc_scroll--;
+ swallow = 1;
+ draw = 1;
+ }
+ else if (tools & TOOL_SUGG_LIST) {
+ SuggItem *sel = texttool_suggest_selected();
+ while (sel && sel != texttool_suggest_first() && sel->prev && scroll--) {
+ texttool_suggest_select(sel->prev);
+ sel = sel->prev;
+ }
+ text_pop_suggest_list();
+ swallow = 1;
+ draw = 1;
+ }
+ }
+ break;
+ case RIGHTSHIFTKEY:
+ case LEFTSHIFTKEY:
+ break;
+#if 0
+ default:
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(), draw = 1;
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
+#endif
+ }
+
+ if (draw) {
+ ED_area_tag_redraw(CTX_wm_area(C));
+ }
+
+// if (swallow) {
+// retval = OPERATOR_RUNNING_MODAL;
+// }
+
+ if (texttool_suggest_first()) {
+ if (retval != OPERATOR_RUNNING_MODAL) {
+ text_autocomplete_free(C, op);
+ }
+ return retval;
+ }
+ else {
+ text_autocomplete_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+}
+
+static void text_autocomplete_free(bContext *C, wmOperator *op)
+{
+ GHash *gh = op->customdata;
+ if (gh) {
+ BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
+ op->customdata = NULL;
+ }
+
+ /* other stuff */
+ {
+ SpaceText *st = CTX_wm_space_text(C);
+ st->doplugins = FALSE;
+ texttool_text_clear();
+ }
+}
+
+static int text_autocomplete_cancel(bContext *C, wmOperator *op)
+{
+ text_autocomplete_free(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+void TEXT_OT_autocomplete(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Text Auto Complete";
+ ot->description = "Show a list of used text in the open document";
+ ot->idname = "TEXT_OT_autocomplete";
+
+ /* api callbacks */
+ ot->invoke = text_autocomplete_invoke;
+ ot->cancel = text_autocomplete_cancel;
+ ot->modal = text_autocomplete_modal;
+ ot->poll = text_space_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
+}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 46ab2d9e688..c264368e714 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -29,10 +29,6 @@
*/
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
#include "MEM_guardedalloc.h"
@@ -40,12 +36,10 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_utildefines.h"
#include "DNA_text_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
-#include "DNA_userdef_types.h"
#include "BKE_context.h"
#include "BKE_suggestions.h"
@@ -53,11 +47,12 @@
#include "BIF_gl.h"
-#include "ED_datafiles.h"
#include "UI_interface.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "text_intern.h"
+#include "text_format.h"
/******************** text font drawing ******************/
// XXX, fixme
@@ -65,7 +60,7 @@
static void text_font_begin(SpaceText *st)
{
- BLF_size(mono, st->lheight, 72);
+ BLF_size(mono, st->lheight_dpi, 72);
}
static void text_font_end(SpaceText *UNUSED(st))
@@ -82,373 +77,20 @@ static int text_font_draw(SpaceText *UNUSED(st), int x, int y, const char *str)
static int text_font_draw_character(SpaceText *st, int x, int y, char c)
{
- char str[2];
- str[0] = c;
- str[1] = '\0';
-
BLF_position(mono, x, y, 0);
- BLF_draw(mono, str, 1);
+ BLF_draw(mono, &c, 1);
return st->cwidth;
}
static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char *c)
{
- char str[BLI_UTF8_MAX + 1];
- size_t len = BLI_str_utf8_size_safe(c);
- memcpy(str, c, len);
- str[len] = '\0';
-
+ const size_t len = BLI_str_utf8_size_safe(c);
BLF_position(mono, x, y, 0);
- BLF_draw(mono, str, len);
-
+ BLF_draw(mono, c, len);
return st->cwidth;
}
-/****************** flatten string **********************/
-
-static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
-{
- int i;
-
- if (fs->pos + len > fs->len) {
- char *nbuf; int *naccum;
- fs->len *= 2;
-
- nbuf = MEM_callocN(sizeof(*fs->buf) * fs->len, "fs->buf");
- naccum = MEM_callocN(sizeof(*fs->accum) * fs->len, "fs->accum");
-
- memcpy(nbuf, fs->buf, fs->pos * sizeof(*fs->buf));
- memcpy(naccum, fs->accum, fs->pos * sizeof(*fs->accum));
-
- if (fs->buf != fs->fixedbuf) {
- MEM_freeN(fs->buf);
- MEM_freeN(fs->accum);
- }
-
- fs->buf = nbuf;
- fs->accum = naccum;
- }
-
- for (i = 0; i < len; i++) {
- fs->buf[fs->pos + i] = c[i];
- fs->accum[fs->pos + i] = accum;
- }
-
- fs->pos += len;
-}
-
-int flatten_string(SpaceText *st, FlattenString *fs, const char *in)
-{
- int r, i, total = 0;
-
- memset(fs, 0, sizeof(FlattenString));
- fs->buf = fs->fixedbuf;
- fs->accum = fs->fixedaccum;
- fs->len = sizeof(fs->fixedbuf);
-
- for (r = 0, i = 0; *in; r++) {
- if (*in == '\t') {
- i = st->tabnumber - (total % st->tabnumber);
- total += i;
-
- while (i--)
- flatten_string_append(fs, " ", r, 1);
-
- in++;
- }
- else {
- size_t len = BLI_str_utf8_size_safe(in);
- flatten_string_append(fs, in, r, len);
- in += len;
- total++;
- }
- }
-
- flatten_string_append(fs, "\0", r, 1);
-
- return total;
-}
-
-void flatten_string_free(FlattenString *fs)
-{
- if (fs->buf != fs->fixedbuf)
- MEM_freeN(fs->buf);
- if (fs->accum != fs->fixedaccum)
- MEM_freeN(fs->accum);
-}
-
-/* Checks the specified source string for a Python built-in function name. This
- * name must start at the beginning of the source string and must be followed by
- * a non-identifier (see text_check_identifier(char)) or null character.
- *
- * If a built-in function is found, the length of the matching name is returned.
- * Otherwise, -1 is returned.
- *
- * See:
- * http://docs.python.org/py3k/reference/lexical_analysis.html#keywords
- */
-
-static int find_builtinfunc(char *string)
-{
- int a, i;
- const char *builtinfuncs[] = {
- /* "False", "None", "True", */ /* see find_bool() */
- "and", "as", "assert", "break",
- "class", "continue", "def", "del", "elif", "else", "except",
- "finally", "for", "from", "global", "if", "import", "in",
- "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
- "return", "try", "while", "with", "yield",
- };
-
- for (a = 0; a < sizeof(builtinfuncs) / sizeof(builtinfuncs[0]); a++) {
- i = 0;
- while (1) {
- /* If we hit the end of a keyword... (eg. "def") */
- if (builtinfuncs[a][i] == '\0') {
- /* If we still have identifier chars in the source (eg. "definate") */
- if (text_check_identifier(string[i]))
- i = -1; /* No match */
- break; /* Next keyword if no match, otherwise we're done */
-
- /* If chars mismatch, move on to next keyword */
- }
- else if (string[i] != builtinfuncs[a][i]) {
- i = -1;
- break; /* Break inner loop, start next keyword */
- }
- i++;
- }
- if (i > 0) break; /* If we have a match, we're done */
- }
- return i;
-}
-
-/* Checks the specified source string for a Python special name. This name must
- * start at the beginning of the source string and must be followed by a non-
- * identifier (see text_check_identifier(char)) or null character.
- *
- * If a special name is found, the length of the matching name is returned.
- * Otherwise, -1 is returned. */
-
-static int find_specialvar(char *string)
-{
- int i = 0;
- /* Check for "def" */
- if (string[0] == 'd' && string[1] == 'e' && string[2] == 'f')
- i = 3;
- /* Check for "class" */
- else if (string[0] == 'c' && string[1] == 'l' && string[2] == 'a' && string[3] == 's' && string[4] == 's')
- i = 5;
- /* If next source char is an identifier (eg. 'i' in "definate") no match */
- if (i == 0 || text_check_identifier(string[i]))
- return -1;
- return i;
-}
-
-static int find_decorator(char *string)
-{
- if (string[0] == '@') {
- int i = 1;
- while (text_check_identifier(string[i])) {
- i++;
- }
- return i;
- }
- return -1;
-}
-
-static int find_bool(char *string)
-{
- int i = 0;
- /* Check for "False" */
- if (string[0] == 'F' && string[1] == 'a' && string[2] == 'l' && string[3] == 's' && string[4] == 'e')
- i = 5;
- /* Check for "True" */
- else if (string[0] == 'T' && string[1] == 'r' && string[2] == 'u' && string[3] == 'e')
- i = 4;
- /* Check for "None" */
- else if (string[0] == 'N' && string[1] == 'o' && string[2] == 'n' && string[3] == 'e')
- i = 4;
- /* If next source char is an identifier (eg. 'i' in "definate") no match */
- if (i == 0 || text_check_identifier(string[i]))
- return -1;
- return i;
-}
-
-/* Ensures the format string for the given line is long enough, reallocating
- * as needed. Allocation is done here, alone, to ensure consistency. */
-static int text_check_format_len(TextLine *line, unsigned int len)
-{
- if (line->format) {
- if (strlen(line->format) < len) {
- MEM_freeN(line->format);
- line->format = MEM_mallocN(len + 2, "SyntaxFormat");
- if (!line->format) return 0;
- }
- }
- else {
- line->format = MEM_mallocN(len + 2, "SyntaxFormat");
- if (!line->format) return 0;
- }
-
- return 1;
-}
-
-/* Formats the specified line. If do_next is set, the process will move on to
- * the succeeding line if it is affected (eg. multiline strings). Format strings
- * may contain any of the following characters:
- * '_' Whitespace
- * '#' Comment text
- * '!' Punctuation and other symbols
- * 'n' Numerals
- * 'l' String letters
- * 'v' Special variables (class, def)
- * 'b' Built-in names (print, for, etc.)
- * 'q' Other text (identifiers, etc.)
- * It is terminated with a null-terminator '\0' followed by a continuation
- * flag indicating whether the line is part of a multi-line string. */
-
-static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
-{
- FlattenString fs;
- char *str, *fmt, orig, cont, find, prev = ' ';
- int len, i;
-
- /* Get continuation from previous line */
- if (line->prev && line->prev->format != NULL) {
- fmt = line->prev->format;
- cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
- }
- else cont = 0;
-
- /* Get original continuation from this line */
- if (line->format != NULL) {
- fmt = line->format;
- orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
- }
- else orig = 0xFF;
-
- len = flatten_string(st, &fs, line->line);
- str = fs.buf;
- if (!text_check_format_len(line, len)) {
- flatten_string_free(&fs);
- return;
- }
- fmt = line->format;
-
- while (*str) {
- /* Handle escape sequences by skipping both \ and next char */
- if (*str == '\\') {
- *fmt = prev; fmt++; str++;
- if (*str == '\0') break;
- *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
- continue;
- }
- /* Handle continuations */
- else if (cont) {
- /* Triple strings ("""...""" or '''...''') */
- if (cont & TXT_TRISTR) {
- find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
- if (*str == find && *(str + 1) == find && *(str + 2) == find) {
- *fmt = 'l'; fmt++; str++;
- *fmt = 'l'; fmt++; str++;
- cont = 0;
- }
- /* Handle other strings */
- }
- else {
- find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
- if (*str == find) cont = 0;
- }
-
- *fmt = 'l';
- str += BLI_str_utf8_size_safe(str) - 1;
- }
- /* Not in a string... */
- else {
- /* Deal with comments first */
- if (prev == '#' || *str == '#') {
- *fmt = '#';
- str += BLI_str_utf8_size_safe(str) - 1;
- }
- else if (*str == '"' || *str == '\'') {
- /* Strings */
- find = *str;
- cont = (*str == '"') ? TXT_DBLQUOTSTR : TXT_SNGQUOTSTR;
- if (*(str + 1) == find && *(str + 2) == find) {
- *fmt = 'l'; fmt++; str++;
- *fmt = 'l'; fmt++; str++;
- cont |= TXT_TRISTR;
- }
- *fmt = 'l';
- }
- /* Whitespace (all ws. has been converted to spaces) */
- else if (*str == ' ')
- *fmt = '_';
- /* Numbers (digits not part of an identifier and periods followed by digits) */
- else if ((prev != 'q' && text_check_digit(*str)) || (*str == '.' && text_check_digit(*(str + 1))))
- *fmt = 'n';
- /* Booleans */
- else if (prev != 'q' && (i = find_bool(str)) != -1)
- if (i > 0) {
- while (i > 1) {
- *fmt = 'n'; fmt++; str++;
- i--;
- }
- *fmt = 'n';
- }
- else {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- /* Punctuation */
- else if (text_check_delim(*str))
- *fmt = '!';
- /* Identifiers and other text (no previous ws. or delims. so text continues) */
- else if (prev == 'q') {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
- else {
- /* Special vars(v) or built-in keywords(b) */
- if ((i = find_specialvar(str)) != -1)
- prev = 'v';
- else if ((i = find_builtinfunc(str)) != -1)
- prev = 'b';
- else if ((i = find_decorator(str)) != -1)
- prev = 'v'; /* could have a new color for this */
- if (i > 0) {
- while (i > 1) {
- *fmt = prev; fmt++; str++;
- i--;
- }
- *fmt = prev;
- }
- else {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- }
- }
- prev = *fmt;
- fmt++;
- str++;
- }
-
- /* Terminate and add continuation char */
- *fmt = '\0'; fmt++;
- *fmt = cont;
-
- /* If continuation has changed and we're allowed, process the next line */
- if (cont != orig && do_next && line->next) {
- txt_format_line(st, line->next, do_next);
- }
-
- flatten_string_free(&fs);
-}
-
#if 0
/* Formats every line of the current text */
static void txt_format_text(SpaceText *st)
@@ -466,27 +108,33 @@ static void txt_format_text(SpaceText *st)
static void format_draw_color(char formatchar)
{
switch (formatchar) {
- case '_': /* Whitespace */
+ case FMT_TYPE_WHITESPACE:
break;
- case '!': /* Symbols */
- UI_ThemeColorBlend(TH_TEXT, TH_BACK, 0.5f);
+ case FMT_TYPE_SYMBOL:
+ UI_ThemeColor(TH_SYNTAX_S);
break;
- case '#': /* Comments */
+ case FMT_TYPE_COMMENT:
UI_ThemeColor(TH_SYNTAX_C);
break;
- case 'n': /* Numerals */
+ case FMT_TYPE_NUMERAL:
UI_ThemeColor(TH_SYNTAX_N);
break;
- case 'l': /* Strings */
+ case FMT_TYPE_STRING:
UI_ThemeColor(TH_SYNTAX_L);
break;
- case 'v': /* Specials: class, def */
+ case FMT_TYPE_DIRECTIVE:
+ UI_ThemeColor(TH_SYNTAX_D);
+ break;
+ case FMT_TYPE_SPECIAL:
UI_ThemeColor(TH_SYNTAX_V);
break;
- case 'b': /* Keywords: for, print, etc. */
+ case FMT_TYPE_RESERVED:
+ UI_ThemeColor(TH_SYNTAX_R);
+ break;
+ case FMT_TYPE_KEYWORD:
UI_ThemeColor(TH_SYNTAX_B);
break;
- case 'q': /* Other text (identifiers) */
+ case FMT_TYPE_DEFAULT:
default:
UI_ThemeColor(TH_TEXT);
break;
@@ -708,6 +356,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
FlattenString fs;
int basex, i, a, start, end, max, lines; /* view */
int mi, ma, mstart, mend; /* mem */
+ char fmt_prev = 0xff;
flatten_string(st, &fs, str);
str = fs.buf;
@@ -731,10 +380,12 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
/* Draw the visible portion of text on the overshot line */
for (a = start, ma = mstart; a < end; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
- if (st->showsyntax && format) format_draw_color(format[a]);
+ if (st->showsyntax && format) {
+ if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
+ }
x += text_font_draw_character_utf8(st, x, y, str + ma);
}
- y -= st->lheight + TXT_LINE_SPACING;
+ y -= st->lheight_dpi + TXT_LINE_SPACING;
x = basex;
lines++;
start = end; mstart = mend;
@@ -749,8 +400,9 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
/* Draw the remaining text */
for (a = start, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
- if (st->showsyntax && format)
- format_draw_color(format[a]);
+ if (st->showsyntax && format) {
+ if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
+ }
x += text_font_draw_character_utf8(st, x, y, str + ma);
}
@@ -781,15 +433,18 @@ static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int dra
if (st->showsyntax && format) {
int a, str_shift = 0;
+ char fmt_prev = 0xff;
format = format + cshift;
for (a = 0; a < amount; a++) {
- format_draw_color(format[a]);
+ if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]);
x += text_font_draw_character_utf8(st, x, y, in + str_shift);
str_shift += BLI_str_utf8_size_safe(in + str_shift);
}
}
- else text_font_draw(st, x, y, in);
+ else {
+ text_font_draw(st, x, y, in);
+ }
}
else {
while (w-- && *acc++ < maxwidth)
@@ -852,7 +507,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
full_update |= drawcache->wordwrap != st->wordwrap; /* word-wrapping option was toggled */
full_update |= drawcache->showlinenrs != st->showlinenrs; /* word-wrapping option was toggled */
full_update |= drawcache->tabnumber != st->tabnumber; /* word-wrapping option was toggled */
- full_update |= drawcache->lheight != st->lheight; /* 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 */
@@ -928,7 +583,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
/* store settings */
drawcache->winx = ar->winx;
drawcache->wordwrap = st->wordwrap;
- drawcache->lheight = st->lheight;
+ drawcache->lheight = st->lheight_dpi;
drawcache->cwidth = st->cwidth;
drawcache->showlinenrs = st->showlinenrs;
drawcache->tabnumber = st->tabnumber;
@@ -1085,12 +740,12 @@ static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll, rcti *back)
blank_lines = st->viewlines / 2;
/* nicer code: use scroll rect for entire bar */
- back->xmin = ar->winx - 18;
+ back->xmin = ar->winx - (V2D_SCROLL_WIDTH + 1);
back->xmax = ar->winx;
back->ymin = 0;
back->ymax = ar->winy;
- scroll->xmin = ar->winx - 17;
+ scroll->xmin = ar->winx - V2D_SCROLL_WIDTH;
scroll->xmax = ar->winx - 5;
scroll->ymin = 4;
scroll->ymax = 4 + pix_available;
@@ -1237,9 +892,9 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
x += SUGG_LIST_WIDTH * st->cwidth + 50;
}
- /* top = */ /* UNUSED */ y = ar->winy - st->lheight * l - 2;
+ /* top = */ /* UNUSED */ y = ar->winy - st->lheight_dpi * l - 2;
boxw = DOC_WIDTH * st->cwidth + 20;
- boxh = (DOC_HEIGHT + 1) * st->lheight;
+ boxh = (DOC_HEIGHT + 1) * (st->lheight_dpi + TXT_LINE_SPACING);
/* Draw panel */
UI_ThemeColor(TH_BACK);
@@ -1271,7 +926,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
else if (*p == '\n') {
buf[i] = '\0';
if (lines >= 0) {
- y -= st->lheight;
+ y -= st->lheight_dpi;
text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
}
i = 0; br = DOC_WIDTH; lines++;
@@ -1280,7 +935,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
if (i == DOC_WIDTH) { /* Reached the width, go to last break and wrap there */
buf[br] = '\0';
if (lines >= 0) {
- y -= st->lheight;
+ y -= st->lheight_dpi;
text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
}
p -= i - br - 1; /* Rewind pointer to last break */
@@ -1302,9 +957,11 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
SuggItem *item, *first, *last, *sel;
TextLine *tmp;
char str[SUGG_LIST_WIDTH + 1];
- int w, boxw = 0, boxh, i, l, x, y, b, *top;
+ int w, boxw = 0, boxh, i, l, x, y, *top;
+ const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
+ const int margin_x = 2;
- if (!st || !st->text) return;
+ if (!st->text) return;
if (!texttool_text_is_active(st->text)) return;
first = texttool_suggest_first();
@@ -1326,14 +983,20 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
else {
x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
}
- y = ar->winy - st->lheight * l - 2;
+ /* offset back so the start of the text lines up with the suggestions,
+ * not essential but makes suggestions easier to follow */
+ x -= st->cwidth * (st->text->curc - text_find_identifier_start(st->text->curl->line, st->text->curc));
+ y = ar->winy - lheight * l - 2;
boxw = SUGG_LIST_WIDTH * st->cwidth + 20;
- boxh = SUGG_LIST_SIZE * st->lheight + 8;
+ boxh = SUGG_LIST_SIZE * lheight + 8;
+ /* not needed but stands out nicer */
+ uiDrawBoxShadow(220, x, y - boxh, x + boxw, y);
+
UI_ThemeColor(TH_SHADE1);
glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1);
- UI_ThemeColor(TH_BACK);
+ UI_ThemeColorShade(TH_BACK, 16);
glRecti(x, y, x + boxw, y - boxh);
/* Set the top 'item' of the visible list */
@@ -1341,7 +1004,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
for (i = 0; i < SUGG_LIST_SIZE && item; i++, item = item->next) {
- y -= st->lheight;
+ y -= lheight;
BLI_strncpy(str, item->name, SUGG_LIST_WIDTH);
@@ -1349,21 +1012,11 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
if (item == sel) {
UI_ThemeColor(TH_SHADE2);
- glRecti(x + 16, y - 3, x + 16 + w, y + st->lheight - 3);
+ glRecti(x + margin_x, y - 3, x + margin_x + w, y + lheight - 3);
}
- b = 1; /* b=1 color block, text is default. b=0 no block, color text */
- switch (item->type) {
- case 'k': UI_ThemeColor(TH_SYNTAX_B); b = 0; break;
- case 'm': UI_ThemeColor(TH_TEXT); break;
- case 'f': UI_ThemeColor(TH_SYNTAX_L); break;
- case 'v': UI_ThemeColor(TH_SYNTAX_N); break;
- case '?': UI_ThemeColor(TH_TEXT); b = 0; break;
- }
- if (b) {
- glRecti(x + 8, y + 2, x + 11, y + 5);
- UI_ThemeColor(TH_TEXT);
- }
- text_draw(st, str, 0, 0, 1, x + 16, y - 1, NULL);
+
+ format_draw_color(item->type);
+ text_draw(st, str, 0, 0, 1, x + margin_x, y - 1, NULL);
if (item == last) break;
}
@@ -1376,7 +1029,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
Text *text = st->text;
int vcurl, vcurc, vsell, vselc, hidden = 0;
int x, y, w, i;
- int lheight = st->lheight + TXT_LINE_SPACING;
+ const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
/* Draw the selection */
if (text->curl != text->sell || text->curc != text->selc) {
@@ -1394,14 +1047,14 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
UI_ThemeColor(TH_SHADE2);
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
- y = ar->winy - 2;
+ y = ar->winy;
if (vcurl == vsell) {
y -= vcurl * lheight;
if (vcurc < vselc)
- glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight + TXT_LINE_SPACING);
+ glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight);
else
- glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight + TXT_LINE_SPACING);
+ glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight);
}
else {
int froml, fromc, tol, toc;
@@ -1420,7 +1073,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
for (i = froml + 1; i < tol; i++)
glRecti(x - 4, y, ar->winx, y - lheight), y -= lheight;
- glRecti(x - 4, y, x + toc * st->cwidth, y - lheight + TXT_LINE_SPACING); y -= lheight;
+ glRecti(x - 4, y, x + toc * st->cwidth, y - lheight); y -= lheight;
}
}
else {
@@ -1445,11 +1098,11 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc);
y1 = ar->winy - 2 - (vsell - offl) * lheight;
- y2 = y1 - lheight * visible_lines + 1;
+ y2 = y1 - (lheight * visible_lines + TXT_LINE_SPACING);
}
else {
y1 = ar->winy - 2 - vsell * lheight;
- y2 = y1 - lheight + 1;
+ y2 = y1 - (lheight + TXT_LINE_SPACING);
}
if (!(y1 < 0 || y2 > ar->winy)) { /* check we need to draw */
@@ -1469,7 +1122,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
/* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
x += vselc * st->cwidth;
- y = ar->winy - 2 - vsell * lheight;
+ y = ar->winy - vsell * lheight;
if (st->overwrite) {
char ch = text->sell->line[text->selc];
@@ -1483,7 +1136,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
}
else {
UI_ThemeColor(TH_HILITE);
- glRecti(x - 1, y, x + 1, y - lheight + TXT_LINE_SPACING);
+ glRecti(x - 1, y, x + 1, y - lheight);
}
}
}
@@ -1517,7 +1170,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
stack = 0;
/* Don't highlight backets if syntax HL is off or bracket in string or comment. */
- if (!linep->format || linep->format[fc] == 'l' || linep->format[fc] == '#')
+ if (!linep->format || linep->format[fc] == FMT_TYPE_STRING || linep->format[fc] == FMT_TYPE_COMMENT)
return;
if (b > 0) {
@@ -1526,7 +1179,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
c += BLI_str_utf8_size_safe(linep->line + c);
while (linep) {
while (c < linep->len) {
- if (linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') {
+ if (linep->format && linep->format[fc] != FMT_TYPE_STRING && linep->format[fc] != FMT_TYPE_COMMENT) {
b = text_check_bracket(linep->line[c]);
if (b == find) {
if (stack == 0) {
@@ -1555,7 +1208,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (c > 0) c -= linep->line + c - BLI_str_prev_char_utf8(linep->line + c);
while (linep) {
while (fc >= 0) {
- if (linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') {
+ if (linep->format && linep->format[fc] != FMT_TYPE_STRING && linep->format[fc] != FMT_TYPE_COMMENT) {
b = text_check_bracket(linep->line[c]);
if (b == find) {
if (stack == 0) {
@@ -1588,7 +1241,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
UI_ThemeColor(TH_HILITE);
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
- y = ar->winy - st->lheight;
+ y = ar->winy - st->lheight_dpi;
/* draw opening bracket */
ch = startl->line[startc];
@@ -1598,8 +1251,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (viewc >= 0) {
viewl = txt_get_span(text->lines.first, startl) - st->top + offl;
- text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
- text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
}
/* draw closing bracket */
@@ -1610,8 +1263,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (viewc >= 0) {
viewl = txt_get_span(text->lines.first, endl) - st->top + offl;
- text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
- text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
}
}
@@ -1620,6 +1273,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
void draw_text_main(SpaceText *st, ARegion *ar)
{
Text *text = st->text;
+ TextFormatType *tft;
TextLine *tmp;
rcti scroll, back;
char linenr[12];
@@ -1627,7 +1281,10 @@ void draw_text_main(SpaceText *st, ARegion *ar)
int wraplinecount = 0, wrap_skip = 0;
int margin_column_x;
- if (st->lheight) st->viewlines = (int)ar->winy / (st->lheight + TXT_LINE_SPACING);
+ /* dpi controlled line height and font size */
+ st->lheight_dpi = (U.widget_unit * st->lheight) / 20;
+
+ if (st->lheight_dpi) st->viewlines = (int)ar->winy / (st->lheight_dpi + TXT_LINE_SPACING);
else st->viewlines = 0;
/* if no text, nothing to do */
@@ -1644,11 +1301,12 @@ void draw_text_main(SpaceText *st, ARegion *ar)
calc_text_rcts(st, ar, &scroll, &back); /* scroll will hold the entire bar size */
/* update syntax formatting if needed */
+ tft = ED_text_format_get(text);
tmp = text->lines.first;
lineno = 0;
for (i = 0; i < st->top && tmp; i++) {
if (st->showsyntax && !tmp->format)
- txt_format_line(st, tmp, 0);
+ tft->format_line(st, tmp, 0);
if (st->wordwrap) {
int lines = text_get_visible_lines_no(st, lineno);
@@ -1686,7 +1344,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
st->linenrs_tot = 0; /* not used */
x = TXT_OFFSET;
}
- y = ar->winy - st->lheight;
+ y = ar->winy - st->lheight_dpi;
winx = ar->winx - TXT_SCROLL_WIDTH;
/* draw cursor */
@@ -1697,7 +1355,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
for (i = 0; y > 0 && i < st->viewlines && tmp; i++, tmp = tmp->next) {
if (st->showsyntax && !tmp->format)
- txt_format_line(st, tmp, 0);
+ tft->format_line(st, tmp, 0);
if (st->showlinenrs && !wrap_skip) {
/* draw line number */
@@ -1716,12 +1374,12 @@ void draw_text_main(SpaceText *st, ARegion *ar)
if (st->wordwrap) {
/* draw word wrapped text */
int lines = text_draw_wrapped(st, tmp->line, x, y, winx - x, tmp->format, wrap_skip);
- y -= lines * (st->lheight + TXT_LINE_SPACING);
+ y -= lines * (st->lheight_dpi + TXT_LINE_SPACING);
}
else {
/* draw unwrapped text */
text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format);
- y -= st->lheight + TXT_LINE_SPACING;
+ y -= st->lheight_dpi + TXT_LINE_SPACING;
}
wrap_skip = 0;
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
new file mode 100644
index 00000000000..a8c2de193c4
--- /dev/null
+++ b/source/blender/editors/space_text/text_format.c
@@ -0,0 +1,227 @@
+/*
+ * ***** 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
+ * 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 blender/editors/space_text/text_format.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "text_format.h"
+
+
+/****************** flatten string **********************/
+
+static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
+{
+ int i;
+
+ if (fs->pos + len > fs->len) {
+ char *nbuf; int *naccum;
+ fs->len *= 2;
+
+ nbuf = MEM_callocN(sizeof(*fs->buf) * fs->len, "fs->buf");
+ naccum = MEM_callocN(sizeof(*fs->accum) * fs->len, "fs->accum");
+
+ memcpy(nbuf, fs->buf, fs->pos * sizeof(*fs->buf));
+ memcpy(naccum, fs->accum, fs->pos * sizeof(*fs->accum));
+
+ if (fs->buf != fs->fixedbuf) {
+ MEM_freeN(fs->buf);
+ MEM_freeN(fs->accum);
+ }
+
+ fs->buf = nbuf;
+ fs->accum = naccum;
+ }
+
+ for (i = 0; i < len; i++) {
+ fs->buf[fs->pos + i] = c[i];
+ fs->accum[fs->pos + i] = accum;
+ }
+
+ fs->pos += len;
+}
+
+int flatten_string(SpaceText *st, FlattenString *fs, const char *in)
+{
+ int r, i, total = 0;
+
+ memset(fs, 0, sizeof(FlattenString));
+ fs->buf = fs->fixedbuf;
+ fs->accum = fs->fixedaccum;
+ fs->len = sizeof(fs->fixedbuf);
+
+ for (r = 0, i = 0; *in; r++) {
+ if (*in == '\t') {
+ i = st->tabnumber - (total % st->tabnumber);
+ total += i;
+
+ while (i--)
+ flatten_string_append(fs, " ", r, 1);
+
+ in++;
+ }
+ else {
+ size_t len = BLI_str_utf8_size_safe(in);
+ flatten_string_append(fs, in, r, len);
+ in += len;
+ total++;
+ }
+ }
+
+ flatten_string_append(fs, "\0", r, 1);
+
+ return total;
+}
+
+void flatten_string_free(FlattenString *fs)
+{
+ if (fs->buf != fs->fixedbuf)
+ MEM_freeN(fs->buf);
+ if (fs->accum != fs->fixedaccum)
+ MEM_freeN(fs->accum);
+}
+
+/* takes a string within fs->buf and returns its length */
+int flatten_string_strlen(FlattenString *fs, const char *str)
+{
+ const int len = (fs->pos - (int)(str - fs->buf)) - 1;
+ BLI_assert(strlen(str) == len);
+ return len;
+}
+
+/* Ensures the format string for the given line is long enough, reallocating
+ * as needed. Allocation is done here, alone, to ensure consistency. */
+int text_check_format_len(TextLine *line, unsigned int len)
+{
+ if (line->format) {
+ if (strlen(line->format) < len) {
+ MEM_freeN(line->format);
+ line->format = MEM_mallocN(len + 2, "SyntaxFormat");
+ if (!line->format) return 0;
+ }
+ }
+ else {
+ line->format = MEM_mallocN(len + 2, "SyntaxFormat");
+ if (!line->format) return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Fill the string with formatting constant,
+ * advancing \a str_p and \a fmt_p
+ *
+ * \param len length in bytes
+ */
+void text_format_fill(const char **str_p, char **fmt_p, const char type, const int len)
+{
+ const char *str = *str_p;
+ char *fmt = *fmt_p;
+ int i = 0;
+
+ while (i < len) {
+ const int size = BLI_str_utf8_size_safe(str);
+ *fmt++ = type;
+
+ str += size;
+ i += size;
+ }
+
+ str--;
+ fmt--;
+
+ BLI_assert(*str != '\0');
+
+ *str_p = str;
+ *fmt_p = fmt;
+}
+/**
+ * ascii version of #text_format_fill,
+ * use when we no the text being stepped over is ascii (as is the case for most keywords)
+ */
+void text_format_fill_ascii(const char **str_p, char **fmt_p, const char type, const int len)
+{
+ const char *str = *str_p;
+ char *fmt = *fmt_p;
+
+ memset(fmt, type, len);
+
+ str += len - 1;
+ fmt += len - 1;
+
+ BLI_assert(*str != '\0');
+
+ *str_p = str;
+ *fmt_p = fmt;
+}
+
+/* *** Registration *** */
+static ListBase tft_lb = {NULL, NULL};
+void ED_text_format_register(TextFormatType *tft)
+{
+ BLI_addtail(&tft_lb, tft);
+}
+
+TextFormatType *ED_text_format_get(Text *text)
+{
+ TextFormatType *tft;
+
+ if (text) {
+ const char *text_ext = strchr(text->id.name + 2, '.');
+ if (text_ext) {
+ text_ext++; /* skip the '.' */
+ /* Check all text formats in the static list */
+ for (tft = tft_lb.first; tft; tft = tft->next) {
+ /* All formats should have an ext, but just in case */
+ const char **ext;
+ for (ext = tft->ext; *ext; ext++) {
+ /* If extension matches text name, return the matching tft */
+ if (BLI_strcasecmp(text_ext, *ext) == 0) {
+ return tft;
+ }
+ }
+ }
+ }
+
+ /* If we make it here we never found an extension that worked - return
+ * the "default" text format */
+ return tft_lb.first;
+ }
+ else {
+ /* Return the "default" text format */
+ return tft_lb.first;
+ }
+}
diff --git a/source/blender/editors/space_text/text_format.h b/source/blender/editors/space_text/text_format.h
new file mode 100644
index 00000000000..808311cbb62
--- /dev/null
+++ b/source/blender/editors/space_text/text_format.h
@@ -0,0 +1,109 @@
+/*
+ * ***** 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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_format.h
+ * \ingroup sptext
+ */
+
+#ifndef __TEXT_FORMAT_H__
+#define __TEXT_FORMAT_H__
+
+/* *** Flatten String *** */
+typedef struct FlattenString {
+ char fixedbuf[256];
+ int fixedaccum[256];
+
+ char *buf;
+ int *accum;
+ int pos, len;
+} FlattenString;
+
+/* format continuation flags (stored just after the NULL terminator) */
+enum {
+ FMT_CONT_NOP = 0, /* no continuation */
+ FMT_CONT_QUOTESINGLE = (1 << 0), /* single quotes */
+ FMT_CONT_QUOTEDOUBLE = (1 << 1), /* double quotes */
+ FMT_CONT_TRIPLE = (1 << 2), /* triplets of quotes: """ or ''' */
+ FMT_CONT_QUOTESINGLE_TRIPLE = (FMT_CONT_TRIPLE | FMT_CONT_QUOTESINGLE),
+ FMT_CONT_QUOTEDOUBLE_TRIPLE = (FMT_CONT_TRIPLE | FMT_CONT_QUOTEDOUBLE),
+ FMT_CONT_COMMENT_C = (1 << 3) /* multi-line comments, OSL only (C style) */
+};
+#define FMT_CONT_ALL \
+ (FMT_CONT_QUOTESINGLE | FMT_CONT_QUOTEDOUBLE | FMT_CONT_TRIPLE | FMT_CONT_COMMENT_C)
+
+int flatten_string(struct SpaceText *st, FlattenString *fs, const char *in);
+void flatten_string_free(FlattenString *fs);
+int flatten_string_strlen(FlattenString *fs, const char *str);
+
+int text_check_format_len(TextLine *line, unsigned int len);
+void text_format_fill(const char **str_p, char **fmt_p, const char type, const int len);
+void text_format_fill_ascii(const char **str_p, char **fmt_p, const char type, const int len);
+
+/* *** Generalize Formatting *** */
+typedef struct TextFormatType {
+ struct TextFormatType *next, *prev;
+
+ char (*format_identifier)(const char *string);
+
+ /* Formats the specified line. If do_next is set, the process will move on to
+ * the succeeding line if it is affected (eg. multiline strings). Format strings
+ * may contain any of the following characters:
+ *
+ * It is terminated with a null-terminator '\0' followed by a continuation
+ * flag indicating whether the line is part of a multi-line string.
+ *
+ * See: FMT_TYPE_ enums below
+ */
+ void (*format_line)(SpaceText *st, TextLine *line, int do_next);
+
+ const char **ext; /* NULL terminated extensions */
+} TextFormatType;
+
+enum {
+ FMT_TYPE_WHITESPACE = '_', /* Whitespace */
+ FMT_TYPE_COMMENT = '#', /* Comment text */
+ FMT_TYPE_SYMBOL = '!', /* Punctuation and other symbols */
+ FMT_TYPE_NUMERAL = 'n', /* Numerals */
+ FMT_TYPE_STRING = 'l', /* String letters */
+ FMT_TYPE_DIRECTIVE = 'd', /* Decorator / Preprocessor directive */
+ FMT_TYPE_SPECIAL = 'v', /* Special variables (class, def) */
+ FMT_TYPE_RESERVED = 'r', /* Reserved keywords currently not in use, but still prohibited (OSL -> switch e.g.) */
+ FMT_TYPE_KEYWORD = 'b', /* Built-in names (return, for, etc.) */
+ FMT_TYPE_DEFAULT = 'q', /* Regular text (identifiers, etc.) */
+};
+
+TextFormatType *ED_text_format_get(Text *text);
+void ED_text_format_register(TextFormatType *tft);
+
+/* formatters */
+void ED_text_format_register_py(void);
+void ED_text_format_register_osl(void);
+void ED_text_format_register_lua(void);
+
+#define STR_LITERAL_STARTSWITH(str, str_literal, len_var) \
+ (strncmp(str, str_literal, len_var = (sizeof(str_literal) - 1)) == 0)
+
+#endif /* __TEXT_FORMAT_H__ */
diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c
new file mode 100644
index 00000000000..6c72e043930
--- /dev/null
+++ b/source/blender/editors/space_text/text_format_lua.c
@@ -0,0 +1,318 @@
+/*
+ * ***** 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
+ * 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 blender/editors/space_text/text_format_lua.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_text.h"
+
+#include "text_format.h"
+
+/* *** Lua Keywords (for format_line) *** */
+
+/* Checks the specified source string for a Lua keyword (minus boolean & 'nil').
+ * This name must start at the beginning of the source string and must be
+ * followed by a non-identifier (see text_check_identifier(char)) or null char.
+ *
+ * If a keyword is found, the length of the matching word is returned.
+ * Otherwise, -1 is returned.
+ *
+ * See:
+ * http://www.lua.org/manual/5.1/manual.html#2.1
+ */
+
+static int txtfmt_lua_find_keyword(const char *string)
+{
+ int i, len;
+
+ if (STR_LITERAL_STARTSWITH(string, "and", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "do", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "elseif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "function", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "in", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "local", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "not", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "or", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "repeat", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "then", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "until", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+/* Checks the specified source string for a Lua special name/function. This
+ * name must start at the beginning of the source string and must be followed
+ * by a non-identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a special name is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned.
+ *
+ * See:
+ * http://www.lua.org/manual/5.1/manual.html#5.1
+ */
+
+static int txtfmt_lua_find_specialvar(const char *string)
+{
+ int i, len;
+
+ if (STR_LITERAL_STARTSWITH(string, "assert", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "collectgarbage", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dofile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "error", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "_G", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "getfenv", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "getmetatable", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "__index", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ipairs", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "load", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "loadfile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "loadstring", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "next", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pairs", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pcall", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "print", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rawequal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rawget", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rawset", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "select", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "setfenv", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "setmetatable", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tonumber", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tostring", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "unpack", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "_VERSION", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "xpcall", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static int txtfmt_lua_find_bool(const char *string)
+{
+ int i, len;
+
+ if (STR_LITERAL_STARTSWITH(string, "nil", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "true", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "false", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "Nonetheless") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static char txtfmt_lua_format_identifier(const char *str)
+{
+ char fmt;
+ if ((txtfmt_lua_find_specialvar(str)) != -1) fmt = FMT_TYPE_SPECIAL;
+ else if ((txtfmt_lua_find_keyword(str)) != -1) fmt = FMT_TYPE_KEYWORD;
+ else fmt = FMT_TYPE_DEFAULT;
+ return fmt;
+}
+
+static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const int do_next)
+{
+ FlattenString fs;
+ const char *str;
+ char *fmt;
+ char cont_orig, cont, find, prev = ' ';
+ int len, i;
+
+ /* Get continuation from previous line */
+ if (line->prev && line->prev->format != NULL) {
+ fmt = line->prev->format;
+ cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont) == cont);
+ }
+ else {
+ cont = FMT_CONT_NOP;
+ }
+
+ /* Get original continuation from this line */
+ if (line->format != NULL) {
+ fmt = line->format;
+ cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
+ }
+ else {
+ cont_orig = 0xFF;
+ }
+
+ len = flatten_string(st, &fs, line->line);
+ str = fs.buf;
+ if (!text_check_format_len(line, len)) {
+ flatten_string_free(&fs);
+ return;
+ }
+ fmt = line->format;
+
+ while (*str) {
+ /* Handle escape sequences by skipping both \ and next char */
+ if (*str == '\\') {
+ *fmt = prev; fmt++; str++;
+ if (*str == '\0') break;
+ *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
+ continue;
+ }
+ /* Handle continuations */
+ else if (cont) {
+ /* Multi-line comments */
+ if (cont & FMT_CONT_COMMENT_C) {
+ if (*str == ']' && *(str + 1) == ']') {
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ cont = FMT_CONT_NOP;
+ }
+ else {
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* Handle other comments */
+ }
+ else {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find) cont = 0;
+ *fmt = FMT_TYPE_STRING;
+ }
+
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ /* Not in a string... */
+ else {
+ /* Multi-line comments */
+ if (*str == '-' && *(str + 1) == '-' &&
+ *(str + 2) == '[' && *(str + 3) == '[')
+ {
+ cont = FMT_CONT_COMMENT_C;
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* Single line comment */
+ else if (*str == '-' && *(str + 1) == '-') {
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ }
+ else if (*str == '"' || *str == '\'') {
+ /* Strings */
+ find = *str;
+ cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
+ *fmt = FMT_TYPE_STRING;
+ }
+ /* Whitespace (all ws. has been converted to spaces) */
+ else if (*str == ' ') {
+ *fmt = FMT_TYPE_WHITESPACE;
+ }
+ /* Numbers (digits not part of an identifier and periods followed by digits) */
+ else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
+ (*str == '.' && text_check_digit(*(str + 1))))
+ {
+ *fmt = FMT_TYPE_NUMERAL;
+ }
+ /* Booleans */
+ else if (prev != FMT_TYPE_DEFAULT && (i = txtfmt_lua_find_bool(str)) != -1) {
+ if (i > 0) {
+ text_format_fill_ascii(&str, &fmt, FMT_TYPE_NUMERAL, i);
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ /* Punctuation */
+ else if ((*str != '#') && text_check_delim(*str)) {
+ *fmt = FMT_TYPE_SYMBOL;
+ }
+ /* Identifiers and other text (no previous ws. or delims. so text continues) */
+ else if (prev == FMT_TYPE_DEFAULT) {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
+ else {
+ /* Special vars(v) or built-in keywords(b) */
+ /* keep in sync with 'txtfmt_osl_format_identifier()' */
+ if ((i = txtfmt_lua_find_specialvar(str)) != -1) prev = FMT_TYPE_SPECIAL;
+ else if ((i = txtfmt_lua_find_keyword(str)) != -1) prev = FMT_TYPE_KEYWORD;
+
+ if (i > 0) {
+ text_format_fill_ascii(&str, &fmt, prev, i);
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ }
+ prev = *fmt; fmt++; str++;
+ }
+
+ /* Terminate and add continuation char */
+ *fmt = '\0'; fmt++;
+ *fmt = cont;
+
+ /* If continuation has changed and we're allowed, process the next line */
+ if (cont != cont_orig && do_next && line->next) {
+ txtfmt_lua_format_line(st, line->next, do_next);
+ }
+
+ flatten_string_free(&fs);
+}
+
+void ED_text_format_register_lua(void)
+{
+ static TextFormatType tft = {0};
+ static const char *ext[] = {"lua", NULL};
+
+ tft.format_identifier = txtfmt_lua_format_identifier;
+ tft.format_line = txtfmt_lua_format_line;
+ tft.ext = ext;
+
+ ED_text_format_register(&tft);
+}
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
new file mode 100644
index 00000000000..7d493eb1f62
--- /dev/null
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -0,0 +1,336 @@
+/*
+ * ***** 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
+ * 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 blender/editors/space_text/text_format_osl.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_text.h"
+
+#include "text_format.h"
+
+/* *** Local Functions (for format_line) *** */
+
+static int txtfmt_osl_find_builtinfunc(const char *string)
+{
+ int i, len;
+ /* list is from
+ * https://github.com/imageworks/OpenShadingLanguage/raw/master/src/doc/osl-languagespec.pdf
+ */
+ if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "closure", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "continue", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "do", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "emit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "float", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "illuminance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "illuminate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "int", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "matrix", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "output", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "point", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "public", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "string", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "struct", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vector", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "void", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static int txtfmt_osl_find_reserved(const char *string)
+{
+ int i, len;
+ /* list is from...
+ * https://github.com/imageworks/OpenShadingLanguage/raw/master/src/doc/osl-languagespec.pdf
+ */
+ if (STR_LITERAL_STARTSWITH(string, "bool", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "catch", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "char", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "const", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "delete", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "default", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "double", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "enum", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "extern", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "false", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "friend", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "goto", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "long", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "new", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "operator", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "private", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "protected", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "short", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "signed", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sizeof", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "static", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "switch", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "template", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "this", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "throw", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "true", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "try", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "typedef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uniform", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "union", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "unsigned", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "varying", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "virtual", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "volatile", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+/* Checks the specified source string for a OSL special name. This name must
+ * start at the beginning of the source string and must be followed by a non-
+ * identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a special name is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned. */
+
+static int txtfmt_osl_find_specialvar(const char *string)
+{
+ int i, len;
+
+ /* OSL shader types */
+ if (STR_LITERAL_STARTSWITH(string, "shader", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "surface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "volume", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "displacement", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+/* matches py 'txtfmt_osl_find_decorator' */
+static int txtfmt_osl_find_preprocessor(const char *string)
+{
+ if (string[0] == '#') {
+ int i = 1;
+ /* Whitespace is ok '# foo' */
+ while (text_check_whitespace(string[i])) {
+ i++;
+ }
+ while (text_check_identifier(string[i])) {
+ i++;
+ }
+ return i;
+ }
+ return -1;
+}
+
+static char txtfmt_osl_format_identifier(const char *str)
+{
+ char fmt;
+ if ((txtfmt_osl_find_specialvar(str)) != -1) fmt = FMT_TYPE_SPECIAL;
+ else if ((txtfmt_osl_find_builtinfunc(str)) != -1) fmt = FMT_TYPE_KEYWORD;
+ else if ((txtfmt_osl_find_reserved(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else if ((txtfmt_osl_find_preprocessor(str)) != -1) fmt = FMT_TYPE_DIRECTIVE;
+ else fmt = FMT_TYPE_DEFAULT;
+ return fmt;
+}
+
+static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const int do_next)
+{
+ FlattenString fs;
+ const char *str;
+ char *fmt;
+ char cont_orig, cont, find, prev = ' ';
+ int len, i;
+
+ /* Get continuation from previous line */
+ if (line->prev && line->prev->format != NULL) {
+ fmt = line->prev->format;
+ cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont) == cont);
+ }
+ else {
+ cont = FMT_CONT_NOP;
+ }
+
+ /* Get original continuation from this line */
+ if (line->format != NULL) {
+ fmt = line->format;
+ cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
+ }
+ else {
+ cont_orig = 0xFF;
+ }
+
+ len = flatten_string(st, &fs, line->line);
+ str = fs.buf;
+ if (!text_check_format_len(line, len)) {
+ flatten_string_free(&fs);
+ return;
+ }
+ fmt = line->format;
+
+ while (*str) {
+ /* Handle escape sequences by skipping both \ and next char */
+ if (*str == '\\') {
+ *fmt = prev; fmt++; str++;
+ if (*str == '\0') break;
+ *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
+ continue;
+ }
+ /* Handle continuations */
+ else if (cont) {
+ /* C-Style comments */
+ if (cont & FMT_CONT_COMMENT_C) {
+ if (*str == '*' && *(str + 1) == '/') {
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ cont = FMT_CONT_NOP;
+ }
+ else {
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* Handle other comments */
+ }
+ else {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find) cont = 0;
+ *fmt = FMT_TYPE_STRING;
+ }
+
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ /* Not in a string... */
+ else {
+ /* Deal with comments first */
+ if (*str == '/' && *(str + 1) == '/') {
+ /* fill the remaining line */
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ }
+ /* C-Style (multi-line) comments */
+ else if (*str == '/' && *(str + 1) == '*') {
+ cont = FMT_CONT_COMMENT_C;
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ else if (*str == '"' || *str == '\'') {
+ /* Strings */
+ find = *str;
+ cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
+ *fmt = FMT_TYPE_STRING;
+ }
+ /* Whitespace (all ws. has been converted to spaces) */
+ else if (*str == ' ') {
+ *fmt = FMT_TYPE_WHITESPACE;
+ }
+ /* Numbers (digits not part of an identifier and periods followed by digits) */
+ else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
+ (*str == '.' && text_check_digit(*(str + 1))))
+ {
+ *fmt = FMT_TYPE_NUMERAL;
+ }
+ /* Punctuation */
+ else if ((*str != '#') && text_check_delim(*str)) {
+ *fmt = FMT_TYPE_SYMBOL;
+ }
+ /* Identifiers and other text (no previous ws. or delims. so text continues) */
+ else if (prev == FMT_TYPE_DEFAULT) {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
+ else {
+ /* Special vars(v) or built-in keywords(b) */
+ /* keep in sync with 'txtfmt_osl_format_identifier()' */
+ if ((i = txtfmt_osl_find_specialvar(str)) != -1) prev = FMT_TYPE_SPECIAL;
+ else if ((i = txtfmt_osl_find_builtinfunc(str)) != -1) prev = FMT_TYPE_KEYWORD;
+ else if ((i = txtfmt_osl_find_reserved(str)) != -1) prev = FMT_TYPE_RESERVED;
+ else if ((i = txtfmt_osl_find_preprocessor(str)) != -1) prev = FMT_TYPE_DIRECTIVE;
+
+ if (i > 0) {
+ if (prev == FMT_TYPE_DIRECTIVE) { /* can contain utf8 */
+ text_format_fill(&str, &fmt, prev, i);
+ }
+ else {
+ text_format_fill_ascii(&str, &fmt, prev, i);
+ }
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ }
+ prev = *fmt; fmt++; str++;
+ }
+
+ /* Terminate and add continuation char */
+ *fmt = '\0'; fmt++;
+ *fmt = cont;
+
+ /* If continuation has changed and we're allowed, process the next line */
+ if (cont != cont_orig && do_next && line->next) {
+ txtfmt_osl_format_line(st, line->next, do_next);
+ }
+
+ flatten_string_free(&fs);
+}
+
+void ED_text_format_register_osl(void)
+{
+ static TextFormatType tft = {0};
+ static const char *ext[] = {"osl", NULL};
+
+ tft.format_identifier = txtfmt_osl_format_identifier;
+ tft.format_line = txtfmt_osl_format_line;
+ tft.ext = ext;
+
+ ED_text_format_register(&tft);
+}
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
new file mode 100644
index 00000000000..902d60dcb3e
--- /dev/null
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -0,0 +1,325 @@
+/*
+ * ***** 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
+ * 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 blender/editors/space_text/text_format_py.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_text.h"
+
+#include "text_format.h"
+
+/* *** Local Functions (for format_line) *** */
+
+/* Checks the specified source string for a Python built-in function name. This
+ * name must start at the beginning of the source string and must be followed by
+ * a non-identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a built-in function is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned.
+ *
+ * See:
+ * http://docs.python.org/py3k/reference/lexical_analysis.html#keywords
+ */
+
+static int txtfmt_py_find_builtinfunc(const char *string)
+{
+ int i, len;
+ /* list is from...
+ * ", ".join(['"%s"' % kw
+ * for kw in __import__("keyword").kwlist
+ * if kw not in {"False", "None", "True", "def", "class"}])
+ *
+ * ... and for this code:
+ * print("\n".join(['else if (STR_LITERAL_STARTSWITH(string, "%s", len)) i = len;' % kw
+ * for kw in __import__("keyword").kwlist
+ * if kw not in {"False", "None", "True", "def", "class"}]))
+ */
+
+ if (STR_LITERAL_STARTSWITH(string, "and", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "as", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "assert", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "continue", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "del", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "elif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "except", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "finally", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "from", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "global", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "import", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "in", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "is", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lambda", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "nonlocal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "not", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "or", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pass", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "raise", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "try", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "with", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "yield", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+/* Checks the specified source string for a Python special name. This name must
+ * start at the beginning of the source string and must be followed by a non-
+ * identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a special name is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned. */
+
+static int txtfmt_py_find_specialvar(const char *string)
+{
+ int i, len;
+
+ if (STR_LITERAL_STARTSWITH(string, "def", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "class", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static int txtfmt_py_find_decorator(const char *string)
+{
+ if (string[0] == '@') {
+ int i = 1;
+ /* Whitespace is ok '@ foo' */
+ while (text_check_whitespace(string[i])) {
+ i++;
+ }
+ while (text_check_identifier(string[i])) {
+ i++;
+ }
+ return i;
+ }
+ return -1;
+}
+
+static int txtfmt_py_find_bool(const char *string)
+{
+ int i, len;
+
+ if (STR_LITERAL_STARTSWITH(string, "None", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "True", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "False", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "Nonetheless") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static char txtfmt_py_format_identifier(const char *str)
+{
+ char fmt;
+ if ((txtfmt_py_find_specialvar(str)) != -1) fmt = FMT_TYPE_SPECIAL;
+ else if ((txtfmt_py_find_builtinfunc(str)) != -1) fmt = FMT_TYPE_KEYWORD;
+ else if ((txtfmt_py_find_decorator(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else fmt = FMT_TYPE_DEFAULT;
+ return fmt;
+}
+
+static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const int do_next)
+{
+ FlattenString fs;
+ const char *str;
+ char *fmt;
+ char cont_orig, cont, find, prev = ' ';
+ int len, i;
+
+ /* Get continuation from previous line */
+ if (line->prev && line->prev->format != NULL) {
+ fmt = line->prev->format;
+ cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont) == cont);
+ }
+ else {
+ cont = FMT_CONT_NOP;
+ }
+
+ /* Get original continuation from this line */
+ if (line->format != NULL) {
+ fmt = line->format;
+ cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
+ }
+ else {
+ cont_orig = 0xFF;
+ }
+
+ len = flatten_string(st, &fs, line->line);
+ str = fs.buf;
+ if (!text_check_format_len(line, len)) {
+ flatten_string_free(&fs);
+ return;
+ }
+ fmt = line->format;
+
+ while (*str) {
+ /* Handle escape sequences by skipping both \ and next char */
+ if (*str == '\\') {
+ *fmt = prev; fmt++; str++;
+ if (*str == '\0') break;
+ *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
+ continue;
+ }
+ /* Handle continuations */
+ else if (cont) {
+ /* Triple strings ("""...""" or '''...''') */
+ if (cont & FMT_CONT_TRIPLE) {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find && *(str + 1) == find && *(str + 2) == find) {
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ cont = FMT_CONT_NOP;
+ }
+ /* Handle other strings */
+ }
+ else {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find) cont = FMT_CONT_NOP;
+ }
+
+ *fmt = FMT_TYPE_STRING;
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ /* Not in a string... */
+ else {
+ /* Deal with comments first */
+ if (*str == '#') {
+ /* fill the remaining line */
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ }
+ else if (*str == '"' || *str == '\'') {
+ /* Strings */
+ find = *str;
+ cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
+ if (*(str + 1) == find && *(str + 2) == find) {
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ cont |= FMT_CONT_TRIPLE;
+ }
+ *fmt = FMT_TYPE_STRING;
+ }
+ /* Whitespace (all ws. has been converted to spaces) */
+ else if (*str == ' ') {
+ *fmt = FMT_TYPE_WHITESPACE;
+ }
+ /* Numbers (digits not part of an identifier and periods followed by digits) */
+ else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
+ (*str == '.' && text_check_digit(*(str + 1))))
+ {
+ *fmt = FMT_TYPE_NUMERAL;
+ }
+ /* Booleans */
+ else if (prev != FMT_TYPE_DEFAULT && (i = txtfmt_py_find_bool(str)) != -1) {
+ if (i > 0) {
+ text_format_fill_ascii(&str, &fmt, FMT_TYPE_NUMERAL, i);
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ /* Punctuation */
+ else if ((*str != '@') && text_check_delim(*str)) {
+ *fmt = FMT_TYPE_SYMBOL;
+ }
+ /* Identifiers and other text (no previous ws. or delims. so text continues) */
+ else if (prev == FMT_TYPE_DEFAULT) {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
+ else {
+ /* Special vars(v) or built-in keywords(b) */
+ /* keep in sync with 'txtfmt_py_format_identifier()' */
+ if ((i = txtfmt_py_find_specialvar(str)) != -1) prev = FMT_TYPE_SPECIAL;
+ else if ((i = txtfmt_py_find_builtinfunc(str)) != -1) prev = FMT_TYPE_KEYWORD;
+ else if ((i = txtfmt_py_find_decorator(str)) != -1) prev = FMT_TYPE_DIRECTIVE;
+
+ if (i > 0) {
+ if (prev == FMT_TYPE_DIRECTIVE) { /* can contain utf8 */
+ text_format_fill(&str, &fmt, prev, i);
+ }
+ else {
+ text_format_fill_ascii(&str, &fmt, prev, i);
+ }
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ }
+ prev = *fmt; fmt++; str++;
+ }
+
+ /* Terminate and add continuation char */
+ *fmt = '\0'; fmt++;
+ *fmt = cont;
+
+ /* If continuation has changed and we're allowed, process the next line */
+ if (cont != cont_orig && do_next && line->next) {
+ txtfmt_py_format_line(st, line->next, do_next);
+ }
+
+ flatten_string_free(&fs);
+}
+
+void ED_text_format_register_py(void)
+{
+ static TextFormatType tft = {0};
+ static const char *ext[] = {"py", NULL};
+
+ tft.format_identifier = txtfmt_py_format_identifier;
+ tft.format_line = txtfmt_py_format_line;
+ tft.ext = ext;
+
+ ED_text_format_register(&tft);
+}
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index 7dc3ec1ac60..605a08e587a 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -29,20 +29,11 @@
*/
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
/* file time checking */
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#ifndef _WIN32
-# include <unistd.h>
#else
-# include <io.h>
-# include "BLI_winstuff.h"
#endif
#include "DNA_windowmanager_types.h"
@@ -50,7 +41,8 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
+
+#include "BLF_translation.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -130,7 +122,7 @@ void TEXT_OT_properties(wmOperatorType *ot)
uiPopupMenu *pup;
if (text) {
- pup = uiPupMenuBegin(C, "Text", ICON_NONE);
+ pup = uiPupMenuBegin(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");
@@ -144,7 +136,7 @@ void TEXT_OT_properties(wmOperatorType *ot)
uiPupMenuEnd(C, pup);
}
else {
- pup = uiPupMenuBegin(C, "File", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("File"), ICON_NONE);
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
uiPupMenuEnd(C, pup);
@@ -156,7 +148,7 @@ void TEXT_OT_properties(wmOperatorType *ot)
uiPopupMenu *pup;
- pup = uiPupMenuBegin(C, "Edit", ICON_NONE);
+ pup = uiPupMenuBegin(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");
@@ -169,7 +161,7 @@ void TEXT_OT_properties(wmOperatorType *ot)
uiPopupMenu *pup;
if (text) {
- pup = uiPupMenuBegin(C, "Text", ICON_NONE);
+ pup = uiPupMenuBegin(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");
@@ -178,7 +170,7 @@ void TEXT_OT_properties(wmOperatorType *ot)
uiPupMenuEnd(C, pup);
}
else {
- pup = uiPupMenuBegin(C, "File", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("File"), ICON_NONE);
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
uiPupMenuEnd(C, pup);
@@ -190,11 +182,14 @@ void TEXT_OT_properties(wmOperatorType *ot)
uiPopupMenu *pup;
- pup = uiPupMenuBegin(C, "Text", ICON_NONE);
- uiItemEnumO(layout, "TEXT_OT_move", "Top of File", 0, "type", FILE_TOP);
- uiItemEnumO(layout, "TEXT_OT_move", "Bottom of File", 0, "type", FILE_BOTTOM);
- uiItemEnumO(layout, "TEXT_OT_move", "Page Up", 0, "type", PREV_PAGE);
- uiItemEnumO(layout, "TEXT_OT_move", "Page Down", 0, "type", NEXT_PAGE);
+ pup = uiPupMenuBegin(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"),
+ 0, "type", FILE_BOTTOM);
+ 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);
}
#endif
diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h
index ea61644cee9..799bc49b624 100644
--- a/source/blender/editors/space_text/text_intern.h
+++ b/source/blender/editors/space_text/text_intern.h
@@ -54,12 +54,11 @@ void text_scroll_to_cursor(struct SpaceText *st, struct ScrArea *sa);
void text_update_cursor_moved(struct bContext *C);
/* TXT_OFFSET used to be 35 when the scrollbar was on the left... */
-#define TXT_OFFSET 15
-#define TXT_SCROLL_WIDTH 20
-#define TXT_SCROLL_SPACE 2
-#define TXT_LINE_SPACING 4 /* space between lines */
-
-#define TEXTXLOC (st->cwidth * st->linenrs_tot)
+#define TXT_OFFSET ((int)(0.75f * U.widget_unit))
+#define TXT_SCROLL_WIDTH U.widget_unit
+#define TXT_SCROLL_SPACE ((int)(0.1f * U.widget_unit))
+#define TXT_LINE_SPACING ((int)(0.2f * U.widget_unit)) /* space between lines */
+#define TEXTXLOC (st->cwidth * st->linenrs_tot)
#define SUGG_LIST_SIZE 7
#define SUGG_LIST_WIDTH 20
@@ -69,18 +68,6 @@ void text_update_cursor_moved(struct bContext *C);
#define TOOL_SUGG_LIST 0x01
#define TOOL_DOCUMENT 0x02
-typedef struct FlattenString {
- char fixedbuf[256];
- int fixedaccum[256];
-
- char *buf;
- int *accum;
- int pos, len;
-} FlattenString;
-
-int flatten_string(struct SpaceText *st, FlattenString *fs, const char *in);
-void flatten_string_free(FlattenString *fs);
-
int wrap_width(struct SpaceText *st, struct ARegion *ar);
void wrap_offset(struct SpaceText *st, struct ARegion *ar, struct TextLine *linein, int cursin, int *offl, int *offc);
void wrap_offset_in_line(struct SpaceText *st, struct ARegion *ar, struct TextLine *linep, int cursin, int *offl, int *offc);
@@ -156,6 +143,11 @@ void TEXT_OT_to_3d_object(struct wmOperatorType *ot);
void TEXT_OT_resolve_conflict(struct wmOperatorType *ot);
+int text_space_edit_poll(struct bContext *C);
+
+/* text_autocomplete.c */
+void TEXT_OT_autocomplete(struct wmOperatorType *ot);
+
/* space_text.c */
extern const char *text_context_dir[]; /* doc access */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 5b7f92739ed..b45961bff11 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -30,19 +30,14 @@
*/
-#include <stdlib.h>
#include <string.h>
-#include <ctype.h> /* ispunct */
-#include <sys/stat.h>
#include <errno.h>
#include "MEM_guardedalloc.h"
#include "DNA_text_types.h"
-#include "DNA_userdef_types.h"
#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -72,6 +67,7 @@
#endif
#include "text_intern.h"
+#include "text_format.h"
/************************ poll ***************************/
@@ -102,7 +98,7 @@ static int text_edit_poll(bContext *C)
return 1;
}
-static int text_space_edit_poll(bContext *C)
+int text_space_edit_poll(bContext *C)
{
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
@@ -165,11 +161,12 @@ void text_update_edited(Text *text)
static int text_new_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceText *st = CTX_wm_space_text(C);
+ Main *bmain = CTX_data_main(C);
Text *text;
PointerRNA ptr, idptr;
PropertyRNA *prop;
- text = BKE_text_add("Text");
+ text = BKE_text_add(bmain, "Text");
/* hook into UI */
uiIDContextProperty(C, &ptr, &prop);
@@ -230,6 +227,7 @@ static int text_open_cancel(bContext *UNUSED(C), wmOperator *op)
static int text_open_exec(bContext *C, wmOperator *op)
{
SpaceText *st = CTX_wm_space_text(C);
+ Main *bmain = CTX_data_main(C);
Text *text;
PropertyPointerRNA *pprop;
PointerRNA idptr;
@@ -238,7 +236,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", str);
- text = BKE_text_load(str, G.main->name);
+ text = BKE_text_load(bmain, str, G.main->name);
if (!text) {
if (op->customdata) MEM_freeN(op->customdata);
@@ -1131,21 +1129,20 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
TextLine *tmp;
FlattenString fs;
size_t a, j;
- char *text_check_line, *new_line;
+ char *new_line;
int extra, number; //unknown for now
int type = RNA_enum_get(op->ptr, "type");
-
- tmp = text->lines.first;
-
+
/* first convert to all space, this make it a lot easier to convert to tabs
* because there is no mixtures of ' ' && '\t' */
- while (tmp) {
- text_check_line = tmp->line;
+ for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+ const char *text_check_line = tmp->line;
+ const int text_check_line_len = tmp->len;
number = flatten_string(st, &fs, text_check_line) + 1;
flatten_string_free(&fs);
new_line = MEM_callocN(number, "Converted_Line");
j = 0;
- for (a = 0; a < strlen(text_check_line); a++) { //foreach char in line
+ for (a = 0; a < text_check_line_len; a++) { //foreach char in line
if (text_check_line[a] == '\t') { //checking for tabs
//get the number of spaces this tabs is showing
//i don't like doing it this way but will look into it later
@@ -1175,20 +1172,19 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
tmp->line = new_line;
tmp->len = strlen(new_line);
tmp->format = NULL;
- tmp = tmp->next;
}
if (type == TO_TABS) { // Converting to tabs
//start over from the beginning
- tmp = text->lines.first;
- while (tmp) {
- text_check_line = tmp->line;
+ for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+ const char *text_check_line = tmp->line;
+ const int text_check_line_len = tmp->len;
extra = 0;
- for (a = 0; a < strlen(text_check_line); a++) {
+ for (a = 0; a < text_check_line_len; a++) {
number = 0;
for (j = 0; j < (size_t)st->tabnumber; j++) {
- if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line
+ if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
if (text_check_line[a + j] != ' ') {
number = 1;
}
@@ -1201,12 +1197,12 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
}
if (extra > 0) { //got tabs make malloc and do what you have to do
- new_line = MEM_callocN(strlen(text_check_line) - (((st->tabnumber * extra) - extra) - 1), "Converted_Line");
+ new_line = MEM_callocN(text_check_line_len - (((st->tabnumber * extra) - extra) - 1), "Converted_Line");
extra = 0; //reuse vars
- for (a = 0; a < strlen(text_check_line); a++) {
+ for (a = 0; a < text_check_line_len; a++) {
number = 0;
for (j = 0; j < (size_t)st->tabnumber; j++) {
- if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line
+ if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
if (text_check_line[a + j] != ' ') {
number = 1;
}
@@ -1233,7 +1229,6 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
tmp->len = strlen(new_line);
tmp->format = NULL;
}
- tmp = tmp->next;
}
}
@@ -1317,9 +1312,11 @@ void TEXT_OT_select_line(wmOperatorType *ot)
static int text_select_word_exec(bContext *C, wmOperator *UNUSED(op))
{
Text *text = CTX_data_edit_text(C);
+ /* don't advance cursor before stepping */
+ const bool use_init_step = false;
- txt_jump_left(text, 0);
- txt_jump_right(text, 1);
+ txt_jump_left(text, false, use_init_step);
+ txt_jump_right(text, true, use_init_step);
text_update_cursor_moved(C);
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
@@ -1821,11 +1818,11 @@ static int text_move_cursor(bContext *C, int type, int select)
break;
case PREV_WORD:
- txt_jump_left(text, select);
+ txt_jump_left(text, select, true);
break;
case NEXT_WORD:
- txt_jump_right(text, select);
+ txt_jump_right(text, select, true);
break;
case PREV_CHAR:
@@ -1932,12 +1929,14 @@ static int text_jump_exec(bContext *C, wmOperator *op)
static int text_jump_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
- return WM_operator_props_dialog_popup(C, op, 200, 100);
+ return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y);
}
void TEXT_OT_jump(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Jump";
ot->idname = "TEXT_OT_jump";
@@ -1949,7 +1948,8 @@ void TEXT_OT_jump(wmOperatorType *ot)
ot->poll = text_edit_poll;
/* properties */
- RNA_def_int(ot->srna, "line", 1, 1, INT_MAX, "Line", "Line number to jump to", 1, 10000);
+ prop = RNA_def_int(ot->srna, "line", 1, 1, INT_MAX, "Line", "Line number to jump to", 1, 10000);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_TEXT);
}
/******************* delete operator **********************/
@@ -2106,10 +2106,10 @@ static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
if (!tsc->scrollbar) {
txtdelta[0] = -tsc->delta[0] / st->cwidth;
- txtdelta[1] = tsc->delta[1] / (st->lheight + TXT_LINE_SPACING);
+ txtdelta[1] = tsc->delta[1] / (st->lheight_dpi + TXT_LINE_SPACING);
tsc->delta[0] %= st->cwidth;
- tsc->delta[1] %= (st->lheight + TXT_LINE_SPACING);
+ tsc->delta[1] %= (st->lheight_dpi + TXT_LINE_SPACING);
}
else {
txtdelta[1] = -tsc->delta[1] * st->pix_per_line;
@@ -2204,7 +2204,7 @@ static int text_scroll_invoke(bContext *C, wmOperator *op, wmEvent *event)
tsc->old[1] = event->y;
/* Sensitivity of scroll set to 4pix per line/char */
tsc->delta[0] = (event->x - event->prevx) * st->cwidth / 4;
- tsc->delta[1] = (event->y - event->prevy) * st->lheight / 4;
+ tsc->delta[1] = (event->y - event->prevy) * st->lheight_dpi / 4;
tsc->first = 0;
tsc->scrollbar = 0;
text_scroll_apply(C, op, event);
@@ -2503,7 +2503,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
{
Text *text = st->text;
text_update_character_width(st);
- y = (ar->winy - 2 - y) / (st->lheight + TXT_LINE_SPACING);
+ y = (ar->winy - 2 - y) / (st->lheight_dpi + TXT_LINE_SPACING);
if (st->showlinenrs) x -= TXT_OFFSET + TEXTXLOC;
else x -= TXT_OFFSET;
@@ -3110,27 +3110,31 @@ static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *UN
case 1:
if (text->flags & TXT_ISDIRTY) {
/* modified locally and externally, ahhh. offer more possibilites. */
- pup = uiPupMenuBegin(C, "File Modified Outside and Inside Blender", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE);
layout = uiPupMenuLayout(pup);
- uiItemEnumO_ptr(layout, op->type, "Reload from disk (ignore local changes)", 0, "resolution", RESOLVE_RELOAD);
- uiItemEnumO_ptr(layout, op->type, "Save to disk (ignore outside changes)", 0, "resolution", RESOLVE_SAVE);
- uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL);
+ 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);
}
else {
- pup = uiPupMenuBegin(C, "File Modified Outside Blender", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("File Modified Outside Blender"), ICON_NONE);
layout = uiPupMenuLayout(pup);
- uiItemEnumO_ptr(layout, op->type, "Reload from disk", 0, "resolution", RESOLVE_RELOAD);
- uiItemEnumO_ptr(layout, op->type, "Make text internal (separate copy)", 0, "resolution", RESOLVE_MAKE_INTERNAL);
- uiItemEnumO_ptr(layout, op->type, "Ignore", 0, "resolution", RESOLVE_IGNORE);
+ 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);
}
break;
case 2:
- pup = uiPupMenuBegin(C, "File Deleted Outside Blender", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("File Deleted Outside Blender"), ICON_NONE);
layout = uiPupMenuLayout(pup);
- uiItemEnumO_ptr(layout, op->type, "Make text internal", 0, "resolution", RESOLVE_MAKE_INTERNAL);
- uiItemEnumO_ptr(layout, op->type, "Recreate file", 0, "resolution", RESOLVE_SAVE);
+ 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);
break;
}
diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c
deleted file mode 100644
index 4c9b4b900cc..00000000000
--- a/source/blender/editors/space_text/text_python.c
+++ /dev/null
@@ -1,361 +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.
- * All rights reserved.
- *
- *
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/space_text/text_python.c
- * \ingroup sptext
- */
-
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_text_types.h"
-
-#include "BKE_suggestions.h"
-#include "BKE_text.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
-#include "WM_types.h"
-
-#include "text_intern.h"
-
-int text_do_suggest_select(SpaceText *st, ARegion *ar)
-{
- SuggItem *item, *first, *last /* , *sel */ /* UNUSED */;
- TextLine *tmp;
- int l, x, y, w, h, i;
- int tgti, *top;
- int mval[2] = {0, 0};
-
- if (!st || !st->text) return 0;
- if (!texttool_text_is_active(st->text)) return 0;
-
- first = texttool_suggest_first();
- last = texttool_suggest_last();
- /* sel = texttool_suggest_selected(); */ /* UNUSED */
- top = texttool_suggest_top();
-
- if (!last || !first)
- return 0;
-
- /* Count the visible lines to the cursor */
- for (tmp = st->text->curl, l = -st->top; tmp; tmp = tmp->prev, l++) ;
- if (l < 0) return 0;
-
- text_update_character_width(st);
-
- if (st->showlinenrs) {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET + TEXTXLOC - 4;
- }
- else {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
- }
- y = ar->winy - st->lheight * l - 2;
-
- w = SUGG_LIST_WIDTH * st->cwidth + 20;
- h = SUGG_LIST_SIZE * st->lheight + 8;
-
- // XXX getmouseco_areawin(mval);
-
- if (mval[0] < x || x + w < mval[0] || mval[1] < y - h || y < mval[1])
- return 0;
-
- /* Work out which of the items is at the top of the visible list */
- for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ;
-
- /* Work out the target item index in the visible list */
- tgti = (y - mval[1] - 4) / st->lheight;
- if (tgti < 0 || tgti > SUGG_LIST_SIZE)
- return 1;
-
- for (i = tgti; i > 0 && item->next; i--, item = item->next) ;
- if (item)
- texttool_suggest_select(item);
- return 1;
-}
-
-void text_pop_suggest_list(void)
-{
- SuggItem *item, *sel;
- int *top, i;
-
- item = texttool_suggest_first();
- sel = texttool_suggest_selected();
- top = texttool_suggest_top();
-
- i = 0;
- while (item && item != sel) {
- item = item->next;
- i++;
- }
- if (i > *top + SUGG_LIST_SIZE - 1)
- *top = i - SUGG_LIST_SIZE + 1;
- else if (i < *top)
- *top = i;
-}
-
-static void get_suggest_prefix(Text *text, int offset)
-{
- int i, len;
- char *line, tmp[256];
-
- if (!text) return;
- if (!texttool_text_is_active(text)) return;
-
- line = text->curl->line;
- for (i = text->curc - 1 + offset; i >= 0; i--)
- if (!text_check_identifier(line[i]))
- break;
- i++;
- len = text->curc - i + offset;
- if (len > 255) {
- printf("Suggestion prefix too long\n");
- len = 255;
- }
- BLI_strncpy(tmp, line + i, len);
- tmp[len] = '\0';
- texttool_suggest_prefix(tmp);
-}
-
-static void confirm_suggestion(Text *text, int skipleft)
-{
- SuggItem *sel;
- int i, over = 0;
- char *line;
-
- if (!text) return;
- if (!texttool_text_is_active(text)) return;
-
- sel = texttool_suggest_selected();
- if (!sel) return;
-
- line = text->curl->line;
- i = text->curc - skipleft - 1;
- while (i >= 0) {
- if (!text_check_identifier(line[i]))
- break;
- over++;
- i--;
- }
-
- for (i = 0; i < skipleft; i++)
- txt_move_left(text, 0);
- for (i = 0; i < over; i++)
- txt_move_left(text, 1);
-
- txt_insert_buf(text, sel->name);
-
- for (i = 0; i < skipleft; i++)
- txt_move_right(text, 0);
-
- texttool_text_clear();
-}
-
-// XXX
-#define LR_SHIFTKEY 0
-#define LR_ALTKEY 0
-#define LR_CTRLKEY 0
-
-// XXX
-static int doc_scroll = 0;
-
-static short UNUSED_FUNCTION(do_texttools) (SpaceText * st, char ascii, unsigned short evnt, short val)
-{
- ARegion *ar = NULL; // XXX
- int qual = 0; // XXX
- int draw = 0, tools = 0, swallow = 0, scroll = 1;
- if (!texttool_text_is_active(st->text)) return 0;
- if (!st->text || st->text->id.lib) return 0;
-
- if (st->doplugins && texttool_text_is_active(st->text)) {
- if (texttool_suggest_first()) tools |= TOOL_SUGG_LIST;
- if (texttool_docs_get()) tools |= TOOL_DOCUMENT;
- }
-
- if (ascii) {
- if (tools & TOOL_SUGG_LIST) {
- if ((ascii != '_' && ascii != '*' && ispunct(ascii)) || text_check_whitespace(ascii)) {
- confirm_suggestion(st->text, 0);
- text_update_line_edited(st->text->curl);
- }
- else if ((st->overwrite && txt_replace_char(st->text, ascii)) || txt_add_char(st->text, ascii)) {
- get_suggest_prefix(st->text, 0);
- text_pop_suggest_list();
- swallow = 1;
- draw = 1;
- }
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
-
- }
- else if (val == 1 && evnt) {
- switch (evnt) {
- case LEFTMOUSE:
- if (text_do_suggest_select(st, ar))
- swallow = 1;
- else {
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- }
- draw = 1;
- break;
- case MIDDLEMOUSE:
- if (text_do_suggest_select(st, ar)) {
- confirm_suggestion(st->text, 0);
- text_update_line_edited(st->text->curl);
- swallow = 1;
- }
- else {
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- }
- draw = 1;
- break;
- case ESCKEY:
- draw = swallow = 1;
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
- else if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- else draw = swallow = 0;
- break;
- case RETKEY:
- if (tools & TOOL_SUGG_LIST) {
- confirm_suggestion(st->text, 0);
- text_update_line_edited(st->text->curl);
- swallow = 1;
- draw = 1;
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
- break;
- case LEFTARROWKEY:
- case BACKSPACEKEY:
- if (tools & TOOL_SUGG_LIST) {
- if (qual)
- texttool_suggest_clear();
- else {
- /* Work out which char we are about to delete/pass */
- if (st->text->curl && st->text->curc > 0) {
- char ch = st->text->curl->line[st->text->curc - 1];
- if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
- get_suggest_prefix(st->text, -1);
- text_pop_suggest_list();
- }
- else
- texttool_suggest_clear();
- }
- else
- texttool_suggest_clear();
- }
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- break;
- case RIGHTARROWKEY:
- if (tools & TOOL_SUGG_LIST) {
- if (qual)
- texttool_suggest_clear();
- else {
- /* Work out which char we are about to pass */
- if (st->text->curl && st->text->curc < st->text->curl->len) {
- char ch = st->text->curl->line[st->text->curc + 1];
- if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
- get_suggest_prefix(st->text, 1);
- text_pop_suggest_list();
- }
- else
- texttool_suggest_clear();
- }
- else
- texttool_suggest_clear();
- }
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- break;
- case PAGEDOWNKEY:
- scroll = SUGG_LIST_SIZE - 1;
- case WHEELDOWNMOUSE:
- case DOWNARROWKEY:
- if (tools & TOOL_DOCUMENT) {
- doc_scroll++;
- swallow = 1;
- draw = 1;
- break;
- }
- else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- if (!sel) {
- texttool_suggest_select(texttool_suggest_first());
- }
- else {
- while (sel && sel != texttool_suggest_last() && sel->next && scroll--) {
- texttool_suggest_select(sel->next);
- sel = sel->next;
- }
- }
- text_pop_suggest_list();
- swallow = 1;
- draw = 1;
- break;
- }
- case PAGEUPKEY:
- scroll = SUGG_LIST_SIZE - 1;
- case WHEELUPMOUSE:
- case UPARROWKEY:
- if (tools & TOOL_DOCUMENT) {
- if (doc_scroll > 0) doc_scroll--;
- swallow = 1;
- draw = 1;
- break;
- }
- else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- while (sel && sel != texttool_suggest_first() && sel->prev && scroll--) {
- texttool_suggest_select(sel->prev);
- sel = sel->prev;
- }
- text_pop_suggest_list();
- swallow = 1;
- draw = 1;
- break;
- }
- case RIGHTSHIFTKEY:
- case LEFTSHIFTKEY:
- break;
- default:
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(), draw = 1;
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
- }
- }
-
- if (draw) {
- // XXX redraw_alltext();
- }
-
- return swallow;
-}
diff --git a/source/blender/editors/space_time/SConscript b/source/blender/editors/space_time/SConscript
index c08339ba692..32f02bff008 100644
--- a/source/blender/editors/space_time/SConscript
+++ b/source/blender/editors/space_time/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 13c1938d77c..e5bd9e62c74 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -92,7 +92,7 @@ static void time_draw_sfra_efra(Scene *scene, View2D *v2d)
#define CACHE_DRAW_HEIGHT 3.0f
-static void time_draw_cache(SpaceTime *stime, Object *ob)
+static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
{
PTCacheID *pid;
ListBase pidlist;
@@ -102,7 +102,7 @@ static void time_draw_cache(SpaceTime *stime, Object *ob)
if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob))
return;
- BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
+ BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
/* iterate over pointcaches on the active object,
* add spacetimecache and vertex array for each */
@@ -128,6 +128,9 @@ static void time_draw_cache(SpaceTime *stime, Object *ob)
case PTCACHE_TYPE_DYNAMICPAINT:
if (!(stime->cache_display & TIME_CACHE_DYNAMICPAINT)) continue;
break;
+ case PTCACHE_TYPE_RIGIDBODY:
+ if (!(stime->cache_display & TIME_CACHE_RIGIDBODY)) continue;
+ break;
}
if (pid->cache->cached_frames == NULL)
@@ -193,6 +196,10 @@ static void time_draw_cache(SpaceTime *stime, Object *ob)
col[0] = 1.0; col[1] = 0.1; col[2] = 0.75;
col[3] = 0.1;
break;
+ case PTCACHE_TYPE_RIGIDBODY:
+ col[0] = 1.0; col[1] = 0.6; col[2] = 0.0;
+ col[3] = 0.1;
+ break;
default:
BLI_assert(0);
col[0] = 1.0; col[1] = 0.0; col[2] = 1.0;
@@ -499,7 +506,7 @@ static void time_main_area_draw(const bContext *C, ARegion *ar)
draw_markers_time(C, 0);
/* caches */
- time_draw_cache(stime, obact);
+ time_draw_cache(stime, obact, scene);
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -648,6 +655,7 @@ static void time_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
stime->cache_display |= TIME_CACHE_DISPLAY;
stime->cache_display |= (TIME_CACHE_SOFTBODY | TIME_CACHE_PARTICLES);
stime->cache_display |= (TIME_CACHE_CLOTH | TIME_CACHE_SMOKE | TIME_CACHE_DYNAMICPAINT);
+ stime->cache_display |= TIME_CACHE_RIGIDBODY;
}
static SpaceLink *time_duplicate(SpaceLink *sl)
diff --git a/source/blender/editors/space_userpref/SConscript b/source/blender/editors/space_userpref/SConscript
index 5c52e6f4c41..d5aa9304364 100644
--- a/source/blender/editors/space_userpref/SConscript
+++ b/source/blender/editors/space_userpref/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 1ea3876f5cc..5ebbebec35b 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -105,14 +105,16 @@ static SpaceLink *userpref_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void userpref_main_area_init(wmWindowManager *wm, ARegion *ar)
{
+ /* do not use here, the properties changed in userprefs do a system-wide refresh, then scroller jumps back */
+ /* ar->v2d.flag &= ~V2D_IS_INITIALISED; */
+
+ ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
+
ED_region_panels_init(wm, ar);
}
static void userpref_main_area_draw(const bContext *C, ARegion *ar)
{
- /* this solves "vibrating UI" bug #25422 */
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
-
ED_region_panels(C, ar, 1, NULL, -1);
}
diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript
index ffe35019960..578f06ada16 100644
--- a/source/blender/editors/space_view3d/SConscript
+++ b/source/blender/editors/space_view3d/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index 0649edc1ac4..57864854734 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -139,35 +139,38 @@ void draw_motion_path_instance(Scene *scene,
short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
float intensity; /* how faint */
+ int frame = sfra + i;
+ int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */
+
/* set color
* - more intense for active/selected bones, less intense for unselected bones
* - black for before current frame, green for current frame, blue for after current frame
* - intensity decreases as distance from current frame increases
*/
#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min)
- if ((sfra + i) < CFRA) {
+ if (frame < CFRA) {
/* black - before cfra */
if (sel) {
- // intensity = 0.5f;
+ /* intensity = 0.5f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f);
}
else {
- //intensity = 0.8f;
+ /* intensity = 0.8f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
+ UI_ThemeColorBlend(TH_WIRE, blend_base, intensity);
}
- else if ((sfra + i) > CFRA) {
+ else if (frame > CFRA) {
/* blue - after cfra */
if (sel) {
- //intensity = 0.5f;
+ /* intensity = 0.5f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f);
}
else {
- //intensity = 0.8f;
+ /* intensity = 0.8f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
+ UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity);
}
else {
/* green - on cfra */
@@ -232,21 +235,22 @@ void draw_motion_path_instance(Scene *scene,
col[3] = 255;
for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
+ int frame = sfra + i;
char numstr[32];
float co[3];
/* only draw framenum if several consecutive highlighted points don't occur on same point */
if (i == 0) {
- sprintf(numstr, "%d", (i + sfra));
+ sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
- else if ((i > stepsize) && (i < len - stepsize)) {
+ else if ((i >= stepsize) && (i < len - stepsize)) {
bMotionPathVert *mpvP = (mpv - stepsize);
bMotionPathVert *mpvN = (mpv + stepsize);
if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
- sprintf(numstr, "%d", (sfra + i));
+ sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
@@ -286,12 +290,13 @@ void draw_motion_path_instance(Scene *scene,
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
col[3] = 255;
- glPointSize(4.0f); // XXX perhaps a bit too big
+ glPointSize(4.0f);
glColor3ubv(col);
glBegin(GL_POINTS);
for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
- float mframe = (float)(sfra + i);
+ int frame = sfra + i;
+ float mframe = (float)(frame);
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
glVertex3fv(mpv->co);
@@ -309,7 +314,7 @@ void draw_motion_path_instance(Scene *scene,
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
char numstr[32];
- sprintf(numstr, "%d", (sfra + i));
+ sprintf(numstr, " %d", (sfra + i));
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index beafee335d4..f37437b159d 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -637,7 +637,7 @@ static float co[16] = {
/* smat, imat = mat & imat to draw screenaligned */
-static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel *pchan, EditBone *ebone)
+static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChannel *pchan, EditBone *ebone)
{
float head, tail, dist /*, length*/;
float *headvec, *tailvec, dirvec[3];
@@ -755,7 +755,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel
/* smat, imat = mat & imat to draw screenaligned */
-static void draw_sphere_bone_wire(float smat[][4], float imat[][4],
+static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
int armflag, int boneflag, short constflag, unsigned int id,
bPoseChannel *pchan, EditBone *ebone)
{
@@ -1648,7 +1648,7 @@ static void draw_pose_dofs(Object *ob)
}
}
-static void bone_matrix_translate_y(float mat[][4], float y)
+static void bone_matrix_translate_y(float mat[4][4], float y)
{
float trans[3];
@@ -2069,7 +2069,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
/* in editmode, we don't store the bone matrix... */
-static void get_matrix_editbone(EditBone *eBone, float bmat[][4])
+static void get_matrix_editbone(EditBone *eBone, float bmat[4][4])
{
float delta[3];
float mat[3][3];
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 0ecde350b00..2cef10e1981 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -236,8 +236,9 @@ static struct TextureDrawState {
Object *ob;
int is_lit, is_tex;
int color_profile;
+ bool use_backface_culling;
unsigned char obcol[4];
-} Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
+} Gtexdraw = {NULL, 0, 0, 0, false, {0, 0, 0, 0}};
static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
{
@@ -250,7 +251,7 @@ static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *m
static int c_has_texface;
Object *litob = NULL; /* to get mode to turn off mipmap in painting mode */
- int backculled = GEMAT_BACKCULL;
+ int backculled = GEMAT_BACKCULL || gtexdraw.use_backface_culling;
int alphablend = 0;
int textured = 0;
int lit = 0;
@@ -274,7 +275,7 @@ static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *m
if (ma) {
alphablend = ma->game.alpha_blend;
if (ma->mode & MA_SHLESS) lit = 0;
- backculled = ma->game.flag & GEMAT_BACKCULL;
+ backculled = (ma->game.flag & GEMAT_BACKCULL) || gtexdraw.use_backface_culling;
}
if (texface) {
@@ -375,17 +376,12 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
Gtexdraw.is_tex = is_tex;
Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
+ Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
glShadeModel(GL_SMOOTH);
- if (v3d->flag2 & V3D_BACKFACE_CULLING) {
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- }
- else {
- glDisable(GL_CULL_FACE);
- }
+ glCullFace(GL_BACK);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TWOSIDED) ? GL_TRUE : GL_FALSE);
}
@@ -396,6 +392,7 @@ static void draw_textured_end(void)
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
/* XXX, bad patch - GPU_default_lights() calls
* glLightfv(GL_POSITION, ...) which
@@ -415,14 +412,14 @@ static void draw_textured_end(void)
static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
{
Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
- int validtexture = 0;
+ int invalidtexture = 0;
if (ma && (ma->game.flag & GEMAT_INVISIBLE))
return DM_DRAW_OPTION_SKIP;
- validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
+ invalidtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
- if (tface && validtexture) {
+ if (tface && invalidtexture) {
glColor3ub(0xFF, 0x00, 0xFF);
return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
}
@@ -457,25 +454,17 @@ static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mc
return DM_DRAW_OPTION_NO_MCOL;
}
-static DMDrawOption draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
+static DMDrawOption draw_tface__set_draw(MTFace *tface, int UNUSED(has_mcol), int matnr)
{
Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
- if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
- return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
- }
- else if (tface && (tface->mode & TF_OBCOL)) {
- return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
- }
- else if (!has_mcol) {
- /* XXX: this return value looks wrong (and doesn't match comment) */
- return DM_DRAW_OPTION_NORMAL; /* Don't set color */
- }
- else {
- return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
- }
+ if (tface)
+ set_draw_settings_cached(0, tface, ma, Gtexdraw);
+
+ /* always use color from mcol, as set in update_tface_color_layer */
+ return DM_DRAW_OPTION_NORMAL;
}
static void update_tface_color_layer(DerivedMesh *dm)
@@ -517,11 +506,11 @@ static void update_tface_color_layer(DerivedMesh *dm)
finalCol[i * 4 + j].r = 255;
}
}
- else if (tface && (tface->mode & TF_OBCOL)) {
+ else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
for (j = 0; j < 4; j++) {
- finalCol[i * 4 + j].b = FTOCHAR(Gtexdraw.obcol[0]);
- finalCol[i * 4 + j].g = FTOCHAR(Gtexdraw.obcol[1]);
- finalCol[i * 4 + j].r = FTOCHAR(Gtexdraw.obcol[2]);
+ finalCol[i * 4 + j].b = Gtexdraw.obcol[0];
+ finalCol[i * 4 + j].g = Gtexdraw.obcol[1];
+ finalCol[i * 4 + j].r = Gtexdraw.obcol[2];
}
}
else if (!mcol) {
@@ -947,7 +936,8 @@ static int tex_mat_set_face_editmesh_cb(void *userData, int index)
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
Object *ob, DerivedMesh *dm, const int draw_flags)
{
- if ((!BKE_scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_MODIFIERS_PREVIEW)) {
+ /* if not cycles, or preview-modifiers, or drawing matcaps */
+ if ((!BKE_scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_MODIFIERS_PREVIEW) || (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)) {
draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
return;
}
@@ -1029,7 +1019,7 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
const short do_light = (v3d->drawtype >= OB_SOLID);
/* hide faces in face select mode */
- if (draw_flags & DRAW_FACE_SELECT)
+ if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL))
facemask = wpaint__setSolidDrawOptions_facemask;
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
@@ -1077,12 +1067,18 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
draw_mesh_face_select(rv3d, me, dm);
}
else if ((do_light == FALSE) || (ob->dtx & OB_DRAWWIRE)) {
+ const int use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT);
/* weight paint in solid mode, special case. focus on making the weights clear
* rather than the shading, this is also forced in wire view */
- bglPolygonOffset(rv3d->dist, 1.0);
- glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
+ if (use_depth) {
+ bglPolygonOffset(rv3d->dist, 1.0);
+ glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
+ }
+ else {
+ glDisable(GL_DEPTH_TEST);
+ }
glEnable(GL_BLEND);
glColor4ub(255, 255, 255, 96);
@@ -1091,8 +1087,14 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
dm->drawEdges(dm, 1, 1);
- bglPolygonOffset(rv3d->dist, 0.0);
- glDepthMask(1);
+ if (use_depth) {
+ bglPolygonOffset(rv3d->dist, 0.0);
+ glDepthMask(1);
+ }
+ else {
+ glEnable(GL_DEPTH_TEST);
+ }
+
glDisable(GL_LINE_STIPPLE);
glDisable(GL_BLEND);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 5ac7327b93b..5d669974711 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -88,6 +88,7 @@
#include "ED_types.h"
#include "UI_resources.h"
+#include "UI_interface_icons.h"
#include "WM_api.h"
#include "BLF_api.h"
@@ -101,7 +102,7 @@ typedef enum eWireDrawMode {
} eWireDrawMode;
typedef struct drawDMVerts_userData {
- BMEditMesh *em; /* BMESH BRANCH ONLY */
+ BMEditMesh *em;
int sel;
BMVert *eve_act;
@@ -119,7 +120,7 @@ typedef struct drawDMVerts_userData {
} drawDMVerts_userData;
typedef struct drawDMEdgesSel_userData {
- BMEditMesh *em; /* BMESH BRANCH ONLY */
+ BMEditMesh *em;
unsigned char *baseCol, *selCol, *actCol;
BMEdge *eed_act;
@@ -128,8 +129,8 @@ typedef struct drawDMEdgesSel_userData {
typedef struct drawDMFacesSel_userData {
unsigned char *cols[3];
- DerivedMesh *dm; /* BMESH BRANCH ONLY */
- BMEditMesh *em; /* BMESH BRANCH ONLY */
+ DerivedMesh *dm;
+ BMEditMesh *em;
BMFace *efa_act;
int *orig_index_mf_to_mpoly;
@@ -168,17 +169,26 @@ static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], con
}
/* this condition has been made more complex since editmode can draw textures */
-static int check_object_draw_texture(Scene *scene, View3D *v3d, int drawtype)
+static bool check_object_draw_texture(Scene *scene, View3D *v3d, int drawtype)
{
/* texture and material draw modes */
- if (ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID)
- return TRUE;
+ if (ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID) {
+ return true;
+ }
/* textured solid */
- if (v3d->drawtype == OB_SOLID && (v3d->flag2 & V3D_SOLID_TEX) && !BKE_scene_use_new_shading_nodes(scene))
- return TRUE;
+ if ((v3d->drawtype == OB_SOLID) &&
+ (v3d->flag2 & V3D_SOLID_TEX) &&
+ (BKE_scene_use_new_shading_nodes(scene) == false))
+ {
+ return true;
+ }
- return FALSE;
+ if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) {
+ return true;
+ }
+
+ return false;
}
static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
@@ -206,7 +216,7 @@ static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
/* check for glsl drawing */
-int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const short dt)
+int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
{
if (!GPU_glsl_support())
return 0;
@@ -216,6 +226,10 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const short dt)
return 0;
if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
return 0;
+
+ if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
+ return 1;
+
if (BKE_scene_use_new_shading_nodes(scene))
return 0;
@@ -605,16 +619,17 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
if ((dflag & DRAW_CONSTCOLOR) == 0) {
glColor3ubv(ob_wire_col);
-
- /* Calculate the outline vertex positions */
- glBegin(GL_LINE_LOOP);
- glVertex2f(ofs_x, ofs_y);
- glVertex2f(ofs_x + ima_x, ofs_y);
- glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
- glVertex2f(ofs_x, ofs_y + ima_y);
- glEnd();
}
+ /* Calculate the outline vertex positions */
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(ofs_x, ofs_y);
+ glVertex2f(ofs_x + ima_x, ofs_y);
+ glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
+ glVertex2f(ofs_x, ofs_y + ima_y);
+ glEnd();
+
+
/* Reset GL settings */
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
@@ -622,7 +637,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
BKE_image_release_ibuf(ima, ibuf, NULL);
}
-static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[][4])
+static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[4][4])
{
float vx[3], vy[3];
float *viter = (float *)verts;
@@ -638,7 +653,7 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3
}
}
-void drawcircball(int mode, const float cent[3], float rad, float tmat[][4])
+void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4])
{
float verts[CIRCLE_RESOL][3];
@@ -739,7 +754,7 @@ void view3d_cached_text_draw_add(const float co[3],
memcpy(++vos, str, alloc_len);
}
-void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4])
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
ListBase *strings = &CachedText[CachedTextLevel - 1];
@@ -755,7 +770,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
(vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
(vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0,
vos->vec, vos->sco,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
tot++;
}
@@ -929,7 +944,7 @@ static void drawcube_size(const float size[3])
}
#endif
-static void drawshadbuflimits(Lamp *la, float mat[][4])
+static void drawshadbuflimits(Lamp *la, float mat[4][4])
{
float sta[3], end[3], lavec[3];
@@ -1077,7 +1092,7 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z)
}
static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4])
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]);
@@ -1286,6 +1301,13 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
glVertex3fv(vvec_clip);
glEnd();
}
+ /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
+ else {
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(0.0, 0.0, -circrad);
+ glVertex3f(0.0, 0.0, -la->dist);
+ glEnd();
+ }
}
else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
@@ -2584,10 +2606,10 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
/* make the precision of the display value proportionate to the gridsize */
- if (grid < 0.01f) conv_float = "%.6g";
- else if (grid < 0.1f) conv_float = "%.5g";
- else if (grid < 1.0f) conv_float = "%.4g";
- else if (grid < 10.0f) conv_float = "%.3g";
+ if (grid <= 0.01f) conv_float = "%.6g";
+ else if (grid <= 0.1f) conv_float = "%.5g";
+ else if (grid <= 1.0f) conv_float = "%.4g";
+ else if (grid <= 10.0f) conv_float = "%.3g";
else conv_float = "%.2g";
if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
@@ -2632,16 +2654,21 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
BMFace *f;
int n;
-#define DRAW_EM_MEASURE_STATS_FACEAREA() \
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { \
- mul_v3_fl(vmid, 1.0f / (float)n); \
- if (unit->system) \
- bUnit_AsString(numstr, sizeof(numstr), \
- (double)(area * unit->scale_length), \
- 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); \
- else \
- BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \
- view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); \
+#define DRAW_EM_MEASURE_STATS_FACEAREA() \
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { \
+ mul_v3_fl(vmid, 1.0f / (float)n); \
+ if (unit->system) { \
+ bUnit_AsString(numstr, sizeof(numstr), \
+ (double)(area * unit->scale_length * unit->scale_length), \
+ 3, unit->system, B_UNIT_AREA, do_split, FALSE); \
+ view3d_cached_text_draw_add(vmid, numstr, 0, \
+ /* Metric system uses unicode "squared" sign! */ \
+ txt_flag ^ V3D_CACHE_TEXT_ASCII, col); \
+ } \
+ else { \
+ BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \
+ view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); \
+ } \
} (void)0
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
@@ -2813,7 +2840,7 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
}
static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
- Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const short dt)
+ Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt)
{
Mesh *me = ob->data;
@@ -2838,7 +2865,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
}
}
- EDBM_index_arrays_init(em, 1, 1, 1);
+ EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE);
if (dt > OB_WIRE) {
if (check_object_draw_texture(scene, v3d, dt)) {
@@ -2989,8 +3016,6 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
bglPolygonOffset(rv3d->dist, 0.0);
GPU_disable_material();
}
-
- EDBM_index_arrays_free(em);
}
/* Mesh drawing routines */
@@ -3021,7 +3046,7 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
}
static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dt, const unsigned char ob_wire_col[4], const short dflag)
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
Object *ob = base->object;
Mesh *me = ob->data;
@@ -3230,7 +3255,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
}
- dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), me->drawflag & ME_ALLEDGES);
+ dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), (ob->dtx & OB_DRAW_ALL_EDGES));
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
glDepthMask(1);
@@ -3239,11 +3264,15 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
if (is_obact && paint_vertsel_test(ob)) {
-
+ const int use_depth = (v3d->flag & V3D_ZBUF_SELECT);
glColor3f(0.0f, 0.0f, 0.0f);
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
+
+ if (!use_depth) glDisable(GL_DEPTH_TEST);
+ else bglPolygonOffset(rv3d->dist, 1.0);
drawSelectedVertices(dm, ob->data);
+ if (!use_depth) glEnable(GL_DEPTH_TEST);
+ else bglPolygonOffset(rv3d->dist, 0.0);
glPointSize(1.0f);
}
@@ -3252,7 +3281,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
/* returns 1 if nothing was drawn, for detecting to draw an object center */
static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dt, const unsigned char ob_wire_col[4], const short dflag)
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
Object *ob = base->object;
Object *obedit = scene->obedit;
@@ -3416,7 +3445,7 @@ static int drawDispListwire(ListBase *dlbase)
#if 0
/* (ton) this code crashes for me when resolv is 86 or higher... no clue */
- glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3*nr);
+ glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr);
if (dl->flag & DL_CYCL_V)
glDrawArrays(GL_LINE_LOOP, 0, dl->parts);
else
@@ -3574,7 +3603,7 @@ static void drawCurveDMWired(Object *ob)
}
/* return 1 when nothing was drawn */
-static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const short dt)
+static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt)
{
Object *ob = base->object;
DerivedMesh *dm = ob->derivedFinal;
@@ -3610,7 +3639,7 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B
* \return 1 when nothing was drawn
*/
static int drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4])
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
ListBase *lb = NULL;
@@ -3736,7 +3765,7 @@ static int drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d
return FALSE;
}
static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4])
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
int retval;
@@ -4659,9 +4688,11 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
if (!(point->flag & PEP_HIDE))
totkeys += point->totkey;
- if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO))
- pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data");
- cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data");
+ if (totkeys) {
+ if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO))
+ pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data");
+ cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data");
+ }
for (i = 0, point = edit->points; i < totpoint; i++, point++) {
if (point->flag & PEP_HIDE)
@@ -4898,9 +4929,9 @@ static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo
glEnd();
}
-/*place to add drawers */
+/* place to add drawers */
-static void tekenhandlesN(Nurb *nu, short sel, short hide_handles)
+static void drawhandlesN(Nurb *nu, short sel, short hide_handles)
{
BezTriple *bezt;
float *fp;
@@ -4960,7 +4991,7 @@ static void tekenhandlesN(Nurb *nu, short sel, short hide_handles)
glEnd();
}
-static void tekenhandlesN_active(Nurb *nu)
+static void drawhandlesN_active(Nurb *nu)
{
BezTriple *bezt;
float *fp;
@@ -4995,7 +5026,7 @@ static void tekenhandlesN_active(Nurb *nu)
glLineWidth(1);
}
-static void tekenvertsN(Nurb *nu, short sel, short hide_handles, void *lastsel)
+static void drawvertsN(Nurb *nu, short sel, short hide_handles, void *lastsel)
{
BezTriple *bezt;
BPoint *bp;
@@ -5251,7 +5282,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
}
static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
- const short dt, const short dflag, const unsigned char ob_wire_col[4])
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
ToolSettings *ts = scene->toolsettings;
Object *ob = base->object;
@@ -5275,8 +5306,8 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
for (nu = nurb; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
if (index == cu->actnu && !hide_handles)
- tekenhandlesN_active(nu);
- tekenhandlesN(nu, 0, hide_handles);
+ drawhandlesN_active(nu);
+ drawhandlesN(nu, 0, hide_handles);
}
index++;
}
@@ -5285,8 +5316,8 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
/* selected handles */
for (nu = nurb; nu; nu = nu->next) {
if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0)
- tekenhandlesN(nu, 1, hide_handles);
- tekenvertsN(nu, 0, hide_handles, NULL);
+ drawhandlesN(nu, 1, hide_handles);
+ drawvertsN(nu, 0, hide_handles, NULL);
}
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -5337,7 +5368,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
for (nu = nurb; nu; nu = nu->next) {
- tekenvertsN(nu, 1, hide_handles, cu->lastsel);
+ drawvertsN(nu, 1, hide_handles, cu->lastsel);
}
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -5399,43 +5430,10 @@ static void draw_empty_cone(float size)
gluDeleteQuadric(qobj);
}
-/* draw points on curve speed handles */
-#if 0 /* XXX old animation system stuff */
-static void curve_draw_speed(Scene *scene, Object *ob)
-{
- Curve *cu = ob->data;
- IpoCurve *icu;
- BezTriple *bezt;
- float loc[4], dir[3];
- int a;
-
- if (cu->ipo == NULL)
- return;
-
- icu = cu->ipo->curve.first;
- if (icu == NULL || icu->totvert < 2)
- return;
-
- glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
- bglBegin(GL_POINTS);
-
- for (a = 0, bezt = icu->bezt; a < icu->totvert; a++, bezt++) {
- if (where_on_path(ob, bezt->vec[1][1], loc, dir)) {
- UI_ThemeColor((bezt->f2 & SELECT) && ob == OBACT ? TH_VERTEX_SELECT : TH_VERTEX);
- bglVertex3fv(loc);
- }
- }
-
- glPointSize(1.0);
- bglEnd();
-}
-#endif /* XXX old animation system stuff */
-
-
-static void draw_textcurs(float textcurs[4][2])
+static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2])
{
cpack(0);
-
+ bglPolygonOffset(rv3d->dist, -1.0);
set_inverted_drawing(1);
glBegin(GL_QUADS);
glVertex2fv(textcurs[0]);
@@ -5444,9 +5442,10 @@ static void draw_textcurs(float textcurs[4][2])
glVertex2fv(textcurs[3]);
glEnd();
set_inverted_drawing(0);
+ bglPolygonOffset(rv3d->dist, 0.0);
}
-static void drawspiral(const float cent[3], float rad, float tmat[][4], int start)
+static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start)
{
float vec[3], vx[3], vy[3];
const float tot_inv = (1.0f / (float)CIRCLE_RESOL);
@@ -5534,8 +5533,8 @@ static void drawcircle_size(float size)
}
-/* needs fixing if non-identity matrice used */
-static void drawtube(const float vec[3], float radius, float height, float tmat[][4])
+/* needs fixing if non-identity matrix used */
+static void drawtube(const float vec[3], float radius, float height, float tmat[4][4])
{
float cur[3];
drawcircball(GL_LINE_LOOP, vec, radius, tmat);
@@ -5556,8 +5555,9 @@ static void drawtube(const float vec[3], float radius, float height, float tmat[
glVertex3f(cur[0], cur[1] - radius, cur[2]);
glEnd();
}
-/* needs fixing if non-identity matrice used */
-static void drawcone(const float vec[3], float radius, float height, float tmat[][4])
+
+/* needs fixing if non-identity matrix used */
+static void drawcone(const float vec[3], float radius, float height, float tmat[4][4])
{
float cur[3];
@@ -5577,9 +5577,10 @@ static void drawcone(const float vec[3], float radius, float height, float tmat[
glVertex3f(cur[0], cur[1] - radius, cur[2]);
glEnd();
}
+
/* return TRUE if nothing was drawn */
static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4])
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
MetaBall *mb;
@@ -5625,7 +5626,6 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
}
while (ml) {
-
/* draw radius */
if (mb->editelems) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
@@ -6212,6 +6212,34 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
r_ob_wire_col[3] = 255;
}
+static void draw_object_matcap_check(Scene *scene, View3D *v3d, Object *ob)
+{
+ /* fixed rule, active object draws as matcap */
+ if (ob == OBACT) {
+ if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
+ return;
+
+ if (v3d->defmaterial == NULL) {
+ extern Material defmaterial;
+
+ v3d->defmaterial = MEM_mallocN(sizeof(Material), "matcap material");
+ *(v3d->defmaterial) = defmaterial;
+ v3d->defmaterial->gpumaterial.first = v3d->defmaterial->gpumaterial.last = NULL;
+ v3d->defmaterial->preview = NULL;
+ }
+ /* first time users */
+ if (v3d->matcap_icon == 0)
+ v3d->matcap_icon = ICON_MATCAP_01;
+
+ if (v3d->defmaterial->preview == NULL)
+ v3d->defmaterial->preview = UI_icon_to_preview(v3d->matcap_icon);
+
+ /* signal to all material checks, gets cleared below */
+ v3d->flag2 |= V3D_SHOW_SOLID_MATCAP;
+ }
+
+}
+
/**
* main object drawing function, draws in selection
* \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET
@@ -6228,7 +6256,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
unsigned char _ob_wire_col[4]; /* dont initialize this */
unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */
int i, selstart, selend, empty_object = 0;
- short dt, dtx, zbufoff = 0;
+ short dtx;
+ char dt;
+ short zbufoff = 0;
const short is_obact = (ob == OBACT);
/* only once set now, will be removed too, should become a global standard */
@@ -6299,6 +6329,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
dt = MIN2(dt, ob->dt);
if (v3d->zbuf == 0 && dt > OB_WIRE) dt = OB_WIRE;
dtx = 0;
+
+ /* matcap check */
+ if (dt == OB_SOLID && (v3d->flag2 & V3D_SOLID_MATCAP))
+ draw_object_matcap_check(scene, v3d, ob);
/* faceselect exception: also draw solid when (dt == wire), except in editmode */
if (is_obact && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
@@ -6364,7 +6398,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
case OB_FONT:
cu = ob->data;
if (cu->editfont) {
- draw_textcurs(cu->editfont->textcurs);
+ draw_textcurs(rv3d, cu->editfont->textcurs);
if (cu->flag & CU_FAST) {
cpack(0xFFFFFF);
@@ -6742,7 +6776,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
if (ob->gameflag & OB_BOUNDS) {
- if (ob->boundtype != ob->collision_boundtype || (dtx & OB_BOUNDBOX) == 0) {
+ if (ob->boundtype != ob->collision_boundtype || (dtx & OB_DRAWBOUNDOX) == 0) {
setlinestyle(2);
draw_bounding_volume(scene, ob, ob->collision_boundtype);
@@ -6756,7 +6790,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (dtx & OB_AXIS) {
drawaxes(1.0f, OB_ARROWS);
}
- if (dtx & OB_BOUNDBOX) {
+ if (dtx & OB_DRAWBOUNDOX) {
draw_bounding_volume(scene, ob, ob->boundtype);
}
if (dtx & OB_TEXSPACE) {
@@ -6799,7 +6833,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* return warning, this is cached text draw */
invert_m4_m4(ob->imat, ob->obmat);
view3d_cached_text_draw_end(v3d, ar, 1, NULL);
-
+ /* return warning, clear temp flag */
+ v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP;
+
glLoadMatrixf(rv3d->viewmat);
if (zbufoff) {
@@ -6873,10 +6909,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
UI_make_axis_color(col1, col2, 'Z');
glColor3ubv(col2);
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
for (curcon = list->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -6930,7 +6966,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
}
- constraints_clear_evalob(cob);
+ BKE_constraints_clear_evalob(cob);
}
}
@@ -7091,14 +7127,28 @@ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
return DM_DRAW_OPTION_SKIP;
}
}
-static void bbs_mesh_solid(Scene *scene, Object *ob)
+
+static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
+{
+ Mesh *me = ob->data;
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
+ glColor3ub(0, 0, 0);
+
+ dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
+
+ bbs_obmode_mesh_verts(ob, dm, 1);
+ bm_vertoffs = me->totvert + 1;
+ dm->release(dm);
+}
+
+static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
Mesh *me = (Mesh *)ob->data;
glColor3ub(0, 0, 0);
- if ((me->editflag & ME_EDIT_PAINT_MASK))
+ if ((me->editflag & ME_EDIT_PAINT_FACE_SEL))
dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, GPU_enable_material, NULL, me, 0);
else
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, GPU_enable_material, NULL, me, 0);
@@ -7123,7 +7173,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
- EDBM_index_arrays_init(em, 1, 1, 1);
+ EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE);
bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
if (ts->selectmode & SCE_SELECT_FACE)
@@ -7149,27 +7199,17 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
bglPolygonOffset(rv3d->dist, 0.0);
dm->release(dm);
-
- EDBM_index_arrays_free(em);
}
else {
Mesh *me = ob->data;
- if ((me->editflag & ME_EDIT_VERT_SEL) &&
+ if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
/* currently vertex select only supports weight paint */
(ob->mode & OB_MODE_WEIGHT_PAINT))
{
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- glColor3ub(0, 0, 0);
-
- dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
-
-
- bbs_obmode_mesh_verts(ob, dm, 1);
- bm_vertoffs = me->totvert + 1;
- dm->release(dm);
+ bbs_mesh_solid_verts(scene, ob);
}
else {
- bbs_mesh_solid(scene, ob);
+ bbs_mesh_solid_faces(scene, ob);
}
}
break;
@@ -7235,7 +7275,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
if (dm) dm->release(dm);
}
-void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline)
+void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline)
{
if (ob == NULL)
return;
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index ebb48960b80..70d3857601f 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -38,6 +38,7 @@
#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_blenlib.h"
@@ -73,61 +74,18 @@
#include "ED_mesh.h"
-
#include "BLF_api.h"
-
#include "view3d_intern.h" // own include
+struct GPUTexture;
-#ifdef _WIN32
-#include <time.h>
-#include <stdio.h>
-#include <conio.h>
-#include <windows.h>
-
-static LARGE_INTEGER liFrequency;
-static LARGE_INTEGER liStartTime;
-static LARGE_INTEGER liCurrentTime;
+// #define DEBUG_DRAW_TIME
-static void tstart(void)
-{
- QueryPerformanceFrequency(&liFrequency);
- QueryPerformanceCounter(&liStartTime);
-}
-static void tend(void)
-{
- QueryPerformanceCounter(&liCurrentTime);
-}
-static double tval(void)
-{
- return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart) * (double)1000.0 / (double)liFrequency.QuadPart));
-}
-#else
-#include <sys/time.h>
-static struct timeval _tstart, _tend;
-static struct timezone tz;
-static void tstart(void)
-{
- gettimeofday(&_tstart, &tz);
-}
-static void tend(void)
-{
- gettimeofday(&_tend, &tz);
-}
- #if 0
-static double tval()
-{
- double t1, t2;
- t1 = ( double ) _tstart.tv_sec * 1000 + ( double ) _tstart.tv_usec / (1000);
- t2 = ( double ) _tend.tv_sec * 1000 + ( double ) _tend.tv_usec / (1000);
- return t2 - t1;
-}
- #endif
+#ifdef DEBUG_DRAW_TIME
+# include "PIL_time.h"
#endif
-struct GPUTexture;
-
static int intersect_edges(float *points, float a, float b, float c, float d, float edges[12][2][3])
{
int i;
@@ -274,7 +232,10 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
return;
}
- tstart();
+#ifdef DEBUG_DRAW_TIME
+ TIMEIT_START(draw);
+#endif
+
/* generate flame spectrum texture */
#define SPEC_WIDTH 256
#define FIRE_THRESH 7
@@ -448,8 +409,8 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
* inserting previously found vertex into the plane equation */
/* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */
- ds = (ABS(viewnormal[0]) * size[0] + ABS(viewnormal[1]) * size[1] + ABS(viewnormal[2]) * size[2]);
- dd = MAX3(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f;
+ ds = (fabsf(viewnormal[0]) * size[0] + fabsf(viewnormal[1]) * size[1] + fabsf(viewnormal[2]) * size[2]);
+ dd = max_fff(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f;
n = 0;
good_index = i;
@@ -521,8 +482,10 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
n++;
}
- tend();
- // printf ( "Draw Time: %f\n",(float) tval() );
+#ifdef DEBUG_DRAW_TIME
+ printf("Draw Time: %f\n", (float)TIMEIT_VALUE(draw));
+ TIMEIT_END(draw);
+#endif
if (tex_shadow)
GPU_texture_unbind(tex_shadow);
@@ -569,7 +532,7 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob)
float min[3];
float *cell_size = domain->cell_size;
- float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f;
+ float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f;
float vf = domain->scale / 16.f * 2.f; /* velocity factor */
glLineWidth(1.0f);
@@ -623,7 +586,7 @@ void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob)
float min[3];
float *cell_size = domain->cell_size;
- float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f;
+ float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f;
float vf = domain->scale / 16.f * 2.f; /* velocity factor */
/* set first position so that it doesn't jump when domain moves */
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 1c31cd23e33..2ed1ec694d8 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <stdio.h>
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -42,16 +43,18 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
-#include "BKE_object.h"
#include "BKE_context.h"
+#include "BKE_icons.h"
+#include "BKE_object.h"
#include "BKE_screen.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_object.h"
-#include "BIF_gl.h"
+#include "GPU_material.h"
+#include "BIF_gl.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -117,7 +120,7 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
BLI_insertlinkafter(&sa->regionbase, arhead, artool);
artool->regiontype = RGN_TYPE_TOOLS;
- artool->alignment = RGN_ALIGN_LEFT; //RGN_OVERLAP_LEFT;
+ artool->alignment = RGN_ALIGN_LEFT;
artool->flag = RGN_FLAG_HIDDEN;
}
@@ -143,7 +146,7 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C)
if (rv3d == NULL) {
ScrArea *sa = CTX_wm_area(C);
if (sa && sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ ARegion *ar = BKE_area_find_region_active_win(sa);
if (ar) {
rv3d = ar->regiondata;
}
@@ -261,14 +264,11 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->gridlines = 16;
v3d->gridsubdiv = 10;
v3d->drawtype = OB_SOLID;
+
+ v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
- v3d->gridflag |= V3D_SHOW_X;
- v3d->gridflag |= V3D_SHOW_Y;
- v3d->gridflag |= V3D_SHOW_FLOOR;
- v3d->gridflag &= ~V3D_SHOW_Z;
-
- v3d->flag |= V3D_SELECT_OUTLINE;
- v3d->flag2 |= V3D_SHOW_RECONSTRUCTION;
+ v3d->flag = V3D_SELECT_OUTLINE;
+ v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
v3d->lens = 35.0f;
v3d->near = 0.01f;
@@ -338,6 +338,14 @@ static void view3d_free(SpaceLink *sl)
if (vd->localvd) MEM_freeN(vd->localvd);
if (vd->properties_storage) MEM_freeN(vd->properties_storage);
+
+ /* matcap material, its preview rect gets freed via icons */
+ if (vd->defmaterial) {
+ if (vd->defmaterial->gpumaterial.first)
+ GPU_material_free(vd->defmaterial);
+ BKE_previewimg_free(&vd->defmaterial->preview);
+ MEM_freeN(vd->defmaterial);
+ }
}
@@ -368,6 +376,8 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
/* copy or clear inside new stuff */
+ v3dn->defmaterial = NULL;
+
BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
v3dn->properties_storage = NULL;
@@ -469,6 +479,16 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSE
return 0;
}
+static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+{
+ if (drag->type == WM_DRAG_ID) {
+ ID *id = (ID *)drag->poin;
+ if (GS(id->name) == ID_GR)
+ return 1;
+ }
+ return 0;
+}
+
static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
@@ -494,33 +514,37 @@ static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS
}
-static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
{
- if (ED_view3d_give_base_under_cursor(C, event->mval) ) {
- return 0;
- }
- return view3d_ima_drop_poll(C, drag, event);
-}
+ Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
-static int view3d_ima_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
-{
- if (ED_view3d_give_base_under_cursor(C, event->mval) ) {
+ if (!base || (base && base->object->type == OB_EMPTY))
return view3d_ima_drop_poll(C, drag, event);
- }
return 0;
}
+static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+{
+ Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
+
+ if (base && base->object->type == OB_MESH)
+ return view3d_ima_drop_poll(C, drag, event);
+ return 0;
+}
+
static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = (ID *)drag->poin;
- PointerRNA ptr;
- /* need to put name in sub-operator in macro */
- ptr = RNA_pointer_get(drop->ptr, "OBJECT_OT_add_named");
- if (ptr.data)
- RNA_string_set(&ptr, "name", id->name + 2);
- else
- RNA_string_set(drop->ptr, "name", id->name + 2);
+ RNA_string_set(drop->ptr, "name", id->name + 2);
+}
+
+static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
+{
+ ID *id = (ID *)drag->poin;
+
+ drop->opcontext = WM_OP_EXEC_DEFAULT;
+ RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
@@ -546,10 +570,11 @@ static void view3d_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
- WM_dropbox_add(lb, "OBJECT_OT_add_named_cursor", view3d_ob_drop_poll, view3d_ob_drop_copy);
+ WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
- WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_ob_drop_poll, view3d_id_path_drop_copy);
- WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
+ WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_mesh_drop_poll, view3d_id_path_drop_copy);
+ WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
+ WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
}
@@ -574,6 +599,9 @@ static void view3d_main_area_free(ARegion *ar)
if (rv3d->depths->depths) MEM_freeN(rv3d->depths->depths);
MEM_freeN(rv3d->depths);
}
+ if (rv3d->sms) {
+ MEM_freeN(rv3d->sms);
+ }
MEM_freeN(rv3d);
ar->regiondata = NULL;
}
@@ -635,8 +663,7 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene
static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
{
- bScreen *sc;
-
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -659,7 +686,8 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case NC_SCENE:
switch (wmn->data) {
case ND_LAYER_CONTENT:
- view3d_recalc_used_layers(ar, wmn, wmn->reference);
+ if (wmn->reference)
+ view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar);
break;
case ND_FRAME:
@@ -787,8 +815,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_SCREENSET:
/* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */
/* updates used layers only for View3D in active screen */
- sc = wmn->reference;
- view3d_recalc_used_layers(ar, wmn, sc->scene);
+ if (wmn->reference) {
+ bScreen *sc = wmn->reference;
+ view3d_recalc_used_layers(ar, wmn, sc->scene);
+ }
ED_region_tag_redraw(ar);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index bf14d915412..bb286194992 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -179,34 +179,52 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
BMEdge *eed;
BMIter iter;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs;
-
- evedef = eve;
- tot++;
- add_v3_v3(&median[LOC_X], eve->co);
-
- vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs) {
- add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */
- totskinradius++;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ if (bm->totvertsel) {
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ evedef = eve;
+ tot++;
+ add_v3_v3(&median[LOC_X], eve->co);
+
+ /* TODO cd_vert_bweight_offset */
+ (void)cd_vert_bweight_offset;
+
+ if (cd_vert_skin_offset != -1) {
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */
+ totskinradius++;
+ }
}
}
}
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *f;
+ if ((cd_edge_bweight_offset != -1) ||
+ (cd_edge_crease_offset != -1))
+ {
+ if (bm->totedgesel) {
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
+ if (cd_edge_bweight_offset != -1) {
+ median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset);
+ }
- totedgedata++;
- f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- median[M_CREASE] += f ? *f : 0.0f;
+ if (cd_edge_crease_offset != -1) {
+ median[M_CREASE] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
+ }
- f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- median[M_WEIGHT] += f ? *f : 0.0f;
+ totedgedata++;
+ }
+ }
}
}
+ else {
+ totedgedata = bm->totedgesel;
+ }
/* check for defgroups */
if (evedef)
@@ -365,7 +383,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
if (block) { /* buttons */
uiBut *but;
int yi = 200;
- const int buth = 20 * UI_DPI_ICON_FAC;
+ const int buth = 20 * UI_DPI_FAC;
const int but_margin = 2;
const char *c;
@@ -385,41 +403,43 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
uiBlockBeginAlign(block);
/* Should be no need to translate these. */
- but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, yi -= buth, 200, buth,
+ but = uiDefButF(block, 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, "Y:", 0, yi -= buth, 200, buth,
+ but = uiDefButF(block, 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, "Z:", 0, yi -= buth, 200, buth,
+ but = uiDefButF(block, 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);
if (totcurvebweight == tot) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, yi -= buth, 200, buth,
+ uiDefButF(block, 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"),
0, yi -= buth + but_margin, 100, buth,
- &v3d->flag, 0, 0, 0, 0, "Displays global values");
+ &v3d->flag, 0, 0, 0, 0, TIP_("Displays global values"));
uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, IFACE_("Local"),
100, yi, 100, buth,
- &v3d->flag, 0, 0, 0, 0, "Displays local values");
+ &v3d->flag, 0, 0, 0, 0, TIP_("Displays local values"));
uiBlockEndAlign(block);
/* Meshes... */
if (meshdata) {
if (totedgedata) {
+ /* customdata layer added on demand */
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
- totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
+ totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
+ /* customdata layer added on demand */
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
- totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
}
if (totskinradius) {
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
@@ -434,12 +454,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
/* Curve... */
else if (totcurvedata == 1) {
- uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth,
+ uiDefButR(block, 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, "Radius", 0, yi -= buth + but_margin, 200, buth,
+ uiDefButR(block, 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, "Tilt", 0, yi -= buth + but_margin, 200, buth,
- &data_ptr, "tilt", 0, -M_PI * 2.0, M_PI * 2.0, 1, 3, NULL);
+ uiDefButR(block, NUM, 0, IFACE_("Tilt"), 0, yi -= buth + but_margin, 200, buth,
+ &data_ptr, "tilt", 0, -FLT_MAX, FLT_MAX, 1, 3, NULL);
}
else if (totcurvedata > 1) {
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
@@ -450,13 +470,13 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
&(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:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[C_TILT]), -M_PI * 2.0, M_PI * 2.0, 1, 3,
+ &(tfp->ve_median[C_TILT]), -FLT_MAX, FLT_MAX, 1, 3,
TIP_("Tilt of curve control points"));
uiButSetUnitType(but, PROP_UNIT_ROTATION);
}
/* Lattice... */
else if (totlattdata == 1) {
- uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth,
+ uiDefButR(block, 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) {
@@ -502,91 +522,87 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (median[M_CREASE] != 0.0f) {
- BMEdge *eed;
+ const int cd_edge_crease_offset = (BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE),
+ CustomData_get_offset(&bm->edata, CD_CREASE));
const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]);
+ BMEdge *eed;
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease = sca;
- }
+ BM_ELEM_CD_SET_FLOAT(eed, cd_edge_crease_offset, sca);
}
}
}
else if (sca > 0.0f) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease *= sca;
- CLAMP(*crease, 0.0f, 1.0f);
- }
+ float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
+ *crease *= sca;
+ CLAMP(*crease, 0.0f, 1.0f);
}
}
}
else {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease = 1.0f + ((1.0f - *crease) * sca);
- CLAMP(*crease, 0.0f, 1.0f);
- }
+ float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
+ *crease = 1.0f + ((1.0f - *crease) * sca);
+ CLAMP(*crease, 0.0f, 1.0f);
}
}
}
}
if (median[M_WEIGHT] != 0.0f) {
- BMEdge *eed;
+ const int cd_edge_bweight_offset = (BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT),
+ CustomData_get_offset(&bm->edata, CD_BWEIGHT));
const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]);
+ BMEdge *eed;
+
+ BLI_assert(cd_edge_bweight_offset != -1);
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight = sca;
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight = sca;
}
}
}
else if (sca > 0.0f) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight *= sca;
- CLAMP(*bweight, 0.0f, 1.0f);
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight *= sca;
+ CLAMP(*bweight, 0.0f, 1.0f);
}
}
}
else {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight = 1.0f + ((1.0f - *bweight) * sca);
- CLAMP(*bweight, 0.0f, 1.0f);
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight = 1.0f + ((1.0f - *bweight) * sca);
+ CLAMP(*bweight, 0.0f, 1.0f);
}
}
}
}
if (median[M_SKIN_X] != 0.0f) {
- BMVert *eve;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
/* That one is not clamped to [0.0, 1.0]. */
float sca = ve_median[M_SKIN_X];
+ BMVert *eve;
+
+ BLI_assert(cd_vert_skin_offset != -1);
+
if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[0] = sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[0] = sca;
}
}
}
@@ -594,23 +610,25 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[0] *= sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[0] *= sca;
}
}
}
}
if (median[M_SKIN_Y] != 0.0f) {
- BMVert *eve;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
/* That one is not clamped to [0.0, 1.0]. */
float sca = ve_median[M_SKIN_Y];
+ BMVert *eve;
+
+ BLI_assert(cd_vert_skin_offset != -1);
+
if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[1] = sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[1] = sca;
}
}
}
@@ -618,14 +636,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[1] *= sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[1] *= sca;
}
}
}
}
- EDBM_mesh_normals_update(em);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
@@ -1253,19 +1269,20 @@ void view3d_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
strcpy(pt->idname, "VIEW3D_PT_object");
- strcpy(pt->label, "Transform");
+ strcpy(pt->label, N_("Transform")); /* XXX C panels not available through RNA (bpy.types)! */
pt->draw = view3d_panel_object;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
strcpy(pt->idname, "VIEW3D_PT_gpencil");
- strcpy(pt->label, "Grease Pencil");
+ strcpy(pt->label, N_("Grease Pencil")); /* XXX C panels are not available through RNA (bpy.types)! */
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = 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, "Vertex Groups");
+ strcpy(pt->label, N_("Vertex Groups")); /* XXX C panels are not available through RNA (bpy.types)! */
pt->draw = view3d_panel_vgroup;
pt->poll = view3d_panel_vgroup_poll;
BLI_addtail(&art->paneltypes, pt);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 51261f4c341..4aaa3332252 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -75,7 +75,9 @@
#include "BIF_glutil.h"
#include "WM_api.h"
+
#include "BLF_api.h"
+#include "BLF_translation.h"
#include "ED_armature.h"
#include "ED_keyframing.h"
@@ -217,7 +219,7 @@ void ED_view3d_clipping_enable(void)
}
}
-static int view3d_clipping_test(const float vec[3], float clip[][4])
+static int view3d_clipping_test(const float vec[3], float clip[6][4])
{
float view[3];
copy_v3_v3(view, vec);
@@ -315,7 +317,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
UI_ThemeColor(TH_GRID);
if (unit->system) {
- /* Use GRID_MIN_PX*2 for units because very very small grid
+ /* Use GRID_MIN_PX * 2 for units because very very small grid
* items are less useful when dealing with units */
void *usys;
int len, i;
@@ -345,7 +347,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
CLAMP(blend_fac, 0.3f, 1.0f);
- UI_ThemeColorBlend(TH_BACK, TH_GRID, blend_fac);
+ UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, blend_fac);
drawgrid_draw(ar, wx, wy, x, y, dx_scalar);
}
@@ -374,15 +376,15 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
}
}
else { /* start blending out */
- UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
+ UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
}
}
- else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX*10)) */
- UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
+ else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */
+ UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
@@ -401,21 +403,21 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
drawgrid_draw(ar, wx, wy, x, y, dx);
}
else {
- UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
+ UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
}
}
else {
- UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
+ UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
}
}
else {
- UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
+ UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
drawgrid_draw(ar, wx, wy, x, y, dx);
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
@@ -563,41 +565,49 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
if (v3d->zbuf && scene->obedit) glDepthMask(1);
}
+
static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
{
int co[2];
/* we don't want the clipping for cursor */
if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ const float f5 = 0.25f * U.widget_unit;
+ const float f10 = 0.5f * U.widget_unit;
+ const float f20 = U.widget_unit;
+
setlinestyle(0);
cpack(0xFF);
- circ((float)co[0], (float)co[1], 10.0);
- setlinestyle(4);
+ circ((float)co[0], (float)co[1], f10);
+ setlinestyle(4);
cpack(0xFFFFFF);
- circ((float)co[0], (float)co[1], 10.0);
+ circ((float)co[0], (float)co[1], f10);
setlinestyle(0);
cpack(0x0);
- sdrawline(co[0] - 20, co[1], co[0] - 5, co[1]);
- sdrawline(co[0] + 5, co[1], co[0] + 20, co[1]);
- sdrawline(co[0], co[1] - 20, co[0], co[1] - 5);
- sdrawline(co[0], co[1] + 5, co[0], co[1] + 20);
+ sdrawline(co[0] - f20, co[1], co[0] - f5, co[1]);
+ sdrawline(co[0] + f5, co[1], co[0] + f20, co[1]);
+ sdrawline(co[0], co[1] - f20, co[0], co[1] - f5);
+ sdrawline(co[0], co[1] + f5, co[0], co[1] + f20);
}
}
/* Draw a live substitute of the view icon, which is always shown
* colors copied from transform_manipulator.c, we should keep these matching. */
-static void draw_view_axis(RegionView3D *rv3d)
+static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
{
const float k = U.rvisize; /* axis size */
const float toll = 0.5; /* used to see when view is quasi-orthogonal */
- const float start = k + 1.0f; /* axis center in screen coordinates, x=y */
+ float startx = k + 1.0f; /* axis center in screen coordinates, x=y */
+ float starty = k + 1.0f;
float ydisp = 0.0; /* vertical displacement to allow obj info text */
- int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */
-
+ int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
float vec[3];
float dx, dy;
+ startx += rect->xmin;
+ starty += rect->ymin;
+
/* thickness of lines is proportional to k */
glLineWidth(2);
@@ -613,12 +623,12 @@ static void draw_view_axis(RegionView3D *rv3d)
UI_ThemeColorShadeAlpha(TH_AXIS_X, 0, bright);
glBegin(GL_LINES);
- glVertex2f(start, start + ydisp);
- glVertex2f(start + dx, start + dy + ydisp);
+ glVertex2f(startx, starty + ydisp);
+ glVertex2f(startx + dx, starty + dy + ydisp);
glEnd();
if (fabsf(dx) > toll || fabsf(dy) > toll) {
- BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x", 1);
+ BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "x", 1);
}
/* BLF_draw_default disables blending */
@@ -633,12 +643,12 @@ static void draw_view_axis(RegionView3D *rv3d)
UI_ThemeColorShadeAlpha(TH_AXIS_Y, 0, bright);
glBegin(GL_LINES);
- glVertex2f(start, start + ydisp);
- glVertex2f(start + dx, start + dy + ydisp);
+ glVertex2f(startx, starty + ydisp);
+ glVertex2f(startx + dx, starty + dy + ydisp);
glEnd();
if (fabsf(dx) > toll || fabsf(dy) > toll) {
- BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y", 1);
+ BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "y", 1);
}
glEnable(GL_BLEND);
@@ -652,12 +662,12 @@ static void draw_view_axis(RegionView3D *rv3d)
UI_ThemeColorShadeAlpha(TH_AXIS_Z, 0, bright);
glBegin(GL_LINES);
- glVertex2f(start, start + ydisp);
- glVertex2f(start + dx, start + dy + ydisp);
+ glVertex2f(startx, starty + ydisp);
+ glVertex2f(startx + dx, starty + dy + ydisp);
glEnd();
if (fabsf(dx) > toll || fabsf(dy) > toll) {
- BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z", 1);
+ BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "z", 1);
}
/* restore line-width */
@@ -770,7 +780,7 @@ static void draw_rotation_guide(RegionView3D *rv3d)
glDepthMask(1);
}
-static void draw_view_icon(RegionView3D *rv3d)
+static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
{
BIFIconID icon;
@@ -785,7 +795,7 @@ static void draw_view_icon(RegionView3D *rv3d)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- UI_icon_draw(5.0, 5.0, icon);
+ UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
glDisable(GL_BLEND);
}
@@ -796,28 +806,28 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
switch (rv3d->view) {
case RV3D_VIEW_FRONT:
- if (rv3d->persp == RV3D_ORTHO) name = "Front Ortho";
- else name = "Front Persp";
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho");
+ else name = IFACE_("Front Persp");
break;
case RV3D_VIEW_BACK:
- if (rv3d->persp == RV3D_ORTHO) name = "Back Ortho";
- else name = "Back Persp";
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho");
+ else name = IFACE_("Back Persp");
break;
case RV3D_VIEW_TOP:
- if (rv3d->persp == RV3D_ORTHO) name = "Top Ortho";
- else name = "Top Persp";
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho");
+ else name = IFACE_("Top Persp");
break;
case RV3D_VIEW_BOTTOM:
- if (rv3d->persp == RV3D_ORTHO) name = "Bottom Ortho";
- else name = "Bottom Persp";
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho");
+ else name = IFACE_("Bottom Persp");
break;
case RV3D_VIEW_RIGHT:
- if (rv3d->persp == RV3D_ORTHO) name = "Right Ortho";
- else name = "Right Persp";
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho");
+ else name = IFACE_("Right Persp");
break;
case RV3D_VIEW_LEFT:
- if (rv3d->persp == RV3D_ORTHO) name = "Left Ortho";
- else name = "Left Persp";
+ if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho");
+ else name = IFACE_("Left Persp");
break;
default:
@@ -825,14 +835,14 @@ 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) ? "Camera Persp" : "Camera Ortho";
+ name = (cam->type != CAM_ORTHO) ? IFACE_("Camera Persp") : IFACE_("Camera Ortho");
}
else {
- name = "Object as Camera";
+ name = IFACE_("Object as Camera");
}
}
else {
- name = (rv3d->persp == RV3D_ORTHO) ? "User Ortho" : "User Persp";
+ name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp");
}
break;
}
@@ -840,30 +850,39 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
return name;
}
-static void draw_viewport_name(ARegion *ar, View3D *v3d)
+static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
const char *name = view3d_get_name(v3d, rv3d);
+ /* XXX 24 may be a bit small for unicode languages (Chinese in utf-8...) */
+#ifdef WITH_INTERNATIONAL
+ char tmpstr[32];
+#else
char tmpstr[24];
-
+#endif
+
if (v3d->localvd) {
- BLI_snprintf(tmpstr, sizeof(tmpstr), "%s (Local)", name);
+ BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
name = tmpstr;
}
if (name) {
UI_ThemeColor(TH_TEXT_HI);
- BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, name, sizeof(tmpstr));
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
+#else
+ BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
+#endif
}
}
/* draw info beside axes in bottom left-corner:
* framenum, object name, bone name (if available), marker name (if available)
*/
-static void draw_selected_name(Scene *scene, Object *ob)
+static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
{
char info[256], *markern;
- short offset = 30;
+ short offset = 1.5f * UI_UNIT_X + rect->xmin;
/* get name of marker on current frame (if available) */
markern = BKE_scene_find_marker_name(scene, CFRA);
@@ -910,7 +929,7 @@ static void draw_selected_name(Scene *scene, Object *ob)
if (kb) {
BLI_snprintf(shapes, sizeof(shapes), ": %s ", kb->name);
if (ob->shapeflag == OB_SHAPE_LOCK) {
- strcat(shapes, " (Pinned)");
+ strcat(shapes, IFACE_(" (Pinned)"));
}
}
}
@@ -929,7 +948,7 @@ static void draw_selected_name(Scene *scene, Object *ob)
}
/* color depends on whether there is a keyframe */
- if (id_frame_has_keyframe((ID *)ob, /*BKE_scene_frame_get(scene)*/ (float)(CFRA), ANIMFILTER_KEYS_LOCAL))
+ if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)(CFRA), ANIMFILTER_KEYS_LOCAL))
UI_ThemeColor(TH_VERTEX_SELECT);
else
UI_ThemeColor(TH_TEXT_HI);
@@ -946,9 +965,9 @@ static void draw_selected_name(Scene *scene, Object *ob)
}
if (U.uiflag & USER_SHOW_ROTVIEWICON)
- offset = 14 + (U.rvisize * 2);
+ offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
- BLF_draw_default(offset, 10, 0.0f, info, sizeof(info));
+ BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
}
static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
@@ -1289,7 +1308,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
RegionView3D *rv3d = ar->regiondata;
struct Base *base = scene->basact;
int multisample_enabled;
- rcti winrct;
BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
@@ -1338,8 +1356,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if (multisample_enabled)
glDisable(GL_MULTISAMPLE_ARB);
- region_scissor_winrct(ar, &winrct);
- glScissor(winrct.xmin, winrct.ymin, BLI_rcti_size_x(&winrct), BLI_rcti_size_y(&winrct));
+ 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);
if (v3d->zbuf) {
@@ -1921,7 +1938,8 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
GLuint displist = 0;
short transflag, use_displist = -1; /* -1 is initialize */
- char dt, dtx;
+ char dt;
+ short dtx;
if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
@@ -2165,7 +2183,9 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
v3d->zbuf = TRUE;
glEnable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, 1);
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ draw_gpencil_view3d(scene, v3d, ar, TRUE);
+ }
v3d->zbuf = zbuf;
@@ -2307,7 +2327,7 @@ typedef struct View3DShadow {
} View3DShadow;
static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par,
- float obmat[][4], ListBase *shadows)
+ float obmat[4][4], ListBase *shadows)
{
GPULamp *lamp;
Lamp *la = (Lamp *)ob->data;
@@ -2385,7 +2405,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
- ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype = drawtype;
@@ -2466,7 +2486,7 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
return mask;
}
-void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4])
+void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
@@ -2509,7 +2529,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
}
}
-static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4])
+static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
@@ -2532,13 +2552,11 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
/* ED_view3d_draw_offscreen_init should be called before this to initialize
* stuff like shadow buffers
*/
-void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- int winx, int winy, float viewmat[][4], float winmat[][4],
- int do_bgpic, int colormanage_background)
+void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
+ float viewmat[4][4], float winmat[4][4], int do_bgpic)
{
RegionView3D *rv3d = ar->regiondata;
Base *base;
- float backcol[3];
int bwinx, bwiny;
rcti brect;
@@ -2566,34 +2584,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
* warning! can be slow so only free animated images - campbell */
GPU_free_images_anim();
- /* set background color, fallback on the view background color
- * (if active clip is set but frame is failed to load fallback to horizon color as background) */
- if (scene->world) {
- /* NOTE: currently OpenGL is supposed to always work in sRGB space and do not
- * apply any tonemaps since it's really tricky to support for all features (GLSL, textures, etc)
- * but due to compatibility issues background is being affected display transform, so we can
- * emulate behavior of disabled color management
- * but this function is also used for sequencer's scene strips which shouldn't be affected by
- * tonemaps now and should be purely sRGB, that's why we've got this colormanage_background
- * we can drop this flag in cost of some compatibility loss -- background wouldn't be
- * color managed in 3d viewport
- * same goes to opengl rendering, where color profile should be applied as very final step
- */
-
- if (colormanage_background) {
- IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
- }
- else {
- linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr);
- }
-
- glClearColor(backcol[0], backcol[1], backcol[2], 0.0);
- }
- else {
- UI_ThemeClearColor(TH_BACK);
- }
-
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -2645,9 +2636,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
}
/* must be before xray draw which clears the depth buffer */
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, 1);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ draw_gpencil_view3d(scene, v3d, ar, TRUE);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
/* transp and X-ray afterdraw stuff */
if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
@@ -2671,8 +2664,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
/* draw grease-pencil stuff */
ED_region_pixelspace(ar);
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- draw_gpencil_view3d(scene, v3d, ar, 0);
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ draw_gpencil_view3d(scene, v3d, ar, FALSE);
+ }
/* freeing the images again here could be done after the operator runs, leaving for now */
GPU_free_images_anim();
@@ -2690,10 +2686,30 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
G.f &= ~G_RENDER_OGL;
}
+/* get a color used for offscreen sky, returns color in sRGB space */
+void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3])
+{
+ if (scene->world)
+ linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr);
+ else
+ UI_GetThemeColor3fv(TH_BACK, sky_color);
+}
+
+static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene)
+{
+ float sky_color[3];
+
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+
+ if (ibuf->rect_float)
+ IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color);
+ else
+ IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color);
+}
+
/* utility func for ED_view3d_draw_offscreen */
-ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
- int sizex, int sizey, unsigned int flag, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag,
+ int draw_background, int alpha_mode, char err_out[256])
{
RegionView3D *rv3d = ar->regiondata;
ImBuf *ibuf;
@@ -2720,10 +2736,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background);
}
else {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background);
}
/* read in pixels & stamp */
@@ -2734,6 +2750,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
else if (ibuf->rect)
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
+ if (alpha_mode == R_ADDSKY)
+ offscreen_imbuf_add_sky(ibuf, scene);
+
/* unbind */
GPU_offscreen_unbind(ofs);
GPU_offscreen_free(ofs);
@@ -2747,9 +2766,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
}
/* creates own 3d views, used by the sequencer */
-ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height,
- unsigned int flag, int drawtype, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype,
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256])
{
View3D v3d = {NULL};
ARegion ar = {NULL};
@@ -2765,6 +2783,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
v3d.drawtype = drawtype;
v3d.flag2 = V3D_RENDER_OVERRIDE;
+ if (use_solid_tex)
+ v3d.flag2 |= V3D_SOLID_TEX;
+
rv3d.persp = RV3D_CAMOB;
copy_m4_m4(rv3d.viewinv, v3d.camera->obmat);
@@ -2789,7 +2810,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag,
- draw_background, colormanage_background, err_out);
+ draw_background, alpha_mode, err_out);
// seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty);
}
@@ -2798,7 +2819,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
/* NOTE: the info that this uses is updated in ED_refresh_viewport_fps(),
* which currently gets called during SCREEN_OT_animation_step.
*/
-static void draw_viewport_fps(Scene *scene, ARegion *ar)
+static void draw_viewport_fps(Scene *scene, rcti *rect)
{
ScreenFrameRateInfo *fpsi = scene->fps_info;
float fps;
@@ -2836,14 +2857,18 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar)
/* is this more then half a frame behind? */
if (fps + 0.5f < (float)(FPS)) {
UI_ThemeColor(TH_REDALERT);
- BLI_snprintf(printable, sizeof(printable), "fps: %.2f", fps);
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
}
else {
UI_ThemeColor(TH_TEXT_HI);
- BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps + 0.5f));
+ BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
}
-
- BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable));
+
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
+#else
+ BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
+#endif
}
static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit);
@@ -2873,7 +2898,7 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw
if (!(type->view_update && type->view_draw))
return 0;
- engine = RE_engine_create(type);
+ engine = RE_engine_create_ex(type, TRUE);
engine->tile_x = scene->r.tilex;
engine->tile_y = scene->r.tiley;
@@ -2958,6 +2983,169 @@ static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar)
ED_region_info_draw(ar, rv3d->render_engine->text, 1, 0.25);
}
+/*
+ * Function to clear the view
+ */
+static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ /* clear background */
+ if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */
+ if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */
+ int x, y;
+ float col_hor[3];
+ float col_zen[3];
+
+#define VIEWGRAD_RES_X 16
+#define VIEWGRAD_RES_Y 16
+
+ GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4];
+ static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2];
+ static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
+ static char buf_calculated = FALSE;
+
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
+ &scene->display_settings);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* calculate buffers the first time only */
+ if (!buf_calculated) {
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+
+ /* -1..1 range */
+ grid_pos[x][y][0] = (xf - 0.5f) * 2.0f;
+ grid_pos[x][y][1] = (yf - 0.5f) * 2.0f;
+ }
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X - 1; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) {
+ indices[x][y][0] = x * VIEWGRAD_RES_X + y;
+ indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y;
+ }
+ }
+
+ buf_calculated = TRUE;
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+ const float mval[2] = {xf * (float)ar->winx, yf * ar->winy};
+ const float z_up[3] = {0.0f, 0.0f, 1.0f};
+ float out[3];
+ GLubyte *col_ub = grid_col[x][y];
+
+ float col_fac;
+ float col_fl[3];
+
+ ED_view3d_win_to_vector(ar, mval, out);
+
+ if (scene->world->skytype & WO_SKYPAPER) {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = (float)y / (float)VIEWGRAD_RES_Y;
+ }
+ }
+ else {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI);
+ }
+ }
+
+ interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac);
+
+ rgb_float_to_uchar(col_ub, col_fl);
+ col_ub[3] = 0;
+ }
+ }
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, grid_pos);
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col);
+
+ glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glShadeModel(GL_FLAT);
+
+#undef VIEWGRAD_RES_X
+#undef VIEWGRAD_RES_Y
+ }
+ else { /* solid sky */
+ float col_hor[3];
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+
+ glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+ else {
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ /* only clear depth buffer here */
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_QUADS);
+ UI_ThemeColor(TH_LOW_GRAD);
+ glVertex2f(-1.0, -1.0);
+ glVertex2f(1.0, -1.0);
+ UI_ThemeColor(TH_HIGH_GRAD);
+ glVertex2f(1.0, 1.0);
+ glVertex2f(-1.0, 1.0);
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+ else {
+ UI_ThemeClearColor(TH_HIGH_GRAD);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+}
+
/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */
static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit)
{
@@ -2965,7 +3153,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Base *base;
- float backcol[3];
unsigned int lay_used;
/* shadow buffers, before we setup matrices */
@@ -2978,21 +3165,12 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
GPU_default_lights();
}
- /* clear background */
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) && scene->world) {
- IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
-
- glClearColor(backcol[0], backcol[1], backcol[2], 0.0);
- }
- else
- UI_ThemeClearColor(TH_BACK);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
/* setup view matrices */
view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
+ /* clear the background */
+ view3d_main_area_clear(scene, v3d, ar);
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
if (rv3d->rflag & RV3D_CLIPPING)
@@ -3102,10 +3280,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
// REEB_draw();
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
/* must be before xray draw which clears the depth buffer */
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, 1);
+ draw_gpencil_view3d(scene, v3d, ar, TRUE);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
@@ -3152,6 +3330,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ rcti rect;
+
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ ED_region_visible_rect(ar, &rect);
if (rv3d->persp == RV3D_CAMOB) {
drawviewborder(scene, ar, v3d);
@@ -3168,23 +3350,24 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ draw_gpencil_view3d(scene, v3d, ar, FALSE);
+ }
+
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
Object *ob;
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- // if (v3d->flag2 & V3D_DISPGP)
- draw_gpencil_view3d(scene, v3d, ar, 0);
-
drawcursor(scene, ar, v3d);
if (U.uiflag & USER_SHOW_ROTVIEWICON)
- draw_view_axis(rv3d);
+ draw_view_axis(rv3d, &rect);
else
- draw_view_icon(rv3d);
+ draw_view_icon(rv3d, &rect);
ob = OBACT;
if (U.uiflag & USER_DRAWVIEWINFO)
- draw_selected_name(scene, ob);
+ draw_selected_name(scene, ob, &rect);
}
if (rv3d->render_engine) {
@@ -3194,10 +3377,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
- draw_viewport_fps(scene, ar);
+ draw_viewport_fps(scene, &rect);
}
else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
- draw_viewport_name(ar, v3d);
+ draw_viewport_name(ar, v3d, &rect);
}
if (grid_unit) { /* draw below the viewport name */
@@ -3208,7 +3391,8 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
}
- BLF_draw_default_ascii(22, ar->winy - (USER_SHOW_VIEWPORTNAME ? 40 : 20), 0.0f,
+ BLF_draw_default_ascii(rect.xmin + U.widget_unit,
+ rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
numstr[0] ? numstr : grid_unit, sizeof(numstr));
}
}
@@ -3290,14 +3474,14 @@ static void bl_debug_draw(void)
if (_bl_debug_draw_quads_tot) {
int i;
cpack(0x00FF0000);
- glBegin(GL_LINE_LOOP);
for (i = 0; i < _bl_debug_draw_quads_tot; i ++) {
+ glBegin(GL_LINE_LOOP);
glVertex3fv(_bl_debug_draw_quads[i][0]);
glVertex3fv(_bl_debug_draw_quads[i][1]);
glVertex3fv(_bl_debug_draw_quads[i][2]);
glVertex3fv(_bl_debug_draw_quads[i][3]);
+ glEnd();
}
- glEnd();
}
if (_bl_debug_draw_edges_tot) {
int i;
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index d45013c40d9..30ed7a57f9d 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -83,6 +83,9 @@
#include "view3d_intern.h" /* own include */
+/* for ndof prints */
+// #define DEBUG_NDOF_MOTION
+
/* ********************** view3d_edit: view manipulations ********************* */
int ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d)
@@ -96,7 +99,8 @@ int ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d)
void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
{
if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs);
+ /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
+ rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
}
@@ -431,8 +435,21 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
copy_v3_v3(vod->ofs, rv3d->ofs);
if (vod->use_dyn_ofs) {
- /* If there's no selection, lastofs is unmodified and last value since static */
- calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = OBACT;
+
+ if (ob && ob->mode & OB_MODE_ALL_PAINT) {
+ /* transformation is disabled for painting modes, which will make it
+ * so previous offset is used. This is annoying when you open file
+ * saved with active object in painting mode
+ */
+ copy_v3_v3(lastofs, ob->obmat[3]);
+ }
+ else {
+ /* If there's no selection, lastofs is unmodified and last value since static */
+ calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL);
+ }
+
negate_v3_v3(vod->dyn_ofs, lastofs);
}
else if (U.uiflag & USER_ZBUF_ORBIT) {
@@ -895,7 +912,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* changed since 2.4x, use the camera view */
if (vod->v3d->camera) {
- rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs);
+ rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(vod->v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
@@ -907,7 +924,12 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
if (event->type == MOUSEPAN) {
- viewrotate_apply(vod, event->prevx, event->prevy);
+ /* 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(rv3d);
viewops_data_free(C, op);
@@ -957,7 +979,7 @@ static int viewrotate_cancel(bContext *C, wmOperator *op)
void VIEW3D_OT_rotate(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Rotate view";
+ ot->name = "Rotate View";
ot->description = "Rotate the view";
ot->idname = "VIEW3D_OT_rotate";
@@ -994,17 +1016,20 @@ void ndof_to_quat(struct wmNDOFMotionData *ndof, float q[4])
*/
static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- ViewOpsData *vod = op->customdata;
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
else {
View3D *v3d = CTX_wm_view3d(C);
+ ViewOpsData *vod;
RegionView3D *rv3d = CTX_wm_region_view3d(C);
wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
ED_view3d_camera_lock_init(v3d, rv3d);
+ viewops_data_create(C, op, event);
+ vod = op->customdata;
+
rv3d->rot_angle = 0.f; /* off by default, until changed later this function */
if (ndof->progress != P_FINISHING) {
@@ -1021,11 +1046,10 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event)
float view_inv[4];
invert_qt_qt(view_inv, rv3d->viewquat);
- /* #define DEBUG_NDOF_MOTION */
- #ifdef DEBUG_NDOF_MOTION
+#ifdef DEBUG_NDOF_MOTION
printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
- #endif
+#endif
if (rv3d->viewlock == RV3D_LOCKED) {
/* rotation not allowed -- explore panning options instead */
@@ -1124,8 +1148,10 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
+ viewops_data_free(C, op);
+
ED_view3d_camera_lock_sync(v3d, rv3d);
-
+
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
@@ -1147,6 +1173,180 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
ot->flag = 0;
}
+
+static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+
+ if (event->type != NDOF_MOTION)
+ return OPERATOR_CANCELLED;
+ else {
+ ViewOpsData *vod;
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+
+ ED_view3d_camera_lock_init(v3d, rv3d);
+
+ rv3d->rot_angle = 0.f; /* off by default, until changed later this function */
+
+ viewops_data_create(C, op, event);
+ vod = op->customdata;
+
+ if (ndof->progress != P_FINISHING) {
+ const float dt = ndof->dt;
+
+ /* tune these until everything feels right */
+ const float rot_sensitivity = 1.f;
+
+ const float zoom_sensitivity = 1.f;
+
+ const float pan_sensitivity = 1.f;
+ const int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec);
+
+ float view_inv[4];
+ invert_qt_qt(view_inv, rv3d->viewquat);
+
+#ifdef DEBUG_NDOF_MOTION
+ printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
+ ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
+#endif
+
+ if (ndof->tz) {
+ /* Zoom!
+ * velocity should be proportional to the linear velocity attained by rotational motion of same strength
+ * [got that?]
+ * proportional to arclength = radius * angle
+ */
+ float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
+
+ if (U.ndof_flag & NDOF_ZOOM_INVERT)
+ zoom_distance = -zoom_distance;
+
+ rv3d->dist += zoom_distance;
+ }
+
+ if (rv3d->viewlock == RV3D_LOCKED) {
+ /* rotation not allowed -- explore panning options instead */
+ float pan_vec[3] = {ndof->tx, ndof->ty, 0.0f};
+ mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
+
+ /* transform motion from view to world coordinates */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ mul_qt_v3(view_inv, pan_vec);
+
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, pan_vec);
+ }
+
+ if (has_rotation) {
+
+ rv3d->view = RV3D_VIEW_USER;
+
+ if (U.ndof_flag & NDOF_TURNTABLE) {
+
+ /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
+ float angle, rot[4];
+ float xvec[3] = {1, 0, 0};
+
+ /* Determine the direction of the x vector (for rotating up and down) */
+ mul_qt_v3(view_inv, xvec);
+
+ /* Perform the up/down rotation */
+ angle = rot_sensitivity * dt * ndof->rx;
+ if (U.ndof_flag & NDOF_TILT_INVERT_AXIS)
+ angle = -angle;
+ rot[0] = cos(angle);
+ mul_v3_v3fl(rot + 1, xvec, sin(angle));
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ /* Perform the orbital rotation */
+ angle = rot_sensitivity * dt * ndof->ry;
+ if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
+ angle = -angle;
+
+ /* update the onscreen doo-dad */
+ rv3d->rot_angle = angle;
+ rv3d->rot_axis[0] = 0;
+ rv3d->rot_axis[1] = 0;
+ rv3d->rot_axis[2] = 1;
+
+ rot[0] = cos(angle);
+ rot[1] = rot[2] = 0.0;
+ rot[3] = sin(angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ }
+ else {
+ float rot[4];
+ float axis[3];
+ float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
+
+ if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS)
+ axis[2] = -axis[2];
+
+ if (U.ndof_flag & NDOF_TILT_INVERT_AXIS)
+ axis[0] = -axis[0];
+
+ if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
+ axis[1] = -axis[1];
+
+
+ /* transform rotation axis from view to world coordinates */
+ mul_qt_v3(view_inv, axis);
+
+ /* update the onscreen doo-dad */
+ rv3d->rot_angle = angle;
+ copy_v3_v3(rv3d->rot_axis, axis);
+
+ axis_angle_to_quat(rot, axis, angle);
+
+ /* apply rotation */
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ }
+
+ /* rotate around custom center */
+ if (vod && vod->use_dyn_ofs) {
+ float q1[4];
+
+ /* compute the post multiplication quat, to rotate the offset correctly */
+ conjugate_qt_qt(q1, vod->oldquat);
+ mul_qt_qtqt(q1, q1, rv3d->viewquat);
+
+ conjugate_qt(q1); /* conj == inv for unit quat */
+ copy_v3_v3(rv3d->ofs, vod->ofs);
+ sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
+ mul_qt_v3(q1, rv3d->ofs);
+ add_v3_v3(rv3d->ofs, vod->dyn_ofs);
+ }
+ }
+ }
+
+ viewops_data_free(C, op);
+
+ ED_view3d_camera_lock_sync(v3d, rv3d);
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+ }
+}
+
+void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "NDOF Orbit View with Zoom";
+ ot->description = "Explore every angle of an object using the 3D mouse";
+ ot->idname = "VIEW3D_OT_ndof_orbit_zoom";
+
+ /* api callbacks */
+ ot->invoke = ndof_orbit_zoom_invoke;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = 0;
+}
+
/* -- "pan" navigation
* -- zoom or dolly?
*/
@@ -1183,8 +1383,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
#else /* ------------------------------------------------------- dolly with Z */
- float speed = 10.f; /* blender units per second */
- /* ^^ this is ok for default cube scene, but should scale with.. something */
+ float speed = rv3d->dist; /* uses distance from pivot to define dolly */
/* tune these until everything feels right */
const float forward_sensitivity = 1.f;
@@ -1247,8 +1446,9 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
*/
static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if (event->type != NDOF_MOTION)
+ if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
+ }
else {
ViewOpsData *vod;
@@ -1268,23 +1468,14 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
const float dt = ndof->dt;
float view_inv[4];
- float speed = 10.f; /* blender units per second */
- /* ^^ this is ok for default cube scene, but should scale with.. something */
+ float speed = rv3d->dist; /* uses distance from pivot to define dolly */
/* tune these until everything feels right */
const float forward_sensitivity = 1.f;
const float vertical_sensitivity = 0.4f;
const float lateral_sensitivity = 0.6f;
-
float pan_vec[3];
const float rot_sensitivity = 1.f;
-#if 0
- const float zoom_sensitivity = 1.f;
- const float pan_sensitivity = 1.f;
- float rot[4];
- float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
- float axis[3];
-#endif
/* inverse view */
invert_qt_qt(view_inv, rv3d->viewquat);
@@ -1375,7 +1566,7 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* rotate around custom center */
- if (vod && vod->use_dyn_ofs) {
+ if (vod->use_dyn_ofs) {
float q1[4];
/* compute the post multiplication quat, to rotate the offset correctly */
@@ -1390,10 +1581,13 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
+
+ viewops_data_free(C, op);
+
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_region_tag_redraw(CTX_wm_region(C));
- viewops_data_free(C, op);
+
return OPERATOR_FINISHED;
}
}
@@ -1401,7 +1595,7 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
void VIEW3D_OT_ndof_all(struct wmOperatorType *ot)
{
/* identifiers */
- ot->name = "NDOF move View";
+ ot->name = "NDOF Move View";
ot->description = "Position your viewpoint with the 3D mouse";
ot->idname = "VIEW3D_OT_ndof_all";
@@ -1537,7 +1731,8 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
vod = op->customdata;
if (event->type == MOUSEPAN) {
- viewmove_apply(vod, event->prevx, event->prevy);
+ /* invert it, trackpad scroll follows same principle as 2d windows this way */
+ viewmove_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -1563,7 +1758,7 @@ void VIEW3D_OT_move(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Move view";
+ ot->name = "Move View";
ot->description = "Move the view";
ot->idname = "VIEW3D_OT_move";
@@ -1910,17 +2105,16 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
viewzoom_exec(C, op);
}
else {
- if (event->type == MOUSEZOOM) {
- /* Bypass Zoom invert flag for track pads (pass FALSE always) */
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->origx = vod->oldx = event->x;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
ED_view3d_depth_tag_update(vod->rv3d);
@@ -2186,7 +2380,7 @@ static int viewdolly_cancel(bContext *C, wmOperator *op)
void VIEW3D_OT_dolly(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Dolly view";
+ ot->name = "Dolly View";
ot->description = "Dolly in/out in the view";
ot->idname = "VIEW3D_OT_dolly";
@@ -2218,7 +2412,7 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
float new_dist;
sub_v3_v3v3(afm, max, min);
- size = MAX3(afm[0], afm[1], afm[2]);
+ size = max_fff(afm[0], afm[1], afm[2]);
if (ok_dist) {
/* fix up zoom distance if needed */
@@ -3268,7 +3462,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
PropertyRNA *prop;
/* identifiers */
- ot->name = "View numpad";
+ ot->name = "View Numpad";
ot->description = "Use a preset viewpoint";
ot->idname = "VIEW3D_OT_viewnumpad";
@@ -3576,7 +3770,7 @@ static void calc_clipping_plane(float clip[6][4], BoundBox *clipbb)
}
}
-static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float mat[][4])
+static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4])
{
BoundBox clipbb_local;
float imat[4][4];
@@ -3591,7 +3785,7 @@ static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float m
calc_clipping_plane(clip_local, &clipbb_local);
}
-void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[][4])
+void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
{
if (rv3d->rflag & RV3D_CLIPPING)
calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat);
@@ -3662,18 +3856,17 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
/* ***************** 3d cursor cursor op ******************* */
-/* mx my in region coords */
-static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+/* cursor position in vec, result in vec, mval in region coords */
+/* note: cannot use event->mval here (called by object_add() */
+void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
{
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- float *fp = NULL;
float mval_fl[2];
int flip;
- fp = give_cursor(scene, v3d);
-
+
flip = initgrabz(rv3d, fp[0], fp[1], fp[2]);
/* reset the depth based on the view offset (we _know_ the offset is infront of us) */
@@ -3688,20 +3881,20 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, event->mval, fp))
+ if (ED_view3d_autodist(scene, ar, v3d, mval, fp))
depth_used = TRUE;
}
if (depth_used == FALSE) {
float dvec[3];
- VECSUB2D(mval_fl, mval_fl, event->mval);
+ VECSUB2D(mval_fl, mval_fl, mval);
ED_view3d_win_to_delta(ar, mval_fl, dvec);
sub_v3_v3(fp, dvec);
}
}
else {
- const float dx = ((float)(event->mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2);
- const float dy = ((float)(event->mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2);
+ const float dx = ((float)(mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2);
+ const float dy = ((float)(mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2);
const float fz = (rv3d->persmat[0][3] * fp[0] +
rv3d->persmat[1][3] * fp[1] +
rv3d->persmat[2][3] * fp[2] +
@@ -3712,11 +3905,21 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *
fp[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy + rv3d->persinv[2][2] * fz) - rv3d->ofs[2];
}
+}
+
+static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ float *fp = give_cursor(scene, v3d);
+
+ ED_view3d_cursor3d_position(C, fp, event->mval);
+
if (v3d && v3d->localvd)
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
else
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -3977,16 +4180,28 @@ int ED_view3d_autodist_depth_seg(ARegion *ar, const int mval_sta[2], const int m
return (*depth == FLT_MAX) ? 0 : 1;
}
-float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) {
+/* problem - ofs[3] can be on same location as camera itself.
+ * Blender needs proper dist value for zoom.
+ * use fallback_dist to override small values
+ */
+float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist)
+{
float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
-
+ float dist;
+
mul_m4_v4(mat, pos);
add_v3_v3(pos, ofs);
mul_m4_v4(mat, dir);
normalize_v3(dir);
- return dot_v3v3(pos, dir);
+ dist = dot_v3v3(pos, dir);
+
+ if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
+ dist = fallback_dist;
+ }
+
+ return dist;
}
/**
@@ -3997,7 +4212,7 @@ float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) {
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist The view distance from ofs, normally from RegionView3D.dist.
*/
-void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist)
+void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist)
{
/* Offset */
if (ofs)
@@ -4034,7 +4249,7 @@ void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist)
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist The view distance from ofs, normally from RegionView3D.dist.
*/
-void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist)
+void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
{
float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
float dvec[3] = {0.0f, 0.0f, dist};
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index cddfae53f6f..c2e75a1c5d9 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -76,7 +76,8 @@ enum {
FLY_MODAL_PRECISION_ENABLE,
FLY_MODAL_PRECISION_DISABLE,
FLY_MODAL_FREELOOK_ENABLE,
- FLY_MODAL_FREELOOK_DISABLE
+ FLY_MODAL_FREELOOK_DISABLE,
+ FLY_MODAL_SPEED, /* mousepan typically */
};
@@ -132,6 +133,8 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_ACCELERATE);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE);
+ WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, FLY_MODAL_SPEED);
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
/* XXX - Bug in the event system, middle mouse release doesnt work */
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE);
@@ -544,7 +547,22 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
case FLY_MODAL_CONFIRM:
fly->state = FLY_CONFIRM;
break;
-
+
+ /* speed adjusting with mousepan (trackpad) */
+ case FLY_MODAL_SPEED:
+ {
+ float fac = 0.02f * (event->prevy - event->y);
+
+ /* allowing to brake immediate */
+ if (fac > 0.0f && fly->speed < 0.0f)
+ fly->speed = 0.0f;
+ else if (fac < 0.0f && fly->speed > 0.0f)
+ fly->speed = 0.0f;
+ else
+ fly->speed += fly->grid * fac;
+
+ break;
+ }
case FLY_MODAL_ACCELERATE:
{
double time_currwheel;
@@ -816,7 +834,7 @@ static int flyApply(bContext *C, FlyInfo *fly)
/* scale the mouse movement by this value - scales mouse movement to the view size
- * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y)
+ * moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y)
*
* the mouse moves isn't linear */
@@ -1041,8 +1059,8 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly)
const int flag = U.ndof_flag;
#if 0
- int shouldRotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == FALSE),
- shouldTranslate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM));
+ int shouldRotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == FALSE);
+ int shouldTranslate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM));
#endif
int shouldRotate = (fly->pan_view == FALSE);
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 79bf003a563..7161014396a 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -400,13 +400,13 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
block = uiLayoutGetBlock(row);
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- "Vertex select - Shift-Click for multiple modes");
+ TIP_("Vertex select - Shift-Click for multiple modes"));
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- "Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection");
+ TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
- "Face select - Shift-Click for multiple modes, Ctrl-Click expands selection");
+ TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
}
}
@@ -487,11 +487,17 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
block = uiLayoutGetBlock(row);
if (v3d->twflag & V3D_USE_MANIPULATOR) {
- but = uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Translate manipulator - Shift-Click for multiple modes"));
+ but = uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0,
+ TIP_("Translate manipulator - Shift-Click for multiple modes"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Rotate manipulator - Shift-Click for multiple modes"));
+ but = uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0,
+ TIP_("Rotate manipulator - Shift-Click for multiple modes"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Scale manipulator - Shift-Click for multiple modes"));
+ but = uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0,
+ TIP_("Scale manipulator - Shift-Click for multiple modes"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
}
@@ -500,7 +506,8 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
str_menu = BIF_menustringTransformOrientation(C, "Orientation");
- but = uiDefButC(block, MENU, B_MAN_MODE, str_menu, 0, 0, 70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, TIP_("Transform Orientation"));
+ but = uiDefButC(block, MENU, B_MAN_MODE, str_menu, 0, 0, 70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0,
+ TIP_("Transform Orientation"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
MEM_freeN((void *)str_menu);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 5beeda9f220..c8f0fe44433 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -77,6 +77,7 @@ void VIEW3D_OT_zoom_camera_1_to_1(struct wmOperatorType *ot);
void VIEW3D_OT_move(struct wmOperatorType *ot);
void VIEW3D_OT_rotate(struct wmOperatorType *ot);
void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot);
+void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot);
void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot);
void VIEW3D_OT_ndof_all(struct wmOperatorType *ot);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
@@ -118,14 +119,14 @@ void draw_motion_paths_cleanup(View3D *v3d);
/* drawobject.c */
void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, const short dflag);
-int draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const short dt);
-void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const short dt, int outline);
+int draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const char dt);
+void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline);
void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
void drawaxes(float size, char drawtype);
void view3d_cached_text_draw_begin(void);
void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]);
-void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[][4]);
+void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[4][4]);
enum {
V3D_CACHE_TEXT_ZBUF = (1 << 0),
@@ -172,7 +173,7 @@ void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
-int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[][4], struct BoundBox *bb);
+int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[4][4], struct BoundBox *bb);
void view3d_smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *ar, struct Object *, struct Object *,
float *ofs, float *quat, float *dist, float *lens);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 37607729d0d..81e890c37ee 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -27,6 +27,7 @@
#include "DNA_curve_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meta_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
@@ -47,6 +48,12 @@
#include "ED_object.h"
#include "ED_view3d.h"
+typedef struct foreachScreenObjectVert_userData {
+ void (*func)(void *userData, MVert *mv, const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ eV3DProjTest clip_flag;
+} foreachScreenObjectVert_userData;
typedef struct foreachScreenVert_userData {
void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index);
@@ -79,6 +86,46 @@ typedef struct foreachScreenFace_userData {
/* ------------------------------------------------------------------------ */
+
+static void meshobject_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ foreachScreenObjectVert_userData *data = userData;
+ struct MVert *mv = &((Mesh *)(data->vc.obact->data))->mvert[index];
+
+ if (!(mv->flag & ME_HIDE)) {
+ float screen_co[2];
+
+ if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) {
+ return;
+ }
+
+ data->func(data->userData, mv, screen_co, index);
+ }
+}
+
+void meshobject_foreachScreenVert(
+ ViewContext *vc,
+ void (*func)(void *userData, MVert *eve, const float screen_co[2], int index),
+ void *userData, eV3DProjTest clip_flag)
+{
+ foreachScreenObjectVert_userData data;
+ DerivedMesh *dm = mesh_get_derived_deform(vc->scene, vc->obact, CD_MASK_BAREMESH);
+
+ data.vc = *vc;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
+
+ dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data);
+
+ dm->release(dm);
+}
+
static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -113,9 +160,8 @@ void mesh_foreachScreenVert(
ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
}
- EDBM_index_arrays_init(vc->em, 1, 0, 0);
+ EDBM_index_arrays_ensure(vc->em, BM_VERT);
dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
dm->release(dm);
}
@@ -172,9 +218,8 @@ void mesh_foreachScreenEdge(
ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
}
- EDBM_index_arrays_init(vc->em, 0, 1, 0);
+ EDBM_index_arrays_ensure(vc->em, BM_EDGE);
dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
dm->release(dm);
}
@@ -209,9 +254,8 @@ void mesh_foreachScreenFace(
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- EDBM_index_arrays_init(vc->em, 0, 0, 1);
+ EDBM_index_arrays_ensure(vc->em, BM_FACE);
dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
dm->release(dm);
}
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 6105b5e4eb5..bf1c5404c0e 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -43,15 +43,84 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_main.h"
+
#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_screen.h"
#include "ED_transform.h"
#include "view3d_intern.h"
+/* ************************** copy paste ***************************** */
+
+static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
+{
+ char str[FILE_MAX];
+
+ BKE_copybuffer_begin();
+
+ /* context, selection, could be generalized */
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ BKE_copybuffer_tag_ID(&ob->id);
+
+ }
+ CTX_DATA_END;
+
+ BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend");
+ BKE_copybuffer_save(str, op->reports);
+
+ return OPERATOR_FINISHED;
+}
+
+static void VIEW3D_OT_copybuffer(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name = "Copy Selection to Buffer";
+ ot->idname = "VIEW3D_OT_copybuffer";
+ ot->description = "Selected objects are saved in a temp file";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = view3d_copybuffer_exec;
+ ot->poll = ED_operator_view3d_active;
+}
+
+static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
+{
+ char str[FILE_MAX];
+
+ BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend");
+ BKE_copybuffer_paste(C, str, op->reports);
+
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name = "Paste Selection from Buffer";
+ ot->idname = "VIEW3D_OT_pastebuffer";
+ ot->description = "Contents of copy buffer gets pasted";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = view3d_pastebuffer_exec;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
/* ************************** registration **********************************/
@@ -62,6 +131,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_zoom);
WM_operatortype_append(VIEW3D_OT_zoom_camera_1_to_1);
WM_operatortype_append(VIEW3D_OT_dolly);
+ WM_operatortype_append(VIEW3D_OT_ndof_orbit_zoom);
WM_operatortype_append(VIEW3D_OT_ndof_orbit);
WM_operatortype_append(VIEW3D_OT_ndof_pan);
WM_operatortype_append(VIEW3D_OT_ndof_all);
@@ -97,6 +167,8 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_game_start);
WM_operatortype_append(VIEW3D_OT_fly);
WM_operatortype_append(VIEW3D_OT_layers);
+ WM_operatortype_append(VIEW3D_OT_copybuffer);
+ WM_operatortype_append(VIEW3D_OT_pastebuffer);
WM_operatortype_append(VIEW3D_OT_properties);
WM_operatortype_append(VIEW3D_OT_toolshelf);
@@ -117,13 +189,13 @@ void view3d_keymap(wmKeyConfig *keyconf)
wmKeyMapItem *kmi;
keymap = WM_keymap_find(keyconf, "3D View Generic", SPACE_VIEW3D, 0);
-
+
WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_toolshelf", TKEY, KM_PRESS, 0, 0);
/* only for region 3D window */
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
-
+
kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
/*
@@ -149,10 +221,11 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEROTATE, 0, 0, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0);
/*numpad +/-*/
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
@@ -170,6 +243,8 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_camera", HOMEKEY, KM_PRESS, 0, 0); /* only with camera view */
+ WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_cursor", HOMEKEY, KM_PRESS, KM_ALT, 0);
+
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, KM_CTRL, 0);
@@ -226,11 +301,16 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+
+ WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
+ /* NDOF: begin */
+ /* note: positioned here so keymaps show keyboard keys if assigned */
/* 3D mouse */
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit_zoom", NDOF_MOTION, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
@@ -238,7 +318,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
-
+
/* 3D mouse align */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
@@ -249,9 +329,9 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
-
- WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
+ /* NDOF: end */
+
/* layers, shift + alt are properties set in invoke() */
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ACCENTGRAVEKEY, KM_PRESS, 0, 0)->ptr, "nr", 0);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ONEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 1);
@@ -359,6 +439,13 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
+#ifdef __APPLE__
+ WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_OSKEY, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_OSKEY, 0);
+#endif
+ WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_CTRL, 0);
+
/* context ops */
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");
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 34b983f83df..c428cb02236 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -110,13 +110,13 @@ eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
/* perspmat is typically...
* - 'rv3d->perspmat', is_local == FALSE
- * - 'rv3d->perspmatob', is_local == TRUE
+ * - 'rv3d->persmatob', is_local == TRUE
*/
static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
float perspmat[4][4], const int is_local, /* normally hidden */
const float co[3], float r_co[2], const eV3DProjTest flag)
{
- float fx, fy, vec4[4];
+ float vec4[4];
/* check for bad flags */
BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag);
@@ -134,13 +134,19 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
vec4[3] = 1.0;
mul_m4_v4(perspmat, vec4);
- if (vec4[3] > (float)BL_NEAR_CLIP) {
- fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]);
- if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) {
- fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]);
+ if (((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) || (vec4[3] > (float)BL_NEAR_CLIP)) {
+ const float scalar = (vec4[3] != 0.0f) ? (1.0f / vec4[3]): 0.0f;
+ const float fx = ((float)ar->winx / 2.0f) * (1.0f + (vec4[0] * scalar));
+ if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0.0f && fx < (float)ar->winx)) {
+ const float fy = ((float)ar->winy / 2.0f) * (1.0f + (vec4[1] * scalar));
if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
- r_co[0] = (short)floor(fx);
- r_co[1] = (short)floor(fy);
+ r_co[0] = floorf(fx);
+ r_co[1] = floorf(fy);
+
+ /* check if the point is behind the view, we need to flip in this case */
+ if (UNLIKELY((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) && (vec4[3] < 0.0f)) {
+ negate_v2(r_co);
+ }
}
else {
return V3D_PROJ_RET_CLIP_WIN;
@@ -166,8 +172,8 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con
if ((tvec[0] > -32700.0f && tvec[0] < 32700.0f) &&
(tvec[1] > -32700.0f && tvec[1] < 32700.0f))
{
- r_co[0] = (short)floor(tvec[0]);
- r_co[1] = (short)floor(tvec[1]);
+ r_co[0] = (short)floorf(tvec[0]);
+ r_co[1] = (short)floorf(tvec[1]);
}
else {
ret = V3D_PROJ_RET_OVERFLOW;
@@ -185,8 +191,8 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const
if ((tvec[0] > -2140000000.0f && tvec[0] < 2140000000.0f) &&
(tvec[1] > -2140000000.0f && tvec[1] < 2140000000.0f))
{
- r_co[0] = (int)floor(tvec[0]);
- r_co[1] = (int)floor(tvec[1]);
+ r_co[0] = (int)floorf(tvec[0]);
+ r_co[1] = (int)floorf(tvec[1]);
}
else {
ret = V3D_PROJ_RET_OVERFLOW;
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index cffa53b5dfb..dac887f7f13 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -70,6 +70,7 @@
#include "BKE_paint.h"
#include "BKE_tessmesh.h"
#include "BKE_tracking.h"
+#include "BKE_utildefines.h"
#include "BIF_gl.h"
@@ -541,11 +542,11 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -741,67 +742,19 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m
mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
-static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
+static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
{
- Mesh *me;
- MVert *mvert;
- struct ImBuf *ibuf;
- unsigned int *rt;
- int a, index;
- char *selar;
- int sx = BLI_rcti_size_x(rect) + 1;
- int sy = BLI_rcti_size_y(rect) + 1;
-
- me = vc->obact->data;
-
- if (me == NULL || me->totvert == 0 || sx * sy <= 0)
- return OPERATOR_CANCELLED;
-
- selar = MEM_callocN(me->totvert + 1, "selar");
-
- if (extend == 0 && select)
- paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE);
-
- view3d_validate_backbuf(vc);
-
- ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect);
- rt = ibuf->rect;
- glReadPixels(rect->xmin + vc->ar->winrct.xmin, rect->ymin + vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
- if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
-
- a = sx * sy;
- while (a--) {
- if (*rt) {
- index = WM_framebuffer_to_index(*rt);
- if (index <= me->totvert) selar[index] = 1;
- }
- rt++;
- }
+ LassoSelectUserData *data = userData;
- mvert = me->mvert;
- for (a = 1; a <= me->totvert; a++, mvert++) {
- if (selar[a]) {
- if ((mvert->flag & ME_HIDE) == 0) {
- if (select) mvert->flag |= SELECT;
- else mvert->flag &= ~SELECT;
- }
- }
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED))
+ {
+ BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
}
-
- IMB_freeImBuf(ibuf);
- MEM_freeN(selar);
-
-#ifdef __APPLE__
- glReadBuffer(GL_BACK);
-#endif
-
- paintvert_flush_flags(vc->obact);
-
- return OPERATOR_FINISHED;
}
-
static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, short extend, short select)
{
+ const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
Object *ob = vc->obact;
Mesh *me = ob ? ob->data : NULL;
rcti rect;
@@ -811,14 +764,31 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
if (extend == 0 && select)
paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
- bm_vertoffs = me->totvert + 1; /* max index array */
BLI_lasso_boundbox(&rect, mcords, moves);
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- edbm_backbuf_check_and_select_verts_obmode(me, select);
+ if (use_zbuf) {
+ bm_vertoffs = me->totvert + 1; /* max index array */
- EDBM_backbuf_free();
+ EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+
+ edbm_backbuf_check_and_select_verts_obmode(me, select);
+
+ EDBM_backbuf_free();
+ }
+ else {
+ LassoSelectUserData data;
+ rcti rect;
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
+
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
+
+ meshobject_foreachScreenVert(vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+ }
paintvert_flush_flags(ob);
}
@@ -1217,31 +1187,42 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int
}
}
+static int selectbuffer_has_bones(const unsigned int *buffer, const unsigned int hits)
+{
+ unsigned int i;
+ for (i = 0; i < hits; i++) {
+ if (buffer[(4 * i) + 3] & 0xFFFF0000) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
/* we want a select buffer with bones, if there are... */
/* so check three selection levels and compare */
static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2])
{
rcti rect;
int offs;
- short a, hits15, hits9 = 0, hits5 = 0;
- short has_bones15 = 0, has_bones9 = 0, has_bones5 = 0;
+ short hits15, hits9 = 0, hits5 = 0;
+ short has_bones15 = FALSE, has_bones9 = FALSE, has_bones5 = FALSE;
BLI_rcti_init(&rect, mval[0] - 14, mval[0] + 14, mval[1] - 14, mval[1] + 14);
hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
if (hits15 > 0) {
- for (a = 0; a < hits15; a++) if (buffer[4 * a + 3] & 0xFFFF0000) has_bones15 = 1;
+ has_bones15 = selectbuffer_has_bones(buffer, hits15);
offs = 4 * hits15;
BLI_rcti_init(&rect, mval[0] - 9, mval[0] + 9, mval[1] - 9, mval[1] + 9);
hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
if (hits9 > 0) {
- for (a = 0; a < hits9; a++) if (buffer[offs + 4 * a + 3] & 0xFFFF0000) has_bones9 = 1;
+ has_bones9 = selectbuffer_has_bones(buffer + offs, hits9);
offs += 4 * hits9;
BLI_rcti_init(&rect, mval[0] - 5, mval[0] + 5, mval[1] - 5, mval[1] + 5);
hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
if (hits5 > 0) {
- for (a = 0; a < hits5; a++) if (buffer[offs + 4 * a + 3] & 0xFFFF0000) has_bones5 = 1;
+ has_bones5 = selectbuffer_has_bones(buffer + offs, hits5);
}
}
@@ -1383,10 +1364,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
hits = mixed_bones_object_selectbuffer(&vc, buffer, mval);
if (hits > 0) {
- int a, has_bones = 0;
-
- for (a = 0; a < hits; a++) if (buffer[4 * a + 3] & 0xFFFF0000) has_bones = 1;
-
+ const int has_bones = selectbuffer_has_bones(buffer, hits);
basact = mouse_select_eval_buffer(&vc, buffer, hits, mval, vc.scene->base.first, has_bones);
}
@@ -1420,7 +1398,6 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL;
- int a;
float dist = 100.0f;
int retval = 0;
short hits;
@@ -1448,7 +1425,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
if (BASE_SELECTABLE(v3d, base)) {
float screen_co[2];
if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
if (base == BASACT) dist_temp += 10.0f;
@@ -1473,10 +1450,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
hits = mixed_bones_object_selectbuffer(&vc, buffer, mval);
if (hits > 0) {
- int has_bones = 0;
-
/* note: bundles are handling in the same way as bones */
- for (a = 0; a < hits; a++) if (buffer[4 * a + 3] & 0xFFFF0000) has_bones = 1;
+ const int has_bones = selectbuffer_has_bones(buffer, hits);
/* note; shift+alt goes to group-flush-selecting */
if (has_bones == 0 && enumerate) {
@@ -1502,7 +1477,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
}
/* index of bundle is 1<<16-based. if there's no "bone" index
- * in height word, this buffer value belongs to camera,. not to bundle */
+ * in height word, this buffer value belongs to camera. not to bundle */
if (buffer[4 * i + 3] & 0xFFFF0000) {
MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, 0);
MovieTracking *tracking = &clip->tracking;
@@ -1670,6 +1645,85 @@ int edge_inside_circle(const float cent[2], float radius, const float screen_co_
return FALSE;
}
+static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
+{
+ BoxSelectUserData *data = userData;
+
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) {
+ BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
+ }
+}
+static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
+{
+ const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
+ Mesh *me;
+ MVert *mvert;
+ struct ImBuf *ibuf;
+ unsigned int *rt;
+ int a, index;
+ char *selar;
+ int sx = BLI_rcti_size_x(rect) + 1;
+ int sy = BLI_rcti_size_y(rect) + 1;
+
+ me = vc->obact->data;
+
+ if (me == NULL || me->totvert == 0 || sx * sy <= 0)
+ return OPERATOR_CANCELLED;
+
+
+ if (extend == 0 && select)
+ paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE);
+
+ if (use_zbuf) {
+ selar = MEM_callocN(me->totvert + 1, "selar");
+ view3d_validate_backbuf(vc);
+
+ ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect);
+ rt = ibuf->rect;
+ glReadPixels(rect->xmin + vc->ar->winrct.xmin, rect->ymin + vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+
+ a = sx * sy;
+ while (a--) {
+ if (*rt) {
+ index = WM_framebuffer_to_index(*rt);
+ if (index <= me->totvert) selar[index] = 1;
+ }
+ rt++;
+ }
+
+ mvert = me->mvert;
+ for (a = 1; a <= me->totvert; a++, mvert++) {
+ if (selar[a]) {
+ if ((mvert->flag & ME_HIDE) == 0) {
+ if (select) mvert->flag |= SELECT;
+ else mvert->flag &= ~SELECT;
+ }
+ }
+ }
+
+ IMB_freeImBuf(ibuf);
+ MEM_freeN(selar);
+
+#ifdef __APPLE__
+ glReadBuffer(GL_BACK);
+#endif
+ }
+ else {
+ BoxSelectUserData data;
+
+ view3d_userdata_boxselect_init(&data, vc, rect, select);
+
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
+
+ meshobject_foreachScreenVert(vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+
+ paintvert_flush_flags(vc->obact);
+
+ return OPERATOR_FINISHED;
+}
+
static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
{
BoxSelectUserData *data = userData;
@@ -1803,11 +1857,11 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -2142,11 +2196,14 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
/* gets called via generic mouse select operator */
static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, short deselect, short toggle, Object *obact)
{
+ View3D *v3d = CTX_wm_view3d(C);
+ const int use_zbuf = (v3d->flag & V3D_ZBUF_SELECT);
+
Mesh *me = obact->data; /* already checked for NULL */
unsigned int index = 0;
MVert *mv;
- if (ED_mesh_pick_vert(C, me, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) {
+ if (ED_mesh_pick_vert(C, obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, use_zbuf)) {
mv = &me->mvert[index];
if (extend) {
mv->flag |= SELECT;
@@ -2333,7 +2390,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f
edbm_backbuf_check_and_select_edges(vc->em, select == LEFTMOUSE);
}
else {
- mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -2366,22 +2423,39 @@ static void paint_facesel_circle_select(ViewContext *vc, int select, const int m
}
}
+static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
+{
+ CircleSelectUserData *data = userData;
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
+ }
+}
static void paint_vertsel_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
{
+ const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
Object *ob = vc->obact;
- Mesh *me = ob ? ob->data : NULL;
+ Mesh *me = ob->data;
/* int bbsel; */ /* UNUSED */
/* CircleSelectUserData data = {NULL}; */ /* UNUSED */
- if (me) {
+
+ if (use_zbuf) {
bm_vertoffs = me->totvert + 1; /* max index array */
/* bbsel = */ /* UNUSED */ EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
edbm_backbuf_check_and_select_verts_obmode(me, select == LEFTMOUSE);
EDBM_backbuf_free();
+ }
+ else {
+ CircleSelectUserData data;
- paintvert_flush_flags(ob);
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
+
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ meshobject_foreachScreenVert(vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
+
+ paintvert_flush_flags(ob);
}
@@ -2670,7 +2744,7 @@ static int object_circle_select(ViewContext *vc, int select, const int mval[2],
if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) {
float screen_co[2];
if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
ED_base_object_select(base, select);
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 7f1bbb22f24..6edcf980d58 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -340,9 +340,8 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod
}
if (transvmain && em->derivedCage) {
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata);
- EDBM_index_arrays_free(em);
}
}
else if (obedit->type == OB_ARMATURE) {
@@ -533,7 +532,6 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod
static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
RegionView3D *rv3d = CTX_wm_region_data(C);
@@ -624,8 +622,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
else {
- ob->recalc |= OB_RECALC_OB;
-
vec[0] = -ob->obmat[3][0] + gridf * floorf(0.5f + ob->obmat[3][0] / gridf);
vec[1] = -ob->obmat[3][1] + gridf * floorf(0.5f + ob->obmat[3][1] / gridf);
vec[2] = -ob->obmat[3][2] + gridf * floorf(0.5f + ob->obmat[3][2] / gridf);
@@ -645,12 +641,13 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
/* auto-keyframing */
ED_autokeyframe_object(C, scene, ob, ks);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
CTX_DATA_END;
}
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
@@ -675,7 +672,6 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -749,8 +745,6 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
else {
- ob->recalc |= OB_RECALC_OB;
-
vec[0] = -ob->obmat[3][0] + curs[0];
vec[1] = -ob->obmat[3][1] + curs[1];
vec[2] = -ob->obmat[3][2] + curs[2];
@@ -770,12 +764,13 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
/* auto-keyframing */
ED_autokeyframe_object(C, scene, ob, ks);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
CTX_DATA_END;
}
- DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index bfeb56036e6..bb5b7aa6911 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -101,22 +101,33 @@ static void view3d_panel_operator_redo_operator(const bContext *C, Panel *pa, wm
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
{
wmOperator *op = WM_operator_last_redo(C);
- uiBlock *block;
-
- if (op == NULL)
- return;
- if (WM_operator_poll((bContext *)C, op->type) == 0)
+ ARegion *ar;
+ ARegion *ar1;
+
+ if (op == NULL) {
return;
-
- block = uiLayoutGetBlock(pa->layout);
-
- if (!WM_operator_check_ui_enabled(C, op->type->name))
- 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);
-
- view3d_panel_operator_redo_operator(C, pa, op);
+ /* keep in sync with logic in ED_undo_operator_repeat() */
+ ar = CTX_wm_region(C);
+ ar1 = BKE_area_find_region_active_win(CTX_wm_area(C));
+ if (ar1)
+ CTX_wm_region_set((bContext *)C, ar1);
+
+ if (WM_operator_poll((bContext *)C, op->type)) {
+ uiBlock *block = uiLayoutGetBlock(pa->layout);
+
+ if (!WM_operator_check_ui_enabled(C, op->type->name))
+ 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);
+
+ view3d_panel_operator_redo_operator(C, pa, op);
+ }
+
+ /* set region back */
+ CTX_wm_region_set((bContext *)C, ar);
}
/* ******************* */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index ef15c1e734e..fba1ce328ba 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -111,17 +111,43 @@ float *give_cursor(Scene *scene, View3D *v3d)
/* ****************** smooth view operator ****************** */
/* This operator is one of the 'timer refresh' ones like animation playback */
+struct SmoothView3DState {
+ float dist;
+ float lens;
+ float quat[4];
+ float ofs[3];
+};
+
struct SmoothView3DStore {
- float orig_dist, new_dist;
- float orig_lens, new_lens;
- float orig_quat[4], new_quat[4];
- float orig_ofs[3], new_ofs[3];
-
- int to_camera, orig_view;
-
+ /* source*/
+ struct SmoothView3DState src; /* source */
+ struct SmoothView3DState dst; /* destination */
+ struct SmoothView3DState org; /* original */
+
+ bool to_camera;
+ char org_view;
+
double time_allowed;
};
+static void view3d_smooth_view_state_backup(struct SmoothView3DState *sms_state,
+ const View3D *v3d, const RegionView3D *rv3d)
+{
+ copy_v3_v3(sms_state->ofs, rv3d->ofs);
+ copy_qt_qt(sms_state->quat, rv3d->viewquat);
+ sms_state->dist = rv3d->dist;
+ sms_state->lens = v3d->lens;
+}
+
+static void view3d_smooth_view_state_restore(const struct SmoothView3DState *sms_state,
+ View3D *v3d, RegionView3D *rv3d)
+{
+ copy_v3_v3(rv3d->ofs, sms_state->ofs);
+ copy_qt_qt(rv3d->viewquat, sms_state->quat);
+ rv3d->dist = sms_state->dist;
+ v3d->lens = sms_state->lens;
+}
+
/* will start timer if appropriate */
/* the arguments are the desired situation */
void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
@@ -132,15 +158,22 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
ScrArea *sa = CTX_wm_area(C);
RegionView3D *rv3d = ar->regiondata;
- struct SmoothView3DStore sms = {0};
- short ok = FALSE;
+ struct SmoothView3DStore sms = {{0}};
+ bool ok = false;
/* initialize sms */
- copy_v3_v3(sms.new_ofs, rv3d->ofs);
- copy_qt_qt(sms.new_quat, rv3d->viewquat);
- sms.new_dist = rv3d->dist;
- sms.new_lens = v3d->lens;
- sms.to_camera = FALSE;
+ view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
+ view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
+ /* if smoothview runs multiple times... */
+ if (rv3d->sms == NULL) {
+ view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
+ sms.org_view = rv3d->view;
+ }
+ else {
+ sms.org = rv3d->sms->org;
+ sms.org_view = rv3d->sms->org_view;
+ }
+ /* sms.to_camera = false; */ /* initizlized to zero anyway */
/* note on camera locking, this is a little confusing but works ok.
* we may be changing the view 'as if' there is no active camera, but in fact
@@ -155,50 +188,43 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
}
/* store the options we want to end with */
- if (ofs) copy_v3_v3(sms.new_ofs, ofs);
- if (quat) copy_qt_qt(sms.new_quat, quat);
- if (dist) sms.new_dist = *dist;
- if (lens) sms.new_lens = *lens;
+ if (ofs) copy_v3_v3(sms.dst.ofs, ofs);
+ if (quat) copy_qt_qt(sms.dst.quat, quat);
+ if (dist) sms.dst.dist = *dist;
+ if (lens) sms.dst.lens = *lens;
if (camera) {
- sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs);
- ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens);
- sms.to_camera = TRUE; /* restore view3d values in end */
+ sms.dst.dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK);
+ ED_view3d_from_object(camera, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
+ sms.to_camera = true; /* restore view3d values in end */
}
if (C && U.smooth_viewtx) {
- int changed = FALSE; /* zero means no difference */
+ bool changed = false; /* zero means no difference */
if (oldcamera != camera)
- changed = TRUE;
- else if (sms.new_dist != rv3d->dist)
- changed = TRUE;
- else if (sms.new_lens != v3d->lens)
- changed = TRUE;
- else if (!equals_v3v3(sms.new_ofs, rv3d->ofs))
- changed = TRUE;
- else if (!equals_v4v4(sms.new_quat, rv3d->viewquat))
- changed = TRUE;
+ changed = true;
+ else if (sms.dst.dist != rv3d->dist)
+ changed = true;
+ else if (sms.dst.lens != v3d->lens)
+ changed = true;
+ else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs))
+ changed = true;
+ else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat))
+ changed = true;
/* The new view is different from the old one
* so animate the view */
if (changed) {
-
/* original values */
if (oldcamera) {
- sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs);
- ED_view3d_from_object(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens);
- }
- else {
- copy_v3_v3(sms.orig_ofs, rv3d->ofs);
- copy_qt_qt(sms.orig_quat, rv3d->viewquat);
- sms.orig_dist = rv3d->dist;
- sms.orig_lens = v3d->lens;
+ sms.src.dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f);
+ /* this */
+ ED_view3d_from_object(oldcamera, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
}
/* grid draw as floor */
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
/* use existing if exists, means multiple calls to smooth view wont loose the original 'view' setting */
- sms.orig_view = rv3d->sms ? rv3d->sms->orig_view : rv3d->view;
rv3d->view = RV3D_VIEW_USER;
}
@@ -212,8 +238,8 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
float vec1[3] = {0, 0, 1}, vec2[3] = {0, 0, 1};
float q1[4], q2[4];
- invert_qt_qt(q1, sms.new_quat);
- invert_qt_qt(q2, sms.orig_quat);
+ invert_qt_qt(q1, sms.dst.quat);
+ invert_qt_qt(q2, sms.src.quat);
mul_qt_v3(q1, vec1);
mul_qt_v3(q2, vec2);
@@ -223,36 +249,45 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
}
/* ensure it shows correct */
- if (sms.to_camera) rv3d->persp = RV3D_PERSP;
+ if (sms.to_camera) {
+ rv3d->persp = RV3D_PERSP;
+ }
rv3d->rflag |= RV3D_NAVIGATING;
+ /* not essential but in some cases the caller will tag the area for redraw,
+ * and in that case we can get a ficker of the 'org' user view but we want to see 'src' */
+ view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
+
/* keep track of running timer! */
- if (rv3d->sms == NULL)
+ if (rv3d->sms == NULL) {
rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d");
+ }
*rv3d->sms = sms;
- if (rv3d->smooth_timer)
+ if (rv3d->smooth_timer) {
WM_event_remove_timer(wm, win, rv3d->smooth_timer);
+ }
/* TIMER1 is hardcoded in keymap */
rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); /* max 30 frs/sec */
-
- ok = TRUE;
+
+ ok = true;
}
}
/* if we get here nothing happens */
- if (ok == FALSE) {
- if (sms.to_camera == FALSE) {
- copy_v3_v3(rv3d->ofs, sms.new_ofs);
- copy_qt_qt(rv3d->viewquat, sms.new_quat);
- rv3d->dist = sms.new_dist;
- v3d->lens = sms.new_lens;
+ if (ok == false) {
+ if (sms.to_camera == false) {
+ copy_v3_v3(rv3d->ofs, sms.dst.ofs);
+ copy_qt_qt(rv3d->viewquat, sms.dst.quat);
+ rv3d->dist = sms.dst.dist;
+ v3d->lens = sms.dst.lens;
ED_view3d_camera_lock_sync(v3d, rv3d);
}
- if (rv3d->viewlock & RV3D_BOXVIEW)
+ if (rv3d->viewlock & RV3D_BOXVIEW) {
view3d_boxview_copy(sa, ar);
+ }
ED_region_tag_redraw(ar);
}
@@ -281,22 +316,16 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
/* if we went to camera, store the original */
if (sms->to_camera) {
rv3d->persp = RV3D_CAMOB;
- copy_v3_v3(rv3d->ofs, sms->orig_ofs);
- copy_qt_qt(rv3d->viewquat, sms->orig_quat);
- rv3d->dist = sms->orig_dist;
- v3d->lens = sms->orig_lens;
+ view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
}
else {
- copy_v3_v3(rv3d->ofs, sms->new_ofs);
- copy_qt_qt(rv3d->viewquat, sms->new_quat);
- rv3d->dist = sms->new_dist;
- v3d->lens = sms->new_lens;
+ view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
ED_view3d_camera_lock_sync(v3d, rv3d);
}
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
- rv3d->view = sms->orig_view;
+ rv3d->view = sms->org_view;
}
MEM_freeN(rv3d->sms);
@@ -312,11 +341,11 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
step_inv = 1.0f - step;
- interp_v3_v3v3(rv3d->ofs, sms->orig_ofs, sms->new_ofs, step);
- interp_qt_qtqt(rv3d->viewquat, sms->orig_quat, sms->new_quat, step);
+ interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step);
+ interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step);
- rv3d->dist = sms->new_dist * step + sms->orig_dist * step_inv;
- v3d->lens = sms->new_lens * step + sms->orig_lens * step_inv;
+ rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
+ v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
ED_view3d_camera_lock_sync(v3d, rv3d);
}
@@ -325,12 +354,16 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C));
/* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
- * when switching camera in quad-view the other ortho views would zoom & reset. */
-#if 0
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
-#else
- ED_region_tag_redraw(CTX_wm_region(C));
-#endif
+ * when switching camera in quad-view the other ortho views would zoom & reset.
+ *
+ * For now only redraw all regions when smoothview finishes.
+ */
+ if (step >= 1.0f) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ }
+ else {
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
return OPERATOR_FINISHED;
}
@@ -579,7 +612,7 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co
}
-int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb)
+int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], BoundBox *bb)
{
/* return 1: draw */
@@ -846,7 +879,8 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
ARegion *ar = vc->ar;
rctf rect;
short code, hits;
- char dt, dtx;
+ char dt;
+ short dtx;
G.f |= G_PICKSEL;
@@ -1070,11 +1104,9 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL
}
}
}
-
- box[0] = (max[0] - min[0]);
- box[1] = (max[1] - min[1]);
- box[2] = (max[2] - min[2]);
- size = MAX3(box[0], box[1], box[2]);
+
+ sub_v3_v3v3(box, max, min);
+ size = max_fff(box[0], box[1], box[2]);
/* do not zoom closer than the near clipping plane */
size = max_ff(size, v3d->near * 1.5f);
@@ -1530,7 +1562,7 @@ float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
rv3d->persmat[0][3] * co[0] +
rv3d->persmat[1][3] * co[1] +
rv3d->persmat[2][3] * co[2])
- ) * rv3d->pixsize;
+ ) * rv3d->pixsize * U.pixelsize;
}
float ED_view3d_radius_to_persp_dist(const float angle, const float radius)
diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript
index 9cf36a2d970..d579fd73db3 100644
--- a/source/blender/editors/transform/SConscript
+++ b/source/blender/editors/transform/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 6145fec7e51..ea82ebb9234 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -52,12 +52,14 @@
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h" /* PET modes */
-#include "RNA_access.h"
-
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
-#include "BLF_api.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_linklist.h"
+#include "BLI_smallhash.h"
#include "BKE_nla.h"
#include "BKE_bmesh.h"
@@ -69,6 +71,9 @@
#include "BKE_unit.h"
#include "BKE_mask.h"
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
#include "ED_image.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
@@ -79,25 +84,36 @@
#include "ED_clip.h"
#include "ED_mask.h"
-#include "UI_view2d.h"
#include "WM_types.h"
#include "WM_api.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BLI_linklist.h"
-#include "BLI_smallhash.h"
-#include "BLI_array.h"
-
+#include "UI_view2d.h"
#include "UI_interface_icons.h"
#include "UI_resources.h"
+#include "RNA_access.h"
+
+#include "BLF_api.h"
+#include "BLF_translation.h"
+
#include "transform.h"
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 drawEdgeSlide(const struct bContext *C, TransInfo *t);
+static void drawVertSlide(const struct bContext *C, TransInfo *t);
+
+static bool transdata_check_local_center(TransInfo *t)
+{
+ return ((t->around == V3D_LOCAL) && (
+ (t->flag & (T_OBJECT | T_POSE)) ||
+ (t->obedit && t->obedit->type == OB_MESH && (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE))) ||
+ (t->obedit && t->obedit->type == OB_ARMATURE) ||
+ (t->spacetype == SPACE_IPO))
+ );
+}
/* ************************** SPACE DEPENDANT CODE **************************** */
@@ -352,6 +368,7 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
case SPACE_VIEW3D:
{
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
+ /* allow points behind the view [#33643] */
if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
/* XXX, 2.64 and prior did this, weak! */
adr[0] = t->ar->winx / 2.0f;
@@ -461,7 +478,10 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
else
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
+
+ if (t->mode == TFM_EDGE_SLIDE && (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+
/* for realtime animation record - send notifiers recognised by animation editors */
// XXX: is this notifier a lame duck?
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
@@ -685,6 +705,9 @@ static void view_editmove(unsigned short UNUSED(event))
#define TFM_MODAL_EDGESLIDE_UP 24
#define TFM_MODAL_EDGESLIDE_DOWN 25
+/* for analog input, like trackpad */
+#define TFM_MODAL_PROPSIZE 26
+
/* called in transform_ops.c, on each regeneration of keymaps */
wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{
@@ -714,6 +737,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{TFM_MODAL_AUTOIK_LEN_DEC, "AUTOIK_CHAIN_LEN_DOWN", 0, "Decrease Max AutoIK Chain Length", ""},
{TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""},
{TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""},
+ {TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -749,6 +773,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, PAGEDOWNKEY, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_DOWN);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_UP);
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_DOWN);
+ WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, TFM_MODAL_PROPSIZE);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0, TFM_MODAL_EDGESLIDE_UP);
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ALT, 0, TFM_MODAL_EDGESLIDE_DOWN);
@@ -766,22 +791,29 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
if (!(t->flag & T_NO_CONSTRAINT)) {
int constraint_axis, constraint_plane;
int edit_2d = (t->flag & T_2D_EDIT);
- char msg1[] = "along _";
- char msg2[] = "along %s _";
- char msg3[] = "locking %s _";
+ const char *msg1 = "", *msg2 = "", *msg3 = "";
char axis;
/* Initialize */
switch (key_type) {
case XKEY:
+ msg1 = IFACE_("along X");
+ msg2 = IFACE_("along %s X");
+ msg3 = IFACE_("locking %s X");
axis = 'X';
constraint_axis = CON_AXIS0;
break;
case YKEY:
+ msg1 = IFACE_("along Y");
+ msg2 = IFACE_("along %s Y");
+ msg3 = IFACE_("locking %s Y");
axis = 'Y';
constraint_axis = CON_AXIS1;
break;
case ZKEY:
+ msg1 = IFACE_("along Z");
+ msg2 = IFACE_("along %s Z");
+ msg3 = IFACE_("locking %s Z");
axis = 'Z';
constraint_axis = CON_AXIS2;
break;
@@ -789,9 +821,6 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
/* Invalid key */
return;
}
- msg1[sizeof(msg1) - 2] = axis;
- msg2[sizeof(msg2) - 2] = axis;
- msg3[sizeof(msg3) - 2] = axis;
constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) & (~constraint_axis));
if (edit_2d && (key_type != ZKEY)) {
@@ -866,19 +895,56 @@ int transformEvent(TransInfo *t, wmEvent *event)
break;
case TFM_MODAL_TRANSLATE:
/* only switch when... */
- if (ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
+ if (ELEM5(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
+ if (t->mode == TFM_EDGE_SLIDE) {
+ freeEdgeSlideVerts(t);
+ }
+ else if (t->mode == TFM_VERT_SLIDE) {
+ freeVertSlideVerts(t);
+ }
resetTransRestrictions(t);
restoreTransObjects(t);
initTranslation(t);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
+ WM_event_add_mousemove(t->context);
}
- else if (t->mode == TFM_TRANSLATION) {
- if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- restoreTransObjects(t);
+ else if (t->mode == TFM_SEQ_SLIDE) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ }
+ else {
+ if (t->obedit && t->obedit->type == OB_MESH) {
+ if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
+ resetTransRestrictions(t);
+ restoreTransObjects(t);
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
+ /* first try edge slide */
+ initEdgeSlide(t);
+ /* if that fails, do vertex slide */
+ if (t->state == TRANS_CANCEL) {
+ t->state = TRANS_STARTING;
+ initVertSlide(t);
+ }
+ /* vert slide can fail on unconnected vertices (rare but possible) */
+ if (t->state == TRANS_CANCEL) {
+ t->state = TRANS_STARTING;
+ resetTransRestrictions(t);
+ restoreTransObjects(t);
+ initTranslation(t);
+ }
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ WM_event_add_mousemove(t->context);
+ }
+ }
+ else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
+ if (t->mode == TFM_TRANSLATION) {
+ restoreTransObjects(t);
+
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ }
}
}
break;
@@ -911,6 +977,10 @@ int transformEvent(TransInfo *t, wmEvent *event)
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
}
+ else if (t->mode == TFM_SHRINKFATTEN) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ }
else if (t->mode == TFM_RESIZE) {
if (t->options & CTX_MOVIECLIP) {
restoreTransObjects(t);
@@ -940,10 +1010,10 @@ int transformEvent(TransInfo *t, wmEvent *event)
}
else {
if (t->flag & T_2D_EDIT) {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), "along X");
+ setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), IFACE_("along X"));
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS0), "along %s X");
+ setUserConstraint(t, t->current_orientation, (CON_AXIS0), IFACE_("along %s X"));
}
}
t->redraw |= TREDRAW_HARD;
@@ -956,10 +1026,10 @@ int transformEvent(TransInfo *t, wmEvent *event)
}
else {
if (t->flag & T_2D_EDIT) {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), "along Y");
+ setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), IFACE_("along Y"));
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS1), "along %s Y");
+ setUserConstraint(t, t->current_orientation, (CON_AXIS1), IFACE_("along %s Y"));
}
}
t->redraw |= TREDRAW_HARD;
@@ -971,7 +1041,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
stopConstraint(t);
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS2), "along %s Z");
+ setUserConstraint(t, t->current_orientation, (CON_AXIS2), IFACE_("along %s Z"));
}
t->redraw |= TREDRAW_HARD;
}
@@ -982,7 +1052,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
stopConstraint(t);
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS1 | CON_AXIS2), "locking %s X");
+ setUserConstraint(t, t->current_orientation, (CON_AXIS1 | CON_AXIS2), IFACE_("locking %s X"));
}
t->redraw |= TREDRAW_HARD;
}
@@ -993,7 +1063,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
stopConstraint(t);
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS2), "locking %s Y");
+ setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS2), IFACE_("locking %s Y"));
}
t->redraw |= TREDRAW_HARD;
}
@@ -1004,7 +1074,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
stopConstraint(t);
}
else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS1), "locking %s Z");
+ setUserConstraint(t, t->current_orientation, (CON_AXIS0 | CON_AXIS1), IFACE_("locking %s Z"));
}
t->redraw |= TREDRAW_HARD;
}
@@ -1023,6 +1093,19 @@ int transformEvent(TransInfo *t, wmEvent *event)
removeSnapPoint(t);
t->redraw |= TREDRAW_HARD;
break;
+
+ case TFM_MODAL_PROPSIZE:
+ /* MOUSEPAN usage... */
+ if (t->flag & T_PROP_EDIT) {
+ float fac = 1.0f + 0.005f *(event->y - event->prevy);
+ t->prop_size *= fac;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
+ t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
+ calculatePropRatio(t);
+ }
+ t->redraw |= TREDRAW_HARD;
+ break;
+
case TFM_MODAL_PROPSIZE_UP:
if (t->flag & T_PROP_EDIT) {
t->prop_size *= 1.1f;
@@ -1096,7 +1179,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
/* exception for switching to dolly, or trackball, in camera view */
if (t->flag & T_CAMERA) {
if (t->mode == TFM_TRANSLATION)
- setLocalConstraint(t, (CON_AXIS2), "along local Z");
+ setLocalConstraint(t, (CON_AXIS2), IFACE_("along local Z"));
else if (t->mode == TFM_ROTATION) {
restoreTransObjects(t);
initTrackball(t);
@@ -1499,7 +1582,6 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
glTranslatef(mval[0], mval[1], 0);
glLineWidth(3.0);
- glBegin(GL_LINES);
drawArrow(UP, 5, 10, 5);
drawArrow(DOWN, 5, 10, 5);
glLineWidth(1.0);
@@ -1579,26 +1661,36 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi
drawConstraint(t);
drawPropCircle(C, t);
drawSnapping(C, t);
- drawNonPropEdge(C, t);
+
+ /* edge slide, vert slide */
+ drawEdgeSlide(C, t);
+ drawVertSlide(C, t);
}
/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */
static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
{
- const char printable[] = "Auto Keying On";
+ rcti rect;
+ const char *printable = IFACE_("Auto Keying On");
float printable_size[2];
int xco, yco;
+ ED_region_visible_rect(ar, &rect);
+
BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]);
- xco = ar->winx - (int)printable_size[0] - 10;
- yco = ar->winy - (int)printable_size[1] - 10;
+ xco = rect.xmax - (int)printable_size[0] - 10;
+ yco = rect.ymax - (int)printable_size[1] - 10;
/* warning text (to clarify meaning of overlays)
* - original color was red to match the icon, but that clashes badly with a less nasty border
*/
UI_ThemeColorShade(TH_TEXT_HI, -50);
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(xco, ar->winy - 17, 0.0f, printable, sizeof(printable));
+#else
BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable));
+#endif
/* autokey recording icon... */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -1855,6 +1947,8 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
}
+ t->keymap = WM_keymap_active(CTX_wm_manager(C), op->type->modalkeymap);
+
initSnapping(t, op); // Initialize snapping data AFTER mode flags
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
@@ -1925,6 +2019,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
case TFM_EDGE_SLIDE:
initEdgeSlide(t);
break;
+ case TFM_VERT_SLIDE:
+ initVertSlide(t);
+ break;
case TFM_BONE_ROLL:
initBoneRoll(t);
break;
@@ -2056,12 +2153,6 @@ void transformApply(bContext *C, TransInfo *t)
t->state = TRANS_CONFIRM;
}
- if (BKE_ptcache_get_continue_physics()) {
- // TRANSFORM_FIX_ME
- //do_screenhandlers(G.curscreen);
- t->redraw |= TREDRAW_HARD;
- }
-
t->context = NULL;
}
@@ -2254,8 +2345,8 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu
static void constraintTransLim(TransInfo *t, TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *ctiLoc = get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
- bConstraintTypeInfo *ctiDist = get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT);
+ bConstraintTypeInfo *ctiLoc = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
+ bConstraintTypeInfo *ctiDist = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
@@ -2274,7 +2365,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
ListBase targets = {NULL, NULL};
/* only consider constraint if enabled */
- if (con->flag & CONSTRAINT_DISABLE) continue;
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) continue;
if (con->enforce == 0.0f) continue;
/* only use it if it's tagged for this purpose (and the right type) */
@@ -2305,7 +2396,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
}
/* get constraint targets if needed */
- get_constraint_targets_for_solving(con, &cob, &targets, ctime);
+ BKE_get_constraint_targets_for_solving(con, &cob, &targets, ctime);
/* do constraint */
cti->evaluate_constraint(con, &cob, &targets);
@@ -2357,7 +2448,7 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
+ bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
bConstraintOb cob;
bConstraint *con;
int do_limit = FALSE;
@@ -2365,7 +2456,7 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
/* Evaluate valid constraints */
for (con = td->con; con; con = con->next) {
/* only consider constraint if enabled */
- if (con->flag & CONSTRAINT_DISABLE) continue;
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) continue;
if (con->enforce == 0.0f) continue;
/* we're only interested in Limit-Rotation constraints */
@@ -2424,7 +2515,7 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
static void constraintSizeLim(TransInfo *t, TransData *td)
{
if (td->con && td->ext) {
- bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
+ bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
float size_sign[3], size_abs[3];
@@ -2455,7 +2546,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* Evaluate valid constraints */
for (con = td->con; con; con = con->next) {
/* only consider constraint if enabled */
- if (con->flag & CONSTRAINT_DISABLE) continue;
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) continue;
if (con->enforce == 0.0f) continue;
/* we're only interested in Limit-Scale constraints */
@@ -2579,7 +2670,8 @@ int handleEventWarp(TransInfo *t, wmEvent *event)
int Warp(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
- float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3];
+ float vec[3], circumfac, dist, phi0, co, si, cursor[3], gcursor[3];
+ const float *curs;
int i;
char str[50];
@@ -2616,13 +2708,13 @@ int Warp(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Warp: %s", c);
+ sprintf(str, IFACE_("Warp: %s"), c);
circumfac = DEG2RADF(circumfac);
}
else {
/* default header print */
- sprintf(str, "Warp: %.3f", RAD2DEGF(circumfac));
+ sprintf(str, IFACE_("Warp: %.3f"), RAD2DEGF(circumfac));
}
t->values[0] = circumfac;
@@ -2716,6 +2808,18 @@ int handleEventShear(TransInfo *t, wmEvent *event)
status = 1;
}
+ else if (event->type == XKEY && event->val == KM_PRESS) {
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+ t->customData = NULL;
+
+ status = 1;
+ }
+ else if (event->type == YKEY && event->val == KM_PRESS) {
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+ t->customData = (void *)1;
+
+ status = 1;
+ }
return status;
}
@@ -2745,11 +2849,11 @@ int Shear(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Shear: %s %s", c, t->proptext);
+ sprintf(str, IFACE_("Shear: %s %s"), c, t->proptext);
}
else {
/* default header print */
- sprintf(str, "Shear: %.3f %s", value, t->proptext);
+ sprintf(str, IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
}
t->values[0] = value;
@@ -2841,30 +2945,30 @@ static void headerResize(TransInfo *t, float vec[3], char *str)
if (t->con.mode & CON_APPLY) {
switch (t->num.idx_max) {
case 0:
- spos += sprintf(spos, "Scale: %s%s %s", &tvec[0], t->con.text, t->proptext);
+ spos += sprintf(spos, IFACE_("Scale: %s%s %s"), &tvec[0], t->con.text, t->proptext);
break;
case 1:
- spos += sprintf(spos, "Scale: %s : %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
+ spos += sprintf(spos, IFACE_("Scale: %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
t->con.text, t->proptext);
break;
case 2:
- spos += sprintf(spos, "Scale: %s : %s : %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
+ spos += sprintf(spos, IFACE_("Scale: %s : %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
&tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
else {
if (t->flag & T_2D_EDIT) {
- spos += sprintf(spos, "Scale X: %s Y: %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
+ spos += sprintf(spos, IFACE_("Scale X: %s Y: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
t->con.text, t->proptext);
}
else {
- spos += sprintf(spos, "Scale X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
+ spos += sprintf(spos, IFACE_("Scale X: %s Y: %s Z: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
&tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, " Proportional size: %.2f", t->prop_size);
+ spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
(void)spos;
@@ -2884,7 +2988,7 @@ BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3])
}
/* smat is reference matrix, only scaled */
-static void TransMat3ToSize(float mat[][3], float smat[][3], float size[3])
+static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3])
{
float vec[3];
@@ -2920,12 +3024,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
}
/* local constraint shouldn't alter center */
- if ((t->around == V3D_LOCAL) &&
- ( (t->flag & (T_OBJECT | T_POSE)) ||
- ((t->flag & T_EDIT) && (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE))) ||
- (t->obedit && t->obedit->type == OB_ARMATURE))
- )
- {
+ if (transdata_check_local_center(t)) {
copy_v3_v3(center, td->center);
}
else if (t->options & CTX_MOVIECLIP) {
@@ -3228,11 +3327,11 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "To Sphere: %s %s", c, t->proptext);
+ sprintf(str, IFACE_("To Sphere: %s %s"), c, t->proptext);
}
else {
/* default header print */
- sprintf(str, "To Sphere: %.4f %s", ratio, t->proptext);
+ sprintf(str, IFACE_("To Sphere: %.4f %s"), ratio, t->proptext);
}
@@ -3302,20 +3401,16 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
{
float vec[3], totmat[3][3], smat[3][3];
float eul[3], fmat[3][3], quat[4];
- float *center = t->center;
+ const float *center;
/* local constraint shouldn't alter center */
- if (around == V3D_LOCAL) {
- if ( (t->flag & (T_OBJECT | T_POSE)) ||
- (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE)) ||
- (t->obedit && t->obedit->type == OB_ARMATURE))
- {
- center = td->center;
- }
-
- if (t->options & CTX_MOVIECLIP) {
- center = td->center;
- }
+ if (transdata_check_local_center(t) ||
+ ((around == V3D_LOCAL) && (t->options & CTX_MOVIECLIP)))
+ {
+ center = td->center;
+ }
+ else {
+ center = t->center;
}
if (t->flag & T_POINTS) {
@@ -3576,17 +3671,17 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- spos += sprintf(spos, "Rot: %s %s %s", &c[0], t->con.text, t->proptext);
+ spos += sprintf(spos, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
/* Clamp between -180 and 180 */
final = angle_wrap_rad(DEG2RADF(final));
}
else {
- spos += sprintf(spos, "Rot: %.2f%s %s", RAD2DEGF(final), t->con.text, t->proptext);
+ spos += sprintf(spos, IFACE_("Rot: %.2f%s %s"), RAD2DEGF(final), t->con.text, t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, " Proportional size: %.2f", t->prop_size);
+ spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
(void)spos;
@@ -3675,17 +3770,17 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- spos += sprintf(spos, "Trackball: %s %s %s", &c[0], &c[NUM_STR_REP_LEN], t->proptext);
+ spos += sprintf(spos, IFACE_("Trackball: %s %s %s"), &c[0], &c[NUM_STR_REP_LEN], t->proptext);
phi[0] = DEG2RADF(phi[0]);
phi[1] = DEG2RADF(phi[1]);
}
else {
- spos += sprintf(spos, "Trackball: %.2f %.2f %s", RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
+ spos += sprintf(spos, IFACE_("Trackball: %.2f %.2f %s"), RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, " Proportional size: %.2f", t->prop_size);
+ spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
(void)spos;
@@ -3796,7 +3891,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str)
short chainlen = t->settings->autoik_chainlen;
if (chainlen)
- sprintf(autoik, "AutoIK-Len: %d", chainlen);
+ sprintf(autoik, IFACE_("AutoIK-Len: %d"), chainlen);
else
autoik[0] = '\0';
}
@@ -3829,7 +3924,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str)
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, " Proportional size: %.2f", t->prop_size);
+ spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
(void)spos;
}
@@ -3979,7 +4074,8 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float distance;
int i;
- char str[64];
+ char str[128];
+ char *str_p;
TransData *td = t->data;
distance = -t->values[0];
@@ -3989,18 +4085,34 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &distance);
/* header print for NumInput */
+ str_p = str;
+ str_p += BLI_snprintf(str_p, sizeof(str), IFACE_("Shrink/Fatten:"));
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
-
outputNumInput(&(t->num), c);
-
- sprintf(str, "Shrink/Fatten: %s %s", c, t->proptext);
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %s", c);
}
else {
/* default header print */
- sprintf(str, "Shrink/Fatten: %.4f %s", distance, t->proptext);
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %.4f", distance);
}
+ if (t->proptext[0]) {
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %s", t->proptext);
+ }
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), ", (");
+
+ {
+ wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
+ if (kmi) {
+ str_p += WM_keymap_item_to_string(kmi, str_p, sizeof(str) - (str_p - str));
+ }
+ }
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_(" or Alt) Even Thickness %s"),
+ (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
+ /* done with header string */
+
+
t->values[0] = -distance;
for (i = 0; i < t->total; i++, td++) {
@@ -4068,7 +4180,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Tilt: %s° %s", &c[0], t->proptext);
+ sprintf(str, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
final = DEG2RADF(final);
@@ -4076,7 +4188,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = final;
}
else {
- sprintf(str, "Tilt: %.2f° %s", RAD2DEGF(final), t->proptext);
+ sprintf(str, IFACE_("Tilt: %.2f° %s"), RAD2DEGF(final), t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4140,10 +4252,10 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, "Shrink/Fatten: %s", c);
+ sprintf(str, IFACE_("Shrink/Fatten: %s"), c);
}
else {
- sprintf(str, "Shrink/Fatten: %3f", ratio);
+ sprintf(str, IFACE_("Shrink/Fatten: %3f"), ratio);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4208,10 +4320,10 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, "Feather Shrink/Fatten: %s", c);
+ sprintf(str, IFACE_("Feather Shrink/Fatten: %s"), c);
}
else {
- sprintf(str, "Feather Shrink/Fatten: %3f", ratio);
+ sprintf(str, IFACE_("Feather Shrink/Fatten: %3f"), ratio);
}
/* detect if no points have feather yet */
@@ -4296,11 +4408,11 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Push/Pull: %s%s %s", c, t->con.text, t->proptext);
+ sprintf(str, IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
}
else {
/* default header print */
- sprintf(str, "Push/Pull: %.4f%s %s", distance, t->con.text, t->proptext);
+ sprintf(str, IFACE_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
}
t->values[0] = distance;
@@ -4417,7 +4529,7 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2]))
const char *mode;
TransData *td = t->data;
- mode = (G.editBMesh->options & BME_BEVEL_VERT) ? "verts only" : "normal";
+ mode = (G.editBMesh->options & BME_BEVEL_VERT) ? IFACE_("verts only") : IFACE_("normal");
distance = t->values[0] / 4; /* 4 just seemed a nice value to me, nothing special */
distance = fabs(distance);
@@ -4432,11 +4544,11 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Bevel - Dist: %s, Mode: %s (MMB to toggle))", c, mode);
+ sprintf(str, IFACE_("Bevel - Dist: %s, Mode: %s (MMB to toggle))"), c, mode);
}
else {
/* default header print */
- sprintf(str, "Bevel - Dist: %.4f, Mode: %s (MMB to toggle))", distance, mode);
+ sprintf(str, IFACE_("Bevel - Dist: %.4f, Mode: %s (MMB to toggle))"), distance, mode);
}
if (distance < 0) distance = -distance;
@@ -4500,16 +4612,16 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
if (weight >= 0.0f)
- sprintf(str, "Bevel Weight: +%s %s", c, t->proptext);
+ sprintf(str, IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
else
- sprintf(str, "Bevel Weight: %s %s", c, t->proptext);
+ sprintf(str, IFACE_("Bevel Weight: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (weight >= 0.0f)
- sprintf(str, "Bevel Weight: +%.3f %s", weight, t->proptext);
+ sprintf(str, IFACE_("Bevel Weight: +%.3f %s"), weight, t->proptext);
else
- sprintf(str, "Bevel Weight: %.3f %s", weight, t->proptext);
+ sprintf(str, IFACE_("Bevel Weight: %.3f %s"), weight, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4573,16 +4685,16 @@ int Crease(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
if (crease >= 0.0f)
- sprintf(str, "Crease: +%s %s", c, t->proptext);
+ sprintf(str, IFACE_("Crease: +%s %s"), c, t->proptext);
else
- sprintf(str, "Crease: %s %s", c, t->proptext);
+ sprintf(str, IFACE_("Crease: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (crease >= 0.0f)
- sprintf(str, "Crease: +%.3f %s", crease, t->proptext);
+ sprintf(str, IFACE_("Crease: +%.3f %s"), crease, t->proptext);
else
- sprintf(str, "Crease: %.3f %s", crease, t->proptext);
+ sprintf(str, IFACE_("Crease: %.3f %s"), crease, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4641,14 +4753,14 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str)
/* hmm... perhaps the y-axis values don't need to be shown? */
if (t->con.mode & CON_APPLY) {
if (t->num.idx_max == 0)
- sprintf(str, "ScaleB: %s%s %s", &tvec[0], t->con.text, t->proptext);
+ sprintf(str, IFACE_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
else
- sprintf(str, "ScaleB: %s : %s : %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2],
- t->con.text, t->proptext);
+ sprintf(str, IFACE_("ScaleB: %s : %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
+ &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
else {
- sprintf(str, "ScaleB X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2],
- t->con.text, t->proptext);
+ sprintf(str, IFACE_("ScaleB X: %s Y: %s Z: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
+ &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
@@ -4764,10 +4876,10 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, "Envelope: %s", c);
+ sprintf(str, IFACE_("Envelope: %s"), c);
}
else {
- sprintf(str, "Envelope: %3f", ratio);
+ sprintf(str, IFACE_("Envelope: %3f"), ratio);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4797,96 +4909,200 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
static BMEdge *get_other_edge(BMVert *v, BMEdge *e)
{
BMIter iter;
- BMEdge *e2;
+ BMEdge *e_iter;
- BM_ITER_ELEM (e2, &iter, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e2, BM_ELEM_SELECT) && e2 != e)
- return e2;
+ BM_ITER_ELEM (e_iter, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT) && e_iter != e) {
+ return e_iter;
+ }
}
return NULL;
}
+static void len_v3_ensure(float v[3], const float length)
+{
+ normalize_v3(v);
+ mul_v3_fl(v, length);
+}
+
+/**
+ * Find the closest point on the ngon on the opposite side.
+ * used to set the edge slide distance for ngons.
+ */
+static bool bm_loop_calc_opposite_co(BMLoop *l_tmp,
+ const float plane_no[3],
+ float r_co[3])
+{
+ /* skip adjacent edges */
+ BMLoop *l_first = l_tmp->next;
+ BMLoop *l_last = l_tmp->prev;
+ BMLoop *l_iter;
+ float dist = FLT_MAX;
+
+ l_iter = l_first;
+ do {
+ float tvec[3];
+ if (isect_line_plane_v3(tvec,
+ l_iter->v->co, l_iter->next->v->co,
+ l_tmp->v->co, plane_no, false))
+ {
+ const float fac = line_point_factor_v3(tvec, l_iter->v->co, l_iter->next->v->co);
+ /* allow some overlap to avoid missing the intersection because of float precision */
+ if ((fac > -FLT_EPSILON) && (fac < 1.0f + FLT_EPSILON)) {
+ /* likelyhood of multiple intersections per ngon is quite low,
+ * it would have to loop back on its self, but better support it
+ * so check for the closest opposite edge */
+ const float tdist = len_v3v3(l_tmp->v->co, tvec);
+ if (tdist < dist) {
+ copy_v3_v3(r_co, tvec);
+ dist = tdist;
+ }
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_last);
+
+ return (dist != FLT_MAX);
+}
+
+/**
+ * Given 2 edges and a loop, step over the loops
+ * and calculate a direction to slide along.
+ *
+ * \param r_slide_vec the direction to slide,
+ * the length of the vector defines the slide distance.
+ */
static BMLoop *get_next_loop(BMVert *v, BMLoop *l,
- BMEdge *olde, BMEdge *nexte, float vec[3])
+ BMEdge *e_prev, BMEdge *e_next, float r_slide_vec[3])
{
- BMLoop *firstl;
- float a[3] = {0.0f, 0.0f, 0.0f}, n[3] = {0.0f, 0.0f, 0.0f};
+ BMLoop *l_first;
+ float vec_accum[3] = {0.0f, 0.0f, 0.0f};
+ float vec_accum_len = 0.0f;
int i = 0;
- firstl = l;
+ BLI_assert(BM_edge_share_vert(e_prev, e_next) == v);
+
+ l_first = l;
do {
l = BM_face_other_edge_loop(l->f, l->e, v);
if (l->radial_next == l)
return NULL;
- if (l->e == nexte) {
+ if (l->e == e_next) {
if (i) {
- mul_v3_fl(a, 1.0f / (float)i);
+ len_v3_ensure(vec_accum, vec_accum_len / (float)i);
}
else {
- float f1[3], f2[3], f3[3];
+ /* When there is no edge to slide along,
+ * we must slide along the vector defined by the face we're attach to */
+ BMLoop *l_tmp = BM_face_vert_share_loop(l_first->f, v);
- sub_v3_v3v3(f1, BM_edge_other_vert(olde, v)->co, v->co);
- sub_v3_v3v3(f2, BM_edge_other_vert(nexte, v)->co, v->co);
+ BLI_assert(ELEM(l_tmp->e, e_prev, e_next) && ELEM(l_tmp->prev->e, e_prev, e_next));
- cross_v3_v3v3(f3, f1, l->f->no);
- cross_v3_v3v3(a, f2, l->f->no);
- mul_v3_fl(a, -1.0f);
+ if (l_tmp->f->len == 4) {
+ /* we could use code below, but in this case
+ * sliding diagonally across the quad works well */
+ sub_v3_v3v3(vec_accum, l_tmp->next->next->v->co, v->co);
+ }
+ else {
+ float tdir[3];
+ BM_loop_calc_face_direction(l_tmp, tdir);
+ cross_v3_v3v3(vec_accum, l_tmp->f->no, tdir);
+#if 0
+ /* rough guess, we can do better! */
+ len_v3_ensure(vec_accum, (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f);
+#else
+ /* be clever, check the opposite ngon edge to slide into.
+ * this gives best results */
+ {
+ float tvec[3];
+ float dist;
+
+ if (bm_loop_calc_opposite_co(l_tmp, tdir, tvec)) {
+ dist = len_v3v3(l_tmp->v->co, tvec);
+ }
+ else {
+ dist = (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f;
+ }
- mid_v3_v3v3(a, a, f3);
+ len_v3_ensure(vec_accum, dist);
+ }
+#endif
+ }
}
-
- copy_v3_v3(vec, a);
+
+ copy_v3_v3(r_slide_vec, vec_accum);
return l;
}
else {
- sub_v3_v3v3(n, BM_edge_other_vert(l->e, v)->co, v->co);
- add_v3_v3v3(a, a, n);
+ /* accumulate the normalized edge vector,
+ * normalize so some edges don't skew the result */
+ float tvec[3];
+ sub_v3_v3v3(tvec, BM_edge_other_vert(l->e, v)->co, v->co);
+ vec_accum_len += normalize_v3(tvec);
+ add_v3_v3(vec_accum, tvec);
i += 1;
}
- if (BM_face_other_edge_loop(l->f, l->e, v)->e == nexte) {
- if (i)
- mul_v3_fl(a, 1.0f / (float)i);
-
- copy_v3_v3(vec, a);
+ if (BM_face_other_edge_loop(l->f, l->e, v)->e == e_next) {
+ if (i) {
+ len_v3_ensure(vec_accum, vec_accum_len / (float)i);
+ }
+
+ copy_v3_v3(r_slide_vec, vec_accum);
return BM_face_other_edge_loop(l->f, l->e, v);
}
+ BLI_assert(l != l->radial_next);
l = l->radial_next;
- } while (l != firstl);
+ } while (l != l_first);
- if (i)
- mul_v3_fl(a, 1.0f / (float)i);
+ if (i) {
+ len_v3_ensure(vec_accum, vec_accum_len / (float)i);
+ }
- copy_v3_v3(vec, a);
+ copy_v3_v3(r_slide_vec, vec_accum);
return NULL;
}
-static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const float mval[2])
+static void calcNonProportionalEdgeSlide(TransInfo *t, EdgeSlideData *sld, const float mval[2])
{
- TransDataSlideVert *sv = sld->sv;
+ TransDataEdgeSlideVert *sv = sld->sv;
if (sld->totsv > 0) {
+ ARegion *ar = t->ar;
+ RegionView3D *rv3d = NULL;
+ float projectMat[4][4];
+
int i = 0;
- float v_proj[3];
+ float v_proj[2];
float dist = 0;
float min_dist = FLT_MAX;
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* background mode support */
+ rv3d = t->ar ? t->ar->regiondata : NULL;
+ }
+
+ if (!rv3d) {
+ /* ok, let's try to survive this */
+ unit_m4(projectMat);
+ }
+ else {
+ ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
+ }
+
for (i = 0; i < sld->totsv; i++, sv++) {
/* Set length */
sv->edge_len = len_v3v3(sv->upvec, sv->downvec);
- mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co);
- if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
- dist = len_squared_v2v2(mval, v_proj);
- if (dist < min_dist) {
- min_dist = dist;
- sld->curr_sv_index = i;
- }
+ ED_view3d_project_float_v2_m4(ar, sv->v->co, v_proj, projectMat);
+ dist = len_squared_v2v2(mval, v_proj);
+ if (dist < min_dist) {
+ min_dist = dist;
+ sld->curr_sv_index = i;
}
}
}
@@ -4895,17 +5111,18 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo
}
}
-static int createSlideVerts(TransInfo *t)
+static int createEdgeSlideVerts(TransInfo *t)
{
BMEditMesh *em = BMEdit_FromObject(t->obedit);
BMesh *bm = em->bm;
BMIter iter;
BMEdge *e, *e1;
- BMVert *v, *v2, *first;
- TransDataSlideVert *sv_array;
- BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL);
+ BMVert *v, *v2;
+ TransDataEdgeSlideVert *sv_array;
+ int sv_tot;
+ BMBVHTree *btree;
SmallHash table;
- SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
View3D *v3d = NULL;
RegionView3D *rv3d = NULL;
ARegion *ar = t->ar;
@@ -4915,6 +5132,7 @@ static int createSlideVerts(TransInfo *t)
float vec[3], vec2[3] /*, lastvec[3], size, dis=0.0, z */ /* UNUSED */;
float dir[3], maxdist, (*loop_dir)[3], *loop_maxdist;
int numsel, i, j, loop_nr, l_nr;
+ int use_btree_disp;
if (t->spacetype == SPACE_VIEW3D) {
/* background mode support */
@@ -4922,6 +5140,15 @@ static int createSlideVerts(TransInfo *t)
rv3d = t->ar ? t->ar->regiondata : NULL;
}
+ use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
+
+ if (use_btree_disp) {
+ btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL);
+ }
+ else {
+ btree = NULL;
+ }
+
sld->is_proportional = TRUE;
sld->curr_sv_index = 0;
sld->flipped_vtx = FALSE;
@@ -4955,7 +5182,8 @@ static int createSlideVerts(TransInfo *t)
if (numsel == 0 || numsel > 2) {
MEM_freeN(sld);
- BMBVH_FreeBVH(btree);
+ if (btree)
+ BMBVH_FreeBVH(btree);
return 0; /* invalid edge selection */
}
}
@@ -4965,7 +5193,8 @@ static int createSlideVerts(TransInfo *t)
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
if (!BM_edge_is_manifold(e)) {
MEM_freeN(sld);
- BMBVH_FreeBVH(btree);
+ if (btree)
+ BMBVH_FreeBVH(btree);
return 0; /* can only handle exactly 2 faces around each edge */
}
}
@@ -4985,16 +5214,18 @@ static int createSlideVerts(TransInfo *t)
if (!j) {
MEM_freeN(sld);
- BMBVH_FreeBVH(btree);
+ if (btree)
+ BMBVH_FreeBVH(btree);
return 0;
}
- sv_array = MEM_callocN(sizeof(TransDataSlideVert) * j, "sv_array");
+ sv_tot = j;
+ sv_array = MEM_callocN(sizeof(TransDataEdgeSlideVert) * sv_tot, "sv_array");
loop_nr = 0;
- j = 0;
while (1) {
BMLoop *l, *l1, *l2;
+ BMVert *v_first;
v = NULL;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -5009,7 +5240,7 @@ static int createSlideVerts(TransInfo *t)
if (!v->e)
continue;
- first = v;
+ v_first = v;
/*walk along the edge loop*/
e = v->e;
@@ -5029,7 +5260,7 @@ static int createSlideVerts(TransInfo *t)
break;
v = BM_edge_other_vert(e, v);
- } while (e != first->e);
+ } while (e != v_first->e);
BM_elem_flag_disable(v, BM_ELEM_TAG);
@@ -5049,10 +5280,12 @@ static int createSlideVerts(TransInfo *t)
}
/*iterate over the loop*/
- first = v;
+ v_first = v;
do {
- TransDataSlideVert *sv = sv_array + j;
+ TransDataEdgeSlideVert *sv;
+ /* XXX, 'sv' will initialize multiple times, this is suspicious. see [#34024] */
+ sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
sv->v = v;
sv->origvert = *v;
sv->loop_nr = loop_nr;
@@ -5074,9 +5307,7 @@ static int createSlideVerts(TransInfo *t)
e1 = e;
e = get_other_edge(v, e);
if (!e) {
- //v2=v, v = BM_edge_other_vert(l1->e, v);
-
- sv = sv_array + j + 1;
+ sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
sv->v = v;
sv->origvert = *v;
sv->loop_nr = loop_nr;
@@ -5093,19 +5324,16 @@ static int createSlideVerts(TransInfo *t)
BM_elem_flag_disable(v, BM_ELEM_TAG);
BM_elem_flag_disable(v2, BM_ELEM_TAG);
-
- j += 2;
+
break;
}
l1 = get_next_loop(v, l1, e1, e, vec);
l2 = l2 ? get_next_loop(v, l2, e1, e, vec2) : NULL;
- j += 1;
-
BM_elem_flag_disable(v, BM_ELEM_TAG);
BM_elem_flag_disable(v2, BM_ELEM_TAG);
- } while (e != first->e && l1);
+ } while (e != v_first->e && l1);
loop_nr++;
}
@@ -5113,7 +5341,7 @@ static int createSlideVerts(TransInfo *t)
/* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
sld->sv = sv_array;
- sld->totsv = j;
+ sld->totsv = sv_tot;
/* find mouse vectors, the global one, and one per loop in case we have
* multiple loops selected, in case they are oriented different */
@@ -5140,9 +5368,7 @@ static int createSlideVerts(TransInfo *t)
continue;
/* This test is only relevant if object is not wire-drawn! See [#32068]. */
- if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE &&
- !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit))
- {
+ if (use_btree_disp && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) {
continue;
}
@@ -5216,14 +5442,14 @@ static int createSlideVerts(TransInfo *t)
if (dot_v3v3(loop_dir[l_nr], dir) < 0.0f) {
swap_v3_v3(sv_array->upvec, sv_array->downvec);
SWAP(BMVert, sv_array->vup, sv_array->vdown);
- SWAP(BMVert*, sv_array->up, sv_array->down);
+ SWAP(BMVert *, sv_array->up, sv_array->down);
}
}
if (rv3d)
calcNonProportionalEdgeSlide(t, sld, mval);
- sld->origfaces_init = TRUE;
+ sld->origfaces_init = true;
sld->em = em;
/*zero out start*/
@@ -5244,17 +5470,22 @@ static int createSlideVerts(TransInfo *t)
t->customData = sld;
BLI_smallhash_release(&table);
- BMBVH_FreeBVH(btree);
+ if (btree) {
+ BMBVH_FreeBVH(btree);
+ }
MEM_freeN(loop_dir);
MEM_freeN(loop_maxdist);
-
+
+ /* arrays are dirty from copying faces: EDBM_index_arrays_free */
+ EDBM_update_generic(em, FALSE, TRUE);
+
return 1;
}
-void projectSVData(TransInfo *t, int final)
+void projectEdgeSlideData(TransInfo *t, bool is_final)
{
- SlideData *sld = t->customData;
- TransDataSlideVert *sv;
+ EdgeSlideData *sld = t->customData;
+ TransDataEdgeSlideVert *sv;
BMEditMesh *em = sld->em;
SmallHash visit;
int i;
@@ -5373,7 +5604,7 @@ void projectSVData(TransInfo *t, int final)
}
}
-
+
if (!affected)
continue;
@@ -5381,7 +5612,7 @@ void projectSVData(TransInfo *t, int final)
* 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 (final) {
+ 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);
@@ -5405,7 +5636,7 @@ void projectSVData(TransInfo *t, int final)
BLI_smallhash_release(&visit);
}
-void freeSlideTempFaces(SlideData *sld)
+void freeEdgeSlideTempFaces(EdgeSlideData *sld)
{
if (sld->origfaces_init) {
SmallHashIter hiter;
@@ -5418,18 +5649,21 @@ void freeSlideTempFaces(SlideData *sld)
BLI_smallhash_release(&sld->origfaces);
- sld->origfaces_init = FALSE;
+ sld->origfaces_init = false;
+
+ /* arrays are dirty from removing faces: EDBM_index_arrays_free */
+ EDBM_update_generic(sld->em, FALSE, TRUE);
}
}
-void freeSlideVerts(TransInfo *t)
+void freeEdgeSlideVerts(TransInfo *t)
{
- SlideData *sld = t->customData;
+ EdgeSlideData *sld = t->customData;
#if 0 /*BMESH_TODO*/
if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
- TransDataSlideVert *sv;
+ TransDataEdgeSlideVert *sv;
LinkNode *look = sld->vertlist;
GHash *vertgh = sld->vhash;
while (look) {
@@ -5446,7 +5680,7 @@ void freeSlideVerts(TransInfo *t)
if (!sld)
return;
- freeSlideTempFaces(sld);
+ freeEdgeSlideTempFaces(sld);
bmesh_edit_end(sld->em->bm, BMO_OP_FLAG_UNTAN_MULTIRES);
@@ -5462,13 +5696,13 @@ void freeSlideVerts(TransInfo *t)
void initEdgeSlide(TransInfo *t)
{
- SlideData *sld;
+ EdgeSlideData *sld;
t->mode = TFM_EDGE_SLIDE;
t->transform = EdgeSlide;
t->handleEvent = handleEventEdgeSlide;
- if (!createSlideVerts(t)) {
+ if (!createEdgeSlideVerts(t)) {
t->state = TRANS_CANCEL;
return;
}
@@ -5478,11 +5712,11 @@ void initEdgeSlide(TransInfo *t)
if (!sld)
return;
- t->customFree = freeSlideVerts;
+ t->customFree = freeEdgeSlideVerts;
/* set custom point first if you want value to be initialized by init */
setCustomPoints(t, &t->mouse, sld->end, sld->start);
- initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+ initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP);
t->idx_max = 0;
t->num.idx_max = 0;
@@ -5498,7 +5732,7 @@ void initEdgeSlide(TransInfo *t)
int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event)
{
if (t->mode == TFM_EDGE_SLIDE) {
- SlideData *sld = t->customData;
+ EdgeSlideData *sld = t->customData;
if (sld) {
switch (event->type) {
@@ -5541,17 +5775,17 @@ int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event)
return 0;
}
-void drawNonPropEdge(const struct bContext *C, TransInfo *t)
+void drawEdgeSlide(const struct bContext *C, TransInfo *t)
{
if (t->mode == TFM_EDGE_SLIDE) {
- SlideData *sld = (SlideData *)t->customData;
+ EdgeSlideData *sld = (EdgeSlideData *)t->customData;
/* Non-Prop mode */
if (sld && sld->is_proportional == FALSE) {
View3D *v3d = CTX_wm_view3d(C);
float marker[3];
float v1[3], v2[3];
float interp_v;
- TransDataSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
const float guide_size = ctrl_size - 0.5f;
const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
@@ -5617,8 +5851,8 @@ void drawNonPropEdge(const struct bContext *C, TransInfo *t)
static int doEdgeSlide(TransInfo *t, float perc)
{
- SlideData *sld = t->customData;
- TransDataSlideVert *svlist = sld->sv, *sv;
+ EdgeSlideData *sld = t->customData;
+ TransDataEdgeSlideVert *svlist = sld->sv, *sv;
int i;
sld->perc = perc;
@@ -5648,7 +5882,7 @@ static int doEdgeSlide(TransInfo *t, float perc)
* \note len_v3v3(curr_sv->upvec, curr_sv->downvec)
* is the same as the distance between the original vert locations, same goes for the lines below.
*/
- TransDataSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
const float curr_length_perc = curr_sv->edge_len * (((sld->flipped_vtx ? perc : -perc) + 1.0f) / 2.0f);
float down_co[3];
@@ -5671,7 +5905,7 @@ static int doEdgeSlide(TransInfo *t, float perc)
}
}
- projectSVData(t, 0);
+ projectEdgeSlideData(t, 0);
return 1;
}
@@ -5680,9 +5914,9 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
{
char str[128];
float final;
- SlideData *sld = t->customData;
- int flipped = sld->flipped_vtx;
- int is_proportional = sld->is_proportional;
+ EdgeSlideData *sld = t->customData;
+ bool flipped = sld->flipped_vtx;
+ bool is_proportional = sld->is_proportional;
final = t->values[0];
@@ -5698,12 +5932,12 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- BLI_snprintf(str, sizeof(str), "Edge Slide: %s (E)ven: %s, (F)lipped: %s",
- &c[0], !is_proportional ? "ON" : "OFF", flipped ? "ON" : "OFF");
+ BLI_snprintf(str, sizeof(str), IFACE_("Edge Slide: %s (E)ven: %s, (F)lipped: %s"),
+ &c[0], !is_proportional ? IFACE_("ON") : IFACE_("OFF"), flipped ? IFACE_("ON") : IFACE_("OFF"));
}
else {
- BLI_snprintf(str, sizeof(str), "Edge Slide: %.2f (E)ven: %s, (F)lipped: %s",
- final, !is_proportional ? "ON" : "OFF", flipped ? "ON" : "OFF");
+ BLI_snprintf(str, sizeof(str), IFACE_("Edge Slide: %.4f (E)ven: %s, (F)lipped: %s"),
+ final, !is_proportional ? IFACE_("ON") : IFACE_("OFF"), flipped ? IFACE_("ON") : IFACE_("OFF"));
}
CLAMP(final, -1.0f, 1.0f);
@@ -5714,7 +5948,7 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
if (t->customData)
doEdgeSlide(t, final);
else {
- strcpy(str, "Invalid Edge Selection");
+ strcpy(str, IFACE_("Invalid Edge Selection"));
t->state = TRANS_CANCEL;
}
@@ -5725,6 +5959,521 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
return 1;
}
+
+/* ******************** Vert Slide *************** */
+static void calcVertSlideCustomPoints(struct TransInfo *t)
+{
+ VertSlideData *sld = t->customData;
+ TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index];
+ float *co_orig = sv->co_orig_2d;
+ float *co_curr = sv->co_link_orig_2d[sv->co_link_curr];
+ const int start[2] = {co_orig[0], co_orig[1]};
+ const int end[2] = {co_curr[0], co_curr[1]};
+
+ if (sld->flipped_vtx && sld->is_proportional == false) {
+ setCustomPoints(t, &t->mouse, start, end);
+ }
+ else {
+ setCustomPoints(t, &t->mouse, end, start);
+ }
+}
+
+/**
+ * Run once when initializing vert slide to find the reference edge
+ */
+static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2])
+{
+ VertSlideData *sld = t->customData;
+ float mval_fl[2] = {UNPACK2(mval)};
+ TransDataVertSlideVert *sv;
+
+ /* set the vertex to use as a reference for the mouse direction 'curr_sv_index' */
+ float dist = 0.0f;
+ float min_dist = FLT_MAX;
+ int i;
+
+ for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
+ dist = len_squared_v2v2(mval_fl, sv->co_orig_2d);
+ if (dist < min_dist) {
+ min_dist = dist;
+ sld->curr_sv_index = i;
+ }
+ }
+}
+/**
+ * Run while moving the mouse to slide along the edge matching the mouse direction
+ */
+static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2])
+{
+ VertSlideData *sld = t->customData;
+ float mval_fl[2] = {UNPACK2(mval)};
+
+ float dir[2];
+ TransDataVertSlideVert *sv;
+ int i;
+
+ /* first get the direction of the original vertex */
+ sub_v2_v2v2(dir, sld->sv[sld->curr_sv_index].co_orig_2d, mval_fl);
+ normalize_v2(dir);
+
+ for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
+ if (sv->co_link_tot > 1) {
+ float dir_dot_best = -FLT_MAX;
+ int co_link_curr_best = -1;
+ int j;
+
+ for (j = 0; j < sv->co_link_tot; j++) {
+ float tdir[2];
+ float dir_dot;
+ sub_v2_v2v2(tdir, sv->co_orig_2d, sv->co_link_orig_2d[j]);
+ normalize_v2(tdir);
+ dir_dot = dot_v2v2(dir, tdir);
+ if (dir_dot > dir_dot_best) {
+ dir_dot_best = dir_dot;
+ co_link_curr_best = j;
+ }
+ }
+
+ if (co_link_curr_best != -1) {
+ sv->co_link_curr = co_link_curr_best;
+ }
+ }
+ }
+}
+
+static int createVertSlideVerts(TransInfo *t)
+{
+ BMEditMesh *em = BMEdit_FromObject(t->obedit);
+ BMesh *bm = em->bm;
+ BMIter iter;
+ BMIter eiter;
+ BMEdge *e;
+ BMVert *v;
+ TransDataVertSlideVert *sv_array;
+ VertSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+// View3D *v3d = NULL;
+ RegionView3D *rv3d = NULL;
+ ARegion *ar = t->ar;
+ float projectMat[4][4];
+ int j;
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* background mode support */
+// v3d = t->sa ? t->sa->spacedata.first : NULL;
+ rv3d = ar ? ar->regiondata : NULL;
+ }
+
+ sld->is_proportional = true;
+ sld->curr_sv_index = 0;
+ sld->flipped_vtx = false;
+
+ if (!rv3d) {
+ /* ok, let's try to survive this */
+ unit_m4(projectMat);
+ }
+ else {
+ ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
+ }
+
+ j = 0;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ bool ok = false;
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) && v->e) {
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ ok = true;
+ break;
+ }
+ }
+ }
+
+ if (ok) {
+ BM_elem_flag_enable(v, BM_ELEM_TAG);
+ j += 1;
+ }
+ else {
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ }
+ }
+
+ if (!j) {
+ MEM_freeN(sld);
+ return 0;
+ }
+
+ sv_array = MEM_callocN(sizeof(TransDataVertSlideVert) * j, "sv_array");
+
+ j = 0;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ int k;
+ sv_array[j].v = v;
+ copy_v3_v3(sv_array[j].co_orig_3d, v->co);
+
+ k = 0;
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ k++;
+ }
+ }
+
+ sv_array[j].co_link_orig_3d = MEM_mallocN(sizeof(*sv_array[j].co_link_orig_3d) * k, __func__);
+ sv_array[j].co_link_orig_2d = MEM_mallocN(sizeof(*sv_array[j].co_link_orig_2d) * k, __func__);
+ sv_array[j].co_link_tot = k;
+
+ k = 0;
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ copy_v3_v3(sv_array[j].co_link_orig_3d[k], v_other->co);
+ if (ar) {
+ ED_view3d_project_float_v2_m4(ar,
+ sv_array[j].co_link_orig_3d[k],
+ sv_array[j].co_link_orig_2d[k],
+ projectMat);
+ }
+ else {
+ copy_v2_v2(sv_array[j].co_link_orig_2d[k],
+ sv_array[j].co_link_orig_3d[k]);
+ }
+ k++;
+ }
+ }
+
+ if (ar) {
+ ED_view3d_project_float_v2_m4(ar,
+ sv_array[j].co_orig_3d,
+ sv_array[j].co_orig_2d,
+ projectMat);
+ }
+ else {
+ copy_v2_v2(sv_array[j].co_orig_2d,
+ sv_array[j].co_orig_3d);
+ }
+
+ j++;
+ }
+ }
+
+ sld->sv = sv_array;
+ sld->totsv = j;
+
+ sld->em = em;
+
+ sld->perc = 0.0f;
+
+ t->customData = sld;
+
+ if (rv3d) {
+ calcVertSlideMouseActiveVert(t, t->mval);
+ calcVertSlideMouseActiveEdges(t, t->mval);
+ }
+
+ return 1;
+}
+
+void freeVertSlideVerts(TransInfo *t)
+{
+ VertSlideData *sld = t->customData;
+
+ if (!sld)
+ return;
+
+
+ if (sld->totsv > 0) {
+ TransDataVertSlideVert *sv = sld->sv;
+ int i = 0;
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ MEM_freeN(sv->co_link_orig_2d);
+ MEM_freeN(sv->co_link_orig_3d);
+ }
+ }
+
+ MEM_freeN(sld->sv);
+ MEM_freeN(sld);
+
+ t->customData = NULL;
+
+ recalcData(t);
+}
+
+void initVertSlide(TransInfo *t)
+{
+ VertSlideData *sld;
+
+ t->mode = TFM_VERT_SLIDE;
+ t->transform = VertSlide;
+ t->handleEvent = handleEventVertSlide;
+
+ if (!createVertSlideVerts(t)) {
+ t->state = TRANS_CANCEL;
+ return;
+ }
+
+ sld = t->customData;
+
+ if (!sld)
+ return;
+
+ t->customFree = freeVertSlideVerts;
+
+ /* set custom point first if you want value to be initialized by init */
+ calcVertSlideCustomPoints(t);
+ initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+
+ 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;
+
+ t->num.increment = t->snap[1];
+
+ t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
+}
+
+int handleEventVertSlide(struct TransInfo *t, struct wmEvent *event)
+{
+ if (t->mode == TFM_VERT_SLIDE) {
+ VertSlideData *sld = t->customData;
+
+ if (sld) {
+ switch (event->type) {
+ case EKEY:
+ if (event->val == KM_PRESS) {
+ sld->is_proportional = !sld->is_proportional;
+ if (sld->flipped_vtx) {
+ calcVertSlideCustomPoints(t);
+ }
+ return 1;
+ }
+ break;
+ case FKEY:
+ {
+ if (event->val == KM_PRESS) {
+ sld->flipped_vtx = !sld->flipped_vtx;
+ calcVertSlideCustomPoints(t);
+ return 1;
+ }
+ break;
+ }
+ case CKEY:
+ {
+ /* use like a modifier key */
+ if (event->val == KM_PRESS) {
+ t->flag ^= T_ALT_TRANSFORM;
+ calcVertSlideCustomPoints(t);
+ return 1;
+ }
+ break;
+ }
+#if 0
+ case EVT_MODAL_MAP:
+ {
+ switch (event->val) {
+ case TFM_MODAL_EDGESLIDE_DOWN:
+ {
+ sld->curr_sv_index = ((sld->curr_sv_index - 1) + sld->totsv) % sld->totsv;
+ break;
+ }
+ case TFM_MODAL_EDGESLIDE_UP:
+ {
+ sld->curr_sv_index = (sld->curr_sv_index + 1) % sld->totsv;
+ break;
+ }
+ }
+ }
+#endif
+ case MOUSEMOVE:
+ {
+ /* don't recalculat the best edge */
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ if (is_clamp) {
+ calcVertSlideMouseActiveEdges(t, event->mval);
+ }
+ calcVertSlideCustomPoints(t);
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+static void drawVertSlide(const struct bContext *C, TransInfo *t)
+{
+ if (t->mode == TFM_VERT_SLIDE) {
+ VertSlideData *sld = (VertSlideData *)t->customData;
+ /* Non-Prop mode */
+ if (sld) {
+ View3D *v3d = CTX_wm_view3d(C);
+ TransDataVertSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ TransDataVertSlideVert *sv;
+ const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
+ const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
+ const int alpha_shade = -30;
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ int i;
+
+ if (v3d && v3d->zbuf)
+ glDisable(GL_DEPTH_TEST);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT | GL_POINT_BIT);
+ glPushMatrix();
+
+ glMultMatrixf(t->obedit->obmat);
+
+ glLineWidth(line_size);
+ UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ glBegin(GL_LINES);
+ if (is_clamp) {
+ sv = sld->sv;
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ glVertex3fv(sv->co_orig_3d);
+ glVertex3fv(sv->co_link_orig_3d[sv->co_link_curr]);
+ }
+ }
+ else {
+ sv = sld->sv;
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ float a[3], b[3];
+ sub_v3_v3v3(a, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
+ mul_v3_fl(a, 100.0f);
+ negate_v3_v3(b, a);
+ add_v3_v3(a, sv->co_orig_3d);
+ add_v3_v3(b, sv->co_orig_3d);
+
+ glVertex3fv(a);
+ glVertex3fv(b);
+ }
+ }
+ bglEnd();
+
+ glPointSize(ctrl_size);
+
+ bglBegin(GL_POINTS);
+ bglVertex3fv((sld->flipped_vtx && sld->is_proportional == FALSE) ?
+ curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
+ curr_sv->co_orig_3d);
+ bglEnd();
+
+ glPopMatrix();
+ glPopAttrib();
+
+ glDisable(GL_BLEND);
+
+ if (v3d && v3d->zbuf)
+ glEnable(GL_DEPTH_TEST);
+ }
+ }
+}
+
+static int doVertSlide(TransInfo *t, float perc)
+{
+ VertSlideData *sld = t->customData;
+ TransDataVertSlideVert *svlist = sld->sv, *sv;
+ int i;
+
+ sld->perc = perc;
+ sv = svlist;
+
+ if (sld->is_proportional == TRUE) {
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ interp_v3_v3v3(sv->v->co, sv->co_orig_3d, sv->co_link_orig_3d[sv->co_link_curr], perc);
+ }
+ }
+ else {
+ TransDataVertSlideVert *sv_curr = &sld->sv[sld->curr_sv_index];
+ const float edge_len_curr = len_v3v3(sv_curr->co_orig_3d, sv_curr->co_link_orig_3d[sv_curr->co_link_curr]);
+ const float tperc = perc * edge_len_curr;
+
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ float edge_len;
+ float dir[3];
+
+ sub_v3_v3v3(dir, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
+ edge_len = normalize_v3(dir);
+
+ if (edge_len > FLT_EPSILON) {
+ if (sld->flipped_vtx) {
+ madd_v3_v3v3fl(sv->v->co, sv->co_link_orig_3d[sv->co_link_curr], dir, -tperc);
+ }
+ else {
+ madd_v3_v3v3fl(sv->v->co, sv->co_orig_3d, dir, tperc);
+ }
+ }
+ else {
+ copy_v3_v3(sv->v->co, sv->co_orig_3d);
+ }
+ }
+ }
+
+ return 1;
+}
+
+int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
+{
+ char str[128];
+ char *str_p;
+ float final;
+ VertSlideData *sld = t->customData;
+ const bool flipped = sld->flipped_vtx;
+ const bool is_proportional = sld->is_proportional;
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num));
+
+ final = t->values[0];
+
+ snapGrid(t, &final);
+
+ /* only do this so out of range values are not displayed */
+ if (is_constrained) {
+ CLAMP(final, 0.0f, 1.0f);
+ }
+
+ /* header string */
+ str_p = str;
+ str_p += BLI_snprintf(str_p, sizeof(str), IFACE_("Vert Slide: "));
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
+ applyNumInput(&t->num, &final);
+ outputNumInput(&(t->num), c);
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), "%s", &c[0]);
+ }
+ else {
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), "%.4f ", final);
+ }
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("(E)ven: %s, "),
+ !is_proportional ? IFACE_("ON") : IFACE_("OFF"));
+ if (!is_proportional) {
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("(F)lipped: %s, "),
+ flipped ? IFACE_("ON") : IFACE_("OFF"));
+ }
+ str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("Alt or (C)lamp: %s"),
+ is_clamp ? IFACE_("ON") : IFACE_("OFF"));
+ /* done with header string */
+
+ /*do stuff here*/
+ if (t->customData) {
+ doVertSlide(t, final);
+ }
+ else {
+ strcpy(str, IFACE_("Invalid Vert Selection"));
+ t->state = TRANS_CANCEL;
+ }
+
+ recalcData(t);
+
+ ED_area_headerprint(t->sa, str);
+
+ return 1;
+}
+
+
/* ******************** EditBone roll *************** */
void initBoneRoll(TransInfo *t)
@@ -5764,12 +6513,12 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Roll: %s", &c[0]);
+ sprintf(str, IFACE_("Roll: %s"), &c[0]);
final = DEG2RADF(final);
}
else {
- sprintf(str, "Roll: %.2f", RAD2DEGF(final));
+ sprintf(str, IFACE_("Roll: %.2f"), RAD2DEGF(final));
}
/* set roll values */
@@ -5835,16 +6584,16 @@ int BakeTime(TransInfo *t, const int mval[2])
outputNumInput(&(t->num), c);
if (time >= 0.0f)
- sprintf(str, "Time: +%s %s", c, t->proptext);
+ sprintf(str, IFACE_("Time: +%s %s"), c, t->proptext);
else
- sprintf(str, "Time: %s %s", c, t->proptext);
+ sprintf(str, IFACE_("Time: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (time >= 0.0f)
- sprintf(str, "Time: +%.3f %s", time, t->proptext);
+ sprintf(str, IFACE_("Time: +%.3f %s"), time, t->proptext);
else
- sprintf(str, "Time: %.3f %s", time, t->proptext);
+ sprintf(str, IFACE_("Time: %.3f %s"), time, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -5904,7 +6653,7 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2]))
t->con.applySize(t, NULL, mat);
}
- sprintf(str, "Mirror%s", t->con.text);
+ sprintf(str, IFACE_("Mirror%s"), t->con.text);
for (i = 0, td = t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
@@ -5938,9 +6687,9 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2]))
recalcData(t);
if (t->flag & T_2D_EDIT)
- ED_area_headerprint(t->sa, "Select a mirror axis (X, Y)");
+ ED_area_headerprint(t->sa, IFACE_("Select a mirror axis (X, Y)"));
else
- ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)");
+ ED_area_headerprint(t->sa, IFACE_("Select a mirror axis (X, Y, Z)"));
}
return 1;
@@ -5997,7 +6746,7 @@ int Align(TransInfo *t, const int UNUSED(mval[2]))
recalcData(t);
- ED_area_headerprint(t->sa, "Align");
+ ED_area_headerprint(t->sa, IFACE_("Align"));
return 1;
}
@@ -6021,9 +6770,10 @@ void initSeqSlide(TransInfo *t)
t->num.increment = t->snap[1];
}
-static void headerSeqSlide(TransInfo *t, float val[2], char *str)
+static void headerSeqSlide(TransInfo *t, float val[2], char *str, size_t str_len)
{
char tvec[NUM_STR_REP_LEN * 3];
+ char *str_p;
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
@@ -6032,7 +6782,17 @@ static void headerSeqSlide(TransInfo *t, float val[2], char *str)
sprintf(&tvec[0], "%.0f, %.0f", val[0], val[1]);
}
- sprintf(str, "Sequence Slide: %s%s", &tvec[0], t->con.text);
+ str_p = str;
+ str_p += BLI_snprintf(str, str_len, IFACE_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
+
+ {
+ wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
+ if (kmi) {
+ str_p += WM_keymap_item_to_string(kmi, str_p, str_len - (str_p - str));
+ }
+ }
+ str_p += BLI_snprintf(str_p, str_len - (str_p - str), IFACE_(" or Alt) Expand to fit %s"),
+ (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
}
static void applySeqSlide(TransInfo *t, float val[2])
@@ -6076,7 +6836,7 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = floor(t->values[0] + 0.5f);
t->values[1] = floor(t->values[1] + 0.5f);
- headerSeqSlide(t, t->values, str);
+ headerSeqSlide(t, t->values, str, sizeof(str));
applySeqSlide(t, t->values);
recalcData(t);
@@ -6297,7 +7057,7 @@ static void headerTimeTranslate(TransInfo *t, char *str)
sprintf(&tvec[0], "%.4f", val);
}
- sprintf(str, "DeltaX: %s", &tvec[0]);
+ sprintf(str, IFACE_("DeltaX: %s"), &tvec[0]);
}
static void applyTimeTranslate(TransInfo *t, float UNUSED(sval))
@@ -6438,7 +7198,7 @@ static void headerTimeSlide(TransInfo *t, float sval, char *str)
sprintf(&tvec[0], "%.4f", val);
}
- sprintf(str, "TimeSlide: %s", &tvec[0]);
+ sprintf(str, IFACE_("TimeSlide: %s"), &tvec[0]);
}
static void applyTimeSlide(TransInfo *t, float sval)
@@ -6570,7 +7330,7 @@ static void headerTimeScale(TransInfo *t, char *str)
else
sprintf(&tvec[0], "%.4f", t->values[0]);
- sprintf(str, "ScaleX: %s", &tvec[0]);
+ sprintf(str, IFACE_("ScaleX: %s"), &tvec[0]);
}
static void applyTimeScale(TransInfo *t)
@@ -6639,3 +7399,10 @@ void BIF_TransformSetUndo(const char *UNUSED(str))
// TRANSFORM_FIX_ME
//Trans.undostr = str;
}
+
+
+/* TODO, move to: transform_queries.c */
+bool checkUseLocalCenter_GraphEdit(TransInfo *t)
+{
+ return ((t->around == V3D_LOCAL) && !ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE));
+}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index bc959a772d6..9c57c74a26d 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -52,12 +52,7 @@ struct Object;
struct View3D;
struct ScrArea;
struct Scene;
-struct bPose;
struct bConstraint;
-struct BezTriple;
-struct wmOperatorType;
-struct wmOperator;
-struct wmWindowManager;
struct wmKeyMap;
struct wmKeyConfig;
struct bContext;
@@ -65,7 +60,6 @@ struct wmEvent;
struct wmTimer;
struct ARegion;
struct ReportList;
-struct SmallHash;
typedef struct TransSnapPoint {
struct TransSnapPoint *next, *prev;
@@ -108,15 +102,15 @@ typedef struct TransCon {
int imval[2]; /* initial mouse value for visual calculation */
/* the one in TransInfo is not garanty to stay the same (Rotates change it) */
int mode; /* Mode flags of the Constraint */
- void (*drawExtra)(struct TransInfo *);
+ void (*drawExtra)(struct TransInfo *t);
/* For constraints that needs to draw differently from the other
* uses this instead of the generic draw function */
- void (*applyVec)(struct TransInfo *, struct TransData *, float *, float *, float *);
+ void (*applyVec)(struct TransInfo *t, struct TransData *td, const float in[3], float out[3], float pvec[3]);
/* Apply function pointer for linear vectorial transformation */
/* The last three parameters are pointers to the in/out/printable vectors */
- void (*applySize)(struct TransInfo *, struct TransData *, float [3][3]);
+ void (*applySize)(struct TransInfo *t, struct TransData *td, float smat[3][3]);
/* Apply function pointer for size transformation */
- void (*applyRot)(struct TransInfo *, struct TransData *, float [3], float *);
+ void (*applyRot)(struct TransInfo *t, struct TransData *td, float vec[3], float *angle);
/* Apply function pointer for rotation transformation */
} TransCon;
@@ -143,6 +137,7 @@ typedef struct TransDataExtension {
* namely when a bone is in "NoLocal" or "Hinge" mode)... */
float r_smtx[3][3]; /* Invers of previous one. */
int rotOrder; /* rotation mode, as defined in eRotationModes (DNA_action_types.h) */
+ float oloc[3], orot[3], oquat[4], orotAxis[3], orotAngle; /* Original object transformation used for rigid bodies */
} TransDataExtension;
typedef struct TransData2D {
@@ -188,7 +183,7 @@ typedef struct TransDataNla {
struct LinkNode;
struct GHash;
-typedef struct TransDataSlideVert {
+typedef struct TransDataEdgeSlideVert {
struct BMVert vup, vdown;
struct BMVert origvert;
@@ -201,10 +196,10 @@ typedef struct TransDataSlideVert {
float upvec[3], downvec[3];
int loop_nr;
-} TransDataSlideVert;
+} TransDataEdgeSlideVert;
-typedef struct SlideData {
- TransDataSlideVert *sv;
+typedef struct EdgeSlideData {
+ TransDataEdgeSlideVert *sv;
int totsv;
struct SmallHash vhash;
@@ -214,15 +209,40 @@ typedef struct SlideData {
struct BMEditMesh *em;
/* flag that is set when origfaces is initialized */
- int origfaces_init;
+ bool origfaces_init;
float perc;
- int is_proportional;
- int flipped_vtx;
+ bool is_proportional;
+ bool flipped_vtx;
int curr_sv_index;
-} SlideData;
+} EdgeSlideData;
+
+
+typedef struct TransDataVertSlideVert {
+ BMVert *v;
+ float co_orig_3d[3];
+ float co_orig_2d[2];
+ float (*co_link_orig_3d)[3];
+ float (*co_link_orig_2d)[2];
+ int co_link_tot;
+ int co_link_curr;
+} TransDataVertSlideVert;
+
+typedef struct VertSlideData {
+ TransDataVertSlideVert *sv;
+ int totsv;
+
+ struct BMEditMesh *em;
+
+ float perc;
+
+ bool is_proportional;
+ bool flipped_vtx;
+
+ int curr_sv_index;
+} VertSlideData;
typedef struct TransData {
float dist; /* Distance needed to affect element (for Proportionnal Editing) */
@@ -246,8 +266,8 @@ typedef struct TransData {
} TransData;
typedef struct MouseInput {
- void (*apply)(struct TransInfo *, struct MouseInput *, const int [2], float [3]);
- void (*post)(struct TransInfo *, float [3]);
+ void (*apply)(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]);
+ void (*post)(struct TransInfo *t, float values[3]);
int imval[2]; /* initial mouse position */
char precision;
@@ -331,6 +351,7 @@ typedef struct TransInfo {
struct Scene *scene;
struct ToolSettings *settings;
struct wmTimer *animtimer;
+ struct wmKeyMap *keymap; /* so we can do lookups for header text */
int mval[2]; /* current mouse position */
struct Object *obedit;
void *draw_handle_apply;
@@ -530,6 +551,10 @@ void initEdgeSlide(TransInfo *t);
int handleEventEdgeSlide(TransInfo *t, struct wmEvent *event);
int EdgeSlide(TransInfo *t, const int mval[2]);
+void initVertSlide(TransInfo *t);
+int handleEventVertSlide(TransInfo *t, struct wmEvent *event);
+int VertSlide(TransInfo *t, const int mval[2]);
+
void initTimeTranslate(TransInfo *t);
int TimeTranslate(TransInfo *t, const int mval[2]);
@@ -572,7 +597,7 @@ void flushTransTracking(TransInfo *t);
void flushTransMasking(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
-int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */
+int gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
int calc_manipulator_stats(const struct bContext *C);
/*********************** TransData Creation and General Handling *********** */
@@ -653,16 +678,17 @@ typedef enum {
INPUT_HORIZONTAL_ABSOLUTE,
INPUT_VERTICAL_RATIO,
INPUT_VERTICAL_ABSOLUTE,
- INPUT_CUSTOM_RATIO
+ INPUT_CUSTOM_RATIO,
+ INPUT_CUSTOM_RATIO_FLIP
} MouseInputMode;
-void initMouseInput(TransInfo *t, MouseInput *mi, int center[2], int mval[2]);
+void initMouseInput(TransInfo *t, MouseInput *mi, const int center[2], const int mval[2]);
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, struct wmEvent *event);
void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]);
-void setCustomPoints(TransInfo *t, MouseInput *mi, int start[2], int end[2]);
-void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *, float [3]));
+void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
+void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float values[3]));
/*********************** Generics ********************************/
@@ -672,8 +698,6 @@ void resetTransRestrictions(TransInfo *t);
void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options);
-void drawNonPropEdge(const struct bContext *C, TransInfo *t);
-
/* DRAWLINE options flags */
#define DRAWLIGHT 1
@@ -715,8 +739,14 @@ void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *
int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3], int activeOnly);
-void freeSlideTempFaces(SlideData *sld);
-void freeSlideVerts(TransInfo *t);
-void projectSVData(TransInfo *t, int final);
+void freeEdgeSlideTempFaces(EdgeSlideData *sld);
+void freeEdgeSlideVerts(TransInfo *t);
+void projectEdgeSlideData(TransInfo *t, bool is_final);
+
+void freeVertSlideVerts(TransInfo *t);
+
+
+/* TODO. transform_queries.c */
+bool checkUseLocalCenter_GraphEdit(TransInfo *t);
#endif
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 947bdf53bee..c4d61472f18 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -60,6 +60,8 @@
#include "BLI_utildefines.h"
#include "BLI_string.h"
+#include "BLF_translation.h"
+
#include "UI_resources.h"
#include "transform.h"
@@ -200,13 +202,14 @@ static void viewAxisCorrectCenter(TransInfo *t, float t_con_center[3])
}
}
-static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3])
+static void axisProjection(TransInfo *t, const float axis[3], const float in[3], float out[3])
{
float norm[3], vec[3], factor, angle;
float t_con_center[3];
- if (in[0] == 0.0f && in[1] == 0.0f && in[2] == 0.0f)
+ if (is_zero_v3(in)) {
return;
+ }
copy_v3_v3(t_con_center, t->con.center);
@@ -278,7 +281,7 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3
}
}
-static void planeProjection(TransInfo *t, float in[3], float out[3])
+static void planeProjection(TransInfo *t, const float in[3], float out[3])
{
float vec[3], factor, norm[3];
@@ -308,7 +311,7 @@ static void planeProjection(TransInfo *t, float in[3], float out[3])
*
*/
-static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], float out[3], float pvec[3])
+static void applyAxisConstraintVec(TransInfo *t, TransData *td, const float in[3], float out[3], float pvec[3])
{
copy_v3_v3(out, in);
if (!td && t->con.mode & CON_APPLY) {
@@ -351,7 +354,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo
* Further down, that vector is mapped to each data's space.
*/
-static void applyObjectConstraintVec(TransInfo *t, TransData *td, float in[3], float out[3], float pvec[3])
+static void applyObjectConstraintVec(TransInfo *t, TransData *td, const float in[3], float out[3], float pvec[3])
{
copy_v3_v3(out, in);
if (t->con.mode & CON_APPLY) {
@@ -597,24 +600,24 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
case V3D_MANIP_GLOBAL:
{
float mtx[3][3] = MAT3_UNITY;
- BLI_snprintf(text, sizeof(text), ftext, "global");
+ BLI_snprintf(text, sizeof(text), ftext, IFACE_("global"));
setConstraint(t, mtx, mode, text);
}
break;
case V3D_MANIP_LOCAL:
- BLI_snprintf(text, sizeof(text), ftext, "local");
+ BLI_snprintf(text, sizeof(text), ftext, IFACE_("local"));
setLocalConstraint(t, mode, text);
break;
case V3D_MANIP_NORMAL:
- BLI_snprintf(text, sizeof(text), ftext, "normal");
+ BLI_snprintf(text, sizeof(text), ftext, IFACE_("normal"));
setConstraint(t, t->spacemtx, mode, text);
break;
case V3D_MANIP_VIEW:
- BLI_snprintf(text, sizeof(text), ftext, "view");
+ BLI_snprintf(text, sizeof(text), ftext, IFACE_("view"));
setConstraint(t, t->spacemtx, mode, text);
break;
case V3D_MANIP_GIMBAL:
- BLI_snprintf(text, sizeof(text), ftext, "gimbal");
+ BLI_snprintf(text, sizeof(text), ftext, IFACE_("gimbal"));
setConstraint(t, t->spacemtx, mode, text);
break;
default: /* V3D_MANIP_CUSTOM */
@@ -864,11 +867,11 @@ static void setNearestAxis2d(TransInfo *t)
/* no correction needed... just use whichever one is lower */
if (abs(t->mval[0] - t->con.imval[0]) < abs(t->mval[1] - t->con.imval[1]) ) {
t->con.mode |= CON_AXIS1;
- BLI_snprintf(t->con.text, sizeof(t->con.text), " along Y axis");
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along Y axis"));
}
else {
t->con.mode |= CON_AXIS0;
- BLI_snprintf(t->con.text, sizeof(t->con.text), " along X axis");
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along X axis"));
}
}
@@ -919,31 +922,31 @@ static void setNearestAxis3d(TransInfo *t)
if (len[0] <= len[1] && len[0] <= len[2]) {
if (t->modifiers & MOD_CONSTRAINT_PLANE) {
t->con.mode |= (CON_AXIS1 | CON_AXIS2);
- BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s X axis", t->spacename);
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s X axis"), t->spacename);
}
else {
t->con.mode |= CON_AXIS0;
- BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s X axis", t->spacename);
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s X axis"), t->spacename);
}
}
else if (len[1] <= len[0] && len[1] <= len[2]) {
if (t->modifiers & MOD_CONSTRAINT_PLANE) {
t->con.mode |= (CON_AXIS0 | CON_AXIS2);
- BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Y axis", t->spacename);
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Y axis"), t->spacename);
}
else {
t->con.mode |= CON_AXIS1;
- BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s Y axis", t->spacename);
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Y axis"), t->spacename);
}
}
else if (len[2] <= len[1] && len[2] <= len[0]) {
if (t->modifiers & MOD_CONSTRAINT_PLANE) {
t->con.mode |= (CON_AXIS0 | CON_AXIS1);
- BLI_snprintf(t->con.text, sizeof(t->con.text), " locking %s Z axis", t->spacename);
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Z axis"), t->spacename);
}
else {
t->con.mode |= CON_AXIS2;
- BLI_snprintf(t->con.text, sizeof(t->con.text), " along %s Z axis", t->spacename);
+ BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Z axis"), t->spacename);
}
}
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 51efa2b0e40..5be06188e4e 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -85,6 +85,7 @@
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_report.h"
+#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_tessmesh.h"
@@ -113,6 +114,7 @@
#include "WM_types.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "RNA_access.h"
@@ -121,35 +123,30 @@
#include "BLO_sys_types.h" // for intptr_t support
+
/* local function prototype - for Object/Bone Constraints */
static short constraints_list_needinv(TransInfo *t, ListBase *list);
/* ************************** Functions *************************** */
-static int trans_data_compare_dist(const void *A, const void *B)
+static int trans_data_compare_dist(const void *a, const void *b)
{
- const TransData *td_A = (const TransData*)A;
- const TransData *td_B = (const TransData*)B;
+ const TransData *td_a = (const TransData *)a;
+ const TransData *td_b = (const TransData *)b;
- if (td_A->dist < td_B->dist)
- return -1;
- else if (td_A->dist > td_B->dist)
- return 1;
-
- return 0;
+ if (td_a->dist < td_b->dist) return -1;
+ else if (td_a->dist > td_b->dist) return 1;
+ else return 0;
}
-static int trans_data_compare_rdist(const void *A, const void *B)
+static int trans_data_compare_rdist(const void *a, const void *b)
{
- const TransData *td_A = (const TransData*)A;
- const TransData *td_B = (const TransData*)B;
+ const TransData *td_a = (const TransData *)a;
+ const TransData *td_b = (const TransData *)b;
- if (td_A->rdist < td_B->rdist)
- return -1;
- else if (td_A->rdist > td_B->rdist)
- return 1;
-
- return 0;
+ if (td_a->rdist < td_b->rdist) return -1;
+ else if (td_a->rdist > td_b->rdist) return 1;
+ else return 0;
}
void sort_trans_data_dist(TransInfo *t)
@@ -271,7 +268,7 @@ static void createTransTexspace(TransInfo *t)
copy_m3_m4(td->mtx, ob->obmat);
copy_m3_m4(td->axismtx, ob->obmat);
normalize_m3(td->axismtx);
- invert_m3_m3(td->smtx, td->mtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) {
ob->dtx |= OB_TEXSPACE;
@@ -294,6 +291,7 @@ static void createTransEdge(TransInfo *t)
float mtx[3][3], smtx[3][3];
int count = 0, countsel = 0;
int propmode = t->flag & T_PROP_EDIT;
+ int cd_edge_float_offset;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -315,10 +313,24 @@ static void createTransEdge(TransInfo *t)
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
+
+ /* create data we need */
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_BWEIGHT);
+ cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
+ }
+ else { //if (t->mode == TFM_CREASE) {
+ BLI_assert(t->mode == TFM_CREASE);
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_CREASE);
+ cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
+ }
+
+ BLI_assert(cd_edge_float_offset != -1);
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) {
+ float *fl_ptr;
/* need to set center for center calculations */
mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
@@ -332,17 +344,10 @@ static void createTransEdge(TransInfo *t)
copy_m3_m3(td->mtx, mtx);
td->ext = NULL;
- if (t->mode == TFM_BWEIGHT) {
- float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT);
- td->val = bweight;
- td->ival = bweight ? *bweight : 1.0f;
- }
- else {
- float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE);
- BLI_assert(t->mode == TFM_CREASE);
- td->val = crease;
- td->ival = crease ? *crease : 0.0f;
- }
+
+ fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
+ td->val = fl_ptr;
+ td->ival = *fl_ptr;
td++;
}
@@ -552,7 +557,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx);
}
- invert_m3_m3(td->smtx, td->mtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
/* exceptional case: rotate the pose bone which also applies transformation
* when a parentless bone has BONE_NO_LOCAL_LOCATION [] */
@@ -604,7 +609,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
/* only object matrix correction */
copy_m3_m3(td->mtx, omat);
- invert_m3_m3(td->smtx, td->mtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
}
}
@@ -834,7 +839,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
}
}
- con = add_pose_constraint(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
+ con = BKE_add_pose_constraint(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET); /* for draw, but also for detecting while pose solving */
data = con->data;
if (targetless) {
@@ -1053,7 +1058,7 @@ static void createTransArmatureVerts(TransInfo *t)
if (!t->total) return;
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone");
@@ -1221,7 +1226,7 @@ static void createTransMBallVerts(TransInfo *t)
tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
for (ml = mb->editelems->first; ml; ml = ml->next) {
if (propmode || (ml->flag & SELECT)) {
@@ -1378,7 +1383,7 @@ static void createTransCurveVerts(TransInfo *t)
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = t->data;
for (nu = nurbs->first; nu; nu = nu->next) {
@@ -1569,7 +1574,7 @@ static void createTransLatticeVerts(TransInfo *t)
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = t->data;
bp = latt->def;
@@ -1769,7 +1774,7 @@ void flushTransParticles(TransInfo *t)
* but instead it's a depth-first search, fudged
* to report shortest distances. I have no idea how fast
* or slow this is. */
-static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists)
+static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[3][3], float *dists)
{
BMVert **queue = NULL;
float *dqueue = NULL;
@@ -1912,8 +1917,8 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
td->val = NULL;
td->extra = NULL;
if (t->mode == TFM_BWEIGHT) {
- td->val = bweight;
- td->ival = bweight ? *(bweight) : 1.0f;
+ td->val = bweight;
+ td->ival = *bweight;
}
else if (t->mode == TFM_SKIN_RESIZE) {
MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata,
@@ -1927,7 +1932,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(eve);
+ tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, BM_ELEM_SELECT);
}
}
@@ -1949,6 +1954,7 @@ static void createTransEditVerts(TransInfo *t)
int mirror = 0;
char *selstate = NULL;
short selectmode = ts->selectmode;
+ int cd_vert_bweight_offset = -1;
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_begin(em, TRUE);
@@ -2030,6 +2036,10 @@ static void createTransEditVerts(TransInfo *t)
}
}
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT);
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ }
if (propmode) {
t->total = count;
@@ -2051,7 +2061,9 @@ static void createTransEditVerts(TransInfo *t)
}
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ /* we use a pseudoinverse so that when one of the axes is scaled to 0,
+ * matrix inversion still works and we can still moving along the other */
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
if (propmode & T_PROP_CONNECTED) {
editmesh_set_connectivity_distance(em, mtx, dists);
@@ -2094,11 +2106,10 @@ static void createTransEditVerts(TransInfo *t)
}
}
- eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
- for (a = 0; eve; eve = BM_iter_step(&iter), a++) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (propmode || selstate[a]) {
- float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
+ float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
VertsToTransData(t, tob, tx, em, eve, bweight);
if (tx)
@@ -2195,7 +2206,12 @@ void flushTransNodes(TransInfo *t)
/* flush to 2d vector from internally used 3d vector */
for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) {
bNode *node = td->extra;
- add_v2_v2v2(&node->locx, td2d->loc, td2d->ih1);
+ float vec[2];
+
+ /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
+ add_v2_v2v2(vec, td2d->loc, td2d->ih1);
+ node->locx = vec[0] / UI_DPI_FAC;
+ node->locy = vec[1] / UI_DPI_FAC;
}
/* handle intersection with noodles */
@@ -2627,6 +2643,14 @@ static void createTransNlaData(bContext *C, TransInfo *t)
/* stop if trying to build list if nothing selected */
if (count == 0) {
+ /* clear temp metas that may have been created but aren't needed now
+ * because they fell on the wrong side of CFRA
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+ BKE_nlastrips_clear_metas(&nlt->strips, 0, 1);
+ }
+
/* cleanup temp list */
BLI_freelistN(&anim_data);
return;
@@ -2671,14 +2695,14 @@ static void createTransNlaData(bContext *C, TransInfo *t)
tdn->oldTrack = tdn->nlt = nlt;
tdn->strip = strip;
tdn->trackIndex = BLI_findindex(&adt->nla_tracks, nlt);
-
+
yval = (float)(tdn->trackIndex * NLACHANNEL_STEP(snla));
-
+
tdn->h1[0] = strip->start;
tdn->h1[1] = yval;
tdn->h2[0] = strip->end;
tdn->h2[1] = yval;
-
+
center[0] = (float)CFRA;
center[1] = yval;
center[2] = 0.0f;
@@ -3507,7 +3531,9 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
int count = 0, i;
float cfra;
float mtx[3][3], smtx[3][3];
- const short use_handle = !(sipo->flag & SIPO_NOHANDLES);
+ const bool use_handle = !(sipo->flag & SIPO_NOHANDLES);
+ const bool use_local_center = checkUseLocalCenter_GraphEdit(t);
+ const short anim_map_flag = ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS;
/* determine what type of data we are operating on */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -3639,7 +3665,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
if (fcu->bezt == NULL)
continue;
- ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS);
+ ANIM_unit_mapping_apply_fcurve(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++) {
@@ -3674,7 +3700,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
}
/* only include main vert if selected */
- if (sel2 && (sipo->around != V3D_LOCAL || ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE))) {
+ if (sel2 && (use_local_center == false)) {
/* move handles relative to center */
if (ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE)) {
@@ -3710,6 +3736,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
/* Sets handles based on the selection */
testhandles_fcurve(fcu, use_handle);
+
+ /* even though transform values are written back right after during transform,
+ * using individual center's with rotation means the center point wont
+ * be touched again see: [#34303] */
+ if (use_local_center) {
+ ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, anim_map_flag | ANIM_UNITCONV_RESTORE);
+ }
}
/* cleanup temp list */
@@ -4082,7 +4115,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
/* Meta's can only directly be moved between channels since they
* don't have their start and length set directly (children affect that)
* since this Meta is nested we don't need any of its data in fact.
- * calc_sequence() will update its settings when run on the toplevel meta */
+ * BKE_sequence_calc() will update its settings when run on the toplevel meta */
*flag = 0;
*count = 0;
*recursive = TRUE;
@@ -4260,8 +4293,8 @@ static void freeSeqData(TransInfo *t)
{
int overlap = 0;
+ seq_prev = NULL;
for (a = 0; a < t->total; a++, td++) {
- seq_prev = NULL;
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
overlap = 1;
@@ -4527,6 +4560,27 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
short constinv;
short skip_invert = 0;
+ if (ob->rigidbody_object) {
+ float rot[3][3], scale[3];
+
+ /* save original object transform */
+ copy_v3_v3(td->ext->oloc, ob->loc);
+
+ if (ob->rotmode > 0) {
+ copy_v3_v3(td->ext->orot, ob->rot);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ td->ext->orotAngle = ob->rotAngle;
+ copy_v3_v3(td->ext->orotAxis, ob->rotAxis);
+ }
+ else {
+ copy_qt_qt(td->ext->oquat, ob->quat);
+ }
+ /* update object's loc/rot to get current rigid body transform */
+ mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
+ BKE_object_mat3_to_rot(ob, rot, FALSE);
+ }
+
/* axismtx has the real orientation */
copy_m3_m4(td->axismtx, ob->obmat);
normalize_m3(td->axismtx);
@@ -4689,6 +4743,7 @@ static void set_trans_object_base_flags(TransInfo *t)
}
/* all recalc flags get flushed to all layers, so a layer flip later on works fine */
+ DAG_scene_relations_update(G.main, t->scene);
DAG_scene_flush_update(G.main, t->scene, -1, 0);
/* and we store them temporal in base (only used for transform code) */
@@ -4766,6 +4821,7 @@ static int count_proportional_objects(TransInfo *t)
/* all recalc flags get flushed to all layers, so a layer flip later on works fine */
+ DAG_scene_relations_update(G.main, t->scene);
DAG_scene_flush_update(G.main, t->scene, -1, 0);
/* and we store them temporal in base (only used for transform code) */
@@ -5080,25 +5136,25 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (canceled == 0) {
/* we need to delete the temporary faces before automerging */
if (t->mode == TFM_EDGE_SLIDE) {
- SlideData *sld = t->customData;
+ EdgeSlideData *sld = t->customData;
/* handle multires re-projection, done
* on transform completion since it's
* really slow -joeedh */
- projectSVData(t, TRUE);
+ projectEdgeSlideData(t, TRUE);
/* free temporary faces to avoid automerging and deleting
* during cleanup - psy-fi */
- freeSlideTempFaces(sld);
+ freeEdgeSlideTempFaces(sld);
}
- EDBM_automerge(t->scene, t->obedit, 1);
+ EDBM_automerge(t->scene, t->obedit, TRUE);
}
else {
if (t->mode == TFM_EDGE_SLIDE) {
- SlideData *sld = t->customData;
+ EdgeSlideData *sld = t->customData;
sld->perc = 0.0;
- projectSVData(t, FALSE);
+ projectEdgeSlideData(t, FALSE);
}
}
}
@@ -5480,6 +5536,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)
recalcObPaths = 1;
}
+ /* restore rigid body transform */
+ if (ob->rigidbody_object && canceled)
+ BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle);
}
/* recalculate motion paths for objects (if necessary)
@@ -5592,7 +5651,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node)
/* hold original location */
float locxy[2] = {BLI_rctf_cent_x(&node->totr),
BLI_rctf_cent_y(&node->totr)};
-
+ float nodeloc[2];
+
copy_v2_v2(td2d->loc, locxy);
td2d->loc[2] = 0.0f;
td2d->loc2d = td2d->loc; /* current location */
@@ -5617,7 +5677,10 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node)
unit_m3(td->mtx);
unit_m3(td->smtx);
- sub_v2_v2v2(td2d->ih1, &node->locx, locxy);
+ /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
+ nodeloc[0] = UI_DPI_FAC * node->locx;
+ nodeloc[1] = UI_DPI_FAC * node->locy;
+ sub_v2_v2v2(td2d->ih1, nodeloc, locxy);
td->extra = node;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 615bb786071..c2a331f5249 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -56,11 +56,15 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "RNA_access.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "BIK_api.h"
+
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -128,6 +132,7 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3])
/* ************************** GENERICS **************************** */
+
static void clipMirrorModifier(TransInfo *t, Object *ob)
{
ModifierData *md = ob->modifiers.first;
@@ -375,6 +380,8 @@ static void recalcData_graphedit(TransInfo *t)
bAnimListElem *ale;
int dosort = 0;
+
+ const bool use_local_center = checkUseLocalCenter_GraphEdit(t);
/* initialize relevant anim-context 'context' data from TransInfo data */
@@ -403,9 +410,10 @@ static void recalcData_graphedit(TransInfo *t)
/* ignore unselected fcurves */
if (!fcu_test_selected(fcu))
continue;
-
- // fixme: only do this for selected verts...
- ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS | ANIM_UNITCONV_RESTORE);
+
+ ANIM_unit_mapping_apply_fcurve(ac.scene, ale->id, ale->key_data,
+ ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS | ANIM_UNITCONV_RESTORE |
+ (use_local_center ? ANIM_UNITCONV_SKIPKNOTS : 0));
/* watch it: if the time is wrong: do not correct handles yet */
@@ -548,13 +556,20 @@ static void recalcData_nla(TransInfo *t)
break;
}
- /* use RNA to write the values... */
- // TODO: do we need to write in 2 passes to make sure that no truncation goes on?
+ /* Use RNA to write the values to ensure that constraints on these are obeyed
+ * (e.g. for transition strips, the values are taken from the neighbours)
+ *
+ * NOTE: we write these twice to avoid truncation errors which can arise when
+ * moving the strips a large distance using numeric input [#33852]
+ */
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
+ RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
+ RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
+
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);
@@ -796,6 +811,7 @@ static void recalcData_view3d(TransInfo *t)
if (td->extra) {
float vec[3], up_axis[3];
float qrot[4];
+ float roll;
ebo = td->extra;
copy_v3_v3(up_axis, td->axismtx[2]);
@@ -810,7 +826,9 @@ static void recalcData_view3d(TransInfo *t)
mul_m3_v3(t->mat, up_axis);
}
- ebo->roll = ED_rollBoneToVector(ebo, up_axis, FALSE);
+ /* roll has a tendency to flip in certain orientations - [#34283], [#33974] */
+ roll = ED_rollBoneToVector(ebo, up_axis, false);
+ ebo->roll = angle_compat_rad(roll, ebo->roll);
}
}
}
@@ -847,6 +865,8 @@ static void recalcData_view3d(TransInfo *t)
/* old optimize trick... this enforces to bypass the depgraph */
if (!(arm->flag & ARM_DELAYDEFORM)) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
+ /* transformation of pose may affect IK tree, make sure it is rebuilt */
+ BIK_clear_data(ob->pose);
}
else
BKE_pose_where_is(t->scene, ob);
@@ -1445,7 +1465,7 @@ void calculateCenter2D(TransInfo *t)
void calculateCenterCursor(TransInfo *t)
{
- float *cursor;
+ const float *cursor;
cursor = give_cursor(t->scene, t->view);
copy_v3_v3(t->center, cursor);
@@ -1529,13 +1549,6 @@ void calculateCenterMedian(TransInfo *t)
total++;
}
}
- else {
- /*
- * All the selected elements are at the head of the array
- * which means we can stop when it finds unselected data
- */
- break;
- }
}
if (i)
mul_v3_fl(partial, 1.0f / total);
@@ -1555,13 +1568,6 @@ void calculateCenterBound(TransInfo *t)
if (!(t->data[i].flag & TD_NOCENTER))
minmax_v3v3_v3(min, max, t->data[i].center);
}
- else {
- /*
- * All the selected elements are at the head of the array
- * which means we can stop when it finds unselected data
- */
- break;
- }
}
else {
copy_v3_v3(max, t->data[i].center);
@@ -1764,25 +1770,25 @@ void calculatePropRatio(TransInfo *t)
}
switch (t->prop_mode) {
case PROP_SHARP:
- strcpy(t->proptext, "(Sharp)");
+ strcpy(t->proptext, IFACE_("(Sharp)"));
break;
case PROP_SMOOTH:
- strcpy(t->proptext, "(Smooth)");
+ strcpy(t->proptext, IFACE_("(Smooth)"));
break;
case PROP_ROOT:
- strcpy(t->proptext, "(Root)");
+ strcpy(t->proptext, IFACE_("(Root)"));
break;
case PROP_LIN:
- strcpy(t->proptext, "(Linear)");
+ strcpy(t->proptext, IFACE_("(Linear)"));
break;
case PROP_CONST:
- strcpy(t->proptext, "(Constant)");
+ strcpy(t->proptext, IFACE_("(Constant)"));
break;
case PROP_SPHERE:
- strcpy(t->proptext, "(Sphere)");
+ strcpy(t->proptext, IFACE_("(Sphere)"));
break;
case PROP_RANDOM:
- strcpy(t->proptext, "(Random)");
+ strcpy(t->proptext, IFACE_("(Random)"));
break;
default:
t->proptext[0] = '\0';
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 7e05fdae364..4e9a54692a5 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -164,7 +164,7 @@ static void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, const int mval[2
output[0] = dot_v3v3(t->viewinv[1], vec) * 2.0f;
}
-void setCustomPoints(TransInfo *UNUSED(t), MouseInput *mi, int start[2], int end[2])
+void setCustomPoints(TransInfo *UNUSED(t), MouseInput *mi, const int start[2], const int end[2])
{
int *data;
@@ -180,7 +180,7 @@ void setCustomPoints(TransInfo *UNUSED(t), MouseInput *mi, int start[2], int end
data[3] = end[1];
}
-static void InputCustomRatio(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
+static void InputCustomRatioFlip(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
{
double length;
double distance;
@@ -213,6 +213,12 @@ static void InputCustomRatio(TransInfo *UNUSED(t), MouseInput *mi, const int mva
}
}
+static void InputCustomRatio(TransInfo *t, MouseInput *mi, const int mval[2], float output[3])
+{
+ InputCustomRatioFlip(t, mi, mval, output);
+ output[0] = -output[0];
+}
+
static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2], float output[3])
{
double dx2 = mval[0] - mi->center[0];
@@ -232,7 +238,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2],
double deler = (((dx1 * dx1 + dy1 * dy1) +
(dx2 * dx2 + dy2 * dy2) -
(dx3 * dx3 + dy3 * dy3)) / (2.0 * ((A * B) ? (A * B) : 1.0)));
- /* ((A*B)?(A*B):1.0) this takes care of potential divide by zero errors */
+ /* ((A * B) ? (A * B) : 1.0) this takes care of potential divide by zero errors */
float dphi;
@@ -275,7 +281,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2],
output[0] = *angle;
}
-void initMouseInput(TransInfo *UNUSED(t), MouseInput *mi, int center[2], int mval[2])
+void initMouseInput(TransInfo *UNUSED(t), MouseInput *mi, const int center[2], const int mval[2])
{
mi->factor = 0;
mi->precision = 0;
@@ -301,15 +307,8 @@ static void calcSpringFactor(MouseInput *mi)
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
{
- /* may have been allocated previously */
- /* TODO, holding R-key can cause mem leak, but this causes [#28903]
- * disable for now. */
-#if 0
- if (mi->data) {
- MEM_freeN(mi->data);
- mi->data = NULL;
- }
-#endif
+ /* incase we allocate a new value */
+ void *mi_data_prev = mi->data;
switch (mode) {
case INPUT_VECTOR:
@@ -358,17 +357,27 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
mi->apply = InputCustomRatio;
t->helpline = HLP_NONE;
break;
+ case INPUT_CUSTOM_RATIO_FLIP:
+ mi->apply = InputCustomRatioFlip;
+ t->helpline = HLP_NONE;
+ break;
case INPUT_NONE:
default:
mi->apply = NULL;
break;
}
+ /* if we've allocated new data, free the old data
+ * less hassle then checking before every alloc above */
+ if (mi_data_prev && (mi_data_prev != mi->data)) {
+ MEM_freeN(mi_data_prev);
+ }
+
/* bootstrap mouse input with initial values */
applyMouseInput(t, mi, mi->imval, t->values);
}
-void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *, float[3]))
+void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float values[3]))
{
mi->post = post;
}
@@ -397,12 +406,13 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event)
* store the mouse position where the normal movement ended */
copy_v2_v2_int(mi->precision_mval, event->mval);
mi->precision = 1;
+ redraw = TREDRAW_HARD;
}
- else {
+ else if (event->val == KM_RELEASE) {
t->modifiers &= ~MOD_PRECISION;
mi->precision = 0;
+ redraw = TREDRAW_HARD;
}
- redraw = TREDRAW_HARD;
break;
}
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index a3f45acc02e..cd6035a232b 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -148,10 +148,8 @@ static void stats_pose(Scene *scene, RegionView3D *rv3d, bPoseChannel *pchan)
Bone *bone = pchan->bone;
if (bone) {
- if (bone->flag & BONE_TRANSFORM) {
- calc_tw_center(scene, pchan->pose_head);
- protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag);
- }
+ calc_tw_center(scene, pchan->pose_head);
+ protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag);
}
}
@@ -199,7 +197,7 @@ static int test_rotmode_euler(short rotmode)
return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
}
-int gimbal_axis(Object *ob, float gmat[][3])
+int gimbal_axis(Object *ob, float gmat[3][3])
{
if (ob) {
if (ob->mode & OB_MODE_POSE) {
@@ -361,18 +359,35 @@ int calc_manipulator_stats(const bContext *C)
else if (obedit->type == OB_ARMATURE) {
bArmature *arm = obedit->data;
EditBone *ebo;
- for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
- if (EBONE_VISIBLE(arm, ebo)) {
- if (ebo->flag & BONE_TIPSEL) {
- calc_tw_center(scene, ebo->tail);
- totsel++;
- }
- if (ebo->flag & BONE_ROOTSEL) {
- calc_tw_center(scene, ebo->head);
- totsel++;
- }
- if (ebo->flag & BONE_SELECTED) {
- stats_editbone(rv3d, ebo);
+
+ if ((v3d->around == V3D_ACTIVE) && (ebo = arm->act_edbone)) {
+ /* doesn't check selection or visibility intentionally */
+ if (ebo->flag & BONE_TIPSEL) {
+ calc_tw_center(scene, ebo->tail);
+ totsel++;
+ }
+ if ((ebo->flag & BONE_ROOTSEL) ||
+ ((ebo->flag & BONE_TIPSEL) == FALSE)) /* ensure we get at least one point */
+ {
+ calc_tw_center(scene, ebo->head);
+ totsel++;
+ }
+ stats_editbone(rv3d, ebo);
+ }
+ else {
+ for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
+ if (EBONE_VISIBLE(arm, ebo)) {
+ if (ebo->flag & BONE_TIPSEL) {
+ calc_tw_center(scene, ebo->tail);
+ totsel++;
+ }
+ if (ebo->flag & BONE_ROOTSEL) {
+ calc_tw_center(scene, ebo->head);
+ totsel++;
+ }
+ if (ebo->flag & BONE_SELECTED) {
+ stats_editbone(rv3d, ebo);
+ }
}
}
}
@@ -480,17 +495,35 @@ int calc_manipulator_stats(const bContext *C)
else if (ob && (ob->mode & OB_MODE_POSE)) {
bPoseChannel *pchan;
int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed
+ int ok = FALSE;
if ((ob->lay & v3d->lay) == 0) return 0;
- totsel = count_set_pose_transflags(&mode, 0, ob);
-
- if (totsel) {
- /* use channels to get stats */
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((v3d->around == V3D_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) {
+ /* doesn't check selection or visibility intentionally */
+ Bone *bone = pchan->bone;
+ if (bone) {
stats_pose(scene, rv3d, pchan);
+ totsel = 1;
+ ok = TRUE;
+ }
+ }
+ else {
+ totsel = count_set_pose_transflags(&mode, 0, ob);
+
+ if (totsel) {
+ /* use channels to get stats */
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ Bone *bone = pchan->bone;
+ if (bone && (bone->flag & BONE_TRANSFORM)) {
+ stats_pose(scene, rv3d, pchan);
+ }
+ }
+ ok = TRUE;
}
+ }
+ if (ok) {
mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid!
mul_m4_v3(ob->obmat, scene->twcent);
mul_m4_v3(ob->obmat, scene->twmin);
@@ -552,8 +585,9 @@ int calc_manipulator_stats(const bContext *C)
switch (v3d->twmode) {
case V3D_MANIP_GLOBAL:
+ {
break; /* nothing to do */
-
+ }
case V3D_MANIP_GIMBAL:
{
float mat[3][3];
@@ -562,28 +596,43 @@ int calc_manipulator_stats(const bContext *C)
break;
}
/* if not gimbal, fall through to normal */
+ /* pass through */
}
case V3D_MANIP_NORMAL:
+ {
if (obedit || ob->mode & OB_MODE_POSE) {
float mat[3][3];
ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE));
copy_m4_m3(rv3d->twmat, mat);
break;
}
- /* no break we define 'normal' as 'local' in Object mode */
+ /* no break we define 'normal' as 'local' in Object mode */
+ /* pass through */
+ }
case V3D_MANIP_LOCAL:
+ {
+ if (ob->mode & OB_MODE_POSE) {
+ /* each bone moves on its own local axis, but to avoid confusion,
+ * use the active pones axis for display [#33575], this works as expected on a single bone
+ * and users who select many bones will understand whats going on and what local means
+ * when they start transforming */
+ float mat[3][3];
+ ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE));
+ copy_m4_m3(rv3d->twmat, mat);
+ break;
+ }
copy_m4_m4(rv3d->twmat, ob->obmat);
normalize_m4(rv3d->twmat);
break;
-
+ }
case V3D_MANIP_VIEW:
{
float mat[3][3];
copy_m3_m4(mat, rv3d->viewinv);
normalize_m3(mat);
copy_m4_m3(rv3d->twmat, mat);
+ break;
}
- break;
default: /* V3D_MANIP_CUSTOM */
{
float mat[3][3];
@@ -638,7 +687,7 @@ static void test_manipulator_axis(const bContext *C)
/* ******************** DRAWING STUFFIES *********** */
-static float screen_aligned(RegionView3D *rv3d, float mat[][4])
+static float screen_aligned(RegionView3D *rv3d, float mat[4][4])
{
glTranslatef(mat[3][0], mat[3][1], mat[3][2]);
@@ -685,8 +734,8 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i
float cos_phi, sin_phi, dist;
phi += side_delta;
- cos_phi = (float)cos(phi);
- sin_phi = (float)sin(phi);
+ cos_phi = cosf(phi);
+ sin_phi = sinf(phi);
dist = radhole + radring * cos_phi;
glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
@@ -700,8 +749,8 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i
float cos_phi, sin_phi, dist;
phi += side_delta;
- cos_phi = (float)cos(phi);
- sin_phi = (float)sin(phi);
+ cos_phi = cosf(phi);
+ sin_phi = sinf(phi);
dist = radhole + radring * cos_phi;
glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
@@ -826,7 +875,7 @@ static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode,
}
}
-static void preOrthoFront(int ortho, float twmat[][4], int axis)
+static void preOrthoFront(int ortho, float twmat[4][4], int axis)
{
if (ortho == 0) {
float omat[4][4];
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 916cf540589..0392c0f47a2 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -37,6 +37,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_armature.h"
@@ -73,6 +75,7 @@ static char OP_TILT[] = "TRANSFORM_OT_tilt";
static char OP_TRACKBALL[] = "TRANSFORM_OT_trackball";
static char OP_MIRROR[] = "TRANSFORM_OT_mirror";
static char OP_EDGE_SLIDE[] = "TRANSFORM_OT_edge_slide";
+static char OP_VERT_SLIDE[] = "TRANSFORM_OT_vert_slide";
static char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
static char OP_EDGE_BWEIGHT[] = "TRANSFORM_OT_edge_bevelweight";
static char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
@@ -90,6 +93,7 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot);
static void TRANSFORM_OT_trackball(struct wmOperatorType *ot);
static void TRANSFORM_OT_mirror(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot);
+static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot);
static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
@@ -109,6 +113,7 @@ static TransformModeItem transform_modes[] =
{OP_TRACKBALL, TFM_TRACKBALL, TRANSFORM_OT_trackball},
{OP_MIRROR, TFM_MIRROR, TRANSFORM_OT_mirror},
{OP_EDGE_SLIDE, TFM_EDGE_SLIDE, TRANSFORM_OT_edge_slide},
+ {OP_VERT_SLIDE, TFM_VERT_SLIDE, TRANSFORM_OT_vert_slide},
{OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease},
{OP_EDGE_BWEIGHT, TFM_BWEIGHT, TRANSFORM_OT_edge_bevelweight},
{OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide},
@@ -150,38 +155,6 @@ EnumPropertyItem transform_mode_types[] =
{0, NULL, 0, NULL, NULL}
};
-static int snap_type_exec(bContext *C, wmOperator *op)
-{
- ToolSettings *ts = CTX_data_tool_settings(C);
-
- ts->snap_mode = RNA_enum_get(op->ptr, "type");
-
- WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
-
- return OPERATOR_FINISHED;
-}
-
-static void TRANSFORM_OT_snap_type(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Snap Type";
- ot->description = "Set the snap element type";
- ot->idname = "TRANSFORM_OT_snap_type";
-
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = snap_type_exec;
-
- ot->poll = ED_operator_areaactive;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* props */
- ot->prop = RNA_def_enum(ot->srna, "type", snap_element_items, 0, "Type", "Set the snap element type");
-
-}
-
static int select_orientation_exec(bContext *C, wmOperator *op)
{
int orientation = RNA_enum_get(op->ptr, "orientation");
@@ -198,7 +171,7 @@ static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), wmEven
uiPopupMenu *pup;
uiLayout *layout;
- pup = uiPupMenuBegin(C, "Orientation", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Orientation"), ICON_NONE);
layout = uiPupMenuLayout(pup);
uiItemsEnumO(layout, "TRANSFORM_OT_select_orientation", "orientation");
uiPupMenuEnd(C, pup);
@@ -793,6 +766,26 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
}
+static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Vertex Slide";
+ ot->description = "Slide a vertex along a mesh";
+ ot->idname = OP_VERT_SLIDE;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editmesh;
+
+ RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
+
+ Transform_Properties(ot, P_MIRROR | P_SNAP);
+}
+
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
{
/* identifiers */
@@ -891,8 +884,6 @@ void transform_operatortypes(void)
WM_operatortype_append(TRANSFORM_OT_select_orientation);
WM_operatortype_append(TRANSFORM_OT_create_orientation);
WM_operatortype_append(TRANSFORM_OT_delete_orientation);
-
- WM_operatortype_append(TRANSFORM_OT_snap_type);
}
void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spaceid)
@@ -939,7 +930,9 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
- WM_keymap_add_item(keymap, "TRANSFORM_OT_snap_type", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.snap_element");
+
kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
@@ -1032,6 +1025,9 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.snap_uv_element");
break;
case SPACE_CLIP:
WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 70e4d4cd027..e507d062b0e 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -43,6 +43,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_context.h"
@@ -437,7 +438,7 @@ int BIF_countTransformOrientation(const bContext *C)
return count;
}
-void applyTransformOrientation(const bContext *C, float mat[3][3], char *name)
+void applyTransformOrientation(const bContext *C, float mat[3][3], char name[MAX_NAME])
{
TransformOrientation *ts;
View3D *v3d = CTX_wm_view3d(C);
@@ -448,8 +449,9 @@ void applyTransformOrientation(const bContext *C, float mat[3][3], char *name)
for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) {
if (selected_index == i) {
- if (name)
- strcpy(name, ts->name);
+ if (name) {
+ BLI_strncpy(name, ts->name, MAX_NAME);
+ }
copy_m3_m3(mat, ts->mat);
break;
@@ -491,25 +493,25 @@ void initTransformOrientation(bContext *C, TransInfo *t)
switch (t->current_orientation) {
case V3D_MANIP_GLOBAL:
unit_m3(t->spacemtx);
- strcpy(t->spacename, "global");
+ strcpy(t->spacename, IFACE_("global"));
break;
case V3D_MANIP_GIMBAL:
unit_m3(t->spacemtx);
if (gimbal_axis(ob, t->spacemtx)) {
- strcpy(t->spacename, "gimbal");
+ strcpy(t->spacename, IFACE_("gimbal"));
break;
}
/* no gimbal fallthrough to normal */
case V3D_MANIP_NORMAL:
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
- strcpy(t->spacename, "normal");
+ strcpy(t->spacename, IFACE_("normal"));
ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE));
break;
}
/* no break we define 'normal' as 'local' in Object mode */
case V3D_MANIP_LOCAL:
- strcpy(t->spacename, "local");
+ strcpy(t->spacename, IFACE_("local"));
if (ob) {
copy_m3_m4(t->spacemtx, ob->obmat);
@@ -526,7 +528,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
RegionView3D *rv3d = t->ar->regiondata;
float mat[3][3];
- strcpy(t->spacename, "view");
+ strcpy(t->spacename, IFACE_("view"));
copy_m3_m4(mat, rv3d->viewinv);
normalize_m3(mat);
copy_m3_m3(t->spacemtx, mat);
@@ -737,7 +739,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
}
}
- if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0) {
+ if (!is_zero_v3(normal)) {
result = ORIENTATION_NORMAL;
}
}
@@ -760,29 +762,45 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
else if (obedit->type == OB_ARMATURE) {
bArmature *arm = obedit->data;
EditBone *ebone;
+ int ok = FALSE;
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (arm->layer & ebone->layer) {
- if (ebone->flag & BONE_SELECTED) {
- float tmat[3][3];
- float vec[3];
- sub_v3_v3v3(vec, ebone->tail, ebone->head);
- normalize_v3(vec);
- add_v3_v3(normal, vec);
-
- vec_roll_to_mat3(vec, ebone->roll, tmat);
- add_v3_v3(plane, tmat[2]);
+ /* grr. but better then duplicate code */
+#define EBONE_CALC_NORMAL_PLANE { \
+ float tmat[3][3]; \
+ float vec[3]; \
+ sub_v3_v3v3(vec, ebone->tail, ebone->head); \
+ normalize_v3(vec); \
+ add_v3_v3(normal, vec); \
+ \
+ vec_roll_to_mat3(vec, ebone->roll, tmat); \
+ add_v3_v3(plane, tmat[2]); \
+ } (void)0
+
+
+ if (activeOnly && (ebone = arm->act_edbone)) {
+ EBONE_CALC_NORMAL_PLANE;
+ ok = TRUE;
+ }
+ else {
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (arm->layer & ebone->layer) {
+ if (ebone->flag & BONE_SELECTED) {
+ EBONE_CALC_NORMAL_PLANE;
+ ok = TRUE;
+ }
}
}
}
- normalize_v3(normal);
- normalize_v3(plane);
+ if (ok) {
+ normalize_v3(normal);
+ normalize_v3(plane);
- if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0) {
- result = ORIENTATION_EDGE;
+ if (!is_zero_v3(plane)) {
+ result = ORIENTATION_EDGE;
+ }
}
-
+#undef EBONE_CALC_NORMAL_PLANE
}
/* Vectors from edges don't need the special transpose inverse multiplication */
@@ -798,19 +816,32 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
else if (ob && (ob->mode & OB_MODE_POSE)) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
- int totsel;
-
- totsel = count_bone_select(arm, &arm->bonebase, 1);
- if (totsel) {
- float imat[3][3], mat[3][3];
-
- /* use channels to get stats */
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
- add_v3_v3(normal, pchan->pose_mat[2]);
- add_v3_v3(plane, pchan->pose_mat[1]);
+ float imat[3][3], mat[3][3];
+ int ok = FALSE;
+
+ if (activeOnly && (pchan = BKE_pose_channel_active(ob))) {
+ add_v3_v3(normal, pchan->pose_mat[2]);
+ add_v3_v3(plane, pchan->pose_mat[1]);
+ ok = TRUE;
+ }
+ else {
+ int totsel;
+
+ totsel = count_bone_select(arm, &arm->bonebase, 1);
+ if (totsel) {
+ /* use channels to get stats */
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
+ add_v3_v3(normal, pchan->pose_mat[2]);
+ add_v3_v3(plane, pchan->pose_mat[1]);
+ }
}
+ ok = TRUE;
}
+ }
+
+ /* use for both active & all */
+ if (ok) {
negate_v3(plane);
/* we need the transpose of the inverse for a normal... */
@@ -851,7 +882,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
return result;
}
-void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly)
+void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], int activeOnly)
{
float normal[3] = {0.0, 0.0, 0.0};
float plane[3] = {0.0, 0.0, 0.0};
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 2d95e2ecdc6..2efd35327c7 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -303,6 +303,9 @@ void applyProject(TransInfo *t)
if (td->flag & TD_SKIP)
continue;
+
+ if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f))
+ continue;
copy_v3_v3(iloc, td->loc);
if (t->flag & (T_EDIT | T_POSE)) {
@@ -1141,7 +1144,7 @@ static void TargetSnapClosest(TransInfo *t)
}
}
-static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[][4], float timat[][3],
+static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[4][4], float timat[3][3],
const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1228,7 +1231,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh
return retval;
}
-static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], float timat[][3],
+static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4], float timat[3][3],
const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1276,7 +1279,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4],
return retval;
}
-static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4],
+static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float mval[2],
float r_loc[3], float *UNUSED(r_no), int *r_dist, float *r_depth)
{
@@ -1339,7 +1342,7 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm
return retval;
}
-static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[][4],
+static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1417,7 +1420,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
if (em != NULL) {
index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
}
for (i = 0; i < totvert; i++) {
@@ -1452,9 +1455,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
}
}
- if (em != NULL) {
- EDBM_index_arrays_free(em);
- }
break;
}
case SCE_SNAP_MODE_EDGE:
@@ -1468,7 +1468,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
if (em != NULL) {
index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
- EDBM_index_arrays_init(em, 0, 1, 0);
+ EDBM_index_arrays_ensure(em, BM_EDGE);
}
for (i = 0; i < totedge; i++) {
@@ -1505,9 +1505,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
}
}
- if (em != NULL) {
- EDBM_index_arrays_free(em);
- }
break;
}
}
@@ -1517,7 +1514,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
return retval;
}
-static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4],
+static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1670,7 +1667,7 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n
peel->flag = 0;
}
-static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4],
+static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
ListBase *depth_peels)
{
diff --git a/source/blender/editors/util/SConscript b/source/blender/editors/util/SConscript
index 74879e54850..1c1a8e46dd7 100644
--- a/source/blender/editors/util/SConscript
+++ b/source/blender/editors/util/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 23d6b0a075e..f0f31b1e793 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -42,6 +42,8 @@
#include "BLI_blenlib.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -174,10 +176,10 @@ 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, "Unpack file", ICON_NONE);
+ pup = uiPupMenuBegin(C, IFACE_("Unpack File"), ICON_NONE);
layout = uiPupMenuLayout(pup);
- strcpy(line, "Remove Pack");
+ strcpy(line, IFACE_("Remove Pack"));
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_REMOVE);
RNA_string_set(&props_ptr, "id", id_name);
@@ -191,14 +193,14 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
if (strcmp(abs_name, local_name) != 0) {
switch (checkPackedFile(local_name, pf)) {
case PF_NOFILE:
- BLI_snprintf(line, sizeof(line), "Create %s", local_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), local_name);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
RNA_string_set(&props_ptr, "id", id_name);
break;
case PF_EQUAL:
- BLI_snprintf(line, sizeof(line), "Use %s (identical)", local_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Use %s (identical)"), local_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
@@ -206,13 +208,13 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
break;
case PF_DIFFERS:
- BLI_snprintf(line, sizeof(line), "Use %s (differs)", local_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Use %s (differs)"), local_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
RNA_string_set(&props_ptr, "id", id_name);
- BLI_snprintf(line, sizeof(line), "Overwrite %s", local_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Overwrite %s"), local_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_LOCAL);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
@@ -224,27 +226,27 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
switch (checkPackedFile(abs_name, pf)) {
case PF_NOFILE:
- BLI_snprintf(line, sizeof(line), "Create %s", abs_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), abs_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
RNA_string_set(&props_ptr, "id", id_name);
break;
case PF_EQUAL:
- BLI_snprintf(line, sizeof(line), "Use %s (identical)", abs_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Use %s (identical)"), abs_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
RNA_string_set(&props_ptr, "id", id_name);
break;
case PF_DIFFERS:
- BLI_snprintf(line, sizeof(line), "Use %s (differs)", abs_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Use %s (differs)"), abs_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
RNA_string_set(&props_ptr, "id", id_name);
- BLI_snprintf(line, sizeof(line), "Overwrite %s", abs_name);
+ BLI_snprintf(line, sizeof(line), IFACE_("Overwrite %s"), abs_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 1753a564a3c..8a0ef06ef12 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -162,15 +162,18 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
}
}
else {
- int do_glob_undo = FALSE;
-
+ /* Note: we used to do a fall-through here where if the
+ * mode-specific undo system had no more steps to undo (or
+ * redo), the global undo would run.
+ *
+ * That was inconsistent with editmode, and also makes for
+ * unecessarily tricky interaction with the other undo
+ * systems. */
if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
- if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname))
- do_glob_undo = TRUE;
+ ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname);
}
else if (obact && obact->mode & OB_MODE_SCULPT) {
- if (!ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname))
- do_glob_undo = TRUE;
+ ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname);
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
if (step == 1)
@@ -178,24 +181,17 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
else
PE_redo(CTX_data_scene(C));
}
- else {
- do_glob_undo = TRUE;
- }
-
- if (do_glob_undo) {
- if (U.uiflag & USER_GLOBALUNDO) {
- // note python defines not valid here anymore.
- //#ifdef WITH_PYTHON
- // XXX BPY_scripts_clear_pyobjects();
- //#endif
- if (undoname)
- BKE_undo_name(C, undoname);
- else
- BKE_undo_step(C, step);
+ else if (U.uiflag & USER_GLOBALUNDO) {
+ // note python defines not valid here anymore.
+ //#ifdef WITH_PYTHON
+ // XXX BPY_scripts_clear_pyobjects();
+ //#endif
+ if (undoname)
+ BKE_undo_name(C, undoname);
+ else
+ BKE_undo_step(C, step);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
- }
-
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
}
}
@@ -343,8 +339,9 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
wmWindowManager *wm = CTX_wm_manager(C);
struct Scene *scene = CTX_data_scene(C);
+ /* keep in sync with logic in view3d_panel_operator_redo() */
ARegion *ar = CTX_wm_region(C);
- ARegion *ar1 = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW);
+ ARegion *ar1 = BKE_area_find_region_active_win(CTX_wm_area(C));
if (ar1)
CTX_wm_region_set(C, ar1);
diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt
index 1c69e569aa6..695a7cdd0f6 100644
--- a/source/blender/editors/uvedit/CMakeLists.txt
+++ b/source/blender/editors/uvedit/CMakeLists.txt
@@ -22,6 +22,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenfont
../../blenloader
../../bmesh
../../makesdna
@@ -47,4 +48,8 @@ set(SRC
uvedit_parametrizer.h
)
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_uvedit "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/uvedit/SConscript b/source/blender/editors/uvedit/SConscript
index d236b18a8fd..dfa15d2de4f 100644
--- a/source/blender/editors/uvedit/SConscript
+++ b/source/blender/editors/uvedit/SConscript
@@ -1,10 +1,41 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
+defs = []
+
sources = env.Glob('*.c')
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenfont ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../bmesh ../../makesrna #/intern/opennl/extern ../../gpu ../../blenloader'
-env.BlenderLib ( 'bf_editors_uvedit', sources, Split(incs), [], libtype=['core'], priority=[45] )
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
+env.BlenderLib ( 'bf_editors_uvedit', sources, Split(incs), defs, libtype=['core'], priority=[45] )
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index 1c32c01b8f0..5c188628978 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -43,6 +43,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
@@ -152,8 +154,10 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
}
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_UVEDIT_VERTEX, "X:", 10, 10, 145, 19, &uvedit_old_center[0], -10 * imx, 10.0 * imx, step, digits, "");
- uiDefButF(block, NUM, B_UVEDIT_VERTEX, "Y:", 165, 10, 145, 19, &uvedit_old_center[1], -10 * imy, 10.0 * imy, step, digits, "");
+ uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 10, 10, 145, 19, &uvedit_old_center[0],
+ -10 * imx, 10.0 * imx, step, digits, "");
+ uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("Y:"), 165, 10, 145, 19, &uvedit_old_center[1],
+ -10 * imy, 10.0 * imy, step, digits, "");
uiBlockEndAlign(block);
}
}
@@ -214,7 +218,7 @@ void ED_uvedit_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
strcpy(pt->idname, "IMAGE_PT_uv");
- strcpy(pt->label, "UV Vertex");
+ strcpy(pt->label, N_("UV Vertex")); /* XXX C panels are not available through RNA (bpy.types)! */
pt->draw = image_panel_uv;
pt->poll = image_panel_uv_poll;
BLI_addtail(&art->paneltypes, pt);
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 9c2c300c530..ea7e17af086 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -60,48 +60,49 @@
#include "ED_uvedit.h"
#include "UI_resources.h"
+#include "UI_interface.h"
+#include "UI_view2d.h"
#include "uvedit_intern.h"
void draw_image_cursor(SpaceImage *sima, ARegion *ar)
{
- float zoomx, zoomy, w, h;
- int width, height;
+ float zoom[2], x_fac, y_fac;
- ED_space_image_get_size(sima, &width, &height);
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ UI_view2d_getscale_inverse(&ar->v2d, &zoom[0], &zoom[1]);
- w = zoomx * width / 256.0f;
- h = zoomy * height / 256.0f;
+ mul_v2_fl(zoom, 256.0f * UI_DPI_FAC);
+ x_fac = zoom[0];
+ y_fac = zoom[1];
cpack(0xFFFFFF);
glTranslatef(sima->cursor[0], sima->cursor[1], 0.0);
- fdrawline(-0.05f / w, 0, 0, 0.05f / h);
- fdrawline(0, 0.05f / h, 0.05f / w, 0.0f);
- fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h);
- fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f);
+ fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac);
+ fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f);
+ fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac);
+ fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f);
setlinestyle(4);
cpack(0xFF);
- fdrawline(-0.05f / w, 0.0f, 0.0f, 0.05f / h);
- fdrawline(0.0f, 0.05f / h, 0.05f / w, 0.0f);
- fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h);
- fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f);
+ fdrawline(-0.05f * x_fac, 0.0f, 0.0f, 0.05f * y_fac);
+ fdrawline(0.0f, 0.05f * y_fac, 0.05f * x_fac, 0.0f);
+ fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac);
+ fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f);
setlinestyle(0.0f);
cpack(0x0);
- fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f);
- fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f);
- fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h);
- fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h);
+ fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f);
+ fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f);
+ fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac);
+ fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac);
setlinestyle(1);
cpack(0xFFFFFF);
- fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f);
- fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f);
- fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h);
- fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h);
+ fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f);
+ fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f);
+ fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac);
+ fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac);
glTranslatef(-sima->cursor[0], -sima->cursor[1], 0.0);
setlinestyle(0);
@@ -133,14 +134,15 @@ static void draw_uvs_shadow(Object *obedit)
BMIter iter, liter;
MLoopUV *luv;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
/* draws the gray mesh when painting */
glColor3ub(112, 112, 112);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
glBegin(GL_LINE_LOOP);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
-
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -169,10 +171,11 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
MTexPoly *tf;
MLoopUV *luv;
Image *ima = sima->image;
- BLI_array_declare(tf_uv);
- BLI_array_declare(tf_uvorig);
- float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL;
- int i, j, nverts;
+ float aspx, aspy, col[4];
+ int i;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
@@ -182,27 +185,20 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
float totarea = 0.0f, totuvarea = 0.0f, areadiff, uvarea, area;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
-
- BLI_array_empty(tf_uv);
- BLI_array_empty(tf_uvorig);
- BLI_array_grow_items(tf_uv, efa->len);
- BLI_array_grow_items(tf_uvorig, efa->len);
-
- i = 0;
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ const int efa_len = efa->len;
+ float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
+ float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
copy_v2_v2(tf_uvorig[i], luv->uv);
-
- i++;
}
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
totarea += BM_face_calc_area(efa);
- //totuvarea += tf_area(tf, efa->v4!=0);
- totuvarea += uv_poly_area(tf_uv, efa->len);
+ totuvarea += area_poly_v2(efa->len, tf_uv);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -222,7 +218,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
glBegin(GL_POLYGON);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -232,26 +228,20 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
else {
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- area = BM_face_calc_area(efa) / totarea;
-
- BLI_array_empty(tf_uv);
- BLI_array_empty(tf_uvorig);
- BLI_array_grow_items(tf_uv, efa->len);
- BLI_array_grow_items(tf_uvorig, efa->len);
+ const int efa_len = efa->len;
+ float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
+ float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
- i = 0;
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ area = BM_face_calc_area(efa) / totarea;
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
copy_v2_v2(tf_uvorig[i], luv->uv);
-
- i++;
}
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
- //uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
- uvarea = uv_poly_area(tf_uv, efa->len) / totuvarea;
+ uvarea = area_poly_v2(efa->len, tf_uv) / totuvarea;
if (area < FLT_EPSILON || uvarea < FLT_EPSILON)
areadiff = 1.0f;
@@ -265,7 +255,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
glBegin(GL_POLYGON);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -276,68 +266,55 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
}
case SI_UVDT_STRETCH_ANGLE:
{
- float *uvang = NULL;
- float *ang = NULL;
- float (*av)[3] = NULL; /* use for 2d and 3d angle vectors */
- float (*auv)[2] = NULL;
float a;
- BLI_array_declare(uvang);
- BLI_array_declare(ang);
- BLI_array_declare(av);
- BLI_array_declare(auv);
-
- col[3] = 0.5; /* hard coded alpha, not that nice */
+ col[3] = 0.5f; /* hard coded alpha, not that nice */
glShadeModel(GL_SMOOTH);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
- nverts = efa->len;
+ const int efa_len = efa->len;
+ float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
+ float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
+ float *uvang = BLI_array_alloca(uvang, efa_len);
+ float *ang = BLI_array_alloca(ang, efa_len);
+ float (*av)[3] = BLI_array_alloca(av, efa_len); /* use for 2d and 3d angle vectors */
+ float (*auv)[2] = BLI_array_alloca(auv, efa_len);
+ int j;
+
BM_elem_flag_enable(efa, BM_ELEM_TAG);
- BLI_array_empty(tf_uv);
- BLI_array_empty(tf_uvorig);
- BLI_array_empty(uvang);
- BLI_array_empty(ang);
- BLI_array_empty(av);
- BLI_array_empty(auv);
- BLI_array_grow_items(tf_uv, nverts);
- BLI_array_grow_items(tf_uvorig, nverts);
- BLI_array_grow_items(uvang, nverts);
- BLI_array_grow_items(ang, nverts);
- BLI_array_grow_items(av, nverts);
- BLI_array_grow_items(auv, nverts);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
copy_v2_v2(tf_uvorig[i], luv->uv);
}
- uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, nverts);
+ uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa_len);
- j = nverts - 1;
+ j = efa_len - 1;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
sub_v2_v2v2(auv[i], tf_uv[j], tf_uv[i]); normalize_v2(auv[i]);
sub_v3_v3v3(av[i], l->prev->v->co, l->v->co); normalize_v3(av[i]);
j = i;
}
- for (i = 0; i < nverts; i++) {
+ for (i = 0; i < efa_len; i++) {
#if 0
/* Simple but slow, better reuse normalized vectors
* (Not ported to bmesh, copied for reference) */
uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[3], tf_uv[0], tf_uv[1]));
ang1 = RAD2DEG(angle_v3v3v3(efa->v4->co, efa->v1->co, efa->v2->co));
#endif
- uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % nverts]);
- ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % nverts]);
+ uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % efa_len]);
+ ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]);
}
glBegin(GL_POLYGON);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ 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));
glColor3fv(col);
@@ -354,17 +331,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
glShadeModel(GL_FLAT);
- BLI_array_free(uvang);
- BLI_array_free(ang);
- BLI_array_free(av);
- BLI_array_free(auv);
-
break;
}
}
-
- BLI_array_free(tf_uv);
- BLI_array_free(tf_uvorig);
}
static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage)
@@ -453,6 +422,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
int drawfaces, interpedges;
Image *ima = sima->image;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+
activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */
activef = BM_active_face_get(bm, FALSE, FALSE);
ts = scene->toolsettings;
@@ -502,7 +474,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glEnable(GL_BLEND);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -515,7 +487,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBegin(GL_POLYGON);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -532,7 +504,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
/* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -549,7 +521,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
/* 3. draw active face stippled */
if (activef) {
- tf = CustomData_bmesh_get(&bm->pdata, activef->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(activef, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, activef, tf)) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -560,7 +532,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBegin(GL_POLYGON);
BM_ITER_ELEM (l, &liter, activef, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -583,14 +555,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (tf) {
cpack(0x111111);
glBegin(GL_LINE_LOOP);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -600,20 +572,11 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBegin(GL_LINE_LOOP);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
-#if 0
- glBegin(GL_LINE_STRIP);
- luv = CustomData_bmesh_get(&bm->ldata, efa->lbase->head.data, CD_MLOOPUV);
- glVertex2fv(luv->uv);
- luv = CustomData_bmesh_get(&bm->ldata, efa->lbase->next->head.data, CD_MLOOPUV);
- glVertex2fv(luv->uv);
- glEnd();
-#endif
-
setlinestyle(0);
}
}
@@ -629,7 +592,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBegin(GL_LINE_LOOP);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -645,7 +608,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBegin(GL_LINE_LOOP);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -671,7 +634,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
sel = (uvedit_uv_select_test(em, scene, l) ? 1 : 0);
glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2);
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -691,9 +654,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2);
lastsel = sel;
}
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
- luv = CustomData_bmesh_get(&bm->ldata, l->next->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -708,7 +671,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBegin(GL_LINE_LOOP);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
glVertex2fv(luv->uv);
}
glEnd();
@@ -776,7 +739,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (!uvedit_uv_select_test(em, scene, l))
bglVertex2fv(luv->uv);
}
@@ -794,7 +757,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_PINNED)
bglVertex2fv(luv->uv);
@@ -812,7 +775,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (uvedit_uv_select_test(em, scene, l))
bglVertex2fv(luv->uv);
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index b42875f20c2..d1893d639bb 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -50,8 +50,7 @@ struct BMVert;
int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa);
/* geometric utilities */
-float uv_poly_area(float uv[][2], int len);
-void uv_poly_copy_aspect(float uv_orig [][2], float uv[][2], float aspx, float aspy, int len);
+void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len);
void uv_poly_center(struct BMEditMesh *em, struct BMFace *f, float r_cent[2]);
/* find nearest */
@@ -60,7 +59,7 @@ typedef struct NearestHit {
struct BMFace *efa;
struct MTexPoly *tf;
struct BMLoop *l, *nextl;
- struct MLoopUV *luv, *nextluv;
+ struct MLoopUV *luv, *luv_next;
int lindex; //index of loop within face
int vert1, vert2; //index in mesh of edge vertices
} NearestHit;
@@ -73,13 +72,14 @@ 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 */
void UV_OT_average_islands_scale(struct wmOperatorType *ot);
void UV_OT_cube_project(struct wmOperatorType *ot);
void UV_OT_cylinder_project(struct wmOperatorType *ot);
-void UV_OT_from_view(struct wmOperatorType *ot);
+void UV_OT_project_from_view(struct wmOperatorType *ot);
void UV_OT_minimize_stretch(struct wmOperatorType *ot);
void UV_OT_pack_islands(struct wmOperatorType *ot);
void UV_OT_reset(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index a384c777aab..bd2d08729aa 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -199,6 +199,8 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im
else {
BMFace *efa;
+ int cd_poly_tex_offset;
+
/* old shading system, assign image to selected faces */
#ifdef USE_SWITCH_ASPECT
float prev_aspect[2], fprev_aspect;
@@ -220,9 +222,11 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im
update = 1;
}
+ cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
/* now assign to all visible faces */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, previma, efa, tf) &&
(selected == TRUE || uvedit_face_select_test(scene, em, efa)))
@@ -243,7 +247,7 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[0] *= fprev_aspect;
luv->uv[0] /= faspect;
@@ -274,6 +278,7 @@ static int uvedit_set_tile(Object *obedit, Image *ima, int curtile)
BMFace *efa;
BMIter iter;
MTexPoly *tf;
+ int cd_poly_tex_offset;
/* verify if we have something to do */
if (!ima || !ED_uvedit_test(obedit))
@@ -288,10 +293,12 @@ static int uvedit_set_tile(Object *obedit, Image *ima, int curtile)
em = BMEdit_FromObject(obedit);
+ cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT))
+ if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
tf->tile = curtile; /* set tile index */
}
@@ -344,15 +351,18 @@ int uvedit_face_select_test(Scene *scene, BMEditMesh *em, BMFace *efa)
{
ToolSettings *ts = scene->toolsettings;
- if (ts->uv_flag & UV_SYNC_SELECTION)
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
return (BM_elem_flag_test(efa, BM_ELEM_SELECT));
+ }
else {
BMLoop *l;
MLoopUV *luv;
BMIter liter;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /* TODO, pass this on */
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (!(luv->flag & MLOOPUV_VERTSEL))
return 0;
}
@@ -376,8 +386,10 @@ int uvedit_face_select_enable(Scene *scene, BMEditMesh *em, BMFace *efa, const s
MLoopUV *luv;
BMIter liter;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /* TODO, pass this on */
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
@@ -399,8 +411,10 @@ int uvedit_face_select_disable(Scene *scene, BMEditMesh *em, BMFace *efa)
MLoopUV *luv;
BMIter liter;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /* TODO, pass this on */
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag &= ~MLOOPUV_VERTSEL;
}
@@ -503,7 +517,9 @@ int uvedit_uv_select_test(BMEditMesh *em, Scene *scene, BMLoop *l)
return BM_elem_flag_test(l->v, BM_ELEM_SELECT);
}
else {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /* TODO, pass this on */
+
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
return luv->flag & MLOOPUV_VERTSEL;
}
@@ -524,7 +540,8 @@ void uvedit_uv_select_enable(BMEditMesh *em, Scene *scene, BMLoop *l, const shor
}
}
else {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /* TODO, pass this on */
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
@@ -541,7 +558,8 @@ void uvedit_uv_select_disable(BMEditMesh *em, Scene *scene, BMLoop *l)
BM_vert_select_set(em->bm, l->v, FALSE);
}
else {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /* TODO, pass this on */
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag &= ~MLOOPUV_VERTSEL;
}
@@ -565,29 +583,18 @@ void uv_poly_center(BMEditMesh *em, BMFace *f, float r_cent[2])
MLoopUV *luv;
BMIter liter;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); /* TODO, pass this on */
+
zero_v2(r_cent);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
add_v2_v2(r_cent, luv->uv);
}
mul_v2_fl(r_cent, 1.0f / (float)f->len);
}
-float uv_poly_area(float uv[][2], int len)
-{
- //BMESH_TODO: make this not suck
- //maybe use scanfill? I dunno.
-
- if (len >= 4)
- return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]);
- else
- return area_tri_v2(uv[0], uv[1], uv[2]);
-
- return 1.0;
-}
-
void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len)
{
int i;
@@ -607,17 +614,20 @@ int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], f
MLoopUV *luv;
int sel;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
INIT_MINMAX2(r_min, r_max);
sel = 0;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
minmax_v2v2_v2(r_min, r_max, luv->uv);
sel = 1;
}
@@ -637,14 +647,17 @@ static int ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[2
MLoopUV *luv;
unsigned int sel = 0;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
zero_v2(co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (uvedit_uv_select_test(em, scene, l)) {
add_v2_v2(co, luv->uv);
sel++;
@@ -685,26 +698,29 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv, *nextluv;
+ MLoopUV *luv, *luv_next;
float mindist_squared, dist_squared;
int i;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
mindist_squared = 1e10f;
memset(hit, 0, sizeof(*hit));
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
i = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- nextluv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- dist_squared = dist_squared_to_line_segment_v2(co, luv->uv, nextluv->uv);
+ dist_squared = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
if (dist_squared < mindist_squared) {
hit->tf = tf;
@@ -713,7 +729,7 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float
hit->l = l;
hit->nextl = l->next;
hit->luv = luv;
- hit->nextluv = nextluv;
+ hit->luv_next = luv_next;
hit->lindex = i;
hit->vert1 = BM_elem_index_get(hit->l->v);
hit->vert2 = BM_elem_index_get(hit->l->next->v);
@@ -733,16 +749,18 @@ static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, const
BMIter iter;
float mindist, dist, cent[2];
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
mindist = 1e10f;
memset(hit, 0, sizeof(*hit));
/*this will fill in hit.vert1 and hit.vert2*/
uv_find_nearest_edge(scene, ima, em, co, hit);
hit->l = hit->nextl = NULL;
- hit->luv = hit->nextluv = NULL;
+ hit->luv = hit->luv_next = NULL;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
@@ -766,6 +784,7 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i
BMIter iter;
float m[2], v1[2], v2[2], c1, c2, *uv1 = NULL, /* *uv2, */ /* UNUSED */ *uv3 = NULL;
int id1, id2, i;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
id1 = (id + efa->len - 1) % efa->len;
id2 = (id + efa->len + 1) % efa->len;
@@ -774,7 +793,7 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i
i = 0;
BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (i == id1) {
uv1 = luv->uv;
@@ -816,10 +835,13 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
float mindist, dist;
int i;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
/*this will fill in hit.vert1 and hit.vert2*/
uv_find_nearest_edge(scene, ima, em, co, hit);
hit->l = hit->nextl = NULL;
- hit->luv = hit->nextluv = NULL;
+ hit->luv = hit->luv_next = NULL;
mindist = 1e10f;
memset(hit, 0, sizeof(*hit));
@@ -827,13 +849,13 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
i = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (penalty && uvedit_uv_select_test(em, scene, l))
dist = fabsf(co[0] - luv->uv[0]) + penalty[0] + fabsf(co[1] - luv->uv[1]) + penalty[1];
@@ -852,7 +874,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em,
hit->l = l;
hit->nextl = l->next;
hit->luv = luv;
- hit->nextluv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
+ hit->luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
hit->tf = tf;
hit->efa = efa;
hit->lindex = i;
@@ -875,16 +897,19 @@ int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float c
float mindist, dist;
int found = FALSE;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
mindist = 1e10f;
copy_v2_v2(r_uv, co);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
dist = fabsf(co[0] - luv->uv[0]) + fabsf(co[1] - luv->uv[1]);
if (dist <= mindist) {
@@ -998,9 +1023,11 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit
UvMapVert *iterv1, *iterv2;
int a, looking, nverts, starttotf, select;
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
/* setup */
- EDBM_index_arrays_init(em, 0, 0, 1);
- vmap = EDBM_uv_vert_map_create(em, 0, 0, limit);
+ EDBM_index_arrays_ensure(em, BM_FACE);
+ vmap = EDBM_uv_vert_map_create(em, 0, limit);
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
@@ -1031,7 +1058,7 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit
/* find correct valence edges which are not tagged yet, but connect to tagged one */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, ima, efa, tf)) {
nverts = efa->len;
@@ -1091,7 +1118,6 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit
/* cleanup */
EDBM_uv_vert_map_free(vmap);
- EDBM_index_arrays_free(em);
return (select) ? 1 : -1;
}
@@ -1111,8 +1137,11 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
unsigned int a;
char *flag;
- EDBM_index_arrays_init(em, 0, 0, 1); /* we can use this too */
- vmap = EDBM_uv_vert_map_create(em, 1, 1, limit);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
+ EDBM_index_arrays_ensure(em, BM_FACE); /* we can use this too */
+ vmap = EDBM_uv_vert_map_create(em, 1, limit);
if (vmap == NULL)
return;
@@ -1122,11 +1151,11 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
if (!hit) {
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_VERTSEL) {
stack[stacksize] = a;
@@ -1200,7 +1229,7 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
a = 0;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (flag[a])
luv->flag |= MLOOPUV_VERTSEL;
@@ -1219,7 +1248,7 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_VERTSEL)
break;
@@ -1240,7 +1269,7 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag &= ~MLOOPUV_VERTSEL;
}
@@ -1257,7 +1286,7 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
@@ -1270,7 +1299,6 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
MEM_freeN(stack);
MEM_freeN(flag);
EDBM_uv_vert_map_free(vmap);
- EDBM_index_arrays_free(em);
}
/* WATCH IT: this returns first selected UV,
@@ -1280,14 +1308,17 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer
BMIter liter;
BMLoop *l;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- MTexPoly *tf = CustomData_bmesh_get(&em->bm->pdata, l->f->head.data, CD_MTEXPOLY);
+ MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, l->f, tf))
continue;
if (uvedit_uv_select_test(em, scene, l)) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
return luv->uv;
}
}
@@ -1299,17 +1330,18 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer
static void weld_align_uv(bContext *C, int tool)
{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
SpaceImage *sima;
Scene *scene;
- Object *obedit;
Image *ima;
- BMEditMesh *em;
MTexPoly *tf;
float cent[2], min[2], max[2];
-
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
scene = CTX_data_scene(C);
- obedit = CTX_data_edit_object(C);
- em = BMEdit_FromObject(obedit);
ima = CTX_data_edit_image(C);
sima = CTX_wm_space_image(C);
@@ -1321,14 +1353,14 @@ static void weld_align_uv(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
minmax_v2v2_v2(min, max, luv->uv);
}
}
@@ -1345,13 +1377,13 @@ static void weld_align_uv(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[0] = cent[0];
}
@@ -1365,13 +1397,13 @@ static void weld_align_uv(bContext *C, int tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[1] = cent[1];
}
@@ -1394,7 +1426,7 @@ static void weld_align_uv(bContext *C, int tool)
/* tag verts with a selected UV */
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- tf = CustomData_bmesh_get(&em->bm->pdata, l->f->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, l->f, tf))
continue;
@@ -1484,13 +1516,13 @@ static void weld_align_uv(bContext *C, int tool)
/* go over all verts except for endpoints */
for (i = 0; i < BLI_array_count(eve_line); i++) {
BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
- tf = CustomData_bmesh_get(&em->bm->pdata, l->f->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, l->f, tf))
continue;
if (uvedit_uv_select_test(em, scene, l)) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
/* Projection of point (x, y) over line (x1, y1, x2, y2) along X axis:
* new_y = (y2 - y1) / (x2 - x1) * (x - x1) + y1
* Maybe this should be a BLI func? Or is it already existing?
@@ -1550,7 +1582,7 @@ static void UV_OT_align(wmOperatorType *ot)
/* api callbacks */
ot->exec = align_exec;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
/* properties */
RNA_def_enum(ot->srna, "axis", axis_items, 'a', "Axis", "Axis to align UV locations on");
@@ -1569,9 +1601,9 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
SpaceImage *sima;
Scene *scene;
- Object *obedit;
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
Image *ima;
- BMEditMesh *em;
MTexPoly *tf;
int uv_a_index;
int uv_b_index;
@@ -1582,10 +1614,11 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
sima = CTX_wm_space_image(C);
scene = CTX_data_scene(C);
- obedit = CTX_data_edit_object(C);
- em = BMEdit_FromObject(obedit);
ima = CTX_data_edit_image(C);
if (use_unselected == FALSE) {
@@ -1596,13 +1629,13 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
/* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
UVvert vert;
vert.uv_loop = luv;
vert.weld = FALSE;
@@ -1659,12 +1692,12 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
BLI_array_declare(loop_arr_unselected);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (uvedit_uv_select_test(em, scene, l)) {
BLI_array_append(loop_arr, luv);
}
@@ -1753,6 +1786,9 @@ static void select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int act
MTexPoly *tf;
MLoopUV *luv;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
if (ts->uv_flag & UV_SYNC_SELECTION) {
switch (action) {
@@ -1775,13 +1811,13 @@ static void select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int act
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_VERTSEL) {
action = SEL_DESELECT;
@@ -1793,13 +1829,13 @@ static void select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int act
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
switch (action) {
case SEL_SELECT:
@@ -1894,6 +1930,9 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop)
BLI_array_declare(hituv);
float penalty[2];
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
/* notice 'limit' is the same no matter the zoom level, since this is like
* remove doubles and could annoying if it joined points when zoomed out.
* 'penalty' is in screen pixel space otherwise zooming in on a uv-vert and
@@ -1972,7 +2011,7 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop)
hitv[hit.lindex] = hit.vert1;
hitv[(hit.lindex + 1) % hit.efa->len] = hit.vert2;
hituv[hit.lindex] = hit.luv->uv;
- hituv[(hit.lindex + 1) % hit.efa->len] = hit.nextluv->uv;
+ hituv[(hit.lindex + 1) % hit.efa->len] = hit.luv_next->uv;
hitlen = hit.efa->len;
}
@@ -1994,7 +2033,7 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop)
BLI_array_grow_items(hituv, hit.efa->len);
i = 0;
BM_ITER_ELEM (l, &liter, hit.efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
hituv[i] = luv->uv;
hitv[i] = BM_elem_index_get(l->v);
i++;
@@ -2080,12 +2119,12 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop)
/* deselect */
if (select == 0) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (sticky_select(limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen))
uvedit_uv_select_disable(em, scene, l);
}
@@ -2095,12 +2134,12 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop)
/* select */
else {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (sticky_select(limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen))
uvedit_uv_select_enable(em, scene, l, FALSE);
}
@@ -2132,13 +2171,13 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop)
/* select sticky uvs */
if (sticky != SI_STICKY_DISABLE) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (sticky == SI_STICKY_DISABLE) continue;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (sticky_select(limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen))
uvedit_uv_select_enable(em, scene, l, FALSE);
@@ -2219,7 +2258,7 @@ static void UV_OT_select(wmOperatorType *ot)
/* api callbacks */
ot->exec = select_exec;
ot->invoke = select_invoke;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
/* properties */
RNA_def_boolean(ot->srna, "extend", 0,
@@ -2264,7 +2303,7 @@ static void UV_OT_select_loop(wmOperatorType *ot)
/* api callbacks */
ot->exec = select_loop_exec;
ot->invoke = select_loop_invoke;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
/* properties */
RNA_def_boolean(ot->srna, "extend", 0,
@@ -2338,7 +2377,7 @@ static void UV_OT_select_linked(wmOperatorType *ot)
/* api callbacks */
ot->exec = select_linked_exec;
- ot->poll = ED_operator_image_active; /* requires space image */
+ ot->poll = ED_operator_uvedit; /* requires space image */
/* properties */
RNA_def_boolean(ot->srna, "extend", 0,
@@ -2366,7 +2405,7 @@ static void UV_OT_select_linked_pick(wmOperatorType *ot)
/* api callbacks */
ot->invoke = select_linked_pick_invoke;
ot->exec = select_linked_pick_exec;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
/* properties */
RNA_def_boolean(ot->srna, "extend", 0,
@@ -2395,23 +2434,27 @@ static int select_split_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
short change = FALSE;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+
if (ts->uv_flag & UV_SYNC_SELECTION) {
BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled");
return OPERATOR_CANCELLED;
}
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
int is_sel = FALSE;
int is_unsel = FALSE;
- tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
/* are we all selected? */
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_VERTSEL) {
is_sel = TRUE;
@@ -2428,7 +2471,7 @@ static int select_split_exec(bContext *C, wmOperator *op)
if (is_sel && is_unsel) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag &= ~MLOOPUV_VERTSEL;
}
@@ -2474,6 +2517,9 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
MTexPoly *tf;
MLoopUV *luv;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
if (ts->uv_flag & UV_SYNC_SELECTION) {
BKE_report(op->reports, RPT_ERROR, "Cannot unlink selection when sync selection is enabled");
return OPERATOR_CANCELLED;
@@ -2482,12 +2528,12 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int desel = 0;
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (!(luv->flag & MLOOPUV_VERTSEL)) {
desel = 1;
@@ -2497,7 +2543,7 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
if (desel) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag &= ~MLOOPUV_VERTSEL;
}
}
@@ -2584,7 +2630,7 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
/* now select tagged verts */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
+ /* tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); */ /* UNUSED */
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
@@ -2608,8 +2654,8 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
uvedit_pixel_to_float(sima, limit, 0.05);
- EDBM_index_arrays_init(em, 0, 0, 1);
- vmap = EDBM_uv_vert_map_create(em, 0, 0, limit);
+ EDBM_index_arrays_ensure(em, BM_FACE);
+ vmap = EDBM_uv_vert_map_create(em, 0, limit);
/* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */
if (vmap == NULL) {
@@ -2619,7 +2665,7 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
for (efa_index = 0; efa; efa = BM_iter_step(&iter), efa_index++) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
+ /* tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); */ /* UNUSED */
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (select)
@@ -2648,7 +2694,7 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
if (efa_index != vlist_iter->f) {
BMLoop *l_other;
efa_vlist = EDBM_face_at_index(em, vlist_iter->f);
- /* tf_vlist = CustomData_bmesh_get(&em->bm->pdata, efa_vlist->head.data, CD_MTEXPOLY); */ /* UNUSED */
+ /* tf_vlist = BM_ELEM_CD_GET_VOID_P(efa_vlist, cd_poly_tex_offset); */ /* UNUSED */
l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex);
@@ -2662,7 +2708,6 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
}
}
}
- EDBM_index_arrays_free(em);
EDBM_uv_vert_map_free(vmap);
}
@@ -2701,6 +2746,9 @@ static int border_select_exec(bContext *C, wmOperator *op)
(ts->selectmode == SCE_SELECT_FACE) :
(ts->uv_selectmode == UV_SELECT_FACE);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
/* get rectangle from operator */
WM_operator_properties_border_to_rcti(op, &rect);
@@ -2726,7 +2774,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
/* assume not touched */
BM_elem_flag_disable(efa, BM_ELEM_TAG);
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
uv_poly_center(em, efa, cent);
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
@@ -2746,11 +2794,11 @@ static int border_select_exec(bContext *C, wmOperator *op)
change = 1;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION) ) {
@@ -2794,7 +2842,7 @@ static void UV_OT_select_border(wmOperatorType *ot)
ot->invoke = WM_border_select_invoke;
ot->exec = border_select_exec;
ot->modal = WM_border_select_modal;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
ot->cancel = WM_border_select_cancel;
/* flags */
@@ -2850,6 +2898,8 @@ static int circle_select_exec(bContext *C, wmOperator *op)
(ts->selectmode == SCE_SELECT_FACE) :
(ts->uv_selectmode == UV_SELECT_FACE);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
/* get operator properties */
select = (gesture_mode == GESTURE_MODAL_SELECT);
x = RNA_int_get(op->ptr, "x");
@@ -2890,7 +2940,7 @@ static int circle_select_exec(bContext *C, wmOperator *op)
else {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
change |= select_uv_inside_ellipse(em, scene, select, offset, ellipse, l, luv);
}
}
@@ -2916,7 +2966,7 @@ static void UV_OT_circle_select(wmOperatorType *ot)
ot->invoke = WM_gesture_circle_invoke;
ot->modal = WM_gesture_circle_modal;
ot->exec = circle_select_exec;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
ot->cancel = WM_gesture_circle_cancel;
/* flags */
@@ -2945,6 +2995,9 @@ static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mov
(ts->selectmode == SCE_SELECT_FACE) :
(ts->uv_selectmode == UV_SELECT_FACE);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
BMIter iter, liter;
BMFace *efa;
@@ -2980,11 +3033,11 @@ static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mov
}
else { /* Vert Sel */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if ((select) != (uvedit_uv_select_test(em, scene, l))) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
UI_view2d_view_to_region(&ar->v2d, luv->uv[0], luv->uv[1], &screen_uv[0], &screen_uv[1]);
if (BLI_rcti_isect_pt_v(&rect, screen_uv) &&
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
@@ -3042,7 +3095,7 @@ static void UV_OT_select_lasso(wmOperatorType *ot)
ot->invoke = WM_gesture_lasso_invoke;
ot->modal = WM_gesture_lasso_modal;
ot->exec = uv_lasso_select_exec;
- ot->poll = ED_operator_image_active;
+ ot->poll = ED_operator_uvedit;
ot->cancel = WM_gesture_lasso_cancel;
/* flags */
@@ -3117,7 +3170,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot)
/* api callbacks */
ot->exec = snap_cursor_exec;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
/* properties */
RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UVs to");
@@ -3135,14 +3188,17 @@ static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, SpaceIma
MLoopUV *luv;
short change = 0;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
copy_v2_v2(luv->uv, sima->cursor);
change = 1;
}
@@ -3162,11 +3218,13 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
MTexPoly *tface;
MLoopUV *luv;
short change = FALSE;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
/* index every vert that has a selected UV using it, but only once so as to
* get unique indices and to count how much to malloc */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- tface = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_MTEXPOLY);
+ tface = BM_ELEM_CD_GET_VOID_P(f, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, f, tface)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -3189,15 +3247,14 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
if (BM_elem_flag_test(lsub->f, BM_ELEM_TAG) && /* face: visible */
!BM_elem_flag_test(lsub, BM_ELEM_TAG)) /* loop: unselected */
{
-
- luv = CustomData_bmesh_get(&bm->ldata, lsub->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(lsub, cd_loop_uv_offset);
add_v2_v2(uv, luv->uv);
uv_tot++;
}
}
if (uv_tot) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
mul_v2_v2fl(luv->uv, uv, 1.0f / (float)uv_tot);
change = TRUE;
}
@@ -3222,18 +3279,21 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
float w, h;
short change = 0;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
ED_space_image_get_size(sima, &width, &height);
w = (float)width;
h = (float)height;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
snap_uv_to_pixel(luv->uv, w, h);
}
}
@@ -3290,7 +3350,7 @@ static void UV_OT_snap_selected(wmOperatorType *ot)
/* api callbacks */
ot->exec = snap_selection_exec;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
/* properties */
RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UVs to");
@@ -3311,13 +3371,16 @@ static int pin_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
int clear = RNA_boolean_get(op->ptr, "clear");
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (!clear) {
if (uvedit_uv_select_test(em, scene, l))
@@ -3365,13 +3428,16 @@ static int select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
MTexPoly *tface;
MLoopUV *luv;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tface = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tface))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (luv->flag & MLOOPUV_PINNED)
uvedit_uv_select_enable(em, scene, l, FALSE);
@@ -3403,15 +3469,17 @@ static void UV_OT_select_pinned(wmOperatorType *ot)
#define UV_SEL_TEST(luv, bool_test) ((((luv)->flag & MLOOPUV_VERTSEL) == MLOOPUV_VERTSEL) == bool_test)
/* is every UV vert selected or unselected depending on bool_test */
-static int bm_face_is_all_uv_sel(BMesh *bm, BMFace *f, int bool_test)
+static int bm_face_is_all_uv_sel(BMFace *f, bool select_test,
+ const int cd_loop_uv_offset)
{
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- MLoopUV *luv = CustomData_bmesh_get(&bm->ldata, l_iter->head.data, CD_MLOOPUV);
- if (!UV_SEL_TEST(luv, bool_test)) {
+
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
+ if (!UV_SEL_TEST(luv, select_test)) {
return FALSE;
}
} while ((l_iter = l_iter->next) != l_first);
@@ -3435,6 +3503,9 @@ static int hide_exec(bContext *C, wmOperator *op)
Image *ima = sima ? sima->image : NULL;
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
if (ts->uv_flag & UV_SYNC_SELECTION) {
EDBM_mesh_hide(em, swap);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -3445,14 +3516,14 @@ static int hide_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int hide = 0;
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
if (!uvedit_face_visible_test(scene, ima, efa, tf)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (UV_SEL_TEST(luv, !swap)) {
hide = 1;
@@ -3466,15 +3537,15 @@ static int hide_exec(bContext *C, wmOperator *op)
if (use_face_center) {
if (em->selectmode == SCE_SELECT_FACE) {
/* check that every UV is selected */
- if (bm_face_is_all_uv_sel(em->bm, efa, TRUE) == !swap) {
+ if (bm_face_is_all_uv_sel(efa, true, cd_loop_uv_offset) == !swap) {
BM_face_select_set(em->bm, efa, FALSE);
}
uvedit_face_select_disable(scene, em, efa);
}
else {
- if (bm_face_is_all_uv_sel(em->bm, efa, TRUE) == !swap) {
+ if (bm_face_is_all_uv_sel(efa, true, cd_loop_uv_offset) == !swap) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (UV_SEL_TEST(luv, !swap)) {
BM_vert_select_set(em->bm, l->v, FALSE);
}
@@ -3485,14 +3556,14 @@ static int hide_exec(bContext *C, wmOperator *op)
}
else if (em->selectmode == SCE_SELECT_FACE) {
/* check if a UV is de-selected */
- if (bm_face_is_all_uv_sel(em->bm, efa, FALSE) != !swap) {
+ if (bm_face_is_all_uv_sel(efa, false, cd_loop_uv_offset) != !swap) {
BM_face_select_set(em->bm, efa, FALSE);
uvedit_face_select_disable(scene, em, efa);
}
}
else {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (UV_SEL_TEST(luv, !swap)) {
BM_vert_select_set(em->bm, l->v, FALSE);
if (!swap) luv->flag &= ~MLOOPUV_VERTSEL;
@@ -3546,6 +3617,8 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
const int stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
/* note on tagging, selecting faces needs to be delayed so it doesn't select the verts and
* confuse our checks on selected verts. */
@@ -3562,7 +3635,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
BM_elem_flag_disable(efa, BM_ELEM_TAG);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
/* BM_face_select_set(em->bm, efa, TRUE); */
@@ -3583,7 +3656,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
if (!totsel) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
/* BM_face_select_set(em->bm, efa, TRUE); */
@@ -3598,7 +3671,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT) == 0) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
}
@@ -3614,7 +3687,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
BM_elem_flag_disable(efa, BM_ELEM_TAG);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
/* BM_face_select_set(em->bm, efa, TRUE); */
@@ -3628,7 +3701,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT) == 0) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
}
@@ -3696,7 +3769,7 @@ static void UV_OT_cursor_set(wmOperatorType *ot)
/* api callbacks */
ot->exec = set_2d_cursor_exec;
ot->invoke = set_2d_cursor_invoke;
- ot->poll = ED_operator_image_active; /* requires space image */;
+ ot->poll = ED_operator_uvedit; /* requires space image */;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3795,8 +3868,8 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op)
}
/* This code sets editvert->tmp.l to the index. This will be useful later on. */
- EDBM_index_arrays_init(em, 0, 0, 1);
- vmap = EDBM_uv_vert_map_create(em, 0, 0, limit);
+ EDBM_index_arrays_ensure(em, BM_FACE);
+ vmap = EDBM_uv_vert_map_create(em, 0, limit);
BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) {
/* flags to determine if we uv is separated from first editface match */
@@ -3875,7 +3948,6 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op)
me->drawflag |= ME_DRAWSEAMS;
EDBM_uv_vert_map_free(vmap);
- EDBM_index_arrays_free(em);
DAG_id_tag_update(&me->id, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
@@ -3981,7 +4053,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_average_islands_scale);
WM_operatortype_append(UV_OT_cube_project);
WM_operatortype_append(UV_OT_cylinder_project);
- WM_operatortype_append(UV_OT_from_view);
+ WM_operatortype_append(UV_OT_project_from_view);
WM_operatortype_append(UV_OT_minimize_stretch);
WM_operatortype_append(UV_OT_pack_islands);
WM_operatortype_append(UV_OT_reset);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 8703234122a..bf5fc9a3021 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -60,6 +60,7 @@
{ /*printf("Assertion %s:%d\n", __FILE__, __LINE__); abort();*/ } (void)0
#define param_warning(message) \
{ /*printf("Warning %s:%d: %s\n", __FILE__, __LINE__, message);*/ } (void)0
+#if 0
#define param_test_equals_ptr(str, a, b) \
if (a != b) \
{ /*printf("Equals %s => %p != %p\n", str, a, b);*/ } (void)0
@@ -67,6 +68,7 @@
if (a != b) \
{ /*printf("Equals %s => %d != %d\n", str, a, b);*/ } (void)0
#endif
+#endif
typedef enum PBool {
P_TRUE = 1,
P_FALSE = 0
@@ -707,7 +709,7 @@ static void p_face_restore_uvs(PFace *f)
static PVert *p_vert_add(PHandle *handle, PHashKey key, const float co[3], PEdge *e)
{
- PVert *v = (PVert *)BLI_memarena_alloc(handle->arena, sizeof *v);
+ PVert *v = (PVert *)BLI_memarena_alloc(handle->arena, sizeof(*v));
copy_v3_v3(v->co, co);
v->u.key = key;
v->edge = e;
@@ -730,7 +732,7 @@ static PVert *p_vert_lookup(PHandle *handle, PHashKey key, const float co[3], PE
static PVert *p_vert_copy(PChart *chart, PVert *v)
{
- PVert *nv = (PVert *)BLI_memarena_alloc(chart->handle->arena, sizeof *nv);
+ PVert *nv = (PVert *)BLI_memarena_alloc(chart->handle->arena, sizeof(*nv));
copy_v3_v3(nv->co, v->co);
nv->uv[0] = v->uv[0];
@@ -784,7 +786,7 @@ static int p_face_exists(ParamHandle *phandle, ParamKey *pvkeys, int i1, int i2,
static PChart *p_chart_new(PHandle *handle)
{
- PChart *chart = (PChart *)MEM_callocN(sizeof *chart, "PChart");
+ PChart *chart = (PChart *)MEM_callocN(sizeof(*chart), "PChart");
chart->handle = handle;
return chart;
@@ -902,7 +904,7 @@ static PBool p_edge_connect_pair(PHandle *handle, PEdge *e, PEdge ***stack, PBoo
static int p_connect_pairs(PHandle *handle, PBool impl)
{
- PEdge **stackbase = MEM_mallocN(sizeof *stackbase * phash_size(handle->hash_faces), "Pstackbase");
+ PEdge **stackbase = MEM_mallocN(sizeof(*stackbase) * phash_size(handle->hash_faces), "Pstackbase");
PEdge **stack = stackbase;
PFace *f, *first;
PEdge *e, *e1, *e2;
@@ -997,7 +999,7 @@ static void p_split_vert(PChart *chart, PEdge *e)
static PChart **p_split_charts(PHandle *handle, PChart *chart, int ncharts)
{
- PChart **charts = MEM_mallocN(sizeof *charts * ncharts, "PCharts"), *nchart;
+ PChart **charts = MEM_mallocN(sizeof(*charts) * ncharts, "PCharts"), *nchart;
PFace *f, *nextf;
int i;
@@ -1039,12 +1041,12 @@ static PFace *p_face_add(PHandle *handle)
PEdge *e1, *e2, *e3;
/* allocate */
- f = (PFace *)BLI_memarena_alloc(handle->arena, sizeof *f);
+ f = (PFace *)BLI_memarena_alloc(handle->arena, sizeof(*f));
f->flag = 0; /* init ! */
- e1 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof *e1);
- e2 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof *e2);
- e3 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof *e3);
+ e1 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof(*e1));
+ e2 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof(*e2));
+ e3 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof(*e3));
/* set up edges */
f->edge = e1;
@@ -1057,7 +1059,7 @@ static PFace *p_face_add(PHandle *handle)
e1->pair = NULL;
e2->pair = NULL;
e3->pair = NULL;
-
+
e1->flag = 0;
e2->flag = 0;
e3->flag = 0;
@@ -3047,6 +3049,8 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
PVert *v, *pin1 = chart->u.lscm.pin1, *pin2 = chart->u.lscm.pin2;
PFace *f;
float *alpha = chart->u.lscm.abf_alpha;
+ float area_pinned_up, area_pinned_down;
+ bool flip_faces;
int row;
nlMakeCurrent(chart->u.lscm.context);
@@ -3085,6 +3089,26 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
}
}
+ /* detect up direction based on pinned vertices */
+ area_pinned_up = 0.0f;
+ area_pinned_down = 0.0f;
+
+ for (f = chart->faces; f; f = f->nextlink) {
+ PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
+ PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert;
+
+ if ((v1->flag & PVERT_PIN) && (v2->flag & PVERT_PIN) && (v3->flag & PVERT_PIN)) {
+ float area = p_face_uv_area_signed(f);
+
+ if (area > 0.0f)
+ area_pinned_up += area;
+ else
+ area_pinned_down -= area;
+ }
+ }
+
+ flip_faces = (area_pinned_down > area_pinned_up);
+
/* construct matrix */
nlBegin(NL_MATRIX);
@@ -3105,11 +3129,17 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
else
p_face_angles(f, &a1, &a2, &a3);
+ if (flip_faces) {
+ SWAP(float, a2, a3);
+ SWAP(PEdge *, e2, e3);
+ SWAP(PVert *, v2, v3);
+ }
+
sina1 = sin(a1);
sina2 = sin(a2);
sina3 = sin(a3);
- sinmax = MAX3(sina1, sina2, sina3);
+ sinmax = max_fff(sina1, sina2, sina3);
/* shift vertices to find most stable order */
if (sina3 != sinmax) {
@@ -3644,7 +3674,7 @@ static PBool p_triangle_inside(SmoothTriangle *t, float co[2])
static SmoothNode *p_node_new(MemArena *arena, SmoothTriangle **tri, int ntri, float *bmin, float *bmax, int depth)
{
- SmoothNode *node = BLI_memarena_alloc(arena, sizeof *node);
+ SmoothNode *node = BLI_memarena_alloc(arena, sizeof(*node));
int axis, i, t1size = 0, t2size = 0;
float split, /* mi, */ /* UNUSED */ mx;
SmoothTriangle **t1, **t2, *t;
@@ -4084,7 +4114,7 @@ static void p_smooth(PChart *chart)
ParamHandle *param_construct_begin(void)
{
- PHandle *handle = MEM_callocN(sizeof *handle, "PHandle");
+ PHandle *handle = MEM_callocN(sizeof(*handle), "PHandle");
handle->construction_chart = p_chart_new(handle);
handle->state = PHANDLE_STATE_ALLOCATED;
handle->arena = BLI_memarena_new((1 << 16), "param construct arena");
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 4ca642690c4..5bb8105cd14 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -72,7 +72,7 @@
/* ********************** smart stitch operator *********************** */
-/* object that stores display data for previewing before accepting stitching */
+/* object that stores display data for previewing before confirming stitching */
typedef struct StitchPreviewer {
/* here we'll store the preview triangle indices of the mesh */
float *preview_polys;
@@ -87,7 +87,7 @@ typedef struct StitchPreviewer {
unsigned int num_stitchable;
unsigned int num_unstitchable;
unsigned int preview_uvs;
- /* ...and here we'll store the triangles*/
+ /* ...and here we'll store the static island triangles*/
float *static_tris;
unsigned int num_static_tris;
} StitchPreviewer;
@@ -100,11 +100,13 @@ struct IslandStitchData;
typedef struct IslandStitchData {
/* rotation can be used only for edges, for vertices there is no such notion */
float rotation;
+ float rotation_neg;
float translation[2];
/* Used for rotation, the island will rotate around this point */
float medianPoint[2];
int numOfElements;
int num_rot_elements;
+ int num_rot_elements_neg;
/* flag to remember if island has been added for preview */
char addedForPreview;
/* flag an island to be considered for determining static island */
@@ -124,14 +126,19 @@ typedef struct UvEdge {
unsigned int uv1;
unsigned int uv2;
/* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */
- char flag;
- /* element that guarantees element->face has the face on element->tfindex and element->tfindex+1 is the second uv */
+ unsigned char flag;
+ /* element that guarantees element->face has the edge on element->tfindex and element->tfindex+1 is the second uv */
UvElement *element;
+ /* next uv edge with the same exact vertices as this one.. Calculated at startup to save time */
+ struct UvEdge *next;
+ /* point to first of common edges. Needed for iteration */
+ struct UvEdge *first;
} UvEdge;
/* stitch state object */
typedef struct StitchState {
+ float aspect;
/* use limit flag */
char use_limit;
/* limit to operator, same as original operator */
@@ -156,19 +163,26 @@ typedef struct StitchState {
float *normals;
/* edge storage */
UvEdge *edges;
+ /* hash for quick lookup of edges */
+ GHash *edge_hash;
/* count of separate uvs and edges */
- int total_boundary_edges;
+ int total_separate_edges;
int total_separate_uvs;
/* hold selection related information */
- UvElement **selection_stack;
+ void **selection_stack;
int selection_size;
/* island that stays in place */
int static_island;
/* store number of primitives per face so that we can allocate the active island buffer later */
unsigned int *tris_per_island;
+ /* vert or edge mode used for stitching */
+ char mode;
+ /* handle for drawing */
void *draw_handle;
+ /* preview data */
+ StitchPreviewer *stitch_preview;
} StitchState;
typedef struct PreviewPosition {
@@ -176,7 +190,7 @@ typedef struct PreviewPosition {
int polycount_position;
} PreviewPosition;
/*
- * defines for UvElement flags
+ * defines for UvElement/UcEdge flags
*/
#define STITCH_SELECTED 1
#define STITCH_STITCHABLE 2
@@ -186,83 +200,79 @@ typedef struct PreviewPosition {
#define STITCH_NO_PREVIEW -1
-/* previewer stuff (see uvedit_intern.h for more info) */
-static StitchPreviewer *_stitch_preview;
+enum StitchModes {
+ STITCH_VERT,
+ STITCH_EDGE
+};
/* constructor */
static StitchPreviewer *stitch_preview_init(void)
{
- _stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
- _stitch_preview->preview_polys = NULL;
- _stitch_preview->preview_stitchable = NULL;
- _stitch_preview->preview_unstitchable = NULL;
- _stitch_preview->uvs_per_polygon = NULL;
+ StitchPreviewer *stitch_preview;
- _stitch_preview->preview_uvs = 0;
- _stitch_preview->num_polys = 0;
- _stitch_preview->num_stitchable = 0;
- _stitch_preview->num_unstitchable = 0;
+ stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
+ stitch_preview->preview_polys = NULL;
+ stitch_preview->preview_stitchable = NULL;
+ stitch_preview->preview_unstitchable = NULL;
+ stitch_preview->uvs_per_polygon = NULL;
- _stitch_preview->static_tris = NULL;
+ stitch_preview->preview_uvs = 0;
+ stitch_preview->num_polys = 0;
+ stitch_preview->num_stitchable = 0;
+ stitch_preview->num_unstitchable = 0;
- _stitch_preview->num_static_tris = 0;
+ stitch_preview->static_tris = NULL;
- return _stitch_preview;
+ stitch_preview->num_static_tris = 0;
+
+ return stitch_preview;
}
/* destructor...yeah this should be C++ :) */
-static void stitch_preview_delete(void)
+static void stitch_preview_delete(StitchPreviewer *stitch_preview)
{
- if (_stitch_preview) {
- if (_stitch_preview->preview_polys) {
- MEM_freeN(_stitch_preview->preview_polys);
- _stitch_preview->preview_polys = NULL;
+ if (stitch_preview) {
+ if (stitch_preview->preview_polys) {
+ MEM_freeN(stitch_preview->preview_polys);
+ stitch_preview->preview_polys = NULL;
}
- if (_stitch_preview->uvs_per_polygon) {
- MEM_freeN(_stitch_preview->uvs_per_polygon);
- _stitch_preview->uvs_per_polygon = NULL;
+ if (stitch_preview->uvs_per_polygon) {
+ MEM_freeN(stitch_preview->uvs_per_polygon);
+ stitch_preview->uvs_per_polygon = NULL;
}
- if (_stitch_preview->preview_stitchable) {
- MEM_freeN(_stitch_preview->preview_stitchable);
- _stitch_preview->preview_stitchable = NULL;
+ if (stitch_preview->preview_stitchable) {
+ MEM_freeN(stitch_preview->preview_stitchable);
+ stitch_preview->preview_stitchable = NULL;
}
- if (_stitch_preview->preview_unstitchable) {
- MEM_freeN(_stitch_preview->preview_unstitchable);
- _stitch_preview->preview_unstitchable = NULL;
+ if (stitch_preview->preview_unstitchable) {
+ MEM_freeN(stitch_preview->preview_unstitchable);
+ stitch_preview->preview_unstitchable = NULL;
}
- if (_stitch_preview->static_tris) {
- MEM_freeN(_stitch_preview->static_tris);
- _stitch_preview->static_tris = NULL;
+ if (stitch_preview->static_tris) {
+ MEM_freeN(stitch_preview->static_tris);
+ stitch_preview->static_tris = NULL;
}
-
- MEM_freeN(_stitch_preview);
- _stitch_preview = NULL;
+ MEM_freeN(stitch_preview);
}
}
-
-/* "getter method" */
-static StitchPreviewer *uv_get_stitch_previewer(void)
-{
- return _stitch_preview;
-}
-
#define HEADER_LENGTH 256
/* This function updates the header of the UV editor when the stitch tool updates its settings */
-static void stitch_update_header(StitchState *stitch_state, bContext *C)
+static void stitch_update_header(StitchState *state, bContext *C)
{
- static char str[] = "(S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices";
+ static char str[] = "Mode(TAB) %s, (S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices";
char msg[HEADER_LENGTH];
ScrArea *sa = CTX_wm_area(C);
if (sa) {
BLI_snprintf(msg, HEADER_LENGTH, str,
- stitch_state->snap_islands ? "On" : "Off",
- stitch_state->midpoints ? "On" : "Off",
- stitch_state->limit_dist,
- stitch_state->use_limit ? "On" : "Off");
+ state->mode == STITCH_VERT ? "Vertex" : "Edge",
+ state->snap_islands ? "On" : "Off",
+ state->midpoints ? "On" : "Off",
+ state->limit_dist,
+ state->use_limit ? "On" : "Off");
ED_area_headerprint(sa, msg);
}
@@ -278,44 +288,42 @@ static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
}
}
-static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2])
+static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2], float aspect)
{
float uv_rotation_result[2];
- uv[0] -= medianPoint[0];
- uv[1] -= medianPoint[1];
+ uv[1] /= aspect;
- uv_rotation_result[0] = cosf(rotation) * uv[0] - sinf(rotation) * uv[1];
- uv_rotation_result[1] = sinf(rotation) * uv[0] + cosf(rotation) * uv[1];
+ sub_v2_v2(uv, medianPoint);
+ mul_v2_m2v2(uv_rotation_result, mat, uv);
+ add_v2_v2v2(uv, uv_rotation_result, medianPoint);
- uv[0] = uv_rotation_result[0] + medianPoint[0];
- uv[1] = uv_rotation_result[1] + medianPoint[1];
+ uv[1] *= aspect;
}
+/* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */
static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
{
float limit;
- int do_limit;
if (element_iter == element) {
return 0;
}
limit = state->limit_dist;
- do_limit = state->use_limit;
- if (do_limit) {
- MLoopUV *luv_orig, *luv_iter;
- BMLoop *l_orig, *l_iter;
+ if (state->use_limit) {
+ MLoopUV *luv, *luv_iter;
+ BMLoop *l;
- l_orig = element->l;
- luv_orig = CustomData_bmesh_get(&state->em->bm->ldata, l_orig->head.data, CD_MLOOPUV);
- l_iter = element_iter->l;
- luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l_iter->head.data, CD_MLOOPUV);
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = element_iter->l;
+ luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- if (fabsf(luv_orig->uv[0] - luv_iter->uv[0]) < limit &&
- fabsf(luv_orig->uv[1] - luv_iter->uv[1]) < limit)
+ if (fabsf(luv->uv[0] - luv_iter->uv[0]) < limit &&
+ fabsf(luv->uv[1] - luv_iter->uv[1]) < limit)
{
return 1;
}
@@ -328,6 +336,46 @@ static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_it
}
}
+static int stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+{
+ float limit;
+
+ if (edge_iter == edge) {
+ return 0;
+ }
+
+ limit = state->limit_dist;
+
+ if (state->use_limit) {
+ BMLoop *l;
+ MLoopUV *luv_orig1, *luv_iter1;
+ MLoopUV *luv_orig2, *luv_iter2;
+
+ l = state->uvs[edge->uv1]->l;
+ luv_orig1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge_iter->uv1]->l;
+ luv_iter1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ l = state->uvs[edge->uv2]->l;
+ luv_orig2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge_iter->uv2]->l;
+ luv_iter2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ if (fabsf(luv_orig1->uv[0] - luv_iter1->uv[0]) < limit &&
+ fabsf(luv_orig1->uv[1] - luv_iter1->uv[1]) < limit &&
+ fabsf(luv_orig2->uv[0] - luv_iter2->uv[0]) < limit &&
+ fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit)
+ {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+ else {
+ return 1;
+ }
+}
static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
{
@@ -341,6 +389,17 @@ static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *elem
}
+static int stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+{
+ if ((state->snap_islands && edge->element->island == edge_iter->element->island) ||
+ (!state->midpoints && edge->element->island == edge_iter->element->island))
+ {
+ return 0;
+ }
+
+ return stitch_check_edges_stitchable(edge, edge_iter, state);
+}
+
/* calculate snapping for islands */
static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final)
{
@@ -350,15 +409,40 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition
for (i = 0; i < state->element_map->totalIslands; i++) {
if (island_stitch_data[i].addedForPreview) {
int numOfIslandUVs = 0, j;
+ int totelem = island_stitch_data[i].num_rot_elements_neg + island_stitch_data[i].num_rot_elements;
+ float rotation;
+ float rotation_mat[2][2];
/* check to avoid divide by 0 */
- if (island_stitch_data[i].num_rot_elements > 0) {
+ if (island_stitch_data[i].num_rot_elements > 1)
island_stitch_data[i].rotation /= island_stitch_data[i].num_rot_elements;
+
+ if (island_stitch_data[i].num_rot_elements_neg > 1)
+ island_stitch_data[i].rotation_neg /= island_stitch_data[i].num_rot_elements_neg;
+
+ if (island_stitch_data[i].numOfElements > 1) {
island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfElements;
island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfElements;
+
+ island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
+ island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
+ }
+
+ island_stitch_data[i].medianPoint[1] /= state->aspect;
+ if ((island_stitch_data[i].rotation + island_stitch_data[i].rotation_neg < (float)M_PI_2) ||
+ island_stitch_data[i].num_rot_elements == 0 || island_stitch_data[i].num_rot_elements_neg == 0)
+ {
+ rotation = (island_stitch_data[i].rotation * island_stitch_data[i].num_rot_elements -
+ island_stitch_data[i].rotation_neg *
+ island_stitch_data[i].num_rot_elements_neg) / totelem;
}
- island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
- island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
+ else {
+ rotation = (island_stitch_data[i].rotation * island_stitch_data[i].num_rot_elements +
+ (2.0f * (float)M_PI - island_stitch_data[i].rotation_neg) *
+ island_stitch_data[i].num_rot_elements_neg) / totelem;
+ }
+
+ rotate_m2(rotation_mat, rotation);
numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
element = &state->element_map->buf[state->element_map->islandIndices[i]];
for (j = 0; j < numOfIslandUVs; j++, element++) {
@@ -372,16 +456,17 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition
if (final) {
- stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, luv->uv);
+ stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint, luv->uv, state->aspect);
add_v2_v2(luv->uv, island_stitch_data[i].translation);
}
else {
- int face_preview_pos = preview_position[BM_elem_index_get(element->face)].data_position;
- stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint,
- preview->preview_polys + face_preview_pos + 2 * element->tfindex);
+ int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position;
+
+ stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint,
+ preview->preview_polys + face_preview_pos + 2 * element->tfindex, state->aspect);
add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->tfindex,
island_stitch_data[i].translation);
@@ -404,39 +489,48 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta
int index1, index2;
float rotation;
MLoopUV *luv1, *luv2;
- BMLoop *l1, *l2;
element1 = state->uvs[edge->uv1];
element2 = state->uvs[edge->uv2];
- l1 = element1->l;
- luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l1->head.data, CD_MLOOPUV);
- l2 = element2->l;
- luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l2->head.data, CD_MLOOPUV);
-
- index1 = uvfinal_map[element1 - state->element_map->buf];
- index2 = uvfinal_map[element2 - state->element_map->buf];
+ luv1 = CustomData_bmesh_get(&state->em->bm->ldata, element1->l->head.data, CD_MLOOPUV);
+ luv2 = CustomData_bmesh_get(&state->em->bm->ldata, element2->l->head.data, CD_MLOOPUV);
+ if (state->mode == STITCH_VERT) {
+ index1 = uvfinal_map[element1 - state->element_map->buf];
+ index2 = uvfinal_map[element2 - state->element_map->buf];
+ }
+ else {
+ index1 = edge->uv1;
+ index2 = edge->uv2;
+ }
/* the idea here is to take the directions of the edges and find the rotation between final and initial
* direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */
uv1[0] = luv2->uv[0] - luv1->uv[0];
uv1[1] = luv2->uv[1] - luv1->uv[1];
+ uv1[1] /= state->aspect;
+
uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0];
uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1];
+ uv2[1] /= state->aspect;
+
normalize_v2(uv1);
normalize_v2(uv2);
- edgecos = uv1[0] * uv2[0] + uv1[1] * uv2[1];
- edgesin = uv1[0] * uv2[1] - uv2[0] * uv1[1];
-
- rotation = (edgesin > 0.0f) ?
- +acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))) :
- -acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
+ edgecos = dot_v2v2(uv1, uv2);
+ edgesin = cross_v2v2(uv1, uv2);
+ rotation = acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
- island_stitch_data[element1->island].num_rot_elements++;
- island_stitch_data[element1->island].rotation += rotation;
+ if (edgesin > 0.0f) {
+ island_stitch_data[element1->island].num_rot_elements++;
+ island_stitch_data[element1->island].rotation += rotation;
+ }
+ else {
+ island_stitch_data[element1->island].num_rot_elements_neg++;
+ island_stitch_data[element1->island].rotation_neg += rotation;
+ }
}
@@ -445,7 +539,8 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
float edgecos = 1.0f, edgesin = 0.0f;
int index;
UvElement *element_iter;
- float rotation = 0;
+ float rotation = 0, rotation_neg = 0;
+ int rot_elem = 0, rot_elem_neg = 0;
BMLoop *l;
if (element->island == state->static_island && !state->midpoints)
@@ -461,7 +556,10 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) {
int index_tmp1, index_tmp2;
float normal[2];
- /* easily possible*/
+
+ /* only calculate rotation against static island uv verts */
+ if (!state->midpoints && element_iter->island != state->static_island)
+ continue;
index_tmp1 = element_iter - state->element_map->buf;
index_tmp1 = state->map[index_tmp1];
@@ -471,45 +569,136 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
negate_v2_v2(normal, state->normals + index_tmp2 * 2);
edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2);
edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2);
- rotation += (edgesin > 0.0f) ? acosf(edgecos) : -acosf(edgecos);
+ if (edgesin > 0.0f) {
+ 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)));
+ rot_elem_neg++;
+ }
}
}
- if (state->midpoints)
+ if (state->midpoints) {
rotation /= 2.0f;
- island_stitch_data[element->island].num_rot_elements++;
+ rotation_neg /= 2.0f;
+ }
+ island_stitch_data[element->island].num_rot_elements += rot_elem;
island_stitch_data[element->island].rotation += rotation;
+ island_stitch_data[element->island].num_rot_elements_neg += rot_elem_neg;
+ island_stitch_data[element->island].rotation_neg += rotation_neg;
}
-static void stitch_state_delete(StitchState *stitch_state)
+static void state_delete(StitchState *state)
{
- if (stitch_state) {
- if (stitch_state->element_map) {
- EDBM_uv_element_map_free(stitch_state->element_map);
+ if (state) {
+ if (state->element_map) {
+ EDBM_uv_element_map_free(state->element_map);
}
- if (stitch_state->uvs) {
- MEM_freeN(stitch_state->uvs);
+ if (state->uvs) {
+ MEM_freeN(state->uvs);
}
- if (stitch_state->selection_stack) {
- MEM_freeN(stitch_state->selection_stack);
+ if (state->selection_stack) {
+ MEM_freeN(state->selection_stack);
}
- if (stitch_state->tris_per_island) {
- MEM_freeN(stitch_state->tris_per_island);
+ if (state->tris_per_island) {
+ MEM_freeN(state->tris_per_island);
}
- if (stitch_state->map) {
- MEM_freeN(stitch_state->map);
+ if (state->map) {
+ MEM_freeN(state->map);
}
- if (stitch_state->normals) {
- MEM_freeN(stitch_state->normals);
+ if (state->normals) {
+ MEM_freeN(state->normals);
}
- if (stitch_state->edges) {
- MEM_freeN(stitch_state->edges);
+ if (state->edges) {
+ MEM_freeN(state->edges);
}
- MEM_freeN(stitch_state);
+ if (state->stitch_preview) {
+ stitch_preview_delete(state->stitch_preview);
+ }
+ if (state->edge_hash) {
+ BLI_ghash_free(state->edge_hash, NULL, NULL);
+ }
+ MEM_freeN(state);
}
}
+static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
+{
+ UvEdge *edges = state->edges;
+ int *map = state->map;
+ UvElementMap *element_map = state->element_map;
+ UvElement *first_element = element_map->buf;
+ int i;
+
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = edges + i;
+
+ if (edge->first)
+ continue;
+
+ /* only boundary edges can be stitched. Yes. Sorry about that :p */
+ if (edge->flag & STITCH_BOUNDARY) {
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ /* Now iterate through all faces and try to find edges sharing the same vertices */
+ UvElement *iter1 = element_map->vert[BM_elem_index_get(element1->l->v)];
+ UvEdge *last_set = edge;
+ int elemindex2 = BM_elem_index_get(element2->l->v);
+
+ edge->first = edge;
+
+ for (; iter1; iter1 = iter1->next) {
+ UvElement *iter2 = NULL;
+
+ /* check to see if other vertex of edge belongs to same vertex as */
+ if (BM_elem_index_get(iter1->l->next->v) == elemindex2)
+ iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->next);
+ else if (BM_elem_index_get(iter1->l->prev->v) == elemindex2)
+ iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->prev);
+
+ if (iter2) {
+ int index1 = map[iter1 - first_element];
+ int index2 = map[iter2 - first_element];
+
+ /* make certain we do not have the same edge! */
+ if (state->uvs[index2] != element2 && state->uvs[index1] != element1) {
+ UvEdge edgetmp;
+ UvEdge *edge2;
+
+
+ /* make sure the indices are well behaved */
+ if (index1 < index2) {
+ edgetmp.uv1 = index1;
+ edgetmp.uv2 = index2;
+ }
+ else {
+ edgetmp.uv1 = index2;
+ edgetmp.uv2 = index1;
+ }
+
+ /* get the edge from the hash */
+ edge2 = BLI_ghash_lookup(edge_hash, &edgetmp);
+
+ /* here I am taking care of non manifold case, assuming more than two matching edges.
+ * I am not too sure we want this though */
+ last_set->next = edge2;
+ last_set = edge2;
+ /* set first, similarly to uv elements. Now we can iterate among common edges easily */
+ edge2->first = edge;
+ }
+ }
+ }
+ }
+ else {
+ /* so stitchability code works */
+ edge->first = edge;
+ }
+ }
+}
/* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */
@@ -526,9 +715,6 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
- if (element_iter == element) {
- continue;
- }
if (stitch_check_uvs_stitchable(element, element_iter, state)) {
island_stitch_data[element_iter->island].stitchableCandidate = 1;
island_stitch_data[element->island].stitchableCandidate = 1;
@@ -538,6 +724,19 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I
}
}
+static void determine_uv_edge_stitchability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data)
+{
+ UvEdge *edge_iter = edge->first;
+
+ for (; edge_iter; edge_iter = edge_iter->next) {
+ if (stitch_check_edges_stitchable(edge, edge_iter, state)) {
+ island_stitch_data[edge_iter->element->island].stitchableCandidate = 1;
+ island_stitch_data[edge->element->island].stitchableCandidate = 1;
+ edge->flag |= STITCH_STITCHABLE_CANDIDATE;
+ }
+ }
+}
+
/* set preview buffer position of UV face in editface->tmp.l */
static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position)
@@ -555,7 +754,7 @@ static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer
/* setup face preview for all coincident uvs and their faces */
static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
PreviewPosition *preview_position) {
- StitchPreviewer *preview = uv_get_stitch_previewer();
+ StitchPreviewer *preview = state->stitch_preview;
/* static island does not change so returning immediately */
if (state->snap_islands && !state->midpoints && state->static_island == element->island)
@@ -566,17 +765,17 @@ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchSta
}
do {
- stitch_set_face_preview_buffer_position(element->face, preview, preview_position);
+ stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position);
element = element->next;
} while (element && !element->separate);
}
/* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
-static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
+static void stitch_validate_uv_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
PreviewPosition *preview_position) {
UvElement *element_iter;
- StitchPreviewer *preview;
+ StitchPreviewer *preview = state->stitch_preview;
int vert_index;
BMLoop *l;
@@ -584,7 +783,6 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state,
vert_index = BM_elem_index_get(l->v);
- preview = uv_get_stitch_previewer();
element_iter = state->element_map->vert[vert_index];
for (; element_iter; element_iter = element_iter->next) {
@@ -608,6 +806,72 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state,
}
}
+
+static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data,
+ PreviewPosition *preview_position) {
+ UvEdge *edge_iter = edge->first;
+ StitchPreviewer *preview = state->stitch_preview;
+
+ for (; edge_iter; edge_iter = edge_iter->next) {
+ if (edge_iter == edge)
+ continue;
+ if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) {
+ if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) {
+ edge->flag |= STITCH_STITCHABLE;
+ preview->num_stitchable++;
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position);
+ return;
+ }
+ }
+ }
+
+ /* this can happen if the uvs to be stitched are not on a stitchable island */
+ if (!(edge->flag & STITCH_STITCHABLE)) {
+ preview->num_unstitchable++;
+ }
+}
+
+
+static void stitch_propagate_uv_final_position(UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene *scene)
+{
+ StitchPreviewer *preview = state->stitch_preview;
+
+ if (element->flag & STITCH_STITCHABLE) {
+ UvElement *element_iter = element;
+ /* propagate to coincident uvs */
+ do {
+ BMLoop *l;
+ MLoopUV *luv;
+
+ l = element_iter->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ element_iter->flag |= STITCH_PROCESSED;
+ /* either flush to preview or to the MTFace, if final */
+ if (final) {
+ copy_v2_v2(luv->uv, final_position[index].uv);
+
+ uvedit_uv_select_enable(state->em, scene, l, FALSE);
+ }
+ else {
+ int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position;
+ if (face_preview_pos != STITCH_NO_PREVIEW) {
+ copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex,
+ final_position[index].uv);
+ }
+ }
+
+ /* end of calculations, keep only the selection flag */
+ if ( (!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) {
+ element_iter->flag &= STITCH_SELECTED;
+ }
+
+ element_iter = element_iter->next;
+ } while (element_iter && !element_iter->separate);
+ }
+}
+
/* main processing function. It calculates preview and final positions. */
static int stitch_process_data(StitchState *state, Scene *scene, int final)
{
@@ -617,16 +881,17 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
int previous_island = state->static_island;
BMFace *efa;
BMIter iter;
- UVVertAverage *final_position;
+ UVVertAverage *final_position = NULL;
+
char stitch_midpoints = state->midpoints;
/* used to map uv indices to uvaverage indices for selection */
- unsigned int *uvfinal_map;
+ unsigned int *uvfinal_map = NULL;
/* per face preview position in preview buffer */
- PreviewPosition *preview_position;
+ PreviewPosition *preview_position = NULL;
/* cleanup previous preview */
- stitch_preview_delete();
- preview = stitch_preview_init();
+ stitch_preview_delete(state->stitch_preview);
+ preview = state->stitch_preview = stitch_preview_init();
if (preview == NULL)
return 0;
@@ -649,8 +914,14 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
*****************************************/
for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- determine_uv_stitchability(element, state, island_stitch_data);
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = (UvElement *)state->selection_stack[i];
+ determine_uv_stitchability(element, state, island_stitch_data);
+ }
+ else {
+ UvEdge *edge = (UvEdge *)state->selection_stack[i];
+ determine_uv_edge_stitchability(edge, state, island_stitch_data);
+ }
}
/* set static island to one that is added for preview */
@@ -664,14 +935,26 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
- element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
- stitch_validate_stichability(element, state, island_stitch_data, preview_position);
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = (UvElement *)state->selection_stack[i];
+ if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
+ element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
+ stitch_validate_uv_stichability(element, state, island_stitch_data, preview_position);
+ }
+ else {
+ /* add to preview for unstitchable */
+ preview->num_unstitchable++;
+ }
}
else {
- /* add to preview for unstitchable */
- preview->num_unstitchable++;
+ UvEdge *edge = (UvEdge *)state->selection_stack[i];
+ if (edge->flag & STITCH_STITCHABLE_CANDIDATE) {
+ edge->flag &= ~STITCH_STITCHABLE_CANDIDATE;
+ stitch_validate_edge_stichability(edge, state, island_stitch_data, preview_position);
+ }
+ else {
+ preview->num_unstitchable++;
+ }
}
}
@@ -686,7 +969,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
element = &state->element_map->buf[state->element_map->islandIndices[i]];
for (j = 0; j < numOfIslandUVs; j++, element++) {
- stitch_set_face_preview_buffer_position(element->face, preview, preview_position);
+ stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position);
}
}
}
@@ -701,11 +984,12 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
MLoopUV *luv;
unsigned int buffer_index = 0;
int stitchBufferIndex = 0, unstitchBufferIndex = 0;
+ int preview_size = (state->mode == STITCH_VERT) ? 2 : 4;
/* initialize the preview buffers */
preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev");
preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev");
- preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * 2, "stitch_preview_stichable_data");
- preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * 2, "stitch_preview_unstichable_data");
+ preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stichable_data");
+ preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstichable_data");
preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris");
@@ -715,7 +999,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
return 0;
}
- /* copy data from MTFaces to the preview display buffers */
+ /* copy data from MLoopUVs to the preview display buffers */
BM_ITER_MESH (efa, &iter, state->em->bm, BM_FACES_OF_MESH) {
/* just to test if face was added for processing. uvs of inselected vertices will return NULL */
UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
@@ -757,22 +1041,56 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/* fill the appropriate preview buffers */
- for (i = 0; i < state->total_separate_uvs; i++) {
- UvElement *element = (UvElement *)state->uvs[i];
- if (element->flag & STITCH_STITCHABLE) {
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (state->mode == STITCH_VERT) {
+ for (i = 0; i < state->total_separate_uvs; i++) {
+ UvElement *element = (UvElement *)state->uvs[i];
+ if (element->flag & STITCH_STITCHABLE) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
- stitchBufferIndex++;
+ stitchBufferIndex++;
+ }
+ else if (element->flag & STITCH_SELECTED) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
+ unstitchBufferIndex++;
+ }
}
- else if (element->flag & STITCH_SELECTED) {
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ }
+ else {
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ if (edge->flag & STITCH_STITCHABLE) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
- unstitchBufferIndex++;
+ l = element2->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
+
+ stitchBufferIndex++;
+ BLI_assert(stitchBufferIndex <= preview->num_stitchable);
+ }
+ else if (edge->flag & STITCH_SELECTED) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
+
+ l = element2->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
+
+ unstitchBufferIndex++;
+ BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
+ }
}
}
}
@@ -781,51 +1099,111 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
* Here we calculate the final coordinates of the uvs *
******************************************************/
- final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
- uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
+ if (state->mode == STITCH_VERT) {
+ final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
+ uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
+ }
+ else {
+ final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average");
+ }
/* first pass, calculate final position for stitchable uvs of the static island */
for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE) {
- BMLoop *l;
- MLoopUV *luv;
- UvElement *element_iter;
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = state->selection_stack[i];
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (element->flag & STITCH_STITCHABLE) {
+ BMLoop *l;
+ MLoopUV *luv;
+ UvElement *element_iter;
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- uvfinal_map[element - state->element_map->buf] = i;
+ uvfinal_map[element - state->element_map->buf] = i;
- copy_v2_v2(final_position[i].uv, luv->uv);
- final_position[i].count = 1;
+ copy_v2_v2(final_position[i].uv, luv->uv);
+ final_position[i].count = 1;
- if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
- continue;
+ if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
+ continue;
+
+ element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
+
+ for ( ; element_iter; element_iter = element_iter->next) {
+ if (element_iter->separate) {
+ if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
+ l = element_iter->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (stitch_midpoints) {
+ add_v2_v2(final_position[i].uv, luv->uv);
+ final_position[i].count++;
+ }
+ else if (element_iter->island == state->static_island) {
+ /* if multiple uvs on the static island exist,
+ * last checked remains. to disambiguate we need to limit or use
+ * edge stitch */
+ copy_v2_v2(final_position[i].uv, luv->uv);
+ }
+ }
+ }
+ }
+ }
+ if (stitch_midpoints) {
+ final_position[i].uv[0] /= final_position[i].count;
+ final_position[i].uv[1] /= final_position[i].count;
+ }
+ }
+ else {
+ UvEdge *edge = state->selection_stack[i];
- element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
+ if (edge->flag & STITCH_STITCHABLE) {
+ MLoopUV *luv2, *luv1;
+ BMLoop *l;
+ UvEdge *edge_iter;
+
+ l = state->uvs[edge->uv1]->l;
+ luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge->uv2]->l;
+ luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
+ copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
+ final_position[edge->uv1].count = 1;
+ final_position[edge->uv2].count = 1;
+
+ state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE;
+ state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE;
+
+ if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints)
+ continue;
+
+ for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) {
+ if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) {
+ l = state->uvs[edge_iter->uv1]->l;
+ luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge_iter->uv2]->l;
+ luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- for ( ; element_iter; element_iter = element_iter->next) {
- if (element_iter->separate) {
- if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
- l = element_iter->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
if (stitch_midpoints) {
- add_v2_v2(final_position[i].uv, luv->uv);
- final_position[i].count++;
+ add_v2_v2(final_position[edge->uv1].uv, luv1->uv);
+ final_position[edge->uv1].count++;
+ add_v2_v2(final_position[edge->uv2].uv, luv2->uv);
+ final_position[edge->uv2].count++;
}
- else if (element_iter->island == state->static_island) {
- /* if multiple uvs on the static island exist,
- * last checked remains. to disambiguate we need to limit or use
- * edge stitch */
- copy_v2_v2(final_position[i].uv, luv->uv);
+ else if (edge_iter->element->island == state->static_island) {
+ copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
+ copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
}
}
}
}
}
- if (stitch_midpoints) {
+ }
+
+ /* take mean position here. For edge case, this can't be done inside the loop for shared uvverts */
+ if (state->mode == STITCH_EDGE && stitch_midpoints) {
+ for (i = 0; i < state->total_separate_uvs; i++) {
final_position[i].uv[0] /= final_position[i].count;
final_position[i].uv[1] /= final_position[i].count;
}
@@ -833,89 +1211,110 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* second pass, calculate island rotation and translation before modifying any uvs */
if (state->snap_islands) {
- for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE) {
- BMLoop *l;
- MLoopUV *luv;
+ if (state->mode == STITCH_VERT) {
+ for (i = 0; i < state->selection_size; i++) {
+ UvElement *element = state->selection_stack[i];
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (element->flag & STITCH_STITCHABLE) {
+ BMLoop *l;
+ MLoopUV *luv;
- /* accumulate each islands' translation from stitchable elements. it is important to do here
- * because in final pass MTFaces get modified and result is zero. */
- island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
- island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
- island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
- island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
- island_stitch_data[element->island].numOfElements++;
- }
- }
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- /* only calculate rotation when an edge has been fully selected */
- for (i = 0; i < state->total_boundary_edges; i++) {
- UvEdge *edge = state->edges + i;
- if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) {
- stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
- island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
+ /* accumulate each islands' translation from stitchable elements. it is important to do here
+ * because in final pass MTFaces get modified and result is zero. */
+ island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
+ island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
+ island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
+ island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
+ island_stitch_data[element->island].numOfElements++;
+ }
}
- }
- /* clear seams of stitched edges */
- if (final && state->clear_seams) {
- for (i = 0; i < state->total_boundary_edges; i++) {
+ /* only calculate rotation when an edge has been fully selected */
+ for (i = 0; i < state->total_separate_edges; i++) {
UvEdge *edge = state->edges + i;
- if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
- BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
+ if ((edge->flag & STITCH_BOUNDARY) && (state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) {
+ stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
+ island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
+ }
}
- }
- for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (!island_stitch_data[element->island].use_edge_rotation) {
- if (element->flag & STITCH_STITCHABLE) {
- stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
+ /* clear seams of stitched edges */
+ if (final && state->clear_seams) {
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
+ BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
+ }
+ }
+
+ for (i = 0; i < state->selection_size; i++) {
+ UvElement *element = state->selection_stack[i];
+ if (!island_stitch_data[element->island].use_edge_rotation) {
+ if (element->flag & STITCH_STITCHABLE) {
+ stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
+ }
}
}
}
+ else {
+ for (i = 0; i < state->total_separate_uvs; i++) {
+ UvElement *element = state->uvs[i];
- }
+ if (element->flag & STITCH_STITCHABLE) {
+ BMLoop *l;
+ MLoopUV *luv;
- /* third pass, propagate changes to coincident uvs */
- for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE) {
- UvElement *element_iter = element;
- /* propagate to coincident uvs */
- do {
- BMLoop *l;
- MLoopUV *luv;
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- l = element_iter->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ /* accumulate each islands' translation from stitchable elements. it is important to do here
+ * because in final pass MTFaces get modified and result is zero. */
+ island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
+ island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
+ island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
+ island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
+ island_stitch_data[element->island].numOfElements++;
+ }
+ }
- element_iter->flag |= STITCH_PROCESSED;
- /* either flush to preview or to the MTFace, if final */
- if (final) {
- copy_v2_v2(luv->uv, final_position[i].uv);
+ for (i = 0; i < state->selection_size; i++) {
+ UvEdge *edge = state->selection_stack[i];
- uvedit_uv_select_enable(state->em, scene, l, FALSE);
+ if (edge->flag & STITCH_STITCHABLE) {
+ stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data);
+ island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
}
- else {
- int face_preview_pos = preview_position[BM_elem_index_get(element_iter->face)].data_position;
- if (face_preview_pos != STITCH_NO_PREVIEW) {
- copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex,
- final_position[i].uv);
+ }
+
+ /* clear seams of stitched edges */
+ if (final && state->clear_seams) {
+ for (i = 0; i < state->selection_size; i++) {
+ UvEdge *edge = state->selection_stack[i];
+ if (edge->flag & STITCH_STITCHABLE) {
+ BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
}
}
+ }
+ }
+ }
- /* end of calculations, keep only the selection flag */
- if ( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) {
- element_iter->flag &= STITCH_SELECTED;
- }
+ /* third pass, propagate changes to coincident uvs */
+ for (i = 0; i < state->selection_size; i++) {
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = state->selection_stack[i];
+
+ stitch_propagate_uv_final_position (element, i, preview_position, final_position, state, final, scene);
+ }
+ else {
+ UvEdge *edge = state->selection_stack[i];
+
+ stitch_propagate_uv_final_position (state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final, scene);
+ stitch_propagate_uv_final_position (state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final, scene);
- element_iter = element_iter->next;
- } while (element_iter && !element_iter->separate);
+ edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY);
}
}
@@ -925,7 +1324,9 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
MEM_freeN(final_position);
- MEM_freeN(uvfinal_map);
+ if (state->mode == STITCH_VERT) {
+ MEM_freeN(uvfinal_map);
+ }
MEM_freeN(island_stitch_data);
MEM_freeN(preview_position);
@@ -937,8 +1338,8 @@ static unsigned int uv_edge_hash(const void *key)
{
UvEdge *edge = (UvEdge *)key;
return
- BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
- BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
+ BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
+ BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
}
static int uv_edge_compare(const void *a, const void *b)
@@ -952,13 +1353,41 @@ static int uv_edge_compare(const void *a, const void *b)
return 1;
}
+/* select all common edges */
+static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_select)
+{
+ UvEdge *eiter;
+ UvEdge **selection_stack = (UvEdge **)state->selection_stack;
+
+ for (eiter = edge->first; eiter; eiter = eiter->next) {
+ if (eiter->flag & STITCH_SELECTED) {
+ int i;
+ if (always_select)
+ continue;
+
+ eiter->flag &= ~STITCH_SELECTED;
+ for (i = 0; i < state->selection_size; i++) {
+ if (selection_stack[i] == eiter) {
+ (state->selection_size)--;
+ selection_stack[i] = selection_stack[state->selection_size];
+ break;
+ }
+ }
+ }
+ else {
+ eiter->flag |= STITCH_SELECTED;
+ selection_stack[state->selection_size++] = eiter;
+ }
+ }
+}
+
/* Select all common uvs */
static void stitch_select_uv(UvElement *element, StitchState *state, int always_select)
{
BMLoop *l;
UvElement *element_iter;
- UvElement **selection_stack = state->selection_stack;
+ UvElement **selection_stack = (UvElement **)state->selection_stack;
l = element->l;
@@ -989,33 +1418,86 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_
}
}
-static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal)
+static void stitch_switch_selection_mode(StitchState *state)
+{
+ void **old_selection_stack = state->selection_stack;
+ int old_selection_size = state->selection_size;
+ state->selection_size = 0;
+
+ if (state->mode == STITCH_VERT) {
+ int i;
+ state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
+ "stitch_new_edge_selection_stack");
+
+ /* check if both elements of an edge are selected */
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ if ((element1->flag & STITCH_SELECTED) && (element2->flag & STITCH_SELECTED))
+ stitch_select_edge(edge, state, TRUE);
+ }
+
+ /* unselect selected uvelements */
+ for (i = 0; i < old_selection_size; i++) {
+ UvElement *element = old_selection_stack[i];
+
+ element->flag &= ~STITCH_SELECTED;
+ }
+ state->mode = STITCH_EDGE;
+ }
+ else {
+ int i;
+ state->selection_stack = MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack),
+ "stitch_new_vert_selection_stack");
+
+ for (i = 0; i < old_selection_size; i++) {
+ UvEdge *edge = old_selection_stack[i];
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ stitch_select_uv(element1, state, TRUE);
+ stitch_select_uv(element2, state, TRUE);
+
+ edge->flag &= ~STITCH_SELECTED;
+ }
+ state->mode = STITCH_VERT;
+ }
+ MEM_freeN(old_selection_stack);
+}
+
+static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
{
BMLoop *l1 = edge->element->l;
- BMLoop *l2 = l1->next;
MLoopUV *luv1, *luv2;
float tangent[2];
luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
- luv2 = CustomData_bmesh_get(&em->bm->ldata, l2->head.data, CD_MLOOPUV);
+ luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV);
sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
+ tangent[1] /= aspect;
+
normal[0] = tangent[1];
normal[1] = -tangent[0];
normalize_v2(normal);
}
-static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg))
+static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
int i, index = 0;
float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
- StitchPreviewer *stitch_preview = uv_get_stitch_previewer();
+ StitchState *state = (StitchState *)arg;
+ StitchPreviewer *stitch_preview = state->stitch_preview;
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
+ glPointSize(pointsize * 2.0f);
+
glEnable(GL_BLEND);
UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
@@ -1031,35 +1513,68 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UN
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+ #if 0
+ glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
+ glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+ #endif
index += stitch_preview->uvs_per_polygon[i];
}
- glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
-#if 0
- UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
- glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3);
-#endif
glDisable(GL_BLEND);
/* draw vert preview */
- glPointSize(pointsize * 2.0f);
- UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
+ if (state->mode == STITCH_VERT) {
+ UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
+ glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
+
+ UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
+ glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
+ }
+ else {
+ UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
+ glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_stitchable);
- UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
+ glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_unstitchable);
+ }
glPopClientAttrib();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPointSize(1.0);
+}
+
+static UvEdge *uv_edge_get (BMLoop *l, StitchState *state)
+{
+ UvEdge tmp_edge;
+
+ UvElement *element1 = ED_uv_element_get(state->element_map, l->f, l);
+ UvElement *element2 = ED_uv_element_get(state->element_map, l->f, l->next);
+
+ int uv1 = state->map[element1 - state->element_map->buf];
+ int uv2 = state->map[element2 - state->element_map->buf];
+
+ if (uv1 < uv2) {
+ tmp_edge.uv1 = uv1;
+ tmp_edge.uv2 = uv2;
+ }
+ else {
+ tmp_edge.uv1 = uv2;
+ tmp_edge.uv2 = uv1;
+ }
+
+ return BLI_ghash_lookup(state->edge_hash, &tmp_edge);
}
static int stitch_init(bContext *C, wmOperator *op)
{
/* for fast edge lookup... */
- GHash *edgeHash;
+ GHash *edge_hash;
/* ...and actual edge storage */
UvEdge *edges;
int total_edges;
@@ -1076,7 +1591,7 @@ static int stitch_init(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
ARegion *ar = CTX_wm_region(C);
-
+ float aspx, aspy;
Object *obedit = CTX_data_edit_object(C);
if (!ar)
@@ -1097,21 +1612,44 @@ static int stitch_init(bContext *C, wmOperator *op)
state->static_island = RNA_int_get(op->ptr, "static_island");
state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
- state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW);
+ if (RNA_struct_property_is_set(op->ptr, "mode")) {
+ state->mode = RNA_enum_get(op->ptr, "mode");
+ }
+ else {
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (ts->selectmode & SCE_SELECT_VERTEX)
+ state->mode = STITCH_VERT;
+ else
+ state->mode = STITCH_EDGE;
+ }
+ else {
+ if (ts->uv_selectmode & UV_SELECT_VERTEX) {
+ state->mode = STITCH_VERT;
+ }
+ else {
+ state->mode = STITCH_EDGE;
+ }
+ }
+ }
+
+ state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW);
/* in uv synch selection, all uv's are visible */
if (ts->uv_flag & UV_SYNC_SELECTION) {
- state->element_map = EDBM_uv_element_map_create(state->em, 0, 1);
+ state->element_map = EDBM_uv_element_map_create(state->em, FALSE, TRUE);
}
else {
- state->element_map = EDBM_uv_element_map_create(state->em, 1, 1);
+ state->element_map = EDBM_uv_element_map_create(state->em, TRUE, TRUE);
}
if (!state->element_map) {
- stitch_state_delete(state);
+ state_delete(state);
return 0;
}
+ uvedit_get_aspect(scene, obedit, em, &aspx, &aspy);
+ state->aspect = aspx / aspy;
+
/* Entirely possible if redoing last operator that static island is bigger than total number of islands.
- * This ensures we get no hang in the island checking code in stitch_process_data. */
+ * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */
state->static_island %= state->element_map->totalIslands;
/* Count 'unique' uvs */
@@ -1121,22 +1659,21 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
+ /* explicitly set preview to NULL, to avoid deleting an invalid pointer on stitch_process_data */
+ state->stitch_preview = NULL;
/* Allocate the unique uv buffers */
state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs");
/* internal uvs need no normals but it is hard and slow to keep a map of
* normals only for boundary uvs, so allocating for all uvs */
state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals");
state->total_separate_uvs = counter;
- /* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only
- * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */
- state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * counter, "uv_stitch_selection_stack");
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map");
/* Allocate the edge stack */
- edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
+ edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges");
- if (!state->selection_stack || !state->uvs || !map || !edgeHash || !all_edges) {
- stitch_state_delete(state);
+ if (!state->uvs || !map || !edge_hash || !all_edges) {
+ state_delete(state);
return 0;
}
@@ -1169,6 +1706,8 @@ static int stitch_init(bContext *C, wmOperator *op)
offset1 = map[itmp1];
offset2 = map[itmp2];
+ all_edges[counter].next = NULL;
+ all_edges[counter].first = NULL;
all_edges[counter].flag = 0;
all_edges[counter].element = element;
/* using an order policy, sort uvs according to address space. This avoids
@@ -1182,12 +1721,12 @@ static int stitch_init(bContext *C, wmOperator *op)
all_edges[counter].uv2 = offset1;
}
- if (BLI_ghash_haskey(edgeHash, &all_edges[counter])) {
- char *flag = BLI_ghash_lookup(edgeHash, &all_edges[counter]);
- *flag = 0;
+ if (BLI_ghash_haskey(edge_hash, &all_edges[counter])) {
+ UvEdge *edge = BLI_ghash_lookup(edge_hash, &all_edges[counter]);
+ edge->flag = 0;
}
else {
- BLI_ghash_insert(edgeHash, &all_edges[counter], &(all_edges[counter].flag));
+ BLI_ghash_insert(edge_hash, &all_edges[counter], &all_edges[counter]);
all_edges[counter].flag = STITCH_BOUNDARY;
}
counter++;
@@ -1195,55 +1734,56 @@ static int stitch_init(bContext *C, wmOperator *op)
}
- ghi = BLI_ghashIterator_new(edgeHash);
- total_edges = 0;
- /* fill the edges with data */
- for (; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
- UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
- if (edge->flag & STITCH_BOUNDARY) {
- total_edges++;
- }
- }
+ ghi = BLI_ghashIterator_new(edge_hash);
+ total_edges = BLI_ghash_size(edge_hash);
state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges");
- if (!ghi || !edges) {
- MEM_freeN(all_edges);
- stitch_state_delete(state);
+
+ /* 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;
}
- state->total_boundary_edges = total_edges;
+ state->total_separate_edges = total_edges;
/* fill the edges with data */
- for (i = 0, BLI_ghashIterator_init(ghi, edgeHash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
- UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
- if (edge->flag & STITCH_BOUNDARY) {
- edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
- }
+ for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
}
/* cleanup temporary stuff */
BLI_ghashIterator_free(ghi);
MEM_freeN(all_edges);
- /* refill hash with new pointers to cleanup duplicates */
- BLI_ghash_free(edgeHash, NULL, NULL);
+ BLI_ghash_free(edge_hash, NULL, NULL);
+
+ /* refill an edge hash to create edge connnectivity data */
+ state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
+ for (i = 0; i < total_edges; i++) {
+ BLI_ghash_insert(edge_hash, edges + i, edges + i);
+ }
+ stitch_uv_edge_generate_linked_edges(edge_hash, state);
/***** calculate 2D normals for boundary uvs *****/
/* we use boundary edges to calculate 2D normals.
* to disambiguate the direction of the normal, we also need
* a point "inside" the island, that can be provided by
- * the opposite uv for a quad, or the next uv for a triangle. */
+ * the winding of the polygon (assuming counter-clockwise flow). */
for (i = 0; i < total_edges; i++) {
+ UvEdge *edge = edges + i;
float normal[2];
- stitch_calculate_edge_normal(em, edges + i, normal);
+ if (edge->flag & STITCH_BOUNDARY) {
+ stitch_calculate_edge_normal(em, edge, normal, state->aspect);
- add_v2_v2(state->normals + edges[i].uv1 * 2, normal);
- add_v2_v2(state->normals + edges[i].uv2 * 2, normal);
+ add_v2_v2(state->normals + edge->uv1 * 2, normal);
+ add_v2_v2(state->normals + edge->uv2 * 2, normal);
- normalize_v2(state->normals + edges[i].uv1 * 2);
- normalize_v2(state->normals + edges[i].uv2 * 2);
+ normalize_v2(state->normals + edge->uv1 * 2);
+ normalize_v2(state->normals + edge->uv2 * 2);
+ }
}
@@ -1255,31 +1795,89 @@ static int stitch_init(bContext *C, wmOperator *op)
if (RNA_struct_property_is_set(op->ptr, "selection")) {
int faceIndex, elementIndex;
UvElement *element;
+ enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode");
- EDBM_index_arrays_init(em, 0, 0, 1);
+ EDBM_index_arrays_ensure(em, BM_FACE);
- RNA_BEGIN (op->ptr, itemptr, "selection")
- {
- faceIndex = RNA_int_get(&itemptr, "face_index");
- elementIndex = RNA_int_get(&itemptr, "element_index");
- efa = EDBM_face_at_index(em, faceIndex);
- element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
- stitch_select_uv(element, state, 1);
+ if (stored_mode == STITCH_VERT) {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
+
+ RNA_BEGIN (op->ptr, itemptr, "selection")
+ {
+ faceIndex = RNA_int_get(&itemptr, "face_index");
+ elementIndex = RNA_int_get(&itemptr, "element_index");
+ efa = EDBM_face_at_index(em, faceIndex);
+ element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
+ stitch_select_uv(element, state, 1);
+ }
+ RNA_END;
}
- RNA_END;
+ else {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack");
+
+ RNA_BEGIN (op->ptr, itemptr, "selection")
+ {
+ UvEdge tmp_edge, *edge;
+ int uv1, uv2;
+ faceIndex = RNA_int_get(&itemptr, "face_index");
+ elementIndex = RNA_int_get(&itemptr, "element_index");
+ efa = EDBM_face_at_index(em, faceIndex);
+ element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
+ uv1 = map[element - state->element_map->buf];
+
+ element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len));
+ uv2 = map[element - state->element_map->buf];
+
+ if (uv1 < uv2) {
+ tmp_edge.uv1 = uv1;
+ tmp_edge.uv2 = uv2;
+ }
+ else {
+ tmp_edge.uv1 = uv2;
+ tmp_edge.uv2 = uv1;
+ }
- EDBM_index_arrays_free(em);
+ edge = BLI_ghash_lookup(edge_hash, &tmp_edge);
+
+ stitch_select_edge(edge, state, TRUE);
+ }
+ RNA_END;
+ }
+ /* if user has switched the operator mode after operation, we need to convert
+ * the stored format */
+ if (state->mode != stored_mode) {
+ state->mode = stored_mode;
+ stitch_switch_selection_mode(state);
+ }
/* Clear the selection */
RNA_collection_clear(op->ptr, "selection");
}
else {
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- if (uvedit_uv_select_test(em, scene, l)) {
- UvElement *element = ED_uv_element_get(state->element_map, efa, l);
- if (element) {
- stitch_select_uv(element, state, 1);
+ if (state->mode == STITCH_VERT) {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ if (uvedit_uv_select_test(em, scene, l)) {
+ UvElement *element = ED_uv_element_get(state->element_map, efa, l);
+ if (element) {
+ stitch_select_uv(element, state, 1);
+ }
+ }
+ }
+ }
+ }
+ else {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack");
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ if (uvedit_edge_select_test(em, scene, l)) {
+ UvEdge *edge = uv_edge_get(l, state);
+ if (edge) {
+ stitch_select_edge(edge, state, TRUE);
+ }
}
}
}
@@ -1302,8 +1900,9 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
- if (!stitch_process_data(state, scene, 0)) {
- stitch_state_delete(state);
+ if (!stitch_process_data(state, scene, FALSE)) {
+
+ state_delete(state);
return 0;
}
@@ -1324,7 +1923,7 @@ static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
static void stitch_exit(bContext *C, wmOperator *op, int finished)
{
- StitchState *stitch_state;
+ StitchState *state;
Scene *scene;
SpaceImage *sima;
ScrArea *sa = CTX_wm_area(C);
@@ -1334,45 +1933,48 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
obedit = CTX_data_edit_object(C);
sima = CTX_wm_space_image(C);
- stitch_state = (StitchState *)op->customdata;
+ state = (StitchState *)op->customdata;
if (finished) {
int i;
- RNA_float_set(op->ptr, "limit", stitch_state->limit_dist);
- RNA_boolean_set(op->ptr, "use_limit", stitch_state->use_limit);
- RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snap_islands);
- RNA_int_set(op->ptr, "static_island", stitch_state->static_island);
- RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints);
+ RNA_float_set(op->ptr, "limit", state->limit_dist);
+ RNA_boolean_set(op->ptr, "use_limit", state->use_limit);
+ RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands);
+ RNA_int_set(op->ptr, "static_island", state->static_island);
+ RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints);
+ RNA_enum_set(op->ptr, "mode", state->mode);
+ RNA_enum_set(op->ptr, "stored_mode", state->mode);
/* Store selection for re-execution of stitch */
- for (i = 0; i < stitch_state->selection_size; i++) {
+ for (i = 0; i < state->selection_size; i++) {
+ UvElement *element;
PointerRNA itemptr;
- UvElement *element = stitch_state->selection_stack[i];
-
+ if (state->mode == STITCH_VERT) {
+ element = state->selection_stack[i];
+ }
+ else {
+ element = ((UvEdge *)state->selection_stack[i])->element;
+ }
RNA_collection_add(op->ptr, "selection", &itemptr);
- RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->face));
-
+ RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f));
RNA_int_set(&itemptr, "element_index", element->tfindex);
}
-
uvedit_live_unwrap_update(sima, scene, obedit);
}
if (sa)
ED_area_headerprint(sa, NULL);
- ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle);
+ ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- stitch_state_delete(stitch_state);
+ state_delete(state);
op->customdata = NULL;
-
- stitch_preview_delete();
}
@@ -1398,7 +2000,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
}
}
-static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *stitch_state)
+static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *state)
{
/* add uv under mouse to processed uv's */
float co[2];
@@ -1407,42 +2009,53 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState
Image *ima = CTX_data_edit_image(C);
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
- uv_find_nearest_vert(scene, ima, stitch_state->em, co, NULL, &hit);
- if (hit.efa) {
- /* Add vertex to selection, deselect all common uv's of vert other
- * than selected and update the preview. This behavior was decided so that
- * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
+ if (state->mode == STITCH_VERT) {
+ uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit);
- /* This works due to setting of tmp in find nearest uv vert */
- UvElement *element = ED_uv_element_get(stitch_state->element_map, hit.efa, hit.l);
- stitch_select_uv(element, stitch_state, 0);
+ if (hit.efa) {
+ /* Add vertex to selection, deselect all common uv's of vert other
+ * than selected and update the preview. This behavior was decided so that
+ * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
+ /* This works due to setting of tmp in find nearest uv vert */
+ UvElement *element = ED_uv_element_get(state->element_map, hit.efa, hit.l);
+ stitch_select_uv(element, state, FALSE);
+
+ }
+ }
+ else {
+ uv_find_nearest_edge(scene, ima, state->em, co, &hit);
+
+ if (hit.efa) {
+ UvEdge *edge = uv_edge_get(hit.l, state);
+ stitch_select_edge(edge, state, FALSE);
+ }
}
}
static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
{
- StitchState *stitch_state;
+ StitchState *state;
Scene *scene = CTX_data_scene(C);
- stitch_state = (StitchState *)op->customdata;
+ state = (StitchState *)op->customdata;
switch (event->type) {
case MIDDLEMOUSE:
return OPERATOR_PASS_THROUGH;
- /* Cancel */
+ /* Cancel */
case ESCKEY:
return stitch_cancel(C, op);
case LEFTMOUSE:
if (event->shift && (U.flag & USER_LMOUSESELECT)) {
- if (event->val == KM_RELEASE) {
- stitch_select(C, scene, event, stitch_state);
+ if (event->val == KM_PRESS) {
+ stitch_select(C, scene, event, state);
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
}
@@ -1451,7 +2064,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
case PADENTER:
case RETKEY:
if (event->val == KM_PRESS) {
- if (stitch_process_data(stitch_state, scene, 1)) {
+ if (stitch_process_data(state, scene, TRUE)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
@@ -1462,12 +2075,12 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
else {
return OPERATOR_PASS_THROUGH;
}
- /* Increase limit */
+ /* Increase limit */
case PADPLUSKEY:
case WHEELUPMOUSE:
if (event->val == KM_PRESS && event->alt) {
- stitch_state->limit_dist += 0.01f;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->limit_dist += 0.01f;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1475,13 +2088,13 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
else {
return OPERATOR_PASS_THROUGH;
}
- /* Decrease limit */
+ /* Decrease limit */
case PADMINUS:
case WHEELDOWNMOUSE:
if (event->val == KM_PRESS && event->alt) {
- stitch_state->limit_dist -= 0.01f;
- stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist);
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->limit_dist -= 0.01f;
+ state->limit_dist = MAX2(0.01f, state->limit_dist);
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1490,11 +2103,11 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_PASS_THROUGH;
}
- /* Use Limit (Default off)*/
+ /* Use Limit (Default off)*/
case LKEY:
if (event->val == KM_PRESS) {
- stitch_state->use_limit = !stitch_state->use_limit;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->use_limit = !state->use_limit;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1503,10 +2116,10 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
case IKEY:
if (event->val == KM_PRESS) {
- stitch_state->static_island++;
- stitch_state->static_island %= stitch_state->element_map->totalIslands;
+ state->static_island++;
+ state->static_island %= state->element_map->totalIslands;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1515,33 +2128,33 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
case MKEY:
if (event->val == KM_PRESS) {
- stitch_state->midpoints = !stitch_state->midpoints;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->midpoints = !state->midpoints;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
}
break;
- /* Select geometry*/
+ /* Select geometry*/
case RIGHTMOUSE:
if (!event->shift) {
return stitch_cancel(C, op);
}
- if (event->val == KM_RELEASE && !(U.flag & USER_LMOUSESELECT)) {
- stitch_select(C, scene, event, stitch_state);
+ if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) {
+ stitch_select(C, scene, event, state);
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
}
return OPERATOR_RUNNING_MODAL;
- /* snap islands on/off */
+ /* snap islands on/off */
case SKEY:
if (event->val == KM_PRESS) {
- stitch_state->snap_islands = !stitch_state->snap_islands;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->snap_islands = !state->snap_islands;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1550,12 +2163,23 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+ /* switch between edge/vertex mode */
+ case TABKEY:
+ if (event->val == KM_PRESS) {
+ stitch_switch_selection_mode(state);
+
+ if (!stitch_process_data(state, scene, FALSE)) {
+ return stitch_cancel(C, op);
+ }
+ }
+ break;
+
default:
return OPERATOR_RUNNING_MODAL;
}
/* if updated settings, renew feedback message */
- stitch_update_header(stitch_state, C);
+ stitch_update_header(state, C);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_RUNNING_MODAL;
}
@@ -1564,6 +2188,12 @@ void UV_OT_stitch(wmOperatorType *ot)
{
PropertyRNA *prop;
+ static EnumPropertyItem stitch_modes[] = {
+ {STITCH_VERT, "VERTEX", 0, "Vertex", ""},
+ {STITCH_EDGE, "EDGE", 0, "Edge", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
/* identifiers */
ot->name = "Stitch";
ot->description = "Stitch selected UV vertices by proximity";
@@ -1590,6 +2220,11 @@ void UV_OT_stitch(wmOperatorType *ot)
"UVs are stitched at midpoint instead of at static island");
RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams",
"Clear seams of stitched edges");
+ RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode",
+ "Use vertex or edge stitching");
+ prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode",
+ "Use vertex or edge stitching");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
/* Selection should not be editable or viewed in toolbar */
RNA_def_property_flag(prop, PROP_HIDDEN);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 1f3f21967f4..4ddf4bd6a5c 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -87,6 +87,24 @@
#include "uvedit_intern.h"
#include "uvedit_parametrizer.h"
+static void modifier_unwrap_state(Object *obedit, Scene *scene, short *use_subsurf)
+{
+ ModifierData *md;
+ short subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+
+ md = obedit->modifiers.first;
+
+ /* subsurf will take the modifier settings only if modifier is first or right after mirror */
+ if (subsurf) {
+ if (md && md->type == eModifierType_Subsurf)
+ subsurf = TRUE;
+ else
+ subsurf = FALSE;
+ }
+
+ *use_subsurf = subsurf;
+}
+
static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
{
Main *bmain = CTX_data_main(C);
@@ -143,13 +161,16 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
/****************** Parametrizer Conversion ***************/
-static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit)
+static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit)
{
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ if (!CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) {
+ return (em->bm->totfacesel != 0);
+ }
+
/* verify if we have any selected uv's before unwrapping,
* so we can cancel the operator early */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -157,14 +178,10 @@ static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit)
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
continue;
}
- else if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) || !BM_elem_flag_test(efa, BM_ELEM_SELECT))
+ else if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- if (!luv)
- return 1;
-
if (uvedit_uv_select_test(em, scene, l))
break;
}
@@ -172,13 +189,13 @@ static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit)
if (implicit && !l)
continue;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-static void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
+void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
{
int sloppy = TRUE;
int selected = FALSE;
@@ -208,6 +225,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
short implicit, short fill, short sel,
short correct_aspect)
{
+ BMesh *bm = em->bm;
ScanFillContext sf_ctx;
ParamHandle *handle;
BMFace *efa;
@@ -215,12 +233,15 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
BMEdge *eed;
BMIter iter, liter;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
handle = param_construct_begin();
+
if (correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
@@ -266,7 +287,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
* about which split is best for unwrapping than scanfill */
i = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
vkeys[i] = (ParamKey)BM_elem_index_get(l->v);
co[i] = l->v->co;
uv[i] = luv->uv;
@@ -314,7 +335,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
ls[2] = sf_tri->v3->tmp.p;
for (i = 0; i < 3; i++) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, ls[i]->head.data, CD_MLOOPUV);
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(ls[i], cd_loop_uv_offset);
vkeys[i] = (ParamKey)BM_elem_index_get(ls[i]->v);
co[i] = ls[i]->v->co;
uv[i] = luv->uv;
@@ -346,7 +367,8 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
}
-static void texface_from_original_index(BMFace *efa, int index, float **uv, ParamBool *pin, ParamBool *select, Scene *scene, BMEditMesh *em)
+static void texface_from_original_index(BMFace *efa, int index, float **uv, ParamBool *pin, ParamBool *select,
+ Scene *scene, BMEditMesh *em, const int cd_loop_uv_offset)
{
BMLoop *l;
BMIter liter;
@@ -361,10 +383,11 @@ static void texface_from_original_index(BMFace *efa, int index, float **uv, Para
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_index_get(l->v) == index) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
*uv = luv->uv;
*pin = (luv->flag & MLOOPUV_PINNED) ? 1 : 0;
*select = (uvedit_uv_select_test(em, scene, l) != 0);
+ break;
}
}
}
@@ -379,6 +402,9 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
MEdge *edge;
int i;
+ /* pointers to modifier data for unwrap control */
+ ModifierData *md;
+ SubsurfModifierData *smd_real;
/* modifier initialization data, will control what type of subdivision will happen*/
SubsurfModifierData smd = {{0}};
/* Used to hold subsurfed Mesh */
@@ -397,20 +423,25 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* similar to the above, we need a way to map edges to their original ones */
BMEdge **edgeMap;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
handle = param_construct_begin();
if (correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
}
/* number of subdivisions to perform */
- smd.levels = scene->toolsettings->uv_subsurf_level;
- smd.subdivType = ME_CC_SUBSURF;
+ md = ob->modifiers.first;
+ smd_real = (SubsurfModifierData *)md;
+
+ smd.levels = smd_real->levels;
+ smd.subdivType = smd_real->subdivType;
initialDerived = CDDM_from_editbmesh(em, FALSE, FALSE);
derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd,
@@ -434,7 +465,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map");
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
- EDBM_index_arrays_init(em, 0, 1, 1);
+ EDBM_index_arrays_ensure(em, BM_EDGE | BM_FACE);
/* map subsurfed faces to original editFaces */
for (i = 0; i < numOfFaces; i++)
@@ -445,12 +476,10 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* map subsurfed edges to original editEdges */
for (i = 0; i < numOfEdges; i++) {
/* not all edges correspond to an old edge */
- edgeMap[i] = (origEdgeIndices[i] != -1) ?
+ edgeMap[i] = (origEdgeIndices[i] != ORIGINDEX_NONE) ?
EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL;
}
- EDBM_index_arrays_free(em);
-
/* Prepare and feed faces to the solver */
for (i = 0; i < numOfFaces; i++) {
ParamKey key, vkeys[4];
@@ -484,10 +513,10 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* This is where all the magic is done. If the vertex exists in the, we pass the original uv pointer to the solver, thus
* flushing the solution to the edit mesh. */
- texface_from_original_index(origFace, origVertIndices[face->v1], &uv[0], &pin[0], &select[0], scene, em);
- texface_from_original_index(origFace, origVertIndices[face->v2], &uv[1], &pin[1], &select[1], scene, em);
- texface_from_original_index(origFace, origVertIndices[face->v3], &uv[2], &pin[2], &select[2], scene, em);
- texface_from_original_index(origFace, origVertIndices[face->v4], &uv[3], &pin[3], &select[3], scene, em);
+ texface_from_original_index(origFace, origVertIndices[face->v1], &uv[0], &pin[0], &select[0], scene, em, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[face->v2], &uv[1], &pin[1], &select[1], scene, em, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[face->v3], &uv[2], &pin[2], &select[2], scene, em, cd_loop_uv_offset);
+ texface_from_original_index(origFace, origVertIndices[face->v4], &uv[3], &pin[3], &select[3], scene, em, cd_loop_uv_offset);
param_face_add(handle, key, 4, vkeys, co, uv, pin, select);
}
@@ -525,17 +554,17 @@ typedef struct MinStretch {
wmTimer *timer;
} MinStretch;
-static int minimize_stretch_init(bContext *C, wmOperator *op)
+static bool minimize_stretch_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
MinStretch *ms;
int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
- short implicit = 1;
+ bool implicit = true;
if (!uvedit_have_selection(scene, em, implicit)) {
- return 0;
+ return false;
}
ms = MEM_callocN(sizeof(MinStretch), "MinStretch");
@@ -554,7 +583,7 @@ static int minimize_stretch_init(bContext *C, wmOperator *op)
op->customdata = ms;
- return 1;
+ return true;
}
static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interactive)
@@ -574,7 +603,7 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interact
param_flush(ms->handle);
if (sa) {
- BLI_snprintf(str, sizeof(str), "Minimize Stretch. Blend %.2f", ms->blend);
+ BLI_snprintf(str, sizeof(str), "Minimize Stretch. Blend %.2f (Press + and -, or scroll wheel to set)", ms->blend);
ED_area_headerprint(sa, str);
}
@@ -657,20 +686,24 @@ static int minimize_stretch_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
case PADPLUSKEY:
case WHEELUPMOUSE:
- if (ms->blend < 0.95f) {
- ms->blend += 0.1f;
- ms->lasttime = 0.0f;
- RNA_float_set(op->ptr, "blend", ms->blend);
- minimize_stretch_iteration(C, op, 1);
+ if (event->val == KM_PRESS) {
+ if (ms->blend < 0.95f) {
+ ms->blend += 0.1f;
+ ms->lasttime = 0.0f;
+ RNA_float_set(op->ptr, "blend", ms->blend);
+ minimize_stretch_iteration(C, op, 1);
+ }
}
break;
case PADMINUS:
case WHEELDOWNMOUSE:
- if (ms->blend > 0.05f) {
- ms->blend -= 0.1f;
- ms->lasttime = 0.0f;
- RNA_float_set(op->ptr, "blend", ms->blend);
- minimize_stretch_iteration(C, op, 1);
+ if (event->val == KM_PRESS) {
+ if (ms->blend > 0.05f) {
+ ms->blend -= 0.1f;
+ ms->lasttime = 0.0f;
+ RNA_float_set(op->ptr, "blend", ms->blend);
+ minimize_stretch_iteration(C, op, 1);
+ }
}
break;
case TIMER:
@@ -728,7 +761,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
ParamHandle *handle;
- short implicit = 1;
+ bool implicit = true;
if (!uvedit_have_selection(scene, em, implicit)) {
return OPERATOR_CANCELLED;
@@ -775,7 +808,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
ParamHandle *handle;
- short implicit = 1;
+ bool implicit = true;
if (!uvedit_have_selection(scene, em, implicit)) {
return OPERATOR_CANCELLED;
@@ -815,16 +848,18 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
BMEditMesh *em = BMEdit_FromObject(obedit);
short abf = scene->toolsettings->unwrapper == 0;
short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
- short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+ short use_subsurf;
+
+ modifier_unwrap_state(obedit, scene, &use_subsurf);
if (!ED_uvedit_test(obedit)) {
return;
}
if (use_subsurf)
- liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, 0, 1);
+ liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, FALSE, TRUE);
else
- liveHandle = construct_param_handle(scene, obedit, em, 0, fillholes, 0, 1);
+ liveHandle = construct_param_handle(scene, obedit, em, FALSE, fillholes, FALSE, TRUE);
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
}
@@ -871,16 +906,18 @@ void ED_uvedit_live_unwrap(Scene *scene, Object *obedit)
static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result,
Object *ob, BMEditMesh *em)
{
- BMFace *efa;
- BMLoop *l;
- BMIter iter, liter;
- float min[3], max[3], *cursx;
int around = (v3d) ? v3d->around : V3D_CENTER;
/* only operates on the edit object - this is all that's needed now */
switch (around) {
case V3D_CENTER: /* bounding box center */
+ {
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ float min[3], max[3];
+
INIT_MINMAX(min, max);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -892,22 +929,23 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result,
}
mid_v3_v3v3(result, min, max);
break;
-
+ }
case V3D_CURSOR: /* cursor center */
- cursx = give_cursor(scene, v3d);
+ {
+ const float *curs = give_cursor(scene, v3d);
/* shift to objects world */
- sub_v3_v3v3(result, cursx, ob->obmat[3]);
+ sub_v3_v3v3(result, curs, ob->obmat[3]);
break;
-
+ }
case V3D_LOCAL: /* object center */
case V3D_CENTROID: /* multiple objects centers, only one object here*/
default:
- result[0] = result[1] = result[2] = 0.0;
+ zero_v3(result);
break;
}
}
-static void uv_map_rotation_matrix(float result[][4], RegionView3D *rv3d, Object *ob,
+static void uv_map_rotation_matrix(float result[4][4], RegionView3D *rv3d, Object *ob,
float upangledeg, float sideangledeg, float radius)
{
float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4];
@@ -938,18 +976,18 @@ static void uv_map_rotation_matrix(float result[][4], RegionView3D *rv3d, Object
/* this is "kanonen gegen spatzen", a few plus minus 1 will do here */
/* i wanted to keep the reason here, so we're rotating*/
sideangle = (float)M_PI * (sideangledeg + 180.0f) / 180.0f;
- rotside[0][0] = (float)cos(sideangle);
- rotside[0][1] = -(float)sin(sideangle);
- rotside[1][0] = (float)sin(sideangle);
- rotside[1][1] = (float)cos(sideangle);
- rotside[2][2] = 1.0f;
+ rotside[0][0] = cosf(sideangle);
+ rotside[0][1] = -sinf(sideangle);
+ rotside[1][0] = sinf(sideangle);
+ rotside[1][1] = cosf(sideangle);
+ rotside[2][2] = 1.0f;
upangle = (float)M_PI * upangledeg / 180.0f;
- rotup[1][1] = (float)cos(upangle) / radius;
- rotup[1][2] = -(float)sin(upangle) / radius;
- rotup[2][1] = (float)sin(upangle) / radius;
- rotup[2][2] = (float)cos(upangle) / radius;
- rotup[0][0] = (float)1.0f / radius;
+ rotup[1][1] = cosf(upangle) / radius;
+ rotup[1][2] = -sinf(upangle) / radius;
+ rotup[2][1] = sinf(upangle) / radius;
+ rotup[2][2] = cosf(upangle) / radius;
+ rotup[0][0] = 1.0f / radius;
/* calculate transforms*/
mul_serie_m4(result, rotup, rotside, viewmatrix, rotobj, NULL, NULL, NULL, NULL);
@@ -1020,7 +1058,9 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
BMFace *efa;
float scale, aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx == aspy)
return;
@@ -1029,11 +1069,11 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
scale = aspy / aspx;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_SELECT) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
+ if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[0] = ((luv->uv[0] - 0.5f) * scale) + 0.5f;
}
}
@@ -1042,11 +1082,11 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
scale = aspx / aspy;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_SELECT) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
+ if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[1] = ((luv->uv[1] - 0.5f) * scale) + 0.5f;
}
}
@@ -1076,6 +1116,8 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
int clip_to_bounds = RNA_boolean_get(op->ptr, "clip_to_bounds");
int scale_to_bounds = RNA_boolean_get(op->ptr, "scale_to_bounds");
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
/* correct for image aspect ratio */
if (correct_aspect)
correct_uv_aspect(scene, ob, em);
@@ -1088,7 +1130,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
minmax_v2v2_v2(min, max, luv->uv);
}
}
@@ -1107,7 +1149,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ 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;
@@ -1121,7 +1163,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
CLAMP(luv->uv[0], 0.0f, 1.0f);
CLAMP(luv->uv[1], 0.0f, 1.0f);
}
@@ -1139,12 +1181,14 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
const short fill_holes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
const short correct_aspect = !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT);
- const short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+ short use_subsurf;
+
+ modifier_unwrap_state(obedit, scene, &use_subsurf);
if (use_subsurf)
handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect);
else
- handle = construct_param_handle(scene, obedit, em, 0, fill_holes, sel, correct_aspect);
+ handle = construct_param_handle(scene, obedit, em, FALSE, fill_holes, sel, correct_aspect);
param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
param_lscm_solve(handle);
@@ -1167,9 +1211,9 @@ static int unwrap_exec(bContext *C, wmOperator *op)
int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
int use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data");
- int subsurf_level = RNA_int_get(op->ptr, "uv_subsurf_level");
+ short use_subsurf_final;
float obsize[3];
- short implicit = 0;
+ bool implicit = false;
if (!uvedit_have_selection(scene, em, implicit)) {
return OPERATOR_CANCELLED;
@@ -1197,8 +1241,6 @@ static int unwrap_exec(bContext *C, wmOperator *op)
else
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
- scene->toolsettings->uv_subsurf_level = subsurf_level;
-
if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES;
else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES;
@@ -1208,6 +1250,12 @@ static int unwrap_exec(bContext *C, wmOperator *op)
if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF;
else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF;
+ /* double up the check here but better keep ED_unwrap_lscm interface simple and not
+ * pass operator for warning append */
+ modifier_unwrap_state(obedit, scene, &use_subsurf_final);
+ if (use_subsurf != use_subsurf_final)
+ BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap");
+
/* execute unwrap */
ED_unwrap_lscm(scene, obedit, TRUE);
@@ -1242,10 +1290,8 @@ void UV_OT_unwrap(wmOperatorType *ot)
"Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry");
RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect",
"Map UVs taking image aspect ratio into account");
- RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data",
+ RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Modifier",
"Map UVs taking vertex position after subsurf into account");
- RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target",
- "Number of times to subdivide before calculating UVs", 1, 6);
RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
@@ -1265,11 +1311,15 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
float rotmat[4][4];
+ 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(&em->bm->ldata, CD_MLOOPUV);
+
/* establish the camera object, so we can default to view mapping if anything is wrong with it */
if ((rv3d->persp == RV3D_CAMOB) && (v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
camera = v3d->camera->data;
@@ -1283,7 +1333,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
BLI_uvproject_from_view_ortho(luv->uv, l->v->co, rotmat);
}
}
@@ -1297,7 +1347,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
BLI_uvproject_from_camera(luv->uv, l->v->co, uci);
}
}
@@ -1313,7 +1363,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
BLI_uvproject_from_view(luv->uv, l->v->co, rv3d->persmat, rotmat, ar->winx, ar->winy);
}
}
@@ -1337,7 +1387,7 @@ static int uv_from_view_poll(bContext *C)
return (rv3d != NULL);
}
-void UV_OT_from_view(wmOperatorType *ot)
+void UV_OT_project_from_view(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Project From View";
@@ -1413,16 +1463,15 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
BMLoop *l;
BMIter liter;
MLoopUV *luv;
- float **uvs = NULL;
- BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__);
+ float **uvs = BLI_array_alloca(uvs, efa->len);
float dx;
int i, mi;
- i = 0;
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uvs[i] = luv->uv;
- i++;
}
mi = 0;
@@ -1436,8 +1485,6 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
if (dx > 0.5f) uvs[i][0] += 1.0f;
}
}
-
- BLI_array_fixedstack_free(uvs);
}
static int sphere_project_exec(bContext *C, wmOperator *op)
@@ -1452,11 +1499,15 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
float center[3], rotmat[4][4];
+ 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(&em->bm->ldata, CD_MLOOPUV);
+
uv_map_transform(C, op, center, rotmat);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -1464,7 +1515,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv_sphere_project(luv->uv, l->v->co, center, rotmat);
}
@@ -1527,24 +1578,28 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
float center[3], rotmat[4][4];
+ 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(&em->bm->ldata, CD_MLOOPUV);
+
uv_map_transform(C, op, center, rotmat);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv_cylinder_project(luv->uv, l->v->co, center, rotmat);
}
+ tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
uv_map_mirror(em, efa, tf);
}
@@ -1589,11 +1644,15 @@ static int cube_project_exec(bContext *C, wmOperator *op)
float cube_size, *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(&em->bm->ldata, CD_MLOOPUV);
+
loc = obedit->obmat[3];
cube_size = RNA_float_get(op->ptr, "cube_size");
@@ -1611,7 +1670,7 @@ static int cube_project_exec(bContext *C, wmOperator *op)
dx = dy = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
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]);
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 9ce42d9e0bb..6abc41759e7 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -28,6 +28,7 @@ set(INC
../blenkernel
../blenlib
../blenloader
+ ../bmesh
../imbuf
../makesdna
../makesrna
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 36fbd818f11..9f6f80585ab 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -39,12 +39,15 @@
#define DEBUG_VBO(X)
#endif
+struct BMesh;
struct CCGElem;
struct CCGKey;
struct CustomData;
struct DMFlagMat;
struct DerivedMesh;
+struct GHash;
struct GPUVertPointLink;
+struct PBVH;
typedef struct GPUBuffer {
int size; /* in bytes */
@@ -168,12 +171,21 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid,
unsigned int **grid_hidden, int gridsize);
+GPU_Buffers *GPU_build_bmesh_buffers(int smooth_shading);
+
+void GPU_update_bmesh_buffers(GPU_Buffers *buffers,
+ struct BMesh *bm,
+ struct GHash *bm_faces,
+ struct GHash *bm_unique_verts,
+ struct GHash *bm_other_verts);
+
void GPU_update_grid_buffers(GPU_Buffers *buffers, struct CCGElem **grids,
const struct DMFlagMat *grid_flag_mats,
int *grid_indices, int totgrid, const struct CCGKey *key,
int show_diffuse_color);
-void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial);
+void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial,
+ int wireframe);
int GPU_buffers_diffuse_changed(GPU_Buffers *buffers, int show_diffuse_color);
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index b26c25558c3..974865db1c0 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -93,7 +93,7 @@ int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp);
int GPU_default_lights(void);
int GPU_scene_object_lights(struct Scene *scene, struct Object *ob,
- int lay, float viewmat[][4], int ortho);
+ int lay, float viewmat[4][4], int ortho);
/* Text render
* - based on moving uv coordinates */
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 7eaa4084e61..66a7c917a55 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -38,7 +38,8 @@ extern "C" {
struct Image;
struct ImageUser;
-
+struct PreviewImage;
+
struct GPUTexture;
typedef struct GPUTexture GPUTexture;
@@ -112,6 +113,8 @@ 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_from_blender(struct Image *ima,
struct ImageUser *iuser, int isdata, double time, int mipmap);
+GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
+
void GPU_texture_free(GPUTexture *tex);
void GPU_texture_ref(GPUTexture *tex);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index c46230de8bf..17d3ce3cd73 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -54,6 +54,7 @@ struct GPUNodeStack;
struct GPUMaterial;
struct GPUTexture;
struct GPULamp;
+struct PreviewImage;
typedef struct GPUNode GPUNode;
typedef struct GPUNodeLink GPUNodeLink;
@@ -108,6 +109,7 @@ GPUNodeLink *GPU_attribute(int type, const char *name);
GPUNodeLink *GPU_uniform(float *num);
GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data);
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, int isdata);
+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_builtin(GPUBuiltin builtin);
@@ -122,12 +124,13 @@ GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
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_materials_free(void);
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap);
-void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale);
+void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material);
@@ -232,10 +235,11 @@ void GPU_lamp_free(struct Object *ob);
int GPU_lamp_has_shadow_buffer(GPULamp *lamp);
void GPU_lamp_update_buffer_mats(GPULamp *lamp);
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]);
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
+int GPU_lamp_shadow_buffer_type(GPULamp *lamp);
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]);
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2);
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index 9b8a86eac15..f7db3dfeaa0 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
@@ -7,7 +33,7 @@ sources += env.Glob('shaders/*.c')
defs = [ 'GLEW_STATIC' ]
incs = '../blenlib ../blenkernel ../makesdna ../makesrna ../include ../blenloader ../nodes ../nodes/intern'
-incs += ' #/extern/glew/include #intern/guardedalloc #intern/smoke/extern ../imbuf .'
+incs += ' #/extern/glew/include #intern/guardedalloc #intern/smoke/extern ../imbuf ../bmesh .'
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 6e475ace09d..5bef7a8ae0b 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -45,6 +45,7 @@
#include "BLI_threads.h"
#include "DNA_meshdata_types.h"
+#include "DNA_material_types.h"
#include "BKE_ccg.h"
#include "BKE_DerivedMesh.h"
@@ -56,6 +57,8 @@
#include "GPU_buffers.h"
#include "GPU_draw.h"
+#include "bmesh.h"
+
typedef enum {
GPU_BUFFER_VERTEX_STATE = 1,
GPU_BUFFER_NORMAL_STATE = 2,
@@ -66,8 +69,8 @@ typedef enum {
#define MAX_GPU_ATTRIB_DATA 32
-/* material number is an 16-bit short and the range of short is from -16383 to 16383 (assume material number is non-negative) */
-#define MAX_MATERIALS 16384
+/* material number is an 16-bit signed short and the range (assume material number is non-negative) */
+#define MAX_MATERIALS MAXMAT
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
static int useVBOs = -1;
@@ -1268,6 +1271,8 @@ struct GPU_Buffers {
int totgrid;
int has_hidden;
+ int use_bmesh;
+
unsigned int tot_tri, tot_quad;
/* The PBVH ensures that either all faces in the node are
@@ -1386,7 +1391,7 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
if (vert_data) {
- /* Vertex data is shared if smooth-shaded, but seperate
+ /* Vertex data is shared if smooth-shaded, but separate
copies are made for flat shading because normals
shouldn't be shared. */
if (buffers->smooth) {
@@ -1861,6 +1866,244 @@ GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid,
#undef FILL_QUAD_BUFFER
+/* Output a BMVert into a VertexBufferFormat array
+ *
+ * The vertex is skipped if hidden, otherwise the output goes into
+ * index '*v_index' in the 'vert_data' array and '*v_index' is
+ * incremented.
+ */
+static void gpu_bmesh_vert_to_buffer_copy(BMVert *v, BMesh *bm,
+ VertexBufferFormat *vert_data,
+ int *v_index,
+ const float fno[3],
+ const float *fmask)
+{
+ VertexBufferFormat *vd = &vert_data[*v_index];
+ float *mask;
+
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ /* TODO: should use material color */
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+ /* Set coord, normal, and mask */
+ copy_v3_v3(vd->co, v->co);
+ normal_float_to_short_v3(vd->no, fno ? fno : v->no);
+ mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
+ gpu_color_from_mask_copy(fmask ? *fmask : *mask,
+ diffuse_color,
+ vd->color);
+
+
+ /* Assign index for use in the triangle index buffer */
+ BM_elem_index_set(v, (*v_index)); /* set_dirty! */
+
+ (*v_index)++;
+ }
+}
+
+/* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
+static int gpu_bmesh_vert_visible_count(GHash *bm_unique_verts,
+ GHash *bm_other_verts)
+{
+ GHashIterator gh_iter;
+ int totvert = 0;
+
+ GHASH_ITER (gh_iter, bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
+ totvert++;
+ }
+ GHASH_ITER (gh_iter, bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
+ totvert++;
+ }
+
+ return totvert;
+}
+
+/* Return the total number of visible faces */
+static int gpu_bmesh_face_visible_count(GHash *bm_faces)
+{
+ GHashIterator gh_iter;
+ int totface = 0;
+
+ GHASH_ITER (gh_iter, bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ if (!paint_is_bmesh_face_hidden(f))
+ totface++;
+ }
+
+ return totface;
+}
+
+/* Creates a vertex buffer (coordinate, normal, color) and, if smooth
+ shading, an element index buffer. */
+void GPU_update_bmesh_buffers(GPU_Buffers *buffers,
+ BMesh *bm,
+ GHash *bm_faces,
+ GHash *bm_unique_verts,
+ GHash *bm_other_verts)
+{
+ VertexBufferFormat *vert_data;
+ void *tri_data;
+ int tottri, totvert, maxvert = 0;
+
+ if (!buffers->vert_buf || (buffers->smooth && !buffers->index_buf))
+ return;
+
+ /* Count visible triangles */
+ tottri = gpu_bmesh_face_visible_count(bm_faces);
+
+ if (buffers->smooth) {
+ /* Count visible vertices */
+ totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
+ }
+ else
+ totvert = tottri * 3;
+
+ /* Initialize vertex buffer */
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(VertexBufferFormat) * totvert,
+ NULL, GL_STATIC_DRAW_ARB);
+
+ /* Fill vertex buffer */
+ vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ if (vert_data) {
+ GHashIterator gh_iter;
+ int v_index = 0;
+
+ if (buffers->smooth) {
+ /* Vertices get an index assigned for use in the triangle
+ index buffer */
+ bm->elem_index_dirty |= BM_VERT;
+
+ GHASH_ITER (gh_iter, bm_unique_verts) {
+ gpu_bmesh_vert_to_buffer_copy(BLI_ghashIterator_getKey(&gh_iter),
+ bm, vert_data, &v_index, NULL, NULL);
+ }
+
+ GHASH_ITER (gh_iter, bm_other_verts) {
+ gpu_bmesh_vert_to_buffer_copy(BLI_ghashIterator_getKey(&gh_iter),
+ bm, vert_data, &v_index, NULL, NULL);
+ }
+
+ maxvert = v_index;
+ }
+ else {
+ GHASH_ITER (gh_iter, bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ BLI_assert(f->len == 3);
+
+ if (!paint_is_bmesh_face_hidden(f)) {
+ BMVert *v[3];
+ float fmask = 0;
+ int i;
+
+ // BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3);
+ BM_face_as_array_vert_tri(f, v);
+
+ /* Average mask value */
+ for (i = 0; i < 3; i++) {
+ fmask += *((float*)CustomData_bmesh_get(&bm->vdata,
+ v[i]->head.data,
+ CD_PAINT_MASK));
+ }
+ fmask /= 3.0f;
+
+ for (i = 0; i < 3; i++) {
+ gpu_bmesh_vert_to_buffer_copy(v[i], bm, vert_data,
+ &v_index, f->no, &fmask);
+ }
+ }
+ }
+
+ buffers->tot_tri = tottri;
+ }
+
+ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+ }
+ else {
+ /* Memory map failed */
+ glDeleteBuffersARB(1, &buffers->vert_buf);
+ buffers->vert_buf = 0;
+ return;
+ }
+
+ if (buffers->smooth) {
+ const int use_short = (maxvert < USHRT_MAX);
+
+ /* Initialize triangle index buffer */
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ (use_short ?
+ sizeof(unsigned short) :
+ sizeof(unsigned int)) * 3 * tottri,
+ NULL, GL_STATIC_DRAW_ARB);
+
+ /* Fill triangle index buffer */
+ tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ if (tri_data) {
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ if (!paint_is_bmesh_face_hidden(f)) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BMVert *v = l_iter->v;
+ if (use_short) {
+ unsigned short *elem = tri_data;
+ (*elem) = BM_elem_index_get(v);
+ elem++;
+ tri_data = elem;
+ }
+ else {
+ unsigned int *elem = tri_data;
+ (*elem) = BM_elem_index_get(v);
+ elem++;
+ tri_data = elem;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+
+ buffers->tot_tri = tottri;
+ buffers->index_type = (use_short ?
+ GL_UNSIGNED_SHORT :
+ GL_UNSIGNED_INT);
+ }
+ else {
+ /* Memory map failed */
+ glDeleteBuffersARB(1, &buffers->index_buf);
+ buffers->index_buf = 0;
+ }
+ }
+}
+
+GPU_Buffers *GPU_build_bmesh_buffers(int smooth_shading)
+{
+ GPU_Buffers *buffers;
+
+ buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers");
+ if (smooth_shading)
+ glGenBuffersARB(1, &buffers->index_buf);
+ glGenBuffersARB(1, &buffers->vert_buf);
+ buffers->use_bmesh = TRUE;
+ buffers->smooth = smooth_shading;
+
+ return buffers;
+}
+
static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers)
{
const MVert *mvert = buffers->mvert;
@@ -2059,7 +2302,8 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
}
}
-void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
+void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial,
+ int wireframe)
{
if (buffers->totface) {
const MFace *f = &buffers->mface[buffers->face_indices[0]];
@@ -2076,14 +2320,19 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
if (buffers->vert_buf) {
glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- gpu_colors_enable(VBO_ENABLED);
+ if (!wireframe) {
+ glEnableClientState(GL_NORMAL_ARRAY);
+ gpu_colors_enable(VBO_ENABLED);
+ }
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
if (buffers->index_buf)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+ if (wireframe)
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
if (buffers->tot_quad) {
char *offset = 0;
int i, last = buffers->has_hidden ? 1 : buffers->totgrid;
@@ -2116,13 +2365,18 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
glDrawArrays(GL_TRIANGLES, 0, totelem);
}
+ if (wireframe)
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
if (buffers->index_buf)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- gpu_colors_disable(VBO_ENABLED);
+ if (!wireframe) {
+ glDisableClientState(GL_NORMAL_ARRAY);
+ gpu_colors_disable(VBO_ENABLED);
+ }
}
/* fallbacks if we are out of memory or VBO is disabled */
else if (buffers->totface) {
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 4432627ee7e..b27a4be9f21 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -68,6 +68,9 @@ static char *glsl_material_library = NULL;
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. */
@@ -339,7 +342,7 @@ static int codegen_input_has_texture(GPUInput *input)
{
if (input->link)
return 0;
- else if (input->ima)
+ else if (input->ima || input->prv)
return 1;
else
return input->tex != NULL;
@@ -411,6 +414,17 @@ static void codegen_set_unique_ids(ListBase *nodes)
else
input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, 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));
+ }
else {
if (!BLI_ghash_haskey(bindhash, input->tex)) {
/* input is user created texture, check tex pointer */
@@ -718,7 +732,7 @@ static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
continue;
}
- if (input->ima || input->tex)
+ if (input->ima || input->tex || input->prv)
BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
else
BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
@@ -726,7 +740,7 @@ static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
/* pass non-dynamic uniforms to opengl */
extract = 0;
- if (input->ima || input->tex) {
+ if (input->ima || input->tex || input->prv) {
if (input->bindtex)
extract = 1;
}
@@ -762,11 +776,14 @@ void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
for (input=inputs->first; input; input=input->next) {
if (input->ima)
input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->image_isdata, time, mipmap);
+ else if (input->prv)
+ input->tex = GPU_texture_from_preview(input->prv, mipmap);
if (input->tex && input->bindtex) {
GPU_texture_bind(input->tex, input->texid);
GPU_shader_uniform_texture(shader, input->shaderloc, input->tex);
}
+
}
}
@@ -781,7 +798,7 @@ void GPU_pass_update_uniforms(GPUPass *pass)
/* pass dynamic inputs to opengl, others were removed */
for (input=inputs->first; input; input=input->next)
- if (!(input->ima || input->tex))
+ if (!(input->ima || input->tex || input->prv))
GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
input->dynamicvec);
}
@@ -799,7 +816,7 @@ void GPU_pass_unbind(GPUPass *pass)
if (input->tex && input->bindtex)
GPU_texture_unbind(input->tex);
- if (input->ima)
+ if (input->ima || input->prv)
input->tex = NULL;
}
@@ -915,9 +932,13 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
input->type = GPU_VEC4;
input->source = GPU_SOURCE_TEX;
- input->ima = link->ptr1;
- input->iuser = link->ptr2;
- input->image_isdata = link->image_isdata;
+ if (link->image == LINK_IMAGE_PREVIEW)
+ input->prv = link->ptr1;
+ else {
+ input->ima = link->ptr1;
+ input->iuser = link->ptr2;
+ input->image_isdata = link->image_isdata;
+ }
input->textarget = GL_TEXTURE_2D;
input->textype = GPU_TEX2D;
MEM_freeN(link);
@@ -1117,7 +1138,7 @@ GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
{
GPUNodeLink *link = GPU_node_link_create(0);
- link->image= 1;
+ link->image= LINK_IMAGE_BLENDER;
link->ptr1= ima;
link->ptr2= iuser;
link->image_isdata= isdata;
@@ -1125,6 +1146,17 @@ GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
return link;
}
+GPUNodeLink *GPU_image_preview(PreviewImage *prv)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->image= LINK_IMAGE_PREVIEW;
+ link->ptr1= prv;
+
+ return link;
+}
+
+
GPUNodeLink *GPU_texture(int size, float *pixels)
{
GPUNodeLink *link = GPU_node_link_create(0);
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index f61f34908c5..2e4cfe2e37c 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -43,6 +43,7 @@ struct GPUOutput;
struct GPUNode;
struct GPUVertexAttribs;
struct GPUFrameBuffer;
+struct PreviewImage;
#define MAX_FUNCTION_NAME 64
#define MAX_PARAMETER 32
@@ -138,6 +139,7 @@ typedef struct GPUInput {
struct Image *ima; /* image */
struct ImageUser *iuser;/* image user */
+ struct PreviewImage *prv; /* preview images & icons */
int 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) */
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index d466e59452b..c631f7efbe9 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -52,6 +52,9 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "BLI_threads.h"
+#include "BLI_blenlib.h"
+
#include "BKE_bmfont.h"
#include "BKE_global.h"
#include "BKE_image.h"
@@ -62,9 +65,6 @@
#include "BKE_scene.h"
#include "BKE_DerivedMesh.h"
-#include "BLI_threads.h"
-#include "BLI_blenlib.h"
-
#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
@@ -92,7 +92,7 @@ void GPU_render_text(MTFace *tface, int mode,
float *v1, float *v2, float *v3, float *v4, int glattrib)
{
if ((mode & GEMAT_TEXT) && (textlen>0) && tface->tpage) {
- Image* ima = (Image*)tface->tpage;
+ Image* ima = (Image *)tface->tpage;
int index, character;
float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
float advance_tab;
@@ -101,9 +101,9 @@ void GPU_render_text(MTFace *tface, int mode,
float line_start= 0.0f, line_height;
if (v4)
- line_height= MAX4(v1[1], v2[1], v3[1], v4[2]) - MIN4(v1[1], v2[1], v3[1], v4[2]);
+ line_height = max_ffff(v1[1], v2[1], v3[1], v4[2]) - min_ffff(v1[1], v2[1], v3[1], v4[2]);
else
- line_height= MAX3(v1[1], v2[1], v3[1]) - MIN3(v1[1], v2[1], v3[1]);
+ line_height = max_fff(v1[1], v2[1], v3[1]) - min_fff(v1[1], v2[1], v3[1]);
line_height *= 1.2f; /* could be an option? */
/* end multiline */
@@ -252,6 +252,25 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap)
}
}
+static void gpu_generate_mipmap(GLenum target)
+{
+ int is_ati = GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY);
+ int target_enabled = 0;
+
+ /* work around bug in ATI driver, need to have GL_TEXTURE_2D enabled
+ * http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation */
+ if (is_ati) {
+ target_enabled = glIsEnabled(target);
+ if (!target_enabled)
+ glEnable(target);
+ }
+
+ glGenerateMipmapEXT(target);
+
+ if (is_ati && !target_enabled)
+ glDisable(target);
+}
+
void GPU_set_mipmap(int mipmap)
{
if (GTS.domipmap != (mipmap != 0)) {
@@ -376,7 +395,12 @@ static void gpu_set_alpha_blend(GPUBlendMode alphablend)
}
else if (ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ALPHA_SORT)) {
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* for OpenGL render we use the alpha channel, this makes alpha blend correct */
+ if (GLEW_VERSION_1_4)
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ else
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* if U.glalphaclip == 1.0, some cards go bonkers...
* turn off alpha test in this case */
@@ -537,8 +561,9 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (do_color_management) {
srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(float)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
- ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, 0,
+ ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y);
frect= srgb_frect + texwinsy*ibuf->x + texwinsx;
@@ -562,8 +587,9 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (do_color_management) {
frect = srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(*srgb_frect)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
- ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, 0,
+ ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y);
}
@@ -643,6 +669,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
return *bind;
}
+/* Image *ima can be NULL */
void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
{
unsigned int *scalerect = NULL;
@@ -691,7 +718,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix);
- glGenerateMipmapEXT(GL_TEXTURE_2D);
+ gpu_generate_mipmap(GL_TEXTURE_2D);
}
else {
if (use_high_bit_depth)
@@ -702,7 +729,8 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int
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));
- ima->tpageflag |= IMA_MIPMAP_COMPLETE;
+ if (ima)
+ ima->tpageflag |= IMA_MIPMAP_COMPLETE;
}
if (GLEW_EXT_texture_filter_anisotropic)
@@ -749,11 +777,14 @@ int GPU_upload_dxt_texture(ImBuf *ibuf)
return FALSE;
}
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ 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));
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ if (GLEW_EXT_texture_filter_anisotropic)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
+
blocksize = (ibuf->dds_data.fourcc == FOURCC_DXT1) ? 8 : 16;
for (i=0; i<ibuf->dds_data.nummipmaps && (width||height); ++i) {
if (width == 0)
@@ -791,7 +822,7 @@ void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x,
glBindTexture(GL_TEXTURE_2D, *bind);
if (GPU_upload_dxt_texture(ibuf) == 0) {
- glDeleteTextures(1, (GLuint*)bind);
+ glDeleteTextures(1, (GLuint *)bind);
GPU_create_gl_tex(bind, pix, NULL, x, y, mipmap, 0, ima);
}
#endif
@@ -904,8 +935,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima->repbind || (GPU_get_mipmap() && !GTS.gpu_mipmap) || !ima->bindcode || !ibuf ||
- (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) ||
- (w == 0) || (h == 0))
+ (w == 0) || (h == 0))
{
/* these cases require full reload still */
GPU_free_image(ima);
@@ -934,7 +964,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
/* we have already accounted for the case where GTS.gpu_mipmap is false
* so we will be using GPU mipmap generation here */
if (GPU_get_mipmap()) {
- glGenerateMipmapEXT(GL_TEXTURE_2D);
+ gpu_generate_mipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -959,7 +989,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
/* see comment above as to why we are using gpu mipmap generation here */
if (GPU_get_mipmap()) {
- glGenerateMipmapEXT(GL_TEXTURE_2D);
+ gpu_generate_mipmap(GL_TEXTURE_2D);
}
else {
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
@@ -1259,10 +1289,9 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GPUMaterial *gpumat;
GPUBlendMode alphablend;
int a;
-
int gamma = BKE_scene_check_color_management_enabled(scene);
-
int new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
+ int use_matcap = (v3d->flag2 & V3D_SHOW_SOLID_MATCAP); /* assumes v3d->defmaterial->preview is set */
/* initialize state */
memset(&GMS, 0, sizeof(GMS));
@@ -1274,7 +1303,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.gob = ob;
GMS.gscene = scene;
- GMS.totmat= ob->totcol+1; /* materials start from 1, default material is 0 */
+ GMS.totmat= use_matcap? 1 : ob->totcol+1; /* materials start from 1, default material is 0 */
GMS.glay= (v3d->localvd)? v3d->localvd->lay: v3d->lay; /* keep lamps visible in local view */
GMS.gviewmat= rv3d->viewmat;
GMS.gviewinv= rv3d->viewinv;
@@ -1300,59 +1329,72 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.alphablend= GMS.alphablend_fixed;
}
- /* no materials assigned? */
- if (ob->totcol==0) {
- gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes);
-
+ /* viewport material, setup in space_view3d, defaults to matcap using ma->preview now */
+ if (use_matcap) {
+ GMS.gmatbuf[0] = v3d->defmaterial;
+ GPU_material_matcap(scene, v3d->defmaterial);
+
/* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
-
- if (glsl) {
- GMS.gmatbuf[0]= &defmaterial;
- GPU_material_from_blender(GMS.gscene, &defmaterial);
- }
-
+
GMS.alphablend[0]= GPU_BLEND_SOLID;
}
+ else {
- /* setup materials */
- for (a=1; a<=ob->totcol; a++) {
- /* find a suitable material */
- ma= give_current_material(ob, a);
- if (!glsl && !new_shading_nodes) ma= gpu_active_node_material(ma);
- if (ma==NULL) ma= &defmaterial;
-
- /* create glsl material if requested */
- gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
-
- if (gpumat) {
- /* do glsl only if creating it succeed, else fallback */
- GMS.gmatbuf[a]= ma;
- alphablend = GPU_material_alpha_blend(gpumat, ob->col);
- }
- else {
- /* fixed function opengl materials */
- gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
+ /* no materials assigned? */
+ if (ob->totcol==0) {
+ gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes);
- if (GMS.use_alpha_pass) {
- GMS.matbuf[a].diff[3]= ma->alpha;
- alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
+ /* do material 1 too, for displists! */
+ memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
+
+ if (glsl) {
+ GMS.gmatbuf[0]= &defmaterial;
+ GPU_material_from_blender(GMS.gscene, &defmaterial);
+ }
+
+ GMS.alphablend[0]= GPU_BLEND_SOLID;
+ }
+
+ /* setup materials */
+ for (a=1; a<=ob->totcol; a++) {
+ /* find a suitable material */
+ ma= give_current_material(ob, a);
+ if (!glsl && !new_shading_nodes) ma= gpu_active_node_material(ma);
+ if (ma==NULL) ma= &defmaterial;
+
+ /* create glsl material if requested */
+ gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
+
+ if (gpumat) {
+ /* do glsl only if creating it succeed, else fallback */
+ GMS.gmatbuf[a]= ma;
+ alphablend = GPU_material_alpha_blend(gpumat, ob->col);
}
else {
- GMS.matbuf[a].diff[3]= 1.0f;
- alphablend = GPU_BLEND_SOLID;
+ /* fixed function opengl materials */
+ gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
+
+ if (GMS.use_alpha_pass) {
+ GMS.matbuf[a].diff[3]= ma->alpha;
+ alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
+ }
+ else {
+ GMS.matbuf[a].diff[3]= 1.0f;
+ alphablend = GPU_BLEND_SOLID;
+ }
}
- }
- /* setting 'do_alpha_after = TRUE' indicates this object needs to be
- * drawn in a second alpha pass for improved blending */
- if (do_alpha_after && !GMS.is_alpha_pass)
- if (ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
- *do_alpha_after = TRUE;
+ /* setting 'do_alpha_after = TRUE' indicates this object needs to be
+ * drawn in a second alpha pass for improved blending */
+ if (do_alpha_after && !GMS.is_alpha_pass)
+ if (ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
+ *do_alpha_after = TRUE;
- GMS.alphablend[a]= alphablend;
+ GMS.alphablend[a]= alphablend;
+ }
}
-
+
/* let's start with a clean state */
GPU_disable_material();
}
@@ -1593,7 +1635,7 @@ int GPU_default_lights(void)
return count;
}
-int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4], int ortho)
+int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][4], int ortho)
{
Base *base;
Lamp *la;
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 7a0ac29c9ab..e8e47013159 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -36,13 +36,12 @@
#include "MEM_guardedalloc.h"
-#include "BKE_global.h"
-
-
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
+#include "BKE_global.h"
+
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "gpu_codegen.h"
@@ -134,8 +133,8 @@ void GPU_extensions_init(void)
glGetIntegerv(GL_BLUE_BITS, &b);
GG.colordepth = r+g+b; /* assumes same depth for RGB */
- vendor = (const char*)glGetString(GL_VENDOR);
- renderer = (const char*)glGetString(GL_RENDERER);
+ vendor = (const char *)glGetString(GL_VENDOR);
+ renderer = (const char *)glGetString(GL_RENDERER);
if (strstr(vendor, "ATI")) {
GG.device = GPU_DEVICE_ATI;
@@ -539,6 +538,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int isdata, d
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
GPU_update_image_time(ima, time);
+ /* this binds a texture, so that's why to restore it with lastbindcode */
bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, isdata);
if (ima->gputexture) {
@@ -579,6 +579,59 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int isdata, d
return tex;
}
+GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
+{
+ GPUTexture *tex = prv->gputexture[0];
+ GLint w, h, lastbindcode;
+ GLuint bindcode = 0;
+
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
+
+ if (tex)
+ bindcode = tex->bindcode;
+
+ /* this binds a texture, so that's why to restore it */
+ if (bindcode == 0) {
+ GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], mipmap, 0, NULL);
+ }
+ if (tex) {
+ tex->bindcode = bindcode;
+ glBindTexture(GL_TEXTURE_2D, lastbindcode);
+ return tex;
+ }
+
+ /* error binding anything */
+ if (!bindcode) {
+ glBindTexture(GL_TEXTURE_2D, lastbindcode);
+ return NULL;
+ }
+
+ tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ tex->bindcode = bindcode;
+ tex->number = -1;
+ tex->refcount = 1;
+ tex->target = GL_TEXTURE_2D;
+
+ prv->gputexture[0]= tex;
+
+ if (!glIsTexture(tex->bindcode)) {
+ GPU_print_error("Blender Texture");
+ }
+ else {
+ glBindTexture(GL_TEXTURE_2D, tex->bindcode);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
+
+ tex->w = w;
+ tex->h = h;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, lastbindcode);
+
+ return tex;
+
+}
+
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);
@@ -916,7 +969,7 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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, (float *)scaleh);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
glViewport(0, 0, GPU_texture_opengl_width(blurtex), GPU_texture_opengl_height(blurtex));
@@ -942,7 +995,7 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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, (float *)scalev);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
GPU_texture_bind(blurtex, 0);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 9c48f74bf5f..b5ef27a338d 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -282,7 +282,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
}
}
-void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale)
+void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale)
{
if (material->pass) {
GPUShader *shader = GPU_pass_shader(material->pass);
@@ -1035,8 +1035,7 @@ static void do_material_tex(GPUShadeInput *shi)
GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, FALSE), &tin, &trgb);
rgbnor= TEX_RGB;
- if (tex->imaflag & TEX_USEALPHA)
- talpha= 1;
+ talpha = (tex->ima->flag & IMA_IGNORE_ALPHA) == 0;
}
else {
continue;
@@ -1507,6 +1506,52 @@ static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma)
return outlink;
}
+static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma)
+{
+ GPUNodeLink *outlink;
+
+ GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
+
+ return outlink;
+}
+
+/* new solid draw mode with glsl matcaps */
+GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
+{
+ GPUMaterial *mat;
+ GPUNodeLink *outlink;
+ LinkData *link;
+
+ for (link=ma->gpumaterial.first; link; link=link->next)
+ if (((GPUMaterial*)link->data)->scene == scene)
+ return link->data;
+
+ /* allocate material */
+ mat = GPU_material_construct_begin(ma);
+ mat->scene = scene;
+
+ if (ma->preview && ma->preview->rect[0]) {
+ outlink = gpu_material_preview_matcap(mat, ma);
+ }
+ else {
+ outlink = gpu_material_diffuse_bsdf(mat, ma);
+ }
+
+ GPU_material_output_link(mat, outlink);
+
+ GPU_material_construct_end(mat);
+
+ /* 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(&ma->gpumaterial, link);
+
+ return mat;
+}
+
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
{
GPUMaterial *mat;
@@ -1526,7 +1571,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
ntreeGPUMaterialNodes(ma->nodetree, mat);
}
else {
- if(BKE_scene_use_new_shading_nodes(scene)) {
+ if (BKE_scene_use_new_shading_nodes(scene)) {
/* create simple diffuse material instead of nodes */
outlink = gpu_material_diffuse_bsdf(mat, ma);
}
@@ -1572,7 +1617,7 @@ void GPU_materials_free(void)
/* Lamps and shadow buffers */
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4])
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
{
float mat[4][4];
@@ -1854,7 +1899,7 @@ void GPU_lamp_update_buffer_mats(GPULamp *lamp)
mult_m4_m4m4(lamp->persmat, rangemat, persmat);
}
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
{
GPU_lamp_update_buffer_mats(lamp);
@@ -1883,6 +1928,11 @@ void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
glEnable(GL_SCISSOR_TEST);
}
+int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
+{
+ return lamp->la->shadowmap_type;
+}
+
int GPU_lamp_shadow_layer(GPULamp *lamp)
{
if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW)))
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 9a238e979fa..8fc18bf8726 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -390,6 +390,17 @@ void set_rgba_zero(out vec4 outval)
outval = vec4(0.0);
}
+void brightness_contrast(vec4 col, float brightness, float contrast, out vec4 outcol)
+{
+ float a = 1.0 + contrast;
+ float b = brightness - contrast*0.5;
+
+ outcol.r = max(a*col.r + b, 0.0);
+ outcol.g = max(a*col.g + b, 0.0);
+ outcol.b = max(a*col.b + b, 0.0);
+ outcol.a = col.a;
+}
+
void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
fac = clamp(fac, 0.0, 1.0);
@@ -811,7 +822,7 @@ void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 inc
float facm;
fact *= facg;
- facm = 1.0-facg;
+ facm = 1.0-fact;
incol = (facm + fact*texcol)*outcol;
}
@@ -821,7 +832,7 @@ void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3
float facm;
fact *= facg;
- facm = 1.0-facg;
+ facm = 1.0-fact;
incol = vec3(1.0) - (vec3(facm) + fact*(vec3(1.0) - texcol))*(vec3(1.0) - outcol);
}
@@ -831,7 +842,7 @@ void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3
float facm;
fact *= facg;
- facm = 1.0-facg;
+ facm = 1.0-fact;
if(outcol.r < 0.5)
incol.r = outcol.r*(facm + 2.0*fact*texcol.r);
@@ -888,11 +899,11 @@ void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 in
fact *= facg;
facm = 1.0-fact;
- col = fact*texcol.r;
+ col= texcol.r + ((1.0 -texcol.r)*facm);
if(col < outcol.r) incol.r = col; else incol.r = outcol.r;
- col = fact*texcol.g;
+ col= texcol.g + ((1.0 -texcol.g)*facm);
if(col < outcol.g) incol.g = col; else incol.g = outcol.g;
- col = fact*texcol.b;
+ col= texcol.b + ((1.0 -texcol.b)*facm);
if(col < outcol.b) incol.b = col; else incol.b = outcol.b;
}
@@ -901,7 +912,6 @@ void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 i
float facm, col;
fact *= facg;
- facm = 1.0-fact;
col = fact*texcol.r;
if(col > outcol.r) incol.r = col; else incol.r = outcol.r;
@@ -2257,3 +2267,18 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
result = surface;
}
+/* ********************** matcap style render ******************** */
+
+void material_preview_matcap(vec4 color, sampler2D ima, vec3 N, out vec4 result)
+{
+ vec2 tex;
+
+ if (N.z < 0.0) {
+ N.z = 0.0;
+ N = normalize(N);
+ }
+
+ tex.x = 0.5 + 0.49 * N.x;
+ tex.y = 0.5 + 0.49 * N.y;
+ result = texture2D(ima, tex);
+}
diff --git a/source/blender/ikplugin/SConscript b/source/blender/ikplugin/SConscript
index 97b1cf18e0d..0d201cb423c 100644
--- a/source/blender/ikplugin/SConscript
+++ b/source/blender/ikplugin/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
defs = []
sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp')
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index ca81f4c915a..67f0694797b 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -206,7 +206,7 @@ static void make_dmats(bPoseChannel *pchan)
/* applies IK matrix to pchan, IK is done separated */
/* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */
/* to make this work, the diffmats have to be precalculated! Stored in chan_mat */
-static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = to detect if this is first bone
+static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr = to detect if this is first bone
{
float vec[3], ikmat[4][4];
@@ -372,7 +372,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
* strictly speaking, it is a posechannel)
*/
- get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+ BKE_get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
/* and set and transform goal */
mult_m4_m4m4(goal, goalinv, rootmat);
@@ -383,7 +383,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* same for pole vector target */
if (data->poletar) {
- get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+ BKE_get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
if (data->flag & CONSTRAINT_IK_SETANGLE) {
/* don't solve IK when we are setting the pole angle */
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 903080d5b79..e1ef7d92bd0 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -370,7 +370,7 @@ static int initialize_chain(Object *ob, bPoseChannel *pchan_tip, bConstraint *co
static bool is_cartesian_constraint(bConstraint *con)
{
- //bKinematicConstraint* data=(bKinematicConstraint*)con->data;
+ //bKinematicConstraint* data=(bKinematicConstraint *)con->data;
return true;
}
@@ -551,7 +551,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram
bConstraint *constraint = (bConstraint *)target->blenderConstraint;
float tarmat[4][4];
- get_constraint_target_matrix(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
+ BKE_get_constraint_target_matrix(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
// rootmat contains the target pose in world coordinate
// if enforce is != 1.0, blend the target position with the end effector position
@@ -620,7 +620,7 @@ static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame&
IK_Channel &rootchan = ikscene->channels[0];
// get polar target matrix in world space
- get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
+ BKE_get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
// convert to armature space
mult_m4_m4m4(polemat, imat, mat);
// get the target in world space (was computed before as target object are defined before base object)
@@ -864,7 +864,7 @@ static bool joint_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintV
}
// build array of joint corresponding to IK chain
-static int convert_channels(IK_Scene *ikscene, PoseTree *tree)
+static int convert_channels(IK_Scene *ikscene, PoseTree *tree, float ctime)
{
IK_Channel *ikchan;
bPoseChannel *pchan;
@@ -877,6 +877,14 @@ static int convert_channels(IK_Scene *ikscene, PoseTree *tree)
ikchan->parent = (a > 0) ? tree->parent[a] : -1;
ikchan->owner = ikscene->blArmature;
+ // the constraint and channels must be applied before we build the iTaSC scene,
+ // this is because some of the pose data (e.g. pose head) don't have corresponding
+ // joint angles and can't be applied to the iTaSC armature dynamically
+ if (!(pchan->flag & POSE_DONE))
+ BKE_pose_where_is_bone(ikscene->blscene, ikscene->blArmature, pchan, ctime, 1);
+ // tell blender that this channel was controlled by IK, it's cleared on each BKE_pose_where_is()
+ pchan->flag |= (POSE_DONE | POSE_CHAIN);
+
/* set DoF flag */
flag = 0;
if (!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP) &&
@@ -1049,7 +1057,7 @@ static void BKE_pose_rest(IK_Scene *ikscene)
}
}
-static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
+static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan, float ctime)
{
PoseTree *tree = (PoseTree *)pchan->iktree.first;
PoseTarget *target;
@@ -1068,6 +1076,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
float length;
bool ret = true, ingame;
double *rot;
+ float start[3];
if (tree->totchannel == 0)
return NULL;
@@ -1126,7 +1135,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
std::vector<double> weights;
double weight[3];
// build the array of joints corresponding to the IK chain
- convert_channels(ikscene, tree);
+ convert_channels(ikscene, tree, ctime);
if (ingame) {
// in the GE, set the initial joint angle to match the current pose
// this will update the jointArray in ikscene
@@ -1137,17 +1146,37 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
BKE_pose_rest(ikscene);
}
rot = ikscene->jointArray(0);
+
for (a = 0, ikchan = ikscene->channels; a < tree->totchannel; ++a, ++ikchan) {
pchan = ikchan->pchan;
bone = pchan->bone;
KDL::Frame tip(iTaSC::F_identity);
+ // compute the position and rotation of the head from previous segment
Vector3 *fl = bone->bone_mat;
KDL::Rotation brot(
fl[0][0], fl[1][0], fl[2][0],
fl[0][1], fl[1][1], fl[2][1],
fl[0][2], fl[1][2], fl[2][2]);
- KDL::Vector bpos(bone->head[0], bone->head[1], bone->head[2]);
+ // if the bone is disconnected, the head is movable in pose mode
+ // take that into account by using pose matrix instead of bone
+ // Note that pose is expressed in armature space, convert to previous bone space
+ {
+ float R_parmat[3][3];
+ float iR_parmat[3][3];
+ if (pchan->parent)
+ copy_m3_m4(R_parmat, pchan->parent->pose_mat);
+ else
+ unit_m3(R_parmat);
+ if (pchan->parent)
+ sub_v3_v3v3(start, pchan->pose_head, pchan->parent->pose_tail);
+ else
+ start[0] = start[1] = start[2] = 0.0f;
+ invert_m3_m3(iR_parmat, R_parmat);
+ normalize_m3(iR_parmat);
+ mul_m3_v3(iR_parmat, start);
+ }
+ KDL::Vector bpos(start[0], start[1], start[2]);
bpos *= ikscene->blScale;
KDL::Frame head(brot, bpos);
@@ -1155,7 +1184,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
length = bone->length * ikscene->blScale;
parent = (a > 0) ? ikscene->channels[tree->parent[a]].tail : root;
// first the fixed segment to the bone head
- if (head.p.Norm() > KDL::epsilon || head.M.GetRot().Norm() > KDL::epsilon) {
+ if (!(ikchan->pchan->bone->flag & BONE_CONNECTED) || head.M.GetRot().Norm() > KDL::epsilon) {
joint = bone->name;
joint += ":H";
ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, head);
@@ -1497,7 +1526,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
return ikscene;
}
-static void create_scene(Scene *scene, Object *ob)
+static void create_scene(Scene *scene, Object *ob, float ctime)
{
bPoseChannel *pchan;
@@ -1508,7 +1537,7 @@ static void create_scene(Scene *scene, Object *ob)
if (tree) {
IK_Data *ikdata = get_ikdata(ob->pose);
// convert tree in iTaSC::Scene
- IK_Scene *ikscene = convert_tree(scene, ob, pchan);
+ IK_Scene *ikscene = convert_tree(scene, ob, pchan, ctime);
if (ikscene) {
ikscene->next = ikdata->first;
ikdata->first = ikscene;
@@ -1732,15 +1761,21 @@ void itasc_initialize_tree(struct Scene *scene, Object *ob, float ctime)
count += initialize_scene(ob, pchan);
}
// if at least one tree, create the scenes from the PoseTree stored in the channels
- if (count)
- create_scene(scene, ob);
- itasc_update_param(ob->pose);
+ // postpone until execute_tree: this way the pose constraint are included
+ //if (count)
+ // create_scene(scene, ob, ctime);
+ //itasc_update_param(ob->pose);
// make sure we don't rebuilt until the user changes something important
ob->pose->flag &= ~POSE_WAS_REBUILT;
}
void itasc_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime)
{
+ if (!ob->pose->ikdata) {
+ // IK tree not yet created, no it now
+ create_scene(scene, ob, ctime);
+ itasc_update_param(ob->pose);
+ }
if (ob->pose->ikdata) {
IK_Data *ikdata = (IK_Data *)ob->pose->ikdata;
bItasc *ikparam = (bItasc *) ob->pose->ikparam;
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 0653956e113..a05f0d5b3e6 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -133,11 +133,14 @@ void IMB_partial_display_buffer_update(struct ImBuf *ibuf, const float *linear_b
int xmin, int ymin, int xmax, int ymax,
int update_orig_byte_buffer);
+void IMB_partial_display_buffer_update_delayed(struct ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax);
+
/* ** Pixel processor functions ** */
struct ColormanageProcessor *IMB_colormanagement_display_processor_new(const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings);
struct ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace);
void IMB_colormanagement_processor_apply_v4(struct ColormanageProcessor *cm_processor, float pixel[4]);
+void IMB_colormanagement_processor_apply_v4_predivide(struct ColormanageProcessor *cm_processor, float pixel[4]);
void IMB_colormanagement_processor_apply_v3(struct ColormanageProcessor *cm_processor, float pixel[3]);
void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_processor, float *buffer, int width, int height,
int channels, int predivide);
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index d0ac71a7131..a19433dbd2f 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -373,9 +373,6 @@ void IMB_rect_from_float(struct ImBuf *ibuf);
* Changed part will be stored in buffer. This is expected to be used for texture painting updates */
void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data);
void IMB_float_from_rect(struct ImBuf *ibuf);
-void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
-/* note, check that the conversion exists, only some are supported */
-float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc);
void IMB_color_to_bw(struct ImBuf *ibuf);
void IMB_saturation(struct ImBuf *ibuf, float sat);
@@ -393,6 +390,8 @@ void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect
int profile_to, int profile_from, int predivide,
int width, int height, int stride_to, int stride_from);
void IMB_buffer_float_clamp(float *buf, int width, int height);
+void IMB_buffer_float_unpremultiply(float *buf, int width, int height);
+void IMB_buffer_float_premultiply(float *buf, int width, int height);
/**
* Change the ordering of the color bytes pointed to by rect from
@@ -407,14 +406,17 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf);
* \attention defined in imageprocess.c
*/
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
-void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+void nearest_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
-void neareast_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]);
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]);
+
/**
*
* \attention defined in readimage.c
@@ -467,6 +469,7 @@ void IMB_flipy(struct ImBuf *ibuf);
/* Premultiply alpha */
void IMB_premultiply_alpha(struct ImBuf *ibuf);
+void IMB_unpremultiply_alpha(struct ImBuf *ibuf);
/**
*
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 28e62d496b2..dde8d4d4ab7 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -28,6 +28,8 @@
#ifndef __IMB_IMBUF_TYPES_H__
#define __IMB_IMBUF_TYPES_H__
+#include "DNA_vec_types.h" /* for rcti */
+
/**
* \file IMB_imbuf_types.h
* \ingroup imbuf
@@ -132,6 +134,7 @@ typedef struct ImBuf {
unsigned int *display_buffer_flags; /* array of per-display display buffers dirty flags */
struct ColormanageCache *colormanage_cache; /* cache used by color management */
int colormanage_flag;
+ rcti invalid_rect;
/* information for compressed textures */
struct DDSData dds_data;
@@ -167,14 +170,15 @@ typedef struct ImBuf {
#define IB_animdeinterlace (1 << 9)
#define IB_tiles (1 << 10)
#define IB_tilecache (1 << 11)
-#define IB_premul (1 << 12)
-#define IB_cm_predivide (1 << 13)
+#define IB_alphamode_premul (1 << 12) /* indicates whether image on disk have premul alpha */
+#define IB_alphamode_detect (1 << 13) /* if this flag is set, alpha mode would be guessed from file */
+#define IB_ignore_alpha (1 << 14) /* ignore alpha on load and substitude it with 1.0f */
/*
* The bit flag is stored in the ImBuf.ftype variable.
- * Note that the lower 10 bits is used for storing custom flags
+ * Note that the lower 11 bits is used for storing custom flags
*/
-#define IB_CUSTOM_FLAGS_MASK 0x3ff
+#define IB_CUSTOM_FLAGS_MASK 0x7ff
#define PNG (1 << 30)
#define TGA (1 << 28)
@@ -217,8 +221,12 @@ typedef struct ImBuf {
#define JP2_YCC (1 << 15)
#define JP2_CINE (1 << 14)
#define JP2_CINE_48FPS (1 << 13)
+#define JP2_JP2 (1 << 12)
+#define JP2_J2K (1 << 11)
#endif
+#define PNG_16BIT (1 << 10)
+
#define RAWTGA (TGA | 1)
#define JPG_STD (JPG | (0 << 8))
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index a6f38516a14..9fc075e4e8b 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -58,7 +58,7 @@ typedef enum ThumbSource {
} ThumbSource;
/* don't generate thumbs for images bigger then this (100mb) */
-#define THUMB_SIZE_MAX (100 * 1024*1024)
+#define THUMB_SIZE_MAX (100 * 1024 * 1024)
// IB_metadata
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index 976108cd84e..f76da8cd9d0 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import os
Import ('env')
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index ba9e20ac411..e2a8e1e3442 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -33,8 +33,6 @@
#include "DNA_listBase.h"
-#define BCM_CONFIG_FILE "config.ocio"
-
struct OCIO_ConstProcessorRcPtr;
struct ImBuf;
diff --git a/source/blender/imbuf/intern/IMB_filter.h b/source/blender/imbuf/intern/IMB_filter.h
index eaedb160c94..6bd5f44307f 100644
--- a/source/blender/imbuf/intern/IMB_filter.h
+++ b/source/blender/imbuf/intern/IMB_filter.h
@@ -41,6 +41,9 @@ void imb_filterx(struct ImBuf *ibuf);
void IMB_premultiply_rect(unsigned int *rect, char planes, int w, int h);
void IMB_premultiply_rect_float(float *rect_float, char planes, int w, int h);
+void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h);
+void IMB_unpremultiply_rect_float(float *rect_float, char planes, int w, int h);
+
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1);
#endif
diff --git a/source/blender/imbuf/intern/IMB_metadata.h b/source/blender/imbuf/intern/IMB_metadata.h
index a68d7a7813e..f731fd69620 100644
--- a/source/blender/imbuf/intern/IMB_metadata.h
+++ b/source/blender/imbuf/intern/IMB_metadata.h
@@ -42,7 +42,7 @@ typedef struct ImMetaData {
int len;
} ImMetaData;
-/** The metadata is a list of key/value pairs (both char*) that can me
+/** 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
* 'Software' and 'Description' (png standard) we'll use keys within the
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 1b3a6d4a4cd..ca0b26fa4b7 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -355,7 +355,7 @@ ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int
ibuf->x = x;
ibuf->y = y;
ibuf->planes = planes;
- ibuf->ftype = TGA;
+ ibuf->ftype = PNG | 90; /* the 90 means, set compression to nearly the maximum */
ibuf->channels = 4; /* float option, is set to other values when buffers get assigned */
ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 8dfdbd4fddc..8d79482ed18 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -486,7 +486,7 @@ static int startffmpeg(struct anim *anim)
return -1;
}
- if (av_find_stream_info(pFormatCtx) < 0) {
+ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
av_close_input_file(pFormatCtx);
return -1;
}
@@ -523,7 +523,7 @@ static int startffmpeg(struct anim *anim)
pCodecCtx->workaround_bugs = 1;
- if (avcodec_open(pCodecCtx, pCodec) < 0) {
+ if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
av_close_input_file(pFormatCtx);
return -1;
}
diff --git a/source/blender/imbuf/intern/cineon/SConscript b/source/blender/imbuf/intern/cineon/SConscript
index a07334632d7..d8fc2502081 100644
--- a/source/blender/imbuf/intern/cineon/SConscript
+++ b/source/blender/imbuf/intern/cineon/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
source_files = env.Glob('*.c')
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index c8bc3f8ebb8..ba84063f317 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -95,6 +95,9 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, size_t size, int us
if (flags & IB_rect)
IMB_rect_from_float(ibuf);
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
+
return ibuf;
}
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 3049a5be514..b858251a6b9 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -50,7 +50,8 @@
static int verbose = 0;
-void cineonSetVerbose(int verbosity) {
+void cineonSetVerbose(int verbosity)
+{
verbose = verbosity;
}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 4c9b5e620dd..aeebf46a632 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -48,7 +48,8 @@
static int verbose = 0;
-void dpxSetVerbose(int verbosity) {
+void dpxSetVerbose(int verbosity)
+{
verbose = verbosity;
}
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 1c68a466ade..ff297d70cc3 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -57,6 +57,7 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_threads.h"
+#include "BLI_rect.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -189,7 +190,6 @@ typedef struct ColormnaageCacheData {
int flag; /* view flags of cached buffer */
float exposure; /* exposure value cached buffer is calculated with */
float gamma; /* gamma value cached buffer is calculated with */
- int predivide; /* predivide flag of cached buffer */
CurveMapping *curve_mapping; /* curve mapping used for cached buffer */
int curve_mapping_timestamp; /* time stamp of curve mapping used for cached buffer */
} ColormnaageCacheData;
@@ -323,7 +323,6 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
ColormanageCacheKey key;
ImBuf *cache_ibuf;
int view_flag = 1 << (view_settings->view - 1);
- int predivide = ibuf->flags & IB_cm_predivide;
CurveMapping *curve_mapping = view_settings->curve_mapping;
int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
@@ -353,10 +352,9 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
if (cache_data->exposure != view_settings->exposure ||
cache_data->gamma != view_settings->gamma ||
- cache_data->predivide != predivide ||
- cache_data->flag != view_settings->flag ||
- cache_data->curve_mapping != curve_mapping ||
- cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
+ cache_data->flag != view_settings->flag ||
+ cache_data->curve_mapping != curve_mapping ||
+ cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
{
*cache_handle = NULL;
@@ -379,7 +377,6 @@ static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSetting
ImBuf *cache_ibuf;
ColormnaageCacheData *cache_data;
int view_flag = 1 << (view_settings->view - 1);
- int predivide = ibuf->flags & IB_cm_predivide;
struct MovieCache *moviecache = colormanage_moviecache_ensure(ibuf);
CurveMapping *curve_mapping = view_settings->curve_mapping;
int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
@@ -400,7 +397,6 @@ static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSetting
cache_data = MEM_callocN(sizeof(ColormnaageCacheData), "color manage cache imbuf data");
cache_data->exposure = view_settings->exposure;
cache_data->gamma = view_settings->gamma;
- cache_data->predivide = predivide;
cache_data->flag = view_settings->flag;
cache_data->curve_mapping = curve_mapping;
cache_data->curve_mapping_timestamp = curve_mapping_timestamp;
@@ -686,7 +682,7 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin
}
static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display,
- float exposure, float gamma)
+ float exposure, float gamma)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_DisplayTransformRcPtr *dt;
@@ -703,7 +699,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie
if (exposure != 0.0f) {
OCIO_MatrixTransformRcPtr *mt;
float gain = powf(2.0f, exposure);
- const float scale4f[] = {gain, gain, gain, gain};
+ const float scale4f[] = {gain, gain, gain, 1.0f};
float m44[16], offset4[4];
OCIO_matrixTransformScale(m44, offset4, scale4f);
@@ -736,7 +732,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie
}
static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace,
- const char *to_colorspace)
+ const char *to_colorspace)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_ConstProcessorRcPtr *processor;
@@ -897,13 +893,12 @@ void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
if (ibuf->rect_float) {
const char *to_colorspace = global_role_scene_linear;
- int predivide = ibuf->flags & IB_cm_predivide;
if (ibuf->rect)
imb_freerectImBuf(ibuf);
IMB_colormanagement_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -1130,7 +1125,6 @@ typedef struct DisplayBufferThread {
int channels;
float dither;
- int predivide;
int is_data;
const char *byte_colorspace;
@@ -1158,7 +1152,6 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
DisplayBufferInitData *init_data = (DisplayBufferInitData *) init_data_v;
ImBuf *ibuf = init_data->ibuf;
- int predivide = ibuf->flags & IB_cm_predivide;
int channels = ibuf->channels;
float dither = ibuf->dither;
int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
@@ -1189,7 +1182,6 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
handle->channels = channels;
handle->dither = dither;
- handle->predivide = predivide;
handle->is_data = is_data;
handle->byte_colorspace = init_data->byte_colorspace;
@@ -1206,7 +1198,6 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
int buffer_size = channels * width * height;
- int predivide = handle->predivide;
int is_data = handle->is_data;
int is_data_display = handle->cm_processor->is_data_result;
@@ -1224,16 +1215,25 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
/* first convert byte buffer to float, keep in image space */
for (i = 0, fp = linear_buffer, cp = byte_buffer;
- i < channels * width * height;
- i++, fp++, cp++)
+ i < width * height;
+ i++, fp += channels, cp += channels)
{
- *fp = (float)(*cp) / 255.0f;
+ if (channels == 3) {
+ rgb_uchar_to_float(fp, cp);
+ }
+ else if (channels == 4) {
+ rgba_uchar_to_float(fp, cp);
+ straight_to_premul_v4(fp);
+ }
+ else {
+ BLI_assert(!"Buffers of 3 or 4 channels are only supported here");
+ }
}
if (!is_data && !is_data_display) {
/* convert float buffer to scene linear space */
IMB_colormanagement_transform(linear_buffer, width, height, channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
else if (handle->float_colorspace) {
@@ -1249,7 +1249,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
IMB_colormanagement_transform(linear_buffer, width, height, channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
else {
/* some processors would want to modify float original buffer
@@ -1277,13 +1277,12 @@ static void *do_display_buffer_apply_thread(void *handle_v)
int width = handle->width;
int height = handle->tot_line;
float dither = handle->dither;
- int predivide = handle->predivide;
int is_data = handle->is_data;
if (cm_processor == NULL) {
if (display_buffer_byte) {
IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- FALSE, width, height, width, width);
+ FALSE, width, height, width, width);
}
if (display_buffer) {
@@ -1301,7 +1300,7 @@ static void *do_display_buffer_apply_thread(void *handle_v)
}
else {
/* apply processor */
- IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, predivide);
+ IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, TRUE);
}
/* copy result to output buffers */
@@ -1309,7 +1308,7 @@ static void *do_display_buffer_apply_thread(void *handle_v)
/* do conversion */
IMB_buffer_byte_from_float(display_buffer_byte, linear_buffer,
channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- predivide, width, height, width, width);
+ TRUE, width, height, width, width);
}
if (display_buffer)
@@ -1355,6 +1354,23 @@ static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned c
display_buffer_init_handle, do_display_buffer_apply_thread);
}
+static int is_ibuf_rect_in_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
+ view_settings->exposure == 0.0f &&
+ view_settings->gamma == 1.0f)
+ {
+ const char *from_colorspace = ibuf->rect_colorspace->name;
+ const char *to_colorspace = display_transform_get_colorspace_name(view_settings, display_settings);
+
+ if (to_colorspace && !strcmp(from_colorspace, to_colorspace))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_buffer, unsigned char *display_buffer_byte,
const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings)
@@ -1368,16 +1384,7 @@ static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_bu
* computation noticeable faster
*/
if (ibuf->rect_float == NULL && ibuf->rect_colorspace) {
- if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
- view_settings->exposure == 0.0f &&
- view_settings->gamma == 1.0f)
- {
- const char *from_colorspace = ibuf->rect_colorspace->name;
- const char *to_colorspace = display_transform_get_colorspace_name(view_settings, display_settings);
-
- if (to_colorspace && !strcmp(from_colorspace, to_colorspace))
- skip_transform = TRUE;
- }
+ skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
}
if (skip_transform == FALSE)
@@ -1593,14 +1600,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in
OCIO_PackedImageDesc *img;
img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float),
- channels * sizeof(float), channels * sizeof(float) * width);
+ channels * sizeof(float), channels * sizeof(float) * width);
if (predivide)
OCIO_processorApply_predivide(processor, img);
else
OCIO_processorApply(processor, img);
- OCIO_OCIO_PackedImageDescRelease(img);
+ OCIO_PackedImageDescRelease(img);
}
}
@@ -1663,7 +1670,7 @@ static void colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorMan
if (global_tot_display == 0 || global_tot_view == 0) {
IMB_buffer_float_from_float(ibuf->rect_float, ibuf->rect_float, ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB,
- ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ TRUE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
else {
colormanage_display_buffer_process_ex(ibuf, ibuf->rect_float, (unsigned char *)ibuf->rect,
@@ -1817,6 +1824,18 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
colormanage_view_settings_to_cache(&cache_view_settings, applied_view_settings);
colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
+ if (ibuf->invalid_rect.xmin != ibuf->invalid_rect.xmax) {
+ if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
+ IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect,
+ ibuf->x, 0, 0, applied_view_settings, display_settings,
+ ibuf->invalid_rect.xmin, ibuf->invalid_rect.ymin,
+ ibuf->invalid_rect.xmax, ibuf->invalid_rect.ymax,
+ FALSE);
+ }
+
+ BLI_rcti_init(&ibuf->invalid_rect, 0, 0, 0, 0);
+ }
+
BLI_lock_thread(LOCK_COLORMANAGE);
/* ensure color management bit fields exists */
@@ -2112,7 +2131,7 @@ static void colormanage_description_strip(char *description)
{
int i, n;
- for (i = strlen(description) - 1; i >= 0; i--) {
+ for (i = (int)strlen(description) - 1; i >= 0; i--) {
if (ELEM(description[i], '\r', '\n')) {
description[i] = '\0';
}
@@ -2326,7 +2345,6 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
{
int x, y;
int channels = ibuf->channels;
- int predivide = ibuf->flags & IB_cm_predivide;
float dither = ibuf->dither;
ColorSpace *rect_colorspace = ibuf->rect_colorspace;
float *display_buffer_float = NULL;
@@ -2335,37 +2353,67 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
if (dither != 0.0f) {
+ /* cm_processor is NULL in cases byte_buffer's space matches display
+ * buffer's space
+ * in this case we could skip extra transform and only apply dither
+ * use 4 channels for easier byte->float->byte conversion here so
+ * (this is only needed to apply dither, in other cases we'll convert
+ * byte buffer to display directly)
+ */
+ if (!cm_processor)
+ channels = 4;
+
display_buffer_float = MEM_callocN(channels * width * height * sizeof(float), "display buffer for dither");
}
- for (y = ymin; y < ymax; y++) {
- for (x = xmin; x < xmax; x++) {
- int display_index = (y * display_stride + x) * channels;
- int linear_index = ((y - linear_offset_y) * linear_stride + (x - linear_offset_x)) * channels;
- float pixel[4];
-
- if (linear_buffer) {
- copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
- }
- else if (byte_buffer) {
- rgba_uchar_to_float(pixel, byte_buffer + linear_index);
- IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
- }
-
- if (!is_data) {
- if (predivide)
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
- else
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+ if (cm_processor) {
+ for (y = ymin; y < ymax; y++) {
+ for (x = xmin; x < xmax; x++) {
+ int display_index = (y * display_stride + x) * channels;
+ int linear_index = ((y - linear_offset_y) * linear_stride + (x - linear_offset_x)) * channels;
+ float pixel[4];
+
+ if (linear_buffer) {
+ copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
+ }
+ else if (byte_buffer) {
+ rgba_uchar_to_float(pixel, byte_buffer + linear_index);
+ IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
+ straight_to_premul_v4(pixel);
+ }
+
+ if (!is_data) {
+ IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
+ }
+
+ if (display_buffer_float) {
+ int index = ((y - ymin) * width + (x - xmin)) * channels;
+
+ copy_v4_v4(display_buffer_float + index, pixel);
+ }
+ else {
+ float pixel_straight[4];
+ premul_to_straight_v4_v4(pixel_straight, pixel);
+ rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+ }
}
+ }
+ }
+ else {
+ if (display_buffer_float) {
+ /* huh, for dither we need float buffer first, no cheaper way. currently */
+ IMB_buffer_float_from_byte(display_buffer_float, byte_buffer,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB, TRUE,
+ width, height, width, display_stride);
+ }
+ else {
+ int i, width = xmax - xmin;
- if (display_buffer_float) {
- int index = ((y - ymin) * width + (x - xmin)) * channels;
+ for (i = ymin; i < ymax; i++) {
+ int byte_offset = (linear_stride * i + xmin) * 4;
+ int display_offset = (display_stride * i + xmin) * 4;
- copy_v4_v4(display_buffer_float + index, pixel);
- }
- else {
- rgba_float_to_uchar(display_buffer + display_index, pixel);
+ memcpy(display_buffer + display_offset, byte_buffer + byte_offset, 4 * sizeof(char) * width);
}
}
}
@@ -2374,7 +2422,7 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
int display_index = (ymin * display_stride + xmin) * channels;
IMB_buffer_byte_from_float(display_buffer + display_index, display_buffer_float, channels, dither,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, width, height, display_stride, width);
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB, TRUE, width, height, display_stride, width);
MEM_freeN(display_buffer_float);
}
@@ -2389,7 +2437,6 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
/* update byte buffer created by legacy color management */
unsigned char *rect = (unsigned char *) ibuf->rect;
- int predivide = ibuf->flags & IB_cm_predivide;
int channels = ibuf->channels;
int width = xmax - xmin;
int height = ymax - ymin;
@@ -2397,7 +2444,7 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
int linear_index = ((ymin - offset_y) * stride + (xmin - offset_x)) * channels;
IMB_buffer_byte_from_float(rect + rect_index, linear_buffer + linear_index, channels, ibuf->dither,
- IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, predivide, width, height, ibuf->x, stride);
+ IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE, width, height, ibuf->x, stride);
}
if (ibuf->display_buffer_flags) {
@@ -2430,20 +2477,42 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
BLI_unlock_thread(LOCK_COLORMANAGE);
if (display_buffer) {
- ColormanageProcessor *cm_processor;
+ ColormanageProcessor *cm_processor = NULL;
+ int skip_transform = 0;
- cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ /* byte buffer is assumed to be in imbuf's rect space, so if byte buffer
+ * is known we could skip display->linear->display conversion in case
+ * display color space matches imbuf's rect space
+ */
+ if (byte_buffer != NULL)
+ skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
+
+ if (!skip_transform)
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
partial_buffer_update_rect(ibuf, display_buffer, linear_buffer, byte_buffer, buffer_width, stride,
offset_x, offset_y, cm_processor, xmin, ymin, xmax, ymax);
- IMB_colormanagement_processor_free(cm_processor);
+ if (cm_processor)
+ IMB_colormanagement_processor_free(cm_processor);
IMB_display_buffer_release(cache_handle);
}
}
}
+void IMB_partial_display_buffer_update_delayed(ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax)
+{
+ if (ibuf->invalid_rect.xmin == ibuf->invalid_rect.xmax) {
+ BLI_rcti_init(&ibuf->invalid_rect, xmin, xmax, ymin, ymax);
+ }
+ else {
+ rcti rect;
+ BLI_rcti_init(&rect, xmin, xmax, ymin, ymax);
+ BLI_rcti_union(&ibuf->invalid_rect, &rect);
+ }
+}
+
/*********************** Pixel processor functions *************************/
ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManagedViewSettings *view_settings,
@@ -2503,6 +2572,15 @@ void IMB_colormanagement_processor_apply_v4(ColormanageProcessor *cm_processor,
OCIO_processorApplyRGBA(cm_processor->processor, pixel);
}
+void IMB_colormanagement_processor_apply_v4_predivide(ColormanageProcessor *cm_processor, float pixel[4])
+{
+ if (cm_processor->curve_mapping)
+ curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
+
+ if (cm_processor->processor)
+ OCIO_processorApplyRGBA_predivide(cm_processor->processor, pixel);
+}
+
void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor, float pixel[3])
{
if (cm_processor->curve_mapping)
@@ -2533,14 +2611,14 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo
/* apply OCIO processor */
img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float),
- channels * sizeof(float), channels * sizeof(float) * width);
+ channels * sizeof(float), channels * sizeof(float) * width);
if (predivide)
OCIO_processorApply_predivide(cm_processor->processor, img);
else
OCIO_processorApply(cm_processor->processor, img);
- OCIO_OCIO_PackedImageDescRelease(img);
+ OCIO_PackedImageDescRelease(img);
}
}
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index f0864f06e6f..730a19d84fd 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -69,7 +69,7 @@ struct ColorBlock
private:
- Color32 m_color[4*4];
+ Color32 m_color[4 * 4];
};
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
index 72a524daba2..11e6d4a5708 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -172,7 +172,7 @@ public:
void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m);
- void* readData(uint &size);
+ void *readData(uint &size);
// void mipmap(FloatImage * img, uint f, uint m);
void printInfo() const;
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index 05821b27ca6..660643530ba 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -147,10 +147,10 @@ static void FlipDXT5BlockFull(uint8_t *block)
block[2] = line_3_2 & 0xff;
block[3] = (line_3_2 & 0xff00) >> 8;
- block[4] = (line_3_2 & 0xff0000) >> 8;
+ block[4] = (line_3_2 & 0xff0000) >> 16;
block[5] = line_1_0 & 0xff;
block[6] = (line_1_0 & 0xff00) >> 8;
- block[7] = (line_1_0 & 0xff0000) >> 8;
+ block[7] = (line_1_0 & 0xff0000) >> 16;
// And flip the DXT1 block using the above function.
FlipDXT1BlockFull(block + 8);
@@ -165,7 +165,7 @@ static void FlipDXT5BlockHalf(uint8_t *block)
((line_0_1 & 0xfff000) >> 12);
block[2] = line_1_0 & 0xff;
block[3] = (line_1_0 & 0xff00) >> 8;
- block[4] = (line_1_0 & 0xff0000) >> 8;
+ block[4] = (line_1_0 & 0xff0000) >> 16;
FlipDXT1BlockHalf(block + 8);
}
diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript
index 475d21135aa..960e15f8e55 100644
--- a/source/blender/imbuf/intern/dds/SConscript
+++ b/source/blender/imbuf/intern/dds/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp', 'FlipDXT.cpp']
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
index 00e1b679c69..57a251261a1 100644
--- a/source/blender/imbuf/intern/dds/Stream.cpp
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -47,7 +47,7 @@ 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?)");
return(0);
- };
+ }
memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian
mem.pos += 8;
return(8);
@@ -58,7 +58,7 @@ 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?)");
return(0);
- };
+ }
memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian
mem.pos += 4;
return(4);
@@ -69,7 +69,7 @@ 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?)");
return(0);
- };
+ }
memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian
mem.pos += 2;
return(2);
@@ -80,7 +80,7 @@ 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?)");
return(0);
- };
+ }
i = (mem.mem + mem.pos)[0];
mem.pos += 1;
return(1);
@@ -91,7 +91,7 @@ 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?)");
return(0);
- };
+ }
memcpy(i, mem.mem + mem.pos, cnt);
mem.pos += cnt;
return(cnt);
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index 5459cffe590..0c240f16227 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -96,7 +96,7 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags, char colo
Color32 pixel;
Color32 *pixels = 0;
- /* OCIO_TODO: never was able to save DDS, so can'ttest loading
+ /* OCIO_TODO: never was able to save DDS, so can't test loading
* but profile used to be set to sRGB and can't see rect_float here, so
* default byte space should work fine
*/
@@ -136,9 +136,9 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags, char colo
if (pixel.a != 255) {
bits_per_pixel = 32;
break;
- };
- };
- };
+ }
+ }
+ }
ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0);
if (ibuf == 0) return(0); /* memory allocation failed */
@@ -164,7 +164,7 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags, char colo
}
if (ibuf->dds_data.fourcc != FOURCC_DDS) {
- ibuf->dds_data.data = (unsigned char*)dds.readData(ibuf->dds_data.size);
+ ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size);
/* flip compressed texture */
FlipDXTCImage(dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data);
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index f049c404e2d..20d51fddb35 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -39,6 +39,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
+#include "IMB_filter.h"
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
@@ -249,11 +250,25 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
uchar *to = rect_to + stride_to * y * 4;
if (profile_to == profile_from) {
+ float straight[4];
+
/* no color space conversion */
- if (dither) {
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4_v4(straight, from);
+ float_to_byte_dither_v4(to, straight, di);
+ }
+ }
+ else if (dither) {
for (x = 0; x < width; x++, from += 4, to += 4)
float_to_byte_dither_v4(to, from, di);
}
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4_v4(straight, from);
+ rgba_float_to_uchar(to, straight);
+ }
+ }
else {
for (x = 0; x < width; x++, from += 4, to += 4)
rgba_float_to_uchar(to, from);
@@ -262,10 +277,12 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
else if (profile_to == IB_PROFILE_SRGB) {
/* convert from linear to sRGB */
unsigned short us[4];
+ float straight[4];
if (dither && predivide) {
for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4_predivide(us, from);
+ premul_to_straight_v4_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
ushort_to_byte_dither_v4(to, us, di);
}
}
@@ -277,7 +294,8 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
}
else if (predivide) {
for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4_predivide(us, from);
+ premul_to_straight_v4_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
ushort_to_byte_v4(to, us);
}
}
@@ -526,7 +544,6 @@ void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
void IMB_rect_from_float(ImBuf *ibuf)
{
- int predivide = (ibuf->flags & IB_cm_predivide);
float *buffer;
const char *from_colorspace;
@@ -548,7 +565,10 @@ void IMB_rect_from_float(ImBuf *ibuf)
buffer = MEM_dupallocN(ibuf->rect_float);
/* first make float buffer in byte space */
- IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, predivide);
+ IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, TRUE);
+
+ /* convert from float's premul alpha to byte's straight alpha */
+ IMB_unpremultiply_rect_float(buffer, ibuf->planes, ibuf->x, ibuf->y);
/* convert float to byte */
IMB_buffer_byte_from_float((unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
@@ -565,7 +585,6 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
{
float *rect_float;
uchar *rect_byte;
- int predivide = (ibuf->flags & IB_cm_predivide);
int profile_from = IB_PROFILE_LINEAR_RGB;
/* verify we have a float buffer */
@@ -588,12 +607,12 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
/* and do color space conversion to byte */
IMB_buffer_byte_from_float(rect_byte, rect_float,
- 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
+ 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, TRUE,
w, h, ibuf->x, w);
}
else {
IMB_buffer_float_from_float(buffer, rect_float,
- ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide,
+ ibuf->channels, IB_PROFILE_SRGB, profile_from, TRUE,
w, h, w, ibuf->x);
/* XXX: need to convert to image buffer's rect space */
@@ -608,8 +627,6 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
void IMB_float_from_rect(ImBuf *ibuf)
{
- int predivide = (ibuf->flags & IB_cm_predivide);
-
/* verify if we byte and float buffers */
if (ibuf->rect == NULL)
return;
@@ -634,69 +651,12 @@ void IMB_float_from_rect(ImBuf *ibuf)
/* then make float be in linear space */
IMB_colormanagement_colorspace_to_scene_linear(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- ibuf->rect_colorspace, predivide);
-
- BLI_unlock_thread(LOCK_COLORMANAGE);
-}
-
-/* no profile conversion */
-void IMB_float_from_rect_simple(ImBuf *ibuf)
-{
- int predivide = (ibuf->flags & IB_cm_predivide);
-
- if (ibuf->rect_float == NULL)
- imb_addrectfloatImBuf(ibuf);
-
- IMB_buffer_float_from_byte(ibuf->rect_float, (uchar *)ibuf->rect,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
-}
+ ibuf->rect_colorspace, FALSE);
-/* use when you need to get a buffer with a certain profile
- * if the return */
+ /* byte buffer is straight alpha, float should always be premul */
+ IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
-/* OCIO_TODO: used only by Cineon/DPX exporter which is still broken, so can not guarantee
- * this function is working properly
- */
-float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc)
-{
- int predivide = (ibuf->flags & IB_cm_predivide);
- int profile_from = IB_PROFILE_LINEAR_RGB;
- int profile_to;
-
- /* determine profile */
- if (profile == IB_PROFILE_NONE)
- profile_to = IB_PROFILE_LINEAR_RGB;
- else
- profile_to = IB_PROFILE_SRGB;
-
- if (profile_from == profile_to) {
- /* simple case, just allocate the buffer and return */
- *alloc = 0;
-
- if (ibuf->rect_float == NULL)
- IMB_float_from_rect(ibuf);
-
- return ibuf->rect_float;
- }
- else {
- /* conversion is needed, first check */
- float *fbuf = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure");
- *alloc = 1;
-
- if (ibuf->rect_float == NULL) {
- IMB_buffer_float_from_byte(fbuf, (uchar *)ibuf->rect,
- profile_to, profile_from, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
- else {
- IMB_buffer_float_from_float(fbuf, ibuf->rect_float,
- 4, profile_to, profile_from, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
-
- return fbuf;
- }
+ BLI_unlock_thread(LOCK_COLORMANAGE);
}
/**************************** Color to Grayscale *****************************/
@@ -727,6 +687,26 @@ void IMB_buffer_float_clamp(float *buf, int width, int height)
}
}
+void IMB_buffer_float_unpremultiply(float *buf, int width, int height)
+{
+ int total = width * height;
+ float *fp = buf;
+ while (total--) {
+ premul_to_straight_v4(fp);
+ fp += 4;
+ }
+}
+
+void IMB_buffer_float_premultiply(float *buf, int width, int height)
+{
+ int total = width * height;
+ float *fp = buf;
+ while (total--) {
+ straight_to_premul_v4(fp);
+ fp += 4;
+ }
+}
+
/**************************** alter saturation *****************************/
void IMB_saturation(ImBuf *ibuf, float sat)
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 678b2908b96..9193954f1d6 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -506,6 +506,10 @@ void IMB_makemipmap(ImBuf *ibuf, int use_filter)
imb_freemipmapImBuf(ibuf);
+ /* no mipmap for non RGBA images */
+ if (ibuf->rect_float && ibuf->channels < 4)
+ return;
+
ibuf->miptot = 1;
while (curmap < IB_MIPMAP_LEVELS) {
@@ -599,3 +603,67 @@ void IMB_premultiply_alpha(ImBuf *ibuf)
IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
}
+void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h)
+{
+ char *cp;
+ int x, y;
+ float val;
+
+ if (planes == 24) { /* put alpha at 255 */
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++, cp += 4)
+ cp[3] = 255;
+ }
+ else {
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, cp += 4) {
+ val = cp[3] != 0 ? 1.0f / (float)cp[3] : 1.0f;
+ cp[0] = FTOCHAR(cp[0] * val);
+ cp[1] = FTOCHAR(cp[1] * val);
+ cp[2] = FTOCHAR(cp[2] * val);
+ }
+ }
+ }
+}
+
+void IMB_unpremultiply_rect_float(float *rect_float, char planes, int w, int h)
+{
+ float val, *fp;
+ int x, y;
+
+ if (planes == 24) { /* put alpha at 1.0 */
+ fp = rect_float;
+
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++, fp += 4)
+ fp[3] = 1.0;
+ }
+ else {
+ fp = rect_float;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, fp += 4) {
+ val = fp[3] != 0.0f ? 1.0f / fp[3] : 1.0f;
+ fp[0] = fp[0] * val;
+ fp[1] = fp[1] * val;
+ fp[2] = fp[2] * val;
+ }
+ }
+ }
+
+}
+
+void IMB_unpremultiply_alpha(ImBuf *ibuf)
+{
+ if (ibuf == NULL)
+ return;
+
+ if (ibuf->rect)
+ IMB_unpremultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
+
+ if (ibuf->rect_float)
+ IMB_unpremultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
+}
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index a185c4ee3e0..59282c9d207 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -104,7 +104,7 @@ void bicubic_interpolation_color(struct ImBuf *in, unsigned char outI[4], float
BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
}
else {
- BLI_bicubic_interpolation_char((unsigned char*) in->rect, outI, in->x, in->y, 4, u, v);
+ BLI_bicubic_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
}
}
@@ -130,7 +130,7 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char outI[4], float
BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
}
else {
- BLI_bilinear_interpolation_char((unsigned char*) in->rect, outI, in->x, in->y, 4, u, v);
+ BLI_bilinear_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
}
}
@@ -219,7 +219,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
/* function assumes out to be zero'ed, only does RGBA */
/* NEAREST INTERPOLATION */
-void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
float *dataF;
unsigned char *dataI;
@@ -268,7 +268,7 @@ void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float
}
}
-void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
+void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
{
unsigned char *outI = NULL;
float *outF = NULL;
@@ -279,7 +279,7 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, i
pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
- neareast_interpolation_color(in, outI, outF, x, y);
+ nearest_interpolation_color(in, outI, outF, x, y);
}
/*********************** Threaded image processing *************************/
@@ -327,3 +327,53 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_
MEM_freeN(handles);
}
+
+/* Alpha-under */
+
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ float *fp = rect_float;
+
+ while (a--) {
+ if (fp[3] == 0.0f) {
+ copy_v3_v3(fp, backcol);
+ }
+ else {
+ float mul = 1.0f - fp[3];
+
+ fp[0] += mul * backcol[0];
+ fp[1] += mul * backcol[1];
+ fp[2] += mul * backcol[2];
+ }
+
+ fp[3] = 1.0f;
+
+ fp += 4;
+ }
+}
+
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ unsigned char *cp = rect;
+
+ while (a--) {
+ if (cp[3] == 0) {
+ cp[0] = backcol[0] * 255;
+ cp[1] = backcol[1] * 255;
+ cp[2] = backcol[2] * 255;
+ }
+ else {
+ int mul = 255 - cp[3];
+
+ cp[0] += mul * backcol[0] / 255;
+ cp[1] += mul * backcol[1] / 255;
+ cp[2] += mul * backcol[2] / 255;
+ }
+
+ cp[3] = 255;
+
+ cp += 4;
+ }
+}
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 277f50bcdbc..56e5be7c12a 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -332,7 +332,7 @@ int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size)
return 3;
default:
return 0;
- };
+ }
return 0;
}
@@ -352,7 +352,7 @@ int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
return 3;
default:
return 0;
- };
+ }
return 0;
}
@@ -496,7 +496,9 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
- rv->st = av_new_stream(rv->of, 0);
+ rv->st = avformat_new_stream(rv->of, NULL);
+ rv->st->id = 0;
+
rv->c = rv->st->codec;
rv->c->codec_type = AVMEDIA_TYPE_VIDEO;
rv->c->codec_id = CODEC_ID_MJPEG;
@@ -531,8 +533,8 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
/* there's no way to set JPEG quality in the same way as in AVI JPEG and image sequence,
* but this seems to be giving expected quality result */
ffmpeg_quality = (int)(1.0f + 30.0f * (1.0f - (float)quality / 100.0f) + 0.5f);
- av_set_int(rv->c, "qmin", ffmpeg_quality);
- av_set_int(rv->c, "qmax", ffmpeg_quality);
+ av_opt_set_int(rv->c, "qmin", ffmpeg_quality, 0);
+ av_opt_set_int(rv->c, "qmax", ffmpeg_quality, 0);
if (rv->of->flags & AVFMT_GLOBALHEADER) {
rv->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
@@ -545,7 +547,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
return 0;
}
- avcodec_open(rv->c, rv->codec);
+ avcodec_open2(rv->c, rv->codec, NULL);
rv->video_buffersize = 2000000;
rv->video_buffer = (uint8_t *)MEM_mallocN(
@@ -758,7 +760,7 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Tim
return NULL;
}
- if (av_find_stream_info(context->iFormatCtx) < 0) {
+ if (avformat_find_stream_info(context->iFormatCtx, NULL) < 0) {
av_close_input_file(context->iFormatCtx);
MEM_freeN(context);
return NULL;
@@ -797,7 +799,7 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Tim
context->iCodecCtx->workaround_bugs = 1;
- if (avcodec_open(context->iCodecCtx, context->iCodec) < 0) {
+ if (avcodec_open2(context->iCodecCtx, context->iCodec, NULL) < 0) {
av_close_input_file(context->iFormatCtx);
MEM_freeN(context);
return NULL;
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index dec5f6fb39e..47bd3e54a6f 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -672,7 +672,7 @@ static void expandrow(unsigned char *optr, unsigned char *iptr, int z)
* represents one pixel. xsize and ysize specify the dimensions of
* the pixel array. zsize specifies what kind of image file to
* write out. if zsize is 1, the luminance of the pixels are
- * calculated, and a sinlge channel black and white image is saved.
+ * calculated, and a single channel black and white image is saved.
* If zsize is 3, an RGB image file is saved. If zsize is 4, an
* RGBA image file is saved.
*
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 3a2bf99c75c..f4ac4322747 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -108,6 +108,13 @@ static void info_callback(const char *msg, void *client_data)
i++, _rect += 4) \
{ \
+# define PIXEL_LOOPER_BEGIN_CHANNELS(_rect, _channels) \
+ for (y = h - 1; y != (unsigned int)(-1); y--) { \
+ for (i = y * w, i_next = (y + 1) * w; \
+ i < i_next; \
+ i++, _rect += _channels) \
+ { \
+
# define PIXEL_LOOPER_END \
} \
} (void)0 \
@@ -228,6 +235,10 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char co
}
ibuf->ftype = JP2;
+ if (is_jp2)
+ ibuf->ftype |= JP2_JP2;
+ else
+ ibuf->ftype |= JP2_J2K;
if (use_float) {
float *rect_float = ibuf->rect_float;
@@ -552,7 +563,7 @@ static float channel_colormanage_noop(float value)
static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
{
unsigned char *rect_uchar;
- float *rect_float;
+ float *rect_float, from_straight[4];
unsigned int subsampling_dx = parameters->subsampling_dx;
unsigned int subsampling_dy = parameters->subsampling_dy;
@@ -659,70 +670,198 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
}
if (rect_float) {
+ int channels_in_float = ibuf->channels ? ibuf->channels : 4;
+
switch (prec) {
case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */
if (numcomps == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
- a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]);
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN(rect_float)
+ {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
+ a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(from_straight[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
+ a[i] = 255;
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ a[i] = 255;
+ }
+ PIXEL_LOOPER_END;
}
- PIXEL_LOOPER_END;
}
else {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN(rect_float)
+ {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ }
+ PIXEL_LOOPER_END;
}
- PIXEL_LOOPER_END;
}
break;
case 12:
if (numcomps == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
- a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]);
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN(rect_float)
+ {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
+ a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(from_straight[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
+ a[i] = 4095;
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ a[i] = 4095;
+ }
+ PIXEL_LOOPER_END;
}
- PIXEL_LOOPER_END;
}
else {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN(rect_float)
+ {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ }
+ PIXEL_LOOPER_END;
}
- PIXEL_LOOPER_END;
}
break;
case 16:
if (numcomps == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
- a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]);
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN(rect_float)
+ {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
+ a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(from_straight[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
+ a[i] = 65535;
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ a[i] = 65535;
+ }
+ PIXEL_LOOPER_END;
}
- PIXEL_LOOPER_END;
}
else {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN(rect_float)
+ {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ }
+ PIXEL_LOOPER_END;
}
- PIXEL_LOOPER_END;
}
break;
}
@@ -852,9 +991,15 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags)
int codestream_length;
opj_cio_t *cio = NULL;
FILE *f = NULL;
+ opj_cinfo_t *cinfo = NULL;
/* get a JP2 compressor handle */
- opj_cinfo_t *cinfo = opj_create_compress(CODEC_JP2);
+ if (ibuf->ftype & JP2_JP2)
+ cinfo = opj_create_compress(CODEC_JP2);
+ else if (ibuf->ftype & JP2_J2K)
+ cinfo = opj_create_compress(CODEC_J2K);
+ else
+ BLI_assert(!"Unsupported codec was specified in save settings");
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index 758617bdd48..6a5b534c688 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -234,7 +234,7 @@ static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t
* If must suspend, take the specified action (typically "return FALSE").
*/
#define INPUT_BYTE(cinfo, V, action) \
- MAKESTMT(MAKE_BYTE_AVAIL(cinfo,action); \
+ MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V = GETJOCTET(*next_input_byte++); )
@@ -242,7 +242,7 @@ static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t
* V should be declared unsigned int or perhaps INT32.
*/
#define INPUT_2BYTES(cinfo, V, action) \
- MAKESTMT(MAKE_BYTE_AVAIL(cinfo,action); \
+ MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
MAKE_BYTE_AVAIL(cinfo, action); \
diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript
index a6c5ad984e2..ac38c0458d9 100644
--- a/source/blender/imbuf/intern/openexr/SConscript
+++ b/source/blender/imbuf/intern/openexr/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
source_files = ['openexr_api.cpp']
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index da7b31cc2ba..1b7aa1e7e63 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -882,6 +882,12 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
const char *token;
char tokenbuf[EXR_TOT_MAXNAME];
int len;
+
+ /* some multilayers have the combined buffer with names A B G R saved */
+ if (name[1] == 0) {
+ echan->chan_id = name[0];
+ return 1;
+ }
/* last token is single character channel identifier */
len = imb_exr_split_token(name, end, &token);
@@ -1197,6 +1203,9 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
delete file;
}
}
+
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
}
return(ibuf);
}
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index dcfebb95b87..68385f22a7a 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -60,6 +60,11 @@ static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length);
static void WriteData(png_structp png_ptr, png_bytep data, png_size_t length);
static void Flush(png_structp png_ptr);
+BLI_INLINE unsigned short UPSAMPLE_8_TO_16(const unsigned char _val)
+{
+ return (_val << 8) + _val;
+}
+
int imb_is_a_png(unsigned char *mem)
{
int ret_val = 0;
@@ -102,6 +107,17 @@ static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length)
longjmp(png_jmpbuf(png_ptr), 1);
}
+static float channel_colormanage_noop(float value)
+{
+ return value;
+}
+
+/* wrap to avoid macro calling functions multiple times */
+BLI_INLINE unsigned short ftoshort(float val)
+{
+ return FTOUSHORT(val);
+}
+
int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
{
png_structp png_ptr;
@@ -109,22 +125,39 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
unsigned char *pixels = NULL;
unsigned char *from, *to;
+ unsigned short *pixels16 = NULL, *to16;
+ float *from_float, from_straight[4];
png_bytepp row_pointers = NULL;
int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
FILE *fp = NULL;
+ bool is_16bit = (ibuf->ftype & PNG_16BIT);
+ bool has_float = (ibuf->rect_float != NULL);
+ int channels_in_float = ibuf->channels ? ibuf->channels : 4;
+
+ float (*chanel_colormanage_cb)(float);
+
/* use the jpeg quality setting for compression */
int compression;
compression = (int)(((float)(ibuf->ftype & 0xff) / 11.1111f));
compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);
+ if (ibuf->float_colorspace) {
+ /* float buffer was managed already, no need in color space conversion */
+ chanel_colormanage_cb = channel_colormanage_noop;
+ }
+ else {
+ /* standard linear-to-srgb conversion if float buffer wasn't managed */
+ chanel_colormanage_cb = linearrgb_to_srgb;
+ }
+
/* for prints */
if (flags & IB_mem)
name = "<memory>";
bytesperpixel = (ibuf->planes + 7) >> 3;
if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
- printf("imb_savepng: Cunsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
+ printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
return (0);
}
@@ -150,8 +183,12 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
/* copy image data */
- pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "pixels");
- if (pixels == NULL) {
+ if (is_16bit)
+ pixels16 = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned short), "png 16bit pixels");
+ else
+ pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "png 8bit pixels");
+
+ if (pixels == NULL && pixels16 == NULL) {
png_destroy_write_struct(&png_ptr, &info_ptr);
printf("imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n", ibuf->x, ibuf->y, bytesperpixel, name);
return 0;
@@ -159,32 +196,152 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
from = (unsigned char *) ibuf->rect;
to = pixels;
+ from_float = ibuf->rect_float;
+ to16 = pixels16;
switch (bytesperpixel) {
case 4:
color_type = PNG_COLOR_TYPE_RGBA;
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = from[3];
- to += 4; from += 4;
+ if (is_16bit) {
+ if (has_float) {
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
+ to16 += 4; from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16[3] = 65535;
+ to16 += 4; from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16[3] = 65535;
+ to16 += 4; from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16[1] = UPSAMPLE_8_TO_16(from[1]);
+ to16[2] = UPSAMPLE_8_TO_16(from[2]);
+ to16[3] = UPSAMPLE_8_TO_16(from[3]);
+ to16 += 4; from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+ to += 4; from += 4;
+ }
}
break;
case 3:
color_type = PNG_COLOR_TYPE_RGB;
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to += 3; from += 4;
+ if (is_16bit) {
+ if (has_float) {
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16 += 3; from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16 += 3; from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16 += 3; from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16[1] = UPSAMPLE_8_TO_16(from[1]);
+ to16[2] = UPSAMPLE_8_TO_16(from[2]);
+ to16 += 3; from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to += 3; from += 4;
+ }
}
break;
case 1:
color_type = PNG_COLOR_TYPE_GRAY;
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to++; from += 4;
+ if (is_16bit) {
+ if (has_float) {
+ float rgb[3];
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ rgb[0] = chanel_colormanage_cb(from_straight[0]);
+ rgb[1] = chanel_colormanage_cb(from_straight[1]);
+ rgb[2] = chanel_colormanage_cb(from_straight[2]);
+ to16[0] = ftoshort(rgb_to_bw(rgb));
+ to16++; from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ rgb[0] = chanel_colormanage_cb(from_float[0]);
+ rgb[1] = chanel_colormanage_cb(from_float[1]);
+ rgb[2] = chanel_colormanage_cb(from_float[2]);
+ to16[0] = ftoshort(rgb_to_bw(rgb));
+ to16++; from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16++; from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16++; from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to++; from += 4;
+ }
}
break;
}
@@ -203,7 +360,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
fp = BLI_fopen(name, "wb");
if (!fp) {
png_destroy_write_struct(&png_ptr, &info_ptr);
- MEM_freeN(pixels);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
printf("imb_savepng: Cannot open file for writing: '%s'\n", name);
return 0;
}
@@ -227,7 +387,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
info_ptr,
ibuf->x,
ibuf->y,
- 8,
+ is_16bit ? 16 : 8,
color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
@@ -268,12 +428,19 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
/* write the file header information */
png_write_info(png_ptr, info_ptr);
+#ifdef __LITTLE_ENDIAN__
+ png_set_swap(png_ptr);
+#endif
+
/* allocate memory for an array of row-pointers */
row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
if (row_pointers == NULL) {
printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name);
png_destroy_write_struct(&png_ptr, &info_ptr);
- MEM_freeN(pixels);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
if (fp) {
fclose(fp);
}
@@ -281,9 +448,17 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
}
/* set the individual row-pointers to point at the correct offsets */
- for (i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char));
+ if (is_16bit) {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)
+ ((unsigned short *)pixels16 + (i * ibuf->x) * bytesperpixel);
+ }
+ }
+ else {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)
+ ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char));
+ }
}
/* write out the entire image data in one call */
@@ -293,7 +468,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
png_write_end(png_ptr, info_ptr);
/* clean up */
- MEM_freeN(pixels);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
MEM_freeN(row_pointers);
png_destroy_write_struct(&png_ptr, &info_ptr);
@@ -394,6 +572,8 @@ ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags, char colorspace[I
if (ibuf) {
ibuf->ftype = PNG;
+ if (bit_depth == 16)
+ ibuf->ftype |= PNG_16BIT;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
int unit_type;
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 03ed1bb8008..d09adeb09b5 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -212,6 +212,9 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char color
if (ibuf == NULL) return NULL;
ibuf->ftype = RADHDR;
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
+
if (flags & IB_test) return ibuf;
/* read in and decode the actual data */
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index be20c80bdec..4d47d883444 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -75,6 +75,8 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char co
if (type->load) {
ibuf = type->load(mem, size, flags, effective_colorspace);
if (ibuf) {
+ int alpha_flags;
+
if (colorspace) {
if (ibuf->rect) {
/* byte buffer is never internally converted to some standard space,
@@ -86,15 +88,37 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char co
BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
}
+ if (flags & IB_alphamode_detect)
+ alpha_flags = ibuf->flags & IB_alphamode_premul;
+ else
+ alpha_flags = flags & IB_alphamode_premul;
+
+ if (flags & IB_ignore_alpha) {
+ IMB_rectfill_alpha(ibuf, 1.0f);
+ }
+ else {
+ if (alpha_flags & IB_alphamode_premul) {
+ if (ibuf->rect) {
+ IMB_unpremultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, floats are expected to be premul */
+ }
+ }
+ else {
+ if (ibuf->rect_float) {
+ IMB_premultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, bytes are expected to be straight */
+ }
+ }
+ }
+
/* OCIO_TODO: in some cases it's faster to do threaded conversion,
* but how to distinguish such cases */
colormanage_imbuf_make_linear(ibuf, effective_colorspace);
- if (flags & IB_premul) {
- IMB_premultiply_alpha(ibuf);
- ibuf->flags |= IB_premul;
- }
-
return ibuf;
}
}
@@ -230,4 +254,3 @@ void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
close(file);
}
-
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index d2b0645cf93..0b739b9fe92 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -594,11 +594,13 @@ void IMB_rectfill_area(struct ImBuf *ibuf, const float col[4], int x1, int y1, i
void IMB_rectfill_alpha(ImBuf *ibuf, const float value)
{
int i;
- if (ibuf->rect_float) {
+
+ if (ibuf->rect_float && (ibuf->channels == 4)) {
float *fbuf = ibuf->rect_float + 3;
for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf += 4) { *fbuf = value; }
}
- else {
+
+ if (ibuf->rect) {
const unsigned char cvalue = value * 255;
unsigned char *cbuf = ((unsigned char *)ibuf->rect) + 3;
for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf += 4) { *cbuf = cvalue; }
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 1e701b8d615..1050d3f8715 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -33,6 +33,7 @@
#include "BLI_utildefines.h"
+#include "BLI_math_color.h"
#include "MEM_guardedalloc.h"
#include "imbuf.h"
@@ -291,6 +292,37 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1)
return (ibuf2);
}
+/* pretty much specific functions which converts uchar <-> ushort but assumes
+ * ushort range of 255*255 which is more convenient here
+ */
+MINLINE void straight_uchar_to_premul_ushort(unsigned short result[4], const unsigned char color[4])
+{
+ unsigned short alpha = color[3];
+
+ result[0] = color[0] * alpha;
+ result[1] = color[1] * alpha;
+ result[2] = color[2] * alpha;
+ result[3] = alpha * 255;
+}
+
+MINLINE void premul_ushort_to_straight_uchar(unsigned char *result, const unsigned short color[4])
+{
+ if (color[3] <= 255) {
+ result[0] = color[0] / 255;
+ result[1] = color[1] / 255;
+ result[2] = color[2] / 255;
+ result[3] = color[3] / 255;
+ }
+ else {
+ unsigned short alpha = color[3] / 255;
+
+ result[0] = color[0] / alpha;
+ result[1] = color[1] / alpha;
+ result[2] = color[2] / alpha;
+ result[3] = alpha;
+ }
+}
+
/* result in ibuf2, scaling should be done correctly */
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
@@ -303,23 +335,33 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
}
if (do_rect) {
- char *p1, *p2, *dest;
+ unsigned char *cp1, *cp2, *dest;
- p1 = (char *) ibuf1->rect;
- dest = (char *) ibuf2->rect;
+ cp1 = (unsigned char *) ibuf1->rect;
+ dest = (unsigned char *) ibuf2->rect;
for (y = ibuf2->y; y > 0; y--) {
- p2 = p1 + (ibuf1->x << 2);
+ cp2 = cp1 + (ibuf1->x << 2);
for (x = ibuf2->x; x > 0; x--) {
- dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2;
- dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2;
- dest[2] = (p1[2] + p2[2] + p1[6] + p2[6]) >> 2;
- dest[3] = (p1[3] + p2[3] + p1[7] + p2[7]) >> 2;
- p1 += 8;
- p2 += 8;
+ unsigned short p1i[8], p2i[8], desti[4];
+
+ straight_uchar_to_premul_ushort(p1i, cp1);
+ straight_uchar_to_premul_ushort(p2i, cp2);
+ straight_uchar_to_premul_ushort(p1i + 4, cp1 + 4);
+ straight_uchar_to_premul_ushort(p2i + 4, cp2 + 4);
+
+ desti[0] = ((unsigned int) p1i[0] + p2i[0] + p1i[4] + p2i[4]) >> 2;
+ desti[1] = ((unsigned int) p1i[1] + p2i[1] + p1i[5] + p2i[5]) >> 2;
+ desti[2] = ((unsigned int) p1i[2] + p2i[2] + p1i[6] + p2i[6]) >> 2;
+ desti[3] = ((unsigned int) p1i[3] + p2i[3] + p1i[7] + p2i[7]) >> 2;
+
+ premul_ushort_to_straight_uchar(dest, desti);
+
+ cp1 += 8;
+ cp2 += 8;
dest += 4;
}
- p1 = p2;
- if (ibuf1->x & 1) p1 += 4;
+ cp1 = cp2;
+ if (ibuf1->x & 1) cp1 += 4;
}
}
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 94bb85b49ea..c1d80ad9067 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -154,7 +154,7 @@ static void escape_uri_string(const char *string, char *escaped_string, int len,
*q++ = *p;
}
}
-
+
*q = '\0';
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 83830f260e1..2630aebef3b 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -376,7 +376,7 @@ static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image)
* This method is most flexible and can handle multiple different bit depths
* and RGB channel orderings.
*/
-static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
+static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image)
{
ImBuf *tmpibuf;
int success = 0;
@@ -390,6 +390,23 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */
TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);
+ if (spp == 4) {
+ /* HACK: this is really tricky hack, which is only needed to force libtiff
+ * do not touch RGB channels when there's alpha channel present
+ * The thing is: libtiff will premul RGB if alpha mode is set to
+ * unassociated, which really conflicts with blender's assumptions
+ *
+ * Alternative would be to unpremul after load, but it'll be really
+ * lossy and unwanted behavior
+ *
+ * So let's keep this thing here for until proper solution is found (sergey)
+ */
+
+ unsigned short extraSampleTypes[1];
+ extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
+ TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes);
+ }
+
imb_read_tiff_resolution(ibuf, image);
scanline = TIFFScanlineSize(image);
@@ -471,10 +488,6 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
if (bitspersample < 16)
if (ENDIAN_ORDER == B_ENDIAN)
IMB_convert_rgba_to_abgr(tmpibuf);
- if (premul) {
- IMB_premultiply_alpha(tmpibuf);
- ibuf->flags |= IB_premul;
- }
/* assign rect last */
if (tmpibuf->rect_float)
@@ -557,6 +570,18 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[
return NULL;
}
+ /* get alpha mode from file header */
+ if (flags & IB_alphamode_detect) {
+ if (spp == 4) {
+ unsigned short extra, *extraSampleTypes;
+
+ TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes);
+
+ if (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA)
+ ibuf->flags |= IB_alphamode_premul;
+ }
+ }
+
/* if testing, we're done */
if (flags & IB_test) {
TIFFClose(image);
@@ -585,9 +610,6 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[
hbuf->miplevel = level;
hbuf->ftype = ibuf->ftype;
ibuf->mipmap[level - 1] = hbuf;
-
- if (flags & IB_premul)
- hbuf->flags |= IB_premul;
}
else
hbuf = ibuf;
@@ -608,7 +630,7 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[
}
/* read pixels */
- if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image, 0)) {
+ if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image)) {
fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n");
TIFFClose(image);
return NULL;
@@ -644,9 +666,6 @@ void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int
if (TIFFReadRGBATile(image, tx * ibuf->tilex, (ibuf->ytiles - 1 - ty) * ibuf->tiley, rect) == 1) {
if (ibuf->tiley > ibuf->y)
memmove(rect, rect + ibuf->tilex * (ibuf->tiley - ibuf->y), sizeof(int) * ibuf->tilex * ibuf->y);
-
- if (ibuf->flags & IB_premul)
- IMB_premultiply_rect(rect, 32, ibuf->tilex, ibuf->tiley);
}
else
printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel);
@@ -689,8 +708,6 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
float *fromf = NULL;
float xres, yres;
int x, y, from_i, to_i, i;
- int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
-
/* check for a valid number of bytes per pixel. Like the PNG writer,
* the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding
@@ -763,6 +780,13 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
if (samplesperpixel == 4) {
+ unsigned short extraSampleTypes[1];
+
+ if (bitspersample == 16)
+ extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
+ else
+ extraSampleTypes[0] = EXTRASAMPLE_UNASSALPHA;
+
/* RGBA images */
TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
extraSampleTypes);
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 42fb0c79b62..549a95e383d 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -306,8 +306,8 @@ static int isffmpeg(const char *filename)
return 0;
}
- if (av_find_stream_info(pFormatCtx) < 0) {
- if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
+ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
+ if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
av_close_input_file(pFormatCtx);
return 0;
}
@@ -340,7 +340,7 @@ static int isffmpeg(const char *filename)
return 0;
}
- if (avcodec_open(pCodecCtx, pCodec) < 0) {
+ if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
av_close_input_file(pFormatCtx);
return 0;
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index a769ce742c9..91e98181ab9 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -42,7 +42,9 @@ extern "C" {
struct Library;
struct FileData;
struct ID;
-
+struct PackedFile;
+struct GPUTexture;
+
typedef struct IDPropertyData {
void *pointer;
ListBase group;
@@ -136,6 +138,8 @@ typedef struct Library {
* setting 'name' directly and it will be kept in
* sync - campbell */
struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
+
+ struct PackedFile *packedfile;
} Library;
enum eIconSizes {
@@ -151,6 +155,7 @@ typedef struct PreviewImage {
short changed[2];
short changed_timestamp[2];
unsigned int *rect[2];
+ struct GPUTexture *gputexture[2];
} PreviewImage;
/**
@@ -228,7 +233,8 @@ typedef struct PreviewImage {
#ifdef GS
# undef GS
#endif
-#define GS(a) (*((short *)(a)))
+// #define GS(a) (*((short *)(a)))
+#define GS(a) (CHECK_TYPE_INLINE(a, const char), (*((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++; }
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index b445d59db2c..7c4772f24e8 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -277,10 +277,13 @@ typedef struct bActuator {
#define ACT_ANG_VEL_LOCAL 32
//#define ACT_ADD_LIN_VEL_LOCAL 64
#define ACT_ADD_LIN_VEL 64
+#define ACT_ADD_CHAR_LOC 128
+#define ACT_CHAR_JUMP 256
/* objectactuator->type */
-#define ACT_OBJECT_NORMAL 0
-#define ACT_OBJECT_SERVO 1
+#define ACT_OBJECT_NORMAL 0
+#define ACT_OBJECT_SERVO 1
+#define ACT_OBJECT_CHARACTER 2
/* actuator->type */
#define ACT_OBJECT 0
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index fd68a6d9a27..8fcb079cd4f 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -198,7 +198,9 @@ typedef enum eBone_Flag {
BONE_EDITMODE_LOCKED = (1 << 19), /* bone transforms are locked in EditMode */
BONE_TRANSFORM_CHILD = (1 << 20), /* Indicates that a parent is also being transformed */
BONE_UNSELECTABLE = (1 << 21), /* bone cannot be selected */
- BONE_NO_LOCAL_LOCATION = (1 << 22) /* bone location is in armature space */
+ BONE_NO_LOCAL_LOCATION = (1 << 22), /* bone location is in armature space */
+ BONE_RELATIVE_PARENTING = (1 << 23) /* object child will use relative transform (like deform) */
+
} eBone_Flag;
#define MAXBONENAME 64
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index cc26ee479d7..62d696ec255 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -112,7 +112,7 @@ typedef enum BrushFlags {
BRUSH_SIZE_PRESSURE = (1 << 3),
BRUSH_JITTER_PRESSURE = (1 << 4),
BRUSH_SPACING_PRESSURE = (1 << 5),
- BRUSH_FIXED_TEX = (1 << 6),
+ // BRUSH_FIXED_TEX = (1 << 6), /* obsolete, use mtex->brush_map_mode = MTEX_MAP_MODE_TILED instead */
BRUSH_RAKE = (1 << 7),
BRUSH_ANCHORED = (1 << 8),
BRUSH_DIR_IN = (1 << 9),
@@ -156,10 +156,7 @@ typedef enum BrushSculptTool {
SCULPT_TOOL_THUMB = 12,
SCULPT_TOOL_SNAKE_HOOK = 13,
SCULPT_TOOL_ROTATE = 14,
-
- /* slot 15 is free for use */
- /* SCULPT_TOOL_ = 15, */
-
+ SCULPT_TOOL_SIMPLIFY = 15,
SCULPT_TOOL_CREASE = 16,
SCULPT_TOOL_BLOB = 17,
SCULPT_TOOL_CLAY_STRIPS = 18,
@@ -167,10 +164,12 @@ typedef enum BrushSculptTool {
} BrushSculptTool;
/* ImagePaintSettings.tool */
-#define PAINT_TOOL_DRAW 0
-#define PAINT_TOOL_SOFTEN 1
-#define PAINT_TOOL_SMEAR 2
-#define PAINT_TOOL_CLONE 3
+typedef enum BrushImagePaintTool {
+ PAINT_TOOL_DRAW = 0,
+ PAINT_TOOL_SOFTEN = 1,
+ PAINT_TOOL_SMEAR = 2,
+ PAINT_TOOL_CLONE = 3
+} BrushImagePaintTool;
/* direction that the brush displaces along */
enum {
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 6f7bb5a723e..e28b8780250 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -46,7 +46,7 @@ typedef struct CustomDataLayer {
int active_clone; /* number of the layer to render*/
int active_mask; /* number of the layer to render*/
int uid; /* shape keyblock unique id reference*/
- char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_AAME */
+ char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_NAME */
void *data; /* layer data */
} CustomDataLayer;
diff --git a/source/blender/makesdna/DNA_genfile.h b/source/blender/makesdna/DNA_genfile.h
index 2d1549ff487..ac75b03c742 100644
--- a/source/blender/makesdna/DNA_genfile.h
+++ b/source/blender/makesdna/DNA_genfile.h
@@ -35,9 +35,13 @@
struct SDNA;
-extern const unsigned char DNAstr[]; /* DNA.c */
-extern const int DNAlen;
+/* DNAstr contains the prebuilt SDNA structure defining the layouts of the types
+ * used by this version of Blender. It is defined in a file dna.c, which is
+ * generated by the makesdna program during the build process (see makesdna.c). */
+extern const unsigned char DNAstr[];
+extern const int DNAlen; /* length of DNAstr */
+/* primitive (non-struct, non-pointer/function/array) types--do not change ordering! */
typedef enum eSDNA_Type {
SDNA_TYPE_CHAR = 0,
SDNA_TYPE_UCHAR = 1,
@@ -56,7 +60,7 @@ typedef enum eSDNA_Type {
/* define so switch statements don't complain */
#define SDNA_TYPE_VOID 9
-struct SDNA *DNA_sdna_from_data(const void *data, const int datalen, int do_endian_swap);
+struct SDNA *DNA_sdna_from_data(const void *data, const int datalen, bool do_endian_swap);
void DNA_sdna_free(struct SDNA *sdna);
int DNA_struct_find_nr(struct SDNA *sdna, const char *str);
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index fe3550327f7..682f54481fc 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -111,6 +111,9 @@ typedef struct Image {
/* color management */
ColorManagedColorspaceSettings colorspace_settings;
+ char alpha_mode;
+
+ char pad[7];
} Image;
@@ -119,15 +122,16 @@ typedef struct Image {
/* Image.flag */
#define IMA_FIELDS 1
#define IMA_STD_FIELD 2
-#define IMA_DO_PREMUL 4
+#define IMA_DO_PREMUL 4 /* deprecated, should not be used */
#define IMA_REFLECT 16
#define IMA_NOCOLLECT 32
-#define IMA_DEPRECATED 64
+#define IMA_DONE_TAG 64
#define IMA_OLD_PREMUL 128
-#define IMA_CM_PREDIVIDE 256
+/*#define IMA_CM_PREDIVIDE 256*/ /* deprecated, should not be used */
#define IMA_USED_FOR_RENDER 512
#define IMA_USER_FRAME_IN_RANGE 1024 /* for image user, but these flags are mixed */
#define IMA_VIEW_AS_RENDER 2048
+#define IMA_IGNORE_ALPHA 4096
/* Image.tpageflag */
#define IMA_TILES 1
@@ -148,4 +152,10 @@ typedef struct Image {
/* gen_flag */
#define IMA_GEN_FLOAT 1
+/* alpha_mode */
+enum {
+ IMA_ALPHA_STRAIGHT = 0,
+ IMA_ALPHA_PREMUL = 1,
+};
+
#endif
diff --git a/source/blender/makesdna/DNA_listBase.h b/source/blender/makesdna/DNA_listBase.h
index 333e414278d..f6035cd6653 100644
--- a/source/blender/makesdna/DNA_listBase.h
+++ b/source/blender/makesdna/DNA_listBase.h
@@ -31,6 +31,9 @@
* \ingroup DNA
* \brief These structs are the foundation for all linked lists in the
* library system.
+ *
+ * Doubly-linked lists start from a ListBase and contain elements beginning
+ * with Link.
*/
#ifndef __DNA_LISTBASE_H__
@@ -40,13 +43,13 @@
extern "C" {
#endif
-/* generic - all structs which are used in linked-lists used this */
+/* generic - all structs which are put into linked lists begin with this */
typedef struct Link {
struct Link *next, *prev;
} Link;
-/* use this when it is not worth defining a custom one... */
+/* simple subclass of Link--use this when it is not worth defining a custom one... */
typedef struct LinkData {
struct LinkData *next, *prev;
void *data;
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 9a8d3bf981c..fceea396507 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -309,7 +309,7 @@ typedef struct Material {
#define MA_SPEC_WARDISO 4
/* dynamode */
-#define MA_DRAW_DYNABUTS 1 /* deprecated */
+// #define MA_DRAW_DYNABUTS 1 /* deprecated */
#define MA_FH_NOR 2
/* ramps */
@@ -373,7 +373,7 @@ typedef struct Material {
#define MAP_AMB 2048
#define MAP_DISPLACE 4096
#define MAP_WARP 8192
-#define MAP_LAYER 16384 /* unused */
+// #define MAP_LAYER 16384 /* unused */
/* volume mapto - reuse definitions for now - a bit naughty! */
#define MAP_DENSITY 128
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index dd0845dbf1e..f2ee73392c7 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -119,7 +119,10 @@ typedef struct Mesh {
short texflag, drawflag;
short smoothresh, flag;
- short subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED;
+ /* customdata flag, for bevel-weight and crease, which are now optional */
+ char cd_flag, pad;
+
+ char subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED;
char subsurftype DNA_DEPRECATED; /* only kept for backwards compat, not used anymore */
char editflag;
@@ -147,15 +150,15 @@ typedef struct TFace {
#define ME_EDIT_MIRROR_Y (1 << 1) // unused so far
#define ME_EDIT_MIRROR_Z (1 << 2) // unused so far
-#define ME_EDIT_PAINT_MASK (1 << 3)
+#define ME_EDIT_PAINT_FACE_SEL (1 << 3)
#define ME_EDIT_MIRROR_TOPO (1 << 4)
-#define ME_EDIT_VERT_SEL (1 << 5)
+#define ME_EDIT_PAINT_VERT_SEL (1 << 5)
/* we cant have both flags enabled at once,
* flags defined in DNA_scene_types.h */
#define ME_EDIT_PAINT_SEL_MODE(_me) ( \
- (_me->editflag & ME_EDIT_PAINT_MASK) ? SCE_SELECT_FACE : \
- (_me->editflag & ME_EDIT_VERT_SEL) ? SCE_SELECT_VERTEX : \
+ (_me->editflag & ME_EDIT_PAINT_FACE_SEL) ? SCE_SELECT_FACE : \
+ (_me->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : \
0 \
)
@@ -170,6 +173,12 @@ typedef struct TFace {
#define ME_SUBSURF 128
#define ME_OPT_EDGES 256
#define ME_DS_EXPAND 512
+#define ME_SCULPT_DYNAMIC_TOPOLOGY 1024
+
+/* me->cd_flag */
+#define ME_CDFLAG_VERT_BWEIGHT (1 << 0)
+#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1)
+#define ME_CDFLAG_EDGE_CREASE (1 << 2)
/* me->drawflag, short */
#define ME_DRAWEDGES (1 << 0)
@@ -177,7 +186,7 @@ typedef struct TFace {
#define ME_DRAWNORMALS (1 << 2)
#define ME_DRAW_VNORMALS (1 << 3)
-#define ME_ALLEDGES (1 << 4)
+// #define ME_ALLEDGES (1 << 4)
#define ME_HIDDENEDGES (1 << 5)
#define ME_DRAWCREASES (1 << 6)
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 0c193e9be21..a189219b211 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -118,9 +118,14 @@ typedef struct MLoopUV {
#define MLOOPUV_VERTSEL 2
#define MLOOPUV_PINNED 4
-/* at the moment alpha is abused for vertex painting
- * and not used for transparency,
- * note that red and blue are _not_ swapped, as they are with #MCol */
+/**
+ * at the moment alpha is abused for vertex painting,
+ * otherwise it should _always_ be initialized to 255
+ * Mostly its not used for transparency...
+ * (except for blender-internal rendering, see [#34096]).
+ *
+ * \note red and blue are _not_ swapped, as they are with #MCol
+ */
typedef struct MLoopCol {
char r, g, b, a;
} MLoopCol;
@@ -167,7 +172,7 @@ typedef struct MIntProperty {
int i;
} MIntProperty;
typedef struct MStringProperty {
- char s[256];
+ char s[255], s_len;
} MStringProperty;
typedef struct OrigSpaceFace {
diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h
index 5b37ff523cb..56683bf4797 100644
--- a/source/blender/makesdna/DNA_meta_types.h
+++ b/source/blender/makesdna/DNA_meta_types.h
@@ -121,6 +121,8 @@ typedef struct MetaBall {
#define MB_ELIPSOID 6
#define MB_CUBE 7
+#define MB_TYPE_SIZE_SQUARED(type) (type == MB_ELIPSOID)
+
/* ml->flag */
#define MB_NEGATIVE 2
#define MB_HIDE 8
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 3875a0d5799..117eac0e42b 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -76,7 +76,9 @@ typedef enum ModifierType {
eModifierType_Remesh = 41,
eModifierType_Skin = 42,
eModifierType_LaplacianSmooth = 43,
- eModifierType_Triangulate = 44,
+ eModifierType_Triangulate = 44,
+ eModifierType_UVWarp = 45,
+ eModifierType_MeshCache = 46,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -586,7 +588,7 @@ typedef struct MeshDeformModifierData {
/* runtime */
void (*bindfunc)(struct Scene *scene,
struct MeshDeformModifierData *mmd,
- float *vertexcos, int totvert, float cagemat[][4]);
+ float *vertexcos, int totvert, float cagemat[4][4]);
} MeshDeformModifierData;
typedef enum {
@@ -1132,6 +1134,7 @@ enum {
#define MOD_LAPLACIANSMOOTH_Y (1<<2)
#define MOD_LAPLACIANSMOOTH_Z (1<<3)
#define MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME (1 << 4)
+#define MOD_LAPLACIANSMOOTH_NORMALIZED (1 << 5)
typedef struct LaplacianSmoothModifierData {
ModifierData modifier;
@@ -1140,4 +1143,80 @@ typedef struct LaplacianSmoothModifierData {
short flag, repeat;
} LaplacianSmoothModifierData;
-#endif
+typedef struct UVWarpModifierData {
+ ModifierData modifier;
+
+ char axis_u, axis_v;
+ char pad[6];
+ float center[2]; /* used for rotate/scale */
+
+ struct Object *object_src; /* source */
+ char bone_src[64]; /* optional name of bone target, MAX_ID_NAME-2 */
+ struct Object *object_dst; /* target */
+ char bone_dst[64]; /* optional name of bone target, MAX_ID_NAME-2 */
+
+ char vgroup_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */
+ char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+} UVWarpModifierData;
+
+/* cache modifier */
+typedef struct MeshCacheModifierData {
+ ModifierData modifier;
+ char flag;
+ char type; /* file format */
+ char time_mode;
+ char play_mode;
+
+ /* axis conversion */
+ char forward_axis;
+ char up_axis;
+ char flip_axis;
+
+ char interp;
+
+ float factor;
+ char deform_mode;
+ char pad[7];
+
+ /* play_mode == MOD_MESHCACHE_PLAY_CFEA */
+ float frame_start;
+ float frame_scale;
+
+ /* play_mode == MOD_MESHCACHE_PLAY_EVAL */
+ /* we could use one float for all these but their purpose is very different */
+ float eval_frame;
+ float eval_time;
+ float eval_factor;
+
+ char filepath[1024]; // FILE_MAX
+} MeshCacheModifierData;
+
+enum {
+ MOD_MESHCACHE_TYPE_MDD = 1,
+ MOD_MESHCACHE_TYPE_PC2 = 2
+};
+
+enum {
+ MOD_MESHCACHE_DEFORM_OVERWRITE = 0,
+ MOD_MESHCACHE_DEFORM_INTEGRATE = 1
+};
+
+enum {
+ MOD_MESHCACHE_INTERP_NONE = 0,
+ MOD_MESHCACHE_INTERP_LINEAR = 1,
+ // MOD_MESHCACHE_INTERP_CARDINAL = 2
+};
+
+enum {
+ MOD_MESHCACHE_TIME_FRAME = 0,
+ MOD_MESHCACHE_TIME_SECONDS = 1,
+ MOD_MESHCACHE_TIME_FACTOR = 2,
+};
+
+enum {
+ MOD_MESHCACHE_PLAY_CFEA = 0,
+ MOD_MESHCACHE_PLAY_EVAL = 1,
+};
+
+
+#endif /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index a05ff66e683..5aaf46a541f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -309,9 +309,11 @@ typedef struct bNodeTree {
#define NTREE_TYPE_INIT 1
/* ntree->flag */
-#define NTREE_DS_EXPAND 1 /* for animation editors */
-#define NTREE_COM_OPENCL 2 /* use opencl */
-#define NTREE_TWO_PASS 4 /* two pass */
+#define NTREE_DS_EXPAND 1 /* for animation editors */
+#define NTREE_COM_OPENCL 2 /* use opencl */
+#define NTREE_TWO_PASS 4 /* two pass */
+#define NTREE_COM_GROUPNODE_BUFFER 8 /* use groupnode buffers */
+
/* XXX not nice, but needed as a temporary flags
* for group updates after library linking.
*/
@@ -711,6 +713,13 @@ typedef struct NodeTrackPosData {
char track_name[64];
} NodeTrackPosData;
+typedef struct NodeTranslateData {
+ char wrap_axis;
+ char relative;
+ char pad[6];
+} NodeTranslateData;
+
+
typedef struct NodeShaderScript {
int mode;
int flag;
@@ -837,6 +846,12 @@ typedef struct NodeShaderNormalMap {
#define CMP_NODE_BLUR_ASPECT_Y 1
#define CMP_NODE_BLUR_ASPECT_X 2
+/* wrapping */
+#define CMP_NODE_WRAP_NONE 0
+#define CMP_NODE_WRAP_X 1
+#define CMP_NODE_WRAP_Y 2
+#define CMP_NODE_WRAP_XY 3
+
#define CMP_NODE_MASK_MBLUR_SAMPLES_MAX 64
#endif
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 89328c33674..de34f101c31 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -56,6 +56,7 @@ struct ParticleSystem;
struct DerivedMesh;
struct SculptSession;
struct bGPdata;
+struct RigidBodyOb;
/* Vertex Groups - Name Info */
@@ -170,7 +171,7 @@ typedef struct Object {
float sf; /* sf is time-offset */
short flag; /* copy of Base */
- short colbits DNA_DEPRECATED; /* deprecated */
+ short colbits DNA_DEPRECATED; /* deprecated, use 'matbits' */
short transflag, protectflag; /* transformation settings and transform locks */
short trackflag, upflag;
@@ -178,7 +179,7 @@ typedef struct Object {
short ipoflag; // xxx deprecated... old animation system
short scaflag; /* ui state for game logic */
char scavisflag; /* more display settings for game logic */
- char pad5;
+ char depsflag;
int dupon, dupoff, dupsta, dupend;
@@ -218,10 +219,8 @@ typedef struct Object {
char boundtype; /* bounding box use for drawing */
char collision_boundtype; /* bounding box type used for collision */
- char restrictflag; /* for restricting view, select, render etc. accessible in outliner */
-
+ short dtx; /* viewport draw extra settings */
char dt; /* viewport draw type */
- char dtx; /* viewport draw extra settings */
char empty_drawtype;
float empty_drawsize;
float dupfacesca; /* dupliface scale */
@@ -241,8 +240,9 @@ typedef struct Object {
struct BulletSoftBody *bsoft; /* settings for game engine bullet soft body */
+ char restrictflag; /* for restricting view, select, render etc. accessible in outliner */
+ char recalc; /* dependency flag */
short softflag; /* softbody settings */
- short recalc; /* dependency flag */
float anisotropicFriction[3];
ListBase constraints; /* object constraints */
@@ -271,6 +271,9 @@ typedef struct Object {
ListBase gpulamp; /* runtime, for glsl lamp display only */
ListBase pc_ids;
ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */
+
+ struct RigidBodyOb *rigidbody_object; /* settings for Bullet rigid body */
+ struct RigidBodyCon *rigidbody_constraint; /* settings for Bullet constraint */
float ima_ofs[2]; /* offset for image empties */
} Object;
@@ -348,6 +351,9 @@ typedef struct DupliObject {
#define OB_DATA_SUPPORT_ID(_id_type) \
(ELEM8(_id_type, ID_ME, ID_CU, ID_MB, ID_LA, ID_SPK, ID_CA, ID_LT, ID_AR))
+#define OB_DATA_SUPPORT_ID_CASE \
+ ID_ME: case ID_CU: case ID_MB: case ID_LA: case ID_SPK: case ID_CA: case ID_LT: case ID_AR
+
/* partype: first 4 bits: type */
#define PARTYPE 15
#define PAROBJECT 0
@@ -406,17 +412,19 @@ typedef struct DupliObject {
#define OB_PAINT 100 /* temporary used in draw code */
-/* dtx: flags, char! */
-#define OB_AXIS 2
-#define OB_TEXSPACE 4
-#define OB_DRAWNAME 8
-#define OB_DRAWIMAGE 16
+/* dtx: flags (short) */
+#define OB_DRAWBOUNDOX (1 << 0)
+#define OB_AXIS (1 << 1)
+#define OB_TEXSPACE (1 << 2)
+#define OB_DRAWNAME (1 << 3)
+#define OB_DRAWIMAGE (1 << 4)
/* for solid+wire display */
-#define OB_DRAWWIRE 32
- /* for overdraw */
-#define OB_DRAWXRAY 64
+#define OB_DRAWWIRE (1 << 5)
+ /* for overdraw s*/
+#define OB_DRAWXRAY (1 << 6)
/* enable transparent draw */
-#define OB_DRAWTRANSP 128
+#define OB_DRAWTRANSP (1 << 7)
+#define OB_DRAW_ALL_EDGES (1 << 8) /* only for meshes currently */
/* empty_drawtype: no flags */
#define OB_ARROWS 1
@@ -530,6 +538,10 @@ typedef struct DupliObject {
#define OB_BODY_TYPE_NAVMESH 7
#define OB_BODY_TYPE_CHARACTER 8
+/* ob->depsflag */
+#define OB_DEPS_EXTRA_OB_RECALC 1
+#define OB_DEPS_EXTRA_DATA_RECALC 2
+
/* ob->scavisflag */
#define OB_VIS_SENS 1
#define OB_VIS_CONT 2
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 5952aa8afb0..ec2a724ac82 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -116,6 +116,9 @@ typedef struct ParticleData {
float size; /* size and multiplier so that we can update size when ever */
+ float sphdensity; /* density of sph particle */
+ int pad;
+
int hair_index;
short flag;
short alive; /* the life state of a particle */
@@ -130,6 +133,8 @@ typedef struct SPHFluidSettings {
float stiffness_k, stiffness_knear, rest_density;
float buoyancy;
int flag, spring_frames;
+ short solver;
+ short pad[3];
} SPHFluidSettings;
/* fluid->flag */
@@ -141,6 +146,10 @@ typedef struct SPHFluidSettings {
#define SPH_FAC_VISCOSITY 32
#define SPH_FAC_REST_LENGTH 64
+/* fluid->solver (numerical ID field, not bitfield) */
+#define SPH_SOLVER_DDR 0
+#define SPH_SOLVER_CLASSICAL 1
+
typedef struct ParticleSettings {
ID id;
struct AnimData *adt;
@@ -164,7 +173,8 @@ typedef struct ParticleSettings {
/* adaptive path rendering */
short adapt_angle, adapt_pix;
- short disp, omat, interpolation, rotfrom, integrator;
+ short disp, omat, interpolation, integrator;
+ short rotfrom DNA_DEPRECATED;
short kink, kink_axis;
/* billboards */
@@ -350,11 +360,6 @@ typedef struct ParticleSystem {
#define PART_SELF_EFFECT (1<<22)
-/* part->rotfrom */
-#define PART_ROT_KEYS 0 /* interpolate directly from keys */
-#define PART_ROT_ZINCR 1 /* same as zdir but done incrementally from previous position */
-#define PART_ROT_IINCR 2 /* same as idir but done incrementally from previous position */
-
/* part->from */
#define PART_FROM_VERT 0
#define PART_FROM_FACE 1
diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h
new file mode 100644
index 00000000000..c144bc4e588
--- /dev/null
+++ b/source/blender/makesdna/DNA_rigidbody_types.h
@@ -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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file DNA_rigidbody_types.h
+ * \ingroup DNA
+ * \brief Types and defines for representing Rigid Body entities
+ */
+
+#ifndef __DNA_RIGIDBODY_TYPES_H__
+#define __DNA_RIGIDBODY_TYPES_H__
+
+#include "DNA_listBase.h"
+
+struct Group;
+
+struct EffectorWeights;
+
+/* ******************************** */
+/* RigidBody World */
+
+/* RigidBodyWorld (rbw)
+ *
+ * Represents a "simulation scene" existing within the parent scene.
+ */
+typedef struct RigidBodyWorld {
+ /* Sim World Settings ------------------------------------------------------------- */
+ struct EffectorWeights *effector_weights; /* effectors info */
+
+ struct Group *group; /* Group containing objects to use for Rigid Bodies */
+ struct Object **objects; /* Array to access group objects by index, only used at runtime */
+
+ struct Group *constraints; /* Group containing objects to use for Rigid Body Constraints*/
+
+ int pad;
+ float ltime; /* last frame world was evaluated for (internal) */
+
+ /* cache */
+ struct PointCache *pointcache;
+ struct ListBase ptcaches;
+ int numbodies; /* number of objects in rigid body group */
+
+ short steps_per_second; /* number of simulation steps thaken per second */
+ short num_solver_iterations;/* number of constraint solver iterations made per simulation step */
+
+ int flag; /* (eRigidBodyWorld_Flag) settings for this RigidBodyWorld */
+ float time_scale; /* used to speed up or slow down the simulation */
+
+ /* References to Physics Sim objects. Exist at runtime only ---------------------- */
+ void *physics_world; /* Physics sim world (i.e. btDiscreteDynamicsWorld) */
+} RigidBodyWorld;
+
+/* Flags for RigidBodyWorld */
+typedef enum eRigidBodyWorld_Flag {
+ /* should sim world be skipped when evaluating (user setting) */
+ RBW_FLAG_MUTED = (1 << 0),
+ /* sim data needs to be rebuilt */
+ RBW_FLAG_NEEDS_REBUILD = (1 << 1),
+ /* usse split impulse when stepping the simulation */
+ RBW_FLAG_USE_SPLIT_IMPULSE = (1 << 2),
+ /* need to step simulation after frame update */
+ RBW_FLAG_FRAME_UPDATE = (1 << 3)
+} eRigidBodyWorld_Flag;
+
+/* ******************************** */
+/* RigidBody Object */
+
+/* RigidBodyObject (rbo)
+ *
+ * Represents an object participating in a RigidBody sim.
+ * This is attached to each object that is currently
+ * participating in a sim.
+ */
+typedef struct RigidBodyOb {
+ /* References to Physics Sim objects. Exist at runtime only */
+ void *physics_object; /* Physics object representation (i.e. btRigidBody) */
+ void *physics_shape; /* Collision shape used by physics sim (i.e. btCollisionShape) */
+
+ /* General Settings for this RigidBodyOb */
+ short type; /* (eRigidBodyOb_Type) role of RigidBody in sim */
+ short shape; /* (eRigidBody_Shape) collision shape to use */
+
+ int flag; /* (eRigidBodyOb_Flag) */
+ int col_groups; /* Collision groups that determines wich rigid bodies can collide with each other */
+ int pad;
+
+ /* Physics Parameters */
+ float mass; /* how much object 'weighs' (i.e. absolute 'amount of stuff' it holds) */
+
+ float friction; /* resistance of object to movement */
+ float restitution; /* how 'bouncy' object is when it collides */
+
+ float margin; /* tolerance for detecting collisions */
+
+ float lin_damping; /* damping for linear velocities */
+ float ang_damping; /* damping for angular velocities */
+
+ float lin_sleep_thresh; /* deactivation threshold for linear velocities */
+ float ang_sleep_thresh; /* deactivation threshold for angular velocities */
+
+ float orn[4]; /* rigid body orientation */
+ float pos[3]; /* rigid body position */
+ float pad1;
+} RigidBodyOb;
+
+
+/* Participation types for RigidBodyOb */
+typedef enum eRigidBodyOb_Type {
+ /* active geometry participant in simulation. is directly controlled by sim */
+ RBO_TYPE_ACTIVE = 0,
+ /* passive geometry participant in simulation. is directly controlled by animsys */
+ RBO_TYPE_PASSIVE
+} eRigidBodyOb_Type;
+
+/* Flags for RigidBodyOb */
+typedef enum eRigidBodyOb_Flag {
+ /* rigidbody is kinematic (controlled by the animation system) */
+ RBO_FLAG_KINEMATIC = (1 << 0),
+ /* rigidbody needs to be validated (usually set after duplicating and not hooked up yet) */
+ RBO_FLAG_NEEDS_VALIDATE = (1 << 1),
+ /* rigidbody shape needs refreshing (usually after exiting editmode) */
+ RBO_FLAG_NEEDS_RESHAPE = (1 << 2),
+ /* rigidbody can be deactivated */
+ RBO_FLAG_USE_DEACTIVATION = (1 << 3),
+ /* rigidbody is deactivated at the beginning of simulation */
+ RBO_FLAG_START_DEACTIVATED = (1 << 4),
+ /* rigidbody is not dynamically simulated */
+ RBO_FLAG_DISABLED = (1 << 5),
+ /* collision margin is not embedded (only used by convex hull shapes for now) */
+ RBO_FLAG_USE_MARGIN = (1 << 6)
+} eRigidBodyOb_Flag;
+
+/* RigidBody Collision Shape */
+typedef enum eRigidBody_Shape {
+ /* simple box (i.e. bounding box) */
+ RB_SHAPE_BOX = 0,
+ /* sphere */
+ RB_SHAPE_SPHERE,
+ /* rounded "pill" shape (i.e. calcium tablets) */
+ RB_SHAPE_CAPSULE,
+ /* cylinder (i.e. pringles can) */
+ RB_SHAPE_CYLINDER,
+ /* cone (i.e. party hat) */
+ RB_SHAPE_CONE,
+
+ /* convex hull (minimal shrinkwrap encompassing all verts) */
+ RB_SHAPE_CONVEXH,
+ /* triangulated mesh */
+ RB_SHAPE_TRIMESH,
+
+ /* concave mesh approximated using primitives */
+ //RB_SHAPE_COMPOUND,
+} eRigidBody_Shape;
+
+/* ******************************** */
+/* RigidBody Constraint */
+
+/* RigidBodyConstraint (rbc)
+ *
+ * Represents an constraint connecting two rigid bodies.
+ */
+typedef struct RigidBodyCon {
+ struct Object *ob1; /* First object influenced by the constraint */
+ struct Object *ob2; /* Second object influenced by the constraint */
+
+ /* General Settings for this RigidBodyCon */
+ short type; /* (eRigidBodyCon_Type) role of RigidBody in sim */
+ short num_solver_iterations;/* number of constraint solver iterations made per simulation step */
+
+ int flag; /* (eRigidBodyCon_Flag) */
+
+ float breaking_threshold; /* breaking impulse threshold */
+ float pad;
+
+ /* limits */
+ /* translation limits */
+ float limit_lin_x_lower;
+ float limit_lin_x_upper;
+ float limit_lin_y_lower;
+ float limit_lin_y_upper;
+ float limit_lin_z_lower;
+ float limit_lin_z_upper;
+ /* rotation limits */
+ float limit_ang_x_lower;
+ float limit_ang_x_upper;
+ float limit_ang_y_lower;
+ float limit_ang_y_upper;
+ float limit_ang_z_lower;
+ float limit_ang_z_upper;
+
+ /* spring settings */
+ /* resistance to deformation */
+ float spring_stiffness_x;
+ float spring_stiffness_y;
+ float spring_stiffness_z;
+ /* amount of velocity lost over time */
+ float spring_damping_x;
+ float spring_damping_y;
+ float spring_damping_z;
+
+ /* motor settings */
+ float motor_lin_target_velocity; /* linear velocity the motor tries to hold */
+ float motor_ang_target_velocity; /* angular velocity the motor tries to hold */
+ float motor_lin_max_impulse; /* maximum force used to reach linear target velocity */
+ float motor_ang_max_impulse; /* maximum force used to reach angular target velocity */
+
+ /* References to Physics Sim object. Exist at runtime only */
+ void *physics_constraint; /* Physics object representation (i.e. btTypedConstraint) */
+} RigidBodyCon;
+
+
+/* Participation types for RigidBodyOb */
+typedef enum eRigidBodyCon_Type {
+ /* lets bodies rotate around a specified point */
+ RBC_TYPE_POINT = 0,
+ /* lets bodies rotate around a specified axis */
+ RBC_TYPE_HINGE,
+ /* simulates wheel suspension */
+ RBC_TYPE_HINGE2,
+ /* restricts movent to a specified axis */
+ RBC_TYPE_SLIDER,
+ /* lets object rotate within a cpecified cone */
+ RBC_TYPE_CONE_TWIST,
+ /* allows user to specify constraint axes */
+ RBC_TYPE_6DOF,
+ /* like 6DOF but has springs */
+ RBC_TYPE_6DOF_SPRING,
+ /* simulates a universal joint */
+ RBC_TYPE_UNIVERSAL,
+ /* glues two bodies together */
+ RBC_TYPE_FIXED,
+ /* similar to slider but also allows rotation around slider axis */
+ RBC_TYPE_PISTON,
+ /* Simplified spring constraint with only once axis that's automatically placed between the connected bodies */
+ RBC_TYPE_SPRING,
+ /* dirves bodies by applying linear and angular forces */
+ RBC_TYPE_MOTOR
+} eRigidBodyCon_Type;
+
+/* Flags for RigidBodyCon */
+typedef enum eRigidBodyCon_Flag {
+ /* constraint influences rigid body motion */
+ RBC_FLAG_ENABLED = (1 << 0),
+ /* constraint needs to be validated */
+ RBC_FLAG_NEEDS_VALIDATE = (1 << 1),
+ /* allow constrained bodies to collide */
+ RBC_FLAG_DISABLE_COLLISIONS = (1 << 2),
+ /* constraint can break */
+ RBC_FLAG_USE_BREAKING = (1 << 3),
+ /* constraint use custom number of constraint solver iterations */
+ RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS = (1 << 4),
+ /* limits */
+ RBC_FLAG_USE_LIMIT_LIN_X = (1 << 5),
+ RBC_FLAG_USE_LIMIT_LIN_Y = (1 << 6),
+ RBC_FLAG_USE_LIMIT_LIN_Z = (1 << 7),
+ RBC_FLAG_USE_LIMIT_ANG_X = (1 << 8),
+ RBC_FLAG_USE_LIMIT_ANG_Y = (1 << 9),
+ RBC_FLAG_USE_LIMIT_ANG_Z = (1 << 10),
+ /* springs */
+ RBC_FLAG_USE_SPRING_X = (1 << 11),
+ RBC_FLAG_USE_SPRING_Y = (1 << 12),
+ RBC_FLAG_USE_SPRING_Z = (1 << 13),
+ /* motors */
+ RBC_FLAG_USE_MOTOR_LIN = (1 << 14),
+ RBC_FLAG_USE_MOTOR_ANG = (1 << 15)
+} eRigidBodyCon_Flag;
+
+/* ******************************** */
+
+#endif /* __DNA_RIGIDBODY_TYPES_H__ */
+
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 1599b71d832..a6c838eb485 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -271,8 +271,9 @@ typedef struct ImageFormatData {
/* Jpeg2000 */
char jp2_flag;
+ char jp2_codec;
- char pad[7];
+ char pad[6];
/* color management */
ColorManagedViewSettings view_settings;
@@ -341,6 +342,10 @@ typedef struct ImageFormatData {
#define R_IMF_JP2_FLAG_CINE_PRESET (1<<1) /* was R_JPEG2K_CINE_PRESET */
#define R_IMF_JP2_FLAG_CINE_48 (1<<2) /* was R_JPEG2K_CINE_48FPS */
+/* ImageFormatData.jp2_codec */
+#define R_IMF_JP2_CODEC_JP2 0
+#define R_IMF_JP2_CODEC_J2K 1
+
/* ImageFormatData.cineon_flag */
#define R_IMF_CINEON_FLAG_LOG (1<<0) /* was R_CINEON_LOG */
@@ -384,15 +389,19 @@ typedef struct RenderData {
short filtertype; /* filter is box, tent, gauss, mitch, etc */
short size, maximsize; /* size in %, max in Kb */
+
+ short pad6;
+
/* from buttons: */
/**
* The desired number of pixels in the x direction
*/
- short xsch;
+ int xsch;
/**
* The desired number of pixels in the y direction
*/
- short ysch;
+ int ysch;
+
/**
* The number of part to use in the x direction
*/
@@ -405,7 +414,7 @@ typedef struct RenderData {
/**
* render tile dimensions
*/
- short tilex, tiley;
+ int tilex, tiley;
short planes DNA_DEPRECATED, imtype DNA_DEPRECATED, subimtype DNA_DEPRECATED, quality DNA_DEPRECATED; /*deprecated!*/
@@ -413,6 +422,7 @@ typedef struct RenderData {
* Render to image editor, fullscreen or to new window.
*/
short displaymode;
+ short pad7;
/**
* Flags for render settings. Use bit-masking to access the settings.
@@ -453,8 +463,6 @@ typedef struct RenderData {
short frs_sec, edgeint;
- int pad;
-
/* safety, border and display rect */
rctf safety, border;
@@ -491,7 +499,8 @@ typedef struct RenderData {
/* Bake Render options */
short bake_osa, bake_filter, bake_mode, bake_flag;
short bake_normal_space, bake_quad_split;
- float bake_maxdist, bake_biasdist, bake_pad;
+ float bake_maxdist, bake_biasdist;
+ short bake_samples, bake_pad;
/* path to render output */
char pic[1024]; /* 1024 = FILE_MAX */
@@ -635,7 +644,8 @@ typedef struct GameData {
short physicsEngine;
short exitkey, pad;
short ticrate, maxlogicstep, physubstep, maxphystep;
- short obstacleSimulation, pad1;
+ short obstacleSimulation;
+ short raster_storage;
float levelHeight;
float deactivationtime, lineardeactthreshold, angulardeactthreshold, pad2;
} GameData;
@@ -662,6 +672,12 @@ typedef struct GameData {
#define OBSTSIMULATION_TOI_rays 1
#define OBSTSIMULATION_TOI_cells 2
+/* Raster storage */
+#define RAS_STORE_AUTO 0
+#define RAS_STORE_IMMEDIATE 1
+#define RAS_STORE_VA 2
+#define RAS_STORE_VBO 3
+
/* GameData.flag */
#define GAME_RESTRICT_ANIM_UPDATES (1 << 0)
#define GAME_ENABLE_ALL_FRAMES (1 << 1)
@@ -680,6 +696,7 @@ typedef struct GameData {
#define GAME_SHOW_MOUSE (1 << 14)
#define GAME_GLSL_NO_COLOR_MANAGEMENT (1 << 15)
#define GAME_SHOW_OBSTACLE_SIMULATION (1 << 16)
+#define GAME_NO_MATERIAL_CACHING (1 << 17)
/* Note: GameData.flag is now an int (max 32 flags). A short could only take 16 flags */
/* GameData.playerflag */
@@ -800,23 +817,11 @@ typedef struct Sculpt {
//char tablet_size, tablet_strength; XXX not used?
int radial_symm[3];
- // all this below is used to communicate with the cursor drawing routine
-
- /* record movement of mouse so that rake can start at an intuitive angle */
- float last_x, last_y;
- float last_angle;
+ /* Maximum edge length for dynamic topology sculpting (in pixels) */
+ int detail_size;
- int draw_anchored;
- int anchored_size;
- float anchored_location[3];
- float anchored_initial_mouse[2];
-
- int draw_pressure;
- float pressure_value;
-
- float special_rotation;
-
- int pad;
+ /* Direction used for SCULPT_OT_symmetrize operator */
+ int symmetrize_direction;
} Sculpt;
typedef struct UvSculpt {
@@ -879,7 +884,24 @@ typedef struct UnifiedPaintSettings {
/* user preferences for sculpt and paint */
int flag;
- int pad;
+
+ /* rake rotation */
+
+ /* record movement of mouse so that rake can start at an intuitive angle */
+ float last_x, last_y;
+ float last_angle;
+
+ float special_rotation;
+
+ // all this below is used to communicate with the cursor drawing routine
+ int draw_anchored;
+ int anchored_size;
+ float anchored_location[3];
+ float anchored_initial_mouse[2];
+
+ /* drawing pressure */
+ int draw_pressure;
+ float pressure_value;
} UnifiedPaintSettings;
typedef enum {
@@ -945,7 +967,7 @@ typedef struct ToolSettings {
short uvcalc_mapalign;
short uvcalc_flag;
short uv_flag, uv_selectmode;
- short uv_subsurf_level;
+ short pad2;
/* Grease Pencil */
short gpencil_flags;
@@ -973,7 +995,7 @@ typedef struct ToolSettings {
/* Multires */
char multires_subdiv_type;
- char pad2[5];
+ char pad3[5];
/* Skeleton generation */
short skgen_resolution;
@@ -1014,10 +1036,11 @@ typedef struct ToolSettings {
short proportional, prop_mode;
char proportional_objects; /* proportional edit, object mode */
char proportional_mask; /* proportional edit, object mode */
- char pad4[2];
+ char pad4[1];
char auto_normalize; /*auto normalizing mode in wpaint*/
char multipaint; /* paint multiple bones in wpaint */
+ char weightuser;
/* UV painting */
int use_uv_sculpt;
@@ -1118,12 +1141,9 @@ typedef struct Scene {
/* none of the dependency graph vars is mean to be saved */
struct DagForest *theDag;
- short dagisvalid, dagflags;
+ short dagflags;
short recalc; /* recalc = counterpart of ob->recalc */
- short pad6;
- int pad5;
-
/* User-Defined KeyingSets */
int active_keyingset; /* index of the active KeyingSet. first KeyingSet has index 1, 'none' active is 0, 'add new' is -1 */
ListBase keyingsets; /* KeyingSets for this scene */
@@ -1151,6 +1171,9 @@ typedef struct Scene {
ColorManagedViewSettings view_settings;
ColorManagedDisplaySettings display_settings;
ColorManagedColorspaceSettings sequencer_colorspace_settings;
+
+ /* RigidBody simulation world+settings */
+ struct RigidBodyWorld *rigidbody_world;
} Scene;
@@ -1198,6 +1221,7 @@ typedef struct Scene {
/* seq_flag */
#define R_SEQ_GL_PREV 1
// #define R_SEQ_GL_REND 2 // UNUSED, opengl render has its own operator now.
+#define R_SEQ_SOLID_TEX 4
/* displaymode */
@@ -1271,11 +1295,11 @@ typedef struct Scene {
/* alphamode */
#define R_ADDSKY 0
#define R_ALPHAPREMUL 1
-#define R_ALPHAKEY 2
+/*#define R_ALPHAKEY 2*/ /* deprecated, shouldn't be used */
/* color_mgt_flag */
#define R_COLOR_MANAGEMENT (1 << 0) /* deprecated, should only be used in versioning code only */
-#define R_COLOR_MANAGEMENT_PREDIVIDE (1 << 1)
+/*#define R_COLOR_MANAGEMENT_PREDIVIDE (1 << 1)*/ /* deprecated, shouldn't be used */
/* subimtype, flag options for imtype */
#define R_OPENEXR_HALF 1 /*deprecated*/
@@ -1298,6 +1322,7 @@ typedef struct Scene {
#define R_BAKE_NORMALIZE 8
#define R_BAKE_MULTIRES 16
#define R_BAKE_LORES_MESH 32
+#define R_BAKE_VCOL 64
/* bake_normal_space */
#define R_BAKE_SPACE_CAMERA 0
@@ -1421,6 +1446,13 @@ typedef struct Scene {
#define PROP_EDIT_ON 1
#define PROP_EDIT_CONNECTED 2
+/* toolsettings->weightuser */
+enum {
+ OB_DRAW_GROUPUSER_NONE = 0,
+ OB_DRAW_GROUPUSER_ACTIVE = 1,
+ OB_DRAW_GROUPUSER_ALL = 2
+};
+
/* sce->flag */
#define SCE_DS_SELECTED (1<<0)
#define SCE_DS_COLLAPSED (1<<1)
@@ -1464,6 +1496,14 @@ typedef enum SculptFlags {
SCULPT_USE_OPENMP = (1<<7),
SCULPT_ONLY_DEFORM = (1<<8),
SCULPT_SHOW_DIFFUSE = (1<<9),
+
+ /* If set, the mesh will be drawn with smooth-shading in
+ * dynamic-topology mode */
+ SCULPT_DYNTOPO_SMOOTH_SHADING = (1<<10),
+
+ /* If set, dynamic-topology brushes will collapse short edges in
+ * addition to subdividing long ones */
+ SCULPT_DYNTOPO_COLLAPSE = (1<<11)
} SculptFlags;
/* ImagePaintSettings.flag */
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index b1cd54950e6..ceae4e28d1f 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -82,7 +82,8 @@ typedef struct bScreen {
typedef struct ScrVert {
struct ScrVert *next, *prev, *newv;
vec2s vec;
- int flag;
+ /* first one used internally, second one for tools */
+ short flag, editflag;
} ScrVert;
typedef struct ScrEdge {
@@ -109,12 +110,26 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
int sortorder; /* panels are aligned according to increasing sortorder */
struct Panel *paneltab; /* this panel is tabbed in *paneltab */
void *activedata; /* runtime for panel manipulation */
-
- int list_scroll, list_size;
- int list_last_len, list_grip_size;
- char list_search[64];
} Panel;
+typedef struct uiList { /* some list UI data need to be saved in file */
+ struct uiList *next, *prev;
+
+ struct uiListType *type; /* runtime */
+ void *padp;
+
+ char list_id[64]; /* defined as UI_MAX_NAME_STR */
+
+ int layout_type; /* How items are layedout in the list */
+ int padi;
+
+ int list_scroll;
+ int list_size;
+ int list_last_len;
+ int list_grip_size;
+/* char list_search[64]; */
+} uiList;
+
typedef struct ScrArea {
struct ScrArea *next, *prev;
@@ -127,9 +142,11 @@ typedef struct ScrArea {
short winx, winy; /* size */
short headertype; /* OLD! 0=no header, 1= down, 2= up */
- short pad;
short do_refresh; /* private, for spacetype refresh callback */
- short cursor, flag;
+ short flag;
+ short region_active_win; /* index of last used region of 'RGN_TYPE_WINDOW'
+ * runtuime variable, updated by executing operators */
+ short pad;
struct SpaceType *type; /* callbacks for this space type */
@@ -159,14 +176,18 @@ typedef struct ARegion {
short do_draw; /* private, cached notifier events */
short do_draw_overlay; /* private, cached notifier events */
short swap; /* private, indicator to survive swap-exchange */
- short pad[3];
+ short overlap; /* private, set for indicate drawing overlapped */
+ short pad[2];
struct ARegionType *type; /* callbacks for this region type */
ListBase uiblocks; /* uiBlock */
ListBase panels; /* Panel */
+ ListBase ui_lists; /* uiList */
ListBase handlers; /* wmEventHandler */
+ struct wmTimer *regiontimer; /* blend in/out */
+
char *headerstr; /* use this string to draw info */
void *regiondata; /* XXX 2.50, need spacedata equivalent? */
} ARegion;
@@ -212,6 +233,13 @@ typedef struct ARegion {
#define PNL_DEFAULT_CLOSED 1
#define PNL_NO_HEADER 2
+/* uilist layout_type */
+enum {
+ UILST_LAYOUT_DEFAULT = 0,
+ UILST_LAYOUT_COMPACT = 1,
+ UILST_LAYOUT_GRID = 2,
+};
+
/* regiontype, first two are the default set */
/* Do NOT change order, append on end. Types are hardcoded needed */
enum {
@@ -235,10 +263,6 @@ enum {
#define RGN_ALIGN_VSPLIT 6
#define RGN_ALIGN_FLOAT 7
#define RGN_ALIGN_QSPLIT 8
-#define RGN_OVERLAP_TOP 9
-#define RGN_OVERLAP_BOTTOM 10
-#define RGN_OVERLAP_LEFT 11
-#define RGN_OVERLAP_RIGHT 12
#define RGN_SPLIT_PREV 32
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index f106c8f918a..0aa466f7245 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -172,7 +172,10 @@ typedef struct Sequence {
float blend_opacity;
/* is sfra needed anymore? - it looks like its only used in one place */
- int sfra, pad; /* starting frame according to the timeline of the scene. */
+ int sfra; /* starting frame according to the timeline of the scene. */
+
+ char alpha_mode;
+ char pad[3];
/* modifiers */
ListBase modifiers;
@@ -315,7 +318,7 @@ typedef struct SequencerScopes {
#define SEQ_OVERLAP (1 << 3)
#define SEQ_FILTERY (1 << 4)
#define SEQ_MUTE (1 << 5)
-#define SEQ_MAKE_PREMUL (1 << 6)
+#define SEQ_MAKE_PREMUL (1 << 6) /* deprecated, used for compatibility code only */
#define SEQ_REVERSE_FRAMES (1 << 7)
#define SEQ_IPO_FRAME_LOCKED (1 << 8)
#define SEQ_EFFECT_NOT_LOADED (1 << 9)
@@ -366,6 +369,12 @@ typedef struct SequencerScopes {
#define SEQ_PROXY_TC_RECORD_RUN_NO_GAPS 8
#define SEQ_PROXY_TC_ALL 15
+/* seq->alpha_mode */
+enum {
+ SEQ_ALPHA_STRAIGHT = 0,
+ SEQ_ALPHA_PREMUL = 1
+};
+
/* seq->type WATCH IT: SEQ_TYPE_EFFECT BIT is used to determine if this is an effect strip!!! */
enum {
SEQ_TYPE_IMAGE = 0,
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index be6464778e5..1dfcff4a3c4 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -434,7 +434,7 @@ typedef enum eScreen_Redraws_Flag {
TIME_WITH_SEQ_AUDIO = (1 << 4), /* DEPRECATED */
TIME_SEQ = (1 << 5),
TIME_ALL_IMAGE_WIN = (1 << 6),
- TIME_CONTINUE_PHYSICS = (1 << 7),
+ TIME_CONTINUE_PHYSICS = (1 << 7), /* UNUSED */
TIME_NODES = (1 << 8),
TIME_CLIPS = (1 << 9),
} eScreen_Redraws_Flag;
@@ -447,6 +447,7 @@ typedef enum eTimeline_Cache_Flag {
TIME_CACHE_CLOTH = (1 << 3),
TIME_CACHE_SMOKE = (1 << 4),
TIME_CACHE_DYNAMICPAINT = (1 << 5),
+ TIME_CACHE_RIGIDBODY = (1 << 6),
} eTimeline_Cache_Flag;
@@ -494,7 +495,7 @@ typedef enum eSpaceSeq_Flag {
SEQ_MARKER_TRANS = (1 << 1),
SEQ_DRAW_COLOR_SEPARATED = (1 << 2),
SEQ_DRAW_SAFE_MARGINS = (1 << 3),
-/* SEQ_DRAW_GPENCIL = (1 << 4), */ /* DEPRECATED */
+ SEQ_SHOW_GPENCIL = (1 << 4),
SEQ_NO_DRAW_CFRANUM = (1 << 5),
} eSpaceSeq_Flag;
@@ -776,7 +777,7 @@ typedef enum eSpaceImage_Flag {
SI_DRAW_TILE = (1 << 19),
SI_SMOOTH_UV = (1 << 20),
SI_DRAW_STRETCH = (1 << 21),
-/* SI_DISPGP = (1 << 22), */ /* deprecated */
+ SI_SHOW_GPENCIL = (1 << 22),
SI_DRAW_OTHER = (1 << 23),
SI_COLOR_CORRECTION = (1 << 24),
@@ -797,7 +798,7 @@ typedef struct SpaceText {
int top, viewlines;
short flags, menunr;
- short lheight; /* user preference */
+ short lheight; /* user preference, is font_size! */
char cwidth, linenrs_tot; /* runtime computed, character width and the number of chars to use when showing line numbers */
int left;
int showlinenrs;
@@ -816,8 +817,9 @@ typedef struct SpaceText {
char findstr[256]; /* ST_MAX_FIND_STR */
char replacestr[256]; /* ST_MAX_FIND_STR */
- short margin_column; /* column number to show right margin at */
- char pad[6];
+ short margin_column; /* column number to show right margin at */
+ short lheight_dpi; /* actual lineheight, dpi controlled */
+ char pad[4];
void *drawcache; /* cache for faster drawing */
} SpaceText;
@@ -886,7 +888,7 @@ typedef struct SpaceNode {
struct ID *id, *from; /* context, no need to save in file? well... pinning... */
short flag, pad1; /* menunr: browse id block in header */
- float aspect, aspect_sqrt;
+ float aspect, pad2; /* internal state variables */
float xof, yof; /* offset for drawing the backdrop */
float zoom; /* zoom for backdrop */
@@ -906,7 +908,7 @@ typedef struct SpaceNode {
/* snode->flag */
typedef enum eSpaceNode_Flag {
SNODE_BACKDRAW = (1 << 1),
-/* SNODE_DISPGP = (1 << 2), */ /* XXX: Grease Pencil - deprecated? */
+ SNODE_SHOW_GPENCIL = (1 << 2),
SNODE_USE_ALPHA = (1 << 3),
SNODE_SHOW_ALPHA = (1 << 4),
SNODE_SHOW_R = (1 << 7),
@@ -915,6 +917,7 @@ typedef enum eSpaceNode_Flag {
SNODE_AUTO_RENDER = (1 << 5),
SNODE_SHOW_HIGHLIGHT = (1 << 6),
SNODE_USE_HIDDEN_PREVIEW = (1 << 10),
+ SNODE_NEW_SHADERS = (1 << 11),
} eSpaceNode_Flag;
/* snode->texfrom */
@@ -1060,7 +1063,7 @@ typedef enum eSpaceClip_Flag {
SC_SHOW_GRID = (1 << 9),
SC_SHOW_STABLE = (1 << 10),
SC_MANUAL_CALIBRATION = (1 << 11),
-/* SC_SHOW_GPENCIL = (1 << 12),*/ /* UNUSED */
+ SC_SHOW_GPENCIL = (1 << 12),
SC_SHOW_FILTERS = (1 << 13),
SC_SHOW_GRAPH_FRAMES = (1 << 14),
SC_SHOW_GRAPH_TRACKS = (1 << 15),
diff --git a/source/blender/makesdna/DNA_text_types.h b/source/blender/makesdna/DNA_text_types.h
index 6ce883905d4..3194adba3a0 100644
--- a/source/blender/makesdna/DNA_text_types.h
+++ b/source/blender/makesdna/DNA_text_types.h
@@ -75,12 +75,4 @@ typedef struct Text {
#define TXT_FOLLOW 0x0200 /* always follow cursor (console) */
#define TXT_TABSTOSPACES 0x0400 /* use space instead of tabs */
-/* format continuation flags */
-#define TXT_NOCONT 0x00 /* no continuation */
-#define TXT_SNGQUOTSTR 0x01 /* single quotes */
-#define TXT_DBLQUOTSTR 0x02 /* double quotes */
-#define TXT_TRISTR 0x04 /* triplets of quotes: """ or ''' */
-#define TXT_SNGTRISTR 0x05 /*(TXT_TRISTR | TXT_SNGQUOTSTR)*/
-#define TXT_DBLTRISTR 0x06 /*(TXT_TRISTR | TXT_DBLQUOTSTR)*/
-
#endif
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index dd63e6aad59..ea4f281efd6 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -340,7 +340,7 @@ typedef struct ColorMapping {
/* imaflag */
#define TEX_INTERPOL 1
-#define TEX_USEALPHA 2
+#define TEX_USEALPHA 2 /* deprecated, used for versioning only */
#define TEX_MIPMAP 4
#define TEX_IMAROT 16
#define TEX_CALCALPHA 32
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 12819303b26..8789a17a7f7 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -248,13 +248,28 @@ typedef struct MovieTrackingDopesheetChannel {
int max_segment, total_frames; /* longest segment length and total number of tracked frames */
} MovieTrackingDopesheetChannel;
+typedef struct MovieTrackingDopesheetCoverageSegment {
+ struct MovieTrackingDopesheetCoverageSegment *next, *prev;
+
+ int coverage;
+ int start_frame;
+ int end_frame;
+
+ int pad;
+} MovieTrackingDopesheetCoverageSegment;
+
typedef struct MovieTrackingDopesheet {
int ok; /* flag if dopesheet information is still relevant */
short sort_method; /* method to be used to sort tracks */
short flag; /* dopesheet building flag such as inverted order of sort */
- /* runtime stuff */
+ /* ** runtime stuff ** */
+
+ /* summary */
+ ListBase coverage_segments;
+
+ /* detailed */
ListBase channels;
int tot_channel;
@@ -373,7 +388,7 @@ enum {
/* MovieTrackingStrabilization->filter */
enum {
- TRACKING_FILTER_NEAREAST = 0,
+ TRACKING_FILTER_NEAREST = 0,
TRACKING_FILTER_BILINEAR = 1,
TRACKING_FILTER_BICUBIC = 2
};
@@ -409,4 +424,11 @@ enum {
TRACKING_DOPE_SHOW_HIDDEN = (1 << 2)
};
+/* MovieTrackingDopesheetCoverageSegment->trackness */
+enum {
+ TRACKING_COVERAGE_BAD = 0,
+ TRACKING_COVERAGE_ACCEPTABLE = 1,
+ TRACKING_COVERAGE_OK = 2
+};
+
#endif
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 2e2f65dbec7..26b33783535 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -66,7 +66,7 @@ typedef struct uiFont {
short blf_id; /* from blfont lib */
short uifont_id; /* own id */
short r_to_l; /* fonts that read from left to right */
- short pad;
+ short hinting;
} uiFont;
/* this state defines appearance of text */
@@ -143,10 +143,19 @@ typedef struct uiWidgetStateColors {
typedef struct uiPanelColors {
char header[4];
+ char back[4];
short show_header;
- short pad;
+ short show_back;
+ int pad;
} uiPanelColors;
+typedef struct uiGradientColors {
+ char gradient[4];
+ char high_gradient[4];
+ int show_grad;
+ int pad2;
+} uiGradientColors;
+
typedef struct ThemeUI {
/* Interface Elements (buttons, menus, icons) */
uiWidgetColors wcol_regular, wcol_tool, wcol_text;
@@ -157,8 +166,14 @@ typedef struct ThemeUI {
uiWidgetStateColors wcol_state;
- uiPanelColors panel;
+ uiPanelColors panel; /* depricated, but we keep it for do_versions (2.66.1) */
+ /* fac: 0 - 1 for blend factor, width in pixels */
+ float menu_shadow_fac;
+ short menu_shadow_width;
+
+ short pad;
+
char iconfile[256]; // FILE_MAXFILE length
float icon_alpha;
@@ -172,34 +187,39 @@ typedef struct ThemeUI {
typedef struct ThemeSpace {
/* main window colors */
char back[4];
- char title[4];
+ char title[4]; /* panel title */
char text[4];
char text_hi[4];
/* header colors */
- char header[4];
- char header_title[4];
+ char header[4]; /* region background */
+ char header_title[4]; /* unused */
char header_text[4];
char header_text_hi[4];
/* button/tool regions */
- char button[4];
- char button_title[4];
+ char button[4]; /* region background */
+ char button_title[4]; /* panel title */
char button_text[4];
char button_text_hi[4];
/* listview regions */
- char list[4];
- char list_title[4];
+ char list[4]; /* region background */
+ char list_title[4]; /* panel title */
char list_text[4];
char list_text_hi[4];
/* float panel */
- char panel[4];
- char panel_title[4];
- char panel_text[4];
- char panel_text_hi[4];
+/* char panel[4]; unused */
+/* char panel_title[4]; unused */
+/* char panel_text[4]; unused */
+/* char panel_text_hi[4]; unused */
+ /* note, cannot use name 'panel' because of DNA mapping old files */
+ uiPanelColors panelcolors;
+
+ uiGradientColors gradients;
+
char shade1[4];
char shade2[4];
@@ -230,16 +250,19 @@ typedef struct ThemeSpace {
char ds_channel[4], ds_subchannel[4]; /* dopesheet */
char console_output[4], console_input[4], console_info[4], console_error[4];
- char console_cursor[4];
+ char console_cursor[4], console_select[4], pad1[4];
char vertex_size, outline_width, facedot_size;
char noodle_curving;
- char syntaxl[4], syntaxn[4], syntaxb[4]; /* syntax for textwindow and nodes */
+ /* syntax for textwindow and nodes */
+ char syntaxl[4], syntaxs[4];
+ char syntaxb[4], syntaxn[4];
char syntaxv[4], syntaxc[4];
+ char syntaxd[4], syntaxr[4];
char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; /* for sequence editor */
- char effect[4], hpad0[4], transition[4], meta[4];
+ char effect[4], transition[4], meta[4];
char editmesh_active[4];
char handle_vertex[4];
@@ -332,6 +355,7 @@ typedef struct bTheme {
typedef struct bAddon {
struct bAddon *next, *prev;
char module[64];
+ IDProperty *prop; /* User-Defined Properties on this Addon (for storing preferences) */
} bAddon;
typedef struct SolidLight {
@@ -340,6 +364,9 @@ typedef struct SolidLight {
} SolidLight;
typedef struct UserDef {
+ /* UserDef has separate do-version handling, and can be read from other files */
+ int versionfile, subversionfile;
+
int flag, dupflag;
int savetime;
char tempdir[768]; /* FILE_MAXDIR length */
@@ -359,9 +386,10 @@ typedef struct UserDef {
short versions;
short dbl_click_time;
- int gameflags;
- int wheellinescroll;
- int uiflag, language;
+ short gameflags;
+ short wheellinescroll;
+ int uiflag, uiflag2;
+ int language;
short userpref, viewzoom;
int mixbufsize;
@@ -412,7 +440,7 @@ typedef struct UserDef {
short scrcastfps; /* frame rate for screencast to be played back */
short scrcastwait; /* milliseconds between screencast snapshots */
- short widget_unit; /* defaults to 20 for 72 DPI setting */
+ short widget_unit; /* private, defaults to 20 for 72 DPI setting */
short anisotropic_filter;
short use_16bit_textures, use_gpu_mipmap;
@@ -421,6 +449,7 @@ typedef struct UserDef {
int ndof_flag; /* flags for 3D mouse */
short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */
+
short pad4;
float glalphaclip;
@@ -443,7 +472,7 @@ typedef struct UserDef {
int compute_device_id;
float fcu_inactive_alpha; /* opacity of inactive F-Curves in F-Curve Editor */
- float pad;
+ float pixelsize; /* private, set by GHOST, to multiply DPI with */
} UserDef;
extern UserDef U; /* from blenkernel blender.c */
@@ -539,6 +568,13 @@ typedef enum eUserpref_UI_Flag {
USER_HIDE_SYSTEM_BOOKMARKS = (1 << 31)
} eUserpref_UI_Flag;
+/* uiflag2 */
+typedef enum eUserpref_UI_Flag2 {
+ USER_KEEP_SESSION = (1 << 0),
+ USER_REGION_OVERLAP = (1 << 1),
+ USER_TRACKPAD_NATURAL = (1 << 2)
+} eUserpref_UI_Flag2;
+
/* Auto-Keying mode */
typedef enum eAutokey_Mode {
/* AUTOKEY_ON is a bitflag */
diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h
index 084496871bf..a7921be44d5 100644
--- a/source/blender/makesdna/DNA_view2d_types.h
+++ b/source/blender/makesdna/DNA_view2d_types.h
@@ -123,9 +123,9 @@ typedef struct View2D {
/* horizontal scrollbar */
#define V2D_SCROLL_TOP (1<<2)
#define V2D_SCROLL_BOTTOM (1<<3)
- /* special hack for outliner hscroll - prevent hanging older versions of Blender */
-#define V2D_SCROLL_BOTTOM_O (1<<4)
-#define V2D_SCROLL_HORIZONTAL (V2D_SCROLL_TOP|V2D_SCROLL_BOTTOM|V2D_SCROLL_BOTTOM_O)
+
+/* UNUSED (1<<4) */
+#define V2D_SCROLL_HORIZONTAL (V2D_SCROLL_TOP|V2D_SCROLL_BOTTOM)
/* scale markings - vertical */
#define V2D_SCROLL_SCALE_VERTICAL (1<<5)
/* scale markings - horizontal */
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index c83b0bc366f..d9d6db5ff91 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -46,6 +46,7 @@ struct RenderEngine;
struct bGPdata;
struct SmoothView3DStore;
struct wmTimer;
+struct Material;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
@@ -160,8 +161,8 @@ typedef struct View3D {
float bundle_size; /* size of bundles in reconstructed data */
short bundle_drawtype; /* display style for bundle */
-
- char pad[6];
+ short pad;
+ int matcap_icon; /* icon id */
unsigned int lay_used; /* used while drawing */
@@ -209,11 +210,11 @@ typedef struct View3D {
/* drawflags, denoting state */
short zbuf, transp, xray;
-
char pad3[2];
- void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */
-
+ void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */
+ struct Material *defmaterial; /* used by matcap now */
+
/* XXX deprecated? */
struct bGPdata *gpd DNA_DEPRECATED; /* Grease-Pencil Data (annotation layers) */
@@ -225,6 +226,7 @@ typedef struct View3D {
#define V3D_DISPBGPICS 2
#define V3D_HIDE_HELPLINES 4
#define V3D_INVALID_BACKBUF 8
+#define V3D_INVALID_BACKBUF 8
#define V3D_ALIGN 1024
#define V3D_SELECT_OUTLINE 2048
@@ -261,14 +263,16 @@ typedef struct View3D {
/* View3d->flag2 (short) */
#define V3D_RENDER_OVERRIDE 4
#define V3D_SOLID_TEX 8
-#define V3D_DISPGP 16
+#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_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_RENDER_BORDER 2048
+#define V3D_SOLID_MATCAP 4096 /* user flag */
+#define V3D_SHOW_SOLID_MATCAP 8192 /* runtime flag */
/* View3D->around */
#define V3D_CENTER 0
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 2294abc0735..27aef3b8ec6 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -65,19 +65,21 @@ struct uiLayout;
/* keep in sync with 'wm_report_items' in wm_rna.c */
typedef enum ReportType {
- RPT_DEBUG = 1<<0,
- RPT_INFO = 1<<1,
- RPT_OPERATOR = 1<<2,
- RPT_WARNING = 1<<3,
- RPT_ERROR = 1<<4,
- RPT_ERROR_INVALID_INPUT = 1<<5,
- RPT_ERROR_INVALID_CONTEXT = 1<<6,
- RPT_ERROR_OUT_OF_MEMORY = 1<<7
+ RPT_DEBUG = 1 << 0,
+ RPT_INFO = 1 << 1,
+ RPT_OPERATOR = 1 << 2,
+ RPT_PROPERTY = 1 << 3,
+ RPT_WARNING = 1 << 4,
+ RPT_ERROR = 1 << 5,
+ RPT_ERROR_INVALID_INPUT = 1 << 6,
+ RPT_ERROR_INVALID_CONTEXT = 1 << 7,
+ RPT_ERROR_OUT_OF_MEMORY = 1 << 8
} ReportType;
#define RPT_DEBUG_ALL (RPT_DEBUG)
#define RPT_INFO_ALL (RPT_INFO)
#define RPT_OPERATOR_ALL (RPT_OPERATOR)
+#define RPT_PROPERTY_ALL (RPT_PROPERTY)
#define RPT_WARNING_ALL (RPT_WARNING)
#define RPT_ERROR_ALL (RPT_ERROR|RPT_ERROR_INVALID_INPUT|RPT_ERROR_INVALID_CONTEXT|RPT_ERROR_OUT_OF_MEMORY)
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 8a14564f8a4..02dc81ccd4d 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -59,10 +59,7 @@ typedef struct World {
float horr, horg, horb;
float zenr, zeng, zenb;
float ambr, ambg, ambb;
- float pad2;
- unsigned int fastcol;
-
/**
* Exposure= mult factor. unused now, but maybe back later. Kept in to be upward compat.
* New is exp/range control. linfac & logfac are constants... don't belong in
diff --git a/source/blender/makesdna/SConscript b/source/blender/makesdna/SConscript
index c3d39783b00..701ad12f2b8 100644
--- a/source/blender/makesdna/SConscript
+++ b/source/blender/makesdna/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
objs = []
@@ -6,6 +32,6 @@ objs = []
o = SConscript('intern/SConscript')
objs += o
-incs = '#/intern/guardedalloc .'
+incs = '#/intern/guardedalloc . ../blenlib'
env.BlenderLib ( 'bf_dna', objs, Split(incs), [], libtype=['core','player'], priority = [215,200] )
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index c1e6eb5281d..add9611866d 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 10c3b0bbee4..86014c4e80e 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -29,7 +29,10 @@
/** \file blender/makesdna/intern/dna_genfile.c
* \ingroup DNA
*
- * Functions for struct-dna, the genetic file dot c!
+ * Lowest-level functions for decoding the parts of a saved .blend
+ * file, including interpretation of its SDNA block and conversion of
+ * contents of other parts according to the differences between that
+ * SDNA and the SDNA of the current (running) version of Blender.
*/
@@ -39,8 +42,9 @@
#include "MEM_guardedalloc.h" // for MEM_freeN MEM_mallocN MEM_callocN
+#include "BLI_utildefines.h"
+
#ifdef WITH_DNA_GHASH
-# include "BLI_utildefines.h"
# include "BLI_ghash.h"
#endif
@@ -134,12 +138,11 @@ typedef long long __int64;
*
*/
-/* local */
-static int le_int(int temp);
-static short le_short(short temp);
-
/* ************************* ENDIAN STUFF ********************** */
+/**
+ * converts a short between big/little endian.
+ */
static short le_short(short temp)
{
short new;
@@ -151,7 +154,9 @@ static short le_short(short temp)
return new;
}
-
+/**
+ * converts an int between big/little endian.
+ */
static int le_int(int temp)
{
int new;
@@ -169,6 +174,10 @@ static int le_int(int temp)
/* ************************* MAKE DNA ********************** */
/* allowed duplicate code from makesdna.c */
+
+/**
+ * parses the "[n]" on the end of an array name and returns the number of array elements n.
+ */
int DNA_elem_array_size(const char *astr, int len)
{
int a, mul = 1;
@@ -207,14 +216,23 @@ void DNA_sdna_free(SDNA *sdna)
MEM_freeN(sdna);
}
-static int ispointer(const char *name)
+/**
+ * Return true if the name indicates a pointer of some kind.
+ */
+static bool ispointer(const char *name)
{
/* check if pointer or function pointer */
return (name[0] == '*' || (name[0] == '(' && name[1] == '*'));
}
-static int elementsize(SDNA *sdna, short type, short name)
-/* call with numbers from struct-array */
+/**
+ * Returns the size of struct fields of the specified type and name.
+ *
+ * \param type Index into sdna->types/typelens
+ * \param name Index into sdna->names,
+ * needed to extract possible pointer/array information.
+ */
+static int elementsize(const SDNA *sdna, short type, short name)
{
int mul, namelen, len;
const char *cp;
@@ -225,16 +243,20 @@ static int elementsize(SDNA *sdna, short type, short name)
namelen = strlen(cp);
/* is it a pointer or function pointer? */
if (ispointer(cp)) {
- /* has the naam an extra length? (array) */
+ /* has the name an extra length? (array) */
mul = 1;
- if (cp[namelen - 1] == ']') mul = DNA_elem_array_size(cp, namelen);
+ if (cp[namelen - 1] == ']') {
+ mul = DNA_elem_array_size(cp, namelen);
+ }
len = sdna->pointerlen * mul;
}
else if (sdna->typelens[type]) {
- /* has the naam an extra length? (array) */
+ /* has the name an extra length? (array) */
mul = 1;
- if (cp[namelen - 1] == ']') mul = DNA_elem_array_size(cp, namelen);
+ if (cp[namelen - 1] == ']') {
+ mul = DNA_elem_array_size(cp, namelen);
+ }
len = mul * sdna->typelens[type];
@@ -262,6 +284,9 @@ static void printstruct(SDNA *sdna, short strnr)
}
#endif
+/**
+ * Returns a pointer to the start of the struct info for the struct with the specified name.
+ */
static short *findstruct_name(SDNA *sdna, const char *str)
{
int a;
@@ -272,19 +297,26 @@ static short *findstruct_name(SDNA *sdna, const char *str)
sp = sdna->structs[a];
- if (strcmp(sdna->types[sp[0]], str) == 0) return sp;
+ if (strcmp(sdna->types[sp[0]], str) == 0) {
+ return sp;
+ }
}
return NULL;
}
+/**
+ * Returns the index of the struct info for the struct with the specified name.
+ */
int DNA_struct_find_nr(SDNA *sdna, const char *str)
{
short *sp = NULL;
if (sdna->lastfind < sdna->nr_structs) {
sp = sdna->structs[sdna->lastfind];
- if (strcmp(sdna->types[sp[0]], str) == 0) return sdna->lastfind;
+ if (strcmp(sdna->types[sp[0]], str) == 0) {
+ return sdna->lastfind;
+ }
}
#ifdef WITH_DNA_GHASH
@@ -311,8 +343,10 @@ int DNA_struct_find_nr(SDNA *sdna, const char *str)
/* ************************* READ DNA ********************** */
-static void init_structDNA(SDNA *sdna, int do_endian_swap)
-/* in sdna->data the data, now we convert that to something understandable */
+/**
+ * In sdna->data the data, now we convert that to something understandable
+ */
+static void init_structDNA(SDNA *sdna, bool do_endian_swap)
{
int *data, *verg, gravity_fix = -1;
intptr_t nr;
@@ -481,7 +515,7 @@ static void init_structDNA(SDNA *sdna, int do_endian_swap)
if (sp[1] != 2 || (sdna->pointerlen != 4 && sdna->pointerlen != 8)) {
printf("ListBase struct error! Needs it to calculate pointerize.\n");
- exit(0);
+ exit(1);
/* well, at least sizeof(ListBase) is error proof! (ton) */
}
@@ -506,7 +540,10 @@ static void init_structDNA(SDNA *sdna, int do_endian_swap)
}
}
-SDNA *DNA_sdna_from_data(const void *data, const int datalen, int do_endian_swap)
+/**
+ * Constructs and returns a decoded SDNA structure from the given encoded SDNA data block.
+ */
+SDNA *DNA_sdna_from_data(const void *data, const int datalen, bool do_endian_swap)
{
SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna");
@@ -525,7 +562,11 @@ SDNA *DNA_sdna_from_data(const void *data, const int datalen, int do_endian_swap
/* ******************* HANDLE DNA ***************** */
-static void recurs_test_compflags(SDNA *sdna, char *compflags, int structnr)
+/**
+ * Used by #DNA_struct_get_compareflags (below) to recursively mark all structs
+ * containing a field of type structnr as changed between old and current SDNAs.
+ */
+static void recurs_test_compflags(const SDNA *sdna, char *compflags, int structnr)
{
int a, b, typenr, elems;
short *sp;
@@ -554,75 +595,70 @@ static void recurs_test_compflags(SDNA *sdna, char *compflags, int structnr)
}
-/* Unsure of exact function - compares the sdna argument to
- * newsdna and sets up the information necessary to convert
- * data written with a dna of oldsdna to in-memory data with a
- * structure defined by the newsdna sdna (I think). -zr
- */
-/* well, the function below is just a lookup table to speed
- * up reading files. doh! -ton
+/**
+ * Constructs and returns an array of byte flags with one element for each struct in oldsdna,
+ * indicating how it compares to newsdna:
+ *
+ * flag value:
+ * - 0 Struct has disappeared (values of this struct type will not be loaded by the current Blender)
+ * - 1 Struct is the same (can be loaded with straight memory copy after any necessary endian conversion)
+ * - 2 Struct is different in some way (needs to be copied/converted field by field)
*/
-
-
-char *DNA_struct_get_compareflags(SDNA *sdna, SDNA *newsdna)
+char *DNA_struct_get_compareflags(SDNA *oldsdna, SDNA *newsdna)
{
- /* flag: 0: doesn't exist anymore (or not yet)
- * 1: is equal
- * 2: is different
- */
int a, b;
- short *spold, *spcur;
+ const short *sp_old, *sp_new;
const char *str1, *str2;
char *compflags;
- if (sdna->nr_structs == 0) {
+ if (oldsdna->nr_structs == 0) {
printf("error: file without SDNA\n");
return NULL;
}
-
- compflags = MEM_callocN(sdna->nr_structs, "compflags");
- /* we check all structs in 'sdna' and compare them with
+ compflags = MEM_callocN(oldsdna->nr_structs, "compflags");
+
+ /* we check all structs in 'oldsdna' and compare them with
* the structs in 'newsdna'
*/
- for (a = 0; a < sdna->nr_structs; a++) {
- spold = sdna->structs[a];
+ for (a = 0; a < oldsdna->nr_structs; a++) {
+ sp_old = oldsdna->structs[a];
/* search for type in cur */
- spcur = findstruct_name(newsdna, sdna->types[spold[0]]);
+ sp_new = findstruct_name(newsdna, oldsdna->types[sp_old[0]]);
- if (spcur) {
- compflags[a] = 2;
+ if (sp_new) {
+ compflags[a] = 2; /* initial assumption */
/* compare length and amount of elems */
- if (spcur[1] == spold[1]) {
- if (newsdna->typelens[spcur[0]] == sdna->typelens[spold[0]]) {
+ if (sp_new[1] == sp_old[1]) {
+ if (newsdna->typelens[sp_new[0]] == oldsdna->typelens[sp_old[0]]) {
/* same length, same amount of elems, now per type and name */
- b = spold[1];
- spold += 2;
- spcur += 2;
+ b = sp_old[1];
+ sp_old += 2;
+ sp_new += 2;
while (b > 0) {
- str1 = newsdna->types[spcur[0]];
- str2 = sdna->types[spold[0]];
+ str1 = newsdna->types[sp_new[0]];
+ str2 = oldsdna->types[sp_old[0]];
if (strcmp(str1, str2) != 0) break;
- str1 = newsdna->names[spcur[1]];
- str2 = sdna->names[spold[1]];
+ str1 = newsdna->names[sp_new[1]];
+ str2 = oldsdna->names[sp_old[1]];
if (strcmp(str1, str2) != 0) break;
/* same type and same name, now pointersize */
if (ispointer(str1)) {
- if (sdna->pointerlen != newsdna->pointerlen) break;
+ if (oldsdna->pointerlen != newsdna->pointerlen) break;
}
b--;
- spold += 2;
- spcur += 2;
+ sp_old += 2;
+ sp_new += 2;
}
- if (b == 0) compflags[a] = 1;
+ if (b == 0) compflags[a] = 1; /* no differences found */
}
}
@@ -638,15 +674,15 @@ char *DNA_struct_get_compareflags(SDNA *sdna, SDNA *newsdna)
/* Because structs can be inside structs, we recursively
* set flags when a struct is altered
*/
- for (a = 0; a < sdna->nr_structs; a++) {
- if (compflags[a] == 2) recurs_test_compflags(sdna, compflags, a);
+ for (a = 0; a < oldsdna->nr_structs; a++) {
+ if (compflags[a] == 2) recurs_test_compflags(oldsdna, compflags, a);
}
#if 0
- for (a = 0; a < sdna->nr_structs; a++) {
+ for (a = 0; a < oldsdna->nr_structs; a++) {
if (compflags[a] == 2) {
- spold = sdna->structs[a];
- printf("changed: %s\n", sdna->types[spold[0]]);
+ spold = oldsdna->structs[a];
+ printf("changed: %s\n", oldsdna->types[spold[0]]);
}
}
#endif
@@ -654,6 +690,9 @@ char *DNA_struct_get_compareflags(SDNA *sdna, SDNA *newsdna)
return compflags;
}
+/**
+ * Converts the name of a primitive type to its enumeration code.
+ */
static eSDNA_Type sdna_type_nr(const char *dna_type)
{
if ((strcmp(dna_type, "char") == 0) || (strcmp(dna_type, "const char") == 0)) return SDNA_TYPE_CHAR;
@@ -670,7 +709,20 @@ static eSDNA_Type sdna_type_nr(const char *dna_type)
else return -1; /* invalid! */
}
-static void cast_elem(const char *ctype, const char *otype, const char *name, char *curdata, char *olddata)
+/**
+ * Converts a value of one primitive type to another.
+ * Note there is no optimization for the case where otype and ctype are the same:
+ * assumption is that caller will handle this case.
+ *
+ * \param ctype Name of type to convert to
+ * \param otype Name of type to convert from
+ * \param name Field name to extract array-size information
+ * \param curdata Where to put converted data
+ * \param olddata Data of type otype to convert
+ */
+static void cast_elem(
+ const char *ctype, const char *otype, const char *name,
+ char *curdata, const char *olddata)
{
double val = 0.0;
int arrlen, curlen = 1, oldlen = 1;
@@ -748,7 +800,18 @@ static void cast_elem(const char *ctype, const char *otype, const char *name, ch
}
}
-static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata, char *olddata)
+/**
+ * Converts pointer values between different sizes. These are only used
+ * as lookup keys to identify data blocks in the saved .blend file, not
+ * as actual in-memory pointers.
+ *
+ * \param curlen Pointer length to conver to
+ * \param oldlen Length of pointers in olddata
+ * \param name Field name to extract array-size information
+ * \param curdata Where to put converted data
+ * \param olddata Data to convert
+ */
+static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata, const char *olddata)
{
#ifdef WIN32
__int64 lval;
@@ -770,7 +833,10 @@ static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata
#else
lval = *( (long long *)olddata);
#endif
- *((int *)curdata) = lval >> 3; /* is of course gambling! */
+ /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender,
+ * pointers may lose uniqueness on truncation! (Hopefully this wont
+ * happen unless/until we ever get to multi-gigabyte .blend files...) */
+ *((int *)curdata) = lval >> 3;
}
else if (curlen == 8 && oldlen == 4) {
#ifdef WIN32
@@ -791,22 +857,42 @@ static void cast_pointer(int curlen, int oldlen, const char *name, char *curdata
}
}
+/**
+ * Equality test on name and oname excluding any array-size suffix.
+ */
static int elem_strcmp(const char *name, const char *oname)
{
int a = 0;
- /* strcmp without array part */
-
while (1) {
if (name[a] != oname[a]) return 1;
- if (name[a] == '[') break;
- if (name[a] == 0) break;
+ if (name[a] == '[' || oname[a] == '[') break;
+ if (name[a] == 0 || oname[a] == 0) break;
a++;
}
return 0;
}
-static char *find_elem(SDNA *sdna, const char *type, const char *name, short *old, char *olddata, short **sppo)
+/**
+ * Returns the address of the data for the specified field within olddata
+ * according to the struct format pointed to by old, or NULL if no such
+ * field can be found.
+ *
+ * \param sdna Old SDNA
+ * \param type Current field type name
+ * \param name Current field name
+ * \param old Pointer to struct information in sdna
+ * \param olddata Struct data
+ * \param sppo Optional place to return pointer to field info in sdna
+ * \return Data address.
+ */
+static char *find_elem(
+ const SDNA *sdna,
+ const char *type,
+ const char *name,
+ const short *old,
+ char *olddata,
+ const short **sppo)
{
int a, elemcount, len;
const char *otype, *oname;
@@ -823,8 +909,8 @@ static char *find_elem(SDNA *sdna, const char *type, const char *name, short *ol
len = elementsize(sdna, old[0], old[1]);
- if (elem_strcmp(name, oname) == 0) { /* naam equal */
- if (strcmp(type, otype) == 0) { /* type equal */
+ if (elem_strcmp(name, oname) == 0) { /* name equal */
+ if (strcmp(type, otype) == 0) { /* type equal */
if (sppo) *sppo = old;
return olddata;
}
@@ -837,8 +923,26 @@ static char *find_elem(SDNA *sdna, const char *type, const char *name, short *ol
return NULL;
}
-static void reconstruct_elem(SDNA *newsdna, SDNA *oldsdna,
- char *type, const char *name, char *curdata, short *old, char *olddata)
+/**
+ * Converts the contents of a single field of a struct, of a non-struct type,
+ * from oldsdna to newsdna format.
+ *
+ * \param newsdna SDNA of current Blender
+ * \param oldsdna SDNA of Blender that saved file
+ * \param type current field type name
+ * \param name current field name
+ * \param curdata put field data converted to newsdna here
+ * \param old pointer to struct info in oldsdna
+ * \param olddata struct contents laid out according to oldsdna
+ */
+static void reconstruct_elem(
+ const SDNA *newsdna,
+ const SDNA *oldsdna,
+ const char *type,
+ const char *name,
+ char *curdata,
+ const short *old,
+ const char *olddata)
{
/* rules: test for NAME:
* - name equal:
@@ -849,17 +953,16 @@ static void reconstruct_elem(SDNA *newsdna, SDNA *oldsdna,
* (nzc 2-4-2001 I want the 'unsigned' bit to be parsed as well. Where
* can I force this?)
*/
- int a, elemcount, len, array, oldsize, cursize, mul;
- char *otype;
- const char *oname, *cp;
+ int a, elemcount, len, countpos, oldsize, cursize, mul;
+ const char *otype, *oname, *cp;
/* is 'name' an array? */
cp = name;
- array = 0;
+ countpos = 0;
while (*cp && *cp != '[') {
- cp++; array++;
+ cp++; countpos++;
}
- if (*cp != '[') array = 0;
+ if (*cp != '[') countpos = 0;
/* in old is the old struct */
elemcount = old[1];
@@ -877,33 +980,38 @@ static void reconstruct_elem(SDNA *newsdna, SDNA *oldsdna,
else if (strcmp(type, otype) == 0) { /* type equal */
memcpy(curdata, olddata, len);
}
- else cast_elem(type, otype, name, curdata, olddata);
+ else {
+ cast_elem(type, otype, name, curdata, olddata);
+ }
return;
}
- else if (array) { /* name is an array */
+ else if (countpos != 0) { /* name is an array */
- if (oname[array] == '[' && strncmp(name, oname, array) == 0) { /* basis equal */
+ if (oname[countpos] == '[' && strncmp(name, oname, countpos) == 0) { /* basis equal */
cursize = DNA_elem_array_size(name, strlen(name));
oldsize = DNA_elem_array_size(oname, strlen(oname));
- if (ispointer(name)) { /* handle pointer or functionpointer */
- if (cursize > oldsize) cast_pointer(newsdna->pointerlen, oldsdna->pointerlen, oname, curdata, olddata);
- else cast_pointer(newsdna->pointerlen, oldsdna->pointerlen, name, curdata, olddata);
+ if (ispointer(name)) { /* handle pointer or functionpointer */
+ cast_pointer(newsdna->pointerlen, oldsdna->pointerlen,
+ cursize > oldsize ? oname : name,
+ curdata, olddata);
}
- else if (name[0] == '*' || strcmp(type, otype) == 0) { /* type equal */
- mul = len / oldsize;
- mul *= (cursize < oldsize) ? cursize : oldsize;
+ else if (strcmp(type, otype) == 0) { /* type equal */
+ mul = len / oldsize; /* size of single old array element */
+ mul *= (cursize < oldsize) ? cursize : oldsize; /* smaller of sizes of old and new arrays */
memcpy(curdata, olddata, mul);
- /* terminate strings */
- if (oldsize > cursize && strcmp(type, "char") == 0)
- curdata[mul - 1] = 0;
+ if (oldsize > cursize && strcmp(type, "char") == 0) {
+ /* string had to be truncated, ensure it's still null-terminated */
+ curdata[mul - 1] = '\0';
+ }
}
else {
- if (cursize > oldsize) cast_elem(type, otype, oname, curdata, olddata);
- else cast_elem(type, otype, name, curdata, olddata);
+ cast_elem(type, otype,
+ cursize > oldsize ? oname : name,
+ curdata, olddata);
}
return;
}
@@ -912,16 +1020,37 @@ static void reconstruct_elem(SDNA *newsdna, SDNA *oldsdna,
}
}
-static void reconstruct_struct(SDNA *newsdna, SDNA *oldsdna,
- char *compflags, int oldSDNAnr, char *data, int curSDNAnr, char *cur)
+/**
+ * Converts the contents of an entire struct from oldsdna to newsdna format.
+ *
+ * \param newsdna SDNA of current Blender
+ * \param oldsdna SDNA of Blender that saved file
+ * \param compflags
+ *
+ * Result from DNA_struct_get_compareflags to avoid needless conversions.
+ * \param oldSDNAnr Index of old struct definition in oldsdna
+ * \param data Struct contents laid out according to oldsdna
+ * \param curSDNAnr Index of current struct definition in newsdna
+ * \param cur Where to put converted struct contents
+ */
+static void reconstruct_struct(
+ SDNA *newsdna,
+ SDNA *oldsdna,
+ const char *compflags,
+
+ int oldSDNAnr,
+ char *data,
+ int curSDNAnr,
+ char *cur)
{
/* Recursive!
* Per element from cur_struct, read data from old_struct.
* If element is a struct, call recursive.
*/
int a, elemcount, elen, eleno, mul, mulo, firststructtypenr;
- short *spo, *spc, *sppo;
- char *type, *cpo, *cpc;
+ const short *spo, *spc, *sppo;
+ const char *type;
+ char *cpo, *cpc;
const char *name, *nameo;
if (oldSDNAnr == -1) return;
@@ -945,7 +1074,7 @@ static void reconstruct_struct(SDNA *newsdna, SDNA *oldsdna,
spc += 2;
cpc = cur;
- for (a = 0; a < elemcount; a++, spc += 2) {
+ for (a = 0; a < elemcount; a++, spc += 2) { /* convert each field */
type = newsdna->types[spc[0]];
name = newsdna->names[spc[1]];
@@ -953,7 +1082,7 @@ static void reconstruct_struct(SDNA *newsdna, SDNA *oldsdna,
/* test: is type a struct? */
if (spc[0] >= firststructtypenr && !ispointer(name)) {
-
+ /* struct field type */
/* where does the old struct data start (and is there an old one?) */
cpo = find_elem(oldsdna, type, name, spo, data, &sppo);
@@ -981,26 +1110,34 @@ static void reconstruct_struct(SDNA *newsdna, SDNA *oldsdna,
if (mulo <= 0) break;
}
}
- else cpc += elen;
+ else {
+ cpc += elen; /* skip field no longer present */
+ }
}
else {
-
+ /* non-struct field type */
reconstruct_elem(newsdna, oldsdna, type, name, cpc, spo, data);
cpc += elen;
-
}
}
}
+/**
+ * Does endian swapping on the fields of a struct value.
+ *
+ * \param oldsdna SDNA of Blender that saved file
+ * \param oldSDNAnr Index of struct info within oldsdna
+ * \param data Struct data
+ */
void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data)
{
/* Recursive!
* If element is a struct, call recursive.
*/
int a, mul, elemcount, elen, elena, firststructtypenr;
- short *spo, *spc, skip;
- char *type, *cpo, *cur, cval;
- const char *name;
+ const short *spo, *spc;
+ char *cpo, *cur, cval;
+ const char *type, *name;
if (oldSDNAnr == -1) return;
firststructtypenr = *(oldsdna->structs[0]);
@@ -1021,6 +1158,7 @@ void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data)
/* test: is type a struct? */
if (spc[0] >= firststructtypenr && !ispointer(name)) {
+ /* struct field type */
/* where does the old data start (is there one?) */
cpo = find_elem(oldsdna, type, name, spo, data, NULL);
if (cpo) {
@@ -1036,7 +1174,7 @@ void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data)
}
}
else {
-
+ /* non-struct field type */
if (ispointer(name)) {
if (oldsdna->pointerlen == 8) {
@@ -1060,15 +1198,15 @@ void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data)
{
/* exception: variable called blocktype/ipowin: derived from ID_ */
- skip = 0;
+ bool skip = false;
if (name[0] == 'b' && name[1] == 'l') {
- if (strcmp(name, "blocktype") == 0) skip = 1;
+ if (strcmp(name, "blocktype") == 0) skip = true;
}
else if (name[0] == 'i' && name[1] == 'p') {
- if (strcmp(name, "ipowin") == 0) skip = 1;
+ if (strcmp(name, "ipowin") == 0) skip = true;
}
- if (skip == 0) {
+ if (skip == false) {
mul = DNA_elem_array_size(name, strlen(name));
cpo = cur;
while (mul--) {
@@ -1111,17 +1249,30 @@ void DNA_struct_switch_endian(SDNA *oldsdna, int oldSDNAnr, char *data)
cpo += 8;
}
}
+ /* FIXME: no conversion for SDNA_TYPE_DOUBLE? */
}
}
cur += elen;
}
}
+/**
+ * \param newsdna SDNA of current Blender
+ * \param oldsdna SDNA of Blender that saved file
+ * \param compflags
+ *
+ * Result from DNA_struct_get_compareflags to avoid needless conversions
+ * \param oldSDNAnr Index of struct info within oldsdna
+ * \param blocks The number of array elements
+ * \param data Array of struct data
+ * \return An allocated reconstructed struct
+ */
void *DNA_struct_reconstruct(SDNA *newsdna, SDNA *oldsdna, char *compflags, int oldSDNAnr, int blocks, void *data)
{
int a, curSDNAnr, curlen = 0, oldlen;
- short *spo, *spc;
- char *cur, *type, *cpc, *cpo;
+ const short *spo, *spc;
+ char *cur, *cpc, *cpo;
+ const char *type;
/* oldSDNAnr == structnr, we're looking for the corresponding 'cur' number */
spo = oldsdna->structs[oldSDNAnr];
@@ -1150,18 +1301,25 @@ void *DNA_struct_reconstruct(SDNA *newsdna, SDNA *oldsdna, char *compflags, int
return cur;
}
+/**
+ * Returns the offset of the field with the specified name and type within the specified
+ * struct type in sdna.
+ */
int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name)
{
- int SDNAnr = DNA_struct_find_nr(sdna, stype);
- short *spo = sdna->structs[SDNAnr];
- char *cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
+ const int SDNAnr = DNA_struct_find_nr(sdna, stype);
+ const short * const spo = sdna->structs[SDNAnr];
+ char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
return (int)((intptr_t)cp);
}
+/**
+ * Returns the size in bytes of a primitive type.
+ */
int DNA_elem_type_size(const eSDNA_Type elem_nr)
{
- /* should containt all enum types */
+ /* should contain all enum types */
switch (elem_nr) {
case SDNA_TYPE_CHAR:
case SDNA_TYPE_UCHAR:
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index fa0b313a120..31ff0ffa8fe 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -133,6 +133,7 @@ static const char *includefiles[] = {
"DNA_tracking_types.h",
"DNA_dynamicpaint_types.h",
"DNA_mask_types.h",
+ "DNA_rigidbody_types.h",
/* empty string to indicate end of includefiles */
""
@@ -208,7 +209,7 @@ static int calculate_structlens(int);
/**
* Construct the DNA.c file
*/
-void dna_write(FILE *file, void *pntr, int size);
+static void dna_write(FILE *file, const void *pntr, const int size);
/**
* Report all structures found so far, and print their lengths.
@@ -892,7 +893,7 @@ static int calculate_structlens(int firststruct)
#define MAX_DNA_LINE_LENGTH 20
-void dna_write(FILE *file, void *pntr, int size)
+static void dna_write(FILE *file, const void *pntr, const int size)
{
static int linelength = 0;
int i;
@@ -934,7 +935,7 @@ void printStructLengths(void)
}
-static int make_structDNA(char *baseDirectory, FILE *file)
+static int make_structDNA(const char *baseDirectory, FILE *file)
{
int len, i;
short *sp;
@@ -984,7 +985,7 @@ static int make_structDNA(char *baseDirectory, FILE *file)
/* little test first... */
/* Mind the breaking condition here! */
if (debugSDNA) printf("\tStart of header scan:\n");
- for (i = 0; strlen(includefiles[i]); i++) {
+ for (i = 0; *(includefiles[i]) != '\0'; i++) {
sprintf(str, "%s%s", baseDirectory, includefiles[i]);
if (debugSDNA) printf("\t|-- Converting %s\n", str);
if (convert_include(str)) {
@@ -1036,12 +1037,10 @@ static int make_structDNA(char *baseDirectory, FILE *file)
/* pass */
}
else {
- strcpy(str, "SDNA");
- dna_write(file, str, 4);
+ dna_write(file, "SDNA", 4);
/* write names */
- strcpy(str, "NAME");
- dna_write(file, str, 4);
+ dna_write(file, "NAME", 4);
len = nr_names;
dna_write(file, &len, 4);
@@ -1053,8 +1052,7 @@ static int make_structDNA(char *baseDirectory, FILE *file)
dna_write(file, names[0], len);
/* write TYPES */
- strcpy(str, "TYPE");
- dna_write(file, str, 4);
+ dna_write(file, "TYPE", 4);
len = nr_types;
dna_write(file, &len, 4);
@@ -1067,16 +1065,14 @@ static int make_structDNA(char *baseDirectory, FILE *file)
dna_write(file, types[0], len);
/* WRITE TYPELENGTHS */
- strcpy(str, "TLEN");
- dna_write(file, str, 4);
+ dna_write(file, "TLEN", 4);
len = 2 * nr_types;
if (nr_types & 1) len += 2;
dna_write(file, typelens_native, len);
/* WRITE STRUCTS */
- strcpy(str, "STRC");
- dna_write(file, str, 4);
+ dna_write(file, "STRC", 4);
len = nr_structs;
dna_write(file, &len, 4);
@@ -1100,7 +1096,7 @@ static int make_structDNA(char *baseDirectory, FILE *file)
else {
/* add all include files defined in the global array */
- for (i = 0; strlen(includefiles[i]); i++) {
+ for (i = 0; *(includefiles[i]) != '\0'; i++) {
fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
}
@@ -1165,13 +1161,13 @@ int main(int argc, char **argv)
return_status = 1;
}
else {
- char baseDirectory[256];
+ const char *baseDirectory;
if (argc == 3) {
- strcpy(baseDirectory, argv[2]);
+ baseDirectory = argv[2];
}
else {
- strcpy(baseDirectory, BASE_HEADER);
+ baseDirectory = BASE_HEADER;
}
fprintf(file, "const unsigned char DNAstr[] = {\n");
@@ -1267,4 +1263,5 @@ int main(int argc, char **argv)
#include "DNA_tracking_types.h"
#include "DNA_dynamicpaint_types.h"
#include "DNA_mask_types.h"
+#include "DNA_rigidbody_types.h"
/* end of list */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 0e5f9c5fa5f..e8c1a5d0642 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -54,6 +54,7 @@ extern StructRNA RNA_ActionPoseMarkers;
extern StructRNA RNA_Actuator;
extern StructRNA RNA_ActuatorSensor;
extern StructRNA RNA_Addon;
+extern StructRNA RNA_AddonPreferences;
extern StructRNA RNA_AdjustmentSequence;
extern StructRNA RNA_AlwaysSensor;
extern StructRNA RNA_AndController;
@@ -91,6 +92,7 @@ extern StructRNA RNA_BoolProperty;
extern StructRNA RNA_Brush;
extern StructRNA RNA_BrushTextureSlot;
extern StructRNA RNA_BuildModifier;
+extern StructRNA RNA_MeshCacheModifier;
extern StructRNA RNA_Camera;
extern StructRNA RNA_CastModifier;
extern StructRNA RNA_ChildOfConstraint;
@@ -104,7 +106,8 @@ extern StructRNA RNA_CollectionProperty;
extern StructRNA RNA_CollisionModifier;
extern StructRNA RNA_CollisionSensor;
extern StructRNA RNA_CollisionSettings;
-extern StructRNA RNA_ColorManagedColorspaceSettings;
+extern StructRNA RNA_ColorManagedInputColorspaceSettings;
+extern StructRNA RNA_ColorManagedSequencerColorspaceSettings;
extern StructRNA RNA_ColorManagedDisplaySettings;
extern StructRNA RNA_ColorManagedViewSettings;
extern StructRNA RNA_ColorRamp;
@@ -425,6 +428,8 @@ extern StructRNA RNA_RenderLayer;
extern StructRNA RNA_RenderPass;
extern StructRNA RNA_RenderResult;
extern StructRNA RNA_RenderSettings;
+extern StructRNA RNA_RigidBodyWorld;
+extern StructRNA RNA_RigidBodyObject;
extern StructRNA RNA_RigidBodyJointConstraint;
extern StructRNA RNA_SPHFluidSettings;
extern StructRNA RNA_Scene;
@@ -569,6 +574,7 @@ extern StructRNA RNA_ThemeOutliner;
extern StructRNA RNA_ThemeProperties;
extern StructRNA RNA_ThemeSequenceEditor;
extern StructRNA RNA_ThemeSpaceGeneric;
+extern StructRNA RNA_ThemeSpaceGradient;
extern StructRNA RNA_ThemeSpaceListGeneric;
extern StructRNA RNA_ThemeStyle;
extern StructRNA RNA_ThemeTextEditor;
@@ -586,7 +592,8 @@ extern StructRNA RNA_TrackToConstraint;
extern StructRNA RNA_TransformConstraint;
extern StructRNA RNA_TransformSequence;
extern StructRNA RNA_UILayout;
-extern StructRNA RNA_UIListItem;
+extern StructRNA RNA_UIList;
+extern StructRNA RNA_UVWarpModifier;
extern StructRNA RNA_UVProjectModifier;
extern StructRNA RNA_UVProjector;
extern StructRNA RNA_UnitSettings;
@@ -862,7 +869,12 @@ int RNA_path_resolve_full(PointerRNA *ptr, const char *path,
char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop);
-char *RNA_path_from_ID_python(struct ID *id);
+
+char *RNA_path_full_ID_py(struct ID *id);
+char *RNA_path_full_struct_py(struct PointerRNA *ptr);
+char *RNA_path_full_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
+char *RNA_path_struct_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
+char *RNA_path_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
/* Quick name based property access
*
@@ -970,8 +982,8 @@ int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier);
int RNA_property_is_idprop(PropertyRNA *prop);
/* python compatible string representation of this property, (must be freed!) */
-char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop);
-char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr);
+char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index);
+char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop);
char *RNA_pointer_as_string_keywords_ex(struct bContext *C, PointerRNA *ptr, PointerRNA *ptr_default,
const short skip_optional_value, const short all_args,
PropertyRNA *iterprop);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 9939d0839e6..5ab37c6d97b 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -43,12 +43,14 @@ BlenderRNA *RNA_create(void);
void RNA_define_free(BlenderRNA *brna);
void RNA_free(BlenderRNA *brna);
void RNA_define_verify_sdna(int verify);
+void RNA_define_animate_sdna(int animate);
void RNA_init(void);
void RNA_exit(void);
/* Struct */
+StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom);
StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from);
void RNA_def_struct_sdna(StructRNA *srna, const char *structname);
void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname);
@@ -86,12 +88,10 @@ PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, c
PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
-PropertyRNA *RNA_def_string_translate(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc);
-void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data);
PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
@@ -177,6 +177,17 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con
void RNA_def_property_srna(PropertyRNA *prop, const char *type);
void RNA_def_py_data(PropertyRNA *prop, void *py_data);
+void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc);
+void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc);
+void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc);
+void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc);
+void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc);
+void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc);
+void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc);
+void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc);
+
+void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data);
+
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context);
/* Function */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 0f9a00de7b6..eabf0391c01 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -70,6 +70,7 @@ extern EnumPropertyItem keyframe_handle_type_items[];
extern EnumPropertyItem keyblock_type_items[];
extern EnumPropertyItem keyingset_path_grouping_items[];
+extern EnumPropertyItem keying_flag_items[];
extern EnumPropertyItem keyframe_paste_offset_items[];
extern EnumPropertyItem keyframe_paste_merge_items[];
@@ -89,6 +90,8 @@ extern EnumPropertyItem brush_sculpt_tool_items[];
extern EnumPropertyItem brush_vertex_tool_items[];
extern EnumPropertyItem brush_image_tool_items[];
+extern EnumPropertyItem symmetrize_direction_items[];
+
extern EnumPropertyItem texture_type_items[];
extern EnumPropertyItem lamp_type_items[];
@@ -99,6 +102,12 @@ extern EnumPropertyItem object_type_items[];
extern EnumPropertyItem object_type_curve_items[];
+extern EnumPropertyItem rigidbody_ob_type_items[];
+extern EnumPropertyItem rigidbody_ob_shape_items[];
+extern EnumPropertyItem rigidbody_con_type_items[];
+
+extern EnumPropertyItem object_axis_items[];
+
extern EnumPropertyItem controller_type_items[];
extern EnumPropertyItem keymap_propvalue_items[];
@@ -132,6 +141,9 @@ extern EnumPropertyItem prop_dynamicpaint_type_items[];
extern EnumPropertyItem clip_editor_mode_items[];
+extern EnumPropertyItem icon_items[];
+extern EnumPropertyItem uilist_layout_type_items[];
+
struct bContext;
struct PointerRNA;
struct PropertyRNA;
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 87504dc6eb7..54d2efcf4cf 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -110,10 +110,9 @@ typedef enum PropertySubType {
PROP_FILEPATH = 1,
PROP_DIRPATH = 2,
PROP_FILENAME = 3,
- PROP_BYTESTRING = 4, /* a string which should be represented as bytes
- * in python, still NULL terminated though. */
- PROP_TRANSLATE = 5, /* a string which should be translated */
- PROP_PASSWORD = 6, /* a string which should not be displayed in UI */
+ PROP_BYTESTRING = 4, /* a string which should be represented as bytes in python, still NULL terminated though. */
+ /* 5 was used by "PROP_TRANSLATE" sub-type, which is now a flag. */
+ PROP_PASSWORD = 6, /* a string which should not be displayed in UI */
/* numbers */
PROP_UNSIGNED = 13,
@@ -121,6 +120,7 @@ typedef enum PropertySubType {
PROP_FACTOR = 15,
PROP_ANGLE = 16 | PROP_UNIT_ROTATION,
PROP_TIME = 17 | PROP_UNIT_TIME,
+ /* distance in 3d space, don't use for pixel distance for eg. */
PROP_DISTANCE = 18 | PROP_UNIT_LENGTH,
/* number arrays */
@@ -135,7 +135,7 @@ typedef enum PropertySubType {
PROP_AXISANGLE = 28,
PROP_XYZ = 29,
PROP_XYZ_LENGTH = 29 | PROP_UNIT_LENGTH,
- PROP_COLOR_GAMMA = 30,
+ PROP_COLOR_GAMMA = 30, /* used for colors which would be color managed before display */
PROP_COORDS = 31, /* generic array, no units applied, only that x/y/z/w are used (python vec) */
/* booleans */
@@ -144,6 +144,7 @@ typedef enum PropertySubType {
} PropertySubType;
/* Make sure enums are updated with thses */
+/* HIGHEST FLAG IN USE: 1 << 28 */
typedef enum PropertyFlag {
/* editable means the property is editable in the user
* interface, properties are editable by default except
@@ -269,7 +270,27 @@ typedef struct EnumPropertyItem {
const char *description;
} EnumPropertyItem;
-/* this is a copy of 'PropEnumItemFunc' defined in rna_internal_types.h */
+/* extended versions with PropertyRNA argument */
+typedef int (*BooleanPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*BooleanPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*BooleanArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*BooleanArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef int (*IntPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*IntPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*IntArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*IntArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef void (*IntPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax);
+typedef float (*FloatPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*FloatPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value);
+typedef void (*FloatArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values);
+typedef void (*FloatArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values);
+typedef void (*FloatPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax);
+typedef void (*StringPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value);
+typedef int (*StringPropertyLengthFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*StringPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value);
+typedef int (*EnumPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*EnumPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+/* same as PropEnumItemFunc */
typedef EnumPropertyItem *(*EnumPropertyItemFunc)(struct bContext *C, PointerRNA *ptr, struct PropertyRNA *prop, int *free);
typedef struct PropertyRNA PropertyRNA;
@@ -309,15 +330,16 @@ typedef struct ParameterDynAlloc {
typedef enum FunctionFlag {
FUNC_NO_SELF = 1, /* for static functions */
- FUNC_USE_MAIN = 2,
- FUNC_USE_CONTEXT = 4,
- FUNC_USE_REPORTS = 8,
+ FUNC_USE_SELF_TYPE = 2, /* for class methods, only used when FUNC_NO_SELF is set */
+ FUNC_USE_MAIN = 4,
+ FUNC_USE_CONTEXT = 8,
+ FUNC_USE_REPORTS = 16,
FUNC_USE_SELF_ID = 2048,
FUNC_ALLOW_WRITE = 4096,
/* registering */
- FUNC_REGISTER = 16,
- FUNC_REGISTER_OPTIONAL = 16 | 32,
+ FUNC_REGISTER = 32,
+ FUNC_REGISTER_OPTIONAL = 32 | 64,
/* internal flags */
FUNC_BUILTIN = 128,
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index 29910121e2a..6031e797905 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
objs = []
@@ -20,6 +46,10 @@ defs = []
if env['WITH_BF_SMOKE']:
defs.append('WITH_SMOKE')
+if env['WITH_BF_BULLET']:
+ defs.append('WITH_BULLET')
+ incs += ' #/intern/rigidbody'
+
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 82c0757456d..7b6fb30d692 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -70,6 +70,7 @@ set(DEFSRC
rna_pose.c
rna_property.c
rna_render.c
+ rna_rigidbody.c
rna_rna.c
rna_scene.c
rna_screen.c
@@ -104,6 +105,7 @@ set(APISRC
rna_main_api.c
rna_material_api.c
rna_mesh_api.c
+ rna_meta_api.c
rna_texture_api.c
rna_object_api.c
rna_pose_api.c
@@ -237,6 +239,13 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_BULLET)
+ list(APPEND INC
+ ../../../../intern/rigidbody
+ )
+ add_definitions(-DWITH_BULLET)
+endif()
+
# Build makesrna executable
blender_include_dirs(
.
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index d26de50fae0..f8608f0c28b 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
@@ -39,7 +65,11 @@ incs += ' #/intern/smoke/extern'
if env['WITH_BF_SMOKE']:
defs.append('WITH_SMOKE')
-
+
+if env['WITH_BF_BULLET']:
+ defs.append('WITH_BULLET')
+ incs += ' #/intern/rigidbody'
+
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 6fa53f4e029..95222a067af 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -91,7 +91,7 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
{ \
WRITE_COMMA; \
fprintf(f, param); \
- }
+ } (void)0
static int replace_if_different(char *tmpfile, const char *dep_files[])
{
@@ -415,10 +415,10 @@ static const char *rna_type_type_name(PropertyRNA *prop)
return "float";
case PROP_STRING:
if (prop->flag & PROP_THICK_WRAP) {
- return "char*";
+ return "char *";
}
else {
- return "const char*";
+ return "const char *";
}
default:
return NULL;
@@ -760,7 +760,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
if (prop->type == PROP_INT) {
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
- if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX) {
+ if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX || iprop->range) {
if (array) fprintf(f, "CLAMPIS(values[i], ");
else fprintf(f, "CLAMPIS(value, ");
if (iprop->range) {
@@ -776,7 +776,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
else if (prop->type == PROP_FLOAT) {
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
- if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX) {
+ if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX || fprop->range) {
if (array) fprintf(f, "CLAMPIS(values[i], ");
else fprintf(f, "CLAMPIS(value, ");
if (fprop->range) {
@@ -870,16 +870,16 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if (prop->flag & PROP_ID_REFCOUNT) {
fprintf(f, "\n if (data->%s)\n", dp->dnaname);
- fprintf(f, " id_us_min((ID*)data->%s);\n", dp->dnaname);
+ fprintf(f, " id_us_min((ID *)data->%s);\n", dp->dnaname);
fprintf(f, " if (value.data)\n");
- fprintf(f, " id_us_plus((ID*)value.data);\n\n");
+ fprintf(f, " id_us_plus((ID *)value.data);\n\n");
}
else {
PointerPropertyRNA *pprop = (PointerPropertyRNA *)dp->prop;
StructRNA *type = rna_find_struct((const char *)pprop->type);
if (type && (type->flag & STRUCT_ID)) {
fprintf(f, " if (value.data)\n");
- fprintf(f, " id_lib_extern((ID*)value.data);\n\n");
+ fprintf(f, " id_lib_extern((ID *)value.data);\n\n");
}
}
@@ -1084,7 +1084,7 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *
fprintf(f, "\n memset(iter, 0, sizeof(*iter));\n");
fprintf(f, " iter->parent= *ptr;\n");
- fprintf(f, " iter->prop= (PropertyRNA*)&rna_%s_%s;\n", srna->identifier, prop->identifier);
+ fprintf(f, " iter->prop= (PropertyRNA *)&rna_%s_%s;\n", srna->identifier, prop->identifier);
if (dp->dnalengthname || dp->dnalengthfixed) {
if (manualfunc) {
@@ -1768,7 +1768,7 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property
const char *collection_funcs = "DefaultCollectionFunctions";
if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)) && cprop->property.srna)
- collection_funcs = (char*)cprop->property.srna;
+ collection_funcs = (char *)cprop->property.srna;
if (cprop->item_type)
fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, (const char *)cprop->item_type, srna->identifier,
@@ -1798,7 +1798,7 @@ static const char *rna_parameter_type_cpp_name(PropertyRNA *prop)
}
}
-static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc,
+static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *UNUSED(srna), FunctionDefRNA *dfunc,
const char *namespace, int close_prototype)
{
PropertyDefRNA *dp;
@@ -1989,6 +1989,10 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func
if (dsrna->dnaname) fprintf(f, "(::%s *) this->ptr.data", dsrna->dnaname);
else fprintf(f, "(::%s *) this->ptr.data", srna->identifier);
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ WRITE_COMMA;
+ fprintf(f, "this->ptr.type");
+ }
if (func->flag & FUNC_USE_MAIN)
WRITE_PARAM("(::Main *) main");
@@ -2112,8 +2116,12 @@ static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, Functio
if (func->flag & FUNC_USE_SELF_ID)
WRITE_PARAM("_selfid");
- if ((func->flag & FUNC_NO_SELF) == 0)
+ if ((func->flag & FUNC_NO_SELF) == 0) {
WRITE_PARAM("_self");
+ }
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ WRITE_PARAM("_type");
+ }
if (func->flag & FUNC_USE_MAIN)
WRITE_PARAM("bmain");
@@ -2174,6 +2182,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (dsrna->dnaname) fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname);
else fprintf(f, "\tstruct %s *_self;\n", srna->identifier);
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ fprintf(f, "\tstruct StructRNA *_type;\n");
+ }
dparm = dfunc->cont.properties.first;
for (; dparm; dparm = dparm->next) {
@@ -2223,6 +2234,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname);
else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier);
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ fprintf(f, "\t_type= _ptr->type;\n");
+ }
if (has_data) {
fprintf(f, "\t_data= (char *)_parms->data;\n");
@@ -2300,6 +2314,11 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
fprintf(f, "_self");
first = 0;
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ if (!first) fprintf(f, ", ");
+ fprintf(f, "_type");
+ first = 0;
+ }
if (func->flag & FUNC_USE_MAIN) {
if (!first) fprintf(f, ", ");
@@ -2425,7 +2444,6 @@ static const char *rna_property_subtypename(PropertySubType type)
case PROP_FILENAME: return "PROP_FILENAME";
case PROP_DIRPATH: return "PROP_DIRPATH";
case PROP_BYTESTRING: return "PROP_BYTESTRING";
- case PROP_TRANSLATE: return "PROP_TRANSLATE";
case PROP_UNSIGNED: return "PROP_UNSIGNED";
case PROP_PERCENTAGE: return "PROP_PERCENTAGE";
case PROP_FACTOR: return "PROP_FACTOR";
@@ -2447,7 +2465,8 @@ static const char *rna_property_subtypename(PropertySubType type)
case PROP_LAYER: return "PROP_LAYER";
case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER";
case PROP_PASSWORD: return "PROP_PASSWORD";
- default: {
+ default:
+ {
/* in case we don't have a type preset that includes the subtype */
if (RNA_SUBTYPE_UNIT(type)) {
return rna_property_subtypename(type & ~RNA_SUBTYPE_UNIT(type));
@@ -2613,6 +2632,11 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
else fprintf(f, "struct %s *_self", srna->identifier);
first = 0;
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ if (!first) fprintf(f, ", ");
+ fprintf(f, "struct StructRNA *_type");
+ first = 0;
+ }
if (func->flag & FUNC_USE_MAIN) {
if (!first) fprintf(f, ", ");
@@ -2882,9 +2906,9 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
rna_property_structname(prop->type),
srna->identifier, strnest, prop->identifier);
- if (prop->next) fprintf(f, "\t{(PropertyRNA*)&rna_%s%s_%s, ", srna->identifier, strnest, prop->next->identifier);
+ if (prop->next) fprintf(f, "\t{(PropertyRNA *)&rna_%s%s_%s, ", srna->identifier, strnest, prop->next->identifier);
else fprintf(f, "\t{NULL, ");
- if (prop->prev) fprintf(f, "(PropertyRNA*)&rna_%s%s_%s,\n", srna->identifier, strnest, prop->prev->identifier);
+ if (prop->prev) fprintf(f, "(PropertyRNA *)&rna_%s%s_%s,\n", srna->identifier, strnest, prop->prev->identifier);
else fprintf(f, "NULL,\n");
fprintf(f, "\t%d, ", prop->magic);
rna_print_c_string(f, prop->identifier);
@@ -2923,11 +2947,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_BOOLEAN:
{
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %d, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %d, ",
rna_function_string(bprop->get),
rna_function_string(bprop->set),
rna_function_string(bprop->getarray),
rna_function_string(bprop->setarray),
+ rna_function_string(bprop->get_ex),
+ rna_function_string(bprop->set_ex),
+ rna_function_string(bprop->getarray_ex),
+ rna_function_string(bprop->setarray_ex),
bprop->defaultvalue);
if (prop->arraydimension && prop->totarraylength)
fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
@@ -2937,12 +2965,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_INT:
{
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %s,\n\t",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,\n\t",
rna_function_string(iprop->get),
rna_function_string(iprop->set),
rna_function_string(iprop->getarray),
rna_function_string(iprop->setarray),
- rna_function_string(iprop->range));
+ rna_function_string(iprop->range),
+ rna_function_string(iprop->get_ex),
+ rna_function_string(iprop->set_ex),
+ rna_function_string(iprop->getarray_ex),
+ rna_function_string(iprop->setarray_ex),
+ rna_function_string(iprop->range_ex));
rna_int_print(f, iprop->softmin); fprintf(f, ", ");
rna_int_print(f, iprop->softmax); fprintf(f, ", ");
rna_int_print(f, iprop->hardmin); fprintf(f, ", ");
@@ -2957,12 +2990,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_FLOAT:
{
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %s, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, ",
rna_function_string(fprop->get),
rna_function_string(fprop->set),
rna_function_string(fprop->getarray),
rna_function_string(fprop->setarray),
- rna_function_string(fprop->range));
+ rna_function_string(fprop->range),
+ rna_function_string(fprop->get_ex),
+ rna_function_string(fprop->set_ex),
+ rna_function_string(fprop->getarray_ex),
+ rna_function_string(fprop->setarray_ex),
+ rna_function_string(fprop->range_ex));
rna_float_print(f, fprop->softmin); fprintf(f, ", ");
rna_float_print(f, fprop->softmax); fprintf(f, ", ");
rna_float_print(f, fprop->hardmin); fprintf(f, ", ");
@@ -2978,10 +3016,13 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_STRING:
{
StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %d, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %d, ",
rna_function_string(sprop->get),
rna_function_string(sprop->length),
rna_function_string(sprop->set),
+ rna_function_string(sprop->get_ex),
+ rna_function_string(sprop->length_ex),
+ rna_function_string(sprop->set_ex),
sprop->maxlength);
rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n");
break;
@@ -2989,10 +3030,12 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_ENUM:
{
EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, NULL, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, NULL, ",
rna_function_string(eprop->get),
rna_function_string(eprop->set),
- rna_function_string(eprop->itemf));
+ rna_function_string(eprop->itemf),
+ rna_function_string(eprop->get_ex),
+ rna_function_string(eprop->set_ex));
if (eprop->item)
fprintf(f, "rna_%s%s_%s_items, ", srna->identifier, strnest, prop->identifier);
else
@@ -3056,12 +3099,12 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "%s%s rna_%s_%s_func = {\n", "", "FunctionRNA", srna->identifier, func->identifier);
if (func->cont.next)
- fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s_func, ", srna->identifier,
+ fprintf(f, "\t{(FunctionRNA *)&rna_%s_%s_func, ", srna->identifier,
((FunctionRNA *)func->cont.next)->identifier);
else
fprintf(f, "\t{NULL, ");
if (func->cont.prev)
- fprintf(f, "(FunctionRNA*)&rna_%s_%s_func,\n", srna->identifier,
+ fprintf(f, "(FunctionRNA *)&rna_%s_%s_func,\n", srna->identifier,
((FunctionRNA *)func->cont.prev)->identifier);
else
fprintf(f, "NULL,\n");
@@ -3069,11 +3112,11 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "\tNULL,\n");
parm = func->cont.properties.first;
- if (parm) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier);
+ if (parm) fprintf(f, "\t{(PropertyRNA *)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier);
else fprintf(f, "\t{NULL, ");
parm = func->cont.properties.last;
- if (parm) fprintf(f, "(PropertyRNA*)&rna_%s_%s_%s}},\n", srna->identifier, func->identifier, parm->identifier);
+ if (parm) fprintf(f, "(PropertyRNA *)&rna_%s_%s_%s}},\n", srna->identifier, func->identifier, parm->identifier);
else fprintf(f, "NULL}},\n");
fprintf(f, "\t");
@@ -3086,7 +3129,7 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
else fprintf(f, "\tNULL,\n");
if (func->c_ret)
- fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->c_ret->identifier);
+ fprintf(f, "\t(PropertyRNA *)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->c_ret->identifier);
else
fprintf(f, "\tNULL\n");
@@ -3104,11 +3147,11 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "\tNULL,\n");
prop = srna->cont.properties.first;
- if (prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier);
+ if (prop) fprintf(f, "\t{(PropertyRNA *)&rna_%s_%s, ", srna->identifier, prop->identifier);
else fprintf(f, "\t{NULL, ");
prop = srna->cont.properties.last;
- if (prop) fprintf(f, "(PropertyRNA*)&rna_%s_%s}},\n", srna->identifier, prop->identifier);
+ if (prop) fprintf(f, "(PropertyRNA *)&rna_%s_%s}},\n", srna->identifier, prop->identifier);
else fprintf(f, "NULL}},\n");
fprintf(f, "\t");
rna_print_c_string(f, srna->identifier);
@@ -3127,7 +3170,7 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
while (base->base && base->base->nameproperty == prop)
base = base->base;
- fprintf(f, "\t(PropertyRNA*)&rna_%s_%s, ", base->identifier, prop->identifier);
+ fprintf(f, "\t(PropertyRNA *)&rna_%s_%s, ", base->identifier, prop->identifier);
}
else fprintf(f, "\tNULL, ");
@@ -3135,7 +3178,7 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
base = srna;
while (base->base && base->base->iteratorproperty == prop)
base = base->base;
- fprintf(f, "(PropertyRNA*)&rna_%s_rna_properties,\n", base->identifier);
+ fprintf(f, "(PropertyRNA *)&rna_%s_rna_properties,\n", base->identifier);
if (srna->base) fprintf(f, "\t&RNA_%s,\n", srna->base->identifier);
else fprintf(f, "\tNULL,\n");
@@ -3157,11 +3200,11 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
}
func = srna->functions.first;
- if (func) fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s_func, ", srna->identifier, func->identifier);
+ if (func) fprintf(f, "\t{(FunctionRNA *)&rna_%s_%s_func, ", srna->identifier, func->identifier);
else fprintf(f, "\t{NULL, ");
func = srna->functions.last;
- if (func) fprintf(f, "(FunctionRNA*)&rna_%s_%s_func}\n", srna->identifier, func->identifier);
+ if (func) fprintf(f, "(FunctionRNA *)&rna_%s_%s_func}\n", srna->identifier, func->identifier);
else fprintf(f, "NULL}\n");
fprintf(f, "};\n");
@@ -3205,7 +3248,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_main.c", "rna_main_api.c", RNA_def_main},
{"rna_material.c", "rna_material_api.c", RNA_def_material},
{"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh},
- {"rna_meta.c", NULL, RNA_def_meta},
+ {"rna_meta.c", "rna_meta_api.c", RNA_def_meta},
{"rna_modifier.c", NULL, RNA_def_modifier},
{"rna_nla.c", NULL, RNA_def_nla},
{"rna_nodetree.c", NULL, RNA_def_nodetree},
@@ -3216,6 +3259,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_pose.c", "rna_pose_api.c", RNA_def_pose},
{"rna_property.c", NULL, RNA_def_gameproperty},
{"rna_render.c", NULL, RNA_def_render},
+ {"rna_rigidbody.c", NULL, RNA_def_rigidbody},
{"rna_scene.c", "rna_scene_api.c", RNA_def_scene},
{"rna_screen.c", NULL, RNA_def_screen},
{"rna_sculpt_paint.c", NULL, RNA_def_sculpt_paint},
@@ -3383,7 +3427,7 @@ static const char *cpp_classes = ""
"namespace BL {\n"
"\n"
"#define BOOLEAN_PROPERTY(sname, identifier) \\\n"
-" inline bool sname::identifier(void) { return sname##_##identifier##_get(&ptr)? true: false; } \\\n"
+" inline bool sname::identifier(void) { return sname##_##identifier##_get(&ptr) ? true: false; } \\\n"
" inline void sname::identifier(int value) { sname##_##identifier##_set(&ptr, value); }\n"
"\n"
"#define BOOLEAN_ARRAY_PROPERTY(sname, size, identifier) \\\n"
@@ -3501,8 +3545,27 @@ static const char *cpp_classes = ""
"#define COLLECTION_PROPERTY_LOOKUP_STRING_FALSE(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n"
" { \\\n"
-" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
-" return 0; \\\n"
+" CollectionPropertyIterator iter; \\\n"
+" int found = 0; \\\n"
+" PropertyRNA *item_name_prop = RNA_struct_name_property(ptr->type); \\\n"
+" sname##_##identifier##_begin(&iter, ptr); \\\n"
+" while (iter.valid && !found) { \\\n"
+" char name_fixed[32]; \\\n"
+" const char *name; \\\n"
+" int name_length; \\\n"
+" name = RNA_property_string_get_alloc(&iter.ptr, item_name_prop, name_fixed, sizeof(name_fixed), &name_length); \\\n"
+" if (!strncmp(name, key, name_length)) { \\\n"
+" *r_ptr = iter.ptr; \\\n"
+" found = 1; \\\n"
+" } \\\n"
+" if (name_fixed != name) \\\n"
+" MEM_freeN((void *) name); \\\n"
+" sname##_##identifier##_next(&iter); \\\n"
+" } \\\n"
+" sname##_##identifier##_end(&iter); \\\n"
+" if (!found) \\\n"
+" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
+" return found; \\\n"
" } \n"
"#define COLLECTION_PROPERTY_LOOKUP_STRING_TRUE(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n"
@@ -3523,7 +3586,7 @@ static const char *cpp_classes = ""
"public:\n"
" Pointer(const PointerRNA &p) : ptr(p) { }\n"
" operator const PointerRNA&() { return ptr; }\n"
-" bool is_a(StructRNA *type) { return RNA_struct_is_a(ptr.type, type)? true: false; }\n"
+" bool is_a(StructRNA *type) { return RNA_struct_is_a(ptr.type, type) ? true: false; }\n"
" operator void*() { return ptr.data; }\n"
" operator bool() { return ptr.data != NULL; }\n"
"\n"
@@ -3551,7 +3614,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 = (float *)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"
@@ -3562,7 +3625,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 = (float *)malloc(sizeof(T) * other.length);\n"
" memcpy(data, other.data, sizeof(T) * other.length);\n"
" length = other.length;\n"
" }\n"
@@ -3593,7 +3656,7 @@ static const char *cpp_classes = ""
"{ return iter.valid != other.iter.valid; }\n"
"\n"
" void begin(const Pointer &ptr)\n"
-" { if (init) Tend(&iter); Tbegin(&iter, (PointerRNA*)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
+" { if (init) Tend(&iter); Tbegin(&iter, (PointerRNA *)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
"\n"
"private:\n"
" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator="
@@ -3727,13 +3790,13 @@ static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f)
if (first_collection_func_struct == NULL)
first_collection_func_struct = ds->srna->identifier;
- if (!rna_is_collection_functions_struct(collection_func_structs, (char*)prop->srna)) {
+ if (!rna_is_collection_functions_struct(collection_func_structs, (char *)prop->srna)) {
if (all_collection_func_structs >= max_collection_func_structs) {
printf("Array size to store all collection structures names is too small\n");
exit(1);
}
- collection_func_structs[all_collection_func_structs++] = (char*)prop->srna;
+ collection_func_structs[all_collection_func_structs++] = (char *)prop->srna;
}
}
}
@@ -3819,6 +3882,13 @@ static int rna_preprocess(const char *outfile)
if (PROCESS_ITEMS[i].define) {
PROCESS_ITEMS[i].define(brna);
+ /* sanity check */
+ if (!DefRNA.animate) {
+ fprintf(stderr,
+ "Error: DefRNA.animate left disabled in %s\n",
+ PROCESS_ITEMS[i].filename);
+ }
+
for (ds = DefRNA.structs.first; ds; ds = ds->cont.next)
if (!ds->filename)
ds->filename = PROCESS_ITEMS[i].filename;
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 11ce7345e41..184ee23b488 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -248,7 +248,7 @@ StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports,
return NULL;
}
- return RNA_def_struct(&BLENDER_RNA, identifier, "PropertyGroup"); /* XXX */
+ return RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_PropertyGroup); /* XXX */
}
StructRNA *rna_PropertyGroup_refine(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 488dbffc3db..adfb096b25f 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -40,6 +40,7 @@
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
+#include "BLI_math.h"
#include "BLF_api.h"
#include "BLF_translation.h"
@@ -937,6 +938,12 @@ void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, in
iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
}
+ else if (iprop->range_ex) {
+ *hardmin = INT_MIN;
+ *hardmax = INT_MAX;
+
+ iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
+ }
else {
*hardmin = iprop->hardmin;
*hardmax = iprop->hardmax;
@@ -977,8 +984,17 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin,
iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
- *softmin = MAX2(*softmin, hardmin);
- *softmax = MIN2(*softmax, hardmax);
+ *softmin = max_ii(*softmin, hardmin);
+ *softmax = min_ii(*softmax, hardmax);
+ }
+ else if (iprop->range_ex) {
+ hardmin = INT_MIN;
+ hardmax = INT_MAX;
+
+ iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
+
+ *softmin = max_ii(*softmin, hardmin);
+ *softmax = min_ii(*softmax, hardmax);
}
*step = iprop->step;
@@ -1012,6 +1028,12 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin
fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
}
+ else if (fprop->range_ex) {
+ *hardmin = -FLT_MAX;
+ *hardmax = FLT_MAX;
+
+ fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
+ }
else {
*hardmin = fprop->hardmin;
*hardmax = fprop->hardmax;
@@ -1056,8 +1078,17 @@ void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *soft
fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
- *softmin = MAX2(*softmin, hardmin);
- *softmax = MIN2(*softmax, hardmax);
+ *softmin = max_ff(*softmin, hardmin);
+ *softmax = min_ff(*softmax, hardmax);
+ }
+ else if (fprop->range_ex) {
+ hardmin = -FLT_MAX;
+ hardmax = FLT_MAX;
+
+ fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
+
+ *softmin = max_ff(*softmin, hardmin);
+ *softmax = min_ff(*softmax, hardmax);
}
*step = fprop->step;
@@ -1197,11 +1228,16 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
RNA_property_enum_items(C, ptr, prop, item, totitem, free);
#ifdef WITH_INTERNATIONAL
- /* Note: keep directly using BLF_gettext here, has we have already done tests like BLF_translate_iface... */
- if (BLF_translate_iface()) {
+ {
int i;
+ /* Note: Only do those tests once, and then use BLF_pgettext. */
+ int do_iface = BLF_translate_iface();
+ int do_tooltip = BLF_translate_tooltips();
EnumPropertyItem *nitem;
+ if (!(do_iface || do_tooltip))
+ return;
+
if (*free) {
nitem = *item;
}
@@ -1217,18 +1253,17 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
for (i = 0; (*item)[i].identifier; i++)
nitem[i] = (*item)[i];
- *free = 1;
+ *free = TRUE;
}
for (i = 0; nitem[i].identifier; i++) {
- if (nitem[i].name) {
- if (prop->translation_context)
- nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
- else
- nitem[i].name = BLF_pgettext(NULL, nitem[i].name);
+ if (nitem[i].name && do_iface) {
+ /* note: prop->translation_context may be NULL, this just means we use the default "" context */
+ nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
}
- if (nitem[i].description)
+ if (nitem[i].description && do_tooltip) {
nitem[i].description = BLF_pgettext(NULL, nitem[i].description);
+ }
}
*item = nitem;
@@ -1470,7 +1505,7 @@ int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
{
- int is_rna = (prop->magic == RNA_MAGIC);
+ const bool is_rna = (prop->magic == RNA_MAGIC);
prop = rna_ensure_property(prop);
if (is_rna) {
@@ -1550,19 +1585,19 @@ static ListBase rna_updates_cache = {NULL, NULL};
void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
{
+ const bool is_rna = (prop->magic == RNA_MAGIC);
tRnaUpdateCacheElem *uce = NULL;
UpdateFunc fn = NULL;
LinkData *ld;
- short is_rna = (prop->magic == RNA_MAGIC);
/* sanity check */
- if (ELEM(NULL, ptr, prop))
+ if (NULL == ptr)
return;
prop = rna_ensure_property(prop);
/* we can only handle update calls with no context args for now (makes animsys updates easier) */
- if ((is_rna == 0) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
+ if ((is_rna == false) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
return;
fn = prop->update;
@@ -1641,6 +1676,8 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (bprop->get)
return bprop->get(ptr);
+ else if (bprop->get_ex)
+ return bprop->get_ex(ptr, prop);
else
return bprop->defaultvalue;
}
@@ -1663,6 +1700,9 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
else if (bprop->set) {
bprop->set(ptr, value);
}
+ else if (bprop->set_ex) {
+ bprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1693,6 +1733,8 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val
values[0] = RNA_property_boolean_get(ptr, prop);
else if (bprop->getarray)
bprop->getarray(ptr, values);
+ else if (bprop->getarray_ex)
+ bprop->getarray_ex(ptr, prop, values);
else if (bprop->defaultarray)
memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
else
@@ -1743,6 +1785,8 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in
RNA_property_boolean_set(ptr, prop, values[0]);
else if (bprop->setarray)
bprop->setarray(ptr, values);
+ else if (bprop->setarray_ex)
+ bprop->setarray_ex(ptr, prop, values);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1844,6 +1888,8 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (iprop->get)
return iprop->get(ptr);
+ else if (iprop->get_ex)
+ return iprop->get_ex(ptr, prop);
else
return iprop->defaultvalue;
}
@@ -1864,6 +1910,8 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
}
else if (iprop->set)
iprop->set(ptr, value);
+ else if (iprop->set_ex)
+ iprop->set_ex(ptr, prop, value);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1896,6 +1944,8 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
values[0] = RNA_property_int_get(ptr, prop);
else if (iprop->getarray)
iprop->getarray(ptr, values);
+ else if (iprop->getarray_ex)
+ iprop->getarray_ex(ptr, prop, values);
else if (iprop->defaultarray)
memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
else
@@ -1983,6 +2033,8 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
RNA_property_int_set(ptr, prop, values[0]);
else if (iprop->setarray)
iprop->setarray(ptr, values);
+ else if (iprop->setarray_ex)
+ iprop->setarray_ex(ptr, prop, values);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2083,6 +2135,8 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
}
else if (fprop->get)
return fprop->get(ptr);
+ else if (fprop->get_ex)
+ return fprop->get_ex(ptr, prop);
else
return fprop->defaultvalue;
}
@@ -2108,6 +2162,9 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
else if (fprop->set) {
fprop->set(ptr, value);
}
+ else if (fprop->set_ex) {
+ fprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2146,6 +2203,8 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
values[0] = RNA_property_float_get(ptr, prop);
else if (fprop->getarray)
fprop->getarray(ptr, values);
+ else if (fprop->getarray_ex)
+ fprop->getarray_ex(ptr, prop, values);
else if (fprop->defaultarray)
memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
else
@@ -2245,6 +2304,9 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
else if (fprop->setarray) {
fprop->setarray(ptr, values);
}
+ else if (fprop->setarray_ex) {
+ fprop->setarray_ex(ptr, prop, values);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2357,6 +2419,9 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
else if (sprop->get) {
sprop->get(ptr, value);
}
+ else if (sprop->get_ex) {
+ sprop->get_ex(ptr, prop, value);
+ }
else {
strcpy(value, sprop->defaultvalue);
}
@@ -2417,6 +2482,8 @@ int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
}
else if (sprop->length)
return sprop->length(ptr);
+ else if (sprop->length_ex)
+ return sprop->length_ex(ptr, prop);
else
return strlen(sprop->defaultvalue);
}
@@ -2435,6 +2502,8 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val
}
else if (sprop->set)
sprop->set(ptr, value); /* set function needs to clamp its self */
+ else if (sprop->set_ex)
+ sprop->set_ex(ptr, prop, value); /* set function needs to clamp its self */
else if (prop->flag & PROP_EDITABLE) {
IDProperty *group;
@@ -2493,6 +2562,8 @@ int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (eprop->get)
return eprop->get(ptr);
+ else if (eprop->get_ex)
+ return eprop->get_ex(ptr, prop);
else
return eprop->defaultvalue;
}
@@ -2511,6 +2582,9 @@ void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
else if (eprop->set) {
eprop->set(ptr, value);
}
+ else if (eprop->set_ex) {
+ eprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -3073,6 +3147,21 @@ int RNA_raw_type_sizeof(RawPropertyType type)
}
}
+static int rna_property_array_length_all_dimensions(PointerRNA *ptr, PropertyRNA *prop)
+{
+ int i, len[RNA_MAX_ARRAY_DIMENSION];
+ const int dim = RNA_property_array_dimension(ptr, prop, len);
+ int size;
+
+ if (dim == 0)
+ return 0;
+
+ for (size = 1, i = 0; i < dim; i++)
+ size *= len[i];
+
+ return size;
+}
+
static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname,
void *inarray, RawPropertyType intype, int inlen, int set)
{
@@ -3107,12 +3196,18 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
return 0;
}
- /* check item array */
- itemlen = RNA_property_array_length(&itemptr, itemprop);
-
+ /* dynamic array? need to get length per item */
+ if (itemprop->getlength) {
+ itemprop = NULL;
+ }
/* try to access as raw array */
- if (RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
- int arraylen = (itemlen == 0) ? 1 : itemlen;
+ else if (RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
+ int arraylen;
+
+ /* check item array */
+ itemlen = RNA_property_array_length(&itemptr, itemprop);
+
+ arraylen = (itemlen == 0) ? 1 : itemlen;
if (in.len != arraylen * out.len) {
BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d)",
out.len * arraylen, in.len);
@@ -3169,7 +3264,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
iprop = RNA_struct_find_property(&itemptr, propname);
if (iprop) {
- itemlen = RNA_property_array_length(&itemptr, iprop);
+ itemlen = rna_property_array_length_all_dimensions(&itemptr, iprop);
itemtype = RNA_property_type(iprop);
}
else {
@@ -4030,8 +4125,9 @@ static char *rna_idp_path(PointerRNA *ptr, IDProperty *haystack, IDProperty *nee
else {
if (iter->type == IDP_GROUP) {
/* ensure this is RNA */
- PointerRNA child_ptr = RNA_pointer_get(ptr, iter->name);
- if (child_ptr.type) {
+ PropertyRNA *prop = RNA_struct_find_property(ptr, iter->name);
+ if (prop && prop->type == PROP_POINTER) {
+ PointerRNA child_ptr = RNA_property_pointer_get(ptr, prop);
link.name = iter->name;
link.index = -1;
if ((path = rna_idp_path(&child_ptr, iter, needle, &link))) {
@@ -4135,11 +4231,11 @@ char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
{
- int is_rna = (prop->magic == RNA_MAGIC);
+ const bool is_rna = (prop->magic == RNA_MAGIC);
const char *propname;
char *ptrpath, *path;
- if (!ptr->id.data || !ptr->data || !prop)
+ if (!ptr->id.data || !ptr->data)
return NULL;
/* path from ID to the struct holding this property */
@@ -4168,7 +4264,7 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
* Get the ID as a python representation, eg:
* bpy.data.foo["bar"]
*/
-char *RNA_path_from_ID_python(ID *id)
+char *RNA_path_full_ID_py(ID *id)
{
char id_esc[(sizeof(id->name) - 2) * 2];
@@ -4177,6 +4273,122 @@ char *RNA_path_from_ID_python(ID *id)
return BLI_sprintfN("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id_esc);
}
+/**
+ * Get the ID.struct as a python representation, eg:
+ * bpy.data.foo["bar"].some_struct
+ */
+char *RNA_path_full_struct_py(struct PointerRNA *ptr)
+{
+ char *id_path;
+ char *data_path;
+
+ char *ret;
+
+ if (!ptr->id.data) {
+ return NULL;
+ }
+
+ /* never fails */
+ id_path = RNA_path_full_ID_py(ptr->id.data);
+
+ data_path = RNA_path_from_ID_to_struct(ptr);
+
+ ret = BLI_sprintfN("%s.%s",
+ id_path, data_path);
+
+ MEM_freeN(data_path);
+
+ return ret;
+}
+
+/**
+ * Get the ID.struct.property as a python representation, eg:
+ * bpy.data.foo["bar"].some_struct.some_prop[10]
+ */
+char *RNA_path_full_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ char *id_path;
+ char *data_path;
+
+ char *ret;
+
+ if (!ptr->id.data) {
+ return NULL;
+ }
+
+ /* never fails */
+ id_path = RNA_path_full_ID_py(ptr->id.data);
+
+ data_path = RNA_path_from_ID_to_property(ptr, prop);
+
+ if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ ret = BLI_sprintfN("%s.%s",
+ id_path, data_path);
+ }
+ else {
+ ret = BLI_sprintfN("%s.%s[%d]",
+ id_path, data_path, index);
+ }
+ MEM_freeN(id_path);
+ if (data_path) {
+ MEM_freeN(data_path);
+ }
+
+ return ret;
+}
+
+/**
+ * Get the struct.property as a python representation, eg:
+ * some_struct.some_prop[10]
+ */
+char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ char *data_path;
+
+ char *ret;
+
+ if (!ptr->id.data) {
+ return NULL;
+ }
+
+ data_path = RNA_path_from_ID_to_property(ptr, prop);
+
+ if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ ret = BLI_sprintfN("%s",
+ data_path);
+ }
+ else {
+ ret = BLI_sprintfN("%s[%d]",
+ data_path, index);
+ }
+
+ if (data_path) {
+ MEM_freeN(data_path);
+ }
+
+ return ret;
+}
+
+/**
+ * Get the struct.property as a python representation, eg:
+ * some_prop[10]
+ */
+char *RNA_path_property_py(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int index)
+{
+ char *ret;
+
+ if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ ret = BLI_sprintfN("%s",
+ RNA_property_identifier(prop));
+ }
+ else {
+ ret = BLI_sprintfN("%s[%d]",
+ RNA_property_identifier(prop), index);
+ }
+
+ return ret;
+}
+
/* Quick name based property access */
int RNA_boolean_get(PointerRNA *ptr, const char *name)
@@ -4606,7 +4818,7 @@ int RNA_property_is_idprop(PropertyRNA *prop)
/* string representation of a property, python
* compatible but can be used for display too,
* context may be NULL */
-char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr)
+static char *rna_pointer_as_string__idprop(bContext *C, PointerRNA *ptr)
{
DynStr *dynstr = BLI_dynstr_new();
char *cstring;
@@ -4627,7 +4839,7 @@ char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr)
BLI_dynstr_append(dynstr, ", ");
first_time = 0;
- cstring = RNA_property_as_string(C, ptr, prop);
+ cstring = RNA_property_as_string(C, ptr, prop, -1);
BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
MEM_freeN(cstring);
}
@@ -4641,6 +4853,28 @@ char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr)
return cstring;
}
+static char *rna_pointer_as_string__bldata(PointerRNA *ptr)
+{
+ if (ptr->type == NULL) {
+ return BLI_strdup("None");
+ }
+ else if (RNA_struct_is_ID(ptr->type)) {
+ return RNA_path_full_ID_py(ptr->id.data);
+ }
+ else {
+ return RNA_path_full_struct_py(ptr);
+ }
+}
+
+char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop)
+{
+ if (RNA_property_flag(prop_ptr) & PROP_IDPROPERTY) {
+ return rna_pointer_as_string__idprop(C, ptr_prop);
+ }
+ else {
+ return rna_pointer_as_string__bldata(ptr_prop);
+ }
+}
/* context and ptr_default can be NULL */
char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA *ptr_default,
@@ -4693,7 +4927,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA
}
}
else {
- buf = RNA_property_as_string(C, ptr, prop);
+ buf = RNA_property_as_string(C, ptr, prop, -1);
}
ok = TRUE;
@@ -4704,7 +4938,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA
prop_default = RNA_struct_find_property(ptr_default, arg_name);
if (prop_default) {
- buf_default = RNA_property_as_string(C, ptr_default, prop_default);
+ buf_default = RNA_property_as_string(C, ptr_default, prop_default, -1);
if (strcmp(buf, buf_default) == 0)
ok = FALSE; /* values match, don't bother printing */
@@ -4754,7 +4988,12 @@ char *RNA_function_as_string_keywords(bContext *C, FunctionRNA *func, PointerRNA
iterprop);
}
-char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
+static const char *bool_as_py_string(const int var)
+{
+ return var ? "True" : "False";
+}
+
+char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
{
int type = RNA_property_type(prop);
int len = RNA_property_array_length(ptr, prop);
@@ -4768,17 +5007,22 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
switch (type) {
case PROP_BOOLEAN:
if (len == 0) {
- BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
+ BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get(ptr, prop)));
}
else {
- BLI_dynstr_append(dynstr, "(");
- for (i = 0; i < len; i++) {
- BLI_dynstr_appendf(dynstr, i ? ", %s" : "%s",
- RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False");
+ if (index != -1) {
+ BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, index)));
+ }
+ else {
+ 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)));
+ }
+ if (len == 1)
+ BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
+ BLI_dynstr_append(dynstr, ")");
}
- if (len == 1)
- BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
- BLI_dynstr_append(dynstr, ")");
}
break;
case PROP_INT:
@@ -4786,13 +5030,18 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
}
else {
- 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));
+ if (index != -1) {
+ BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get_index(ptr, prop, index));
+ }
+ else {
+ 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));
+ }
+ if (len == 1)
+ BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
+ BLI_dynstr_append(dynstr, ")");
}
- if (len == 1)
- BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
- BLI_dynstr_append(dynstr, ")");
}
break;
case PROP_FLOAT:
@@ -4800,13 +5049,18 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
}
else {
- 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));
+ if (index != -1) {
+ BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get_index(ptr, prop, index));
+ }
+ else {
+ 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));
+ }
+ if (len == 1)
+ BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
+ BLI_dynstr_append(dynstr, ")");
}
- if (len == 1)
- BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
- BLI_dynstr_append(dynstr, ")");
}
break;
case PROP_STRING:
@@ -4872,7 +5126,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
case PROP_POINTER:
{
PointerRNA tptr = RNA_property_pointer_get(ptr, prop);
- cstring = RNA_pointer_as_string(C, &tptr);
+ cstring = RNA_pointer_as_string(C, ptr, prop, &tptr);
BLI_dynstr_append(dynstr, cstring);
MEM_freeN(cstring);
break;
@@ -4893,7 +5147,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
first_time = 0;
/* now get every prop of the collection */
- cstring = RNA_pointer_as_string(C, &itemptr);
+ cstring = RNA_pointer_as_string(C, ptr, prop, &itemptr);
BLI_dynstr_append(dynstr, cstring);
MEM_freeN(cstring);
}
@@ -5864,7 +6118,8 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop)
/* get and set the default values as appropriate for the various types */
switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN: {
+ case PROP_BOOLEAN:
+ {
if (len) {
int fixed_a[16], fixed_b[16];
int *array_a, *array_b;
@@ -5889,7 +6144,8 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop)
}
}
- case PROP_INT: {
+ case PROP_INT:
+ {
if (len) {
int fixed_a[16], fixed_b[16];
int *array_a, *array_b;
@@ -5914,7 +6170,8 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop)
}
}
- case PROP_FLOAT: {
+ case PROP_FLOAT:
+ {
if (len) {
float fixed_a[16], fixed_b[16];
float *array_a, *array_b;
@@ -5939,12 +6196,14 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop)
}
}
- case PROP_ENUM: {
+ case PROP_ENUM:
+ {
int value = RNA_property_enum_get(a, prop);
return value == RNA_property_enum_get(b, prop);
}
- case PROP_STRING: {
+ case PROP_STRING:
+ {
char fixed_a[128], fixed_b[128];
int len_a, len_b;
char *value_a = RNA_property_string_get_alloc(a, prop, fixed_a, sizeof(fixed_a), &len_a);
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 1f9503f1cc9..7de1f84acdd 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -39,6 +39,8 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+
#include "BKE_action.h"
#include "WM_types.h"
@@ -157,7 +159,7 @@ static TimeMarker *rna_Action_pose_markers_new(bAction *act, const char name[])
static void rna_Action_pose_markers_remove(bAction *act, ReportList *reports, PointerRNA *marker_ptr)
{
TimeMarker *marker = marker_ptr->data;
- if (BLI_remlink_safe(&act->markers, marker) == FALSE) {
+ if (!BLI_remlink_safe(&act->markers, marker)) {
BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in action '%s'", marker->name, act->id.name + 2);
return;
}
@@ -596,7 +598,7 @@ static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Action_active_pose_marker_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Pose Marker", "Active pose marker for this action");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "active_marker");
RNA_def_property_int_funcs(prop, "rna_Action_active_pose_marker_index_get",
"rna_Action_active_pose_marker_index_set", "rna_Action_active_pose_marker_index_range");
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index b653289e44d..fe4a23cb393 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -389,6 +389,12 @@ static void rna_ObjectActuator_type_set(struct PointerRNA *ptr, int value)
oa->forcerot[1] = 0.5f;
oa->forcerot[2] = 0.0f;
break;
+
+ case ACT_OBJECT_CHARACTER:
+ memset(oa, 0, sizeof(bObjectActuator));
+ oa->flag = ACT_DLOC_LOCAL | ACT_DROT_LOCAL;
+ oa->type = ACT_OBJECT_CHARACTER;
+ break;
}
}
}
@@ -701,6 +707,7 @@ static void rna_def_object_actuator(BlenderRNA *brna)
static EnumPropertyItem prop_type_items[] = {
{ACT_OBJECT_NORMAL, "OBJECT_NORMAL", 0, "Simple Motion", ""},
{ACT_OBJECT_SERVO, "OBJECT_SERVO", 0, "Servo Control", ""},
+ {ACT_OBJECT_CHARACTER, "OBJECT_CHARACTER", 0, "Character Motion", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -867,6 +874,11 @@ static void rna_def_object_actuator(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Add", "Toggles between ADD and SET linV");
RNA_def_property_update(prop, NC_LOGIC, NULL);
+ prop = RNA_def_property(srna, "use_add_character_location", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_ADD_CHAR_LOC);
+ RNA_def_property_ui_text(prop, "Add", "Toggle between ADD and SET character location");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
prop = RNA_def_property(srna, "use_servo_limit_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_SERVO_LIMIT_X);
RNA_def_property_ui_text(prop, "X", "Set limit to force along the X axis");
@@ -881,6 +893,11 @@ static void rna_def_object_actuator(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_SERVO_LIMIT_Z);
RNA_def_property_ui_text(prop, "Z", "Set limit to force along the Z axis");
RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+ prop = RNA_def_property(srna, "use_character_jump", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_CHAR_JUMP);
+ RNA_def_property_ui_text(prop, "Jump", "Make the character jump using the settings in the physics properties");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
}
static void rna_def_camera_actuator(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 7229dddf6d6..d6ea53f6ab3 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -52,6 +52,20 @@ EnumPropertyItem keyingset_path_grouping_items[] = {
{0, NULL, 0, NULL, NULL}
};
+/* It would be cool to get rid of this 'INSERTKEY_' prefix in 'py strings' values, but it would break existing
+ * exported keyingset... :/
+ */
+EnumPropertyItem keying_flag_items[] = {
+ {INSERTKEY_NEEDED, "INSERTKEY_NEEDED", 0, "Only Needed",
+ "Only insert keyframes where they're needed in the relevant F-Curves"},
+ {INSERTKEY_MATRIX, "INSERTKEY_VISUAL", 0, "Visual Keying",
+ "Insert keyframes based on 'visual transforms'"},
+ {INSERTKEY_XYZ2RGB, "INSERTKEY_XYZ_TO_RGB", 0, "XYZ=RGB Colors",
+ "Color for newly added transformation F-Curves (Location, Rotation, Scale) "
+ "and also Color is based on the transform axis"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "BLI_math_base.h"
@@ -184,6 +198,8 @@ static void rna_KeyingSetInfo_unregister(Main *bmain, StructRNA *type)
RNA_struct_free_extension(type, &ksi->ext);
RNA_struct_free(&BLENDER_RNA, type);
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
/* unlink Blender-side data */
ANIM_keyingset_info_unregister(bmain, ksi);
}
@@ -220,7 +236,7 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v
memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo));
/* set RNA-extensions info */
- ksi->ext.srna = RNA_def_struct(&BLENDER_RNA, ksi->idname, "KeyingSetInfo");
+ ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo);
ksi->ext.data = data;
ksi->ext.call = call;
ksi->ext.free = free;
@@ -235,6 +251,8 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v
/* add and register with other info as needed */
ANIM_keyingset_info_register(ksi);
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
/* return the struct-rna added */
return ksi->ext.srna;
}
@@ -518,17 +536,6 @@ static void rna_def_common_keying_flags(StructRNA *srna, short UNUSED(reg))
{
PropertyRNA *prop;
- static EnumPropertyItem keying_flag_items[] = {
- {INSERTKEY_NEEDED, "INSERTKEY_NEEDED", 0, "Only Needed",
- "Only insert keyframes where they're needed in the relevant F-Curves"},
- {INSERTKEY_MATRIX, "INSERTKEY_VISUAL", 0, "Visual Keying",
- "Insert keyframes based on 'visual transforms'"},
- {INSERTKEY_XYZ2RGB, "INSERTKEY_XYZ_TO_RGB", 0, "XYZ=RGB Colors",
- "Color for newly added transformation F-Curves (Location, Rotation, Scale) "
- "and also Color is based on the transform axis"},
- {0, NULL, 0, NULL, NULL}
- };
-
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);
@@ -574,7 +581,7 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
@@ -774,7 +781,7 @@ static void rna_def_keyingset(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_RENAME, NULL);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 4c566d71981..6c48ed25b60 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -529,6 +529,11 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_LOCAL_LOCATION);
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+ prop = RNA_def_property(srna, "use_relative_parent", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Relative Parenting", "Object children will use relative transform, like deform");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_RELATIVE_PARENTING);
+ RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+
prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
RNA_def_property_ui_text(prop, "Draw Wire",
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 3da718afd1c..63f4e480468 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -100,7 +100,7 @@ static void rna_Boids_reset(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRN
WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
}
-static void rna_Boids_reset_deps(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Boids_reset_deps(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
if (ptr->type == &RNA_ParticleSystem) {
ParticleSystem *psys = (ParticleSystem *)ptr->data;
@@ -112,7 +112,7 @@ static void rna_Boids_reset_deps(Main *bmain, Scene *scene, PointerRNA *ptr)
else
DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA | PSYS_RECALC_RESET);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
}
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 7bdebd620ee..c995d3b52c7 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -65,6 +65,7 @@ EnumPropertyItem brush_sculpt_tool_items[] = {
{SCULPT_TOOL_PINCH, "PINCH", ICON_BRUSH_PINCH, "Pinch", ""},
{SCULPT_TOOL_ROTATE, "ROTATE", ICON_BRUSH_ROTATE, "Rotate", ""},
{SCULPT_TOOL_SCRAPE, "SCRAPE", ICON_BRUSH_SCRAPE, "Scrape", ""},
+ {SCULPT_TOOL_SIMPLIFY, "SIMPLIFY", ICON_BRUSH_SUBTRACT /* icon TODO */, "Simplify", ""},
{SCULPT_TOOL_SMOOTH, "SMOOTH", ICON_BRUSH_SMOOTH, "Smooth", ""},
{SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_BRUSH_SNAKE_HOOK, "Snake Hook", ""},
{SCULPT_TOOL_THUMB, "THUMB", ICON_BRUSH_THUMB, "Thumb", ""},
@@ -428,6 +429,13 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem prop_tex_paint_map_mode_items[] = {
+ {MTEX_MAP_MODE_VIEW, "VIEW_PLANE", 0, "View Plane", ""},
+ {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""},
+ {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""},
+ {0, NULL, 0, NULL, 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");
@@ -443,6 +451,12 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_map_mode_items);
RNA_def_property_ui_text(prop, "Mode", "");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
+
+ prop = RNA_def_property(srna, "tex_paint_map_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode");
+ RNA_def_property_enum_items(prop, prop_tex_paint_map_mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
}
static void rna_def_sculpt_capabilities(BlenderRNA *brna)
@@ -604,7 +618,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Brush_update");
/* number values */
- prop = RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "size", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop, NULL, "rna_Brush_set_size", NULL);
RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS * 10);
RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0);
@@ -631,7 +645,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Spacing", "Spacing between brush daubs as a percentage of brush diameter");
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "smooth_stroke_radius", PROP_INT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "smooth_stroke_radius", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 10, 200);
RNA_def_property_ui_text(prop, "Smooth Stroke Radius", "Minimum distance from last point before stroke continues");
RNA_def_property_update(prop, 0, "rna_Brush_update");
@@ -854,11 +868,6 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RESTORE_MESH);
RNA_def_property_ui_text(prop, "Restore Mesh", "Allow a single dot to be carefully positioned");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
- prop = RNA_def_property(srna, "use_fixed_texture", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_FIXED_TEX);
- RNA_def_property_ui_text(prop, "Fixed Texture", "Keep texture origin in fixed position");
- RNA_def_property_update(prop, 0, "rna_Brush_update");
/* only for projection paint, TODO, other paint modes */
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index b72bba0422a..5f11663c057 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -112,8 +112,8 @@ void RNA_def_camera(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem prop_lens_unit_items[] = {
- {0, "MILLIMETERS", 0, "Millimeters", ""},
- {CAM_ANGLETOGGLE, "DEGREES", 0, "Degrees", ""},
+ {0, "MILLIMETERS", 0, "Millimeters", "Specify the lens in millimeters"},
+ {CAM_ANGLETOGGLE, "FOV", 0, "Field of View", "Specify the lens as the field of view's angle"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem sensor_fit_items[] = {
@@ -154,23 +154,23 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
prop = RNA_def_property(srna, "angle_x", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_range(prop, M_PI * (0.367 / 180.0), M_PI * (172.847 / 180.0));
+ RNA_def_property_range(prop, DEG2RAD(0.367), DEG2RAD(172.847));
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Horizontal FOV", "Camera lens horizontal field of view in degrees");
+ RNA_def_property_ui_text(prop, "Horizontal FOV", "Camera lens horizontal field of view");
RNA_def_property_float_funcs(prop, "rna_Camera_angle_x_get", "rna_Camera_angle_x_set", NULL);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
prop = RNA_def_property(srna, "angle_y", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_range(prop, M_PI * (0.367 / 180.0), M_PI * (172.847 / 180.0));
+ RNA_def_property_range(prop, DEG2RAD(0.367), DEG2RAD(172.847));
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Vertical FOV", "Camera lens vertical field of view in degrees");
+ RNA_def_property_ui_text(prop, "Vertical FOV", "Camera lens vertical field of view");
RNA_def_property_float_funcs(prop, "rna_Camera_angle_y_get", "rna_Camera_angle_y_set", NULL);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_range(prop, M_PI * (0.367 / 180.0), M_PI * (172.847 / 180.0));
+ RNA_def_property_range(prop, DEG2RAD(0.367), DEG2RAD(172.847));
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Field of View", "Camera lens field of view in degrees");
+ RNA_def_property_ui_text(prop, "Field of View", "Camera lens field of view");
RNA_def_property_float_funcs(prop, "rna_Camera_angle_get", "rna_Camera_angle_set", NULL);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
@@ -208,7 +208,8 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ortho_scale");
- RNA_def_property_range(prop, 0.01f, 4000.0f);
+ RNA_def_property_range(prop, FLT_MIN, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.001f, 10000.0f, 10, 3);
RNA_def_property_ui_text(prop, "Orthographic Scale", "Orthographic Camera scale (similar to zoom)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index b9e86e116a2..69de86da007 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -403,8 +403,8 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
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, 200);
- RNA_def_property_ui_text(prop, "Pre Roll", "Simulation starts on this frame");
+ 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);
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 5752fd318c7..c70dc285b20 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -424,7 +424,7 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int
}
}
-static EnumPropertyItem* rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
{
Scene *scene = CTX_data_scene(C);
EnumPropertyItem *items = NULL;
@@ -848,7 +848,7 @@ static void rna_def_histogram(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_line", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", HISTO_FLAG_LINE);
- RNA_def_property_ui_text(prop, "Show Line", "Display lines rather then filled shapes");
+ RNA_def_property_ui_text(prop, "Show Line", "Display lines rather than filled shapes");
RNA_def_property_ui_icon(prop, ICON_IPO, 0);
}
@@ -973,15 +973,26 @@ static void rna_def_colormanage(BlenderRNA *brna)
RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagement_update");
/* ** Colorspace ** */
- srna = RNA_def_struct(brna, "ColorManagedColorspaceSettings", NULL);
- RNA_def_struct_ui_text(srna, "ColorManagedColorspaceSettings", "Input color space settings");
+ srna = RNA_def_struct(brna, "ColorManagedInputColorspaceSettings", NULL);
+ RNA_def_struct_ui_text(srna, "ColorManagedInputColorspaceSettings", "Input color space settings");
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
"rna_ColorManagedColorspaceSettings_colorspace_itemf");
- RNA_def_property_ui_text(prop, "Color Space", "Input color space name");
+ RNA_def_property_ui_text(prop, "Input Color Space", "Color space of the image or movie on disk");
+ RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagedColorspaceSettings_reload_update");
+
+ srna = RNA_def_struct(brna, "ColorManagedSequencerColorspaceSettings", NULL);
+ RNA_def_struct_ui_text(srna, "ColorManagedSequencerColorspaceSettings", "Input color space settings");
+
+ prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
+ "rna_ColorManagedColorspaceSettings_colorspace_set",
+ "rna_ColorManagedColorspaceSettings_colorspace_itemf");
+ RNA_def_property_ui_text(prop, "Color Space", "Color space that the sequencer operates in");
RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagedColorspaceSettings_reload_update");
}
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 30a9bfd81f6..956483890f5 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -214,7 +214,7 @@ static void rna_Constraint_name_set(PointerRNA *ptr, const char *value)
/* if we have the list, check for unique name, otherwise give up */
if (list)
- unique_constraint_name(con, list);
+ BKE_unique_constraint_name(con, list);
}
/* fix all the animation data which may link to this */
@@ -244,9 +244,9 @@ static void rna_Constraint_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Poi
ED_object_constraint_update(ptr->id.data);
}
-static void rna_Constraint_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Constraint_dependency_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- ED_object_constraint_dependency_update(bmain, scene, ptr->id.data);
+ ED_object_constraint_dependency_update(bmain, ptr->id.data);
}
static void rna_Constraint_influence_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -293,7 +293,7 @@ static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *UNUSED(C),
PropertyRNA *UNUSED(prop), int *UNUSED(free))
{
bConstraint *con = (bConstraint *)ptr->data;
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1392,19 +1392,19 @@ static void rna_def_constraint_rigid_body_joint(BlenderRNA *brna)
prop = RNA_def_property(srna, "axis_x", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "axX");
RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
- RNA_def_property_ui_text(prop, "Axis X", "Rotate pivot on X axis in degrees");
+ RNA_def_property_ui_text(prop, "Axis X", "Rotate pivot on X axis");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "axis_y", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "axY");
RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
- RNA_def_property_ui_text(prop, "Axis Y", "Rotate pivot on Y axis in degrees");
+ RNA_def_property_ui_text(prop, "Axis Y", "Rotate pivot on Y axis");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "axis_z", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "axZ");
RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
- RNA_def_property_ui_text(prop, "Axis Z", "Rotate pivot on Z axis in degrees");
+ RNA_def_property_ui_text(prop, "Axis Z", "Rotate pivot on Z axis");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "use_linked_collision", PROP_BOOLEAN, PROP_NONE);
@@ -1528,7 +1528,7 @@ static void rna_def_constraint_clamp_to(BlenderRNA *brna)
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", "Target Object");
+ RNA_def_property_ui_text(prop, "Target", "Target Object (Curves only)");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 21aed20ccc3..b7ef76eeaf3 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -304,7 +304,7 @@ static void rna_Curve_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Curve_update_deps(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
rna_Curve_update_data(bmain, scene, ptr);
}
@@ -460,7 +460,7 @@ static void rna_Curve_body_set(PointerRNA *ptr, const char *value)
/* don't know why this is +4, just duplicating load_editText() */
cu->strinfo = MEM_callocN((len + 4) * sizeof(CharInfo), "strinfo");
- /*BLI_strncpy_wchar_as_utf8(cu->str, value, len+1); *//* value is not wchar_t */
+ /*BLI_strncpy_wchar_as_utf8(cu->str, value, len + 1); *//* value is not wchar_t */
BLI_strncpy(cu->str, value, len + 1);
}
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index bb1ecea6a24..c92777af8fd 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <ctype.h>
+#include "BLI_utildefines.h"
#include "MEM_guardedalloc.h"
#include "DNA_genfile.h"
@@ -61,7 +62,7 @@
/* Global used during defining */
-BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1};
+BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1, 1};
/* Duplicated code since we can't link in blenkernel or blenlib */
@@ -391,7 +392,9 @@ static int rna_validate_identifier(const char *identifier, char *error, int prop
{
int a = 0;
- /* list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
+ /* list is from...
+ * ", ".join(['"%s"' % kw for kw in __import__("keyword").kwlist if kw not in {"False", "None", "True"}])
+ */
static const char *kwlist[] = {
/* "False", "None", "True", */
"and", "as", "assert", "break",
@@ -463,7 +466,7 @@ BlenderRNA *RNA_create(void)
brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
- DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, 0);
+ DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false);
DefRNA.structs.first = DefRNA.structs.last = NULL;
DefRNA.error = 0;
DefRNA.preprocess = 1;
@@ -504,6 +507,13 @@ void RNA_define_verify_sdna(int verify)
DefRNA.verify = verify;
}
+#ifndef RNA_RUNTIME
+void RNA_define_animate_sdna(int animate)
+{
+ DefRNA.animate = animate;
+}
+#endif
+
void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *ext)
{
#ifdef RNA_RUNTIME
@@ -621,33 +631,20 @@ static StructDefRNA *rna_find_def_struct(StructRNA *srna)
}
/* Struct Definition */
-
-StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
+StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
{
- StructRNA *srna, *srnafrom = NULL;
+ StructRNA *srna;
StructDefRNA *ds = NULL, *dsfrom = NULL;
PropertyRNA *prop;
-
+
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, 0) == 0) {
+ if (rna_validate_identifier(identifier, error, FALSE) == 0) {
fprintf(stderr, "%s: struct identifier \"%s\" error - %s\n", __func__, identifier, error);
DefRNA.error = 1;
}
}
-
- if (from) {
- /* find struct to derive from */
- for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
- if (strcmp(srnafrom->identifier, from) == 0)
- break;
-
- if (!srnafrom) {
- fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
- DefRNA.error = 1;
- }
- }
srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
DefRNA.laststruct = srna;
@@ -668,7 +665,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
else
srna->base = srnafrom;
}
-
+
srna->identifier = identifier;
srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
srna->description = "";
@@ -739,6 +736,28 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
return srna;
}
+StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
+{
+ StructRNA *srnafrom = NULL;
+
+ /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */
+ BLI_assert(DefRNA.preprocess);
+
+ if (from) {
+ /* find struct to derive from */
+ for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
+ if (strcmp(srnafrom->identifier, from) == 0)
+ break;
+
+ if (!srnafrom) {
+ fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
+ DefRNA.error = 1;
+ }
+ }
+
+ return RNA_def_struct_ptr(brna, identifier, srnafrom);
+}
+
void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
{
StructDefRNA *ds;
@@ -909,7 +928,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, 1) == 0) {
+ if (rna_validate_identifier(identifier, error, TRUE) == 0) {
fprintf(stderr, "%s: property identifier \"%s.%s\" - %s\n", __func__,
CONTAINER_RNA_ID(cont), identifier, error);
DefRNA.error = 1;
@@ -926,6 +945,16 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
dprop = MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
rna_addtail(&dcont->properties, dprop);
}
+ else {
+#ifdef DEBUG
+ char error[512];
+ if (rna_validate_identifier(identifier, error, TRUE) == 0) {
+ fprintf(stderr, "%s: runtime property identifier \"%s.%s\" - %s\n", __func__,
+ CONTAINER_RNA_ID(cont), identifier, error);
+ DefRNA.error = 1;
+ }
+#endif
+ }
prop = MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
@@ -943,6 +972,14 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
{
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
+#ifndef RNA_RUNTIME
+ if (subtype == PROP_DISTANCE) {
+ fprintf(stderr, "%s: subtype does not apply to 'PROP_INT' \"%s.%s\"\n", __func__,
+ CONTAINER_RNA_ID(cont), identifier);
+ DefRNA.error = 1;
+ }
+#endif
+
iprop->hardmin = (subtype == PROP_UNSIGNED) ? 0 : INT_MIN;
iprop->hardmax = INT_MAX;
@@ -1010,8 +1047,15 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
if (type != PROP_COLLECTION && type != PROP_POINTER) {
prop->flag = PROP_EDITABLE;
- if (type != PROP_STRING)
+ if (type != PROP_STRING) {
+#ifdef RNA_RUNTIME
prop->flag |= PROP_ANIMATABLE;
+#else
+ if (DefRNA.animate) {
+ prop->flag |= PROP_ANIMATABLE;
+ }
+#endif
+ }
}
if (type == PROP_STRING) {
@@ -1189,6 +1233,15 @@ void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
prop->flag |= PROP_ICONS_CONSECUTIVE;
}
+/**
+ * The values hare are a little confusing:
+ *
+ * \param step For floats this is (step / 100), why /100? - nobody knows.
+ * for int's, whole values are used.
+ *
+ * \param precision The number of zeros to show
+ * (as a whole number - common range is 1 - 6), see PRECISION_FLOAT_MAX
+ */
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
{
StructRNA *srna = DefRNA.laststruct;
@@ -1209,6 +1262,21 @@ void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double
fprop->softmax = (float)max;
fprop->step = (float)step;
fprop->precision = (int)precision;
+#if 0 /* handy but annoying */
+ if (DefRNA.preprocess) {
+ /* check we're not over PRECISION_FLOAT_MAX */
+ if (fprop->precision > 6) {
+ fprintf(stderr, "%s: \"%s.%s\", precision value over maximum.\n",
+ __func__, srna->identifier, prop->identifier);
+ DefRNA.error = 1;
+ }
+ else if (fprop->precision < 1) {
+ fprintf(stderr, "%s: \"%s.%s\", precision value under minimum.\n",
+ __func__, srna->identifier, prop->identifier);
+ DefRNA.error = 1;
+ }
+ }
+#endif
break;
}
default:
@@ -2005,6 +2073,38 @@ void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const ch
}
}
+void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc)
+{
+ BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
+
+ if (getfunc) bprop->get_ex = getfunc;
+ if (setfunc) bprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc)
+{
+ BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
+
+ if (getfunc) bprop->getarray_ex = getfunc;
+ if (setfunc) bprop->setarray_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2037,6 +2137,40 @@ void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *
}
}
+void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
+{
+ IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
+
+ if (getfunc) iprop->get_ex = getfunc;
+ if (setfunc) iprop->set_ex = setfunc;
+ if (rangefunc) iprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
+{
+ IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
+
+ if (getfunc) iprop->getarray_ex = getfunc;
+ if (setfunc) iprop->setarray_ex = setfunc;
+ if (rangefunc) iprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2069,6 +2203,40 @@ void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char
}
}
+void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
+{
+ FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
+
+ if (getfunc) fprop->get_ex = getfunc;
+ if (setfunc) fprop->set_ex = setfunc;
+ if (rangefunc) fprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
+{
+ FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
+
+ if (getfunc) fprop->getarray_ex = getfunc;
+ if (setfunc) fprop->setarray_ex = setfunc;
+ if (rangefunc) fprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2095,6 +2263,29 @@ void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char
}
}
+void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc)
+{
+ EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
+
+ if (getfunc) eprop->get_ex = getfunc;
+ if (setfunc) eprop->set_ex = setfunc;
+ if (itemfunc) eprop->itemf = itemfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data)
+{
+ EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
+ eprop->py_data = py_data;
+}
+
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2121,6 +2312,23 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha
}
}
+void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc)
+{
+ StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
+
+ if (getfunc) sprop->get_ex = getfunc;
+ if (lengthfunc) sprop->length_ex = lengthfunc;
+ if (setfunc) sprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set,
const char *typef, const char *poll)
{
@@ -2375,20 +2583,6 @@ PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_, const char *id
return prop;
}
-PropertyRNA *RNA_def_string_translate(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value,
- int maxlen, const char *ui_name, const char *ui_description)
-{
- ContainerRNA *cont = cont_;
- PropertyRNA *prop;
-
- prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_TRANSLATE);
- if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
- if (default_value) RNA_def_property_string_default(prop, default_value);
- RNA_def_property_ui_text(prop, ui_name, ui_description);
-
- return prop;
-}
-
PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items,
int default_value, const char *ui_name, const char *ui_description)
{
@@ -2435,12 +2629,6 @@ void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
eprop->itemf = itemfunc;
}
-void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data)
-{
- EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
- eprop->py_data = py_data;
-}
-
PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
float hardmin, float hardmax, const char *ui_name, const char *ui_description,
float softmin, float softmax)
@@ -2674,7 +2862,7 @@ static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier)
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, 0) == 0) {
+ if (rna_validate_identifier(identifier, error, FALSE) == 0) {
fprintf(stderr, "%s: function identifier \"%s\" - %s\n", __func__, identifier, error);
DefRNA.error = 1;
}
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index 4f9f2009a14..a505ae0dec2 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -32,6 +32,8 @@
#include "rna_internal.h"
+#include "BLI_math_base.h"
+
#include "BKE_modifier.h"
#include "BKE_dynamicpaint.h"
@@ -150,7 +152,7 @@ static void rna_DynamicPaintSurfaces_changeFormat(Main *bmain, Scene *scene, Poi
static void rna_DynamicPaint_resetDependancy(Main *bmain, Scene *scene, PointerRNA *ptr)
{
rna_DynamicPaintSurface_reset(bmain, scene, ptr);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
static PointerRNA rna_PaintSurface_active_get(PointerRNA *ptr)
@@ -219,6 +221,14 @@ static int rna_DynamicPaint_is_cache_user_get(PointerRNA *ptr)
return (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) ? 1 : 0;
}
+/* is some 3D view preview available */
+static int rna_DynamicPaint_use_color_preview_get(PointerRNA *ptr)
+{
+ DynamicPaintSurface *surface = (DynamicPaintSurface *)ptr->data;
+
+ return dynamicPaint_surfaceHasColorPreview(surface);
+}
+
/* does output layer exist*/
static int rna_DynamicPaint_is_output_exists(DynamicPaintSurface *surface, Object *ob, int index)
{
@@ -239,6 +249,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_PAINT;
tmp.identifier = "PAINT";
tmp.name = "Paint";
+ tmp.icon = ICON_TPAINT_HLT;
RNA_enum_item_add(&item, &totitem, &tmp);
/* Displace */
@@ -248,6 +259,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_DISPLACE;
tmp.identifier = "DISPLACE";
tmp.name = "Displace";
+ tmp.icon = ICON_MOD_DISPLACE;
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -256,6 +268,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_WEIGHT;
tmp.identifier = "WEIGHT";
tmp.name = "Weight";
+ tmp.icon = ICON_MOD_VERTEX_WEIGHT;
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -264,6 +277,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_WAVE;
tmp.identifier = "WAVE";
tmp.name = "Waves";
+ tmp.icon = ICON_MOD_WAVE;
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -705,6 +719,14 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_DynamicPaint_is_cache_user_get", NULL);
RNA_def_property_ui_text(prop, "Use Cache", "");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+
+ /* whether this surface has preview data for 3D view */
+ RNA_define_verify_sdna(FALSE);
+ prop = RNA_def_property(srna, "use_color_preview", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_DynamicPaint_use_color_preview_get", NULL);
+ RNA_def_property_ui_text(prop, "Use Color Preview", "Whether this surface has some color preview for 3D view");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+ RNA_define_verify_sdna(TRUE);
}
static void rna_def_dynamic_paint_canvas_settings(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 4250acf5848..a91832268e2 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -116,7 +116,7 @@ static void rna_ChannelDriver_update_data(Main *bmain, Scene *scene, PointerRNA
driver->flag &= ~DRIVER_FLAG_INVALID;
/* TODO: this really needs an update guard... */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA);
WM_main_add_notifier(NC_SCENE | ND_FRAME, scene);
@@ -633,6 +633,81 @@ static void rna_fcurve_range(FCurve *fcu, float range[2])
calc_fcurve_range(fcu, range, range + 1, FALSE, FALSE);
}
+
+static FCM_EnvelopeData *rna_FModifierEnvelope_points_add(FModifier *fmod, ReportList *reports, float frame)
+{
+ FCM_EnvelopeData fed;
+ FMod_Envelope *env = (FMod_Envelope *)fmod->data;
+ int i;
+
+ /* init template data */
+ fed.min = -1.0f;
+ fed.max = 1.0f;
+ fed.time = frame;
+ fed.f1 = fed.f2 = 0;
+
+ if (env->data) {
+ short exists = -1;
+ i = BKE_fcm_envelope_find_index(env->data, frame, env->totvert, &exists);
+ if (exists) {
+ BKE_reportf(reports, RPT_ERROR, "Already a control point at frame %.6f", frame);
+ return NULL;
+ }
+
+ /* realloc memory for extra point */
+ env->data = (FCM_EnvelopeData *) MEM_reallocN((void *)env->data, (env->totvert + 1) * sizeof(FCM_EnvelopeData));
+
+ /* move the points after the added point */
+ if (i < env->totvert) {
+ memmove(env->data + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
+ }
+
+ env->totvert++;
+ }
+ else {
+ env->data = MEM_mallocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+ env->totvert = 1;
+ i = 0;
+ }
+
+ /* add point to paste at index i */
+ *(env->data + i) = fed;
+ return (env->data + i);
+}
+
+void rna_FModifierEnvelope_points_remove(FModifier *fmod, ReportList *reports, PointerRNA *point)
+{
+ FCM_EnvelopeData *cp = point->data;
+ FMod_Envelope *env = (FMod_Envelope *)fmod->data;
+
+ int index = (int)(cp - env->data);
+
+ /* test point is in range */
+ if (index < 0 || index >= env->totvert) {
+ BKE_report(reports, RPT_ERROR, "Control point not in Envelope F-Modifier");
+ return;
+ }
+
+ if (env->totvert > 1) {
+ /* move data after the removed point */
+
+ memmove(env->data + index, env->data + (index + 1), sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
+
+ /* realloc smaller array */
+ env->totvert--;
+ env->data = (FCM_EnvelopeData *) MEM_reallocN((void *)env->data, (env->totvert) * sizeof(FCM_EnvelopeData));
+ }
+ else {
+ /* just free array, since the only vert was deleted */
+ if (env->data) {
+ MEM_freeN(env->data);
+ env->data = NULL;
+ }
+ env->totvert = 0;
+ }
+ RNA_POINTER_INVALIDATE(point);
+}
+
#else
static void rna_def_fmodifier_generator(BlenderRNA *brna)
@@ -770,6 +845,36 @@ static void rna_def_fmodifier_envelope_ctrl(BlenderRNA *brna)
/* - selection flags (not implemented in UI yet though) */
}
+static void rna_def_fmodifier_envelope_control_points(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "FModifierEnvelopeControlPoints");
+ srna = RNA_def_struct(brna, "FModifierEnvelopeControlPoints", NULL);
+ RNA_def_struct_sdna(srna, "FModifier");
+
+ RNA_def_struct_ui_text(srna, "Control Points", "Control points defining the shape of the envelope");
+
+ func = RNA_def_function(srna, "add", "rna_FModifierEnvelope_points_add");
+ RNA_def_function_ui_description(func, "Add a control point to a FModifierEnvelope");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_float(func, "frame", 0.0f, -FLT_MAX, FLT_MAX, "",
+ "Frame to add this control-point", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "point", "FModifierEnvelopeControlPoint", "", "Newly created control-point");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_FModifierEnvelope_points_remove");
+ RNA_def_function_ui_description(func, "Remove a control-point from an FModifierEnvelope");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "point", "FModifierEnvelopeControlPoint", "", "Control-point to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+}
+
+
static void rna_def_fmodifier_envelope(BlenderRNA *brna)
{
StructRNA *srna;
@@ -784,6 +889,7 @@ static void rna_def_fmodifier_envelope(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "data", "totvert");
RNA_def_property_struct_type(prop, "FModifierEnvelopeControlPoint");
RNA_def_property_ui_text(prop, "Control Points", "Control points defining the shape of the envelope");
+ rna_def_fmodifier_envelope_control_points(brna, prop);
/* Range Settings */
prop = RNA_def_property(srna, "reference_value", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index b3c1f4dd505..9461a816652 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -118,7 +118,7 @@ static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count)
if (stroke->points == NULL)
stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points");
else
- stroke->points = MEM_reallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count));
+ stroke->points = MEM_recallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count));
stroke->totpoints += count;
}
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 9fedbee41ff..be462e20ee7 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -88,11 +88,15 @@ static int rna_Image_dirty_get(PointerRNA *ptr)
return 0;
}
-static void rna_Image_source_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_Image_source_set(PointerRNA *ptr, int value)
{
Image *ima = ptr->id.data;
- BKE_image_signal(ima, NULL, IMA_SIGNAL_SRC_CHANGE);
- DAG_id_tag_update(&ima->id, 0);
+
+ if (value != ima->source) {
+ ima->source = value;
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_SRC_CHANGE);
+ DAG_id_tag_update(&ima->id, 0);
+ }
}
static void rna_Image_fields_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -116,15 +120,6 @@ static void rna_Image_fields_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
BKE_image_release_ibuf(ima, ibuf, lock);
}
-static void rna_Image_free_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
-{
- Image *ima = ptr->id.data;
- BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
- WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id);
- DAG_id_tag_update(&ima->id, 0);
-}
-
-
static void rna_Image_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Image *ima = ptr->id.data;
@@ -139,6 +134,15 @@ static void rna_Image_generated_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
}
+static void rna_Image_colormanage_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ Image *ima = ptr->id.data;
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_COLORMANAGE);
+ DAG_id_tag_update(&ima->id, 0);
+ WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id);
+ WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id);
+}
+
static void rna_ImageUser_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
{
ImageUser *iuser = ptr->data;
@@ -377,6 +381,38 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
BKE_image_release_ibuf(ima, ibuf, lock);
}
+static int rna_Image_channels_get(PointerRNA *ptr)
+{
+ Image *im = (Image *)ptr->data;
+ ImBuf *ibuf;
+ void *lock;
+ int channels = 0;
+
+ ibuf = BKE_image_acquire_ibuf(im, NULL, &lock);
+ if (ibuf)
+ channels = ibuf->channels;
+
+ BKE_image_release_ibuf(im, ibuf, lock);
+
+ return channels;
+}
+
+static int rna_Image_is_float_get(PointerRNA *ptr)
+{
+ Image *im = (Image *)ptr->data;
+ ImBuf *ibuf;
+ void *lock;
+ int is_float = FALSE;
+
+ ibuf = BKE_image_acquire_ibuf(im, NULL, &lock);
+ if (ibuf)
+ is_float = ibuf->rect_float != NULL;
+
+ BKE_image_release_ibuf(im, ibuf, lock);
+
+ return is_float;
+}
+
#else
static void rna_def_imageuser(BlenderRNA *brna)
@@ -395,6 +431,11 @@ static void rna_def_imageuser(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_ImageUser_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ prop = RNA_def_property(srna, "frame_current", PROP_INT, PROP_TIME);
+ RNA_def_property_int_sdna(prop, NULL, "framenr");
+ RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
+ RNA_def_property_ui_text(prop, "Current Frame", "Current frame number in image sequence or movie");
+
/* animation */
prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cycl", 0);
@@ -463,6 +504,11 @@ static void rna_def_image(BlenderRNA *brna)
{IMA_STD_FIELD, "ODD", 0, "Lower First", "Lower field first"},
{0, NULL, 0, NULL, NULL}
};
+ static const EnumPropertyItem alpha_mode_items[] = {
+ {IMA_ALPHA_STRAIGHT, "STRAIGHT", 0, "Straight", "Transparent RGB and alpha pixels are unmodified"},
+ {IMA_ALPHA_PREMUL, "PREMUL", 0, "Premultiplied", "Transparent RGB pixels are multiplied by the alpha channel"},
+ {0, NULL, 0, NULL, NULL}
+ };
srna = RNA_def_struct(brna, "Image", "ID");
RNA_def_struct_ui_text(srna, "Image", "Image datablock referencing an external or packed image");
@@ -485,9 +531,9 @@ static void rna_def_image(BlenderRNA *brna)
prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, image_source_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Image_source_itemf");
+ RNA_def_property_enum_funcs(prop, NULL, "rna_Image_source_set", "rna_Image_source_itemf");
RNA_def_property_ui_text(prop, "Source", "Where the image comes from");
- RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_source_update");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_type_items);
@@ -512,23 +558,17 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_fields_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- prop = RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DO_PREMUL);
- RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha");
- RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_free_update");
-
- prop = RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_CM_PREDIVIDE);
- RNA_def_property_ui_text(prop, "Color Unpremultiply",
- "For premultiplied alpha images, do color space conversion on colors without alpha, "
- "to avoid fringing for images with light backgrounds");
- RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_free_update");
prop = RNA_def_property(srna, "view_as_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_VIEW_AS_RENDER);
RNA_def_property_ui_text(prop, "View as Render", "Apply render part of display transformation when displaying this image on the screen");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
+ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMA_IGNORE_ALPHA);
+ 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, "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);
@@ -544,14 +584,14 @@ static void rna_def_image(BlenderRNA *brna)
prop = RNA_def_property(srna, "generated_width", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gen_x");
- RNA_def_property_range(prop, 1, 16384);
+ RNA_def_property_range(prop, 1, 65536);
RNA_def_property_ui_text(prop, "Generated Width", "Generated image width");
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_height", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gen_y");
- RNA_def_property_range(prop, 1, 16384);
+ RNA_def_property_range(prop, 1, 65536);
RNA_def_property_ui_text(prop, "Generated Height", "Generated image height");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -665,6 +705,10 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Duration", "Duration (in frames) of the image (1 when not a video/sequence)");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ /* NOTE about pixels/channels/is_floa:
+ * this properties describes how image is stored internally (inside of ImBuf),
+ * not how it was saved to disk or how it'll be saved on disk
+ */
prop = RNA_def_property(srna, "pixels", PROP_FLOAT, PROP_NONE);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_multi_array(prop, 1, NULL);
@@ -672,11 +716,26 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_dynamic_array_funcs(prop, "rna_Image_pixels_get_length");
RNA_def_property_float_funcs(prop, "rna_Image_pixels_get", "rna_Image_pixels_set", NULL);
+ prop = RNA_def_property(srna, "channels", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop, "rna_Image_channels_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Channels", "Number of channels in pixels buffer");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "is_float", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_Image_is_float_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Is Float", "True if this image is stored in float buffer");
+
prop = RNA_def_property(srna, "colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedInputColorspaceSettings");
RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
+ prop = RNA_def_property(srna, "alpha_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, alpha_mode_items);
+ RNA_def_property_ui_text(prop, "Alpha Mode", "Representation of alpha information in the RGBA pixels");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
+
RNA_api_image(srna);
}
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 686e6c80f1d..5d45e0d23b6 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -318,9 +318,9 @@ void RNA_api_image(StructRNA *srna)
RNA_def_function_ui_description(func, "Delay the image from being cleaned from the cache due inactivity");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_int(func, "filter", GL_LINEAR_MIPMAP_NEAREST, -INT_MAX, INT_MAX, "Filter",
- "The texture minifying function to use if the image wan't loaded", -INT_MAX, INT_MAX);
+ "The texture minifying function to use if the image wasn't loaded", -INT_MAX, INT_MAX);
RNA_def_int(func, "mag", GL_LINEAR, -INT_MAX, INT_MAX, "Magnification",
- "The texture magnification function to use if the image wan't loaded", -INT_MAX, INT_MAX);
+ "The texture magnification function to use if the image wasn't loaded", -INT_MAX, INT_MAX);
/* return value */
parm = RNA_def_int(func, "error", 0, -INT_MAX, INT_MAX, "Error", "OpenGL error value", -INT_MAX, INT_MAX);
RNA_def_function_return(func, parm);
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 6520f22fbf5..9161f7932e6 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -117,7 +117,7 @@ typedef struct BlenderDefRNA {
ListBase structs;
ListBase allocs;
struct StructRNA *laststruct;
- int error, silent, preprocess, verify;
+ int error, silent, preprocess, verify, animate;
} BlenderDefRNA;
extern BlenderDefRNA DefRNA;
@@ -164,6 +164,7 @@ void RNA_def_packedfile(struct BlenderRNA *brna);
void RNA_def_particle(struct BlenderRNA *brna);
void RNA_def_pose(struct BlenderRNA *brna);
void RNA_def_render(struct BlenderRNA *brna);
+void RNA_def_rigidbody(struct BlenderRNA *brna);
void RNA_def_rna(struct BlenderRNA *brna);
void RNA_def_scene(struct BlenderRNA *brna);
void RNA_def_screen(struct BlenderRNA *brna);
@@ -263,6 +264,7 @@ void RNA_api_keymapitems(struct StructRNA *srna);
void RNA_api_main(struct StructRNA *srna);
void RNA_api_material(StructRNA *srna);
void RNA_api_mesh(struct StructRNA *srna);
+void RNA_api_meta(struct StructRNA *srna);
void RNA_api_object(struct StructRNA *srna);
void RNA_api_object_base(struct StructRNA *srna);
void RNA_api_pose(struct StructRNA *srna);
@@ -397,6 +399,10 @@ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA *
int rna_parameter_size(struct PropertyRNA *parm);
int rna_parameter_size_alloc(struct PropertyRNA *parm);
+struct Mesh *rna_Main_meshes_new_from_object(
+ struct Main *bmain, struct ReportList *reports, struct Scene *sce,
+ struct Object *ob, int apply_modifiers, int settings, int calc_tessface);
+
/* XXX, these should not need to be defined here~! */
struct MTex *rna_mtex_texture_slots_add(struct ID *self, struct bContext *C, struct ReportList *reports);
struct MTex *rna_mtex_texture_slots_create(struct ID *self, struct bContext *C, struct ReportList *reports, int index);
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index ccfb83b61e3..43ec09de010 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -30,6 +30,8 @@
#include "DNA_listBase.h"
+#include "RNA_types.h"
+
struct BlenderRNA;
struct ContainerRNA;
struct StructRNA;
@@ -64,7 +66,7 @@ typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr
typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
typedef int (*EditableFunc)(struct PointerRNA *ptr);
typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index);
-typedef struct IDProperty* (*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
+typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
typedef char *(*StructPathFunc)(struct PointerRNA *ptr);
@@ -91,7 +93,7 @@ typedef void (*PropEnumSetFunc)(struct PointerRNA *ptr, int value);
typedef EnumPropertyItem *(*PropEnumItemFunc)(struct bContext *C, struct PointerRNA *ptr,
struct PropertyRNA *prop, int *free);
typedef PointerRNA (*PropPointerGetFunc)(struct PointerRNA *ptr);
-typedef StructRNA* (*PropPointerTypeFunc)(struct PointerRNA *ptr);
+typedef StructRNA *(*PropPointerTypeFunc)(struct PointerRNA *ptr);
typedef void (*PropPointerSetFunc)(struct PointerRNA *ptr, const PointerRNA value);
typedef int (*PropPointerPollFunc)(struct PointerRNA *ptr, const PointerRNA value);
typedef void (*PropCollectionBeginFunc)(struct CollectionPropertyIterator *iter, struct PointerRNA *ptr);
@@ -103,6 +105,27 @@ typedef int (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key, stru
typedef int (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key, struct PointerRNA *r_ptr);
typedef int (*PropCollectionAssignIntFunc)(struct PointerRNA *ptr, int key, const struct PointerRNA *assign_ptr);
+/* extended versions with PropertyRNA argument */
+typedef int (*PropBooleanGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropBooleanSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*PropBooleanArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*PropBooleanArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef int (*PropIntGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropIntSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*PropIntArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*PropIntArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef void (*PropIntRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax);
+typedef float (*PropFloatGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropFloatSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value);
+typedef void (*PropFloatArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values);
+typedef void (*PropFloatArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values);
+typedef void (*PropFloatRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax);
+typedef void (*PropStringGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value);
+typedef int (*PropStringLengthFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropStringSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value);
+typedef int (*PropEnumGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropEnumSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+
/* Container - generic abstracted container of RNA properties */
typedef struct ContainerRNA {
void *next, *prev;
@@ -193,10 +216,14 @@ typedef struct BoolPropertyRNA {
PropBooleanGetFunc get;
PropBooleanSetFunc set;
-
PropBooleanArrayGetFunc getarray;
PropBooleanArraySetFunc setarray;
+ PropBooleanGetFuncEx get_ex;
+ PropBooleanSetFuncEx set_ex;
+ PropBooleanArrayGetFuncEx getarray_ex;
+ PropBooleanArraySetFuncEx setarray_ex;
+
int defaultvalue;
const int *defaultarray;
} BoolPropertyRNA;
@@ -206,12 +233,16 @@ typedef struct IntPropertyRNA {
PropIntGetFunc get;
PropIntSetFunc set;
-
PropIntArrayGetFunc getarray;
PropIntArraySetFunc setarray;
-
PropIntRangeFunc range;
+ PropIntGetFuncEx get_ex;
+ PropIntSetFuncEx set_ex;
+ PropIntArrayGetFuncEx getarray_ex;
+ PropIntArraySetFuncEx setarray_ex;
+ PropIntRangeFuncEx range_ex;
+
int softmin, softmax;
int hardmin, hardmax;
int step;
@@ -225,12 +256,16 @@ typedef struct FloatPropertyRNA {
PropFloatGetFunc get;
PropFloatSetFunc set;
-
PropFloatArrayGetFunc getarray;
PropFloatArraySetFunc setarray;
-
PropFloatRangeFunc range;
+ PropFloatGetFuncEx get_ex;
+ PropFloatSetFuncEx set_ex;
+ PropFloatArrayGetFuncEx getarray_ex;
+ PropFloatArraySetFuncEx setarray_ex;
+ PropFloatRangeFuncEx range_ex;
+
float softmin, softmax;
float hardmin, hardmax;
float step;
@@ -247,6 +282,10 @@ typedef struct StringPropertyRNA {
PropStringLengthFunc length;
PropStringSetFunc set;
+ PropStringGetFuncEx get_ex;
+ PropStringLengthFuncEx length_ex;
+ PropStringSetFuncEx set_ex;
+
int maxlength; /* includes string terminator! */
const char *defaultvalue;
@@ -258,6 +297,9 @@ typedef struct EnumPropertyRNA {
PropEnumGetFunc get;
PropEnumSetFunc set;
PropEnumItemFunc itemf;
+
+ PropEnumGetFuncEx get_ex;
+ PropEnumSetFuncEx set_ex;
void *py_data; /* store py callback here */
EnumPropertyItem *item;
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index af39500442d..660f6fc6ab7 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -54,7 +54,7 @@ static void rna_Lamp_buffer_size_set(PointerRNA *ptr, int value)
{
Lamp *la = (Lamp *)ptr->data;
- CLAMP(value, 512, 10240);
+ CLAMP(value, 128, 10240);
la->bufsize = value;
la->bufsize &= (~15); /* round to multiple of 16 */
}
@@ -540,7 +540,7 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area)
prop = RNA_def_property(srna, "shadow_buffer_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "bufsize");
- RNA_def_property_range(prop, 512, 10240);
+ RNA_def_property_range(prop, 128, 10240);
RNA_def_property_ui_text(prop, "Shadow Buffer Size",
"Resolution of the shadow buffer, higher values give crisper shadows "
"but use more memory");
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index cf9415a75e7..7175c8eab78 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -34,8 +34,10 @@
#include <errno.h>
#include "DNA_ID.h"
+#include "DNA_modifier_types.h"
#include "BLI_path_util.h"
+#include "BLI_utildefines.h"
#include "RNA_define.h"
#include "RNA_access.h"
@@ -48,6 +50,8 @@
#include "BKE_main.h"
#include "BKE_camera.h"
#include "BKE_curve.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
#include "BKE_mesh.h"
#include "BKE_armature.h"
#include "BKE_lamp.h"
@@ -99,9 +103,9 @@
#include "BLF_translation.h"
-static Camera *rna_Main_cameras_new(Main *UNUSED(bmain), const char *name)
+static Camera *rna_Main_cameras_new(Main *bmain, const char *name)
{
- ID *id = BKE_camera_add(name);
+ ID *id = BKE_camera_add(bmain, name);
id_us_min(id);
return (Camera *)id;
}
@@ -118,9 +122,9 @@ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static Scene *rna_Main_scenes_new(Main *UNUSED(bmain), const char *name)
+static Scene *rna_Main_scenes_new(Main *bmain, const char *name)
{
- return BKE_scene_add(name);
+ return BKE_scene_add(bmain, name);
}
static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr)
{
@@ -144,7 +148,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports
}
}
-static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, const char *name, ID *data)
+static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char *name, ID *data)
{
Object *ob;
int type = OB_EMPTY;
@@ -189,7 +193,7 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co
id_us_plus(data);
}
- ob = BKE_object_add_only_object(type, name);
+ ob = BKE_object_add_only_object(bmain, type, name);
id_us_min(&ob->id);
ob->data = data;
@@ -212,9 +216,9 @@ static void rna_Main_objects_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static Material *rna_Main_materials_new(Main *UNUSED(bmain), const char *name)
+static Material *rna_Main_materials_new(Main *bmain, const char *name)
{
- ID *id = (ID *)BKE_material_add(name);
+ ID *id = (ID *)BKE_material_add(bmain, name);
id_us_min(id);
return (Material *)id;
}
@@ -231,9 +235,9 @@ static void rna_Main_materials_remove(Main *bmain, ReportList *reports, PointerR
}
}
-static bNodeTree *rna_Main_nodetree_new(Main *UNUSED(bmain), const char *name, int type)
+static bNodeTree *rna_Main_nodetree_new(Main *bmain, const char *name, int type)
{
- bNodeTree *tree = ntreeAddTree(name, type, NODE_GROUP);
+ bNodeTree *tree = ntreeAddTree(bmain, name, type, NODE_GROUP);
id_us_min(&tree->id);
return tree;
@@ -251,12 +255,211 @@ static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, PointerRN
}
}
-static Mesh *rna_Main_meshes_new(Main *UNUSED(bmain), const char *name)
+static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
{
- Mesh *me = BKE_mesh_add(name);
+ Mesh *me = BKE_mesh_add(bmain, name);
id_us_min(&me->id);
return me;
}
+
+/* copied from Mesh_getFromObject and adapted to RNA interface */
+/* settings: 1 - preview, 2 - render */
+Mesh *rna_Main_meshes_new_from_object(
+ Main *bmain, ReportList *reports, Scene *sce,
+ Object *ob, int apply_modifiers, int settings, int calc_tessface)
+{
+ Mesh *tmpmesh;
+ Curve *tmpcu = NULL, *copycu;
+ Object *tmpobj = NULL;
+ int render = settings == eModifierMode_Render, i;
+ int cage = !apply_modifiers;
+
+ /* perform the mesh extraction based on type */
+ switch (ob->type) {
+ case OB_FONT:
+ case OB_CURVE:
+ case OB_SURF:
+ {
+ ListBase dispbase = {NULL, NULL};
+ DerivedMesh *derivedFinal = NULL;
+ int uv_from_orco;
+
+ /* copies object and modifiers (but not the data) */
+ tmpobj = BKE_object_copy_ex(bmain, ob, TRUE);
+ tmpcu = (Curve *)tmpobj->data;
+ tmpcu->id.us--;
+
+ /* if getting the original caged mesh, delete object modifiers */
+ if (cage)
+ BKE_object_free_modifiers(tmpobj);
+
+ /* copies the data */
+ copycu = tmpobj->data = BKE_curve_copy((Curve *) ob->data);
+
+ /* temporarily set edit so we get updates from edit mode, but
+ * also because for text datablocks copying it while in edit
+ * mode gives invalid data structures */
+ copycu->editfont = tmpcu->editfont;
+ copycu->editnurb = tmpcu->editnurb;
+
+ /* get updated display list, and convert to a mesh */
+ BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE);
+
+ copycu->editfont = NULL;
+ copycu->editnurb = NULL;
+
+ tmpobj->derivedFinal = derivedFinal;
+
+ /* convert object type to mesh */
+ uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
+ BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
+
+ tmpmesh = tmpobj->data;
+
+ BKE_displist_free(&dispbase);
+
+ /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */
+ if (tmpobj->type != OB_MESH) {
+ BKE_libblock_free_us(&(G.main->object), tmpobj);
+ BKE_report(reports, RPT_ERROR, "Cannot convert curve to mesh (does the curve have any segments?)");
+ return NULL;
+ }
+
+ BKE_libblock_free_us(&bmain->object, tmpobj);
+ break;
+ }
+
+ case OB_MBALL:
+ {
+ /* metaballs don't have modifiers, so just convert to mesh */
+ Object *basis_ob = BKE_mball_basis_find(sce, ob);
+ /* todo, re-generatre for render-res */
+ /* metaball_polygonize(scene, ob) */
+
+ if (ob != basis_ob)
+ return NULL; /* only do basis metaball */
+
+ tmpmesh = BKE_mesh_add(bmain, "Mesh");
+ /* BKE_mesh_add gives us a user count we don't need */
+ tmpmesh->id.us--;
+
+ if (render) {
+ ListBase disp = {NULL, NULL};
+ BKE_displist_make_mball_forRender(sce, ob, &disp);
+ BKE_mesh_from_metaball(&disp, tmpmesh);
+ BKE_displist_free(&disp);
+ }
+ else
+ BKE_mesh_from_metaball(&ob->disp, tmpmesh);
+
+ break;
+
+ }
+ case OB_MESH:
+ /* copies object and modifiers (but not the data) */
+ if (cage) {
+ /* copies the data */
+ tmpmesh = BKE_mesh_copy_ex(bmain, ob->data);
+ /* if not getting the original caged mesh, get final derived mesh */
+ }
+ else {
+ /* Make a dummy mesh, saves copying */
+ DerivedMesh *dm;
+ /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
+ CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
+ * for example, needs CD_MASK_MDEFORMVERT */
+
+ /* Write the display mesh into the dummy mesh */
+ if (render)
+ dm = mesh_create_derived_render(sce, ob, mask);
+ else
+ dm = mesh_create_derived_view(sce, ob, mask);
+
+ tmpmesh = BKE_mesh_add(bmain, "Mesh");
+ DM_to_mesh(dm, tmpmesh, ob);
+ dm->release(dm);
+ }
+
+ /* BKE_mesh_add/copy gives us a user count we don't need */
+ tmpmesh->id.us--;
+
+ break;
+ default:
+ BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
+ return NULL;
+ }
+
+ /* Copy materials to new mesh */
+ switch (ob->type) {
+ case OB_SURF:
+ case OB_FONT:
+ case OB_CURVE:
+ tmpmesh->totcol = tmpcu->totcol;
+
+ /* free old material list (if it exists) and adjust user counts */
+ if (tmpcu->mat) {
+ for (i = tmpcu->totcol; i-- > 0; ) {
+ /* are we an object material or data based? */
+
+ tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
+
+ if (tmpmesh->mat[i]) {
+ tmpmesh->mat[i]->id.us++;
+ }
+ }
+ }
+ break;
+
+#if 0
+ /* Crashes when assigning the new material, not sure why */
+ case OB_MBALL:
+ tmpmb = (MetaBall *)ob->data;
+ tmpmesh->totcol = tmpmb->totcol;
+
+ /* free old material list (if it exists) and adjust user counts */
+ if (tmpmb->mat) {
+ for (i = tmpmb->totcol; i-- > 0; ) {
+ tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
+ if (tmpmesh->mat[i]) {
+ tmpmb->mat[i]->id.us++;
+ }
+ }
+ }
+ break;
+#endif
+
+ case OB_MESH:
+ if (!cage) {
+ Mesh *origmesh = ob->data;
+ tmpmesh->flag = origmesh->flag;
+ tmpmesh->mat = MEM_dupallocN(origmesh->mat);
+ tmpmesh->totcol = origmesh->totcol;
+ tmpmesh->smoothresh = origmesh->smoothresh;
+ if (origmesh->mat) {
+ for (i = origmesh->totcol; i-- > 0; ) {
+ /* are we an object material or data based? */
+ tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
+
+ if (tmpmesh->mat[i]) {
+ tmpmesh->mat[i]->id.us++;
+ }
+ }
+ }
+ }
+ break;
+ } /* end copy materials */
+
+ if (calc_tessface) {
+ /* cycles and exporters rely on this still */
+ BKE_mesh_tessface_ensure(tmpmesh);
+ }
+
+ /* make sure materials get updated in objects */
+ test_object_materials(&tmpmesh->id);
+
+ return tmpmesh;
+}
+
static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr)
{
Mesh *mesh = mesh_ptr->data;
@@ -270,9 +473,9 @@ static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static Lamp *rna_Main_lamps_new(Main *UNUSED(bmain), const char *name, int type)
+static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type)
{
- Lamp *lamp = BKE_lamp_add(name);
+ Lamp *lamp = BKE_lamp_add(bmain, name);
lamp->type = type;
id_us_min(&lamp->id);
return lamp;
@@ -290,19 +493,19 @@ static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, PointerRNA *
}
}
-static Image *rna_Main_images_new(Main *UNUSED(bmain), const char *name, int width, int height, int alpha, int float_buffer)
+static Image *rna_Main_images_new(Main *bmain, const char *name, int width, int height, int alpha, int float_buffer)
{
float color[4] = {0.0, 0.0, 0.0, 1.0};
- Image *image = BKE_image_add_generated(width, height, name, alpha ? 32 : 24, float_buffer, 0, color);
+ Image *image = BKE_image_add_generated(bmain, width, height, name, alpha ? 32 : 24, float_buffer, 0, color);
id_us_min(&image->id);
return image;
}
-static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath)
+static Image *rna_Main_images_load(Main *bmain, ReportList *reports, const char *filepath)
{
Image *ima;
errno = 0;
- ima = BKE_image_load(filepath);
+ ima = BKE_image_load(bmain, filepath);
if (!ima) {
BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
@@ -324,9 +527,9 @@ static void rna_Main_images_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static Lattice *rna_Main_lattices_new(Main *UNUSED(bmain), const char *name)
+static Lattice *rna_Main_lattices_new(Main *bmain, const char *name)
{
- Lattice *lt = BKE_lattice_add(name);
+ Lattice *lt = BKE_lattice_add(bmain, name);
id_us_min(&lt->id);
return lt;
}
@@ -343,9 +546,9 @@ static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, PointerRN
}
}
-static Curve *rna_Main_curves_new(Main *UNUSED(bmain), const char *name, int type)
+static Curve *rna_Main_curves_new(Main *bmain, const char *name, int type)
{
- Curve *cu = BKE_curve_add(name, type);
+ Curve *cu = BKE_curve_add(bmain, name, type);
id_us_min(&cu->id);
return cu;
}
@@ -362,9 +565,9 @@ static void rna_Main_curves_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static MetaBall *rna_Main_metaballs_new(Main *UNUSED(bmain), const char *name)
+static MetaBall *rna_Main_metaballs_new(Main *bmain, const char *name)
{
- MetaBall *mb = BKE_mball_add(name);
+ MetaBall *mb = BKE_mball_add(bmain, name);
id_us_min(&mb->id);
return mb;
}
@@ -408,9 +611,9 @@ static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, PointerRNA *
}
}
-static Tex *rna_Main_textures_new(Main *UNUSED(bmain), const char *name, int type)
+static Tex *rna_Main_textures_new(Main *bmain, const char *name, int type)
{
- Tex *tex = add_texture(name);
+ Tex *tex = add_texture(bmain, name);
tex_set_type(tex, type);
id_us_min(&tex->id);
return tex;
@@ -428,9 +631,9 @@ static void rna_Main_textures_remove(Main *bmain, ReportList *reports, PointerRN
}
}
-static Brush *rna_Main_brushes_new(Main *UNUSED(bmain), const char *name)
+static Brush *rna_Main_brushes_new(Main *bmain, const char *name)
{
- Brush *brush = BKE_brush_add(name);
+ Brush *brush = BKE_brush_add(bmain, name);
id_us_min(&brush->id);
return brush;
}
@@ -447,9 +650,9 @@ static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static World *rna_Main_worlds_new(Main *UNUSED(bmain), const char *name)
+static World *rna_Main_worlds_new(Main *bmain, const char *name)
{
- World *world = add_world(name);
+ World *world = add_world(bmain, name);
id_us_min(&world->id);
return world;
}
@@ -466,9 +669,9 @@ static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static Group *rna_Main_groups_new(Main *UNUSED(bmain), const char *name)
+static Group *rna_Main_groups_new(Main *bmain, const char *name)
{
- return add_group(name);
+ return add_group(bmain, name);
}
static void rna_Main_groups_remove(Main *bmain, PointerRNA *group_ptr)
{
@@ -478,9 +681,9 @@ static void rna_Main_groups_remove(Main *bmain, PointerRNA *group_ptr)
RNA_POINTER_INVALIDATE(group_ptr);
}
-static Speaker *rna_Main_speakers_new(Main *UNUSED(bmain), const char *name)
+static Speaker *rna_Main_speakers_new(Main *bmain, const char *name)
{
- Speaker *speaker = BKE_speaker_add(name);
+ Speaker *speaker = BKE_speaker_add(bmain, name);
id_us_min(&speaker->id);
return speaker;
}
@@ -497,9 +700,9 @@ static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, PointerRN
}
}
-static Text *rna_Main_texts_new(Main *UNUSED(bmain), const char *name)
+static Text *rna_Main_texts_new(Main *bmain, const char *name)
{
- return BKE_text_add(name);
+ return BKE_text_add(bmain, name);
}
static void rna_Main_texts_remove(Main *bmain, PointerRNA *text_ptr)
{
@@ -514,7 +717,7 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f
Text *txt;
errno = 0;
- txt = BKE_text_load(filepath, bmain->name);
+ txt = BKE_text_load(bmain, filepath, bmain->name);
if (!txt)
BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
@@ -523,9 +726,9 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f
return txt;
}
-static bArmature *rna_Main_armatures_new(Main *UNUSED(bmain), const char *name)
+static bArmature *rna_Main_armatures_new(Main *bmain, const char *name)
{
- bArmature *arm = BKE_armature_add(name);
+ bArmature *arm = BKE_armature_add(bmain, name);
id_us_min(&arm->id);
return arm;
}
@@ -542,9 +745,9 @@ static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, PointerR
}
}
-static bAction *rna_Main_actions_new(Main *UNUSED(bmain), const char *name)
+static bAction *rna_Main_actions_new(Main *bmain, const char *name)
{
- bAction *act = add_empty_action(name);
+ bAction *act = add_empty_action(bmain, name);
id_us_min(&act->id);
act->id.flag &= ~LIB_FAKEUSER;
return act;
@@ -581,12 +784,12 @@ static void rna_Main_particles_remove(Main *bmain, ReportList *reports, PointerR
}
}
-static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath)
+static MovieClip *rna_Main_movieclip_load(Main *bmain, ReportList *reports, const char *filepath)
{
MovieClip *clip;
errno = 0;
- clip = BKE_movieclip_file_add(filepath);
+ clip = BKE_movieclip_file_add(bmain, filepath);
if (!clip)
BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
@@ -603,11 +806,11 @@ static void rna_Main_movieclips_remove(Main *bmain, PointerRNA *clip_ptr)
RNA_POINTER_INVALIDATE(clip_ptr);
}
-static Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name)
+static Mask *rna_Main_mask_new(Main *bmain, const char *name)
{
Mask *mask;
- mask = BKE_mask_new("Mask");
+ mask = BKE_mask_new(bmain, "Mask");
return mask;
}
@@ -910,6 +1113,12 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
PropertyRNA *parm;
PropertyRNA *prop;
+ static EnumPropertyItem mesh_type_items[] = {
+ {eModifierMode_Realtime, "PREVIEW", 0, "Preview", "Apply modifier preview settings"},
+ {eModifierMode_Render, "RENDER", 0, "Render", "Apply modifier render settings"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
RNA_def_property_srna(cprop, "BlendDataMeshes");
srna = RNA_def_struct(brna, "BlendDataMeshes", NULL);
RNA_def_struct_sdna(srna, "Main");
@@ -923,6 +1132,22 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh datablock");
RNA_def_function_return(func, parm);
+ func = RNA_def_function(srna, "new_from_object", "rna_Main_meshes_new_from_object");
+ RNA_def_function_ui_description(func, "Add a new mesh created from object with modifiers applied");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate modifiers");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ parm = RNA_def_pointer(func, "object", "Object", "", "Object to create mesh from");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ parm = RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces");
+ parm = RNA_def_pointer(func, "mesh", "Mesh", "",
+ "Mesh created from object, remove it if it is only used for export");
+ RNA_def_function_return(func, parm);
+
func = RNA_def_function(srna, "remove", "rna_Main_meshes_remove");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Remove a mesh from the current blendfile");
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 1221b84372c..35173c290de 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -114,7 +114,7 @@ static void rna_Material_update_previews(Main *bmain, Scene *scene, PointerRNA *
if (ma->nodetree)
ntreeClearPreview(ma->nodetree);
- rna_Material_update(bmain, scene, ptr);
+ WM_main_add_notifier(NC_MATERIAL | ND_SHADING, ma);
}
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 287995e0aa6..4b4006f0012 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -152,8 +152,8 @@ void rna_Mesh_update_draw(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Mesh *me = ptr->data;
- if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) {
- me->editflag ^= ME_EDIT_PAINT_MASK;
+ if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
+ me->editflag &= ~ME_EDIT_PAINT_FACE_SEL;
}
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -161,8 +161,8 @@ static void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Mesh_update_facemask(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Mesh *me = ptr->data;
- if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) {
- me->editflag ^= ME_EDIT_VERT_SEL;
+ if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
+ me->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
}
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -1233,6 +1233,26 @@ static char *rna_MeshStringProperty_path(PointerRNA *ptr)
return rna_PolyCustomData_data_path(ptr, "layers_string", CD_PROP_STR);
}
+/* XXX, we dont have propper byte string support yet, so for now use the (bytes + 1)
+ * bmesh API exposes correct python/bytestring access */
+void rna_MeshStringProperty_s_get(PointerRNA *ptr, char *value)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ BLI_strncpy(value, ms->s, (int)ms->s_len + 1);
+}
+
+int rna_MeshStringProperty_s_length(PointerRNA *ptr)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ return (int)ms->s_len + 1;
+}
+
+void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ BLI_strncpy(ms->s, value, sizeof(ms->s));
+}
+
static int rna_Mesh_tot_vert_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
@@ -2161,6 +2181,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
/* low level mesh data access, treat as bytes */
prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING);
RNA_def_property_string_sdna(prop, NULL, "s");
+ RNA_def_property_string_funcs(prop, "rna_MeshStringProperty_s_get", "rna_MeshStringProperty_s_length", "rna_MeshStringProperty_s_set");
RNA_def_property_ui_text(prop, "Value", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
@@ -2353,7 +2374,7 @@ static void rna_def_tessface_vertex_colors(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_RNAPTR);
RNA_def_function_return(func, parm);
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshColorLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_vertex_color_active_get",
"rna_Mesh_tessface_vertex_color_active_set", NULL, NULL);
@@ -2397,11 +2418,11 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
#endif
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshLoopColorLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_vertex_color_active_get",
"rna_Mesh_vertex_color_active_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active Vertex Color Layer", "Active vertex color layer");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
@@ -2425,11 +2446,11 @@ static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(srna, "UV Loop Layers", "Collection of uv loop layers");
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_active_get",
"rna_Mesh_uv_layer_active_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active UV loop layer", "Active UV loop layer");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
@@ -2530,7 +2551,7 @@ static void rna_def_tessface_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_return(func, parm);
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_uv_texture_active_get",
"rna_Mesh_tessface_uv_texture_active_set", NULL, NULL);
@@ -2575,11 +2596,11 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
#endif
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_active_get",
"rna_Mesh_uv_texture_active_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active UV Map", "Active UV Map");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
@@ -2693,7 +2714,7 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Loop Layers", "All UV loop layers");
rna_def_uv_layers(brna, prop);
- prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_clone_get",
"rna_Mesh_uv_layer_clone_set", NULL, NULL);
@@ -2705,7 +2726,7 @@ static void rna_def_mesh(BlenderRNA *brna)
"rna_Mesh_uv_layer_clone_index_set", "rna_Mesh_uv_layer_index_range");
RNA_def_property_ui_text(prop, "Clone UV loop layer Index", "Clone UV loop layer index");
- prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_stencil_get",
"rna_Mesh_uv_layer_stencil_set", NULL, NULL);
@@ -2736,7 +2757,7 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Maps", "All UV maps");
rna_def_uv_textures(brna, prop);
- prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_clone_get",
"rna_Mesh_uv_texture_clone_set", NULL, NULL);
@@ -2748,7 +2769,7 @@ static void rna_def_mesh(BlenderRNA *brna)
"rna_Mesh_uv_texture_clone_index_set", "rna_Mesh_uv_texture_index_range");
RNA_def_property_ui_text(prop, "Clone UV Map Index", "Clone UV map index");
- prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_stencil_get",
"rna_Mesh_uv_texture_stencil_set", NULL, NULL);
@@ -2879,11 +2900,6 @@ static void rna_def_mesh(BlenderRNA *brna)
"Display selected edges using highlights in the 3D view and UV editor");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
- prop = RNA_def_property(srna, "show_all_edges", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_ALLEDGES);
- RNA_def_property_ui_text(prop, "All Edges", "Display all edges for wireframe in all view modes in the 3D view");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
prop = RNA_def_property(srna, "show_faces", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWFACES);
RNA_def_property_ui_text(prop, "Draw Faces", "Display all faces as shades in the 3D view and UV editor");
@@ -2928,7 +2944,7 @@ static void rna_def_mesh(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_extra_face_angle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWEXTRA_FACEANG);
RNA_def_property_ui_text(prop, "Face Angles",
- "Display the angles in the selected edges in degrees, "
+ "Display the angles in the selected edges, "
"using global values when set in the transform panel");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
@@ -2966,17 +2982,33 @@ static void rna_def_mesh(BlenderRNA *brna)
"(for when both sides of mesh have matching, unique topology)");
prop = RNA_def_property(srna, "use_paint_mask", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_MASK);
+ RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_FACE_SEL);
RNA_def_property_ui_text(prop, "Paint Mask", "Face selection masking for painting");
RNA_def_property_ui_icon(prop, ICON_FACESEL_HLT, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_facemask");
prop = RNA_def_property(srna, "use_paint_mask_vertex", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_VERT_SEL);
+ RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_VERT_SEL);
RNA_def_property_ui_text(prop, "Vertex Selection", "Vertex selection masking for painting (weight paint only)");
RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask");
+
+
+ /* customdata flags */
+ prop = RNA_def_property(srna, "use_customdata_vertex_bevel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_BWEIGHT);
+ RNA_def_property_ui_text(prop, "Store Vertex Bevel Weight", "");
+
+ prop = RNA_def_property(srna, "use_customdata_edge_bevel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_BWEIGHT);
+ RNA_def_property_ui_text(prop, "Store Edge Bevel Weight", "");
+
+ prop = RNA_def_property(srna, "use_customdata_edge_crease", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_CREASE);
+ RNA_def_property_ui_text(prop, "Store Edge Crease", "");
+
+
/* readonly editmesh info - use for extrude menu */
prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 08eefc082bf..4813f25dea7 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -351,6 +351,8 @@ static void rna_def_metaball(BlenderRNA *brna)
/* anim */
rna_def_animdata_common(srna);
+
+ RNA_api_meta(srna);
}
void RNA_def_meta(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_meta_api.c b/source/blender/makesrna/intern/rna_meta_api.c
new file mode 100644
index 00000000000..500e202b16f
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_meta_api.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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_meta_api.c
+ * \ingroup RNA
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "RNA_define.h"
+
+#include "BLO_sys_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "ED_mball.h"
+
+#include "rna_internal.h" /* own include */
+
+#ifdef RNA_RUNTIME
+/* none */
+#else
+
+void RNA_api_meta(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func = RNA_def_function(srna, "transform", "ED_mball_transform");
+ RNA_def_function_ui_description(func, "Transform meta elements by a matrix");
+ parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index a2b0945fb46..810999033a4 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -58,7 +58,9 @@
EnumPropertyItem modifier_type_items[] = {
{0, "", 0, N_("Modify"), ""},
+ {eModifierType_MeshCache, "MESH_CACHE", ICON_MOD_MESHDEFORM, "Mesh Cache", ""},
{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", ""},
{eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""},
{eModifierType_WeightVGProximity, "VERTEX_WEIGHT_PROXIMITY", ICON_MOD_VERTEX_WEIGHT,
@@ -129,7 +131,7 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
{
ModifierData *md = (ModifierData *)ptr->data;
- switch (md->type) {
+ switch ((ModifierType)md->type) {
case eModifierType_Subsurf:
return &RNA_SubsurfModifier;
case eModifierType_Lattice:
@@ -216,9 +218,18 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_LaplacianSmoothModifier;
case eModifierType_Triangulate:
return &RNA_TriangulateModifier;
- default:
+ case eModifierType_UVWarp:
+ return &RNA_UVWarpModifier;
+ case eModifierType_MeshCache:
+ return &RNA_MeshCacheModifier;
+ /* Default */
+ case eModifierType_None:
+ case eModifierType_ShapeKey:
+ case NUM_MODIFIER_TYPES:
return &RNA_Modifier;
}
+
+ return &RNA_Modifier;
}
static void rna_Modifier_name_set(PointerRNA *ptr, const char *value)
@@ -256,7 +267,7 @@ static void rna_Modifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
static void rna_Modifier_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
rna_Modifier_update(bmain, scene, ptr);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -738,6 +749,24 @@ static void rna_BevelModifier_angle_limit_set(PointerRNA *ptr, float value)
md->bevel_angle = (int)value;
}
+static void rna_BevelModifier_defgrp_name_set(PointerRNA *ptr, const char *value)
+{
+ BevelModifierData *md = (BevelModifierData *)ptr->data;
+ rna_object_vgroup_name_set(ptr, value, md->defgrp_name, sizeof(md->defgrp_name));
+}
+
+static void rna_UVWarpModifier_vgroup_set(PointerRNA *ptr, const char *value)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)ptr->data;
+ rna_object_vgroup_name_set(ptr, value, umd->vgroup_name, sizeof(umd->vgroup_name));
+}
+
+static void rna_UVWarpModifier_uvlayer_set(PointerRNA *ptr, const char *value)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)ptr->data;
+ rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name));
+}
+
#else
static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[])
@@ -1646,7 +1675,7 @@ static void rna_def_modifier_displace(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DisplaceModifier_vgroup_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop = RNA_def_property(srna, "mid_level", PROP_FLOAT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "mid_level", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "midlevel");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
@@ -1820,18 +1849,23 @@ static void rna_def_modifier_laplaciansmooth(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME);
RNA_def_property_ui_text(prop, "Preserve Volume", "Apply volume preservation after smooth");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "use_normalized", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_LAPLACIANSMOOTH_NORMALIZED);
+ RNA_def_property_ui_text(prop, "Normalized", "Improve and stabilize the enhanced shape");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "lambda_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "lambda");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0000001, 1000.0, 0.0000001, 8);
+ RNA_def_property_ui_range(prop, -1000.0, 1000.0, 5, 3);
RNA_def_property_ui_text(prop, "Lambda Factor", "Smooth factor effect");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "lambda_border", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "lambda_border");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0000001, 1000.0, 0.0000001, 8);
+ RNA_def_property_ui_range(prop, -1000.0, 1000.0, 5, 3);
RNA_def_property_ui_text(prop, "Lambda Border", "Lambda factor in border");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -2263,11 +2297,13 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
{0, "NONE", 0, "None", "Bevel the entire mesh by a constant amount"},
{BME_BEVEL_ANGLE, "ANGLE", 0, "Angle", "Only bevel edges with sharp enough angles between faces"},
{BME_BEVEL_WEIGHT, "WEIGHT", 0, "Weight",
- "Use bevel weights to determine how much bevel is applied; "
- "apply them separately in vert/edge select mode"},
+ "Use bevel weights to determine how much bevel is applied in edge mode"},
+ {BME_BEVEL_VGROUP, "VGROUP", 0, "Vertex Group",
+ "Use vertex group weights to determine how much bevel is applied in vertex mode"},
{0, NULL, 0, NULL, NULL}
};
+ /* TO BE DEPRECATED */
static EnumPropertyItem prop_edge_weight_method_items[] = {
{0, "AVERAGE", 0, "Average", ""},
{BME_BEVEL_EMIN, "SHARPEST", 0, "Sharpest", ""},
@@ -2287,6 +2323,12 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Width", "Bevel value/amount");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "segments", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "res");
+ RNA_def_property_range(prop, 1, 100);
+ RNA_def_property_ui_text(prop, "Segments", "Number of segments for round edges/verts");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "use_only_vertices", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_VERT);
RNA_def_property_ui_text(prop, "Only Vertices", "Bevel verts/corners, not edges");
@@ -2298,6 +2340,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Limit Method", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ /* TO BE DEPRECATED */
prop = RNA_def_property(srna, "edge_weight_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "e_flags");
RNA_def_property_enum_items(prop, prop_edge_weight_method_items);
@@ -2320,15 +2363,10 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
#ifdef USE_BM_BEVEL_OP_AS_MOD
- prop = RNA_def_property(srna, "use_even_offset", PROP_BOOLEAN, PROP_NONE); /* name matches solidify */
- RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_EVEN);
- RNA_def_property_ui_text(prop, "Even", "Use even bevel distance correction");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
- prop = RNA_def_property(srna, "use_distance_offset", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_DIST);
- RNA_def_property_ui_text(prop, "Distance",
- "Use the width as a distance in rather then a factor of the face size");
+ 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");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_BevelModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
#endif
@@ -2773,6 +2811,75 @@ static void rna_def_modifier_screw(BlenderRNA *brna)
#endif
}
+static void rna_def_modifier_uvwarp(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem uvwarp_axis[] = {
+ {0, "X", 0, "X", ""},
+ {1, "Y", 0, "Y", ""},
+ {2, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "UVWarpModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "UVWarp Modifier", "Add target position to uv coordinates");
+ RNA_def_struct_sdna(srna, "UVWarpModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_UVPROJECT);
+
+ prop = RNA_def_property(srna, "axis_u", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "axis_u");
+ RNA_def_property_enum_items(prop, uvwarp_axis);
+ RNA_def_property_ui_text(prop, "U-Axis", "Pole axis for rotation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "axis_v", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "axis_v");
+ RNA_def_property_enum_items(prop, uvwarp_axis);
+ RNA_def_property_ui_text(prop, "V-Axis", "Pole axis for rotation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "center");
+ RNA_def_property_ui_text(prop, "UV Center", "Center point for rotate/scale");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ 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_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_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_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_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "vgroup_name");
+ RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_vgroup_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
+ RNA_def_property_ui_text(prop, "UV Layer", "UV Layer name");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_uvlayer_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *srna)
{
static EnumPropertyItem weightvg_mask_tex_map_items[] = {
@@ -3180,7 +3287,7 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "size");
- RNA_def_property_ui_text(prop, "Size", "");
+ RNA_def_property_ui_text(prop, "Size", "Surface scale factor (does not affect the height of the waves)");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
@@ -3221,16 +3328,17 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Resolution", "Resolution of the generated surface");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
- prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "spatial_size");
RNA_def_property_ui_range(prop, 1, 512, 2, 0);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Spatial Size", "Physical size of the simulation domain (m)");
+ RNA_def_property_ui_text(prop, "Spatial Size",
+ "Size of the simulation domain (in meters), and of the generated geometry (in BU)");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wind_velocity", PROP_FLOAT, PROP_VELOCITY);
RNA_def_property_float_sdna(prop, NULL, "wind_velocity");
- RNA_def_property_ui_text(prop, "Wind Velocity", "Wind speed (m/s)");
+ RNA_def_property_ui_text(prop, "Wind Velocity", "Wind speed");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "damping", PROP_FLOAT, PROP_FACTOR);
@@ -3243,42 +3351,43 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "smallest_wave");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0, FLT_MAX);
- RNA_def_property_ui_text(prop, "Smallest Wave", "Shortest allowed wavelength (m)");
+ RNA_def_property_ui_text(prop, "Smallest Wave", "Shortest allowed wavelength");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wave_alignment", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "wave_alignment");
RNA_def_property_range(prop, 0.0, 10.0);
- RNA_def_property_ui_text(prop, "Wave Alignment", "");
+ RNA_def_property_ui_text(prop, "Wave Alignment", "How much the waves are aligned to each other");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wave_direction", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "wave_direction");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Wave Direction", "");
+ RNA_def_property_ui_text(prop, "Wave Direction", "Main direction of the waves when they are (partially) aligned");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wave_scale", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "wave_scale");
- RNA_def_property_ui_text(prop, "Wave Scale", "");
+ RNA_def_property_ui_text(prop, "Wave Scale", "Scale of the displacement effect");
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
- prop = RNA_def_property(srna, "depth", PROP_FLOAT, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "depth", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "depth");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Depth", "");
+ RNA_def_property_ui_text(prop, "Depth", "Depth of the solid ground below the water surface");
RNA_def_property_ui_range(prop, 0, 250, 1, 0);
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "foam_coverage", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "foam_coverage");
- RNA_def_property_ui_text(prop, "Foam Coverage", "");
+ RNA_def_property_ui_text(prop, "Foam Coverage", "Amount of generated foam");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "bake_foam_fade", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "foam_fade");
- RNA_def_property_ui_text(prop, "Foam Fade", "");
- RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Foam Fade", "How much foam accumulates over time (baked ocean only)");
+ RNA_def_property_ui_range(prop, 0.0, 10.0, 1, 0);
RNA_def_property_update(prop, 0, NULL);
prop = RNA_def_property(srna, "foam_layer_name", PROP_STRING, PROP_NONE);
@@ -3288,33 +3397,34 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
prop = RNA_def_property(srna, "choppiness", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "chop_amount");
- RNA_def_property_ui_text(prop, "Choppiness", "");
+ RNA_def_property_ui_text(prop, "Choppiness",
+ "Choppiness of the wave's crest (adds some horizontal component to the displacement)");
RNA_def_property_ui_range(prop, 0.0, 4.0, 3, 0);
RNA_def_property_float_funcs(prop, NULL, "rna_OceanModifier_ocean_chop_set", NULL);
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
prop = RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "time");
- RNA_def_property_ui_text(prop, "Time", "");
+ RNA_def_property_ui_text(prop, "Time", "Current time of the simulation");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
prop = RNA_def_property(srna, "random_seed", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "seed");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Random Seed", "");
+ RNA_def_property_ui_text(prop, "Random Seed", "Seed of the random generator");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bakestart");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Bake Start", "");
+ RNA_def_property_ui_text(prop, "Bake Start", "Start frame of the ocean baking");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bakeend");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Bake End", "");
+ RNA_def_property_ui_text(prop, "Bake End", "End frame of the ocean baking");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "is_cached", PROP_BOOLEAN, PROP_NONE);
@@ -3381,6 +3491,158 @@ static void rna_def_modifier_triangulate(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
+static void rna_def_modifier_meshcache(BlenderRNA *brna)
+{
+ static EnumPropertyItem prop_format_type_items[] = {
+ {MOD_MESHCACHE_TYPE_MDD, "MDD", 0, "MDD ", ""},
+ {MOD_MESHCACHE_TYPE_PC2, "PC2", 0, "PC2", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_deform_mode_items[] = {
+ {MOD_MESHCACHE_DEFORM_OVERWRITE, "OVERWRITE", 0, "Overwrite",
+ "Replace vertex coords with cached values"},
+ {MOD_MESHCACHE_DEFORM_INTEGRATE, "INTEGRATE", 0, "Integrate",
+ "Integrate deformation from this modifiers input with the mesh-cache coords (useful for shape keys)"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_interpolation_type_items[] = {
+ {MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None ", ""},
+ {MOD_MESHCACHE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
+ /* for cardinal we'd need to read 4x cache's */
+ // {MOD_MESHCACHE_INTERP_CARDINAL, "CARDINAL", 0, "Cardinal", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_time_type_items[] = {
+ /* use 'eval_frame' */
+ {MOD_MESHCACHE_TIME_FRAME, "FRAME", 0, "Frame", "Control playback using a frame-number "
+ "(ignoring time FPS and start frame from the file)"},
+ /* use 'eval_time' */
+ {MOD_MESHCACHE_TIME_SECONDS, "TIME", 0, "Time", "Control playback using time in seconds"},
+ /* use 'eval_factor' */
+ {MOD_MESHCACHE_TIME_FACTOR, "FACTOR", 0, "Factor", "Control playback using a value between [0, 1]"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_time_play_items[] = {
+ {MOD_MESHCACHE_PLAY_CFEA, "SCENE", 0, "Scene", "Use the time from the scene"},
+ {MOD_MESHCACHE_PLAY_EVAL, "CUSTOM", 0, "Custom", "Use the modifier's own time evaluation"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_flip_axis_flag_items[] = {
+ {(1 << 0), "X", 0, "X", ""},
+ {(1 << 1), "Y", 0, "Y", ""},
+ {(1 << 2), "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "MeshCacheModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Cache Modifier", "Cache Mesh");
+ RNA_def_struct_sdna(srna, "MeshCacheModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_MESHDEFORM); /* XXX, needs own icon */
+
+ prop = RNA_def_property(srna, "cache_format", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, prop_format_type_items);
+ RNA_def_property_ui_text(prop, "Format", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "interp");
+ RNA_def_property_enum_items(prop, prop_interpolation_type_items);
+ RNA_def_property_ui_text(prop, "Interpolation", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "time_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "time_mode");
+ RNA_def_property_enum_items(prop, prop_time_type_items);
+ RNA_def_property_ui_text(prop, "Time Mode", "Method to control playback time");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "play_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "play_mode");
+ RNA_def_property_enum_items(prop, prop_time_play_items);
+ RNA_def_property_ui_text(prop, "Time Mode", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "deform_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "deform_mode");
+ RNA_def_property_enum_items(prop, prop_deform_mode_items);
+ RNA_def_property_ui_text(prop, "Deform Mode", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
+ RNA_def_property_ui_text(prop, "File Path", "Path to external displacements file");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "factor");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Influence", "Influence of the deformation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* -------------------------------------------------------------------- */
+ /* Axis Conversion */
+ prop = RNA_def_property(srna, "forward_axis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "forward_axis");
+ RNA_def_property_enum_items(prop, object_axis_items);
+ RNA_def_property_ui_text(prop, "Forward", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "up_axis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "up_axis");
+ RNA_def_property_enum_items(prop, object_axis_items);
+ RNA_def_property_ui_text(prop, "Up", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "flip_axis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "flip_axis");
+ RNA_def_property_enum_items(prop, prop_flip_axis_flag_items);
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_ui_text(prop, "Flip Axis", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* -------------------------------------------------------------------- */
+ /* For Scene time */
+ prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "frame_start");
+ RNA_def_property_range(prop, -MAXFRAME, MAXFRAME);
+ RNA_def_property_ui_text(prop, "Frame Start", "Add this to the start frame");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "frame_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "frame_scale");
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_text(prop, "Frame Scale", "Evaluation time in seconds");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* -------------------------------------------------------------------- */
+ /* eval values depend on 'time_mode' */
+ prop = RNA_def_property(srna, "eval_frame", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "eval_frame");
+ RNA_def_property_range(prop, MINFRAME, MAXFRAME);
+ RNA_def_property_ui_text(prop, "Evaluation Frame", "The frame to evaluate (starting at 0)");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "eval_time", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "eval_time");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Evaluation Time", "Evaluation time in seconds");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "eval_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "eval_factor");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Evaluation Factor", "Evaluation time in seconds");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3480,6 +3742,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_smoke(brna);
rna_def_modifier_solidify(brna);
rna_def_modifier_screw(brna);
+ rna_def_modifier_uvwarp(brna);
rna_def_modifier_weightvgedit(brna);
rna_def_modifier_weightvgmix(brna);
rna_def_modifier_weightvgproximity(brna);
@@ -3489,6 +3752,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_skin(brna);
rna_def_modifier_laplaciansmooth(brna);
rna_def_modifier_triangulate(brna);
+ rna_def_modifier_meshcache(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index 99effc990a8..3b018591455 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -308,7 +308,7 @@ static void rna_def_movieclip(BlenderRNA *brna)
/* color management */
prop = RNA_def_property(srna, "colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedInputColorspaceSettings");
RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
}
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 574f06e9107..2b7f6a182a0 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -115,7 +115,7 @@ static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
if (data->prev->type == NLASTRIP_TYPE_TRANSITION) {
CLAMP(value, data->prev->start + NLASTRIP_MIN_LEN_THRESH, data->end - NLASTRIP_MIN_LEN_THRESH);
- /* readjust the transition to stick to the endpoints of the action-clips */
+ /* re-adjust the transition to stick to the endpoints of the action-clips */
data->prev->end = value;
}
else {
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 1da9a450c2c..1fff567f25c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -271,6 +271,64 @@ static char *rna_Node_path(PointerRNA *ptr)
return BLI_sprintfN("nodes[\"%s\"]", node->name);
}
+static const char *rna_Node_get_node_type(StructRNA *type)
+{
+ bNodeType *nodetype = RNA_struct_blender_type_get(type);
+ if (nodetype) {
+ /* XXX hack: with customnodes branch, nodes will use an identifier string instead of integer ID.
+ * Then this can be returned directly instead of doing this ugly include thingy ...
+ */
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (ID == nodetype->type) { \
+ return EnumName; \
+ }
+
+ #include "rna_nodetree_types.h"
+ }
+ return "";
+}
+
+static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value)
+{
+ bNode *node = ptr->data;
+ bNode *parent = value.data;
+
+ if (parent) {
+ /* XXX only Frame node allowed for now,
+ * in the future should have a poll function or so to test possible attachment.
+ */
+ if (parent->type != NODE_FRAME)
+ return;
+
+ /* make sure parent is not attached to the node */
+ if (nodeAttachNodeCheck(parent, node))
+ return;
+ }
+
+ nodeDetachNode(node);
+ if (parent) {
+ nodeAttachNode(node, parent);
+ }
+}
+
+static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value)
+{
+ bNode *node = ptr->data;
+ bNode *parent = value.data;
+
+ /* XXX only Frame node allowed for now,
+ * in the future should have a poll function or so to test possible attachment.
+ */
+ if (parent->type != NODE_FRAME)
+ return FALSE;
+
+ /* make sure parent is not attached to the node */
+ if (nodeAttachNodeCheck(parent, node))
+ return FALSE;
+
+ return TRUE;
+}
+
static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
@@ -499,6 +557,20 @@ static void rna_Node_name_set(PointerRNA *ptr, const char *value)
BKE_all_animdata_fix_paths_rename(NULL, "nodes", oldname, node->name);
}
+static void rna_Node_width_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+{
+ bNode *node = ptr->data;
+ *min = *softmin = node->typeinfo->minwidth;
+ *max = *softmax = node->typeinfo->maxwidth;
+}
+
+static void rna_Node_height_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+{
+ bNode *node = ptr->data;
+ *min = *softmin = node->typeinfo->minheight;
+ *max = *softmax = node->typeinfo->maxheight;
+}
+
static void rna_NodeSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -1070,7 +1142,7 @@ static void rna_ShaderNodeScript_mode_set(PointerRNA *ptr, int value)
/* replace text datablock by filepath */
if (node->id) {
- Text *text = (Text*)node->id;
+ Text *text = (Text *)node->id;
if (value == NODE_SCRIPT_EXTERNAL && text->name) {
BLI_strncpy(nss->filepath, text->name, sizeof(nss->filepath));
@@ -1236,7 +1308,7 @@ static void reg_node(int ID, int category, const char *enum_name, const char *st
static void init(void)
{
- memset(nodes, 0, sizeof nodes);
+ memset(nodes, 0, sizeof(nodes));
#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
reg_node(ID, Category_##Category, EnumName, STRINGIFY_ARG(Category##StructName), #Category, UIName, UIDesc);
@@ -1251,12 +1323,20 @@ static void init(void)
static StructRNA *def_node(BlenderRNA *brna, int node_id)
{
StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
NodeInfo *node = nodes + node_id;
srna = RNA_def_struct(brna, node->struct_name, node->base_name);
RNA_def_struct_ui_text(srna, node->ui_name, node->ui_desc);
RNA_def_struct_sdna(srna, "bNode");
+ func = RNA_def_function(srna, "get_node_type", "rna_Node_get_node_type");
+ RNA_def_function_ui_description(func, "Get the identifier of the node type");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
+ parm = RNA_def_string(func, "result", "", 0, "Result", "");
+ RNA_def_function_return(func, parm);
+
return srna;
}
@@ -2441,7 +2521,7 @@ static void def_cmp_dilate_erode(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem type_items[] = {
+ static EnumPropertyItem mode_items[] = {
{CMP_NODE_DILATEERODE_STEP, "STEP", 0, "Step", ""},
{CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""},
{CMP_NODE_DILATEERODE_DISTANCE, "DISTANCE", 0, "Distance", ""},
@@ -2449,15 +2529,16 @@ static void def_cmp_dilate_erode(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, type_items);
- RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)");
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Growing/shrinking mode");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
- RNA_def_property_range(prop, -100, 100);
+ RNA_def_property_range(prop, -5000, 5000);
+ RNA_def_property_ui_range(prop, -100, 100, 0, 0);
RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -3178,8 +3259,8 @@ static void def_cmp_premul_key(StructRNA *srna)
PropertyRNA *prop;
static EnumPropertyItem type_items[] = {
- {0, "KEY_TO_PREMUL", 0, "Key to Premul", ""},
- {1, "PREMUL_TO_KEY", 0, "Premul to Key", ""},
+ {0, "STRAIGHT_TO_PREMUL", 0, "Straight to Premul", ""},
+ {1, "PREMUL_TO_STRAIGHT", 0, "Premul to Straight", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -3719,7 +3800,8 @@ static void def_cmp_bokehblur(StructRNA *srna)
/* duplicated in def_cmp_blur */
prop = RNA_def_property(srna, "use_variable_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODEFLAG_BLUR_VARIABLE_SIZE);
- RNA_def_property_ui_text(prop, "Variable Size", "Support variable blue per-pixel when using an image for size input");
+ RNA_def_property_ui_text(prop, "Variable Size",
+ "Support variable blur per-pixel when using an image for size input");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
#if 0
@@ -4002,6 +4084,21 @@ static void def_cmp_viewer(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Y", "");
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_negative_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_ui_text(prop, "Use Alpha", "Colors are treated alpha premultiplied, or colors output straight (alpha gets set to 1)");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
+static void def_cmp_composite(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_ui_text(prop, "Use Alpha", "Colors are treated alpha premultiplied, or colors output straight (alpha gets set to 1)");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_keyingscreen(StructRNA *srna)
@@ -4144,6 +4241,33 @@ static void def_cmp_trackpos(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_cmp_translate(StructRNA *srna)
+{
+ static EnumPropertyItem translate_items[] = {
+ {CMP_NODE_WRAP_NONE, "NONE", 0, "None", "No wrapping on X and Y"},
+ {CMP_NODE_WRAP_X, "XAXIS", 0, "X Axis", "Wrap all pixels on the X axis"},
+ {CMP_NODE_WRAP_Y, "YAXIS", 0, "Y Axis", "Wrap all pixels on the Y axis"},
+ {CMP_NODE_WRAP_XY, "BOTH", 0, "Both Axes", "Wrap all pixels on both axes"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeTranslateData", "storage");
+
+ prop = RNA_def_property(srna, "use_relative", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "relative", 1);
+ RNA_def_property_ui_text(prop, "Relative", "Use relative (percent) values to define blur radius");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "wrap_axis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "wrap_axis");
+ RNA_def_property_enum_items(prop, translate_items);
+ RNA_def_property_ui_text(prop, "Wrapping", "Wrap image on a specific axis");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
+
/* -- Texture Nodes --------------------------------------------------------- */
static void def_tex_output(StructRNA *srna)
@@ -4605,10 +4729,28 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "locx");
RNA_def_property_array(prop, 2);
- RNA_def_property_range(prop, -10000.0f, 10000.0f);
+ RNA_def_property_range(prop, -100000.0f, 100000.0f);
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_update(prop, NC_NODE, "rna_Node_update");
+ prop = RNA_def_property(srna, "width", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "width");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range");
+ RNA_def_property_ui_text(prop, "Width", "Width of the node");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+
+ prop = RNA_def_property(srna, "width_hidden", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "miniwidth");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range");
+ RNA_def_property_ui_text(prop, "Width Hidden", "Width of the node in hidden state");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+
+ prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "height");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_height_range");
+ RNA_def_property_ui_text(prop, "Height", "Height of the node");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Unique node identifier");
RNA_def_struct_name_property(srna, prop);
@@ -4632,8 +4774,9 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "parent");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_parent_set", NULL, "rna_Node_parent_poll");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Node");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to");
prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE);
@@ -4829,6 +4972,10 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_COM_OPENCL);
RNA_def_property_ui_text(prop, "OpenCL", "Enable GPU calculations");
+ prop = RNA_def_property(srna, "use_groupnode_buffer", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_COM_GROUPNODE_BUFFER);
+ RNA_def_property_ui_text(prop, "Buffer Groups", "Enable buffering of group nodes");
+
prop = RNA_def_property(srna, "two_pass", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_TWO_PASS);
RNA_def_property_ui_text(prop, "Two Pass", "Use two pass execution during editing: first calculate fast nodes, "
@@ -4874,12 +5021,12 @@ static void rna_def_texture_nodetree(BlenderRNA *brna)
rna_def_texture_nodetree_api(brna, prop);
}
-static void define_specific_node(BlenderRNA *brna, int id, void (*func)(StructRNA *))
+static void define_specific_node(BlenderRNA *brna, int id, void (*def_func)(StructRNA *))
{
StructRNA *srna = def_node(brna, id);
-
- if (func)
- func(srna);
+
+ if (def_func)
+ def_func(srna);
}
void RNA_def_nodetree(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index 14cdbc6cf7d..b7ec9235483 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -31,6 +31,8 @@
#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc)
#endif
+/* WARNING! If you edit those strings, please do the same in relevant nodes files (under blender/nodes/...)! */
+
/* Tree type Node ID RNA def function Enum name Struct name UI Name UI Description */
DefNode( ShaderNode, SH_NODE_OUTPUT, 0, "OUTPUT", Output, "Output", "" )
DefNode( ShaderNode, SH_NODE_MATERIAL, def_sh_material, "MATERIAL", Material, "Material", "" )
@@ -45,12 +47,12 @@ DefNode( ShaderNode, SH_NODE_GAMMA, 0, "GAMMA
DefNode( ShaderNode, SH_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" )
DefNode( ShaderNode, SH_NODE_GEOMETRY, def_sh_geometry, "GEOMETRY", Geometry, "Geometry", "" )
DefNode( ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPING", Mapping, "Mapping", "" )
-DefNode( ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curve", "" )
-DefNode( ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curve", "" )
+DefNode( ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curves", "" )
+DefNode( ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curves", "" )
DefNode( ShaderNode, SH_NODE_CAMERA, 0, "CAMERA", CameraData, "Camera Data", "" )
DefNode( ShaderNode, SH_NODE_MATH, def_math, "MATH", Math, "Math", "" )
DefNode( ShaderNode, SH_NODE_VECT_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" )
-DefNode( ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze", "" )
+DefNode( ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze Value", "" )
DefNode( ShaderNode, SH_NODE_MATERIAL_EXT, def_sh_material, "MATERIAL_EXT", ExtendedMaterial, "Extended Material", "" )
DefNode( ShaderNode, SH_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
DefNode( ShaderNode, SH_NODE_SEPRGB, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" )
@@ -68,14 +70,14 @@ DefNode( ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "AT
DefNode( ShaderNode, SH_NODE_AMBIENT_OCCLUSION, 0, "AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "" )
DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "" )
DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, 0, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic Bsdf", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse Bsdf", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy Bsdf", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glossy, "BSDF_GLASS", BsdfGlass, "Glass Bsdf", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_REFRACTION, def_glossy, "BSDF_REFRACTION", BsdfRefraction, "Refraction Bsdf", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_TRANSLUCENT, 0, "BSDF_TRANSLUCENT", BsdfTranslucent, "Translucent Bsdf", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_TRANSPARENT, 0, "BSDF_TRANSPARENT", BsdfTransparent, "Transparent Bsdf", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_VELVET, 0, "BSDF_VELVET", BsdfVelvet, "Velvet Bsdf", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, 0, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glossy, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_REFRACTION, def_glossy, "BSDF_REFRACTION", BsdfRefraction, "Refraction BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_TRANSLUCENT, 0, "BSDF_TRANSLUCENT", BsdfTranslucent, "Translucent BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_TRANSPARENT, 0, "BSDF_TRANSPARENT", BsdfTransparent, "Transparent BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_VELVET, 0, "BSDF_VELVET", BsdfVelvet, "Velvet BSDF", "" )
DefNode( ShaderNode, SH_NODE_VOLUME_TRANSPARENT, 0, "VOLUME_TRANSPARENT", VolumeTransparent,"Transparent Volume","" )
DefNode( ShaderNode, SH_NODE_VOLUME_ISOTROPIC, 0, "VOLUME_ISOTROPIC", VolumeIsotropic, "Isotropic Volume", "" )
DefNode( ShaderNode, SH_NODE_EMISSION, 0, "EMISSION", Emission, "Emission", "" )
@@ -84,6 +86,7 @@ DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LI
DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" )
DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" )
DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" )
+DefNode( ShaderNode, SH_NODE_HAIR_INFO, 0, "HAIR_INFO", HairInfo, "Hair Info", "" )
DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", Bump, "Bump", "" )
DefNode( ShaderNode, SH_NODE_NORMAL_MAP, def_sh_normal_map, "NORMAL_MAP", NormalMap, "Normal Map", "" )
DefNode( ShaderNode, SH_NODE_TANGENT, def_sh_tangent, "TANGENT", Tangent, "Tangent", "" )
@@ -104,12 +107,12 @@ DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TE
DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
DefNode( CompositorNode, CMP_NODE_VALUE, 0, "VALUE", Value, "Value", "" )
-DefNode( CompositorNode, CMP_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix RGB", "" )
+DefNode( CompositorNode, CMP_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix", "" )
DefNode( CompositorNode, CMP_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
DefNode( CompositorNode, CMP_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
DefNode( CompositorNode, CMP_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
-DefNode( CompositorNode, CMP_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", CurveVec, "Vector Curve", "" )
-DefNode( CompositorNode, CMP_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curve", "" )
+DefNode( CompositorNode, CMP_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", CurveVec, "Vector Curves", "" )
+DefNode( CompositorNode, CMP_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curves", "" )
DefNode( CompositorNode, CMP_NODE_ALPHAOVER, def_cmp_alpha_over, "ALPHAOVER", AlphaOver, "Alpha Over", "" )
DefNode( CompositorNode, CMP_NODE_BLUR, def_cmp_blur, "BLUR", Blur, "Blur", "" )
DefNode( CompositorNode, CMP_NODE_FILTER, def_cmp_filter, "FILTER", Filter, "Filter", "" )
@@ -120,13 +123,13 @@ DefNode( CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBL
DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
DefNode( CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
DefNode( CompositorNode, CMP_NODE_SETALPHA, 0, "SETALPHA", SetAlpha, "Set Alpha", "" )
-DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue/Saturation", "" )
+DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue Saturation Value","" )
DefNode( CompositorNode, CMP_NODE_IMAGE, def_cmp_image, "IMAGE", Image, "Image", "" )
DefNode( CompositorNode, CMP_NODE_R_LAYERS, def_cmp_render_layers, "R_LAYERS", RLayers, "Render Layers", "" )
-DefNode( CompositorNode, CMP_NODE_COMPOSITE, 0, "COMPOSITE", Composite, "Composite", "" )
-DefNode( CompositorNode, CMP_NODE_OUTPUT_FILE, def_cmp_output_file, "OUTPUT_FILE", OutputFile, "Output File", "" )
+DefNode( CompositorNode, CMP_NODE_COMPOSITE, def_cmp_composite, "COMPOSITE", Composite, "Composite", "" )
+DefNode( CompositorNode, CMP_NODE_OUTPUT_FILE, def_cmp_output_file, "OUTPUT_FILE", OutputFile, "File Output", "" )
DefNode( CompositorNode, CMP_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
-DefNode( CompositorNode, CMP_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
+DefNode( CompositorNode, CMP_NODE_TRANSLATE, def_cmp_translate, "TRANSLATE", Translate, "Translate", "" )
DefNode( CompositorNode, CMP_NODE_ZCOMBINE, def_cmp_zcombine, "ZCOMBINE", Zcombine, "Z Combine", "" )
DefNode( CompositorNode, CMP_NODE_COMBRGBA, 0, "COMBRGBA", CombRGBA, "Combine RGBA", "" )
DefNode( CompositorNode, CMP_NODE_DILATEERODE, def_cmp_dilate_erode, "DILATEERODE", DilateErode, "Dilate/Erode", "" )
@@ -134,8 +137,8 @@ DefNode( CompositorNode, CMP_NODE_INPAINT, def_cmp_inpaint, "INPAI
DefNode( CompositorNode, CMP_NODE_DESPECKLE, def_cmp_despeckle, "DESPECKLE", Despeckle, "Despeckle", "" )
DefNode( CompositorNode, CMP_NODE_ROTATE, def_cmp_rotate, "ROTATE", Rotate, "Rotate", "" )
DefNode( CompositorNode, CMP_NODE_SCALE, def_cmp_scale, "SCALE", Scale, "Scale", "" )
-DefNode( CompositorNode, CMP_NODE_SEPYCCA, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCCA", "" )
-DefNode( CompositorNode, CMP_NODE_COMBYCCA, def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCCA", "" )
+DefNode( CompositorNode, CMP_NODE_SEPYCCA, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCbCrA", "" )
+DefNode( CompositorNode, CMP_NODE_COMBYCCA, def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCbCrA", "" )
DefNode( CompositorNode, CMP_NODE_SEPYUVA, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
DefNode( CompositorNode, CMP_NODE_COMBYUVA, 0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
DefNode( CompositorNode, CMP_NODE_DIFF_MATTE, def_cmp_diff_matte, "DIFF_MATTE", DiffMatte, "Difference Key", "" )
@@ -146,42 +149,43 @@ DefNode( CompositorNode, CMP_NODE_FLIP, def_cmp_flip, "FLIP"
DefNode( CompositorNode, CMP_NODE_SPLITVIEWER, def_cmp_splitviewer, "SPLITVIEWER", SplitViewer, "Split Viewer", "" )
DefNode( CompositorNode, CMP_NODE_MAP_UV, def_cmp_map_uv, "MAP_UV", MapUV, "Map UV", "" )
DefNode( CompositorNode, CMP_NODE_ID_MASK, def_cmp_id_mask, "ID_MASK", IDMask, "ID Mask", "" )
-DefNode( CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
+DefNode( CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
DefNode( CompositorNode, CMP_NODE_DEFOCUS, def_cmp_defocus, "DEFOCUS", Defocus, "Defocus", "" )
DefNode( CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" )
DefNode( CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
DefNode( CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
-DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luma Matte", "" )
-DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" )
+DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
+DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
DefNode( CompositorNode, CMP_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" )
DefNode( CompositorNode, CMP_NODE_INVERT, def_cmp_invert, "INVERT", Invert, "Invert", "" )
DefNode( CompositorNode, CMP_NODE_NORMALIZE, 0, "NORMALIZE", Normalize, "Normalize", "" )
DefNode( CompositorNode, CMP_NODE_CROP, def_cmp_crop, "CROP", Crop, "Crop", "" )
DefNode( CompositorNode, CMP_NODE_DBLUR, def_cmp_dblur, "DBLUR", DBlur, "Directional Blur", "" )
DefNode( CompositorNode, CMP_NODE_BILATERALBLUR, def_cmp_bilateral_blur, "BILATERALBLUR", Bilateralblur, "Bilateral Blur", "" )
-DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMULKEY", PremulKey, "Premul Key", "" )
+DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMULKEY", PremulKey, "Alpha Convert", "" )
DefNode( CompositorNode, CMP_NODE_GLARE, def_cmp_glare, "GLARE", Glare, "Glare", "" )
DefNode( CompositorNode, CMP_NODE_TONEMAP, def_cmp_tonemap, "TONEMAP", Tonemap, "Tonemap", "" )
-DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSDIST", Lensdist, "Lensdist", "" )
+DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSDIST", Lensdist, "Lens Distortion", "" )
DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS, def_cmp_levels, "LEVELS", Levels, "Levels", "" )
-DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Matte", "" )
-DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" )
+DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Key", "" )
+DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Key", "" )
DefNode( CompositorNode, CMP_NODE_COLORBALANCE, def_cmp_colorbalance, "COLORBALANCE", ColorBalance, "Color Balance", "" )
DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECORRECT", HueCorrect, "Hue Correct", "" )
-DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "MovieClip", "" )
+DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "Movie Clip", "" )
DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" )
DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabilize 2D", "" )
DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" )
-DefNode( CompositorNode, CMP_NODE_MASK_BOX, def_cmp_boxmask, "BOXMASK", BoxMask, "Box mask", "" )
-DefNode( CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIPSEMASK", EllipseMask, "Ellipse mask", "" )
-DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE", BokehImage, "Bokeh image", "" )
+DefNode( CompositorNode, CMP_NODE_MASK_BOX, def_cmp_boxmask, "BOXMASK", BoxMask, "Box Mask", "" )
+DefNode( CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIPSEMASK", EllipseMask, "Ellipse Mask", "" )
+DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE", BokehImage, "Bokeh Image", "" )
DefNode( CompositorNode, CMP_NODE_BOKEHBLUR, def_cmp_bokehblur, "BOKEHBLUR", BokehBlur, "Bokeh Blur", "" )
DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH", Switch, "Switch", "" )
-DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "ColorCorrection", "" )
+DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "Color Correction", "" )
DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" )
-DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "KeyingScreen", "" )
+DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "Keying Screen", "" )
DefNode( CompositorNode, CMP_NODE_KEYING, def_cmp_keying, "KEYING", Keying, "Keying", "" )
DefNode( CompositorNode, CMP_NODE_TRACKPOS, def_cmp_trackpos, "TRACKPOS", TrackPos, "Track Position", "" )
+DefNode( CompositorNode, CMP_NODE_PIXELATE, 0, "PIXELATE", Pixelate, "Pixelate", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
@@ -192,7 +196,7 @@ DefNode( TextureNode, TEX_NODE_MIX_RGB, def_mix_rgb, "MIX_R
DefNode( TextureNode, TEX_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
DefNode( TextureNode, TEX_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
DefNode( TextureNode, TEX_NODE_IMAGE, def_tex_image, "IMAGE", Image, "Image", "" )
-DefNode( TextureNode, TEX_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curve", "" )
+DefNode( TextureNode, TEX_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curves", "" )
DefNode( TextureNode, TEX_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
DefNode( TextureNode, TEX_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
DefNode( TextureNode, TEX_NODE_CURVE_TIME, def_time, "CURVE_TIME", CurveTime, "Curve Time", "" )
@@ -201,8 +205,8 @@ DefNode( TextureNode, TEX_NODE_VIEWER, 0, "VIEWE
DefNode( TextureNode, TEX_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
DefNode( TextureNode, TEX_NODE_COORD, 0, "COORD", Coordinates, "Coordinates", "" )
DefNode( TextureNode, TEX_NODE_DISTANCE, 0, "DISTANCE", Distance, "Distance", "" )
-DefNode( TextureNode, TEX_NODE_COMPOSE, 0, "COMPOSE", Compose, "Compose", "" )
-DefNode( TextureNode, TEX_NODE_DECOMPOSE, 0, "DECOMPOSE", Decompose, "Decompose", "" )
+DefNode( TextureNode, TEX_NODE_COMPOSE, 0, "COMPOSE", Compose, "Combine RGBA", "" )
+DefNode( TextureNode, TEX_NODE_DECOMPOSE, 0, "DECOMPOSE", Decompose, "Separate RGBA", "" )
DefNode( TextureNode, TEX_NODE_VALTONOR, 0, "VALTONOR", ValToNor, "Value to Normal", "" )
DefNode( TextureNode, TEX_NODE_SCALE, 0, "SCALE", Scale, "Scale", "" )
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 1d08ea97b79..2c736df1ed2 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -48,6 +48,7 @@
#include "BLI_utildefines.h"
+#include "BKE_paint.h"
#include "BKE_tessmesh.h"
#include "BKE_group.h" /* needed for object_in_group() */
@@ -94,6 +95,7 @@ static EnumPropertyItem parent_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
+#ifndef RNA_RUNTIME
static EnumPropertyItem dupli_items[] = {
{0, "NONE", 0, "None", ""},
{OB_DUPLIFRAMES, "FRAMES", 0, "Frames", "Make copy of object for every frame"},
@@ -102,6 +104,7 @@ static EnumPropertyItem dupli_items[] = {
{OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing"},
{0, NULL, 0, NULL, NULL}
};
+#endif
static EnumPropertyItem collision_bounds_items[] = {
{OB_BOUND_BOX, "BOX", 0, "Box", ""},
@@ -153,6 +156,15 @@ EnumPropertyItem object_type_curve_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem object_axis_items[] = {
+ {OB_POSX, "POS_X", 0, "+X", ""},
+ {OB_POSY, "POS_Y", 0, "+Y", ""},
+ {OB_POSZ, "POS_Z", 0, "+Z", ""},
+ {OB_NEGX, "NEG_X", 0, "-X", ""},
+ {OB_NEGY, "NEG_Y", 0, "-Y", ""},
+ {OB_NEGZ, "NEG_Z", 0, "-Z", ""},
+ {0, NULL, 0, NULL, NULL}
+};
#ifdef RNA_RUNTIME
@@ -281,12 +293,10 @@ static void rna_Object_active_shape_update(Main *bmain, Scene *scene, PointerRNA
rna_Object_internal_update_data(bmain, scene, ptr);
}
-static void rna_Object_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Object_dependency_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
DAG_id_tag_update(ptr->id.data, OB_RECALC_OB);
- if (scene) {
- DAG_scene_sort(bmain, scene);
- }
+ DAG_relations_tag_update(bmain);
WM_main_add_notifier(NC_OBJECT | ND_PARENT, ptr->id.data);
}
@@ -320,7 +330,7 @@ static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, Base *b
/* pass */
}
else {
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
DAG_id_type_tag(bmain, ID_OB);
@@ -1121,7 +1131,7 @@ static void rna_GameObjectSettings_used_state_get(PointerRNA *ptr, int *values)
static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i;
for (i = 0; i < OB_MAX_COL_MASKS; i++) {
@@ -1131,7 +1141,7 @@ static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values)
static void rna_GameObjectSettings_col_group_set(PointerRNA *ptr, const int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i, tot = 0;
/* ensure we always have some group selected */
@@ -1150,7 +1160,7 @@ static void rna_GameObjectSettings_col_group_set(PointerRNA *ptr, const int *val
static void rna_GameObjectSettings_col_mask_get(PointerRNA *ptr, int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i;
for (i = 0; i < OB_MAX_COL_MASKS; i++) {
@@ -1160,7 +1170,7 @@ static void rna_GameObjectSettings_col_mask_get(PointerRNA *ptr, int *values)
static void rna_GameObjectSettings_col_mask_set(PointerRNA *ptr, const int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i, tot = 0;
/* ensure we always have some mask selected */
@@ -1250,20 +1260,20 @@ static PointerRNA rna_Object_collision_get(PointerRNA *ptr)
static PointerRNA rna_Object_active_constraint_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
- bConstraint *con = constraints_get_active(&ob->constraints);
+ bConstraint *con = BKE_constraints_get_active(&ob->constraints);
return rna_pointer_inherit_refine(ptr, &RNA_Constraint, con);
}
static void rna_Object_active_constraint_set(PointerRNA *ptr, PointerRNA value)
{
Object *ob = (Object *)ptr->id.data;
- constraints_set_active(&ob->constraints, (bConstraint *)value.data);
+ BKE_constraints_set_active(&ob->constraints, (bConstraint *)value.data);
}
static bConstraint *rna_Object_constraints_new(Object *object, int type)
{
WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_ADDED, object);
- return add_ob_constraint(object, NULL, type);
+ return BKE_add_ob_constraint(object, NULL, type);
}
static void rna_Object_constraints_remove(Object *object, ReportList *reports, PointerRNA *con_ptr)
@@ -1274,7 +1284,7 @@ static void rna_Object_constraints_remove(Object *object, ReportList *reports, P
return;
}
- remove_constraint(&object->constraints, con);
+ BKE_remove_constraint(&object->constraints, con);
RNA_POINTER_INVALIDATE(con_ptr);
ED_object_constraint_update(object);
@@ -1284,7 +1294,7 @@ static void rna_Object_constraints_remove(Object *object, ReportList *reports, P
static void rna_Object_constraints_clear(Object *object)
{
- free_constraints(&object->constraints);
+ BKE_free_constraints(&object->constraints);
ED_object_constraint_update(object);
ED_object_constraint_set_active(object, NULL);
@@ -1301,7 +1311,7 @@ static ModifierData *rna_Object_modifier_new(Object *object, bContext *C, Report
static void rna_Object_modifier_remove(Object *object, bContext *C, ReportList *reports, PointerRNA *md_ptr)
{
ModifierData *md = md_ptr->data;
- if (ED_object_modifier_remove(reports, CTX_data_main(C), CTX_data_scene(C), object, md) == FALSE) {
+ if (ED_object_modifier_remove(reports, CTX_data_main(C), object, md) == FALSE) {
/* error is already set */
return;
}
@@ -1313,7 +1323,7 @@ static void rna_Object_modifier_remove(Object *object, bContext *C, ReportList *
static void rna_Object_modifier_clear(Object *object, bContext *C)
{
- ED_object_modifier_clear(CTX_data_main(C), CTX_data_scene(C), object);
+ ED_object_modifier_clear(CTX_data_main(C), object);
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object);
}
@@ -1434,6 +1444,12 @@ int rna_DupliObject_index_get(PointerRNA *ptr)
return dob->persistent_id[0];
}
+int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
+{
+ SculptSession *ss = ((Object *)ptr->id.data)->sculpt;
+ return (ss && ss->bm);
+}
+
#else
static int rna_matrix_dimsize_4x4[] = {4, 4};
@@ -1961,7 +1977,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "actdef");
RNA_def_property_int_funcs(prop, "rna_Object_active_vertex_group_index_get",
@@ -1993,16 +2009,6 @@ static void rna_def_object(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
- static EnumPropertyItem track_items[] = {
- {OB_POSX, "POS_X", 0, "+X", ""},
- {OB_POSY, "POS_Y", 0, "+Y", ""},
- {OB_POSZ, "POS_Z", 0, "+Z", ""},
- {OB_NEGX, "NEG_X", 0, "-X", ""},
- {OB_NEGY, "NEG_Y", 0, "-Y", ""},
- {OB_NEGZ, "NEG_Z", 0, "-Z", ""},
- {0, NULL, 0, NULL, NULL}
- };
static EnumPropertyItem up_items[] = {
{OB_POSX, "X", 0, "X", ""},
@@ -2080,6 +2086,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_layer_set");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_layer_update");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "layers_local_view", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "lay", 0x01000000);
@@ -2132,7 +2139,7 @@ static void rna_def_object(BlenderRNA *brna)
* since some other tools still refer to this */
prop = RNA_def_property(srna, "track_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "trackflag");
- RNA_def_property_enum_items(prop, track_items);
+ RNA_def_property_enum_items(prop, object_axis_items);
RNA_def_property_ui_text(prop, "Track Axis",
"Axis that points in 'forward' direction (applies to DupliFrame when "
"parent 'Follow' is enabled)");
@@ -2419,6 +2426,17 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Particle Systems", "Particle systems emitted from the object");
rna_def_object_particle_systems(brna, prop);
+
+ prop = RNA_def_property(srna, "rigid_body", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "rigidbody_object");
+ RNA_def_property_struct_type(prop, "RigidBodyObject");
+ RNA_def_property_ui_text(prop, "Rigid Body Settings", "Settings for rigid body simulation");
+
+ prop = RNA_def_property(srna, "rigid_body_constraint", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "rigidbody_constraint");
+ RNA_def_property_struct_type(prop, "RigidBodyConstraint");
+ RNA_def_property_ui_text(prop, "Rigid Body Constraint", "Constraint constraining rigid bodies");
+
/* restrict */
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEW);
@@ -2459,6 +2477,15 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Slow Parent Offset", "Delay in the parent relationship");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
+ /* depsgraph hack */
+ prop = RNA_def_property(srna, "extra_recalc_object", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_OB_RECALC);
+ RNA_def_property_ui_text(prop, "Extra Object Update", "Refresh this object again on frame changes, dependency graph hack");
+
+ prop = RNA_def_property(srna, "extra_recalc_data", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_DATA_RECALC);
+ RNA_def_property_ui_text(prop, "Extra Data Update", "Refresh this object's data again on frame changes, dependency graph hack");
+
/* duplicates */
prop = RNA_def_property(srna, "dupli_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag");
@@ -2538,7 +2565,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
prop = RNA_def_property(srna, "show_bounds", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_BOUNDBOX);
+ RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWBOUNDOX);
RNA_def_property_ui_text(prop, "Draw Bounds", "Display the object's bounds");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
@@ -2567,7 +2594,12 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWWIRE);
RNA_def_property_ui_text(prop, "Draw Wire", "Add the object's wireframe over solid drawing");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
+ prop = RNA_def_property(srna, "show_all_edges", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAW_ALL_EDGES);
+ RNA_def_property_ui_text(prop, "Draw All Edges", "Display all edges for mesh objects");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
prop = RNA_def_property(srna, "show_transparent", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWTRANSP);
RNA_def_property_ui_text(prop, "Draw Transparent",
@@ -2626,6 +2658,12 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Active Shape Key Index", "Current shape key index");
RNA_def_property_update(prop, 0, "rna_Object_active_shape_update");
+ /* sculpt */
+ prop = RNA_def_property(srna, "use_dynamic_topology_sculpting", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_Object_use_dynamic_topology_sculpting_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Dynamic Topology Sculpting", NULL);
+
RNA_api_object(srna);
}
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 87fc3be28a2..2b7df1ca317 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -34,265 +34,88 @@
#include <string.h>
#include <time.h>
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
-#include "DNA_object_types.h"
+#include "DNA_constraint_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
#include "rna_internal.h" /* own include */
+static EnumPropertyItem space_items[] = {
+ {CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space",
+ "The most gobal space in Blender"},
+ {CONSTRAINT_SPACE_POSE, "POSE", 0, "Pose Space",
+ "The pose space of a bone (its armature's object space)"},
+ {CONSTRAINT_SPACE_PARLOCAL, "LOCAL_WITH_PARENT", 0, "Local With Parent",
+ "The local space of a bone's parent bone"},
+ {CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space",
+ "The local space of an object/bone"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
+
#include "BLI_math.h"
-#include "BKE_main.h"
-#include "BKE_global.h"
-#include "BKE_context.h"
-#include "BKE_report.h"
-#include "BKE_object.h"
-#include "BKE_mesh.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_anim.h"
#include "BKE_bvhutils.h"
-
+#include "BKE_cdderivedmesh.h"
+#include "BKE_constraint.h"
+#include "BKE_context.h"
#include "BKE_customdata.h"
-#include "BKE_anim.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
#include "BKE_font.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
-#include "BKE_cdderivedmesh.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_scene_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_constraint_types.h"
+#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
#include "MEM_guardedalloc.h"
-/* copied from Mesh_getFromObject and adapted to RNA interface */
-/* settings: 0 - preview, 1 - render */
-static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_modifiers, int settings)
+/* Convert a given matrix from a space to another (using the object and/or a bone as reference). */
+static void rna_Scene_mat_convert_space(Object *ob, ReportList *reports, bPoseChannel *pchan,
+ float *mat, float *mat_ret, int from, int to)
{
- Mesh *tmpmesh;
- Curve *tmpcu = NULL, *copycu;
- Object *tmpobj = NULL;
- int render = settings == eModifierMode_Render, i;
- int cage = !apply_modifiers;
-
- /* perform the mesh extraction based on type */
- switch (ob->type) {
- case OB_FONT:
- case OB_CURVE:
- case OB_SURF:
- {
- ListBase dispbase = {NULL, NULL};
- DerivedMesh *derivedFinal = NULL;
- int uv_from_orco;
-
- int (*orco_index)[4] = NULL;
- float (*orco)[3] = NULL;
-
- /* copies object and modifiers (but not the data) */
- tmpobj = BKE_object_copy_with_caches(ob);
- tmpcu = (Curve *)tmpobj->data;
- tmpcu->id.us--;
-
- /* if getting the original caged mesh, delete object modifiers */
- if (cage)
- BKE_object_free_modifiers(tmpobj);
-
- /* copies the data */
- copycu = tmpobj->data = BKE_curve_copy((Curve *) ob->data);
-
- /* temporarily set edit so we get updates from edit mode, but
- * also because for text datablocks copying it while in edit
- * mode gives invalid data structures */
- copycu->editfont = tmpcu->editfont;
- copycu->editnurb = tmpcu->editnurb;
-
- /* get updated display list, and convert to a mesh */
- BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE);
-
- copycu->editfont = NULL;
- copycu->editnurb = NULL;
-
- tmpobj->derivedFinal = derivedFinal;
-
- uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
-
- if (uv_from_orco) {
- /* before curve conversion */
- orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj);
- }
-
- /* convert object type to mesh */
- BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? (int **)&orco_index : NULL);
-
- tmpmesh = tmpobj->data;
-
- if (uv_from_orco && orco && orco_index) {
- const char *uvname = "Orco";
- /* add UV's */
- MTexPoly *mtpoly = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname);
- MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, tmpmesh->totloop, uvname);
-
- BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly,
- tmpmesh->mloop, mloopuvs,
- orco, orco_index);
-
- (void)mtpoly;
- }
-
- if (orco_index) {
- MEM_freeN(orco_index);
- }
- if (orco) {
- MEM_freeN(orco);
- }
-
- BKE_displist_free(&dispbase);
-
- /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */
- if (tmpobj->type != OB_MESH) {
- BKE_libblock_free_us(&(G.main->object), tmpobj);
- BKE_report(reports, RPT_ERROR, "Cannot convert curve to mesh (does the curve have any segments?)");
- return NULL;
- }
-
- BKE_libblock_free_us(&G.main->object, tmpobj);
- break;
+ copy_m4_m4((float (*)[4])mat_ret, (float (*)[4])mat);
+
+ /* Error in case of invalid from/to values when pchan is NULL */
+ if (pchan == NULL) {
+ if (ELEM(from, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
+ const char *identifier = NULL;
+ RNA_enum_identifier(space_items, from, &identifier);
+ BKE_reportf(reports, RPT_ERROR, "'from_space' '%s' is invalid when no pose bone is given!", identifier);
+ return;
}
-
- case OB_MBALL:
- {
- /* metaballs don't have modifiers, so just convert to mesh */
- Object *basis_ob = BKE_mball_basis_find(sce, ob);
- /* todo, re-generatre for render-res */
- /* metaball_polygonize(scene, ob) */
-
- if (ob != basis_ob)
- return NULL; /* only do basis metaball */
-
- tmpmesh = BKE_mesh_add("Mesh");
- /* BKE_mesh_add gives us a user count we don't need */
- tmpmesh->id.us--;
-
- if (render) {
- ListBase disp = {NULL, NULL};
- BKE_displist_make_mball_forRender(sce, ob, &disp);
- BKE_mesh_from_metaball(&disp, tmpmesh);
- BKE_displist_free(&disp);
- }
- else
- BKE_mesh_from_metaball(&ob->disp, tmpmesh);
-
- break;
-
+ if (ELEM(to, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
+ const char *identifier = NULL;
+ RNA_enum_identifier(space_items, to, &identifier);
+ BKE_reportf(reports, RPT_ERROR, "'to_space' '%s' is invalid when no pose bone is given!", identifier);
+ return;
}
- case OB_MESH:
- /* copies object and modifiers (but not the data) */
- if (cage) {
- /* copies the data */
- tmpmesh = BKE_mesh_copy(ob->data);
- /* if not getting the original caged mesh, get final derived mesh */
- }
- else {
- /* Make a dummy mesh, saves copying */
- DerivedMesh *dm;
- /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
- CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
- * for example, needs CD_MASK_MDEFORMVERT */
-
- /* Write the display mesh into the dummy mesh */
- if (render)
- dm = mesh_create_derived_render(sce, ob, mask);
- else
- dm = mesh_create_derived_view(sce, ob, mask);
-
- tmpmesh = BKE_mesh_add("Mesh");
- DM_to_mesh(dm, tmpmesh, ob);
- dm->release(dm);
- }
-
- /* BKE_mesh_add/copy gives us a user count we don't need */
- tmpmesh->id.us--;
-
- break;
- default:
- BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
- return NULL;
}
- /* Copy materials to new mesh */
- switch (ob->type) {
- case OB_SURF:
- case OB_FONT:
- case OB_CURVE:
- tmpmesh->totcol = tmpcu->totcol;
-
- /* free old material list (if it exists) and adjust user counts */
- if (tmpcu->mat) {
- for (i = tmpcu->totcol; i-- > 0; ) {
- /* are we an object material or data based? */
-
- tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
-
- if (tmpmesh->mat[i]) {
- tmpmesh->mat[i]->id.us++;
- }
- }
- }
- break;
-
-#if 0
- /* Crashes when assigning the new material, not sure why */
- case OB_MBALL:
- tmpmb = (MetaBall *)ob->data;
- tmpmesh->totcol = tmpmb->totcol;
-
- /* free old material list (if it exists) and adjust user counts */
- if (tmpmb->mat) {
- for (i = tmpmb->totcol; i-- > 0; ) {
- tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
- if (tmpmesh->mat[i]) {
- tmpmb->mat[i]->id.us++;
- }
- }
- }
- break;
-#endif
-
- case OB_MESH:
- if (!cage) {
- Mesh *origmesh = ob->data;
- tmpmesh->flag = origmesh->flag;
- tmpmesh->mat = MEM_dupallocN(origmesh->mat);
- tmpmesh->totcol = origmesh->totcol;
- tmpmesh->smoothresh = origmesh->smoothresh;
- if (origmesh->mat) {
- for (i = origmesh->totcol; i-- > 0; ) {
- /* are we an object material or data based? */
- tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
-
- if (tmpmesh->mat[i]) {
- tmpmesh->mat[i]->id.us++;
- }
- }
- }
- }
- break;
- } /* end copy materials */
-
- /* cycles and exporters rely on this still */
- BKE_mesh_tessface_ensure(tmpmesh);
-
- /* make sure materials get updated in objects */
- test_object_materials(&tmpmesh->id);
+ BKE_constraint_mat_convertspace(ob, pchan, (float (*)[4])mat_ret, from, to);
+}
- return tmpmesh;
+/* copied from Mesh_getFromObject and adapted to RNA interface */
+/* settings: 0 - preview, 1 - render */
+static Mesh *rna_Object_to_mesh(
+ Object *ob, ReportList *reports, Scene *sce,
+ int apply_modifiers, int settings, int calc_tessface)
+{
+ return rna_Main_meshes_new_from_object(G.main, reports, sce, ob, apply_modifiers, settings, calc_tessface);
}
/* mostly a copy from convertblender.c */
@@ -570,7 +393,7 @@ void rna_Object_dm_info(struct Object *ob, int type, char *result)
}
#endif /* NDEBUG */
-#else
+#else /* RNA_RUNTIME */
void RNA_api_object(StructRNA *srna)
{
@@ -583,6 +406,8 @@ void RNA_api_object(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
+ static int rna_matrix_dimsize_4x4[] = {4, 4};
+
#ifndef NDEBUG
static EnumPropertyItem mesh_dm_info_items[] = {
{0, "SOURCE", 0, "Source", "Source mesh"},
@@ -592,6 +417,25 @@ void RNA_api_object(StructRNA *srna)
};
#endif
+ /* Matrix space conversion */
+ func = RNA_def_function(srna, "convert_space", "rna_Scene_mat_convert_space");
+ RNA_def_function_ui_description(func, "Convert (transform) the given matrix from one space to another");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "pose_bone", "PoseBone", "",
+ "Bone to use to define spaces (may be None, in which case only the two 'WORLD' and "
+ "'LOCAL' spaces are usable)");
+ parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_ui_text(parm, "", "The matrix to transform");
+ parm = RNA_def_property(func, "matrix_return", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_ui_text(parm, "", "The transformed matrix");
+ RNA_def_function_output(func, parm);
+ parm = RNA_def_enum(func, "from_space", space_items, CONSTRAINT_SPACE_WORLD, "",
+ "The space in which 'matrix' is currently");
+ parm = RNA_def_enum(func, "to_space", space_items, CONSTRAINT_SPACE_WORLD, "",
+ "The space to which you want to transform 'matrix'");
+
/* 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");
@@ -602,6 +446,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply");
RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces");
parm = RNA_def_pointer(func, "mesh", "Mesh", "",
"Mesh created from object, remove it if it is only used for export");
RNA_def_function_return(func, parm);
@@ -737,5 +582,4 @@ void RNA_api_object_base(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
}
-#endif
-
+#endif /* RNA_RUNTIME */
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 6d7187da7d9..ec974df54d5 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -521,7 +521,7 @@ static void rna_FieldSettings_shape_update(Main *bmain, Scene *scene, PointerRNA
}
else {
if (!pd || pd->shape != PFIELD_SHAPE_SURFACE)
- ED_object_modifier_remove(NULL, bmain, scene, ob, md);
+ ED_object_modifier_remove(NULL, bmain, ob, md);
}
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
@@ -547,7 +547,7 @@ static void rna_FieldSettings_dependency_update(Main *bmain, Scene *scene, Point
rna_FieldSettings_shape_update(bmain, scene, ptr);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
if (ob->type == OB_CURVE && ob->pd->forcefield == PFIELD_GUIDE)
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
@@ -590,9 +590,9 @@ static void rna_EffectorWeight_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
}
-static void rna_EffectorWeight_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_EffectorWeight_dependency_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
DAG_id_tag_update((ID *)ptr->id.data, OB_RECALC_DATA | PSYS_RECALC_RESET);
@@ -669,7 +669,7 @@ static void rna_CollisionSettings_dependency_update(Main *bmain, Scene *scene, P
if (ob->pd->deflect && !md)
ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Collision);
else if (!ob->pd->deflect && md)
- ED_object_modifier_remove(NULL, bmain, scene, ob, md);
+ ED_object_modifier_remove(NULL, bmain, ob, md);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
@@ -763,7 +763,8 @@ static void rna_def_pointcache(BlenderRNA *brna)
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "startframe");
- RNA_def_property_range(prop, 1, MAXFRAME);
+ RNA_def_property_range(prop, -MAXFRAME, MAXFRAME);
+ RNA_def_property_ui_range(prop, 1, MAXFRAME, 1, 1);
RNA_def_property_ui_text(prop, "Start", "Frame on which the simulation starts");
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
@@ -1181,7 +1182,7 @@ static void rna_def_field(BlenderRNA *brna)
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f_strength");
- RNA_def_property_range(prop, -1000.0f, 1000.0f);
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(prop, "Strength", "Strength of force field");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 6825d3d781d..4bf5de03b05 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -238,7 +238,369 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float
}
}
-/* property update functions */
+static void rna_ParticleHairKey_co_object(HairKey *hairkey, Object *object, ParticleSystemModifierData *modifier, ParticleData *particle,
+ float n_co[3])
+{
+
+ DerivedMesh *hairdm = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_dm : NULL;
+ if (particle) {
+ if (hairdm) {
+ MVert *mvert = CDDM_get_vert(hairdm, particle->hair_index + (hairkey - particle->hair));
+ copy_v3_v3(n_co, mvert->co);
+ }
+ else {
+ float hairmat[4][4];
+ psys_mat_hair_to_object(object, modifier->dm, modifier->psys->part->from, particle, hairmat);
+ copy_v3_v3(n_co, hairkey->co);
+ mul_m4_v3(hairmat, n_co);
+ }
+ }
+ else {
+ zero_v3(n_co);
+ }
+}
+
+static void rna_Particle_uv_on_emitter(ParticleData *particle, ParticleSystemModifierData *modifier, float n_uv[2])
+{
+ /*psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0);*/
+
+ /* get uvco & mcol */
+ int num = particle->num_dmcache;
+ int from = modifier->psys->part->from;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = particle->num;
+
+ /* get uvco */
+ if (n_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+ mtface += num;
+
+ psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+}
+
+static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *object, ParticleSystemModifierData *modifier,
+ int particle_no, int step, float n_co[3])
+{
+ ParticleSettings *part = 0;
+ ParticleData *pars = 0;
+ ParticleCacheKey *cache = 0;
+ int totchild = 0;
+ int path_nbr = 0;
+ int totpart;
+ int max_k = 0;
+ int step_nbr = 0;
+
+ if (particlesystem == NULL)
+ return;
+
+ part = particlesystem->part;
+ pars = particlesystem->particles;
+
+ if (particlesystem->renderdata) {
+ step_nbr = part->ren_step;
+ totchild = particlesystem->totchild;
+ }
+ else {
+ step_nbr = part->draw_step;
+ totchild = (int)((float)particlesystem->totchild * (float)(part->disp) / 100.0f);
+ }
+
+ if (part == NULL || pars == NULL || !psys_check_enabled(object, particlesystem))
+ return;
+
+ if (part->ren_as == PART_DRAW_OB || part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_NOT)
+ return;
+
+ /* can happen for disconnected/global hair */
+ if (part->type == PART_HAIR && !particlesystem->childcache)
+ totchild = 0;
+
+ totpart = particlesystem->totpart;
+
+ if (particle_no >= totpart + totchild)
+ return;
+
+ if (part->ren_as == PART_DRAW_PATH && particlesystem->pathcache)
+ path_nbr = (int)pow(2.0, step_nbr);
+
+ if (particle_no < totpart) {
+
+ if (path_nbr) {
+ cache = particlesystem->pathcache[particle_no];
+ max_k = (int)cache->steps;
+ }
+
+ }
+ else {
+
+ if (path_nbr) {
+ cache = particlesystem->childcache[particle_no - totpart];
+
+ if (cache->steps < 0)
+ max_k = 0;
+ else
+ max_k = (int)cache->steps;
+ }
+ }
+
+ /*strands key loop data stored in cache + step->co*/
+ if (path_nbr) {
+ if (step >= 0 && step <= path_nbr) {
+ if (step <= max_k) {
+ copy_v3_v3(n_co, (cache + step)->co);
+ mul_m4_v3(particlesystem->imat, n_co);
+ mul_m4_v3(object->obmat, n_co);
+ }
+ }
+ }
+
+}
+
+static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int uv_no,
+ float n_uv[2])
+{
+ ParticleSettings *part = 0;
+ int totpart;
+ int totchild = 0;
+ int num;
+
+ /* 1. check that everything is ok & updated */
+ if (particlesystem == NULL)
+ return;
+
+ part = particlesystem->part;
+
+ if (particlesystem->renderdata) {
+ totchild = particlesystem->totchild;
+ }
+ else {
+ totchild = (int)((float)particlesystem->totchild * (float)(part->disp) / 100.0f);
+ }
+
+ /* can happen for disconnected/global hair */
+ if (part->type == PART_HAIR && !particlesystem->childcache)
+ totchild = 0;
+
+ totpart = particlesystem->totpart;
+
+ if (particle_no >= totpart + totchild)
+ return;
+
+/* 3. start creating renderable things */
+ /* setup per particle individual stuff */
+ if (particle_no < totpart) {
+
+ /* get uvco & mcol */
+ num = particle->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = particle->num;
+
+ if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
+ mtface += num;
+
+ psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+ }
+ else {
+ ChildParticle *cpa = particlesystem->child + particle_no - totpart;
+
+ num = cpa->num;
+
+ /* get uvco & mcol */
+ if (part->childtype == PART_CHILD_FACES) {
+ if (n_uv && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (cpa->num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
+ mtface += cpa->num;
+
+ psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+ }
+ else {
+ ParticleData *parent = particlesystem->particles + cpa->parent;
+ num = parent->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (parent->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = parent->num;
+
+ if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
+ mtface += num;
+
+ psys_interpolate_uvs(mtface, mface->v4, parent->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+ }
+ }
+}
+
+static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier,
+ ParticleData *particle, int particle_no, int vcol_no,
+ float n_mcol[3])
+{
+ ParticleSettings *part;
+ int totpart;
+ int totchild = 0;
+ int num;
+ MCol mcol = {255, 255, 255, 255};
+
+ /* 1. check that everything is ok & updated */
+ if (particlesystem == NULL)
+ return;
+
+ part = particlesystem->part;
+
+ if (particlesystem->renderdata) {
+ totchild = particlesystem->totchild;
+ }
+ else {
+ totchild = (int)((float)particlesystem->totchild * (float)(part->disp) / 100.0f);
+ }
+
+ /* can happen for disconnected/global hair */
+ if (part->type == PART_HAIR && !particlesystem->childcache)
+ totchild = 0;
+
+ totpart = particlesystem->totpart;
+
+ if (particle_no >= totpart + totchild)
+ return;
+
+ /* 3. start creating renderable things */
+ /* setup per particle individual stuff */
+ if (particle_no < totpart) {
+
+ /* get uvco & mcol */
+ num = particle->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = particle->num;
+
+ if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no);
+ mc += num * 4;
+
+ psys_interpolate_mcol(mc, mface->v4, particle->fuv, &mcol);
+ n_mcol[0] = (float)mcol.b / 255.0f;
+ n_mcol[1] = (float)mcol.g / 255.0f;
+ n_mcol[2] = (float)mcol.r / 255.0f;
+ }
+ else {
+ n_mcol[0] = 0.0f;
+ n_mcol[1] = 0.0f;
+ n_mcol[2] = 0.0f;
+ }
+ }
+ }
+ else {
+ ChildParticle *cpa = particlesystem->child + particle_no - totpart;
+
+ num = cpa->num;
+
+ /* get uvco & mcol */
+ if (part->childtype == PART_CHILD_FACES) {
+ if (n_mcol && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (cpa->num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no);
+ mc += cpa->num * 4;
+
+ psys_interpolate_mcol(mc, mface->v4, cpa->fuv, &mcol);
+ n_mcol[0] = (float)mcol.b / 255.0f;
+ n_mcol[1] = (float)mcol.g / 255.0f;
+ n_mcol[2] = (float)mcol.r / 255.0f;
+ }
+ else {
+ n_mcol[0] = 0.0f;
+ n_mcol[1] = 0.0f;
+ n_mcol[2] = 0.0f;
+ }
+ }
+ }
+ else {
+ ParticleData *parent = particlesystem->particles + cpa->parent;
+ num = parent->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (parent->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = parent->num;
+
+ if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no);
+ mc += num * 4;
+
+ psys_interpolate_mcol(mc, mface->v4, parent->fuv, &mcol);
+ n_mcol[0] = (float)mcol.b / 255.0f;
+ n_mcol[1] = (float)mcol.g / 255.0f;
+ n_mcol[2] = (float)mcol.r / 255.0f;
+ }
+ else {
+ n_mcol[0] = 0.0f;
+ n_mcol[1] = 0.0f;
+ n_mcol[2] = 0.0f;
+ }
+ }
+ }
+ }
+}
+
+static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Scene *scene, Object *object, int resolution)
+{
+ if (resolution == eModifierMode_Render) {
+ ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem);
+ float mat[4][4];
+
+ unit_m4(mat);
+
+ psys_render_set(object, particlesystem, mat, mat, 1, 1, 0.f);
+ psmd->flag &= ~eParticleSystemFlag_psys_updated;
+ particle_system_update(scene, object, particlesystem);
+ }
+ else {
+ if (particlesystem->renderdata)
+ psys_render_restore(object, particlesystem);
+ }
+}
+
static void particle_recalc(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr, short flag)
{
if (ptr->type == &RNA_ParticleSystem) {
@@ -260,7 +622,7 @@ static void rna_Particle_redo(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Particle_redo_dependency(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
rna_Particle_redo(bmain, scene, ptr);
}
@@ -297,7 +659,7 @@ static ParticleSystem *rna_particle_system_for_target(Object *ob, ParticleTarget
return NULL;
}
-static void rna_Particle_target_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Particle_target_reset(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
if (ptr->type == &RNA_ParticleTarget) {
Object *ob = (Object *)ptr->id.data;
@@ -325,7 +687,7 @@ static void rna_Particle_target_reset(Main *bmain, Scene *scene, PointerRNA *ptr
psys->recalc = PSYS_RECALC_RESET;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
@@ -905,6 +1267,7 @@ static void rna_def_particle_hair_key(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
srna = RNA_def_struct(brna, "ParticleHairKey", NULL);
RNA_def_struct_sdna(srna, "HairKey");
@@ -923,11 +1286,24 @@ static void rna_def_particle_hair_key(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, "rna_ParticleHairKey_location_object_get",
"rna_ParticleHairKey_location_object_set", NULL);
- prop = RNA_def_property(srna, "co_hair_space", PROP_FLOAT, PROP_TRANSLATION);
+ prop = RNA_def_property(srna, "co_local", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "co");
RNA_def_property_ui_text(prop, "Location",
- "Location of the hair key in its internal coordinate system, "
+ "Location of the hair key in its local coordinate system, "
"relative to the emitting face");
+
+ /* Aided co func */
+ func = RNA_def_function(srna, "co_object", "rna_ParticleHairKey_co_object");
+ RNA_def_function_ui_description(func, "Obtain hairkey location with particle and modifier data");
+
+ prop = RNA_def_pointer(func, "object", "Object", "", "Object");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_pointer(func, "particle", "Particle", "", "hair particle");
+
+ prop = RNA_def_float_vector(func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co",
+ "Exported hairkey location", -1e4, 1e4);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
}
static void rna_def_particle_key(BlenderRNA *brna)
@@ -979,6 +1355,7 @@ static void rna_def_particle(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
static EnumPropertyItem alive_items[] = {
/*{PARS_KILLED, "KILLED", 0, "Killed", ""}, */
@@ -1083,6 +1460,15 @@ static void rna_def_particle(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Alive State", "");
/* short rt2; */
+
+/* UVs */
+ func = RNA_def_function(srna, "uv_on_emitter", "rna_Particle_uv_on_emitter");
+ RNA_def_function_ui_description(func, "Obtain uv for particle on derived mesh");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
}
static void rna_def_particle_dupliweight(BlenderRNA *brna)
@@ -1112,12 +1498,25 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
+ static EnumPropertyItem sph_solver_items[] = {
+ {SPH_SOLVER_DDR, "DDR", 0, "Double-Density", "An artistic solver with strong surface tension effects (original)"},
+ {SPH_SOLVER_CLASSICAL, "CLASSICAL", 0, "Classical", "A more physically-accurate solver"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "SPHFluidSettings", NULL);
RNA_def_struct_path_func(srna, "rna_SPHFluidSettings_path");
RNA_def_struct_ui_text(srna, "SPH Fluid Settings", "Settings for particle fluids physics");
-
+
/* Fluid settings */
+ prop = RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "solver");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_enum_items(prop, sph_solver_items);
+ RNA_def_property_ui_text(prop, "SPH Solver", "The code used to calculate internal forces on particles");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
prop = RNA_def_property(srna, "spring_force", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_k");
RNA_def_property_range(prop, 0.0f, 100.0f);
@@ -1186,9 +1585,9 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
/* Double density relaxation */
prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness_k");
- RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is");
+ RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is (speed of sound)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "repulsion", PROP_FLOAT, PROP_NONE);
@@ -1201,7 +1600,7 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "rest_density", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rest_density");
- RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_ui_range(prop, 0.0f, 2.0f, 1, 3);
RNA_def_property_ui_text(prop, "Rest Density", "Fluid rest density");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -1538,14 +1937,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
};
/*TODO: names, tooltips */
-#if 0
- static EnumPropertyItem rot_from_items[] = {
- {PART_ROT_KEYS, "KEYS", 0, "keys", ""},
- {PART_ROT_ZINCR, "ZINCR", 0, "zincr", ""},
- {PART_ROT_IINCR, "IINCR", 0, "iincr", ""},
- {0, NULL, 0, NULL, NULL}
- };
-#endif
static EnumPropertyItem integrator_type_items[] = {
{PART_INT_EULER, "EULER", 0, "Euler", ""},
{PART_INT_VERLET, "VERLET", 0, "Verlet", ""},
@@ -1947,15 +2338,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Material", "Material used for the particles");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
-
- /* not used anywhere, why is this in DNA??? */
-#if 0
- prop = RNA_def_property(srna, "rotate_from", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "rotfrom");
- RNA_def_property_enum_items(prop, rot_from_items);
- RNA_def_property_ui_text(prop, "Rotate From", "");
-#endif
-
prop = RNA_def_property(srna, "integrator", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, integrator_type_items);
RNA_def_property_ui_text(prop, "Integration",
@@ -2129,11 +2511,11 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "courant_target", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.01, 10);
- RNA_def_property_float_default(prop, 0.2);
+ RNA_def_property_range(prop, 0.0001, 10);
+ RNA_def_property_float_default(prop, 0.1);
RNA_def_property_ui_text(prop, "Adaptive Subframe Threshold",
"The relative distance a particle can move before requiring more subframes "
- "(target Courant number); 0.1-0.3 is the recommended range");
+ "(target Courant number); 0.01-0.3 is the recommended range");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE);
@@ -2281,7 +2663,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
/* physical properties */
prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.001f, 100000.0f);
+ RNA_def_property_range(prop, 0.00000001f, 100000.0f);
RNA_def_property_ui_range(prop, 0.01, 100, 1, 3);
RNA_def_property_ui_text(prop, "Mass", "Mass of the particles");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -2510,7 +2892,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, "rna_PartSetting_linelentail_get", "rna_PartSetting_linelentail_set", NULL);
RNA_def_property_range(prop, 0.0f, 100000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3);
- RNA_def_property_ui_text(prop, "Back", "Length of the line's tail");
+ RNA_def_property_ui_text(prop, "Tail", "Length of the line's tail");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop = RNA_def_property(srna, "line_length_head", PROP_FLOAT, PROP_NONE);
@@ -2683,6 +3065,13 @@ static void rna_def_particle_system(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+
+ static EnumPropertyItem resolution_items[] = {
+ {eModifierMode_Realtime, "PREVIEW", 0, "Preview", "Apply modifier preview settings"},
+ {eModifierMode_Render, "RENDER", 0, "Render", "Apply modifier render settings"},
+ {0, NULL, 0, NULL, NULL}
+ };
srna = RNA_def_struct(brna, "ParticleSystem", NULL);
RNA_def_struct_ui_text(srna, "Particle System", "Particle system in an object");
@@ -2780,7 +3169,6 @@ static void rna_def_particle_system(BlenderRNA *brna)
"rna_ParticleSystem_active_particle_target_index_range");
RNA_def_property_ui_text(prop, "Active Particle Target Index", "");
-
/* billboard */
prop = RNA_def_property(srna, "billboard_normal_uv", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "bb_uvname[0]");
@@ -2982,6 +3370,52 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_struct_path_func(srna, "rna_ParticleSystem_path");
+
+ /* set viewport or render resolution */
+ func = RNA_def_function(srna, "set_resolution", "rna_ParticleSystem_set_resolution");
+ RNA_def_function_ui_description(func, "Set the resolution to use for the number of particles");
+ prop = RNA_def_pointer(func, "scene", "Scene", "", "Scene");
+ prop = RNA_def_pointer(func, "object", "Object", "", "Object");
+ prop = RNA_def_enum(func, "resolution", resolution_items, 0, "", "Resolution settings to apply");
+
+ /* extract cached hair location data */
+ func = RNA_def_function(srna, "co_hair", "rna_ParticleSystem_co_hair");
+ RNA_def_function_ui_description(func, "Obtain cache hair data");
+
+ prop = RNA_def_pointer(func, "object", "Object", "", "Object");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_int(func, "step", 0, INT_MIN, INT_MAX, "step no", "", INT_MIN, INT_MAX);
+
+ prop = RNA_def_float_vector(func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co",
+ "Exported hairkey location", -1e4, 1e4);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
+
+ /* extract hair UVs */
+ func = RNA_def_function(srna, "uv_on_emitter", "rna_ParticleSystem_uv_on_emitter");
+ RNA_def_function_ui_description(func, "Obtain uv for all particles");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
+ prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_int(func, "uv_no", 0, INT_MIN, INT_MAX, "UV no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
+
+ /* extract hair mcols */
+ func = RNA_def_function(srna, "mcol_on_emitter", "rna_ParticleSystem_mcol_on_emitter");
+ RNA_def_function_ui_description(func, "Obtain mcol for all particles");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
+ prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_int(func, "vcol_no", 0, INT_MIN, INT_MAX, "vcol no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_property(func, "mcol", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
+
}
void RNA_def_particle(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 5c90fb8787c..1ed675962f3 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -187,13 +187,13 @@ static void rna_Pose_ik_solver_set(struct PointerRNA *ptr, int value)
}
}
-static void rna_Pose_ik_solver_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Pose_ik_solver_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Object *ob = ptr->id.data;
bPose *pose = ptr->data;
pose->flag |= POSE_RECALC; /* checks & sorts pose channels */
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
BKE_pose_update_constraint_flags(pose);
@@ -472,14 +472,14 @@ static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *r
static PointerRNA rna_PoseChannel_active_constraint_get(PointerRNA *ptr)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- bConstraint *con = constraints_get_active(&pchan->constraints);
+ bConstraint *con = BKE_constraints_get_active(&pchan->constraints);
return rna_pointer_inherit_refine(ptr, &RNA_Constraint, con);
}
static void rna_PoseChannel_active_constraint_set(PointerRNA *ptr, PointerRNA value)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- constraints_set_active(&pchan->constraints, (bConstraint *)value.data);
+ BKE_constraints_set_active(&pchan->constraints, (bConstraint *)value.data);
}
static bConstraint *rna_PoseChannel_constraints_new(bPoseChannel *pchan, int type)
@@ -487,7 +487,7 @@ static bConstraint *rna_PoseChannel_constraints_new(bPoseChannel *pchan, int typ
/*WM_main_add_notifier(NC_OBJECT|ND_CONSTRAINT|NA_ADDED, object); */
/* TODO, pass object also */
/* TODO, new pose bones don't have updated draw flags */
- return add_pose_constraint(NULL, pchan, NULL, type);
+ return BKE_add_pose_constraint(NULL, pchan, NULL, type);
}
static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, ReportList *reports, PointerRNA *con_ptr)
@@ -501,12 +501,12 @@ static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, Repo
return;
}
- remove_constraint(&pchan->constraints, con);
+ BKE_remove_constraint(&pchan->constraints, con);
RNA_POINTER_INVALIDATE(con_ptr);
ED_object_constraint_update(ob);
- constraints_set_active(&pchan->constraints, NULL); /* XXX, is this really needed? - Campbell */
+ BKE_constraints_set_active(&pchan->constraints, NULL); /* XXX, is this really needed? - Campbell */
WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, id);
@@ -786,14 +786,14 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_location_editable");
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
- RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_scale_editable");
RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Scale", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
prop = RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
RNA_def_property_float_sdna(prop, NULL, "quat");
@@ -1246,7 +1246,7 @@ static void rna_def_bone_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_ui_text(prop, "Active Bone Group", "Active bone group for this pose");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "active_group");
RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set",
"rna_Pose_active_bone_group_index_range");
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 46b22cd0963..5931440b422 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -137,7 +137,7 @@ static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *nt
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
- RNA_pointer_create((ID*)ntree, &RNA_Node, node, &nodeptr);
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &nodeptr);
func = &rna_RenderEngine_update_script_node_func;
RNA_parameter_list_create(&list, &ptr, func);
@@ -196,7 +196,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
et = MEM_callocN(sizeof(RenderEngineType), "python render engine");
memcpy(et, &dummyet, sizeof(dummyet));
- et->ext.srna = RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine");
+ et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine);
et->ext.data = data;
et->ext.call = call;
et->ext.free = free;
@@ -406,13 +406,16 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "resolution_y");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES);
+
/* registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->idname");
RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
- prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->name");
RNA_def_property_flag(prop, PROP_REGISTER);
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
new file mode 100644
index 00000000000..171bc702bc5
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -0,0 +1,1150 @@
+/*
+ * ***** 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): Blender Foundation 2013, Joshua Leung, Sergej Reich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file rna_rigidbody.c
+ * \ingroup rna
+ * \brief RNA property definitions for Rigid Body datatypes
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
+#include "DNA_rigidbody_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "WM_types.h"
+
+/* roles of objects in RigidBody Sims */
+EnumPropertyItem rigidbody_ob_type_items[] = {
+ {RBO_TYPE_ACTIVE, "ACTIVE", 0, "Active", "Object is directly controlled by simulation results"},
+ {RBO_TYPE_PASSIVE, "PASSIVE", 0, "Passive", "Object is directly controlled by animation system"},
+ {0, NULL, 0, NULL, NULL}};
+
+/* collision shapes of objects in rigid body sim */
+EnumPropertyItem rigidbody_ob_shape_items[] = {
+ {RB_SHAPE_BOX, "BOX", ICON_MESH_CUBE, "Box", "Box-like shapes (i.e. cubes), including planes (i.e. ground planes)"},
+ {RB_SHAPE_SPHERE, "SPHERE", ICON_MESH_UVSPHERE, "Sphere", ""},
+ {RB_SHAPE_CAPSULE, "CAPSULE", ICON_OUTLINER_OB_META, "Capsule", ""},
+ {RB_SHAPE_CYLINDER, "CYLINDER", ICON_MESH_CYLINDER, "Cylinder", ""},
+ {RB_SHAPE_CONE, "CONE", ICON_MESH_CONE, "Cone", ""},
+ {RB_SHAPE_CONVEXH, "CONVEX_HULL", ICON_MESH_ICOSPHERE, "Convex Hull",
+ "A mesh-like surface encompassing (i.e. shrinkwrap over) all vertices (best results with "
+ "fewer vertices)"},
+ {RB_SHAPE_TRIMESH, "MESH", ICON_MESH_MONKEY, "Mesh",
+ "Mesh consisting of triangles only, allowing for more detailed interactions than convex hulls"},
+ {0, NULL, 0, NULL, NULL}};
+
+/* collision shapes of constraints in rigid body sim */
+EnumPropertyItem rigidbody_con_type_items[] = {
+ {RBC_TYPE_FIXED, "FIXED", ICON_NONE, "Fixed", "Glue rigid bodies together"},
+ {RBC_TYPE_POINT, "POINT", ICON_NONE, "Point", "Constrain rigid bodies to move around common pivot point"},
+ {RBC_TYPE_HINGE, "HINGE", ICON_NONE, "Hinge", "Restrict rigid body rotation to one axis"},
+ {RBC_TYPE_SLIDER, "SLIDER", ICON_NONE, "Slider", "Restrict rigid body translation to one axis"},
+ {RBC_TYPE_PISTON, "PISTON", ICON_NONE, "Piston", "Restrict rigid body translation and rotation to one axis"},
+ {RBC_TYPE_6DOF, "GENERIC", ICON_NONE, "Generic", "Restrict translation and rotation to specified axes"},
+ {RBC_TYPE_6DOF_SPRING, "GENERIC_SPRING", ICON_NONE, "Generic Spring",
+ "Restrict translation and rotation to specified axes with springs"},
+ {RBC_TYPE_MOTOR, "MOTOR", ICON_NONE, "Motor", "Drive rigid body around or along an axis"},
+ {0, NULL, 0, NULL, NULL}};
+
+
+#ifdef RNA_RUNTIME
+
+#ifdef WITH_BULLET
+# include "RBI_api.h"
+#endif
+
+#include "BKE_depsgraph.h"
+#include "BKE_rigidbody.h"
+
+#define RB_FLAG_SET(dest, value, flag) { \
+ if (value) \
+ dest |= flag; \
+ else \
+ dest &= ~flag; \
+}
+
+
+/* ******************************** */
+
+static void rna_RigidBodyWorld_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
+
+ BKE_rigidbody_cache_reset(rbw);
+}
+
+static char *rna_RigidBodyWorld_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("rigidbody_world");
+}
+
+static void rna_RigidBodyWorld_num_solver_iterations_set(PointerRNA *ptr, int value)
+{
+ RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
+
+ rbw->num_solver_iterations = value;
+
+#ifdef WITH_BULLET
+ if (rbw->physics_world) {
+ RB_dworld_set_solver_iterations(rbw->physics_world, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyWorld_split_impulse_set(PointerRNA *ptr, int value)
+{
+ RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
+
+ RB_FLAG_SET(rbw->flag, value, RBW_FLAG_USE_SPLIT_IMPULSE);
+
+#ifdef WITH_BULLET
+ if (rbw->physics_world) {
+ RB_dworld_set_split_impulse(rbw->physics_world, value);
+ }
+#endif
+}
+
+/* ******************************** */
+
+static void rna_RigidBodyOb_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+
+ BKE_rigidbody_cache_reset(rbw);
+}
+
+static void rna_RigidBodyOb_shape_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ BKE_rigidbody_cache_reset(rbw);
+ if (rbo->physics_shape)
+ rbo->flag |= RBO_FLAG_NEEDS_RESHAPE;
+}
+
+static char *rna_RigidBodyOb_path(PointerRNA *ptr)
+{
+ /* NOTE: this hardcoded path should work as long as only Objects have this */
+ return BLI_sprintfN("rigid_body");
+}
+
+static void rna_RigidBodyOb_type_set(PointerRNA *ptr, int value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->type = value;
+ rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
+}
+
+static void rna_RigidBodyOb_disabled_set(PointerRNA *ptr, int value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ RB_FLAG_SET(rbo->flag, !value, RBO_FLAG_DISABLED);
+
+#ifdef WITH_BULLET
+ /* update kinematic state if necessary - only needed for active bodies */
+ if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) {
+ RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ RB_body_set_kinematic_state(rbo->physics_object, !value);
+ rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_mass_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->mass = value;
+
+#ifdef WITH_BULLET
+ /* only active bodies need mass update */
+ if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) {
+ RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_friction_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->friction = value;
+
+#ifdef WITH_BULLET
+ if (rbo->physics_object) {
+ RB_body_set_friction(rbo->physics_object, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_restitution_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->restitution = value;
+#ifdef WITH_BULLET
+ if (rbo->physics_object) {
+ RB_body_set_restitution(rbo->physics_object, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_collision_margin_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->margin = value;
+
+#ifdef WITH_BULLET
+ if (rbo->physics_shape) {
+ RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo));
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_collision_groups_set(PointerRNA *ptr, const int *values)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+ int i;
+
+ for (i = 0; i < 20; i++) {
+ if (values[i])
+ rbo->col_groups |= (1 << i);
+ else
+ rbo->col_groups &= ~(1 << i);
+ }
+ rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
+}
+
+static void rna_RigidBodyOb_kinematic_state_set(PointerRNA *ptr, int value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ RB_FLAG_SET(rbo->flag, value, RBO_FLAG_KINEMATIC);
+
+#ifdef WITH_BULLET
+ /* update kinematic state if necessary */
+ if (rbo->physics_object) {
+ RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ RB_body_set_kinematic_state(rbo->physics_object, value);
+ rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_activation_state_set(PointerRNA *ptr, int value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ RB_FLAG_SET(rbo->flag, value, RBO_FLAG_USE_DEACTIVATION);
+
+#ifdef WITH_BULLET
+ /* update activation state if necessary - only active bodies can be deactivated */
+ if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) {
+ RB_body_set_activation_state(rbo->physics_object, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_linear_sleepThresh_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->lin_sleep_thresh = value;
+
+#ifdef WITH_BULLET
+ /* only active bodies need sleep threshold update */
+ if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) {
+ RB_body_set_linear_sleep_thresh(rbo->physics_object, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_angular_sleepThresh_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->ang_sleep_thresh = value;
+
+#ifdef WITH_BULLET
+ /* only active bodies need sleep threshold update */
+ if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) {
+ RB_body_set_angular_sleep_thresh(rbo->physics_object, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_linear_damping_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->lin_damping = value;
+
+#ifdef WITH_BULLET
+ /* only active bodies need damping update */
+ if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) {
+ RB_body_set_linear_damping(rbo->physics_object, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyOb_angular_damping_set(PointerRNA *ptr, float value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->ang_damping = value;
+
+#ifdef WITH_BULLET
+ /* only active bodies need damping update */
+ if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) {
+ RB_body_set_angular_damping(rbo->physics_object, value);
+ }
+#endif
+}
+
+static char *rna_RigidBodyCon_path(PointerRNA *ptr)
+{
+ /* NOTE: this hardcoded path should work as long as only Objects have this */
+ return BLI_sprintfN("rigid_body_constraint");
+}
+
+static void rna_RigidBodyCon_type_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->type = value;
+ rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
+}
+
+static void rna_RigidBodyCon_enabled_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ RB_FLAG_SET(rbc->flag, value, RBC_FLAG_ENABLED);
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_enabled(rbc->physics_constraint, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_disable_collisions_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ RB_FLAG_SET(rbc->flag, value, RBC_FLAG_DISABLE_COLLISIONS);
+
+ rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
+}
+
+static void rna_RigidBodyCon_use_breaking_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ if (value) {
+ rbc->flag |= RBC_FLAG_USE_BREAKING;
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_breaking_threshold(rbc->physics_constraint, rbc->breaking_threshold);
+ }
+#endif
+ }
+ else {
+ rbc->flag &= ~RBC_FLAG_USE_BREAKING;
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_breaking_threshold(rbc->physics_constraint, FLT_MAX);
+ }
+#endif
+ }
+}
+
+static void rna_RigidBodyCon_breaking_threshold_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->breaking_threshold = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && (rbc->flag & RBC_FLAG_USE_BREAKING)) {
+ RB_constraint_set_breaking_threshold(rbc->physics_constraint, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_override_solver_iterations_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ if (value) {
+ rbc->flag |= RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS;
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_solver_iterations(rbc->physics_constraint, rbc->num_solver_iterations);
+ }
+#endif
+ }
+ else {
+ rbc->flag &= ~RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS;
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_solver_iterations(rbc->physics_constraint, -1);
+ }
+#endif
+ }
+}
+
+static void rna_RigidBodyCon_num_solver_iterations_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->num_solver_iterations = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && (rbc->flag & RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS)) {
+ RB_constraint_set_solver_iterations(rbc->physics_constraint, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->spring_stiffness_x = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X)) {
+ RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_spring_stiffness_y_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->spring_stiffness_y = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y)) {
+ RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_spring_stiffness_z_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->spring_stiffness_z = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z)) {
+ RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->spring_damping_x = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X)) {
+ RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_spring_damping_y_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->spring_damping_y = value;
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y)) {
+ RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->spring_damping_z = value;
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z)) {
+ RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_motor_lin_max_impulse_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_lin_max_impulse = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_max_impulse_motor(rbc->physics_constraint, value, rbc->motor_ang_max_impulse);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_use_motor_lin_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ RB_FLAG_SET(rbc->flag, value, RBC_FLAG_USE_MOTOR_LIN);
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_use_motor_ang_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ RB_FLAG_SET(rbc->flag, value, RBC_FLAG_USE_MOTOR_ANG);
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_motor_lin_target_velocity_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_lin_target_velocity = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_target_velocity_motor(rbc->physics_constraint, value, rbc->motor_ang_target_velocity);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_motor_ang_max_impulse_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_ang_max_impulse = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_motor_ang_target_velocity_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_ang_target_velocity = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, value);
+ }
+#endif
+}
+
+
+#else
+
+static void rna_def_rigidbody_world(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "RigidBodyWorld", NULL);
+ RNA_def_struct_sdna(srna, "RigidBodyWorld");
+ RNA_def_struct_ui_text(srna, "Rigid Body World", "Self-contained rigid body simulation environment and settings");
+ RNA_def_struct_path_func(srna, "rna_RigidBodyWorld_path");
+
+ /* groups */
+ prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Group");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_ui_text(prop, "Group", "Group containing objects participating in this simulation");
+ RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
+
+ prop = RNA_def_property(srna, "constraints", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Group");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_ui_text(prop, "Constraints", "Group containing rigid body constraint objects");
+ RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
+
+ /* booleans */
+ prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", RBW_FLAG_MUTED);
+ RNA_def_property_ui_text(prop, "Enabled", "Simulation will be evaluated");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ /* time scale */
+ prop = RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "time_scale");
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Time Scale", "Change the speed of the simulation");
+ RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
+
+ /* timestep */
+ prop = RNA_def_property(srna, "steps_per_second", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "steps_per_second");
+ RNA_def_property_range(prop, 1, SHRT_MAX);
+ RNA_def_property_ui_range(prop, 60, 1000, 1, 0);
+ RNA_def_property_int_default(prop, 60);
+ RNA_def_property_ui_text(prop, "Steps Per Second",
+ "Number of simulation steps taken per second (higher values are more accurate "
+ "but slower)");
+ RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
+
+ /* constraint solver iterations */
+ prop = RNA_def_property(srna, "num_solver_iterations", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "num_solver_iterations");
+ RNA_def_property_range(prop, 1, 1000);
+ RNA_def_property_ui_range(prop, 10, 100, 1, 0);
+ RNA_def_property_int_default(prop, 10);
+ RNA_def_property_int_funcs(prop, NULL, "rna_RigidBodyWorld_num_solver_iterations_set", NULL);
+ RNA_def_property_ui_text(prop, "Solver Iterations",
+ "Number of constraint solver iterations made per simulation step (higher values are more "
+ "accurate but slower)");
+ RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
+
+ /* split impulse */
+ prop = RNA_def_property(srna, "use_split_impulse", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBW_FLAG_USE_SPLIT_IMPULSE);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyWorld_split_impulse_set");
+ RNA_def_property_ui_text(prop, "Split Impulse",
+ "Reduce extra velocity that can build up when objects collide (lowers simulation "
+ "stability a little so use only when necessary)");
+ RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
+
+ /* cache */
+ prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "pointcache");
+ RNA_def_property_ui_text(prop, "Point Cache", "");
+
+ /* effector weights */
+ prop = RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "EffectorWeights");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Effector Weights", "");
+}
+
+static void rna_def_rigidbody_object(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+
+ srna = RNA_def_struct(brna, "RigidBodyObject", NULL);
+ RNA_def_struct_sdna(srna, "RigidBodyOb");
+ RNA_def_struct_ui_text(srna, "Rigid Body Object", "Settings for object participating in Rigid Body Simulation");
+ RNA_def_struct_path_func(srna, "rna_RigidBodyOb_path");
+
+ /* Enums */
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, rigidbody_ob_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RigidBodyOb_type_set", NULL);
+ RNA_def_property_ui_text(prop, "Type", "Role of object in Rigid Body Simulations");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* booleans */
+ prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", RBO_FLAG_DISABLED);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyOb_disabled_set");
+ RNA_def_property_ui_text(prop, "Enabled", "Rigid Body actively participates to the simulation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "collision_shape", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "shape");
+ RNA_def_property_enum_items(prop, rigidbody_ob_shape_items);
+ RNA_def_property_ui_text(prop, "Collision Shape", "Collision Shape of object in Rigid Body Simulations");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "kinematic", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_KINEMATIC);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyOb_kinematic_state_set");
+ RNA_def_property_ui_text(prop, "Kinematic", "Allow rigid body to be controlled by the animation system");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* Physics Parameters */
+ prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_UNIT_MASS);
+ RNA_def_property_float_sdna(prop, NULL, "mass");
+ RNA_def_property_range(prop, 0.001f, FLT_MAX); // range must always be positive (and non-zero)
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_mass_set", NULL);
+ RNA_def_property_ui_text(prop, "Mass", "How much the object 'weighs' irrespective of gravity");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* Dynamics Parameters - Activation */
+ // TODO: define and figure out how to implement these
+
+ /* Dynamics Parameters - Deactivation */
+ prop = RNA_def_property(srna, "use_deactivation", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_DEACTIVATION);
+ RNA_def_property_boolean_default(prop, TRUE);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyOb_activation_state_set");
+ RNA_def_property_ui_text(prop, "Enable Deactivation",
+ "Enable deactivation of resting rigid bodies (increases performance and stability "
+ "but can cause glitches)");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "start_deactivated", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_START_DEACTIVATED);
+ RNA_def_property_ui_text(prop, "Start Deactivated", "Deactivate rigid body at the start of the simulation");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "deactivate_linear_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY);
+ RNA_def_property_float_sdna(prop, NULL, "lin_sleep_thresh");
+ RNA_def_property_range(prop, FLT_MIN, FLT_MAX); // range must always be positive (and non-zero)
+ RNA_def_property_float_default(prop, 0.4f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_linear_sleepThresh_set", NULL);
+ RNA_def_property_ui_text(prop, "Linear Velocity Deactivation Threshold",
+ "Linear Velocity below which simulation stops simulating object");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "deactivate_angular_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY);
+ RNA_def_property_float_sdna(prop, NULL, "ang_sleep_thresh");
+ RNA_def_property_range(prop, FLT_MIN, FLT_MAX); // range must always be positive (and non-zero)
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_angular_sleepThresh_set", NULL);
+ RNA_def_property_ui_text(prop, "Angular Velocity Deactivation Threshold",
+ "Angular Velocity below which simulation stops simulating object");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* Dynamics Parameters - Damping Parameters */
+ prop = RNA_def_property(srna, "linear_damping", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "lin_damping");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 0.04f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_linear_damping_set", NULL);
+ RNA_def_property_ui_text(prop, "Linear Damping", "Amount of linear velocity that is lost over time");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "angular_damping", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "ang_damping");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 0.1f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_angular_damping_set", NULL);
+ RNA_def_property_ui_text(prop, "Angular Damping", "Amount of angular velocity that is lost over time");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* Collision Parameters - Surface Parameters */
+ prop = RNA_def_property(srna, "friction", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "friction");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_friction_set", NULL);
+ RNA_def_property_ui_text(prop, "Friction", "Resistance of object to movement");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "restitution", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "restitution");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
+ RNA_def_property_float_default(prop, 0.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_restitution_set", NULL);
+ RNA_def_property_ui_text(prop, "Restitution",
+ "Tendency of object to bounce after colliding with another "
+ "(0 = stays still, 1 = perfectly elastic)");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* Collision Parameters - Sensitivity */
+ prop = RNA_def_property(srna, "use_margin", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_MARGIN);
+ RNA_def_property_boolean_default(prop, FALSE);
+ RNA_def_property_ui_text(prop, "Collision Margin",
+ "Use custom collision margin (some shapes will have a visible gap around them)");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_shape_reset");
+
+ prop = RNA_def_property(srna, "collision_margin", PROP_FLOAT, PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "margin");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01, 3);
+ RNA_def_property_float_default(prop, 0.04f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_collision_margin_set", NULL);
+ RNA_def_property_ui_text(prop, "Collision Margin",
+ "Threshold of distance near surface where collisions are still considered "
+ "(best results when non-zero)");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_shape_reset");
+
+ prop = RNA_def_property(srna, "collision_groups", PROP_BOOLEAN, PROP_LAYER_MEMBER);
+ RNA_def_property_boolean_sdna(prop, NULL, "col_groups", 1);
+ RNA_def_property_array(prop, 20);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyOb_collision_groups_set");
+ RNA_def_property_ui_text(prop, "Collision Groups", "Collision Groups Rigid Body belongs to");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+ RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+}
+
+static void rna_def_rigidbody_constraint(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "RigidBodyConstraint", NULL);
+ RNA_def_struct_sdna(srna, "RigidBodyCon");
+ RNA_def_struct_ui_text(srna, "Rigid Body Constraint",
+ "Constraint influencing Objects inside Rigid Body Simulation");
+ RNA_def_struct_path_func(srna, "rna_RigidBodyCon_path");
+
+ /* Enums */
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, rigidbody_con_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RigidBodyCon_type_set", NULL);
+ RNA_def_property_ui_text(prop, "Type", "Type of Rigid Body Constraint");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_ENABLED);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_enabled_set");
+ RNA_def_property_ui_text(prop, "Enabled", "Enable this constraint");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "disable_collisions", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_DISABLE_COLLISIONS);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_disable_collisions_set");
+ RNA_def_property_ui_text(prop, "Disable Collisions", "Disable collisions between constrained rigid bodies");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "object1", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "ob1");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Object 1", "First Rigid Body Object to be constrained");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "object2", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "ob2");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Object 2", "Second Rigid Body Object to be constrained");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* Breaking Threshold */
+ prop = RNA_def_property(srna, "use_breaking", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_BREAKING);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_breaking_set");
+ RNA_def_property_ui_text(prop, "Breakable",
+ "Constraint can be broken if it receives an impulse above the threshold");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "breaking_threshold", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "breaking_threshold");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 1000.0f, 100.0, 2);
+ RNA_def_property_float_default(prop, 10.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_breaking_threshold_set", NULL);
+ RNA_def_property_ui_text(prop, "Breaking Threshold",
+ "Impulse threshold that must be reached for the constraint to break");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ /* Solver Iterations */
+ prop = RNA_def_property(srna, "override_solver_iterations", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_override_solver_iterations_set");
+ RNA_def_property_ui_text(prop, "Override Solver Iterations",
+ "Override the number of solver iterations for this constraint");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "num_solver_iterations", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "num_solver_iterations");
+ RNA_def_property_range(prop, 1, 1000);
+ RNA_def_property_ui_range(prop, 1, 100, 1, 0);
+ RNA_def_property_int_default(prop, 10);
+ RNA_def_property_int_funcs(prop, NULL, "rna_RigidBodyCon_num_solver_iterations_set", NULL);
+ RNA_def_property_ui_text(prop, "Solver Iterations",
+ "Number of constraint solver iterations made per simulation step (higher values are more "
+ "accurate but slower)");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ /* Limits */
+ prop = RNA_def_property(srna, "use_limit_lin_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_LIMIT_LIN_X);
+ RNA_def_property_ui_text(prop, "X Axis", "Limit translation on X axis");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_limit_lin_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_LIMIT_LIN_Y);
+ RNA_def_property_ui_text(prop, "Y Axis", "Limit translation on Y axis");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_limit_lin_z", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_LIMIT_LIN_Z);
+ RNA_def_property_ui_text(prop, "Z Axis", "Limit translation on Z axis");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_limit_ang_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_LIMIT_ANG_X);
+ RNA_def_property_ui_text(prop, "X Angle", "Limit rotation around X axis");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_limit_ang_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_LIMIT_ANG_Y);
+ RNA_def_property_ui_text(prop, "Y Angle", "Limit rotation around Y axis");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_limit_ang_z", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_LIMIT_ANG_Z);
+ RNA_def_property_ui_text(prop, "Z Angle", "Limit rotation around Z axis");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_spring_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_X);
+ RNA_def_property_ui_text(prop, "X Spring", "Enable spring on X axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_spring_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_Y);
+ RNA_def_property_ui_text(prop, "Y Spring", "Enable spring on Y axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_spring_z", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_Z);
+ RNA_def_property_ui_text(prop, "Z Spring", "Enable spring on Z axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_motor_lin", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_LIN);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_lin_set");
+ RNA_def_property_ui_text(prop, "Linear Motor", "Enable linear motor");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_motor_ang", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_ANG);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_ang_set");
+ RNA_def_property_ui_text(prop, "Angular Motor", "Enable angular motor");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_lin_x_lower", PROP_FLOAT, PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "limit_lin_x_lower");
+ RNA_def_property_float_default(prop, -1.0f);
+ RNA_def_property_ui_text(prop, "Lower X Limit", "Lower limit of X axis translation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_lin_x_upper", PROP_FLOAT, PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "limit_lin_x_upper");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Upper X Limit", "Upper limit of X axis translation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_lin_y_lower", PROP_FLOAT, PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "limit_lin_y_lower");
+ RNA_def_property_float_default(prop, -1.0f);
+ RNA_def_property_ui_text(prop, "Lower Y Limit", "Lower limit of Y axis translation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_lin_y_upper", PROP_FLOAT, PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "limit_lin_y_upper");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Upper Y Limit", "Upper limit of Y axis translation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_lin_z_lower", PROP_FLOAT, PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "limit_lin_z_lower");
+ RNA_def_property_float_default(prop, -1.0f);
+ RNA_def_property_ui_text(prop, "Lower Z Limit", "Lower limit of Z axis translation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_lin_z_upper", PROP_FLOAT, PROP_UNIT_LENGTH);
+ RNA_def_property_float_sdna(prop, NULL, "limit_lin_z_upper");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Upper Z Limit", "Upper limit of Z axis translation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_ang_x_lower", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "limit_ang_x_lower");
+ RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
+ RNA_def_property_float_default(prop, -M_PI_4);
+ RNA_def_property_ui_text(prop, "Lower X Angle Limit", "Lower limit of X axis rotation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_ang_x_upper", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "limit_ang_x_upper");
+ RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
+ RNA_def_property_float_default(prop, M_PI_4);
+ RNA_def_property_ui_text(prop, "Upper X Angle Limit", "Upper limit of X axis rotation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_ang_y_lower", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "limit_ang_y_lower");
+ RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
+ RNA_def_property_float_default(prop, -M_PI_4);
+ RNA_def_property_ui_text(prop, "Lower Y Angle Limit", "Lower limit of Y axis rotation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_ang_y_upper", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "limit_ang_y_upper");
+ RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
+ RNA_def_property_float_default(prop, M_PI_4);
+ RNA_def_property_ui_text(prop, "Upper Y Angle Limit", "Upper limit of Y axis rotation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_ang_z_lower", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "limit_ang_z_lower");
+ RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
+ RNA_def_property_float_default(prop, -M_PI_4);
+ RNA_def_property_ui_text(prop, "Lower Z Angle Limit", "Lower limit of Z axis rotation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "limit_ang_z_upper", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "limit_ang_z_upper");
+ RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
+ RNA_def_property_float_default(prop, M_PI_4);
+ RNA_def_property_ui_text(prop, "Upper Z Angle Limit", "Upper limit of Z axis rotation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "spring_stiffness_x", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_x");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 10.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_x_set", NULL);
+ RNA_def_property_ui_text(prop, "X Axis Stiffness", "Stiffness on the X axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "spring_stiffness_y", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_y");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 10.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_y_set", NULL);
+ RNA_def_property_ui_text(prop, "Y Axis Stiffness", "Stiffness on the Y axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "spring_stiffness_z", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_z");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 10.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_z_set", NULL);
+ RNA_def_property_ui_text(prop, "Z Axis Stiffness", "Stiffness on the Z axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "spring_damping_x", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "spring_damping_x");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_x_set", NULL);
+ RNA_def_property_ui_text(prop, "Damping X", "Damping on the X axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "spring_damping_y", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "spring_damping_y");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_y_set", NULL);
+ RNA_def_property_ui_text(prop, "Damping Y", "Damping on the Y axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "spring_damping_z", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "spring_damping_z");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_z_set", NULL);
+ RNA_def_property_ui_text(prop, "Damping Z", "Damping on the Z axis");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "motor_lin_target_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY);
+ RNA_def_property_float_sdna(prop, NULL, "motor_lin_target_velocity");
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+ RNA_def_property_ui_range(prop, -100.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_lin_target_velocity_set", NULL);
+ RNA_def_property_ui_text(prop, "Target Velocity", "Target linear motor velocity");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "motor_lin_max_impulse", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "motor_lin_max_impulse");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_lin_max_impulse_set", NULL);
+ RNA_def_property_ui_text(prop, "Max Impulse", "Maximum linear motor impulse");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "motor_ang_target_velocity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "motor_ang_target_velocity");
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+ RNA_def_property_ui_range(prop, -100.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_ang_target_velocity_set", NULL);
+ RNA_def_property_ui_text(prop, "Target Velocity", "Target angular motor velocity");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "motor_ang_max_impulse", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "motor_ang_max_impulse");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_ang_max_impulse_set", NULL);
+ RNA_def_property_ui_text(prop, "Max Impulse", "Maximum angular motor impulse");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+}
+
+void RNA_def_rigidbody(BlenderRNA *brna)
+{
+ rna_def_rigidbody_world(brna);
+ rna_def_rigidbody_object(brna);
+ rna_def_rigidbody_constraint(brna);
+}
+
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 7355e464fc3..9bd20d854e7 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -31,6 +31,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "rna_internal.h"
@@ -45,6 +46,9 @@ EnumPropertyItem property_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
+/* XXX Keep in sync with bpy_props.c's property_subtype_xxx_items ???
+ * Currently it is not...
+ */
EnumPropertyItem property_subtype_items[] = {
{PROP_NONE, "NONE", 0, "None", ""},
@@ -52,7 +56,7 @@ EnumPropertyItem property_subtype_items[] = {
{PROP_FILEPATH, "FILEPATH", 0, "File Path", ""},
{PROP_DIRPATH, "DIRPATH", 0, "Directory Path", ""},
{PROP_FILENAME, "FILENAME", 0, "File Name", ""},
- {PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
+ {PROP_PASSWORD, "PASSWORD", 0, "Password", "A string that is displayed hidden ('********')"},
/* numbers */
{PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""},
@@ -522,6 +526,13 @@ static int rna_Property_unit_get(PointerRNA *ptr)
return RNA_SUBTYPE_UNIT(prop->subtype);
}
+static int rna_Property_icon_get(PointerRNA *ptr)
+{
+ PropertyRNA *prop = (PropertyRNA *)ptr->data;
+ rna_idproperty_check(&prop, ptr);
+ return prop->icon;
+}
+
static int rna_Property_readonly_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
@@ -880,6 +891,11 @@ static int rna_EnumPropertyItem_value_get(PointerRNA *ptr)
return ((EnumPropertyItem *)ptr->data)->value;
}
+static int rna_EnumPropertyItem_icon_get(PointerRNA *ptr)
+{
+ return ((EnumPropertyItem *)ptr->data)->icon;
+}
+
static PointerRNA rna_PointerProperty_fixed_type_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
@@ -930,7 +946,7 @@ static int rna_Function_registered_get(PointerRNA *ptr)
static int rna_Function_registered_optional_get(PointerRNA *ptr)
{
FunctionRNA *func = (FunctionRNA *)ptr->data;
- return func->flag & FUNC_REGISTER_OPTIONAL;
+ return func->flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER);
}
static int rna_Function_no_self_get(PointerRNA *ptr)
@@ -939,6 +955,12 @@ static int rna_Function_no_self_get(PointerRNA *ptr)
return !(func->flag & FUNC_NO_SELF);
}
+static int rna_Function_use_self_type_get(PointerRNA *ptr)
+{
+ FunctionRNA *func = (FunctionRNA *)ptr->data;
+ return (func->flag & FUNC_USE_SELF_TYPE);
+}
+
/* Blender RNA */
static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@@ -1125,6 +1147,12 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_property_enum_funcs(prop, "rna_Property_unit_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Unit", "Type of units for this property");
+ prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_items(prop, icon_items);
+ RNA_def_property_enum_funcs(prop, "rna_Property_icon_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
+
prop = RNA_def_property(srna, "is_readonly", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Property_readonly_get", NULL);
@@ -1230,7 +1258,13 @@ static void rna_def_function(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Function_no_self_get", NULL);
RNA_def_property_ui_text(prop, "No Self",
- "Function does not pass its self as an argument (becomes a class method in python)");
+ "Function does not pass its self as an argument (becomes a static method in python)");
+
+ prop = RNA_def_property(srna, "use_self_type", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Function_use_self_type_get", NULL);
+ RNA_def_property_ui_text(prop, "Use Self Type",
+ "Function passes its self type as an argument (becomes a class method in python if use_self is false)");
}
static void rna_def_number_property(StructRNA *srna, PropertyType type)
@@ -1396,6 +1430,12 @@ static void rna_def_enum_property(BlenderRNA *brna, StructRNA *srna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_EnumPropertyItem_value_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Value", "Value of the item");
+
+ prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_items(prop, icon_items);
+ RNA_def_property_enum_funcs(prop, "rna_EnumPropertyItem_icon_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
}
static void rna_def_pointer_property(StructRNA *srna, PropertyType type)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 6f3a483cf7e..a9d1f6e0f34 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -35,6 +35,7 @@
#include "DNA_group_types.h"
#include "DNA_modifier_types.h"
#include "DNA_particle_types.h"
+#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
#include "DNA_world_types.h"
@@ -116,7 +117,8 @@ EnumPropertyItem proportional_falloff_curve_only_items[] = {
EnumPropertyItem proportional_editing_items[] = {
{PROP_EDIT_OFF, "DISABLED", ICON_PROP_OFF, "Disable", "Proportional Editing disabled"},
{PROP_EDIT_ON, "ENABLED", ICON_PROP_ON, "Enable", "Proportional Editing enabled"},
- {PROP_EDIT_CONNECTED, "CONNECTED", ICON_PROP_CON, "Connected", "Proportional Editing using connected geometry only"},
+ {PROP_EDIT_CONNECTED, "CONNECTED", ICON_PROP_CON, "Connected",
+ "Proportional Editing using connected geometry only"},
{0, NULL, 0, NULL, NULL}
};
@@ -274,9 +276,11 @@ EnumPropertyItem image_color_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+#ifdef RNA_RUNTIME
#define IMAGE_COLOR_MODE_BW image_color_mode_items[0]
#define IMAGE_COLOR_MODE_RGB image_color_mode_items[1]
#define IMAGE_COLOR_MODE_RGBA image_color_mode_items[2]
+#endif
EnumPropertyItem image_color_depth_items[] = {
/* 1 (monochrome) not used */
@@ -377,10 +381,10 @@ static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *report
if (scene == scene_act)
ob->lay = base->lay;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* slows down importers too much, run scene.update() */
- /* DAG_scene_sort(G.main, scene); */
+ /* DAG_srelations_tag_update(G.main); */
WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene);
@@ -402,14 +406,13 @@ static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *o
scene->basact = NULL;
}
- BLI_remlink(&scene->base, base);
+ BKE_scene_base_unlink(scene, base);
MEM_freeN(base);
ob->id.us--;
/* needed otherwise the depgraph will contain freed objects which can crash, see [#20958] */
- DAG_scene_sort(G.main, scene);
- DAG_ids_flush_update(G.main, 0);
+ DAG_relations_tag_update(G.main);
WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene);
}
@@ -873,7 +876,7 @@ 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.imtype);
+ BKE_add_image_extension(ext, &rd->im_format);
return strlen(ext);
}
@@ -881,7 +884,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.imtype);
+ BKE_add_image_extension(str, &rd->im_format);
}
#ifdef WITH_QUICKTIME
@@ -1130,7 +1133,7 @@ static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
static char *rna_SceneRenderLayer_path(PointerRNA *ptr)
{
- SceneRenderLayer *srl = (SceneRenderLayer*)ptr->data;
+ SceneRenderLayer *srl = (SceneRenderLayer *)ptr->data;
return BLI_sprintfN("render.layers[\"%s\"]", srl->name);
}
@@ -1247,27 +1250,31 @@ static void object_simplify_update(Object *ob)
}
}
-static void rna_Scene_use_simplify_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
+ Scene *sce = ptr->id.data;
Scene *sce_iter;
Base *base;
- for (SETLOOPER(scene, sce_iter, base))
+ for (SETLOOPER(sce, sce_iter, base))
object_simplify_update(base->object);
- DAG_ids_flush_update(bmain, 0);
WM_main_add_notifier(NC_GEOM | ND_DATA, NULL);
}
-static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- if (scene->r.mode & R_SIMPLIFY)
- rna_Scene_use_simplify_update(bmain, scene, ptr);
+ Scene *sce = ptr->id.data;
+
+ if (sce->r.mode & R_SIMPLIFY)
+ rna_Scene_use_simplify_update(bmain, sce, ptr);
}
-static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- if (!(scene->r.mode & R_PERSISTENT_DATA))
+ Scene *sce = ptr->id.data;
+
+ if (!(sce->r.mode & R_PERSISTENT_DATA))
RE_FreePersistentData();
}
@@ -1356,7 +1363,8 @@ static void rna_TimeLine_remove(Scene *scene, ReportList *reports, PointerRNA *m
{
TimeMarker *marker = marker_ptr->data;
if (BLI_remlink_safe(&scene->markers, marker) == FALSE) {
- BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'", marker->name, scene->id.name + 2);
+ BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'",
+ marker->name, scene->id.name + 2);
return;
}
@@ -1411,6 +1419,11 @@ static void rna_UnifiedPaintSettings_unprojected_radius_set(PointerRNA *ptr, flo
ups->unprojected_radius = value;
}
+static char *rna_UnifiedPaintSettings_path(PointerRNA *ptr)
+{
+ return BLI_strdup("tool_settings.unified_paint_settings");
+}
+
/* note: without this, when Multi-Paint is activated/deactivated, the colors
* will not change right away when multiple bones are selected, this function
* is not for general use and only for the few cases where changing scene
@@ -1440,6 +1453,11 @@ static void rna_SceneSequencer_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
BKE_sequencer_preprocessed_cache_cleanup();
}
+static char *rna_ToolSettings_path(PointerRNA *ptr)
+{
+ return BLI_strdup("tool_settings");
+}
+
#else
static void rna_def_transform_orientation(BlenderRNA *brna)
@@ -1510,7 +1528,15 @@ static void rna_def_tool_settings(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem draw_groupuser_items[] = {
+ {OB_DRAW_GROUPUSER_NONE, "NONE", 0, "None", ""},
+ {OB_DRAW_GROUPUSER_ACTIVE, "ACTIVE", 0, "Active", "Show vertices with no weights in the actuve group"},
+ {OB_DRAW_GROUPUSER_ALL, "ALL", 0, "All", "Show vertices with no weights in the any group"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "ToolSettings", NULL);
+ RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
RNA_def_struct_ui_text(srna, "Tool Settings", "");
prop = RNA_def_property(srna, "sculpt", PROP_POINTER, PROP_NONE);
@@ -1531,6 +1557,13 @@ static void rna_def_tool_settings(BlenderRNA *brna)
"weight painting");
RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
+ prop = RNA_def_property(srna, "vertex_group_user", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "weightuser");
+ RNA_def_property_enum_items(prop, draw_groupuser_items);
+ RNA_def_property_ui_text(prop, "Mask Non-Group Vertices", "Display unweighted vertices (multi-paint overrides)");
+ RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
+
+
prop = RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "vpaint");
RNA_def_property_ui_text(prop, "Vertex Paint", "");
@@ -1753,28 +1786,29 @@ static void rna_def_tool_settings(BlenderRNA *brna)
/* etch-a-ton */
prop = RNA_def_property(srna, "use_bone_sketching", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bone_sketching", BONE_SKETCHING);
- RNA_def_property_ui_text(prop, "Use Bone Sketching", "DOC BROKEN");
+ RNA_def_property_ui_text(prop, "Use Bone Sketching", "Use sketching to create and edit bones");
/* RNA_def_property_ui_icon(prop, ICON_EDIT, 0); */
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "use_etch_quick", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bone_sketching", BONE_SKETCHING_QUICK);
- RNA_def_property_ui_text(prop, "Quick Sketching", "DOC BROKEN");
+ RNA_def_property_ui_text(prop, "Quick Sketching", "Automatically convert and delete on stroke end");
prop = RNA_def_property(srna, "use_etch_overdraw", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bone_sketching", BONE_SKETCHING_ADJUST);
- RNA_def_property_ui_text(prop, "Overdraw Sketching", "DOC BROKEN");
+ RNA_def_property_ui_text(prop, "Overdraw Sketching", "Adjust strokes by drawing near them");
prop = RNA_def_property(srna, "use_etch_autoname", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skgen_retarget_options", SK_RETARGET_AUTONAME);
- RNA_def_property_ui_text(prop, "Autoname", "DOC BROKEN");
+ RNA_def_property_ui_text(prop, "Autoname Bones", "Automatically generate values to replace &N and &S suffix placeholders in template names");
prop = RNA_def_property(srna, "etch_number", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "skgen_num_string");
- RNA_def_property_ui_text(prop, "Number", "DOC BROKEN");
+ RNA_def_property_ui_text(prop, "Number", "Text to replace &N with (e.g. 'Finger.&N' -> 'Finger.1' or 'Finger.One')");
prop = RNA_def_property(srna, "etch_side", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "skgen_num_string");
- RNA_def_property_ui_text(prop, "Side", "DOC BROKEN");
+ RNA_def_property_ui_text(prop, "Side", "Text to replace &S with (e.g. 'Arm.&S' -> 'Arm.R' or 'Arm.Right')");
prop = RNA_def_property(srna, "etch_template", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "skgen_template");
@@ -1793,14 +1827,14 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "skgen_correlation_limit");
RNA_def_property_range(prop, 0.00001, 1.0);
RNA_def_property_ui_range(prop, 0.01, 1.0, 0.01, 2);
- RNA_def_property_ui_text(prop, "Limit", "Number of bones in the subdivided stroke");
+ RNA_def_property_ui_text(prop, "Limit", "Correlation threshold for number of bones in the subdivided stroke");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "etch_length_limit", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "skgen_length_limit");
RNA_def_property_range(prop, 0.00001, 100000.0);
RNA_def_property_ui_range(prop, 0.001, 100.0, 0.1, 3);
- RNA_def_property_ui_text(prop, "Length", "Number of bones in the subdivided stroke");
+ RNA_def_property_ui_text(prop, "Length", "Maximum length of the subdivided bones");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "etch_roll_mode", PROP_ENUM, PROP_NONE);
@@ -1827,6 +1861,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
PropertyRNA *prop;
srna = RNA_def_struct(brna, "UnifiedPaintSettings", NULL);
+ RNA_def_struct_path_func(srna, "rna_UnifiedPaintSettings_path");
RNA_def_struct_ui_text(srna, "Unified Paint Settings", "Overrides for some of the active brush's settings");
/* high-level flags to enable or disable unified paint settings */
@@ -1847,7 +1882,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
/* unified paint settings that override the equivalent settings
* from the active brush */
- prop = RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "size", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop, NULL, "rna_UnifiedPaintSettings_size_set", NULL);
RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS * 10);
RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0);
@@ -1989,7 +2024,8 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
if (scene) {
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_ui_text(prop, "Samples", "Override number of render samples for this render layer, 0 will use the scene setting");
+ RNA_def_property_ui_text(prop, "Samples", "Override number of render samples for this render layer, "
+ "0 will use the scene setting");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
}
@@ -2318,7 +2354,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_ui_text(prop, "Max Slope", "Maximum walkable slope angle in degrees");
+ RNA_def_property_ui_text(prop, "Max Slope", "Maximum walkable slope angle");
RNA_def_property_update(prop, NC_SCENE, NULL);
@@ -2417,10 +2453,6 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
static EnumPropertyItem physics_engine_items[] = {
{WOPHY_NONE, "NONE", 0, "None", "Don't use a physics engine"},
- /*{WOPHY_ENJI, "ENJI", 0, "Enji", ""}, */
- /*{WOPHY_SUMO, "SUMO", 0, "Sumo (Deprecated)", ""}, */
- /*{WOPHY_DYNAMO, "DYNAMO", 0, "Dynamo", ""}, */
- /*{WOPHY_ODE, "ODE", 0, "ODE", ""}, */
{WOPHY_BULLET, "BULLET", 0, "Bullet", "Use the Bullet physics engine"},
{0, NULL, 0, NULL, NULL}
};
@@ -2439,6 +2471,16 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem storage_items[] = {
+ {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"},
+ {RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"},
+ {RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Better performance, requires at least OpenGL 1.1"},
+#if 0 /* XXX VBOS are currently disabled since they cannot beat vertex array with display lists in performance. */
+ {RAS_STORE_VBO, "VERTEX_BUFFER_OBJECT", 0, "Vertex Buffer Objects",
+ "Best performance, requires at least OpenGL 1.4"},
+#endif
+ {0, NULL, 0, NULL, NULL}};
+
srna = RNA_def_struct(brna, "SceneGameData", NULL);
RNA_def_struct_sdna(srna, "GameData");
RNA_def_struct_nested(brna, srna, "Scene");
@@ -2471,7 +2513,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "exitkey");
RNA_def_property_enum_items(prop, event_type_items);
RNA_def_property_enum_funcs(prop, NULL, "rna_GameSettings_exit_key_set", NULL);
- RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine");
+ RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop = RNA_def_property(srna, "raster_storage", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "raster_storage");
+ RNA_def_property_enum_items(prop, storage_items);
+ RNA_def_property_ui_text(prop, "Storage", "Set the storage mode used by the rasterizer");
RNA_def_property_update(prop, NC_SCENE, NULL);
/* Do we need it here ? (since we already have it in World */
@@ -2522,7 +2570,7 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "eyeseparation");
RNA_def_property_range(prop, 0.01, 5.0);
RNA_def_property_ui_text(prop, "Eye Separation",
- "Set the distance between the eyes - the camera focal length/30 should be fine");
+ "Set the distance between the eyes - the camera focal distance/30 should be fine");
RNA_def_property_update(prop, NC_SCENE, NULL);
/* Dome */
@@ -2647,10 +2695,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE, NULL);
/* mode */
+ /* not used *//* deprecated !!!!!!!!!!!!! */
prop = RNA_def_property(srna, "use_occlusion_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_DBVT_CULLING);
- RNA_def_property_ui_text(prop, "DBVT culling",
- "Use optimized Bullet DBVT tree for view frustum and occlusion culling");
+ RNA_def_property_ui_text(prop, "DBVT Culling",
+ "Use optimized Bullet DBVT tree for view frustum and occlusion culling (more efficient, "
+ "but it can waste unnecessary CPU if the scene doesn't have occluder objects)");
/* not used *//* deprecated !!!!!!!!!!!!! */
prop = RNA_def_property(srna, "use_activity_culling", PROP_BOOLEAN, PROP_NONE);
@@ -2757,6 +2807,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
"Use extra textures like normal or specular maps for GLSL rendering");
RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_glsl_update");
+ prop = RNA_def_property(srna, "use_material_caching", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_NO_MATERIAL_CACHING);
+ RNA_def_property_ui_text(prop, "Use Material Caching",
+ "Cache materials in the converter (this is faster, but can cause problems with older "
+ "Singletexture and Multitexture games)");
+
/* obstacle simulation */
prop = RNA_def_property(srna, "obstacle_simulation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "obstacleSimulation");
@@ -2812,7 +2868,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_sdna(srna, "RenderData");
RNA_def_struct_ui_text(srna, "Render Layers", "Collection of render layers");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "actlay");
RNA_def_property_int_funcs(prop, "rna_RenderSettings_active_layer_index_get",
"rna_RenderSettings_active_layer_index_set",
@@ -2820,7 +2876,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "SceneRenderLayer");
RNA_def_property_pointer_funcs(prop, "rna_RenderSettings_active_layer_get",
"rna_RenderSettings_active_layer_set", NULL, NULL);
@@ -2862,6 +2918,14 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
};
#endif
+#ifdef WITH_OPENJPEG
+ static EnumPropertyItem jp2_codec_items[] = {
+ {R_IMF_JP2_CODEC_JP2, "JP2", 0, "JP2", ""},
+ {R_IMF_JP2_CODEC_J2K, "J2K", 0, "J2K", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+#endif
+
StructRNA *srna;
PropertyRNA *prop;
@@ -2949,6 +3013,12 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "jp2_flag", R_IMF_JP2_FLAG_CINE_48);
RNA_def_property_ui_text(prop, "Cinema (48)", "Use Openjpeg Cinema Preset (48fps)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "jpeg2k_codec", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "jp2_codec");
+ RNA_def_property_enum_items(prop, jp2_codec_items);
+ RNA_def_property_ui_text(prop, "Codec", "Codec settings for Jpek2000");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
#endif
/* Cineon and DPX */
@@ -3071,21 +3141,18 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "video_bitrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "video_bitrate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 1, 64000);
RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "minrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "rc_min_rate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 0, 48000);
RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "maxrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "rc_max_rate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 1, 96000);
RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
@@ -3291,8 +3358,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
static EnumPropertyItem alpha_mode_items[] = {
{R_ADDSKY, "SKY", 0, "Sky", "Transparent pixels are filled with sky color"},
- {R_ALPHAPREMUL, "PREMUL", 0, "Premultiplied", "Transparent RGB pixels are multiplied by the alpha channel"},
- {R_ALPHAKEY, "STRAIGHT", 0, "Straight Alpha", "Transparent RGB and alpha pixels are unmodified"},
+ {R_ALPHAPREMUL, "TRANSPARENT", 0, "Transparent", "World background is transparent with premultiplied alpha"},
{0, NULL, 0, NULL, NULL}
};
@@ -3400,14 +3466,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "resolution_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "xsch");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 4, 10000);
+ RNA_def_property_range(prop, 4, 65536);
RNA_def_property_ui_text(prop, "Resolution X", "Number of horizontal pixels in the rendered image");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneCamera_update");
prop = RNA_def_property(srna, "resolution_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ysch");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 4, 10000);
+ RNA_def_property_range(prop, 4, 65536);
RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the rendered image");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneCamera_update");
@@ -3421,13 +3487,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "tile_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tilex");
- RNA_def_property_range(prop, 8, 10000);
+ RNA_def_property_range(prop, 8, 65536);
RNA_def_property_ui_text(prop, "Tile X", "Horizontal tile size to use while rendering");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "tile_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tiley");
- RNA_def_property_range(prop, 8, 10000);
+ RNA_def_property_range(prop, 8, 65536);
RNA_def_property_ui_text(prop, "Tile Y", "Vertical tile size to use while rendering");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
@@ -3653,10 +3719,9 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
- prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "blurfac");
- RNA_def_property_range(prop, 0.01f, 10.0f);
- RNA_def_property_ui_range(prop, 0.01, 2.0f, 1, 0);
+ RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 1);
RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
@@ -3670,27 +3735,33 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"(note that this disables save_buffers and full_sample)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+
prop = RNA_def_property(srna, "border_min_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "border.xmin");
RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Border Minimum X", "Minimum X value to for the render border");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "border_min_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "border.ymin");
RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Border Minimum Y", "Minimum Y value for the render border");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "border_max_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "border.xmax");
RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Border Maximum X", "Maximum X value for the render border");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "border_max_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "border.ymax");
RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Border Maximum Y", "Maximum Y value for the render border");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
@@ -3727,13 +3798,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"editor pipeline, if sequencer strips exist");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
- prop = RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT_PREDIVIDE);
- RNA_def_property_ui_text(prop, "Color Unpremultiply",
- "For premultiplied alpha render output, do color space conversion on "
- "colors without alpha, to avoid fringing on light backgrounds");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
prop = RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
RNA_def_property_ui_text(prop, "File Extensions",
@@ -3879,6 +3943,19 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Calculate heights against unsubdivided low resolution mesh");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "bake_samples", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "bake_samples");
+ RNA_def_property_range(prop, 64, 1024);
+ RNA_def_property_int_default(prop, 256);
+ RNA_def_property_ui_text(prop, "Samples", "Number of samples used for ambient occlusion baking from multires");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "use_bake_to_vertex_color", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_VCOL);
+ RNA_def_property_ui_text(prop, "Bake to Vertex Color",
+ "Bake to vertex colors instead of to a UV-mapped image");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
/* stamp */
prop = RNA_def_property(srna, "use_stamp_time", PROP_BOOLEAN, PROP_NONE);
@@ -3992,6 +4069,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_items(prop, viewport_shade_items);
RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view");
+ prop = RNA_def_property(srna, "use_sequencer_gl_textured_solid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_SOLID_TEX);
+ RNA_def_property_ui_text(prop, "Textured Solid", "Draw face-assigned textures in solid draw method");
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update");
+
/* layers */
prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "layers", NULL);
@@ -4489,6 +4571,13 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET, NULL);
rna_def_scene_keying_sets_all(brna, prop);
+ /* Rigid Body Simulation */
+ prop = RNA_def_property(srna, "rigidbody_world", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "rigidbody_world");
+ RNA_def_property_struct_type(prop, "RigidBodyWorld");
+ RNA_def_property_ui_text(prop, "Rigid Body World", "");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
/* Tool Settings */
prop = RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -4623,19 +4712,23 @@ void RNA_def_scene(BlenderRNA *brna)
prop = RNA_def_property(srna, "sequencer_colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "sequencer_colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedSequencerColorspaceSettings");
RNA_def_property_ui_text(prop, "Sequencer Color Space Settings", "Settings of color space sequencer is working in");
/* Nestled Data */
+ /* *** Non-Animated *** */
+ RNA_define_animate_sdna(false);
rna_def_tool_settings(brna);
rna_def_unified_paint_settings(brna);
rna_def_unit_settings(brna);
rna_def_scene_image_format_data(brna);
- rna_def_scene_render_data(brna);
rna_def_scene_game_data(brna);
- rna_def_scene_render_layer(brna);
rna_def_transform_orientation(brna);
rna_def_selected_uv_element(brna);
+ RNA_define_animate_sdna(true);
+ /* *** Animated *** */
+ rna_def_scene_render_data(brna);
+ rna_def_scene_render_layer(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 012767b5845..b0df27b957b 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -55,8 +55,10 @@
static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
{
- scene->r.cfra = frame;
- scene->r.subframe = subframe;
+ float cfra = (float)frame + subframe;
+
+ scene->r.cfra = floorf(cfra);
+ scene->r.subframe = cfra - floorf(cfra);
CLAMP(scene->r.cfra, MINAFRAME, MAXFRAME);
BKE_scene_update_for_newframe(G.main, scene, (1 << 20) - 1);
@@ -84,7 +86,7 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name
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.imtype,
+ BKE_makepicstring(name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame, &rd->im_format,
rd->scemode & R_EXTENSION, TRUE);
}
@@ -101,6 +103,7 @@ static void rna_Scene_collada_export(
int selected,
int include_children,
int include_armatures,
+ int include_shapekeys,
int deform_bones_only,
int active_uv_only,
@@ -113,7 +116,7 @@ static void rna_Scene_collada_export(
int second_life)
{
collada_export(scene, filepath, apply_modifiers, export_mesh_type, selected,
- include_children, include_armatures, deform_bones_only,
+ include_children, include_armatures, include_shapekeys, deform_bones_only,
active_uv_only, include_uv_textures, include_material_textures,
use_texture_copies, use_object_instantiation, sort_by_name, second_life);
}
@@ -149,6 +152,7 @@ void RNA_api_scene(StructRNA *srna)
parm = RNA_def_boolean(func, "selected", 0, "Selection Only", "Export only selected elements");
parm = RNA_def_boolean(func, "include_children", 0, "Include Children", "Export all children of selected objects (even if not selected)");
parm = RNA_def_boolean(func, "include_armatures", 0, "Include Armatures", "Export related armatures (even if not selected)");
+ parm = RNA_def_boolean(func, "include_shapekeys", 0, "Include Shape Keys", "Export all Shape Keys from Mesh Objects");
parm = RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only", "Only export deforming bones with armatures");
parm = RNA_def_boolean(func, "active_uv_only", 0, "Active UV Layer only", "Export only the active UV Layer");
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 84e76fae896..e0687295c70 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -40,6 +40,9 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "BLI_utildefines.h"
+#include "bmesh.h"
+
static EnumPropertyItem particle_edit_hair_brush_items[] = {
{PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush"},
{PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"},
@@ -52,6 +55,18 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem symmetrize_direction_items[] = {
+ {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""},
+ {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""},
+
+ {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""},
+ {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""},
+
+ {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""},
+ {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
@@ -59,8 +74,7 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = {
#include "BKE_pointcache.h"
#include "BKE_particle.h"
#include "BKE_depsgraph.h"
-
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
#include "ED_particle.h"
@@ -176,6 +190,11 @@ static int rna_ParticleEdit_hair_get(PointerRNA *ptr)
return 0;
}
+static char *rna_ParticleEdit_path(PointerRNA *ptr)
+{
+ return BLI_strdup("tool_settings.particle_edit");
+}
+
static int rna_Brush_mode_poll(PointerRNA *ptr, PointerRNA value)
{
Scene *scene = (Scene *)ptr->id.data;
@@ -205,6 +224,11 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU
if (ob) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
+
+ if (ob->sculpt) {
+ ob->sculpt->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
+ SCULPT_DYNTOPO_SMOOTH_SHADING);
+ }
}
}
@@ -212,7 +236,7 @@ static void rna_Sculpt_ShowDiffuseColor_update(Main *UNUSED(bmain), Scene *scene
{
Object *ob = (scene->basact) ? scene->basact->object : NULL;
- if (ob) {
+ if (ob && ob->sculpt) {
Sculpt *sd = scene->toolsettings->sculpt;
ob->sculpt->show_diffuse_color = sd->flags & SCULPT_SHOW_DIFFUSE;
@@ -223,6 +247,38 @@ static void rna_Sculpt_ShowDiffuseColor_update(Main *UNUSED(bmain), Scene *scene
}
}
+static char *rna_Sculpt_path(PointerRNA *ptr)
+{
+ return BLI_strdup("tool_settings.sculpt");
+}
+
+static char *rna_VertexPaint_path(PointerRNA *ptr)
+{
+ Scene *scene = (Scene *)ptr->id.data;
+ ToolSettings *ts = scene->toolsettings;
+ if (ptr->data == ts->vpaint) {
+ return BLI_strdup("tool_settings.vertex_paint");
+ }
+ else {
+ return BLI_strdup("tool_settings.weight_paint");
+ }
+}
+
+static char *rna_ImagePaintSettings_path(PointerRNA *ptr)
+{
+ return BLI_strdup("tool_settings.image_paint");
+}
+
+static char *rna_UvSculpt_path(PointerRNA *ptr)
+{
+ return BLI_strdup("tool_settings.uv_sculpt");
+}
+
+static char *rna_ParticleBrush_path(PointerRNA *ptr)
+{
+ return BLI_strdup("tool_settings.particle_edit.brush");
+}
+
#else
static void rna_def_paint(BlenderRNA *brna)
@@ -264,6 +320,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
PropertyRNA *prop;
srna = RNA_def_struct(brna, "Sculpt", "Paint");
+ RNA_def_struct_path_func(srna, "rna_Sculpt_path");
RNA_def_struct_ui_text(srna, "Sculpt", "");
prop = RNA_def_property(srna, "radial_symmetry", PROP_INT, PROP_XYZ);
@@ -320,6 +377,27 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Diffuse Color",
"Show diffuse color of object and overlay sculpt mask on top of it");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_ShowDiffuseColor_update");
+
+ prop = RNA_def_property(srna, "detail_size", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_range(prop, 2, 100, 0, 0);
+ RNA_def_property_ui_text(prop, "Detail Size", "Maximum edge length for dynamic topology sculpting (in pixels)");
+
+ prop = RNA_def_property(srna, "use_smooth_shading", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_SMOOTH_SHADING);
+ RNA_def_property_ui_text(prop, "Smooth Shading",
+ "Show faces in dynamic-topology mode with smooth "
+ "shading rather than flat shaded");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
+
+ prop = RNA_def_property(srna, "use_edge_collapse", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_COLLAPSE);
+ RNA_def_property_ui_text(prop, "Collapse Short Edges",
+ "In dynamic-topology mode, collapse short edges "
+ "in addition to subdividing long ones");
+
+ prop = RNA_def_property(srna, "symmetrize_direction", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, symmetrize_direction_items);
+ RNA_def_property_ui_text(prop, "Direction", "Source and destination for symmetrize operator");
}
@@ -328,6 +406,7 @@ static void rna_def_uv_sculpt(BlenderRNA *brna)
StructRNA *srna;
srna = RNA_def_struct(brna, "UvSculpt", "Paint");
+ RNA_def_struct_path_func(srna, "rna_UvSculpt_path");
RNA_def_struct_ui_text(srna, "UV Sculpting", "");
}
@@ -340,6 +419,7 @@ static void rna_def_vertex_paint(BlenderRNA *brna)
srna = RNA_def_struct(brna, "VertexPaint", "Paint");
RNA_def_struct_sdna(srna, "VPaint");
+ RNA_def_struct_path_func(srna, "rna_VertexPaint_path");
RNA_def_struct_ui_text(srna, "Vertex Paint", "Properties of vertex and weight paint mode");
/* vertex paint only */
@@ -368,6 +448,7 @@ static void rna_def_image_paint(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ImagePaint", "Paint");
RNA_def_struct_sdna(srna, "ImagePaintSettings");
+ RNA_def_struct_path_func(srna, "rna_ImagePaintSettings_path");
RNA_def_struct_ui_text(srna, "Image Paint", "Properties of image and texture painting mode");
/* booleans */
@@ -452,6 +533,7 @@ static void rna_def_particle_edit(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ParticleEdit", NULL);
RNA_def_struct_sdna(srna, "ParticleEditSettings");
+ RNA_def_struct_path_func(srna, "rna_ParticleEdit_path");
RNA_def_struct_ui_text(srna, "Particle Edit", "Properties of particle editing mode");
prop = RNA_def_property(srna, "tool", PROP_ENUM, PROP_NONE);
@@ -547,9 +629,10 @@ static void rna_def_particle_edit(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ParticleBrush", NULL);
RNA_def_struct_sdna(srna, "ParticleBrushData");
+ RNA_def_struct_path_func(srna, "rna_ParticleBrush_path");
RNA_def_struct_ui_text(srna, "Particle Brush", "Particle editing brush");
- prop = RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "size", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 1, SHRT_MAX);
RNA_def_property_ui_range(prop, 1, 100, 10, 3);
RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels");
@@ -593,12 +676,15 @@ static void rna_def_particle_edit(BlenderRNA *brna)
void RNA_def_sculpt_paint(BlenderRNA *brna)
{
+ /* *** Non-Animated *** */
+ RNA_define_animate_sdna(false);
rna_def_paint(brna);
rna_def_sculpt(brna);
rna_def_uv_sculpt(brna);
rna_def_vertex_paint(brna);
rna_def_image_paint(brna);
rna_def_particle_edit(brna);
+ RNA_define_animate_sdna(true);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 18a9b9683f8..a2704619ee6 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -40,6 +40,8 @@
#include "DNA_sequence_types.h"
#include "DNA_movieclip_types.h"
+#include "BLI_math.h"
+
#include "BKE_animsys.h"
#include "BKE_global.h"
#include "BKE_sequencer.h"
@@ -48,7 +50,6 @@
#include "MEM_guardedalloc.h"
#include "WM_types.h"
-#include "BLI_math.h"
#include "BLF_translation.h"
@@ -412,7 +413,7 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value)
/* fix all the animation data which may link to this */
/* don't rename everywhere because these are per scene */
- /* BKE_all_animdata_fix_paths_rename(NULL, "sequence_editor.sequences_all", oldname, seq->name+2); */
+ /* BKE_all_animdata_fix_paths_rename(NULL, "sequence_editor.sequences_all", oldname, seq->name + 2); */
adt = BKE_animdata_from_id(&scene->id);
if (adt)
BKE_animdata_fix_paths_rename(&scene->id, adt, NULL, "sequence_editor.sequences_all", oldname, seq->name + 2, 0, 0, 1);
@@ -1401,26 +1402,26 @@ static void rna_def_sequence(BlenderRNA *brna)
prop = RNA_def_property(srna, "frame_offset_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "startofs");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_ui_text(prop, "Start Offset", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "frame_offset_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "endofs");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_ui_text(prop, "End Offset", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "frame_still_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "startstill");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "Start Still", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "frame_still_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "endstill");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "End Still", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -1541,14 +1542,20 @@ static void rna_def_filter_video(StructRNA *srna)
{
PropertyRNA *prop;
+ static const EnumPropertyItem alpha_mode_items[] = {
+ {SEQ_ALPHA_STRAIGHT, "STRAIGHT", 0, "Straight", "RGB channels in transparent pixels are unaffected by the alpha channel"},
+ {SEQ_ALPHA_PREMUL, "PREMUL", 0, "Premultiplied", "RGB channels in transparent pixels are multiplied by the alpha channel"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
prop = RNA_def_property(srna, "use_deinterlace", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_FILTERY);
RNA_def_property_ui_text(prop, "De-Interlace", "For video movies to remove fields");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update_reopen_files");
- prop = RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MAKE_PREMUL);
- RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha");
+ prop = RNA_def_property(srna, "alpha_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, alpha_mode_items);
+ RNA_def_property_ui_text(prop, "Alpha Mode", "Representation of alpha information in the RGBA pixels");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "use_flip_x", PROP_BOOLEAN, PROP_NONE);
@@ -1694,7 +1701,7 @@ static void rna_def_color_management(StructRNA *srna)
prop = RNA_def_property(srna, "colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "strip->colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedInputColorspaceSettings");
RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
}
@@ -2052,13 +2059,13 @@ static void rna_def_transform(StructRNA *srna)
prop = RNA_def_property(srna, "scale_start_x", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "ScalexIni");
RNA_def_property_ui_text(prop, "Scale X", "");
- RNA_def_property_ui_range(prop, 0, 10, 3, 10);
+ RNA_def_property_ui_range(prop, 0, 10, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "scale_start_y", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "ScaleyIni");
RNA_def_property_ui_text(prop, "Scale Y", "");
- RNA_def_property_ui_range(prop, 0, 10, 3, 10);
+ RNA_def_property_ui_range(prop, 0, 10, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "use_uniform_scale", PROP_BOOLEAN, PROP_NONE);
@@ -2069,13 +2076,13 @@ static void rna_def_transform(StructRNA *srna)
prop = RNA_def_property(srna, "translate_start_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xIni");
RNA_def_property_ui_text(prop, "Translate X", "");
- RNA_def_property_ui_range(prop, -500.0f, 500.0f, 3, 10);
+ RNA_def_property_ui_range(prop, -500.0f, 500.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "translate_start_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yIni");
RNA_def_property_ui_text(prop, "Translate Y", "");
- RNA_def_property_ui_range(prop, -500.0f, 500.0f, 3, 10);
+ RNA_def_property_ui_range(prop, -500.0f, 500.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "rotation_start", PROP_FLOAT, PROP_NONE);
@@ -2104,7 +2111,7 @@ static void rna_def_solid_color(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "SolidColorVars", "effectdata");
- prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "col");
RNA_def_property_ui_text(prop, "Color", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 7602ec99c2b..386263c784e 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -37,6 +37,8 @@
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "BLI_utildefines.h"
+
#ifdef RNA_RUNTIME
//#include "DNA_anim_types.h"
@@ -62,6 +64,16 @@
#include "WM_api.h"
+static void rna_Sequence_update_rnafunc(ID *id, Sequence *self, int do_data)
+{
+ if (do_data) {
+ BKE_sequencer_update_changed_seq_and_deps((Scene *)id, self, true, true);
+ // new_tstripdata(self); // need 2.6x version of this.
+ }
+ BKE_sequence_calc((Scene *)id, self);
+ BKE_sequence_calc_disp((Scene *)id, self);
+}
+
static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, Sequence *seq_other)
{
const char *error_msg;
@@ -70,14 +82,14 @@ static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports,
BKE_report(reports, RPT_ERROR, error_msg);
}
-static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start_frame,
+static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int frame_start,
int channel, int type, const char *file)
{
Sequence *seq;
Strip *strip;
StripElem *se;
- seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
+ seq = BKE_sequence_alloc(ed->seqbasep, frame_start, channel);
seq->type = type;
BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2);
@@ -101,12 +113,12 @@ static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start
static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed,
const char *name, MovieClip *clip, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIECLIP, clip->name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIECLIP, clip->name);
seq->clip = clip;
seq->len = BKE_movieclip_get_duration(clip);
id_us_plus((ID *)clip);
@@ -120,12 +132,12 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed,
const char *name, Mask *mask, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MASK, mask->id.name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MASK, mask->id.name);
seq->mask = mask;
seq->len = BKE_mask_get_duration(mask);
id_us_plus((ID *)mask);
@@ -139,15 +151,15 @@ static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed,
const char *name, Scene *sce_seq, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SCENE, NULL);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SCENE, NULL);
seq->scene = sce_seq;
seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1;
- seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0);
+ seq->scene_sound = sound_scene_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0);
id_us_plus((ID *)sce_seq);
BKE_sequence_calc_disp(scene, seq);
@@ -159,12 +171,12 @@ static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *reports,
const char *name, const char *file, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_IMAGE, file);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_IMAGE, file);
seq->len = 1;
if (seq->strip->stripdata->name[0] == '\0') {
@@ -183,12 +195,11 @@ static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *report
static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *reports,
const char *name, const char *file, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- /* OCIO_TODO: support configurable color spaces for strips */
struct anim *an = openanim(file, IB_rect, 0, NULL);
if (an == NULL) {
@@ -196,7 +207,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIE, file);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file);
seq->anim = an;
seq->anim_preseek = IMB_anim_get_preseek(an);
seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);
@@ -210,7 +221,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report
#ifdef WITH_AUDASPACE
static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, ReportList *reports,
- const char *name, const char *file, int channel, int start_frame)
+ const char *name, const char *file, int channel, int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
@@ -222,11 +233,11 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SOUND_RAM, sound->name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SOUND_RAM, sound->name);
seq->sound = sound;
seq->len = ceil((double)sound_get_length(sound) * FPS);
- seq->scene_sound = sound_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0);
+ seq->scene_sound = sound_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0);
BKE_sequence_calc_disp(scene, seq);
@@ -237,7 +248,7 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor
#else /* WITH_AUDASPACE */
static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports,
const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel),
- int UNUSED(start_frame))
+ int UNUSED(frame_start))
{
BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support");
return NULL;
@@ -246,7 +257,7 @@ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Ma
static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *reports,
const char *name, int type, int channel,
- int start_frame, int end_frame,
+ int frame_start, int frame_end,
Sequence *seq1, Sequence *seq2, Sequence *seq3)
{
Scene *scene = (Scene *)id;
@@ -256,7 +267,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
switch (num_inputs) {
case 0:
- if (end_frame <= start_frame) {
+ if (frame_end <= frame_start) {
BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set");
return NULL;
}
@@ -286,7 +297,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, type, NULL);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, type, NULL);
sh = BKE_sequence_get_effect(seq);
@@ -298,7 +309,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
if (!seq1) { /* effect has no deps */
seq->len = 1;
- BKE_sequence_tx_set_final_right(seq, end_frame);
+ BKE_sequence_tx_set_final_right(seq, frame_end);
}
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
@@ -389,7 +400,13 @@ void RNA_api_sequence_strip(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
- func = RNA_def_function(srna, "getStripElem", "BKE_sequencer_give_stripelem");
+ func = RNA_def_function(srna, "update", "rna_Sequence_update_rnafunc");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Update the strip dimensions");
+ parm = RNA_def_boolean(func, "data", false, "Frame",
+ "Update strip data");
+
+ func = RNA_def_function(srna, "strip_elem_from_frame", "BKE_sequencer_give_stripelem");
RNA_def_function_ui_description(func, "Return the strip element from a given frame or None");
parm = RNA_def_int(func, "frame", 0, -MAXFRAME, MAXFRAME, "Frame",
"The frame to get the strip element from", -MAXFRAME, MAXFRAME);
@@ -470,7 +487,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -487,7 +504,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -504,7 +521,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -521,7 +538,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -538,7 +555,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -555,7 +572,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -572,12 +589,13 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
+ /* don't use MAXFRAME since it makes importer scripts fail */
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
- "The start frame for the new sequence", -MAXFRAME, MAXFRAME);
+ parm = RNA_def_int(func, "frame_start", 0, INT_MIN, INT_MAX, "",
+ "The start frame for the new sequence", INT_MIN, INT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "",
- "The end frame for the new sequence", -MAXFRAME, MAXFRAME);
+ RNA_def_int(func, "frame_end", 0, INT_MIN, INT_MAX, "",
+ "The end frame for the new sequence", INT_MIN, INT_MAX);
RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect");
RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect");
RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect");
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index bdcda79583e..86b97b93437 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -62,7 +62,7 @@ static void rna_Smoke_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
static void rna_Smoke_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
rna_Smoke_update(bmain, scene, ptr);
- DAG_scene_sort(bmain, scene);
+ DAG_relations_tag_update(bmain);
}
static void rna_Smoke_resetCache(Main *bmain, Scene *scene, PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 2b2e8d97499..0ab74fb617f 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -41,6 +41,7 @@
#include "DNA_action_types.h"
#include "DNA_key_types.h"
+#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_space_types.h"
@@ -79,9 +80,9 @@ EnumPropertyItem space_type_items[] = {
};
static EnumPropertyItem draw_channels_items[] = {
- {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors"},
{SI_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, "Color and Alpha",
"Draw image with RGB colors and alpha transparency"},
+ {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors"},
{SI_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Draw alpha transparency channel"},
{SI_SHOW_ZBUF, "Z_BUFFER", ICON_IMAGE_ZDEPTH, "Z-Buffer",
"Draw Z-buffer associated with image (mapped from camera clip start to end)"},
@@ -144,6 +145,7 @@ EnumPropertyItem clip_editor_mode_items[] = {
#include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_icons.h"
#include "ED_image.h"
#include "ED_node.h"
@@ -152,6 +154,8 @@ EnumPropertyItem clip_editor_mode_items[] = {
#include "ED_sequencer.h"
#include "ED_clip.h"
+#include "GPU_material.h"
+
#include "IMB_imbuf_types.h"
static StructRNA *rna_Space_refine(struct PointerRNA *ptr)
@@ -321,7 +325,7 @@ static void rna_View3D_CursorLocation_get(PointerRNA *ptr, float *values)
View3D *v3d = (View3D *)(ptr->data);
bScreen *sc = (bScreen *)ptr->id.data;
Scene *scene = (Scene *)sc->scene;
- float *loc = give_cursor(scene, v3d);
+ const float *loc = give_cursor(scene, v3d);
copy_v3_v3(values, loc);
}
@@ -376,6 +380,31 @@ static void rna_SpaceView3D_viewport_shade_update(Main *UNUSED(bmain), Scene *UN
}
}
+static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ View3D *v3d = (View3D *)(ptr->data);
+
+ if (v3d->defmaterial) {
+ Material *ma = v3d->defmaterial;
+
+ if (ma->preview)
+ BKE_previewimg_free(&ma->preview);
+
+ if (ma->gpumaterial.first)
+ GPU_material_free(ma);
+
+ WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma);
+ }
+}
+
+static void rna_SpaceView3D_matcap_enable(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ View3D *v3d = (View3D *)(ptr->data);
+
+ if (v3d->matcap_icon == 0)
+ v3d->matcap_icon = ICON_MATCAP_01;
+}
+
static void rna_SpaceView3D_pivot_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
if (U.uiflag & USER_LOCKAROUND) {
@@ -482,8 +511,9 @@ static void rna_RegionView3D_view_rotation_set(PointerRNA *ptr, const float *val
static void rna_RegionView3D_view_matrix_set(PointerRNA *ptr, const float *values)
{
RegionView3D *rv3d = (RegionView3D *)(ptr->data);
- negate_v3_v3(rv3d->ofs, values);
- ED_view3d_from_m4((float (*)[4])values, rv3d->ofs, rv3d->viewquat, &rv3d->dist);
+ float mat[4][4];
+ invert_m4_m4(mat, (float (*)[4])values);
+ ED_view3d_from_m4(mat, rv3d->ofs, rv3d->viewquat, &rv3d->dist);
}
/* api call */
@@ -603,15 +633,18 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *UNUS
if (alpha && zbuf)
return draw_channels_items;
- RNA_enum_items_add_value(&item, &totitem, draw_channels_items, 0);
-
if (alpha) {
RNA_enum_items_add_value(&item, &totitem, draw_channels_items, SI_USE_ALPHA);
+ RNA_enum_items_add_value(&item, &totitem, draw_channels_items, 0);
RNA_enum_items_add_value(&item, &totitem, draw_channels_items, SI_SHOW_ALPHA);
}
else if (zbuf) {
+ RNA_enum_items_add_value(&item, &totitem, draw_channels_items, 0);
RNA_enum_items_add_value(&item, &totitem, draw_channels_items, SI_SHOW_ZBUF);
}
+ else {
+ RNA_enum_items_add_value(&item, &totitem, draw_channels_items, 0);
+ }
RNA_enum_item_end(&item, &totitem);
*free = 1;
@@ -775,7 +808,7 @@ static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value)
static void rna_ConsoleLine_body_get(PointerRNA *ptr, char *value)
{
ConsoleLine *ci = (ConsoleLine *)ptr->data;
- strcpy(value, ci->line);
+ memcpy(value, ci->line, ci->len + 1);
}
static int rna_ConsoleLine_body_length(PointerRNA *ptr)
@@ -871,6 +904,9 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *UNUSED(bmain), Scene *s
/* show new id-count of action we're replacing */
adt->action = saction->action;
id_us_plus(&adt->action->id);
+
+ /* force update of animdata */
+ adt->recalc |= ADT_RECALC_ANIM;
}
/* force depsgraph flush too */
@@ -1250,9 +1286,9 @@ static void rna_def_space_outliner(BlenderRNA *brna)
{SO_SAME_TYPE, "SAME_TYPES", 0, "Same Types",
"Display datablocks of all objects of same type as selected object"},
{SO_GROUPS, "GROUPS", 0, "Groups", "Display groups and their datablocks"},
- {SO_LIBRARIES, "LIBRARIES", 0, "Libraries", "Display libraries"},
{SO_SEQUENCE, "SEQUENCE", 0, "Sequence", "Display sequence datablocks"},
- {SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display raw datablocks"},
+ {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_KEYMAP, "KEYMAPS", 0, "Key Maps", "Display keymap datablocks"},
{0, NULL, 0, NULL, NULL}
@@ -1460,6 +1496,7 @@ static void rna_def_backgroundImages(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Remove all background images");
}
+
static void rna_def_space_view3d(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1496,6 +1533,35 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem view3d_matcap_items[] = {
+ {ICON_MATCAP_01, "01", ICON_MATCAP_01, "", ""},
+ {ICON_MATCAP_02, "02", ICON_MATCAP_02, "", ""},
+ {ICON_MATCAP_03, "03", ICON_MATCAP_03, "", ""},
+ {ICON_MATCAP_04, "04", ICON_MATCAP_04, "", ""},
+ {ICON_MATCAP_05, "05", ICON_MATCAP_05, "", ""},
+ {ICON_MATCAP_06, "06", ICON_MATCAP_06, "", ""},
+ {ICON_MATCAP_07, "07", ICON_MATCAP_07, "", ""},
+ {ICON_MATCAP_08, "08", ICON_MATCAP_08, "", ""},
+ {ICON_MATCAP_09, "09", ICON_MATCAP_09, "", ""},
+ {ICON_MATCAP_10, "10", ICON_MATCAP_10, "", ""},
+ {ICON_MATCAP_11, "11", ICON_MATCAP_11, "", ""},
+ {ICON_MATCAP_12, "12", ICON_MATCAP_12, "", ""},
+ {ICON_MATCAP_13, "13", ICON_MATCAP_13, "", ""},
+ {ICON_MATCAP_14, "14", ICON_MATCAP_14, "", ""},
+ {ICON_MATCAP_15, "15", ICON_MATCAP_15, "", ""},
+ {ICON_MATCAP_16, "16", ICON_MATCAP_16, "", ""},
+ {ICON_MATCAP_17, "17", ICON_MATCAP_17, "", ""},
+ {ICON_MATCAP_18, "18", ICON_MATCAP_18, "", ""},
+ {ICON_MATCAP_19, "19", ICON_MATCAP_19, "", ""},
+ {ICON_MATCAP_20, "20", ICON_MATCAP_20, "", ""},
+ {ICON_MATCAP_21, "21", ICON_MATCAP_21, "", ""},
+ {ICON_MATCAP_22, "22", ICON_MATCAP_22, "", ""},
+ {ICON_MATCAP_23, "23", ICON_MATCAP_23, "", ""},
+ {ICON_MATCAP_24, "24", ICON_MATCAP_24, "", ""},
+ {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");
@@ -1659,6 +1725,12 @@ static void rna_def_space_view3d(BlenderRNA *brna)
"Show dashed lines indicating parent or constraint relationships");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "show_textured_solid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_TEX);
RNA_def_property_ui_text(prop, "Textured Solid", "Display face-assigned textures in solid view");
@@ -1810,6 +1882,17 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show 3D Marker Names", "Show names for reconstructed tracks objects");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "use_matcap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_MATCAP);
+ RNA_def_property_ui_text(prop, "Matcap", "Active Objects draw images mapped on normals, enhancing Solid Draw Mode");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_matcap_enable");
+
+ prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "matcap_icon");
+ RNA_def_property_enum_items(prop, view3d_matcap_items);
+ 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");
+
/* region */
srna = RNA_def_struct(brna, "RegionView3D", NULL);
@@ -1970,7 +2053,7 @@ static void rna_def_space_buttons(BlenderRNA *brna)
/* note: custom set function is ONLY to avoid rna setting a user for this. */
RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceProperties_pin_id_set",
"rna_SpaceProperties_pin_id_typef", NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, "rna_SpaceProperties_pin_id_update");
prop = RNA_def_property(srna, "use_pin_id", PROP_BOOLEAN, PROP_NONE);
@@ -2044,6 +2127,12 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Repeated", "Draw the image repeated outside of the main view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+
prop = RNA_def_property(srna, "draw_channels", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, draw_channels_items);
@@ -2209,6 +2298,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
prop = RNA_def_property(srna, "display_channel", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "chanshown");
RNA_def_property_ui_text(prop, "Display Channel",
@@ -2353,11 +2448,11 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
/* XXX: action-editor is currently for object-level only actions, so show that using object-icon hint */
static EnumPropertyItem mode_items[] = {
- {SACTCONT_DOPESHEET, "DOPESHEET", ICON_OOPS, "DopeSheet", "DopeSheet Editor"},
- {SACTCONT_ACTION, "ACTION", ICON_OBJECT_DATA, "Action Editor", "Action Editor"},
- {SACTCONT_SHAPEKEY, "SHAPEKEY", ICON_SHAPEKEY_DATA, "ShapeKey Editor", "ShapeKey Editor"},
- {SACTCONT_GPENCIL, "GPENCIL", ICON_GREASEPENCIL, "Grease Pencil", "Grease Pencil"},
- {SACTCONT_MASK, "MASK", ICON_MOD_MASK, "Mask", "Mask Editor"},
+ {SACTCONT_DOPESHEET, "DOPESHEET", ICON_OOPS, "DopeSheet", "Edit all keyframes in scene"},
+ {SACTCONT_ACTION, "ACTION", ICON_OBJECT_DATA, "Action Editor", "Edit keyframes in active object's Object-level action"},
+ {SACTCONT_SHAPEKEY, "SHAPEKEY", ICON_SHAPEKEY_DATA, "ShapeKey Editor", "Edit keyframes in active object's Shape Keys action"},
+ {SACTCONT_GPENCIL, "GPENCIL", ICON_GREASEPENCIL, "Grease Pencil", "Edit timings for all Grease Pencil sketches in file"},
+ {SACTCONT_MASK, "MASK", ICON_MOD_MASK, "Mask", "Edit timings for Mask Editor splines"},
{0, NULL, 0, NULL, NULL}
};
@@ -2453,7 +2548,7 @@ static void rna_def_space_graph(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- /* this is basically the same as the one for the 3D-View, but with some entries ommitted */
+ /* this is basically the same as the one for the 3D-View, but with some entries omitted */
static EnumPropertyItem gpivot_items[] = {
{V3D_CENTER, "BOUNDING_BOX_CENTER", ICON_ROTATE, "Bounding Box Center", ""},
{V3D_CURSOR, "CURSOR", ICON_CURSOR, "2D Cursor", ""},
@@ -2677,6 +2772,11 @@ static void rna_def_space_time(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_DYNAMICPAINT);
RNA_def_property_ui_text(prop, "Dynamic Paint", "Show the active object's Dynamic Paint cache");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
+
+ prop = RNA_def_property(srna, "cache_rigidbody", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_RIGIDBODY);
+ RNA_def_property_ui_text(prop, "Rigid Body", "Show the active object's Rigid Body cache");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
}
static void rna_def_console_line(BlenderRNA *brna)
@@ -2701,6 +2801,7 @@ static void rna_def_console_line(BlenderRNA *brna)
"rna_ConsoleLine_body_set");
RNA_def_property_ui_text(prop, "Line", "Text in the line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CONSOLE, NULL);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_TEXT);
prop = RNA_def_property(srna, "current_character", PROP_INT, PROP_NONE); /* copied from text editor */
RNA_def_property_int_sdna(prop, NULL, "cursor");
@@ -2972,9 +3073,9 @@ static void rna_def_space_node(BlenderRNA *brna)
};
static EnumPropertyItem backdrop_channels_items[] = {
- {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors"},
{SNODE_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, "Color and Alpha",
"Draw image with RGB colors and alpha transparency"},
+ {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors"},
{SNODE_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Draw alpha transparency channel"},
{SNODE_SHOW_R, "RED", ICON_COLOR_RED, "Red", ""},
{SNODE_SHOW_G, "GREEN", ICON_COLOR_GREEN, "Green", ""},
@@ -3030,6 +3131,12 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+
prop = RNA_def_property(srna, "use_auto_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_AUTO_RENDER);
RNA_def_property_ui_text(prop, "Auto Render", "Re-render and composite changed layers on 3D edits");
@@ -3302,6 +3409,13 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Manual Calibration", "Use manual calibration helpers");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
+ /* show grease pencil */
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
+
/* show filters */
prop = RNA_def_property(srna, "show_filters", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_FILTERS);
diff --git a/source/blender/makesrna/intern/rna_speaker.c b/source/blender/makesrna/intern/rna_speaker.c
index 139582104ee..8a75aa2d227 100644
--- a/source/blender/makesrna/intern/rna_speaker.c
+++ b/source/blender/makesrna/intern/rna_speaker.c
@@ -62,6 +62,7 @@ static void rna_def_speaker(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPK_MUTED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Mute", "Mute the speaker");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
#if 0 /* This shouldn't be changed actually, hiding it! */
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index b1637ef4c8a..df6181af4b2 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -30,6 +30,8 @@
#include "MEM_guardedalloc.h"
+#include "BLF_translation.h"
+
#include "BKE_text.h"
#include "RNA_define.h"
@@ -127,6 +129,7 @@ static void rna_def_text_line(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, "rna_TextLine_body_get", "rna_TextLine_body_length", "rna_TextLine_body_set");
RNA_def_property_ui_text(prop, "Line", "Text in the line");
RNA_def_property_update(prop, NC_TEXT | NA_EDITED, NULL);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_TEXT);
}
static void rna_def_text(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index bdf9fa4e436..e007fe67c0b 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -44,6 +44,8 @@
#include "DNA_particle_types.h"
#include "DNA_scene_types.h" /* MAXFRAME only */
+#include "BLI_utildefines.h"
+
#include "BKE_node.h"
#include "WM_api.h"
@@ -71,12 +73,12 @@ EnumPropertyItem texture_type_items[] = {
{TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", "Procedural - highly flexible fractal noise texture"},
{TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise",
"Procedural - random noise, gives a different result every time, for every frame, for every pixel"},
+ {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"},
{TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""},
{TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"},
{TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"},
{TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"},
{TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"},
- {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"},
{0, NULL, 0, NULL, NULL}
};
@@ -563,7 +565,7 @@ static void rna_def_colormapping(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.01, 5);
+ RNA_def_property_range(prop, 0.0, 5);
RNA_def_property_ui_text(prop, "Contrast", "Adjust the contrast of the texture");
RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
@@ -1194,11 +1196,6 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Flip Axis", "Flip the texture's X and Y axis");
RNA_def_property_update(prop, 0, "rna_Texture_update");
- prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_USEALPHA);
- RNA_def_property_ui_text(prop, "Use Alpha", "Use the alpha channel information in the image");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
-
prop = RNA_def_property(srna, "use_calculate_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_CALCALPHA);
RNA_def_property_ui_text(prop, "Calculate Alpha", "Calculate an alpha channel based on RGB values in the image");
@@ -1845,7 +1842,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
prop = RNA_def_property(srna, "file_format", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "file_format");
RNA_def_property_enum_items(prop, file_format_items);
- RNA_def_property_ui_text(prop, "File Format", "Format of the source data set to render ");
+ RNA_def_property_ui_text(prop, "File Format", "Format of the source data set to render");
RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update");
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
@@ -1983,7 +1980,7 @@ static void rna_def_texture(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Texture_update");
prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.01, 5);
+ RNA_def_property_range(prop, 0.0, 5);
RNA_def_property_ui_text(prop, "Contrast", "Adjust the contrast of the texture");
RNA_def_property_update(prop, 0, "rna_Texture_update");
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index 5be9d3a0dec..218fda361fa 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -71,7 +71,7 @@ static void clear_envmap(struct EnvMap *env, bContext *C)
static void texture_evaluate(struct Tex *tex, float value[3], float color_r[4])
{
TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
- multitex_ext(tex, value, NULL, NULL, 1, &texres);
+ multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL);
color_r[0] = texres.tr;
color_r[1] = texres.tg;
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 4aefaf991d2..cd646f4849c 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -280,7 +280,7 @@ static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerR
static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- MovieTrackingObject *object = (MovieTrackingObject * )ptr->data;
+ MovieTrackingObject *object = (MovieTrackingObject *)ptr->data;
if (object->flag & TRACKING_OBJECT_CAMERA) {
MovieClip *clip = (MovieClip *)ptr->id.data;
@@ -294,7 +294,7 @@ static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, Po
static PointerRNA rna_trackingObject_reconstruction_get(PointerRNA *ptr)
{
- MovieTrackingObject *object = (MovieTrackingObject * )ptr->data;
+ MovieTrackingObject *object = (MovieTrackingObject *)ptr->data;
if (object->flag & TRACKING_OBJECT_CAMERA) {
MovieClip *clip = (MovieClip *)ptr->id.data;
@@ -402,39 +402,52 @@ static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, P
/* API */
-static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number)
+static MovieTrackingTrack *add_track_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, const char *name, int frame)
{
- int a, width, height;
+ int width, height;
MovieClipUser user = {0};
+ MovieTrackingTrack *track;
user.framenr = 1;
BKE_movieclip_get_size(clip, &user, &width, &height);
- for (a = 0; a < number; a++)
- BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height);
+ track = BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height);
+
+ if (name && name[0]) {
+ BLI_strncpy(track->name, name, sizeof(track->name));
+ BKE_tracking_track_unique_name(tracksbase, track);
+ }
+
+ return track;
}
-static void rna_trackingTracks_add(ID *id, MovieTracking *tracking, int frame, int number)
+static MovieTrackingTrack *rna_trackingTracks_new(ID *id, MovieTracking *tracking, const char *name, int frame)
{
MovieClip *clip = (MovieClip *) id;
+ MovieTrackingTrack *track;
- add_tracks_to_base(clip, tracking, &tracking->tracks, frame, number);
+ track = add_track_to_base(clip, tracking, &tracking->tracks, name, frame);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, clip);
+
+ return track;
}
-static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number)
+static MovieTrackingTrack *rna_trackingObject_tracks_new(ID *id, MovieTrackingObject *object, const char *name, int frame)
{
MovieClip *clip = (MovieClip *) id;
ListBase *tracksbase = &object->tracks;
+ MovieTrackingTrack *track;
if (object->flag & TRACKING_OBJECT_CAMERA)
tracksbase = &clip->tracking.tracks;
- add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number);
+ track = add_track_to_base(clip, &clip->tracking, tracksbase, name, frame);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL);
+
+ return track;
}
static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name)
@@ -475,6 +488,14 @@ static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack
marker.framenr = framenr;
copy_v2_v2(marker.pos, co);
+ /* a bit arbitrary, but better than creating markers with zero pattern
+ * which is forbidden actually
+ */
+ copy_v2_v2(marker.pattern_corners[0], track->markers[0].pattern_corners[0]);
+ copy_v2_v2(marker.pattern_corners[1], track->markers[0].pattern_corners[1]);
+ copy_v2_v2(marker.pattern_corners[2], track->markers[0].pattern_corners[2]);
+ copy_v2_v2(marker.pattern_corners[3], track->markers[0].pattern_corners[3]);
+
new_marker = BKE_tracking_marker_insert(track, &marker);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL);
@@ -1161,7 +1182,7 @@ static void rna_def_trackingStabilization(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem filter_items[] = {
- {TRACKING_FILTER_NEAREAST, "NEAREST", 0, "Nearest", ""},
+ {TRACKING_FILTER_NEAREST, "NEAREST", 0, "Nearest", ""},
{TRACKING_FILTER_BILINEAR, "BILINEAR", 0, "Bilinear", ""},
{TRACKING_FILTER_BICUBIC, "BICUBIC", 0, "Bicubic", ""},
{0, NULL, 0, NULL, NULL}
@@ -1318,16 +1339,19 @@ static void rna_def_trackingTracks(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "MovieTrackingTracks", NULL);
RNA_def_struct_sdna(srna, "MovieTracking");
RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
- func = RNA_def_function(srna, "add", "rna_trackingTracks_add");
+ func = RNA_def_function(srna, "new", "rna_trackingTracks_new");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
- RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
- RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
- RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+ RNA_def_function_ui_description(func, "Create new motion track in this movie clip");
+ RNA_def_string(func, "name", "", 0, "", "Name of new track");
+ RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add track on", MINFRAME, MAXFRAME);
+ parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track");
+ RNA_def_function_return(func, parm);
/* active track */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
@@ -1342,16 +1366,19 @@ static void rna_def_trackingObjectTracks(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "MovieTrackingObjectTracks", NULL);
RNA_def_struct_sdna(srna, "MovieTrackingObject");
RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
- func = RNA_def_function(srna, "add", "rna_trackingObject_tracks_add");
+ func = RNA_def_function(srna, "new", "rna_trackingObject_tracks_new");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
- RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
+ RNA_def_function_ui_description(func, "create new motion track in this movie clip");
+ RNA_def_string(func, "name", "", 0, "", "Name of new track");
RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
- RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+ parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track");
+ RNA_def_function_return(func, parm);
/* active track */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index a0a9f6183af..e5585b4f72d 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -55,6 +55,16 @@ EnumPropertyItem operator_context_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem uilist_layout_type_items[] = {
+ {UILST_LAYOUT_DEFAULT, "DEFAULT", 0, "Default Layout",
+ "Use the default, multi-rows layout"},
+ {UILST_LAYOUT_COMPACT, "COMPACT", 0, "Compact Layout",
+ "Use the compact, single-row layout"},
+ {UILST_LAYOUT_GRID, "GRID", 0, "Grid Layout",
+ "Use the grid-based layout"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include <assert.h>
@@ -155,7 +165,7 @@ static void panel_draw_header(const bContext *C, Panel *pnl)
RNA_parameter_list_free(&list);
}
-static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
+static void rna_Panel_unregister(Main *bmain, StructRNA *type)
{
ARegionType *art;
PanelType *pt = RNA_struct_blender_type_get(type);
@@ -171,7 +181,7 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -215,7 +225,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
memcpy(pt, &dummypt, sizeof(dummypt));
- pt->ext.srna = RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel");
+ pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
pt->ext.data = data;
pt->ext.call = call;
pt->ext.free = free;
@@ -241,7 +251,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
BLI_addtail(&art->paneltypes, pt);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return pt->ext.srna;
}
@@ -252,6 +262,105 @@ static StructRNA *rna_Panel_refine(PointerRNA *ptr)
return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Panel;
}
+/* UIList */
+static void uilist_draw_item(uiList *ui_list, bContext *C, uiLayout *layout, PointerRNA *dataptr, PointerRNA *itemptr,
+ int icon, PointerRNA *active_dataptr, const char *active_propname, int index)
+{
+ extern FunctionRNA rna_UIList_draw_item_func;
+
+ PointerRNA ul_ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
+ func = &rna_UIList_draw_item_func; /* RNA_struct_find_function(&ul_ptr, "draw_item"); */
+
+ RNA_parameter_list_create(&list, &ul_ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ RNA_parameter_set_lookup(&list, "layout", &layout);
+ RNA_parameter_set_lookup(&list, "data", dataptr);
+ RNA_parameter_set_lookup(&list, "item", itemptr);
+ RNA_parameter_set_lookup(&list, "icon", &icon);
+ RNA_parameter_set_lookup(&list, "active_data", active_dataptr);
+ RNA_parameter_set_lookup(&list, "active_property", &active_propname);
+ RNA_parameter_set_lookup(&list, "index", &index);
+ ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+ uiListType *ult = RNA_struct_blender_type_get(type);
+
+ if (!ult)
+ return;
+
+ RNA_struct_free_extension(type, &ult->ext);
+
+ WM_uilisttype_freelink(ult);
+
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+}
+
+static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ uiListType *ult, dummyult = {NULL};
+ uiList dummyuilist = {NULL};
+ PointerRNA dummyul_ptr;
+ int have_function[1];
+ size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
+
+ /* setup dummy menu & menu type to store static properties in */
+ dummyuilist.type = &dummyult;
+ RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr);
+
+ /* validate the python class */
+ if (validate(&dummyul_ptr, data, have_function) != 0)
+ return NULL;
+
+ if (strlen(identifier) >= sizeof(dummyult.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "Registering uilist class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummyult.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this uilist type before, and remove it */
+ ult = WM_uilisttype_find(dummyult.idname, TRUE);
+ if (ult && ult->ext.srna)
+ rna_UIList_unregister(bmain, ult->ext.srna);
+
+ /* create a new menu type */
+ ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist");
+ memcpy(ult, &dummyult, sizeof(dummyult));
+
+ ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList);
+ ult->ext.data = data;
+ ult->ext.call = call;
+ ult->ext.free = free;
+ RNA_struct_blender_type_set(ult->ext.srna, ult);
+ RNA_def_struct_flag(ult->ext.srna, STRUCT_NO_IDPROPERTIES);
+
+ ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL;
+
+ WM_uilisttype_add(ult);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
+ return ult->ext.srna;
+}
+
+static StructRNA *rna_UIList_refine(PointerRNA *ptr)
+{
+ uiList *ui_list = (uiList *)ptr->data;
+ return (ui_list->type && ui_list->type->ext.srna) ? ui_list->type->ext.srna : &RNA_UIList;
+}
+
/* Header */
static void header_draw(const bContext *C, Header *hdr)
@@ -288,7 +397,7 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -330,7 +439,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
ht = MEM_callocN(sizeof(HeaderType), "python buttons header");
memcpy(ht, &dummyht, sizeof(dummyht));
- ht->ext.srna = RNA_def_struct(&BLENDER_RNA, ht->idname, "Header");
+ ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header);
ht->ext.data = data;
ht->ext.call = call;
ht->ext.free = free;
@@ -341,7 +450,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
BLI_addtail(&art->headertypes, ht);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return ht->ext.srna;
}
@@ -411,7 +520,7 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static char _menu_descr[RNA_DYN_DESCR_MAX];
@@ -463,7 +572,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
mt->description = buf;
}
- mt->ext.srna = RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu");
+ mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
mt->ext.data = data;
mt->ext.call = call;
mt->ext.free = free;
@@ -476,7 +585,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
WM_menutype_add(mt);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return mt->ext.srna;
}
@@ -495,6 +604,8 @@ static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
else assert(!"setting the bl_description on a non-builtin menu");
}
+/* UILayout */
+
static int rna_UILayout_active_get(PointerRNA *ptr)
{
return uiLayoutGetActive(ptr->data);
@@ -651,8 +762,8 @@ static void rna_def_panel(BlenderRNA *brna)
static EnumPropertyItem panel_flag_items[] = {
{PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed",
"Defines if the panel has to be open or collapsed at the time of its creation"},
- {PNL_NO_HEADER, "HIDE_HEADER", 0, "Show Header",
- "If set to True, the panel shows a header, which contains a clickable "
+ {PNL_NO_HEADER, "HIDE_HEADER", 0, "Hide Header",
+ "If set to False, the panel shows a header, which contains a clickable "
"arrow to collapse the panel and the label (see bl_label)"},
{0, NULL, 0, NULL, NULL}
};
@@ -680,7 +791,7 @@ static void rna_def_panel(BlenderRNA *brna)
func = RNA_def_function(srna, "draw_header", NULL);
RNA_def_function_ui_description(func, "Draw UI elements into the panel's header UI layout");
- RNA_def_function_flag(func, FUNC_REGISTER);
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
@@ -702,9 +813,6 @@ static void rna_def_panel(BlenderRNA *brna)
"class name is \"OBJECT_PT_hello\", and bl_idname is not set by the "
"script, then bl_idname = \"OBJECT_PT_hello\"");
- /* panel's label indeed doesn't need PROP_TRANSLATE flag: translation of label happens in runtime
- * when drawing panel and having this flag set will make runtime switching of language much more tricky
- * because label will be stored translated */
prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->label");
RNA_def_property_flag(prop, PROP_REGISTER);
@@ -738,6 +846,58 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Options", "Options for this panel type");
}
+static void rna_def_uilist(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ PropertyRNA *parm;
+ FunctionRNA *func;
+
+ srna = RNA_def_struct(brna, "UIList", NULL);
+ RNA_def_struct_ui_text(srna, "UIList", "UI list containing the elements of a collection");
+ RNA_def_struct_sdna(srna, "uiList");
+ RNA_def_struct_refine_func(srna, "rna_UIList_refine");
+ RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL);
+
+ /* draw */
+ func = RNA_def_function(srna, "draw_item", NULL);
+ RNA_def_function_ui_description(func, "Draw an item in the list (NOTE: when you define your own draw_item "
+ "function, you may want to check given 'item' is of the right type...)");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
+ parm = RNA_def_pointer(func, "item", "AnyType", "", "Item of the collection property");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
+ parm = RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Icon of the item in the collection", 0, INT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "active_data", "AnyType", "",
+ "Data from which to take property for the active element");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
+ parm = RNA_def_string(func, "active_property", "", 0, "",
+ "Identifier of property in active_data, for the active element");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the item in the collection", 0, INT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ prop = RNA_def_property(srna, "layout_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, uilist_layout_type_items);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ /* registration */
+ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->idname");
+ RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
+ RNA_def_property_ui_text(prop, "ID Name",
+ "If this is set, the uilist gets a custom ID, otherwise it takes the "
+ "name of the class used to define the uilist (for example, if the "
+ "class name is \"OBJECT_UL_vgroups\", and bl_idname is not set by the "
+ "script, then bl_idname = \"OBJECT_UL_vgroups\")");
+}
+
static void rna_def_header(BlenderRNA *brna)
{
StructRNA *srna;
@@ -829,15 +989,12 @@ static void rna_def_menu(BlenderRNA *brna)
"class name is \"OBJECT_MT_hello\", and bl_idname is not set by the "
"script, then bl_idname = \"OBJECT_MT_hello\")");
- /* menu's label indeed doesn't need PROP_TRANSLATE flag: translation of label happens in runtime
- * when drawing panel and having this flag set will make runtime switching of language much more tricky
- * because label will be stored translated */
prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->label");
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "Label", "The menu label");
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set");
@@ -852,6 +1009,7 @@ void RNA_def_ui(BlenderRNA *brna)
{
rna_def_ui_layout(brna);
rna_def_panel(brna);
+ rna_def_uilist(brna);
rna_def_header(brna);
rna_def_menu(brna);
}
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 548539e3395..0ce98e0b364 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -32,17 +32,72 @@
#include <stdlib.h>
#include <stdio.h>
+#include "BLI_utildefines.h"
+
+#include "BLF_translation.h"
+
#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "DNA_screen_types.h"
#include "UI_resources.h"
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "rna_internal.h"
+#define DEF_ICON_BLANK_SKIP
+#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""},
+#define DEF_VICO(name) {VICO_##name, (#name), 0, (#name), ""},
+EnumPropertyItem icon_items[] = {
+#include "UI_icons.h"
+ {0, NULL, 0, NULL, NULL}
+};
+#undef DEF_ICON_BLANK_SKIP
+#undef DEF_ICON
+#undef DEF_VICO
+
#ifdef RNA_RUNTIME
-static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, int icon,
- int expand, int slider, int toggle, int icon_only, int event, int full_event,
- int emboss, int index)
+static const char *rna_translate_ui_text(const char *text, const char *text_ctxt, StructRNA *type, PropertyRNA *prop,
+ int translate)
+{
+ /* Also return text if UI labels translation is disabled. */
+ if (!text || !text[0] || !translate || !BLF_translate_iface()) {
+ return text;
+ }
+
+ /* If a text_ctxt is specified, use it! */
+ if (text_ctxt && text_ctxt[0]) {
+ return BLF_pgettext(text_ctxt, text);
+ }
+
+ /* Else, if an RNA type or property is specified, use its context. */
+#if 0
+ /* XXX Disabled for now. Unfortunately, their is absolutely no way from py code to get the RNA struct corresponding
+ * to the 'data' (in functions like prop() & co), as this is pure runtime data. Hence, messages extraction
+ * script can't determine the correct context it should use for such 'text' messages...
+ * So for now, one have to explicitly specify the 'text_ctxt' when using prop() etc. functions,
+ * if default context is not suitable.
+ */
+ if (prop) {
+ return BLF_pgettext(RNA_property_translation_context(prop), text);
+ }
+#else
+ (void)prop;
+#endif
+ if (type) {
+ return BLF_pgettext(RNA_struct_translation_context(type), text);
+ }
+
+ /* Else, default context! */
+ return BLF_pgettext(BLF_I18NCONTEXT_DEFAULT, text);
+}
+
+static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, const char *text_ctxt,
+ int translate, int icon, int expand, int slider, int toggle, int icon_only, int event,
+ int full_event, int emboss, int index)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
int flag = 0;
@@ -52,6 +107,9 @@ static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname,
return;
}
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
+
flag |= (slider) ? UI_ITEM_R_SLIDER : 0;
flag |= (expand) ? UI_ITEM_R_EXPAND : 0;
flag |= (toggle) ? UI_ITEM_R_TOGGLE : 0;
@@ -63,36 +121,266 @@ static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname,
uiItemFullR(layout, ptr, prop, index, 0, flag, name, icon);
}
-static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, int icon, int emboss)
+static void rna_uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name,
+ const char *text_ctxt, int translate, int icon)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ /* 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);
+}
+
+static void rna_uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value,
+ const char *name, const char *text_ctxt, int translate, int icon)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
+
+ /* XXX This will search property again :( */
+ uiItemEnumR_string(layout, ptr, propname, value, name, icon);
+}
+
+static void rna_uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
+ struct PointerRNA *searchptr, const char *searchpropname,
+ const char *name, const char *text_ctxt, int translate, int icon)
{
- int flag = UI_ITEM_O_RETURN_PROPS;
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
+
+ /* XXX This will search property again :( */
+ uiItemPointerR(layout, ptr, propname, searchptr, searchpropname, name, icon);
+}
+
+static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, const char *text_ctxt,
+ int translate, int icon, int emboss)
+{
+ wmOperatorType *ot;
+ int flag;
+
+ ot = WM_operatortype_find(opname, 0); /* print error next */
+ if (!ot || !ot->srna) {
+ RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
+ return PointerRNA_NULL;
+ }
+
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);
+
+ flag = UI_ITEM_O_RETURN_PROPS;
flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG;
- return uiItemFullO(layout, opname, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag);
+
+ return uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag);
+}
+
+static void rna_uiItemMenuEnumO(uiLayout *layout, const char *opname, const char *propname, const char *name,
+ const char *text_ctxt, int translate, int icon)
+{
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+
+ if (!ot || !ot->srna) {
+ RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
+ return;
+ }
+
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);
+
+ /* XXX This will search operator again :( */
+ uiItemMenuEnumO(layout, opname, propname, name, icon);
+}
+
+static void rna_uiItemL(uiLayout *layout, const char *name, const char *text_ctxt, int translate,
+ int icon, int icon_value)
+{
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
+
+ if (icon_value && !icon) {
+ icon = icon_value;
+ }
+
+ uiItemL(layout, name, icon);
+}
+
+static void rna_uiItemM(uiLayout *layout, bContext *C, const char *menuname, const char *name, const char *text_ctxt,
+ int translate, int icon)
+{
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
+
+ uiItemM(layout, C, menuname, name, icon);
+}
+
+static void rna_uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
+ const char *name, const char *text_ctxt, int translate)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
+
+ /* XXX This will search property again :( */
+ uiTemplateAnyID(layout, ptr, propname, proptypename, name);
+}
+
+static void rna_uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *root_ptr,
+ const char *name, const char *text_ctxt, int translate)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ /* Get translated name (label). */
+ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
+
+ /* XXX This will search property again :( */
+ uiTemplatePathBuilder(layout, ptr, propname, root_ptr, name);
+}
+
+static int rna_ui_get_rnaptr_icon(bContext *C, PointerRNA *ptr_icon)
+{
+ return UI_rnaptr_icon_get(C, ptr_icon, RNA_struct_ui_icon(ptr_icon->type), FALSE);
+}
+
+static const char *rna_ui_get_enum_name(bContext *C, PointerRNA *ptr, const char *propname, const char *identifier)
+{
+ PropertyRNA *prop = NULL;
+ EnumPropertyItem *items = NULL, *item;
+ int free;
+ const char *name = "";
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop || (RNA_property_type(prop) != PROP_ENUM)) {
+ RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return name;
+ }
+
+ RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
+
+ if (items) {
+ for (item = items; item->identifier; item++) {
+ if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ name = item->name;
+ break;
+ }
+ }
+ if (free) {
+ MEM_freeN(items);
+ }
+ }
+
+ return name;
+}
+
+static const char *rna_ui_get_enum_description(bContext *C, PointerRNA *ptr, const char *propname,
+ const char *identifier)
+{
+ PropertyRNA *prop = NULL;
+ EnumPropertyItem *items = NULL, *item;
+ int free;
+ const char *desc = "";
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop || (RNA_property_type(prop) != PROP_ENUM)) {
+ RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return desc;
+ }
+
+ RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
+
+ if (items) {
+ for (item = items; item->identifier; item++) {
+ if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ desc = item->description;
+ break;
+ }
+ }
+ if (free) {
+ MEM_freeN(items);
+ }
+ }
+
+ return desc;
+}
+
+static int rna_ui_get_enum_icon(bContext *C, PointerRNA *ptr, const char *propname, const char *identifier)
+{
+ PropertyRNA *prop = NULL;
+ EnumPropertyItem *items = NULL, *item;
+ int free;
+ int icon = ICON_NONE;
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop || (RNA_property_type(prop) != PROP_ENUM)) {
+ RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return icon;
+ }
+
+ RNA_property_enum_items(C, ptr, prop, &items, NULL, &free);
+
+ if (items) {
+ for (item = items; item->identifier; item++) {
+ if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ icon = item->icon;
+ break;
+ }
+ }
+ if (free) {
+ MEM_freeN(items);
+ }
+ }
+
+ return icon;
}
#else
-#define DEF_ICON_BLANK_SKIP
-#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""},
-#define DEF_VICO(name) {VICO_##name, (#name), 0, (#name), ""},
-static EnumPropertyItem icon_items[] = {
-#include "UI_icons.h"
- {0, NULL, 0, NULL, NULL}
-};
-#undef DEF_ICON_BLANK_SKIP
-#undef DEF_ICON
-#undef DEF_VICO
+static void api_ui_item_common_text(FunctionRNA *func)
+{
+ RNA_def_string(func, "text", "", 0, "", "Override automatic text of the item");
+ RNA_def_string(func, "text_ctxt", "", 0, "", "Override automatic translation context of the given text");
+ RNA_def_boolean(func, "translate", true, "", "Translate the given text, when UI translation is enabled");
+}
static void api_ui_item_common(FunctionRNA *func)
{
PropertyRNA *prop;
- RNA_def_string_translate(func, "text", "", 0, "", "Override automatic text of the item");
+ api_ui_item_common_text(func);
prop = RNA_def_property(func, "icon", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, icon_items);
RNA_def_property_ui_text(prop, "Icon", "Override automatic icon of the item");
-
}
static void api_ui_item_op(FunctionRNA *func)
@@ -130,13 +418,6 @@ void RNA_api_ui_layout(StructRNA *srna)
{'h', "HUE", 0, "Hue", ""},
{0, NULL, 0, NULL, NULL}
};
-
- static EnumPropertyItem list_type_items[] = {
- {0, "DEFAULT", 0, "None", ""},
- {'c', "COMPACT", 0, "Compact", ""},
- {'i', "ICONS", 0, "Icons", ""},
- {0, NULL, 0, NULL, NULL}
- };
/* simple layout specifiers */
func = RNA_def_function(srna, "row", "uiLayoutRow");
@@ -175,6 +456,44 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_float(func, "percentage", 0.0f, 0.0f, 1.0f, "Percentage", "Percentage of width to split at", 0.0f, 1.0f);
RNA_def_boolean(func, "align", 0, "", "Align buttons to each other");
+ /* Icon of a rna pointer */
+ func = RNA_def_function(srna, "icon", "rna_ui_get_rnaptr_icon");
+ parm = RNA_def_int(func, "icon_value", ICON_NONE, 0, INT_MAX, "", "Icon identifier", 0, INT_MAX);
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take the icon");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
+ RNA_def_function_ui_description(func, "Return the custom icon for this data, "
+ "use it e.g. to get materials or texture icons");
+
+ /* UI name, description and icon of an enum item */
+ func = RNA_def_function(srna, "enum_item_name", "rna_ui_get_enum_name");
+ parm = RNA_def_string(func, "name", "", 0, "", "UI name of the enum item");
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_string(func, "identifier", "", 0, "", "Identifier of the enum item");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Return the UI name for this enum item");
+
+ func = RNA_def_function(srna, "enum_item_description", "rna_ui_get_enum_description");
+ parm = RNA_def_string(func, "description", "", 0, "", "UI description of the enum item");
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_string(func, "identifier", "", 0, "", "Identifier of the enum item");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Return the UI description for this enum item");
+
+ func = RNA_def_function(srna, "enum_item_icon", "rna_ui_get_enum_icon");
+ parm = RNA_def_int(func, "icon_value", ICON_NONE, 0, INT_MAX, "", "Icon identifier", 0, INT_MAX);
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_string(func, "identifier", "", 0, "", "Identifier of the enum item");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Return the icon for this enum item");
+
/* items */
func = RNA_def_function(srna, "prop", "rna_uiItemR");
RNA_def_function_ui_description(func, "Item. Exposes an RNA item and places it into the layout");
@@ -194,17 +513,17 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "props_enum", "uiItemsEnumR");
api_ui_item_rna_common(func);
- func = RNA_def_function(srna, "prop_menu_enum", "uiItemMenuEnumR");
+ func = RNA_def_function(srna, "prop_menu_enum", "rna_uiItemMenuEnumR");
api_ui_item_rna_common(func);
api_ui_item_common(func);
- func = RNA_def_function(srna, "prop_enum", "uiItemEnumR_string");
+ func = RNA_def_function(srna, "prop_enum", "rna_uiItemEnumR_string");
api_ui_item_rna_common(func);
parm = RNA_def_string(func, "value", "", 0, "", "Enum property value");
RNA_def_property_flag(parm, PROP_REQUIRED);
api_ui_item_common(func);
- func = RNA_def_function(srna, "prop_search", "uiItemPointerR");
+ func = RNA_def_function(srna, "prop_search", "rna_uiItemPointerR");
api_ui_item_rna_common(func);
parm = RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
@@ -227,7 +546,7 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator");
RNA_def_property_flag(parm, PROP_REQUIRED);
- func = RNA_def_function(srna, "operator_menu_enum", "uiItemMenuEnumO");
+ func = RNA_def_function(srna, "operator_menu_enum", "rna_uiItemMenuEnumO");
api_ui_item_op(func); /* cant use api_ui_item_op_common because property must come right after */
parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator");
RNA_def_property_flag(parm, PROP_REQUIRED);
@@ -274,11 +593,15 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED);
#endif
- func = RNA_def_function(srna, "label", "uiItemL");
- RNA_def_function_ui_description(func, "Item. Display text in the layout");
- api_ui_item_common(func);
+ func = RNA_def_function(srna, "label", "rna_uiItemL");
+ RNA_def_function_ui_description(func, "Item. Display text and/or icon in the layout");
+ api_ui_item_common(func);
+ 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()...)");
- func = RNA_def_function(srna, "menu", "uiItemM");
+ func = RNA_def_function(srna, "menu", "rna_uiItemM");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu");
api_ui_item_common(func);
@@ -315,7 +638,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX);
RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX);
- func = RNA_def_function(srna, "template_any_ID", "uiTemplateAnyID");
+ func = RNA_def_function(srna, "template_any_ID", "rna_uiTemplateAnyID");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in data");
@@ -323,16 +646,16 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_string(func, "type_property", "", 0, "",
"Identifier of property in data giving the type of the ID-blocks to use");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_string_translate(func, "text", "", 0, "", "Custom label to display in UI");
+ api_ui_item_common_text(func);
- func = RNA_def_function(srna, "template_path_builder", "uiTemplatePathBuilder");
+ func = RNA_def_function(srna, "template_path_builder", "rna_uiTemplatePathBuilder");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in data");
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_pointer(func, "root", "ID", "", "ID-block from which path is evaluated from");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
- RNA_def_string_translate(func, "text", "", 0, "", "Custom label to display in UI");
+ api_ui_item_common_text(func);
func = RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -369,6 +692,10 @@ void RNA_api_ui_layout(StructRNA *srna)
api_ui_item_rna_common(func);
RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail");
+ func = RNA_def_function(srna, "template_icon_view", "uiTemplateIconView");
+ RNA_def_function_ui_description(func, "Enum. Large widget showing Icon previews");
+ api_ui_item_rna_common(func);
+
func = RNA_def_function(srna, "template_histogram", "uiTemplateHistogram");
RNA_def_function_ui_description(func, "Item. A histogramm widget to analyze imaga data");
api_ui_item_rna_common(func);
@@ -439,26 +766,30 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_boolean(func, "compact", 0, "", "Use more compact layout");
func = RNA_def_function(srna, "template_list", "uiTemplateList");
- RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups "
- "(WARNING: only one per panel allowed!).");
+ RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups.");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
- parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
+ parm = RNA_def_string(func, "listtype_name", "", 0, "", "Identifier of the list type to use");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_string(func, "list_id", "", 0, "",
+ "Identifier of this list widget (mandatory when using default \"" UI_UL_DEFAULT_CLASS_NAME
+ "\" class). "
+ "If this is set, the uilist gets a custom ID, otherwise it takes the "
+ "name of the class used to define the uilist (for example, if the "
+ "class name is \"OBJECT_UL_vgroups\", and list_id is not set by the "
+ "script, then bl_idname = \"OBJECT_UL_vgroups\")");
+ parm = RNA_def_pointer(func, "dataptr", "AnyType", "", "Data from which to take the Collection property");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
- parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in data");
+ parm = RNA_def_string(func, "propname", "", 0, "", "Identifier of the Collection property in data");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_pointer(func, "active_data", "AnyType", "",
- "Data from which to take property for the active element");
+ parm = RNA_def_pointer(func, "active_dataptr", "AnyType", "",
+ "Data from which to take the integer property, index of the active item");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
- parm = RNA_def_string(func, "active_property", "", 0, "",
- "Identifier of property in data, for the active element");
+ parm = RNA_def_string(func, "active_propname", "", 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, "prop_list", "", 0, "",
- "Identifier of a string property in each data member, specifying which "
- "of its properties should have a widget displayed in its row "
- "(format: \"propname1:propname2:propname3:...\")");
RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display", 0, INT_MAX);
RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Maximum number of rows to display", 0, INT_MAX);
- RNA_def_enum(func, "type", list_type_items, 0, "Type", "Type of list to use");
+ RNA_def_enum(func, "type", uilist_layout_type_items, UILST_LAYOUT_DEFAULT, "Type", "Type of layout to use");
func = RNA_def_function(srna, "template_running_jobs", "uiTemplateRunningJobs");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 7be34c398ae..9d5a0024c0a 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -47,6 +47,7 @@
#include "BLF_translation.h"
#include "BKE_sound.h"
+#include "BKE_addon.h"
#ifdef WITH_CYCLES
static EnumPropertyItem compute_device_type_items[] = {
@@ -62,10 +63,12 @@ static EnumPropertyItem compute_device_type_items[] = {
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
+#include "BKE_blender.h"
#include "BKE_DerivedMesh.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_idprop.h"
#include "GPU_draw.h"
@@ -78,14 +81,17 @@ static EnumPropertyItem compute_device_type_items[] = {
#include "CCL_api.h"
+#include "BKE_addon.h"
+
static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
WM_main_add_notifier(NC_WINDOW, NULL);
}
+/* also used by buffer swap switching */
static void rna_userdef_dpi_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
- U.widget_unit = (U.dpi * 20 + 36) / 72;
+ BKE_userdef_state();
WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */
}
@@ -319,6 +325,11 @@ static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *bext_ptr)
return;
}
+ if (bext->prop) {
+ IDP_FreeProperty(bext->prop);
+ MEM_freeN(bext->prop);
+ }
+
BLI_freelinkN(&U.addons, bext);
RNA_POINTER_INVALIDATE(bext_ptr);
}
@@ -339,6 +350,11 @@ static PointerRNA rna_Theme_space_generic_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGeneric, ptr->data);
}
+static PointerRNA rna_Theme_space_gradient_get(PointerRNA *ptr)
+{
+ return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGradient, ptr->data);
+}
+
static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr)
{
return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceListGeneric, ptr->data);
@@ -426,6 +442,103 @@ static EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C), Poi
}
#endif
+static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, int create)
+{
+ if (create && !ptr->data) {
+ IDPropertyTemplate val = {0};
+ ptr->data = IDP_New(IDP_GROUP, &val, "RNA_AddonPreferences group");
+ }
+
+ return ptr->data;
+}
+
+static PointerRNA rna_Addon_preferences_get(PointerRNA *ptr)
+{
+ bAddon *addon = (bAddon *)ptr->data;
+ bAddonPrefType *apt = BKE_addon_pref_type_find(addon->module, TRUE);
+ if (apt) {
+ if (addon->prop == NULL) {
+ IDPropertyTemplate val = {0};
+ addon->prop = IDP_New(IDP_GROUP, &val, addon->module); /* name is unimportant */
+ }
+ return rna_pointer_inherit_refine(ptr, apt->ext.srna, addon->prop);
+ }
+ else {
+ return PointerRNA_NULL;
+ }
+}
+
+static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+ bAddonPrefType *apt = RNA_struct_blender_type_get(type);
+
+ if (!apt)
+ return;
+
+ RNA_struct_free_extension(type, &apt->ext);
+
+ BKE_addon_pref_type_remove(apt);
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+}
+
+static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bAddonPrefType *apt, dummyapt = {{'\0'}};
+ bAddon dummyaddon = {NULL};
+ PointerRNA dummyhtr;
+ // int have_function[1];
+
+ /* setup dummy header & header type to store static properties in */
+ RNA_pointer_create(NULL, &RNA_AddonPreferences, &dummyaddon, &dummyhtr);
+
+ /* validate the python class */
+ if (validate(&dummyhtr, data, NULL /* have_function */ ) != 0)
+ return NULL;
+
+ BLI_strncpy(dummyapt.idname, dummyaddon.module, sizeof(dummyapt.idname));
+ if (strlen(identifier) >= sizeof(dummyapt.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "Registering addon-prefs class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummyapt.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this header type before, and remove it */
+ apt = BKE_addon_pref_type_find(dummyaddon.module, TRUE);
+ if (apt) {
+ if (apt->ext.srna) {
+ rna_AddonPref_unregister(bmain, apt->ext.srna);
+ }
+ }
+
+ /* create a new header type */
+ apt = MEM_mallocN(sizeof(bAddonPrefType), "addonpreftype");
+ memcpy(apt, &dummyapt, sizeof(dummyapt));
+ BKE_addon_pref_type_add(apt);
+
+ apt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_AddonPreferences);
+ apt->ext.data = data;
+ apt->ext.call = call;
+ apt->ext.free = free;
+ RNA_struct_blender_type_set(apt->ext.srna, apt);
+
+// apt->draw = (have_function[0]) ? header_draw : NULL;
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
+ return apt->ext.srna;
+}
+
+/* placeholder, doesn't do anything useful yet */
+static StructRNA *rna_AddonPref_refine(PointerRNA *ptr)
+{
+ return (ptr->type) ? ptr->type : &RNA_AddonPreferences;
+}
+
#else
static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
@@ -435,7 +548,7 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
static EnumPropertyItem font_kerning_style[] = {
{0, "UNFITTED", 0, "Unfitted", "Use scaled but un-grid-fitted kerning distances"},
- {1, "DEFAULT", 0, "Default", "Use scaled and grid-fitted kerning distances"},
+ {1, "FITTED", 0, "Fitted", "Use scaled and grid-fitted kerning distances"},
{0, NULL, 0, NULL, NULL}
};
@@ -495,29 +608,14 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna)
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Style", "Theme settings for style sets");
- /* (not used yet) */
-#if 0
- prop = RNA_def_property(srna, "panelzoom", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.5, 2.0);
- RNA_def_property_ui_text(prop, "Panel Zoom", "Default zoom level for panel areas");
-#endif
prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "paneltitle");
RNA_def_property_struct_type(prop, "ThemeFontStyle");
- RNA_def_property_ui_text(prop, "Panel Style", "");
+ RNA_def_property_ui_text(prop, "Panel Title Font", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- /* (not used yet) */
-#if 0
- prop = RNA_def_property(srna, "group_label", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NEVER_NULL);
- RNA_def_property_pointer_sdna(prop, NULL, "grouplabel");
- RNA_def_property_struct_type(prop, "ThemeFontStyle");
- RNA_def_property_ui_text(prop, "Group Label Font", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-#endif
prop = RNA_def_property(srna, "widget_label", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "widgetlabel");
@@ -648,10 +746,44 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna)
prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_ui_text(prop, "Header", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
+ prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_ui_text(prop, "Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
prop = RNA_def_property(srna, "show_header", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Show Header", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "show_back", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+}
+
+static void rna_def_userdef_theme_ui_gradient(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ThemeGradientColors", NULL);
+ RNA_def_struct_sdna(srna, "uiGradientColors");
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Theme Background Color", "Theme settings for background colors and gradient");
+
+ prop = RNA_def_property(srna, "show_grad", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Use Gradient",
+ "Do a gradient for the background of the viewport working area");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "gradient", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Gradient Low", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "high_gradient", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Gradient High/Off", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_ui(BlenderRNA *brna)
@@ -662,7 +794,8 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
rna_def_userdef_theme_ui_wcol(brna);
rna_def_userdef_theme_ui_wcol_state(brna);
rna_def_userdef_theme_ui_panel(brna);
-
+ rna_def_userdef_theme_ui_gradient(brna);
+
srna = RNA_def_struct(brna, "ThemeUserInterface", NULL);
RNA_def_struct_sdna(srna, "ThemeUI");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
@@ -757,9 +890,14 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "State Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "panel", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NEVER_NULL);
- RNA_def_property_ui_text(prop, "Panel Colors", "");
+ prop = RNA_def_property(srna, "menu_shadow_fac", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_ui_text(prop, "Menu Shadow Strength", "Blending factor for menu shadows");
+ RNA_def_property_range(prop, 0.01f, 1.0f);
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "menu_shadow_width", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Menu Shadow Width", "Width of menu shadows in standard pixels, set to zero to disable it");
+ RNA_def_property_range(prop, 0.0f, 24.0f);
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH);
@@ -837,10 +975,93 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Header Text Highlight", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ /* panel settings */
+ prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Panel Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
/* buttons */
/* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */
prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Region Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_title", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text Titles", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+/* } */
+}
+
+static void rna_def_userdef_theme_space_gradient(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ThemeSpaceGradient", NULL);
+ RNA_def_struct_sdna(srna, "ThemeSpace");
+ RNA_def_struct_ui_text(srna, "Theme Space Settings", "");
+
+ /* window */
+ prop = RNA_def_property(srna, "title", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Title", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* header */
+ prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "header_text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "header_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* panel settings */
+ prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Panel Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* gradient/background settings */
+ prop = RNA_def_property(srna, "gradients", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Gradient Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* buttons */
+/* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */
+ prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Region Background", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
@@ -903,6 +1124,17 @@ static void rna_def_userdef_theme_spaces_main(StructRNA *srna)
RNA_def_property_ui_text(prop, "Theme Space", "Settings for space");
}
+static void rna_def_userdef_theme_spaces_gradient(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "space", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "ThemeSpaceGradient");
+ RNA_def_property_pointer_funcs(prop, "rna_Theme_space_gradient_get", NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Theme Space", "Settings for space");
+}
+
static void rna_def_userdef_theme_spaces_list_main(StructRNA *srna)
{
PropertyRNA *prop;
@@ -1107,18 +1339,13 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme 3D View", "Theme settings for the 3D View");
- rna_def_userdef_theme_spaces_main(srna);
+ rna_def_userdef_theme_spaces_gradient(srna);
prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Grid", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 4);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
prop = RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Wire", "");
@@ -1273,11 +1500,6 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Grid", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@@ -1360,12 +1582,6 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Selected File", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "tiles", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_float_sdna(prop, NULL, "panel");
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Tiles", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
prop = RNA_def_property(srna, "scrollbar", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@@ -1473,6 +1689,13 @@ static void rna_def_userdef_theme_space_console(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Cursor", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "select", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "console_select");
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Selection", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
}
static void rna_def_userdef_theme_space_info(BlenderRNA *brna)
@@ -1537,10 +1760,28 @@ static void rna_def_userdef_theme_space_text(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Syntax Built-in", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ prop = RNA_def_property(srna, "syntax_symbols", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxs");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Syntax Symbols", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
prop = RNA_def_property(srna, "syntax_special", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxv");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Decorator", "");
+ RNA_def_property_ui_text(prop, "Syntax Special", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "syntax_preprocessor", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxd");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Syntax PreProcessor", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "syntax_reserved", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxr");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Syntax Reserved", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "syntax_comment", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -1642,6 +1883,18 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Frame Node", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "matte_node", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxs");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Matte Node", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "distor_node", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxd");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Distort Node", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "noodle_curving", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "noodle_curving");
@@ -1654,7 +1907,7 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
static void rna_def_userdef_theme_space_logic(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
+// PropertyRNA *prop;
/* space_logic */
@@ -1665,17 +1918,13 @@ static void rna_def_userdef_theme_space_logic(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_buts(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
+// PropertyRNA *prop;
/* space_buts */
@@ -1686,10 +1935,6 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_time(BlenderRNA *brna)
@@ -2224,6 +2469,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
static EnumPropertyItem active_theme_area[] = {
{0, "USER_INTERFACE", ICON_UI, "User Interface", ""},
+ {19, "STYLE", ICON_FONTPREVIEW, "Text Style", ""},
{18, "BONE_COLOR_SETS", ICON_COLOR, "Bone Color Sets", ""},
{1, "VIEW_3D", ICON_VIEW3D, "3D View", ""},
{2, "TIMELINE", ICON_TIME, "Timeline", ""},
@@ -2390,6 +2636,32 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
prop = RNA_def_property(srna, "module", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Module", "Module name");
RNA_def_struct_name_property(srna, prop);
+
+ /* Collection active property */
+ prop = RNA_def_property(srna, "preferences", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "AddonPreferences");
+ RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL);
+}
+
+static void rna_def_userdef_addon_pref(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "AddonPreferences", NULL);
+ RNA_def_struct_ui_text(srna, "Addon Preferences", "");
+ RNA_def_struct_sdna(srna, "bAddon"); /* WARNING: only a bAddon during registration */
+
+ RNA_def_struct_refine_func(srna, "rna_AddonPref_refine");
+ RNA_def_struct_register_funcs(srna, "rna_AddonPref_register", "rna_AddonPref_unregister", NULL);
+ RNA_def_struct_idprops_func(srna, "rna_AddonPref_idprops");
+
+ /* registration */
+ RNA_define_verify_sdna(0);
+ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "module");
+ RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
+ RNA_define_verify_sdna(1);
}
@@ -2400,6 +2672,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
rna_def_userdef_theme_ui(brna);
rna_def_userdef_theme_space_generic(brna);
+ rna_def_userdef_theme_space_gradient(brna);
rna_def_userdef_theme_space_list_generic(brna);
rna_def_userdef_theme_space_view3d(brna);
@@ -3027,62 +3300,10 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
-#if 0
- /* hardcoded here, could become dynamic somehow */
- /* locale according to http://www.roseindia.net/tutorials/I18N/locales-list.shtml */
- /* if you edit here, please also edit the source/blender/blenfont/intern/blf_lang.c 's locales */
- /* Note: As this list is in alphabetical order, and not defined order,
- * here is the highest define currently in use: 35 (Esperanto). */
static EnumPropertyItem language_items[] = {
- { 0, "", 0, N_("Nearly Done"), ""},
- { 0, "DEFAULT", 0, "Default (Default)", ""},
- /* using the utf8 flipped form of Arabic (العربية) */
- {21, "ARABIC", 0, "Arabic (ﺔﻴﺑﺮﻌﻟïº)", "ar_EG"},
- {32, "BRAZILIANPORTUGUESE", 0, "Brazilian Portuguese (Português do Brasil)", "pt_BR"},
- { 1, "ENGLISH", 0, "English (English)", "en_US"},
- { 8, "FRENCH", 0, "French (Français)", "fr_FR"},
- { 4, "ITALIAN", 0, "Italian (Italiano)", "it_IT"},
- { 2, "JAPANESE", 0, "Japanese (日本語)", "ja_JP"},
- {12, "PORTUGUESE", 0, "Portuguese (Português)", "pt"},
- {15, "RUSSIAN", 0, "Russian (РуÑÑкий)", "ru_RU"},
- {13, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese (简体中文)", "zh_CN"},
- { 9, "SPANISH", 0, "Spanish (Español)", "es"},
- {14, "TRADITIONAL_CHINESE", 0, "Traditional Chinese (ç¹é«”中文)", "zh_TW"},
- {18, "UKRAINIAN", 0, "Ukrainian (УкраїнÑький)", "uk_UA"},
- { 0, "", 0, N_("In Progress"), ""},
-/* {22, "BULGARIAN", 0, "Bulgarian (БългарÑки)", "bg_BG"},*/ /* XXX Not active nor enough translated. */
-/* {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"},*/ /* XXX Not active nor enough translated. */
- {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"},
- {11, "CZECH", 0, "Czech (Český)", "cs_CZ"},
- { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"},
- {35, "ESPERANTO", 0, "Esperanto (Esperanto)", "eo"},
- {34, "ESTONIAN", 0, "Estonian (Eestlane)", "et_EE"},
-/* { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"},*/ /* XXX Not active nor enough translated. */
- { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"},
-/* {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"},*/ /* XXX Not active nor enough translated. */
- /* using the utf8 flipped form of Hebrew (עִבְרִית)) */
- {33, "HEBREW", 0, "Hebrew (תירִבְעִ)", "he_IL"},
- {31, "HUNGARIAN", 0, "Hungarian (Magyar)", "hu_HU"},
- {27, "INDONESIAN", 0, "Indonesian (Bahasa indonesia)", "id_ID"},
- {29, "KYRGYZ", 0, "Kyrgyz (Кыргыз тили)", "ky_KG"},
-/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX Not active nor enough translated. */
-/* {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"},*/ /* XXX Not active nor enough translated. */
- /* using the utf8 flipped form of Persian (Ùارسی) */
- {26, "PERSIAN", 0, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"},
-/* {19, "POLISH", 0, "Polish (Polski)", "pl_PL"},*/ /* XXX Not active nor enough translated. */
-/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX Not active nor enough translated. */
- {17, "SERBIAN", 0, "Serbian (СрпÑки)", "sr_RS"},
- {28, "SERBIAN_LATIN", 0, "Serbian Latin (Srpski latinica)", "sr_RS@latin"},
- { 7, "SWEDISH", 0, "Swedish (Svenska)", "sv_SE"},
- {30, "TURKISH", 0, "Turkish (Türkçe)", "tr_TR"},
- { 0, NULL, 0, NULL, NULL}
- };
-#else
- static EnumPropertyItem language_items[] = {
- { 0, "DEFAULT", 0, "Default (Default)", ""},
- { 0, NULL, 0, NULL, NULL}
+ {0, "DEFAULT", 0, "Default (Default)", ""},
+ {0, NULL, 0, NULL, NULL}
};
-#endif
#ifdef WITH_CYCLES
static EnumPropertyItem compute_device_items[] = {
@@ -3106,7 +3327,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
prop = RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dpi");
- RNA_def_property_range(prop, 48, 128);
+ RNA_def_property_range(prop, 48, 144);
RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
@@ -3275,7 +3496,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "wmdrawmethod");
RNA_def_property_enum_items(prop, draw_method_items);
RNA_def_property_ui_text(prop, "Window Draw Method", "Drawing method used by the window manager");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
+ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
prop = RNA_def_property(srna, "audio_mixing_buffer", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mixbufsize");
@@ -3329,6 +3550,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_enum_items(prop, multi_sample_levels);
RNA_def_property_ui_text(prop, "MultiSample", "Enable OpenGL multi-sampling, only for systems that support it, requires restart");
+ prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP);
+ RNA_def_property_ui_text(prop, "Region Overlap",
+ "Draw tool/property regions over the main region, when using Triple Buffer");
+ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
+
#ifdef WITH_CYCLES
prop = RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
@@ -3534,6 +3761,11 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 32);
RNA_def_property_ui_text(prop, "Wheel Scroll Lines", "Number of lines scrolled at a time with the mouse wheel");
+ prop = RNA_def_property(srna, "use_trackpad_natural", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_TRACKPAD_NATURAL);
+ RNA_def_property_ui_text(prop, "Trackpad Natural",
+ "If your system uses 'natural' scrolling, this option keeps consistent trackpad usage throughout the UI");
+
prop = RNA_def_property(srna, "active_keyconfig", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "keyconfigstr");
RNA_def_property_ui_text(prop, "Key Config", "The name of the active key configuration");
@@ -3664,6 +3896,11 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
"The time (in minutes) to wait between automatic temporary saves");
RNA_def_property_update(prop, 0, "rna_userdef_autosave_update");
+ prop = RNA_def_property(srna, "use_keep_session", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_KEEP_SESSION);
+ RNA_def_property_ui_text(prop, "Keep Session",
+ "Always load session recovery and save it after quitting Blender");
+
prop = RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 30);
RNA_def_property_ui_text(prop, "Recent Files", "Maximum number of recently opened files to remember");
@@ -3785,6 +4022,7 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_filepaths(brna);
rna_def_userdef_system(brna);
rna_def_userdef_addon(brna);
+ rna_def_userdef_addon_pref(brna);
}
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index f83410e7cc1..0c1c5d8f64a 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -416,6 +416,7 @@ EnumPropertyItem wm_report_items[] = {
{RPT_DEBUG, "DEBUG", 0, "Debug", ""},
{RPT_INFO, "INFO", 0, "Info", ""},
{RPT_OPERATOR, "OPERATOR", 0, "Operator", ""},
+ {RPT_PROPERTY, "PROPERTY", 0, "Property", ""},
{RPT_WARNING, "WARNING", 0, "Warning", ""},
{RPT_ERROR, "ERROR", 0, "Error", ""},
{RPT_ERROR_INVALID_INPUT, "ERROR_INVALID_INPUT", 0, "Invalid Input", ""},
@@ -852,8 +853,11 @@ static void rna_Operator_unregister(struct Main *bmain, StructRNA *type)
/* update while blender is running */
wm = bmain->wm.first;
- if (wm)
+ if (wm) {
WM_operator_stack_clear(wm);
+
+ WM_operator_handlers_clear(wm, ot);
+ }
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
RNA_struct_free_extension(type, &ot->ext);
@@ -1137,7 +1141,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
* for now just remove from dir(bpy.types) */
/* create a new operator type */
- dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */
dummyot.ext.data = data;
dummyot.ext.call = call;
@@ -1218,7 +1222,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
* for now just remove from dir(bpy.types) */
/* create a new operator type */
- dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
dummyot.ext.data = data;
dummyot.ext.call = call;
dummyot.ext.free = free;
@@ -1329,9 +1333,6 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
RNA_def_struct_name_property(srna, prop);
- /* operator's label indeed doesn't need PROP_TRANSLATE flag: translation of label happens in runtime
- * when drawing panel and having this flag set will make runtime switching of language much more tricky
- * because label will be stored translated */
prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->name");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
@@ -1339,7 +1340,7 @@ static void rna_def_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set");
@@ -1396,9 +1397,6 @@ static void rna_def_macro_operator(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
RNA_def_struct_name_property(srna, prop);
- /* menu's label indeed doesn't need PROP_TRANSLATE flag: translation of label happens in runtime
- * when drawing panel and having this flag set will make runtime switching of language much more tricky
- * because label will be stored translated */
prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->name");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
@@ -1406,7 +1404,7 @@ static void rna_def_macro_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set");
@@ -1617,6 +1615,26 @@ static void rna_def_window(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_Window_screen_update");
+
+ prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "posx");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "X Position", "Vertical location of the window");
+
+ prop = RNA_def_property(srna, "y", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "posy");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Y Position", "Horizontal location of the window");
+
+ prop = RNA_def_property(srna, "width", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "sizex");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Width", "Window width");
+
+ prop = RNA_def_property(srna, "height", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "sizey");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Height", "Window height");
}
/* curve.splines */
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index a84b1124d44..02a04d36c23 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -494,18 +494,6 @@ void RNA_def_world(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
-#if 0
- static EnumPropertyItem physics_engine_items[] = {
- {WOPHY_NONE, "NONE", 0, "None", ""},
- /*{WOPHY_ENJI, "ENJI", 0, "Enji", ""}, */
- /*{WOPHY_SUMO, "SUMO", 0, "Sumo (Deprecated)", ""}, */
- /*{WOPHY_DYNAMO, "DYNAMO", 0, "Dynamo", ""}, */
- /*{WOPHY_ODE, "ODE", 0, "ODE", ""}, */
- {WOPHY_BULLET, "BULLET", 0, "Bullet", ""},
- {0, NULL, 0, NULL, NULL}
- };
-#endif
-
srna = RNA_def_struct(brna, "World", "ID");
RNA_def_struct_ui_text(srna, "World",
"World datablock describing the environment and ambient lighting of a scene");
@@ -529,7 +517,7 @@ void RNA_def_world(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "zenr");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Zenith Color", "Color at the zenith");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "ambient_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "ambr");
@@ -554,17 +542,17 @@ void RNA_def_world(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_sky_blend", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYBLEND);
RNA_def_property_ui_text(prop, "Blend Sky", "Render background with natural progression from horizon to zenith");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "use_sky_paper", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYPAPER);
RNA_def_property_ui_text(prop, "Paper Sky", "Flatten blend or texture coordinates");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "use_sky_real", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYREAL);
RNA_def_property_ui_text(prop, "Real Sky", "Render background with a real horizon, relative to the camera angle");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
/* nested structs */
prop = RNA_def_property(srna, "light_settings", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index cf3bb05849a..9f1361b4909 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -28,7 +28,6 @@ set(INC
.
intern
../blenkernel
- ../blenkernel/intern
../blenlib
../blenfont
../blenloader
@@ -64,9 +63,13 @@ set(SRC
intern/MOD_fluidsim.c
intern/MOD_fluidsim_util.c
intern/MOD_hook.c
- intern/MOD_lattice.c
intern/MOD_laplaciansmooth.c
+ intern/MOD_lattice.c
intern/MOD_mask.c
+ intern/MOD_meshcache.c
+ intern/MOD_meshcache_mdd.c
+ intern/MOD_meshcache_pc2.c
+ intern/MOD_meshcache_util.c
intern/MOD_meshdeform.c
intern/MOD_mirror.c
intern/MOD_multires.c
@@ -86,7 +89,9 @@ set(SRC
intern/MOD_solidify.c
intern/MOD_subsurf.c
intern/MOD_surface.c
+ intern/MOD_triangulate.c
intern/MOD_util.c
+ intern/MOD_uvwarp.c
intern/MOD_uvproject.c
intern/MOD_warp.c
intern/MOD_wave.c
@@ -94,11 +99,11 @@ set(SRC
intern/MOD_weightvgedit.c
intern/MOD_weightvgmix.c
intern/MOD_weightvgproximity.c
- intern/MOD_triangulate.c
MOD_modifiertypes.h
intern/MOD_boolean_util.h
intern/MOD_fluidsim_util.h
+ intern/MOD_meshcache_util.h
intern/MOD_util.h
intern/MOD_weightvg_util.h
)
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 290ba193567..bac75b3f30f 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -77,6 +77,8 @@ extern ModifierTypeInfo modifierType_Remesh;
extern ModifierTypeInfo modifierType_Skin;
extern ModifierTypeInfo modifierType_LaplacianSmooth;
extern ModifierTypeInfo modifierType_Triangulate;
+extern ModifierTypeInfo modifierType_UVWarp;
+extern ModifierTypeInfo modifierType_MeshCache;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript
index 62fd9ba2de1..679109079c2 100644
--- a/source/blender/modifiers/SConscript
+++ b/source/blender/modifiers/SConscript
@@ -1,15 +1,54 @@
-#!/usr/bin/python
-Import ('env')
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
-sources = env.Glob('intern/*.c')
+Import('env')
-incs = '. ./intern'
-incs += ' #/intern/guardedalloc #/intern/bsp/extern #/intern/elbeem/extern #/extern/glew/include #/intern/opennl/extern'
-incs += ' ../render/extern/include ../blenloader ../bmesh'
-incs += ' ../include ../blenlib ../blenfont ../makesdna ../makesrna ../blenkernel ../blenkernel/intern'
-incs += ' ../gpu'
+sources = env.Glob('intern/*.c')
-incs += ' ' + env['BF_ZLIB_INC']
+incs = [
+ '.',
+ './intern',
+ '#/intern/guardedalloc',
+ '#/intern/bsp/extern',
+ '#/intern/elbeem/extern',
+ '#/extern/glew/include',
+ '#/intern/opennl/extern',
+ '../render/extern/include',
+ '../blenloader',
+ '../bmesh',
+ '../include',
+ '../blenlib',
+ '../blenfont',
+ '../makesdna',
+ '../makesrna',
+ '../blenkernel',
+ '../gpu',
+ env['BF_ZLIB_INC'],
+ ]
defs = []
@@ -17,7 +56,7 @@ if env ['WITH_BF_BOOLEAN']:
defs.append('WITH_MOD_BOOLEAN')
if env['WITH_BF_REMESH']:
- incs += ' #/intern/dualcon'
+ incs.append('#/intern/dualcon')
defs.append('WITH_MOD_REMESH')
if env['WITH_BF_FLUID']:
@@ -27,12 +66,12 @@ if env['WITH_BF_OCEANSIM']:
defs.append('WITH_OCEANSIM')
if env['WITH_BF_GAMEENGINE']:
- incs += ' #/extern/recastnavigation'
+ incs.append('#/extern/recastnavigation')
defs.append('WITH_GAMEENGINE')
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
-env.BlenderLib ( libname = 'bf_modifiers', sources = sources,
- includes = Split(incs), defines=defs,
- libtype=['core','player'], priority = [80, 40] )
+env.BlenderLib(libname='bf_modifiers', sources=sources,
+ includes=incs, defines=defs,
+ libtype=['core', 'player'], priority=[80, 40])
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 59befe4db05..1942fe12a54 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -31,19 +31,22 @@
/** \file blender/modifiers/intern/MOD_bevel.c
* \ingroup modifiers
*/
+
+#include "DNA_object_types.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_deform.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_bmesh.h" /* only for defines */
-#include "bmesh.h"
+#include "MOD_util.h"
-#include "DNA_object_types.h"
+#include "bmesh.h"
#include "MEM_guardedalloc.h"
@@ -88,21 +91,12 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-// #define USE_BM_BEVEL_OP_AS_MOD
-
#ifdef USE_BM_BEVEL_OP_AS_MOD
-/* BMESH_TODO
- *
- * this bevel calls the new bevel code (added since 2.64)
- * which is missing many of the options which the bevel modifier from 2.4x has.
- * - no vertex bevel
- * - no weight bevel
- *
- * These will need to be added to the bmesh operator.
- * - campbell
+/*
+ * This calls the new bevel code (added since 2.64)
*/
-static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
+static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
@@ -110,13 +104,33 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
BMesh *bm;
BMIter iter;
BMEdge *e;
+ BMVert *v;
+ float weight;
+ int vgroup = -1;
+ MDeformVert *dvert = NULL;
BevelModifierData *bmd = (BevelModifierData *) md;
const float threshold = cosf((bmd->bevel_angle + 0.00001f) * (float)M_PI / 180.0f);
- const int segments = 16; /* XXX */
+ const bool vertex_only = bmd->flags & BME_BEVEL_VERT;
bm = DM_to_bmesh(dm);
- if (bmd->lim_flags & BME_BEVEL_ANGLE) {
+ if (vertex_only) {
+ if ((bmd->lim_flags & BME_BEVEL_VGROUP) && bmd->defgrp_name[0]) {
+ modifier_get_vgroup(ob, dm, bmd->defgrp_name, &dvert, &vgroup);
+ }
+ BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_vert_is_manifold(v))
+ continue;
+ if (vgroup != -1) {
+ /* Is it safe to assume bmesh indices and dvert array line up?? */
+ weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup);
+ if (weight <= 0.0f)
+ continue;
+ }
+ BM_elem_flag_enable(v, BM_ELEM_TAG);
+ }
+ }
+ else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
/* check for 1 edge having 2 face users */
BMLoop *l_a, *l_b;
@@ -133,6 +147,11 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
/* crummy, is there a way just to operator on all? - campbell */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_edge_is_manifold(e)) {
+ if (bmd->lim_flags & BME_BEVEL_WEIGHT) {
+ weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT);
+ if (weight == 0.0f)
+ continue;
+ }
BM_elem_flag_enable(e, BM_ELEM_TAG);
BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
@@ -140,11 +159,14 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
}
}
- BM_mesh_bevel(bm, bmd->value, segments);
+ BM_mesh_bevel(bm, bmd->value, bmd->res,
+ vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, dvert, vgroup);
result = CDDM_from_bmesh(bm, TRUE);
- BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */
+ BLI_assert(bm->vtoolflagpool == NULL &&
+ bm->etoolflagpool == NULL &&
+ bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */
BM_mesh_free(bm);
CDDM_calc_normals(result);
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 0a48003fc81..04198d9feb9 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -135,7 +135,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
* in some cases the depsgraph fails us - especially for objects
* in other scenes when compositing */
if (bmd->object != ob) {
- dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_MESH);
+ /* weak! - but we can too easy end up with circular dep crash otherwise */
+ if (modifiers_findByType(bmd->object, eModifierType_Boolean) == NULL) {
+ dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_MESH);
+ }
+ else {
+ dm = bmd->object->derivedFinal;
+ }
}
else {
dm = NULL;
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c
index 2ff93532d14..a3d93b5437e 100644
--- a/source/blender/modifiers/intern/MOD_boolean_util.c
+++ b/source/blender/modifiers/intern/MOD_boolean_util.c
@@ -46,6 +46,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
+#include "BKE_global.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
@@ -295,7 +296,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base)
basen->flag &= ~SELECT;
/* Initialize the mesh data associated with this object. */
- ob_new->data = BKE_mesh_add("Mesh");
+ ob_new->data = BKE_mesh_add(G.main, "Mesh");
/* Finally assign the object type. */
ob_new->type = OB_MESH;
@@ -305,7 +306,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base)
static void InterpCSGFace(
DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr,
- float mapmat[][4])
+ float mapmat[4][4])
{
float obco[3], *co[4], *orig_co[4], w[4][4];
MFace *mface, *orig_mface;
@@ -344,8 +345,8 @@ static void InterpCSGFace(
static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
CSG_FaceIteratorDescriptor *face_it,
CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4],
- float mapmat[][4],
+ float parinv[4][4],
+ float mapmat[4][4],
Material **mat,
int *totmat,
DerivedMesh *dm1,
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index 2105a6efd21..c5a756733f5 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -37,6 +37,7 @@
#include "BLI_utildefines.h"
#include "BLI_rand.h"
+#include "BLI_math_vector.h"
#include "BLI_ghash.h"
#include "DNA_scene_types.h"
@@ -104,12 +105,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
MVert *mvert_src = dm->getVertArray(dm);
- vertMap = MEM_callocN(sizeof(*vertMap) * numVert_src, "build modifier vertMap");
- for (i = 0; i < numVert_src; i++) vertMap[i] = i;
- edgeMap = MEM_callocN(sizeof(*edgeMap) * numEdge_src, "build modifier edgeMap");
- for (i = 0; i < numEdge_src; i++) edgeMap[i] = i;
- faceMap = MEM_callocN(sizeof(*faceMap) * numPoly_src, "build modifier faceMap");
- for (i = 0; i < numPoly_src; i++) faceMap[i] = i;
+ vertMap = MEM_mallocN(sizeof(*vertMap) * numVert_src, "build modifier vertMap");
+ edgeMap = MEM_mallocN(sizeof(*edgeMap) * numEdge_src, "build modifier edgeMap");
+ faceMap = MEM_mallocN(sizeof(*faceMap) * numPoly_src, "build modifier faceMap");
+
+#pragma omp parallel sections if (numVert_src + numEdge_src + numPoly_src >= DM_OMP_LIMIT)
+ {
+#pragma omp section
+ { range_vn_i(vertMap, numVert_src, 0); }
+#pragma omp section
+ { range_vn_i(edgeMap, numEdge_src, 0); }
+#pragma omp section
+ { range_vn_i(faceMap, numPoly_src, 0); }
+ }
frac = (BKE_scene_frame_get(md->scene) - bmd->start) / bmd->length;
CLAMP(frac, 0.0f, 1.0f);
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index b9384e6208e..ab141312932 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -137,7 +137,7 @@ static void deformVerts(ModifierData *md, Object *ob,
numverts = dm->getNumVerts(dm);
- if ((current_time > collmd->time_xnew) || (BKE_ptcache_get_continue_physics())) {
+ if (current_time > collmd->time_xnew) {
unsigned int i;
/* check if mesh has changed */
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 28cdfa810fa..2d3d5c97af7 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -63,7 +63,7 @@ static void initData(ModifierData *md)
DecimateModifierData *dmd = (DecimateModifierData *) md;
dmd->percent = 1.0;
- dmd->angle = DEG2RADF(15.0f);
+ dmd->angle = DEG2RADF(5.0f);
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -188,7 +188,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* update for display only */
dmd->face_count = bm->totface;
result = CDDM_from_bmesh(bm, FALSE);
- BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */
+ BLI_assert(bm->vtoolflagpool == NULL); /* make sure we never alloc'd this */
+ BLI_assert(bm->etoolflagpool == NULL);
+ BLI_assert(bm->ftoolflagpool == NULL);
BM_mesh_free(bm);
#ifdef USE_TIMEIT
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index ec81c5ce699..33601c197b9 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -30,33 +30,24 @@
/** \file blender/modifiers/intern/MOD_edgesplit.c
* \ingroup modifiers
+ *
+ * EdgeSplit modifier
+ *
+ * Splits edges in the mesh according to sharpness flag
+ * or edge angle (can be used to achieve autosmoothing)
*/
-
-/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
- * or edge angle (can be used to achieve autosmoothing) */
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "MEM_guardedalloc.h"
-
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
-#include "BKE_mesh.h"
#include "bmesh.h"
+#include "tools/bmesh_edgesplit.h"
#include "DNA_object_types.h"
-/* EdgeSplit */
-/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
- * or edge angle (can be used to achieve autosmoothing)
- *
- * note: this code is very close to MOD_bevel.c
- */
-
-#define EDGE_MARK 1
static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob))
{
@@ -67,7 +58,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f);
bm = DM_to_bmesh(dm);
- BM_mesh_elem_toolflags_ensure(bm);
if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
@@ -81,7 +71,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
/* 2 face edge - check angle*/
(dot_v3v3(l1->f->no, l2->f->no) < threshold))
{
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
}
}
}
@@ -94,14 +84,13 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
(e->l->next != e->l))
{
if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
}
}
}
}
- BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
- "split_edges edges=%fe", EDGE_MARK);
+ BM_mesh_edgesplit(bm, FALSE, TRUE);
/* BM_mesh_validate(bm); */ /* for troubleshooting */
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index 1298d281de8..638f8f0ae01 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -161,7 +161,7 @@ static void createFacepa(ExplodeModifierData *emd,
mul_v3_fl(center, 0.25);
}
else
- mul_v3_fl(center, 0.3333f);
+ mul_v3_fl(center, 1.0f / 3.0f);
p = BLI_kdtree_find_nearest(tree, center, NULL, NULL);
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index 13d409dc941..b39ddf62c55 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -301,7 +301,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_exam
}
-void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
+void fluid_get_bb(MVert *mvert, int totvert, float obmat[4][4],
/*RET*/ float start[3], /*RET*/ float size[3])
{
float bbsx = 0.0, bbsy = 0.0, bbsz = 0.0;
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 266226040a3..62da82a2af1 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -82,6 +82,7 @@ typedef struct BLaplacianSystem LaplacianSystem;
static CustomDataMask required_data_mask(Object *UNUSED(ob), ModifierData *md);
static int is_disabled(ModifierData *md, int UNUSED(useRenderParams));
+static float average_area_quad_v3(float *v1, float *v2, float *v3, float *v4);
static float compute_volume(float (*vertexCos)[3], MFace *mfaces, int numFaces);
static float cotan_weight(float *v1, float *v2, float *v3);
static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts);
@@ -93,7 +94,7 @@ static void init_data(ModifierData *md);
static void init_laplacian_matrix(LaplacianSystem *sys);
static void memset_laplacian_system(LaplacianSystem *sys, int val);
static void volume_preservation(LaplacianSystem *sys, float vini, float vend, short flag);
-static void validate_solution(LaplacianSystem *sys, short flag);
+static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border);
static void delete_void_pointer(void *data)
{
@@ -196,10 +197,10 @@ static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, in
static void init_data(ModifierData *md)
{
LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *) md;
- smd->lambda = 0.00001f;
- smd->lambda_border = 0.00005f;
+ smd->lambda = 0.01f;
+ smd->lambda_border = 0.01f;
smd->repeat = 1;
- smd->flag = MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z | MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME;
+ smd->flag = MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z | MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME | MOD_LAPLACIANSMOOTH_NORMALIZED;
smd->defgrp_name[0] = '\0';
}
@@ -239,6 +240,13 @@ static CustomDataMask required_data_mask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
+static float average_area_quad_v3(float *v1, float *v2, float *v3, float *v4)
+{
+ float areaq = 0.0f;
+ areaq = area_tri_v3(v1, v2, v3) + area_tri_v3(v1, v2, v4) + area_tri_v3(v1, v3, v4);
+ return areaq / 2.0f;
+}
+
static float cotan_weight(float *v1, float *v2, float *v3)
{
float a[3], b[3], c[3], clen;
@@ -372,10 +380,17 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
if (has_4_vert) sys->zerola[idv4] = 1;
}
- sys->ring_areas[idv1] += areaf;
- sys->ring_areas[idv2] += areaf;
- sys->ring_areas[idv3] += areaf;
- if (has_4_vert) sys->ring_areas[idv4] += areaf;
+ if (has_4_vert) {
+ sys->ring_areas[idv1] += average_area_quad_v3(v1, v2, v3, v4);
+ sys->ring_areas[idv2] += average_area_quad_v3(v2, v3, v4, v1);
+ sys->ring_areas[idv3] += average_area_quad_v3(v3, v4, v1, v2);
+ sys->ring_areas[idv4] += average_area_quad_v3(v4, v1, v2, v3);
+ }
+ else {
+ sys->ring_areas[idv1] += areaf;
+ sys->ring_areas[idv2] += areaf;
+ sys->ring_areas[idv3] += areaf;
+ }
if (has_4_vert) {
@@ -403,9 +418,9 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
}
}
else {
- w1 = cotan_weight(v1, v2, v3);
- w2 = cotan_weight(v2, v3, v1);
- w3 = cotan_weight(v3, v1, v2);
+ w1 = cotan_weight(v1, v2, v3) / 2.0f;
+ w2 = cotan_weight(v2, v3, v1) / 2.0f;
+ w3 = cotan_weight(v3, v1, v2) / 2.0f;
sys->fweights[i][0] = sys->fweights[i][0] + w1;
sys->fweights[i][1] = sys->fweights[i][1] + w2;
@@ -505,43 +520,26 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
}
}
-static void validate_solution(LaplacianSystem *sys, short flag)
+static void validate_solution(LaplacianSystem * sys, short flag, float lambda, float lambda_border)
{
- int i, idv1, idv2;
- float leni, lene;
+ int i;
+ float lam;
float vini, vend;
- float *vi1, *vi2, ve1[3], ve2[3];
+
if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
vini = compute_volume(sys->vertexCos, sys->mfaces, sys->numFaces);
}
- for (i = 0; i < sys->numEdges; i++) {
- idv1 = sys->medges[i].v1;
- idv2 = sys->medges[i].v2;
- vi1 = sys->vertexCos[idv1];
- vi2 = sys->vertexCos[idv2];
- ve1[0] = nlGetVariable(0, idv1);
- ve1[1] = nlGetVariable(1, idv1);
- ve1[2] = nlGetVariable(2, idv1);
- ve2[0] = nlGetVariable(0, idv2);
- ve2[1] = nlGetVariable(1, idv2);
- ve2[2] = nlGetVariable(2, idv2);
- leni = len_v3v3(vi1, vi2);
- lene = len_v3v3(ve1, ve2);
- if (lene > leni * MOD_LAPLACIANSMOOTH_MAX_EDGE_PERCENTAGE || lene < leni * MOD_LAPLACIANSMOOTH_MIN_EDGE_PERCENTAGE) {
- sys->zerola[idv1] = 1;
- sys->zerola[idv2] = 1;
- }
- }
for (i = 0; i < sys->numVerts; i++) {
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] = nlGetVariable(0, i);
+ sys->vertexCos[i][0] += lam * (nlGetVariable(0, i) - sys->vertexCos[i][0]);
}
if (flag & MOD_LAPLACIANSMOOTH_Y) {
- sys->vertexCos[i][1] = nlGetVariable(1, i);
+ sys->vertexCos[i][1] += lam * (nlGetVariable(1, i) - sys->vertexCos[i][1]);
}
if (flag & MOD_LAPLACIANSMOOTH_Z) {
- sys->vertexCos[i][2] = nlGetVariable(2, i);
+ sys->vertexCos[i][2] += lam * (nlGetVariable(2, i) - sys->vertexCos[i][2]);
}
}
}
@@ -578,17 +576,17 @@ static void laplaciansmoothModifier_do(
sys->vert_centroid[0] = 0.0f;
sys->vert_centroid[1] = 0.0f;
sys->vert_centroid[2] = 0.0f;
- for (iter = 0; iter < smd->repeat; iter++) {
- memset_laplacian_system(sys, 0);
- nlNewContext();
- sys->context = nlGetCurrent();
- nlSolverParameteri(NL_NB_VARIABLES, numVerts);
- nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
- nlSolverParameteri(NL_NB_ROWS, numVerts);
- nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3);
+ memset_laplacian_system(sys, 0);
+ nlNewContext();
+ sys->context = nlGetCurrent();
+ nlSolverParameteri(NL_NB_VARIABLES, numVerts);
+ nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
+ nlSolverParameteri(NL_NB_ROWS, numVerts);
+ nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3);
- init_laplacian_matrix(sys);
+ init_laplacian_matrix(sys);
+ for (iter = 0; iter < smd->repeat; iter++) {
nlBegin(NL_SYSTEM);
for (i = 0; i < numVerts; i++) {
nlSetVariable(0, i, vertexCos[i][0]);
@@ -605,46 +603,64 @@ static void laplaciansmoothModifier_do(
nlBegin(NL_MATRIX);
dv = dvert;
for (i = 0; i < numVerts; i++) {
- nlRightHandSideAdd(0, i, vertexCos[i][0]);
- nlRightHandSideAdd(1, i, vertexCos[i][1]);
- nlRightHandSideAdd(2, i, vertexCos[i][2]);
- if (dv) {
- wpaint = defvert_find_weight(dv, defgrp_index);
- dv++;
- }
- else {
- wpaint = 1.0f;
- }
-
- if (sys->zerola[i] == 0) {
- w = sys->vweights[i] * sys->ring_areas[i];
- sys->vweights[i] = (w == 0.0f) ? 0.0f : -smd->lambda * wpaint / (4.0f * w);
- w = sys->vlengths[i];
- sys->vlengths[i] = (w == 0.0f) ? 0.0f : -smd->lambda_border * wpaint * 2.0f / w;
+ nlRightHandSideSet(0, i, vertexCos[i][0]);
+ nlRightHandSideSet(1, i, vertexCos[i][1]);
+ nlRightHandSideSet(2, i, vertexCos[i][2]);
+ if (iter == 0) {
+ if (dv) {
+ wpaint = defvert_find_weight(dv, defgrp_index);
+ dv++;
+ }
+ else {
+ wpaint = 1.0f;
+ }
- if (sys->numNeEd[i] == sys->numNeFa[i]) {
- nlMatrixAdd(i, i, 1.0f + smd->lambda * wpaint / (4.0f * sys->ring_areas[i]));
+ if (sys->zerola[i] == 0) {
+ if (smd->flag & MOD_LAPLACIANSMOOTH_NORMALIZED) {
+ w = sys->vweights[i];
+ sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / w;
+ w = sys->vlengths[i];
+ sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
+ if (sys->numNeEd[i] == sys->numNeFa[i]) {
+ nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda) * wpaint);
+ }
+ else {
+ nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
+ }
+ }
+ else {
+ w = sys->vweights[i] * sys->ring_areas[i];
+ sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / (4.0f * w);
+ w = sys->vlengths[i];
+ sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
+
+ if (sys->numNeEd[i] == sys->numNeFa[i]) {
+ nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda) * wpaint / (4.0f * sys->ring_areas[i]));
+ }
+ else {
+ nlMatrixAdd(i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
+ }
+ }
}
else {
- nlMatrixAdd(i, i, 1.0f + smd->lambda_border * wpaint * 2.0f);
+ nlMatrixAdd(i, i, 1.0f);
}
}
- else {
- nlMatrixAdd(i, i, 1.0f);
- }
}
- fill_laplacian_matrix(sys);
+ if (iter == 0) {
+ fill_laplacian_matrix(sys);
+ }
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
if (nlSolveAdvanced(NULL, NL_TRUE)) {
- validate_solution(sys, smd->flag);
+ validate_solution(sys, smd->flag, smd->lambda, smd->lambda_border);
}
- nlDeleteContext(sys->context);
- sys->context = NULL;
}
+ nlDeleteContext(sys->context);
+ sys->context = NULL;
delete_laplacian_system(sys);
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
new file mode 100644
index 00000000000..5e702a4eabc
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -0,0 +1,344 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/modifiers/intern/MOD_meshcache.c
+ * \ingroup modifiers
+ */
+
+#include <stdio.h>
+
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
+#include "BLI_math.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_scene.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+#include "BKE_main.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "MOD_meshcache_util.h" /* utility functions */
+
+#include "MOD_modifiertypes.h"
+
+#include "MOD_util.h"
+
+static void initData(ModifierData *md)
+{
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+
+ mcmd->flag = 0;
+ mcmd->type = MOD_MESHCACHE_TYPE_MDD;
+ mcmd->interp = MOD_MESHCACHE_INTERP_LINEAR;
+ mcmd->frame_scale = 1.0f;
+
+ mcmd->factor = 1.0f;
+
+ /* (Y, Z). Blender default */
+ mcmd->forward_axis = 1;
+ mcmd->up_axis = 2;
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+ MeshCacheModifierData *tmcmd = (MeshCacheModifierData *)target;
+
+ tmcmd->flag = mcmd->flag;
+ tmcmd->type = mcmd->type;
+
+ tmcmd->time_mode = mcmd->time_mode;
+ tmcmd->play_mode = mcmd->play_mode;
+
+ tmcmd->forward_axis = mcmd->forward_axis;
+ tmcmd->up_axis = mcmd->up_axis;
+ tmcmd->flip_axis = mcmd->flip_axis;
+
+ tmcmd->interp = mcmd->interp;
+
+ tmcmd->frame_start = mcmd->frame_start;
+ tmcmd->frame_scale = mcmd->frame_scale;
+
+ tmcmd->factor = mcmd->factor;
+ tmcmd->deform_mode = mcmd->deform_mode;
+
+ tmcmd->eval_frame = mcmd->eval_frame;
+ tmcmd->eval_time = mcmd->eval_time;
+ tmcmd->eval_factor = mcmd->eval_factor;
+
+ BLI_strncpy(tmcmd->filepath, mcmd->filepath, sizeof(tmcmd->filepath));
+}
+
+static int dependsOnTime(ModifierData *md)
+{
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+ return (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA);
+}
+
+static int isDisabled(ModifierData *md, int UNUSED(useRenderParams))
+{
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *) md;
+
+ /* leave it up to the modifier to check the file is valid on calculation */
+ return (mcmd->factor <= 0.0f) || (mcmd->filepath[0] == '\0');
+}
+
+
+static void meshcache_do(
+ MeshCacheModifierData *mcmd, Object *ob, DerivedMesh *UNUSED(dm),
+ float (*vertexCos_Real)[3], int numVerts)
+{
+ const bool use_factor = mcmd->factor < 1.0f;
+ float (*vertexCos_Store)[3] = (use_factor || (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ?
+ MEM_mallocN(sizeof(*vertexCos_Store) * numVerts, __func__) : NULL;
+ float (*vertexCos)[3] = vertexCos_Store ? vertexCos_Store : vertexCos_Real;
+
+ Scene *scene = mcmd->modifier.scene;
+ const float fps = FPS;
+
+ char filepath[FILE_MAX];
+ const char *err_str = NULL;
+ bool ok;
+
+ float time;
+
+
+ /* -------------------------------------------------------------------- */
+ /* Interpret Time (the reading functions also do some of this ) */
+ if (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA) {
+ const float cfra = BKE_scene_frame_get(scene);
+
+ switch (mcmd->time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME:
+ {
+ time = cfra;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS:
+ {
+ time = cfra / fps;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default:
+ {
+ time = cfra / fps;
+ break;
+ }
+ }
+
+ /* apply offset and scale */
+ time = (mcmd->frame_scale * time) - mcmd->frame_start;
+ }
+ else { /* if (mcmd->play_mode == MOD_MESHCACHE_PLAY_EVAL) { */
+ switch (mcmd->time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME:
+ {
+ time = mcmd->eval_frame;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS:
+ {
+ time = mcmd->eval_time;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default:
+ {
+ time = mcmd->eval_factor;
+ break;
+ }
+ }
+ }
+
+
+ /* -------------------------------------------------------------------- */
+ /* Read the File (or error out when the file is bad) */
+
+ /* would be nice if we could avoid doing this _every_ frame */
+ BLI_strncpy(filepath, mcmd->filepath, sizeof(filepath));
+ BLI_path_abs(filepath, ID_BLEND_PATH(G.main, (ID *)ob));
+
+ switch (mcmd->type) {
+ case MOD_MESHCACHE_TYPE_MDD:
+ ok = MOD_meshcache_read_mdd_times(filepath, vertexCos, numVerts,
+ mcmd->interp, time, fps, mcmd->time_mode, &err_str);
+ break;
+ case MOD_MESHCACHE_TYPE_PC2:
+ ok = MOD_meshcache_read_pc2_times(filepath, vertexCos, numVerts,
+ mcmd->interp, time, fps, mcmd->time_mode, &err_str);
+ break;
+ default:
+ ok = false;
+ break;
+ }
+
+
+ /* -------------------------------------------------------------------- */
+ /* tricky shape key integration (slow!) */
+ if (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE) {
+ Mesh *me = ob->data;
+
+ /* we could support any object type */
+ if (UNLIKELY(ob->type != OB_MESH)) {
+ modifier_setError(&mcmd->modifier, "'Integrate' only valid for Mesh objects");
+ }
+ else if (UNLIKELY(me->totvert != numVerts)) {
+ modifier_setError(&mcmd->modifier, "'Integrate' original mesh vertex mismatch");
+ }
+ else if (UNLIKELY(me->totpoly == 0)) {
+ modifier_setError(&mcmd->modifier, "'Integrate' requires faces");
+ }
+ else {
+ /* the moons align! */
+ int i;
+
+ float (*vertexCos_Source)[3] = MEM_mallocN(sizeof(*vertexCos_Source) * numVerts, __func__);
+ float (*vertexCos_New)[3] = MEM_mallocN(sizeof(*vertexCos_New) * numVerts, __func__);
+ MVert *mv = me->mvert;
+
+ for (i = 0; i < numVerts; i++, mv++) {
+ copy_v3_v3(vertexCos_Source[i], mv->co);
+ }
+
+ BKE_mesh_calc_relative_deform(
+ me->mpoly, me->totpoly,
+ me->mloop, me->totvert,
+
+ (const float (*)[3])vertexCos_Source, /* from the original Mesh*/
+ (const float (*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */
+
+ (const float (*)[3])vertexCos, /* the result of this modifier */
+ vertexCos_New /* the result of this function */
+ );
+
+ /* write the corrected locations back into the result */
+ memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * numVerts);
+
+ MEM_freeN(vertexCos_Source);
+ MEM_freeN(vertexCos_New);
+ }
+ }
+
+
+ /* -------------------------------------------------------------------- */
+ /* Apply the transformation matrix (if needed) */
+ if (UNLIKELY(err_str)) {
+ modifier_setError(&mcmd->modifier, err_str);
+ }
+ else if (ok) {
+ bool use_matrix = false;
+ float mat[3][3];
+ unit_m3(mat);
+
+ if (mat3_from_axis_conversion(mcmd->forward_axis, mcmd->up_axis, 1, 2, mat)) {
+ use_matrix = true;
+ }
+
+ if (mcmd->flip_axis) {
+ float tmat[3][3];
+ unit_m3(tmat);
+ if (mcmd->flip_axis & (1 << 0)) tmat[0][0] = -1.0f;
+ if (mcmd->flip_axis & (1 << 1)) tmat[1][1] = -1.0f;
+ if (mcmd->flip_axis & (1 << 2)) tmat[2][2] = -1.0f;
+ mul_m3_m3m3(mat, tmat, mat);
+
+ use_matrix = true;
+ }
+
+ if (use_matrix) {
+ int i;
+ for (i = 0; i < numVerts; i++) {
+ mul_m3_v3(mat, vertexCos[i]);
+ }
+ }
+ }
+
+ if (vertexCos_Store) {
+ if (ok) {
+ if (use_factor) {
+ interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3);
+ }
+ else {
+ memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * numVerts);
+ }
+ }
+
+ MEM_freeN(vertexCos_Store);
+ }
+}
+
+static void deformVerts(ModifierData *md, Object *ob,
+ DerivedMesh *derivedData,
+ float (*vertexCos)[3],
+ int numVerts,
+ ModifierApplyFlag UNUSED(flag))
+{
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+
+ meshcache_do(mcmd, ob, derivedData, vertexCos, numVerts);
+}
+
+static void deformVertsEM(
+ ModifierData *md, Object *ob, struct BMEditMesh *UNUSED(editData),
+ DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+
+ meshcache_do(mcmd, ob, derivedData, vertexCos, numVerts);
+}
+
+
+ModifierTypeInfo modifierType_MeshCache = {
+ /* name */ "Mesh Cache",
+ /* structName */ "MeshCacheModifierData",
+ /* structSize */ sizeof(MeshCacheModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+ /* applyModifierEM */ NULL,
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepgraph */ NULL,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
new file mode 100644
index 00000000000..e001855ba0b
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
@@ -0,0 +1,301 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton, pkowal
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/modifiers/intern/MOD_meshcache_mdd.c
+ * \ingroup modifiers
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "BLO_sys_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
+#include "BLI_fileops.h"
+#include "BLI_math.h"
+
+#include "MOD_meshcache_util.h" /* own include */
+
+#include "DNA_modifier_types.h"
+
+typedef struct MDDHead {
+ int frame_tot;
+ int verts_tot;
+} MDDHead; /* frames, verts */
+
+static bool meshcache_read_mdd_head(FILE *fp, const int verts_tot,
+ MDDHead *mdd_head,
+ const char **err_str)
+{
+ if (!fread(mdd_head, sizeof(*mdd_head), 1, fp)) {
+ *err_str = "Missing header";
+ return false;
+ }
+
+#ifdef __LITTLE_ENDIAN__
+ BLI_endian_switch_int32_array((int *)mdd_head, 2);
+#endif
+
+ if (mdd_head->verts_tot != verts_tot) {
+ *err_str = "Vertex count mismatch";
+ return false;
+ }
+
+ if (mdd_head->frame_tot <= 0) {
+ *err_str = "Invalid frame total";
+ return false;
+ }
+ /* intentionally dont seek back */
+
+ return true;
+}
+
+/**
+ * Gets the index frange and factor
+ */
+static bool meshcache_read_mdd_range(FILE *fp,
+ const int verts_tot,
+ const float frame, const char interp,
+ int r_index_range[2], float *r_factor,
+ const char **err_str)
+{
+ MDDHead mdd_head;
+
+ /* first check interpolation and get the vert locations */
+
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ return false;
+ }
+
+ MOD_meshcache_calc_range(frame, interp, mdd_head.frame_tot, r_index_range, r_factor);
+
+ return true;
+}
+
+static bool meshcache_read_mdd_range_from_time(FILE *fp,
+ const int verts_tot,
+ const float time, const float UNUSED(fps),
+ float *r_frame,
+ const char **err_str)
+{
+ MDDHead mdd_head;
+ int i;
+ float f_time, f_time_prev = FLT_MAX;
+ float frame;
+
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ return false;
+ }
+
+ for (i = 0; i < mdd_head.frame_tot; i++) {
+ fread(&f_time, sizeof(float), 1, fp);
+#ifdef __LITTLE_ENDIAN__
+ BLI_endian_switch_float(&f_time);
+#endif
+ if (f_time >= time) {
+ break;
+ }
+ f_time_prev = f_time;
+ }
+
+ if (i == mdd_head.frame_tot) {
+ frame = (float)(mdd_head.frame_tot - 1);
+ }
+ if (UNLIKELY(f_time_prev == FLT_MAX)) {
+ frame = 0.0f;
+ }
+ else {
+ const float range = f_time - f_time_prev;
+
+ if (range <= FRAME_SNAP_EPS) {
+ frame = (float)i;
+ }
+ else {
+ frame = (float)(i - 1) + ((time - f_time_prev) / range);
+ }
+ }
+
+ *r_frame = frame;
+ return true;
+}
+
+bool MOD_meshcache_read_mdd_index(FILE *fp,
+ float (*vertexCos)[3], const int verts_tot,
+ const int index, const float factor,
+ const char **err_str)
+{
+ MDDHead mdd_head;
+
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ return false;
+ }
+
+ if (fseek(fp, mdd_head.frame_tot * sizeof(int), SEEK_CUR) != 0) {
+ *err_str = "Header seek failed";
+ return false;
+ }
+
+ if (fseek(fp, index * mdd_head.verts_tot * sizeof(float) * 3, SEEK_CUR) != 0) {
+ *err_str = "Failed to seek frame";
+ return false;
+ }
+
+ if (factor >= 1.0f) {
+#if 1
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = mdd_head.verts_tot; i != 0 ; i--, vco += 3) {
+ fread(vco, sizeof(float) * 3, 1, fp);
+
+# ifdef __LITTLE_ENDIAN__
+ BLI_endian_switch_float(vco + 0);
+ BLI_endian_switch_float(vco + 1);
+ BLI_endian_switch_float(vco + 2);
+# endif /* __LITTLE_ENDIAN__ */
+ }
+#else
+ /* no blending */
+ if (!fread(vertexCos, sizeof(float) * 3, mdd_head.verts_tot, f)) {
+ *err_str = errno ? strerror(errno) : "Failed to read frame";
+ return false;
+ }
+# ifdef __LITTLE_ENDIAN__
+ BLI_endian_switch_float_array(vertexCos[0], mdd_head.verts_tot * 3);
+# endif
+#endif
+ }
+ else {
+ const float ifactor = 1.0f - factor;
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = mdd_head.verts_tot; i != 0 ; i--, vco += 3) {
+ float tvec[3];
+ fread(tvec, sizeof(float) * 3, 1, fp);
+
+#ifdef __LITTLE_ENDIAN__
+ BLI_endian_switch_float(tvec + 0);
+ BLI_endian_switch_float(tvec + 1);
+ BLI_endian_switch_float(tvec + 2);
+#endif
+
+ vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
+ vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);
+ vco[2] = (vco[2] * ifactor) + (tvec[2] * factor);
+ }
+ }
+
+ return true;
+}
+
+bool MOD_meshcache_read_mdd_frame(FILE *fp,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float frame,
+ const char **err_str)
+{
+ int index_range[2];
+ float factor;
+
+ if (meshcache_read_mdd_range(fp, verts_tot, frame, interp,
+ index_range, &factor, /* read into these values */
+ err_str) == false)
+ {
+ return false;
+ }
+
+ if (index_range[0] == index_range[1]) {
+ /* read single */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str))
+ {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ /* read both and interpolate */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
+ (fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str))
+ {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
+
+bool MOD_meshcache_read_mdd_times(const char *filepath,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float time, const float fps, const char time_mode,
+ const char **err_str)
+{
+ float frame;
+
+ FILE *fp = BLI_fopen(filepath, "rb");
+ bool ok;
+
+ if (fp == NULL) {
+ *err_str = errno ? strerror(errno) : "Unknown error opening file";
+ return false;
+ }
+
+ switch (time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME:
+ {
+ frame = time;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS:
+ {
+ /* we need to find the closest time */
+ if (meshcache_read_mdd_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+ rewind(fp);
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default:
+ {
+ MDDHead mdd_head;
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+
+ frame = CLAMPIS(time, 0.0f, 1.0f) * (float)mdd_head.frame_tot;
+ rewind(fp);
+ break;
+ }
+ }
+
+ ok = MOD_meshcache_read_mdd_frame(fp, vertexCos, verts_tot, interp, frame, err_str);
+
+ fclose(fp);
+ return ok;
+}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
new file mode 100644
index 00000000000..1ecb347d174
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -0,0 +1,277 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/modifiers/intern/MOD_meshcache_pc2.c
+ * \ingroup modifiers
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "BLO_sys_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
+#include "BLI_fileops.h"
+#include "BLI_math.h"
+
+#include "MOD_meshcache_util.h" /* own include */
+
+#include "DNA_modifier_types.h"
+
+typedef struct PC2Head {
+ char header[12]; /* 'POINTCACHE2\0' */
+ int file_version; /* unused - should be 1 */
+ int verts_tot;
+ float start;
+ float sampling;
+ int frame_tot;
+} PC2Head; /* frames, verts */
+
+static bool meshcache_read_pc2_head(FILE *fp, const int verts_tot,
+ PC2Head *pc2_head,
+ const char **err_str)
+{
+ if (!fread(pc2_head, sizeof(*pc2_head), 1, fp)) {
+ *err_str = "Missing header";
+ return false;
+ }
+
+ if (strcmp(pc2_head->header, "POINTCACHE2") != 0) {
+ *err_str = "Invalid header";
+ return false;
+ }
+
+#ifdef __BIG_ENDIAN__
+ BLI_endian_switch_int32_array(&pc2_head->huh, (sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
+#endif
+
+ if (pc2_head->verts_tot != verts_tot) {
+ *err_str = "Vertex count mismatch";
+ return false;
+ }
+
+ if (pc2_head->frame_tot <= 0) {
+ *err_str = "Invalid frame total";
+ return false;
+ }
+ /* intentionally dont seek back */
+
+ return true;
+}
+
+
+/**
+ * Gets the index frange and factor
+ *
+ * currently same as for MDD
+ */
+static bool meshcache_read_pc2_range(FILE *fp,
+ const int verts_tot,
+ const float frame, const char interp,
+ int r_index_range[2], float *r_factor,
+ const char **err_str)
+{
+ PC2Head pc2_head;
+
+ /* first check interpolation and get the vert locations */
+
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ return false;
+ }
+
+ MOD_meshcache_calc_range(frame, interp, pc2_head.frame_tot, r_index_range, r_factor);
+
+ return true;
+}
+
+static bool meshcache_read_pc2_range_from_time(FILE *fp,
+ const int verts_tot,
+ const float time, const float fps,
+ float *r_frame,
+ const char **err_str)
+{
+ PC2Head pc2_head;
+ float frame;
+
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ return false;
+ }
+
+ frame = ((time / fps) - pc2_head.start) / pc2_head.sampling;
+
+ if (frame >= pc2_head.frame_tot) {
+ frame = (float)(pc2_head.frame_tot - 1);
+ }
+ else if (frame < 0.0f) {
+ frame = 0.0f;
+ }
+
+ *r_frame = frame;
+ return true;
+}
+
+bool MOD_meshcache_read_pc2_index(FILE *fp,
+ float (*vertexCos)[3], const int verts_tot,
+ const int index, const float factor,
+ const char **err_str)
+{
+ PC2Head pc2_head;
+
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ return false;
+ }
+
+ if (fseek(fp, index * pc2_head.verts_tot * sizeof(float) * 3, SEEK_CUR) != 0) {
+ *err_str = "Failed to seek frame";
+ return false;
+ }
+
+ if (factor >= 1.0f) {
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = pc2_head.verts_tot; i != 0 ; i--, vco += 3) {
+ fread(vco, sizeof(float) * 3, 1, fp);
+
+# ifdef __BIG_ENDIAN__
+ BLI_endian_switch_float(vco + 0);
+ BLI_endian_switch_float(vco + 1);
+ BLI_endian_switch_float(vco + 2);
+# endif /* __BIG_ENDIAN__ */
+ }
+ }
+ else {
+ const float ifactor = 1.0f - factor;
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = pc2_head.verts_tot; i != 0 ; i--, vco += 3) {
+ float tvec[3];
+ fread(tvec, sizeof(float) * 3, 1, fp);
+
+#ifdef __BIG_ENDIAN__
+ BLI_endian_switch_float(tvec + 0);
+ BLI_endian_switch_float(tvec + 1);
+ BLI_endian_switch_float(tvec + 2);
+#endif /* __BIG_ENDIAN__ */
+
+ vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
+ vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);
+ vco[2] = (vco[2] * ifactor) + (tvec[2] * factor);
+ }
+ }
+
+ return true;
+}
+
+
+bool MOD_meshcache_read_pc2_frame(FILE *fp,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float frame,
+ const char **err_str)
+{
+ int index_range[2];
+ float factor;
+
+ if (meshcache_read_pc2_range(fp, verts_tot, frame, interp,
+ index_range, &factor, /* read into these values */
+ err_str) == false)
+ {
+ return false;
+ }
+
+ if (index_range[0] == index_range[1]) {
+ /* read single */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str))
+ {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ /* read both and interpolate */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
+ (fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str))
+ {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
+
+bool MOD_meshcache_read_pc2_times(const char *filepath,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float time, const float fps, const char time_mode,
+ const char **err_str)
+{
+ float frame;
+
+ FILE *fp = BLI_fopen(filepath, "rb");
+ bool ok;
+
+ if (fp == NULL) {
+ *err_str = errno ? strerror(errno) : "Unknown error opening file";
+ return false;
+ }
+
+ switch (time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME:
+ {
+ frame = time;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS:
+ {
+ /* we need to find the closest time */
+ if (meshcache_read_pc2_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+ rewind(fp);
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default:
+ {
+ PC2Head pc2_head;
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+
+ frame = CLAMPIS(time, 0.0f, 1.0f) * (float)pc2_head.frame_tot;
+ rewind(fp);
+ break;
+ }
+ }
+
+ ok = MOD_meshcache_read_pc2_frame(fp, vertexCos, verts_tot, interp, frame, err_str);
+
+ fclose(fp);
+ return ok;
+}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.c b/source/blender/modifiers/intern/MOD_meshcache_util.c
new file mode 100644
index 00000000000..679a79322c3
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.c
@@ -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.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "MOD_meshcache_util.h"
+
+void MOD_meshcache_calc_range(const float frame, const char interp,
+ const int frame_tot,
+ int r_index_range[2], float *r_factor)
+{
+ if (interp == MOD_MESHCACHE_INTERP_NONE) {
+ r_index_range[0] = r_index_range[1] = max_ii(0, min_ii(frame_tot - 1, (int)(floorf(frame) + 0.5f)));
+ *r_factor = 1.0f; /* dummy */
+ }
+ else {
+ const float tframe = floorf(frame);
+ const float range = frame - tframe;
+ r_index_range[0] = (int)tframe;
+ if (range <= FRAME_SNAP_EPS) {
+ /* we're close enough not to need blending */
+ r_index_range[1] = r_index_range[0];
+ *r_factor = 1.0f; /* dummy */
+ }
+ else {
+ /* blend between 2 frames */
+ r_index_range[1] = r_index_range[0] + 1;
+ *r_factor = range;
+ }
+
+ /* clamp */
+ if ((r_index_range[0] >= frame_tot) ||
+ (r_index_range[1] >= frame_tot))
+ {
+ r_index_range[0] = r_index_range[1] = frame_tot - 1;
+ *r_factor = 1.0f; /* dummy */
+ }
+ else if ((r_index_range[0] < 0) ||
+ (r_index_range[1] < 0))
+ {
+ r_index_range[0] = r_index_range[1] = 0;
+ *r_factor = 1.0f; /* dummy */
+ }
+ }
+}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.h b/source/blender/modifiers/intern/MOD_meshcache_util.h
new file mode 100644
index 00000000000..d7e71518f77
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.h
@@ -0,0 +1,67 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/modifiers/intern/MOD_meshcache_util.h
+ * \ingroup modifiers
+ */
+
+#ifndef __MOD_MESHCACHE_UTIL_H__
+
+struct MPoly;
+struct MLoop;
+
+/* MOD_meshcache_mdd.c */
+bool MOD_meshcache_read_mdd_index(FILE *fp,
+ float (*vertexCos)[3], const int vertex_tot,
+ const int index, const float factor,
+ const char **err_str);
+bool MOD_meshcache_read_mdd_frame(FILE *fp,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float frame,
+ const char **err_str);
+bool MOD_meshcache_read_mdd_times(const char *filepath,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float time, const float fps, const char time_mode,
+ const char **err_str);
+
+/* MOD_meshcache_pc2.c */
+bool MOD_meshcache_read_pc2_index(FILE *fp,
+ float (*vertexCos)[3], const int verts_tot,
+ const int index, const float factor,
+ const char **err_str);
+bool MOD_meshcache_read_pc2_frame(FILE *fp,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float frame,
+ const char **err_str);
+bool MOD_meshcache_read_pc2_times(const char *filepath,
+ float (*vertexCos)[3], const int verts_tot, const char interp,
+ const float time, const float fps, const char time_mode,
+ const char **err_str);
+
+/* MOD_meshcache_util.c */
+void MOD_meshcache_calc_range(const float frame, const char interp,
+ const int frame_tot,
+ int r_index_range[2], float *r_factor);
+
+#define FRAME_SNAP_EPS 0.0001f
+
+#endif /* __MOD_MESHCACHE_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 564fa696c2a..77250ec4025 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -1,4 +1,4 @@
-/**
+/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -25,6 +25,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
+/** \file blender/modifiers/intern/MOD_ocean.c
+ * \ingroup modifiers
+ */
+
#include "MEM_guardedalloc.h"
#include "DNA_customdata_types.h"
@@ -139,10 +143,10 @@ static void initData(ModifierData *md)
omd->ocean = BKE_add_ocean();
init_ocean_modifier(omd);
simulate_ocean_modifier(omd);
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* unused */
(void)md;
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
}
static void freeData(ModifierData *md)
@@ -153,10 +157,10 @@ static void freeData(ModifierData *md)
BKE_free_ocean(omd->ocean);
if (omd->oceancache)
BKE_free_ocean_cache(omd->oceancache);
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* unused */
(void)md;
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -201,11 +205,11 @@ static void copyData(ModifierData *md, ModifierData *target)
tomd->ocean = BKE_add_ocean();
init_ocean_modifier(tomd);
simulate_ocean_modifier(tomd);
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* unused */
(void)md;
(void)target;
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
}
#ifdef WITH_OCEANSIM
@@ -219,14 +223,14 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
{
/* unused */
(void)md;
return 0;
}
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
#if 0
static void dm_get_bounds(DerivedMesh *dm, float *sx, float *sy, float *ox, float *oy)
@@ -302,11 +306,7 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd)
mpolys = CDDM_get_polys(result);
mloops = CDDM_get_loops(result);
-#if 0 // trunk
- origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
-#else // bmesh
origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX);
-#endif
/* create vertices */
#pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
@@ -443,7 +443,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
cfra = md->scene->r.cfra;
CLAMP(cfra, omd->bakestart, omd->bakeend);
- cfra -= omd->bakestart; // shift to 0 based
+ cfra -= omd->bakestart; /* shift to 0 based */
num_verts = dm->getNumVerts(dm);
num_faces = dm->getNumPolys(dm);
@@ -490,7 +490,8 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
mlcol = &mloopcols[mp->loopstart + j];
mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255);
- /* mc->a = 255; */ /* no need to set */
+ /* This needs to be set (render engine uses) */
+ mlcol->a = 255;
} while (j--);
}
}
@@ -500,7 +501,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
/* displace the geometry */
- //#pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES)
+ /* #pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES) */
for (i = 0, mv = mverts; i < num_verts; i++, mv++) {
const float u = OCEAN_CO(size_co_inv, mv->co[0]);
const float v = OCEAN_CO(size_co_inv, mv->co[1]);
@@ -522,7 +523,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
return dm;
}
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
DerivedMesh *derivedData,
int UNUSED(useRenderParams))
@@ -531,7 +532,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
(void)md;
return derivedData;
}
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *derivedData,
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 93b5e36e5a4..e7d62452590 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -225,7 +225,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* angle */
-#if 0 // cant incluide this, not predictable enough, though quite fun,.
+#if 0 /* cant incluide this, not predictable enough, though quite fun. */
if (ltmd->flag & MOD_SCREW_OBJECT_ANGLE) {
float mtx3_tx[3][3];
copy_m3_m4(mtx3_tx, mtx_tx);
@@ -274,7 +274,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1);
/* will the screw be closed?
- * Note! smaller then FLT_EPSILON*100 gives problems with float precision so its never closed. */
+ * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */
if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) &&
fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f))
{
@@ -314,11 +314,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
CustomData_add_layer(&result->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, maxPolys);
}
-#if 0 // trunk
- origindex = result->getPolyDataArray(result, CD_ORIGINDEX);
-#else // bmesh
origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX);
-#endif
DM_copy_vert_data(dm, result, 0, 0, totvert); /* copy first otherwise this overwrites our own vertex normals */
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index 7fe8dc69790..697ccdc49a4 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -54,13 +54,16 @@ static void deformVerts(ModifierData *md, Object *ob,
int numVerts,
ModifierApplyFlag UNUSED(flag))
{
- KeyBlock *kb = BKE_keyblock_from_object(ob);
+ Key *key = BKE_key_from_object(ob);
float (*deformedVerts)[3];
- if (kb && kb->totelem == numVerts) {
- deformedVerts = (float(*)[3])do_ob_key(md->scene, ob);
+ if (key && key->block.first) {
+ int deformedVerts_tot;
+ deformedVerts = (float(*)[3])BKE_key_evaluate_object(md->scene, ob, &deformedVerts_tot);
if (deformedVerts) {
- memcpy(vertexCos, deformedVerts, sizeof(float) * 3 * numVerts);
+ if (numVerts == deformedVerts_tot) {
+ memcpy(vertexCos, deformedVerts, sizeof(float) * 3 * numVerts);
+ }
MEM_freeN(deformedVerts);
}
}
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index d3a03614d7c..7a55f9a5b48 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -161,6 +161,15 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
}
+static int dependsOnNormals(ModifierData *md)
+{
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+
+ if (smd->target && smd->shrinkType == MOD_SHRINKWRAP_PROJECT)
+ return (smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL);
+
+ return false;
+}
ModifierTypeInfo modifierType_Shrinkwrap = {
/* name */ "Shrinkwrap",
@@ -185,7 +194,7 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
/* isDisabled */ isDisabled,
/* updateDepgraph */ updateDepgraph,
/* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
/* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index a73d52a0a63..81c53185825 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -1278,7 +1278,8 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
return;
/* Get split face's verts */
- BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4);
+ // BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4);
+ BM_face_as_array_vert_quad(split_face, verts);
skin_choose_quad_bridge_order(verts, frame->verts, best_order);
/* Delete split face and merge */
@@ -1314,16 +1315,21 @@ static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame)
}
-static void quad_from_tris(BMesh *bm, BMEdge *e, BMFace *adj[2], BMVert *ndx[4])
+static void quad_from_tris(BMEdge *e, BMFace *adj[2], BMVert *ndx[4])
{
BMVert *tri[2][3];
BMVert *opp = NULL;
int i, j;
BLI_assert(adj[0]->len == 3 && adj[1]->len == 3);
-
+
+#if 0
BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[0], (void **)tri[0], 3);
BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[1], (void **)tri[1], 3);
+#else
+ BM_face_as_array_vert_tri(adj[0], tri[0]);
+ BM_face_as_array_vert_tri(adj[1], tri[1]);
+#endif
/* Find what the second tri has that the first doesn't */
for (i = 0; i < 3; i++) {
@@ -1354,7 +1360,7 @@ static void add_quad_from_tris(SkinOutput *so, BMEdge *e, BMFace *adj[2])
{
BMVert *quad[4];
- quad_from_tris(so->bm, e, adj, quad);
+ quad_from_tris(e, adj, quad);
add_poly(so, quad[0], quad[1], quad[2], quad[3]);
}
@@ -1381,7 +1387,7 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd)
/* Construct quad using the two triangles adjacent to
* the edge */
- quad_from_tris(so->bm, e, adj, quad);
+ quad_from_tris(e, adj, quad);
/* Calculate a score for the quad, higher score for
* triangles being closer to coplanar */
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 75e54d77b15..038fb4913ec 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -185,6 +185,8 @@ static void copyData(ModifierData *md, ModifierData *target)
tsmd->crease_outer = smd->crease_outer;
tsmd->crease_rim = smd->crease_rim;
tsmd->flag = smd->flag;
+ tsmd->mat_ofs = smd->mat_ofs;
+ tsmd->mat_ofs_rim = smd->mat_ofs_rim;
BLI_strncpy(tsmd->defgrp_name, smd->defgrp_name, sizeof(tsmd->defgrp_name));
}
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index e97f4191e6f..c0d46b14aa8 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -47,7 +47,7 @@
#include "MOD_modifiertypes.h"
-#include "CCGSubSurf.h"
+#include "intern/CCGSubSurf.h"
static void initData(ModifierData *md)
{
@@ -103,7 +103,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
subsurf_flags |= SUBSURF_USE_RENDER_PARAMS;
if (isFinalCalc)
subsurf_flags |= SUBSURF_IS_FINAL_CALC;
- if (ob->flag & OB_MODE_EDIT)
+ if (ob->mode & OB_MODE_EDIT)
subsurf_flags |= SUBSURF_IN_EDIT_MODE;
result = subsurf_make_derived_from_derived(derivedData, smd, NULL, subsurf_flags);
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index 645fd5eb2cf..1c22e9bf364 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -33,8 +33,6 @@
#include "BKE_modifier.h"
#include "BKE_tessmesh.h"
-/* triangulation modifier, directly calls the bmesh operator */
-
static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag)
{
DerivedMesh *result;
@@ -44,13 +42,7 @@ static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag)
bm = DM_to_bmesh(dm);
- BM_mesh_elem_toolflags_ensure(bm);
- BMO_push(bm, NULL);
-
- BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
- "triangulate faces=%af use_beauty=%b",
- (flag & MOD_TRIANGULATE_BEAUTY));
- BMO_pop(bm);
+ BM_mesh_triangulate(bm, (flag & MOD_TRIANGULATE_BEAUTY), false, NULL, NULL);
result = CDDM_from_bmesh(bm, FALSE);
BM_mesh_free(bm);
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index a27d5e5e03b..1084023fcf0 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -74,7 +74,7 @@ void get_texture_value(Tex *texture, float *tex_co, TexResult *texres)
int result_type;
/* no node textures for now */
- result_type = multitex_ext_safe(texture, tex_co, texres);
+ result_type = multitex_ext_safe(texture, tex_co, texres, NULL);
/* 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.
@@ -279,5 +279,7 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(Skin);
INIT_TYPE(LaplacianSmooth);
INIT_TYPE(Triangulate);
+ INIT_TYPE(UVWarp);
+ INIT_TYPE(MeshCache);
#undef INIT_TYPE
}
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
new file mode 100644
index 00000000000..249c3c89d5f
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -0,0 +1,268 @@
+/*
+ * ***** 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): Pawel Kowal, Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_uvwarp.c
+ * \ingroup modifiers
+ */
+
+#include <string.h>
+
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_action.h" /* BKE_pose_channel_find_name */
+#include "BKE_cdderivedmesh.h"
+#include "BKE_deform.h"
+#include "BKE_modifier.h"
+
+#include "depsgraph_private.h"
+
+#include "MOD_util.h"
+
+
+static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4],
+ int axis_u, int axis_v)
+{
+ float tuv[3] = {0.0f};
+
+ tuv[axis_u] = uv_src[0];
+ tuv[axis_v] = uv_src[1];
+
+ mul_m4_v3(warp_mat, tuv);
+
+ uv_dst[0] = tuv[axis_u];
+ uv_dst[1] = tuv[axis_v];
+}
+
+static void initData(ModifierData *md)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+ umd->axis_u = 0;
+ umd->axis_v = 1;
+ copy_v2_fl(umd->center, 0.5f);
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
+ UVWarpModifierData *tumd = (UVWarpModifierData *)target;
+
+ tumd->axis_u = umd->axis_u;
+ tumd->axis_v = umd->axis_v;
+ copy_v2_v2(tumd->center, umd->center);
+ tumd->object_src = umd->object_src;
+ BLI_strncpy(tumd->bone_src, umd->bone_src, sizeof(tumd->bone_src));
+ tumd->object_dst = umd->object_dst;
+ BLI_strncpy(tumd->bone_dst, umd->bone_dst, sizeof(tumd->bone_dst));
+ BLI_strncpy(tumd->vgroup_name, umd->vgroup_name, sizeof(tumd->vgroup_name));
+ BLI_strncpy(tumd->uvlayer_name, umd->uvlayer_name, sizeof(umd->uvlayer_name));
+}
+
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
+ CustomDataMask dataMask = 0;
+
+ /* ask for vertexgroups if we need them */
+ if (umd->vgroup_name[0])
+ dataMask |= CD_MASK_MDEFORMVERT;
+
+ return dataMask;
+}
+
+static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonename)
+{
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename);
+ if (pchan) {
+ mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
+ }
+ else {
+ copy_m4_m4(mat, ob->obmat);
+ }
+}
+
+#define OMP_LIMIT 1000
+static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
+ DerivedMesh *dm,
+ ModifierApplyFlag UNUSED(flag))
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+ int i, numPolys, numLoops;
+ MPoly *mpoly;
+ MLoop *mloop;
+ MLoopUV *mloopuv;
+ MDeformVert *dvert;
+ int defgrp_index;
+ char uvname[MAX_CUSTOMDATA_LAYER_NAME];
+ float mat_src[4][4];
+ float mat_dst[4][4];
+ float imat_dst[4][4];
+ float warp_mat[4][4];
+ const int axis_u = umd->axis_u;
+ const int axis_v = umd->axis_v;
+
+ /* make sure there are UV Maps available */
+ if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
+ return dm;
+ }
+ else if (ELEM(NULL, umd->object_src, umd->object_dst)) {
+ modifier_setError(md, "From/To objects must be set");
+ return dm;
+ }
+
+ /* make sure anything moving UVs is available */
+ matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src);
+ matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst);
+
+ invert_m4_m4(imat_dst, mat_dst);
+ mult_m4_m4m4(warp_mat, imat_dst, mat_src);
+
+ /* apply warp */
+ if (!is_zero_v2(umd->center)) {
+ float mat_cent[4][4];
+ float imat_cent[4][4];
+
+ unit_m4(mat_cent);
+ mat_cent[3][axis_u] = umd->center[0];
+ mat_cent[3][axis_v] = umd->center[1];
+
+ invert_m4_m4(imat_cent, mat_cent);
+
+ mult_m4_m4m4(warp_mat, warp_mat, imat_cent);
+ mult_m4_m4m4(warp_mat, mat_cent, warp_mat);
+ }
+
+ /* make sure we're using an existing layer */
+ CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname);
+
+ numPolys = dm->getNumPolys(dm);
+ numLoops = dm->getNumLoops(dm);
+
+ mpoly = dm->getPolyArray(dm);
+ mloop = dm->getLoopArray(dm);
+ /* make sure we are not modifying the original UV map */
+ mloopuv = CustomData_duplicate_referenced_layer_named(&dm->loopData, CD_MLOOPUV, uvname, numLoops);
+ modifier_get_vgroup(ob, dm, umd->vgroup_name, &dvert, &defgrp_index);
+
+ if (dvert) {
+#pragma omp parallel for if (numPolys > OMP_LIMIT)
+ for (i = 0; i < numPolys; i++) {
+ float uv[2];
+ MPoly *mp = &mpoly[i];
+ MLoop *ml = &mloop[mp->loopstart];
+ MLoopUV *mluv = &mloopuv[mp->loopstart];
+ int l;
+ for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
+ const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index);
+ uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v);
+ interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight);
+ }
+ }
+ }
+ else {
+#pragma omp parallel for if (numPolys > OMP_LIMIT)
+ for (i = 0; i < numPolys; i++) {
+ MPoly *mp = &mpoly[i];
+ // MLoop *ml = &mloop[mp->loopstart];
+ MLoopUV *mluv = &mloopuv[mp->loopstart];
+ int l;
+ for (l = 0; l < mp->totloop; l++, /* ml++, */ mluv++) {
+ uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v);
+ }
+ }
+ }
+
+ dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
+
+ return dm;
+}
+
+static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
+ struct BMEditMesh *UNUSED(editData),
+ DerivedMesh *derivedData)
+{
+ return applyModifier(md, ob, derivedData, MOD_APPLY_USECACHE);
+}
+
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+
+ walk(userData, ob, &umd->object_dst);
+ walk(userData, ob, &umd->object_src);
+}
+
+static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode,
+ Object *obj, const char *bonename)
+{
+ if (obj) {
+ DagNode *curNode = dag_get_node(forest, obj);
+
+ if (bonename[0])
+ dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "UVWarp Modifier");
+ else
+ dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "UVWarp Modifier");
+ }
+}
+
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Scene *UNUSED(scene),
+ Object *UNUSED(ob),
+ DagNode *obNode)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+
+ uv_warp_deps_object_bone(forest, obNode, umd->object_src, umd->bone_src);
+ uv_warp_deps_object_bone(forest, obNode, umd->object_dst, umd->bone_dst);
+}
+
+ModifierTypeInfo modifierType_UVWarp = {
+ /* name */ "UVWarp",
+ /* structName */ "UVWarpModifierData",
+ /* structSize */ sizeof(UVWarpModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh |
+ eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+ /* copyData */ copyData,
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ applyModifierEM,
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepgraph */ updateDepgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 5883b176317..f025352795b 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -361,7 +361,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
/* Mix weights. */
for (i = 0; i < numIdx; i++) {
- float weight2 = 0.0;
+ float weight2;
org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a;
weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b;
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index e936e571a5b..71d6d4880ad 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -107,9 +107,9 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3],
/*nearest_v.dist = nearest_e.dist = nearest_f.dist = FLT_MAX;*/
/* Find the nearest vert/edge/face. */
#ifndef __APPLE__
-#pragma omp parallel for default(none) private(i) firstprivate(nearest_v,nearest_e,nearest_f) \
- shared(treeData_v,treeData_e,treeData_f,numVerts,v_cos,dist_v,dist_e, \
- dist_f,loc2trgt) \
+#pragma omp parallel for default(none) private(i) firstprivate(nearest_v, nearest_e, nearest_f) \
+ shared(treeData_v, treeData_e, treeData_f, numVerts, v_cos, dist_v, dist_e, \
+ dist_f, loc2trgt) \
schedule(static)
#endif
for (i = 0; i < numVerts; i++) {
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 141a3680df2..12842085189 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -123,6 +123,7 @@ set(SRC
composite/nodes/node_composite_pixelate.c
composite/node_composite_tree.c
+ composite/node_composite_util.h
shader/nodes/node_shader_camera.c
shader/nodes/node_shader_common.c
@@ -168,6 +169,7 @@ set(SRC
shader/nodes/node_shader_mix_shader.c
shader/nodes/node_shader_normal_map.c
shader/nodes/node_shader_object_info.c
+ shader/nodes/node_shader_hair_info.c
shader/nodes/node_shader_output_lamp.c
shader/nodes/node_shader_output_material.c
shader/nodes/node_shader_output_world.c
@@ -234,13 +236,6 @@ set(SRC
intern/node_common.h
)
-if(WITH_COMPOSITOR_LEGACY)
- list(APPEND SRC
- composite/node_composite_util.h
- composite/node_composite_util.c
- )
-endif()
-
if(WITH_PYTHON)
list(APPEND INC
../python
@@ -266,8 +261,4 @@ if(WITH_COMPOSITOR)
add_definitions(-DWITH_COMPOSITOR)
endif()
-if(WITH_COMPOSITOR_LEGACY)
- add_definitions(-DWITH_COMPOSITOR_LEGACY)
-endif()
-
blender_add_lib(bf_nodes "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 74135776c9c..0a7a11e4506 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -78,6 +78,7 @@ void register_node_type_sh_fresnel(struct bNodeTreeType *ttype);
void register_node_type_sh_layer_weight(struct bNodeTreeType *ttype);
void register_node_type_sh_tex_coord(struct bNodeTreeType *ttype);
void register_node_type_sh_particle_info(struct bNodeTreeType *ttype);
+void register_node_type_sh_hair_info(struct bNodeTreeType *ttype);
void register_node_type_sh_script(struct bNodeTreeType *ttype);
void register_node_type_sh_normal_map(struct bNodeTreeType *ttype);
void register_node_type_sh_tangent(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript
index ec4f00a199a..9f56689bf43 100644
--- a/source/blender/nodes/SConscript
+++ b/source/blender/nodes/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
@@ -40,9 +66,6 @@ if env['WITH_BF_COMPOSITOR']:
incs += ' ../compositor '
defs.append("WITH_COMPOSITOR")
-if env['WITH_BF_COMPOSITOR_LEGACY']:
- defs.append("WITH_COMPOSITOR_LEGACY")
-
env.BlenderLib ( libname = 'bf_nodes', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [190,105] )
env.BlenderLib ( libname = 'bf_cmpnodes', sources = cmpsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] )
env.BlenderLib ( libname = 'bf_shdnodes', sources = shdsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] )
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 03462738d58..a6592b47e87 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -51,7 +51,6 @@
#include "BKE_tracking.h"
#include "node_common.h"
-#include "node_exec.h"
#include "node_util.h"
#include "PIL_time.h"
@@ -95,9 +94,6 @@ static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
for (sock= node->outputs.first; sock; sock= sock->next) {
if (sock->cache) {
-#ifdef WITH_COMPOSITOR_LEGACY
- free_compbuf(sock->cache);
-#endif
sock->cache= NULL;
}
}
@@ -161,9 +157,6 @@ static void localize(bNodeTree *localtree, bNodeTree *ntree)
for (sock= node->outputs.first; sock; sock= sock->next) {
sock->new_sock->cache= sock->cache;
-#ifdef WITH_COMPOSITOR_LEGACY
- compbuf_set_node(sock->new_sock->cache, node->new_node);
-#endif
sock->cache= NULL;
sock->new_sock->new_sock= sock;
}
@@ -239,9 +232,6 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
for (lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
if (ntreeOutputExists(lnode->new_node, lsock->new_sock)) {
lsock->new_sock->cache= lsock->cache;
-#ifdef WITH_COMPOSITOR_LEGACY
- compbuf_set_node(lsock->new_sock->cache, lnode->new_node);
-#endif
lsock->cache= NULL;
lsock->new_sock= NULL;
}
@@ -277,421 +267,6 @@ bNodeTreeType ntreeType_Composite = {
};
-/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
- * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
- */
-struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree, int use_tree_data)
-{
- bNodeTreeExec *exec;
- bNode *node;
- bNodeSocket *sock;
-
- if (use_tree_data) {
- /* XXX hack: prevent exec data from being generated twice.
- * this should be handled by the renderer!
- */
- if (ntree->execdata)
- return ntree->execdata;
- }
-
- /* ensures only a single output node is enabled */
- ntreeSetOutput(ntree);
-
- exec = ntree_exec_begin(ntree);
-
- for (node= exec->nodetree->nodes.first; node; node= node->next) {
- /* initialize needed for groups */
- node->exec= 0;
-
- for (sock= node->outputs.first; sock; sock= sock->next) {
- bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
- if (ns && sock->cache) {
- ns->data= sock->cache;
- sock->cache= NULL;
- }
- }
- /* cannot initialize them while using in threads */
- if (ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) {
- curvemapping_initialize(node->storage);
- if (node->type==CMP_NODE_CURVE_RGB)
- curvemapping_premultiply(node->storage, 0);
- }
- }
-
- if (use_tree_data) {
- /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
- * which only store the ntree pointer. Should be fixed at some point!
- */
- ntree->execdata = exec;
- }
-
- return exec;
-}
-
-/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
- * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
- */
-void ntreeCompositEndExecTree(bNodeTreeExec *exec, int use_tree_data)
-{
- if (exec) {
- bNodeTree *ntree= exec->nodetree;
- bNode *node;
- bNodeStack *ns;
-
- for (node= exec->nodetree->nodes.first; node; node= node->next) {
- bNodeSocket *sock;
-
- for (sock= node->outputs.first; sock; sock= sock->next) {
- ns = node_get_socket_stack(exec->stack, sock);
- if (ns && ns->data) {
- sock->cache= ns->data;
- ns->data= NULL;
- }
- }
- if (node->type==CMP_NODE_CURVE_RGB)
- curvemapping_premultiply(node->storage, 1);
-
- node->need_exec= 0;
- }
-
- ntree_exec_end(exec);
-
- if (use_tree_data) {
- /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
- ntree->execdata = NULL;
- }
- }
-}
-
-#ifdef WITH_COMPOSITOR
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* ***************************** threaded version for execute composite nodes ************* */
-/* these are nodes without input, only giving values */
-/* or nodes with only value inputs */
-static int node_only_value(bNode *node)
-{
- bNodeSocket *sock;
-
- if (ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
- return 1;
-
- /* doing this for all node types goes wrong. memory free errors */
- if (node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
- int retval= 1;
- for (sock= node->inputs.first; sock; sock= sock->next) {
- if (sock->link)
- retval &= node_only_value(sock->link->fromnode);
- }
- return retval;
- }
- return 0;
-}
-
-/* not changing info, for thread callback */
-typedef struct ThreadData {
- bNodeStack *stack;
- RenderData *rd;
-} ThreadData;
-
-static void *exec_composite_node(void *nodeexec_v)
-{
- bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
- bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
- bNodeExec *nodeexec= nodeexec_v;
- bNode *node= nodeexec->node;
- ThreadData *thd= (ThreadData *)node->threaddata;
-
- node_get_stack(node, thd->stack, nsin, nsout);
-
- if (node->typeinfo->execfunc)
- node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
- else if (node->typeinfo->newexecfunc)
- node->typeinfo->newexecfunc(thd->rd, 0, node, nodeexec->data, nsin, nsout);
-
- node->exec |= NODE_READY;
- return NULL;
-}
-
-/* return total of executable nodes, for timecursor */
-static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd)
-{
- bNodeTree *ntree = exec->nodetree;
- bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
- bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
- bNodeExec *nodeexec;
- bNode *node;
- bNodeSocket *sock;
- int n, totnode= 0, group_edit= 0;
-
- /* if we are in group edit, viewer nodes get skipped when group has viewer */
- for (node= ntree->nodes.first; node; node= node->next)
- if (node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
- if (ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
- group_edit= 1;
-
- /* NB: using the exec data list here to have valid dependency sort */
- for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
- int a;
- node = nodeexec->node;
-
- node_get_stack(node, exec->stack, nsin, nsout);
-
- /* test the outputs */
- /* skip value-only nodes (should be in type!) */
- if (!node_only_value(node)) {
- for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
- if (nsout[a]->data==NULL && nsout[a]->hasoutput) {
- node->need_exec= 1;
- break;
- }
- }
- }
-
- /* test the inputs */
- for (a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
- /* skip viewer nodes in bg render or group edit */
- if ( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
- node->need_exec= 0;
- /* is sock in use? */
- else if (sock->link) {
- bNodeLink *link= sock->link;
-
- /* this is the test for a cyclic case */
- if (link->fromnode==NULL || link->tonode==NULL);
- else if (link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
- if (link->fromnode->need_exec) {
- node->need_exec= 1;
- break;
- }
- }
- else {
- node->need_exec= 0;
- printf("Node %s skipped, cyclic dependency\n", node->name);
- }
- }
- }
-
- if (node->need_exec) {
-
- /* free output buffers */
- for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
- if (nsout[a]->data) {
- free_compbuf(nsout[a]->data);
- nsout[a]->data= NULL;
- }
- }
- totnode++;
- /* printf("node needs exec %s\n", node->name); */
-
- /* tag for getExecutableNode() */
- node->exec= 0;
- }
- else {
- /* tag for getExecutableNode() */
- node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
-
- }
- }
-
- /* last step: set the stack values for only-value nodes */
- /* just does all now, compared to a full buffer exec this is nothing */
- if (totnode) {
- for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
- node = nodeexec->node;
- if (node->need_exec==0 && node_only_value(node)) {
- if (node->typeinfo->execfunc) {
- node_get_stack(node, exec->stack, nsin, nsout);
- node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
- }
- }
- }
- }
-
- return totnode;
-}
-
-/* while executing tree, free buffers from nodes that are not needed anymore */
-static void freeExecutableNode(bNodeTreeExec *exec)
-{
- /* node outputs can be freed when:
- * - not a render result or image node
- * - when node outputs go to nodes all being set NODE_FINISHED
- */
- bNodeTree *ntree = exec->nodetree;
- bNodeExec *nodeexec;
- bNode *node;
- bNodeSocket *sock;
- int n;
-
- /* set exec flag for finished nodes that might need freed */
- for (node= ntree->nodes.first; node; node= node->next) {
- if (node->type!=CMP_NODE_R_LAYERS)
- if (node->exec & NODE_FINISHED)
- node->exec |= NODE_FREEBUFS;
- }
- /* clear this flag for input links that are not done yet.
- * Using the exec data for valid dependency sort.
- */
- for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
- node = nodeexec->node;
- if ((node->exec & NODE_FINISHED)==0) {
- for (sock= node->inputs.first; sock; sock= sock->next)
- if (sock->link)
- sock->link->fromnode->exec &= ~NODE_FREEBUFS;
- }
- }
- /* now we can free buffers */
- for (node= ntree->nodes.first; node; node= node->next) {
- if (node->exec & NODE_FREEBUFS) {
- for (sock= node->outputs.first; sock; sock= sock->next) {
- bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
- if (ns && ns->data) {
- free_compbuf(ns->data);
- ns->data= NULL;
- // printf("freed buf node %s\n", node->name);
- }
- }
- }
- }
-}
-
-static bNodeExec *getExecutableNode(bNodeTreeExec *exec)
-{
- bNodeExec *nodeexec;
- bNodeSocket *sock;
- int n;
-
- for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
- if (nodeexec->node->exec==0) {
- /* input sockets should be ready */
- for (sock= nodeexec->node->inputs.first; sock; sock= sock->next) {
- if (sock->link && sock->link->fromnode)
- if ((sock->link->fromnode->exec & NODE_READY)==0)
- break;
- }
- if (sock==NULL)
- return nodeexec;
- }
- }
- return NULL;
-}
-
-/* check if texture nodes need exec or end */
-static void ntree_composite_texnode(bNodeTree *ntree, int init)
-{
- bNode *node;
-
- for (node= ntree->nodes.first; node; node= node->next) {
- if (node->type==CMP_NODE_TEXTURE && node->id) {
- Tex *tex= (Tex *)node->id;
- if (tex->nodetree && tex->use_nodes) {
- /* has internal flag to detect it only does it once */
- if (init) {
- if (!tex->nodetree->execdata)
- tex->nodetree->execdata = ntreeTexBeginExecTree(tex->nodetree, 1);
- }
- else
- ntreeTexEndExecTree(tex->nodetree->execdata, 1);
- tex->nodetree->execdata = NULL;
- }
- }
- }
-
-}
-
-/* optimized tree execute test for compositing */
-static void ntreeCompositExecTreeOld(bNodeTree *ntree, RenderData *rd, int do_preview)
-{
- bNodeExec *nodeexec;
- bNode *node;
- ListBase threads;
- ThreadData thdata;
- int totnode, curnode, rendering = TRUE, n;
- bNodeTreeExec *exec = ntree->execdata;
-
- if (do_preview)
- ntreeInitPreview(ntree, 0, 0);
-
- if (!ntree->execdata) {
- /* XXX this is the top-level tree, so we use the ntree->execdata pointer. */
- exec = ntreeCompositBeginExecTree(ntree, 1);
- }
- ntree_composite_texnode(ntree, 1);
-
- /* prevent unlucky accidents */
- if (G.background)
- rd->scemode &= ~R_COMP_CROP;
-
- /* setup callerdata for thread callback */
- thdata.rd= rd;
- thdata.stack= exec->stack;
-
- /* fixed seed, for example noise texture */
- BLI_srandom(rd->cfra);
-
- /* sets need_exec tags in nodes */
- curnode = totnode= setExecutableNodes(exec, &thdata);
-
- BLI_init_threads(&threads, exec_composite_node, rd->threads);
-
- while (rendering) {
-
- if (BLI_available_threads(&threads)) {
- nodeexec= getExecutableNode(exec);
- if (nodeexec) {
- node = nodeexec->node;
- if (ntree->progress && totnode)
- ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode));
- if (ntree->stats_draw) {
- char str[128];
- BLI_snprintf(str, sizeof(str), "Compositing %d %s", curnode, node->name);
- ntree->stats_draw(ntree->sdh, str);
- }
- curnode--;
-
- node->threaddata = &thdata;
- node->exec= NODE_PROCESSING;
- BLI_insert_thread(&threads, nodeexec);
- }
- else
- PIL_sleep_ms(50);
- }
- else
- PIL_sleep_ms(50);
-
- rendering= 0;
- /* test for ESC */
- if (ntree->test_break && ntree->test_break(ntree->tbh)) {
- for (node= ntree->nodes.first; node; node= node->next)
- node->exec |= NODE_READY;
- }
-
- /* check for ready ones, and if we need to continue */
- for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
- node = nodeexec->node;
- if (node->exec & NODE_READY) {
- if ((node->exec & NODE_FINISHED)==0) {
- BLI_remove_thread(&threads, nodeexec); /* this waits for running thread to finish btw */
- node->exec |= NODE_FINISHED;
-
- /* freeing unused buffers */
- if (rd->scemode & R_COMP_FREE)
- freeExecutableNode(exec);
- }
- }
- else rendering= 1;
- }
- }
-
- BLI_end_threads(&threads);
-
- /* XXX top-level tree uses the ntree->execdata pointer */
- ntreeCompositEndExecTree(exec, 1);
-}
-#endif /* WITH_COMPOSITOR_LEGACY */
-#endif /* WITH_COMPOSITOR */
-
void *COM_linker_hack = NULL;
void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int do_preview,
@@ -699,16 +274,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int
const ColorManagedDisplaySettings *display_settings)
{
#ifdef WITH_COMPOSITOR
-#ifdef WITH_COMPOSITOR_LEGACY
- if (G.debug_value == 200)
- {
- ntreeCompositExecTreeOld(ntree, rd, do_preview);
- }
- else
-#endif
- {
- COM_execute(rd, ntree, rendering, view_settings, display_settings);
- }
+ COM_execute(rd, ntree, rendering, view_settings, display_settings);
#else
(void)ntree, (void)rd, (void)rendering, (void)do_preview;
(void)view_settings, (void)display_settings;
diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c
deleted file mode 100644
index 57eb99021f6..00000000000
--- a/source/blender/nodes/composite/node_composite_util.c
+++ /dev/null
@@ -1,1412 +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) 2006 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/nodes/composite/node_composite_util.c
- * \ingroup nodes
- */
-
-#include "node_composite_util.h"
-
-#ifdef WITH_COMPOSITOR_LEGACY
-
-#include <limits.h>
-
-CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
-{
- CompBuf *cbuf= MEM_callocN(sizeof(CompBuf), "compbuf");
-
- cbuf->x= sizex;
- cbuf->y= sizey;
- cbuf->xrad= sizex/2;
- cbuf->yrad= sizey/2;
-
- cbuf->type= type;
- if (alloc) {
- if (cbuf->type==CB_RGBA)
- cbuf->rect= MEM_mapallocN(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect");
- else if (cbuf->type==CB_VEC3)
- cbuf->rect= MEM_mapallocN(3*sizeof(float)*sizex*sizey, "compbuf Vector3 rect");
- else if (cbuf->type==CB_VEC2)
- cbuf->rect= MEM_mapallocN(2*sizeof(float)*sizex*sizey, "compbuf Vector2 rect");
- else
- cbuf->rect= MEM_mapallocN(sizeof(float)*sizex*sizey, "compbuf Fac rect");
- cbuf->malloc= 1;
- }
- cbuf->disprect.xmin = 0;
- cbuf->disprect.ymin = 0;
- cbuf->disprect.xmax = sizex;
- cbuf->disprect.ymax = sizey;
-
- return cbuf;
-}
-
-CompBuf *dupalloc_compbuf(CompBuf *cbuf)
-{
- CompBuf *dupbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1);
- if (dupbuf) {
- memcpy(dupbuf->rect, cbuf->rect, cbuf->type*sizeof(float)*cbuf->x*cbuf->y);
-
- dupbuf->xof= cbuf->xof;
- dupbuf->yof= cbuf->yof;
- }
- return dupbuf;
-}
-
-/* instead of reference counting, we create a list */
-CompBuf *pass_on_compbuf(CompBuf *cbuf)
-{
- CompBuf *dupbuf= (cbuf)? alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 0): NULL;
- CompBuf *lastbuf;
-
- if (dupbuf) {
- dupbuf->rect= cbuf->rect;
- dupbuf->xof= cbuf->xof;
- dupbuf->yof= cbuf->yof;
- dupbuf->malloc= 0;
-
- /* get last buffer in list, and append dupbuf */
- for (lastbuf= cbuf; lastbuf; lastbuf= lastbuf->next)
- if (lastbuf->next==NULL)
- break;
- lastbuf->next= dupbuf;
- dupbuf->prev= lastbuf;
- }
- return dupbuf;
-}
-
-
-void free_compbuf(CompBuf *cbuf)
-{
- /* check referencing, then remove from list and set malloc tag */
- if (cbuf->prev || cbuf->next) {
- if (cbuf->prev)
- cbuf->prev->next= cbuf->next;
- if (cbuf->next)
- cbuf->next->prev= cbuf->prev;
- if (cbuf->malloc) {
- if (cbuf->prev)
- cbuf->prev->malloc= 1;
- else
- cbuf->next->malloc= 1;
- cbuf->malloc= 0;
- }
- }
-
- if (cbuf->malloc && cbuf->rect)
- MEM_freeN(cbuf->rect);
-
- MEM_freeN(cbuf);
-}
-
-void print_compbuf(char *str, CompBuf *cbuf)
-{
- printf("Compbuf %s %d %d %p\n", str, cbuf->x, cbuf->y, (void *)cbuf->rect);
-
-}
-
-void compbuf_set_node(CompBuf *cbuf, bNode *node)
-{
- if (cbuf) cbuf->node = node;
-}
-
-
-CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type)
-{
- CompBuf *cbuf;
- rcti disprect= *drect;
- float *outfp;
- int dx, y;
-
- if (disprect.xmax>rectx) disprect.xmax = rectx;
- if (disprect.ymax>recty) disprect.ymax = recty;
- if (disprect.xmin>= disprect.xmax) return NULL;
- if (disprect.ymin>= disprect.ymax) return NULL;
-
- cbuf= alloc_compbuf(BLI_rcti_size_x(&disprect), BLI_rcti_size_y(&disprect), type, 1);
- outfp= cbuf->rect;
- rectf += type*(disprect.ymin*rectx + disprect.xmin);
- dx= type*cbuf->x;
- for (y=cbuf->y; y>0; y--, outfp+=dx, rectf+=type*rectx)
- memcpy(outfp, rectf, sizeof(float)*dx);
-
- return cbuf;
-}
-
-CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy)
-{
- CompBuf *outbuf;
- float *rectf, *newrectf, *rf;
- int x, y, c, pixsize= inbuf->type;
- int ofsx, ofsy, stepx, stepy;
-
- if (inbuf->x==newx && inbuf->y==newy)
- return dupalloc_compbuf(inbuf);
-
- outbuf= alloc_compbuf(newx, newy, inbuf->type, 1);
- newrectf= outbuf->rect;
-
- stepx = (65536.0 * (inbuf->x - 1.0) / (newx - 1.0)) + 0.5;
- stepy = (65536.0 * (inbuf->y - 1.0) / (newy - 1.0)) + 0.5;
- ofsy = 32768;
-
- for (y = newy; y > 0 ; y--) {
- rectf = inbuf->rect;
- rectf += pixsize * (ofsy >> 16) * inbuf->x;
-
- ofsy += stepy;
- ofsx = 32768;
-
- for (x = newx ; x>0 ; x--) {
-
- rf= rectf + pixsize*(ofsx >> 16);
- for (c=0; c<pixsize; c++)
- newrectf[c] = rf[c];
-
- newrectf+= pixsize;
-
- ofsx += stepx;
- }
- }
-
- return outbuf;
-}
-
-void typecheck_compbuf_color(float *out, float *in, int outtype, int intype)
-{
- if (intype == outtype) {
- memcpy(out, in, sizeof(float)*outtype);
- }
- else if (outtype==CB_VAL) {
- if (intype==CB_VEC2) {
- *out= 0.5f*(in[0]+in[1]);
- }
- else if (intype==CB_VEC3) {
- *out= 0.333333f*(in[0]+in[1]+in[2]);
- }
- else if (intype==CB_RGBA) {
- *out = rgb_to_bw(in);
- }
- }
- else if (outtype==CB_VEC2) {
- if (intype==CB_VAL) {
- out[0] = in[0];
- out[1] = in[0];
- }
- else if (intype==CB_VEC3) {
- out[0] = in[0];
- out[1] = in[1];
- }
- else if (intype==CB_RGBA) {
- out[0] = in[0];
- out[1] = in[1];
- }
- }
- else if (outtype==CB_VEC3) {
- if (intype==CB_VAL) {
- out[0] = in[0];
- out[1] = in[0];
- out[2] = in[0];
- }
- else if (intype==CB_VEC2) {
- out[0] = in[0];
- out[1] = in[1];
- out[2] = 0.0f;
- }
- else if (intype==CB_RGBA) {
- out[0] = in[0];
- out[1] = in[1];
- out[2] = in[2];
- }
- }
- else if (outtype==CB_RGBA) {
- if (intype==CB_VAL) {
- out[0] = in[0];
- out[1] = in[0];
- out[2] = in[0];
- out[3] = 1.0f;
- }
- else if (intype==CB_VEC2) {
- out[0] = in[0];
- out[1] = in[1];
- out[2] = 0.0f;
- out[3] = 1.0f;
- }
- else if (intype==CB_VEC3) {
- out[0] = in[0];
- out[1] = in[1];
- out[2] = in[2];
- out[3] = 1.0f;
- }
- }
-}
-
-CompBuf *typecheck_compbuf(CompBuf *inbuf, int type)
-{
- if (inbuf && inbuf->type!=type) {
- CompBuf *outbuf;
- float *inrf, *outrf;
- int x;
-
- outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1);
-
- /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
- outbuf->xof= inbuf->xof;
- outbuf->yof= inbuf->yof;
-
- if (inbuf->rect_procedural) {
- outbuf->rect_procedural= inbuf->rect_procedural;
- copy_v3_v3(outbuf->procedural_size, inbuf->procedural_size);
- copy_v3_v3(outbuf->procedural_offset, inbuf->procedural_offset);
- outbuf->procedural_type= inbuf->procedural_type;
- outbuf->node= inbuf->node;
- return outbuf;
- }
-
- inrf= inbuf->rect;
- outrf= outbuf->rect;
- x= inbuf->x*inbuf->y;
-
- if (type==CB_VAL) {
- if (inbuf->type==CB_VEC2) {
- for (; x>0; x--, outrf+= 1, inrf+= 2)
- *outrf= 0.5f*(inrf[0]+inrf[1]);
- }
- else if (inbuf->type==CB_VEC3) {
- for (; x>0; x--, outrf+= 1, inrf+= 3)
- *outrf= 0.333333f*(inrf[0]+inrf[1]+inrf[2]);
- }
- else if (inbuf->type==CB_RGBA) {
- for (; x>0; x--, outrf+= 1, inrf+= 4)
- *outrf = rgb_to_bw(inrf);
- }
- }
- else if (type==CB_VEC2) {
- if (inbuf->type==CB_VAL) {
- for (; x>0; x--, outrf+= 2, inrf+= 1) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[0];
- }
- }
- else if (inbuf->type==CB_VEC3) {
- for (; x>0; x--, outrf+= 2, inrf+= 3) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[1];
- }
- }
- else if (inbuf->type==CB_RGBA) {
- for (; x>0; x--, outrf+= 2, inrf+= 4) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[1];
- }
- }
- }
- else if (type==CB_VEC3) {
- if (inbuf->type==CB_VAL) {
- for (; x>0; x--, outrf+= 3, inrf+= 1) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[0];
- outrf[2] = inrf[0];
- }
- }
- else if (inbuf->type==CB_VEC2) {
- for (; x>0; x--, outrf+= 3, inrf+= 2) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[1];
- outrf[2] = 0.0f;
- }
- }
- else if (inbuf->type==CB_RGBA) {
- for (; x>0; x--, outrf+= 3, inrf+= 4) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[1];
- outrf[2] = inrf[2];
- }
- }
- }
- else if (type==CB_RGBA) {
- if (inbuf->type==CB_VAL) {
- for (; x>0; x--, outrf+= 4, inrf+= 1) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[0];
- outrf[2] = inrf[0];
- outrf[3] = 1.0f;
- }
- }
- else if (inbuf->type==CB_VEC2) {
- for (; x>0; x--, outrf+= 4, inrf+= 2) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[1];
- outrf[2] = 0.0f;
- outrf[3] = 1.0f;
- }
- }
- else if (inbuf->type==CB_VEC3) {
- for (; x>0; x--, outrf+= 4, inrf+= 3) {
- outrf[0] = inrf[0];
- outrf[1] = inrf[1];
- outrf[2] = inrf[2];
- outrf[3] = 1.0f;
- }
- }
- }
-
- return outbuf;
- }
- return inbuf;
-}
-
-float *compbuf_get_pixel(CompBuf *cbuf, float *defcol, float *use, int x, int y, int xrad, int yrad)
-{
- if (cbuf) {
- if (cbuf->rect_procedural) {
- cbuf->rect_procedural(cbuf, use, (float)x/(float)xrad, (float)y/(float)yrad);
- return use;
- }
- else {
- static float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-
- /* map coords */
- x-= cbuf->xof;
- y-= cbuf->yof;
-
- if (y<-cbuf->yrad || y>= -cbuf->yrad+cbuf->y) return col;
- if (x<-cbuf->xrad || x>= -cbuf->xrad+cbuf->x) return col;
-
- return cbuf->rect + cbuf->type*( (cbuf->yrad+y)*cbuf->x + (cbuf->xrad+x) );
- }
- }
- else return defcol;
-}
-
-/* **************************************************** */
-
-static CompBuf *composit_check_compbuf(CompBuf *cbuf, int type, CompBuf *outbuf)
-{
- /* check type */
- CompBuf *dbuf= typecheck_compbuf(cbuf, type);
-
- /* if same as output and translated, duplicate so pixels don't interfere */
- if (dbuf == outbuf && !dbuf->rect_procedural && (dbuf->xof || dbuf->yof))
- dbuf= dupalloc_compbuf(dbuf);
-
- return dbuf;
-}
-
-/* Pixel-to-Pixel operation, 1 Image in, 1 out */
-void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col,
- void (*func)(bNode *, float *, float *),
- int src_type)
-{
- CompBuf *src_use;
- float *outfp=out->rect, *srcfp;
- float color[4]; /* local color if compbuf is procedural */
- int xrad, yrad, x, y;
-
- src_use= composit_check_compbuf(src_buf, src_type, out);
-
- xrad= out->xrad;
- yrad= out->yrad;
-
- for (y= -yrad; y<-yrad+out->y; y++) {
- for (x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) {
- srcfp= compbuf_get_pixel(src_use, src_col, color, x, y, xrad, yrad);
- func(node, outfp, srcfp);
- }
- }
-
- if (src_use!=src_buf)
- free_compbuf(src_use);
-}
-
-/* Pixel-to-Pixel operation, 2 Images in, 1 out */
-void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col,
- CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *),
- int src_type, int fac_type)
-{
- CompBuf *src_use, *fac_use;
- float *outfp=out->rect, *srcfp, *facfp;
- float color[4]; /* local color if compbuf is procedural */
- int xrad, yrad, x, y;
-
- src_use= composit_check_compbuf(src_buf, src_type, out);
- fac_use= composit_check_compbuf(fac_buf, fac_type, out);
-
- xrad= out->xrad;
- yrad= out->yrad;
-
- for (y= -yrad; y<-yrad+out->y; y++) {
- for (x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) {
- srcfp= compbuf_get_pixel(src_use, src_col, color, x, y, xrad, yrad);
- facfp= compbuf_get_pixel(fac_use, fac, color, x, y, xrad, yrad);
-
- func(node, outfp, srcfp, facfp);
- }
- }
- if (src_use!=src_buf)
- free_compbuf(src_use);
- if (fac_use!=fac_buf)
- free_compbuf(fac_use);
-}
-
-/* Pixel-to-Pixel operation, 3 Images in, 1 out */
-void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, float *src1_col, CompBuf *src2_buf, float *src2_col,
- CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *, float *),
- int src1_type, int src2_type, int fac_type)
-{
- CompBuf *src1_use, *src2_use, *fac_use;
- float *outfp=out->rect, *src1fp, *src2fp, *facfp;
- float color[4]; /* local color if compbuf is procedural */
- int xrad, yrad, x, y;
-
- src1_use= composit_check_compbuf(src1_buf, src1_type, out);
- src2_use= composit_check_compbuf(src2_buf, src2_type, out);
- fac_use= composit_check_compbuf(fac_buf, fac_type, out);
-
- xrad= out->xrad;
- yrad= out->yrad;
-
- for (y= -yrad; y<-yrad+out->y; y++) {
- for (x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) {
- src1fp= compbuf_get_pixel(src1_use, src1_col, color, x, y, xrad, yrad);
- src2fp= compbuf_get_pixel(src2_use, src2_col, color, x, y, xrad, yrad);
- facfp= compbuf_get_pixel(fac_use, fac, color, x, y, xrad, yrad);
-
- func(node, outfp, src1fp, src2fp, facfp);
- }
- }
-
- if (src1_use!=src1_buf)
- free_compbuf(src1_use);
- if (src2_use!=src2_buf)
- free_compbuf(src2_use);
- if (fac_use!=fac_buf)
- free_compbuf(fac_use);
-}
-
-/* Pixel-to-Pixel operation, 4 Images in, 1 out */
-void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, float *src1_col, CompBuf *fac1_buf, float *fac1,
- CompBuf *src2_buf, float *src2_col, CompBuf *fac2_buf, float *fac2,
- void (*func)(bNode *, float *, float *, float *, float *, float *),
- int src1_type, int fac1_type, int src2_type, int fac2_type)
-{
- CompBuf *src1_use, *src2_use, *fac1_use, *fac2_use;
- float *outfp=out->rect, *src1fp, *src2fp, *fac1fp, *fac2fp;
- float color[4]; /* local color if compbuf is procedural */
- int xrad, yrad, x, y;
-
- src1_use= composit_check_compbuf(src1_buf, src1_type, out);
- src2_use= composit_check_compbuf(src2_buf, src2_type, out);
- fac1_use= composit_check_compbuf(fac1_buf, fac1_type, out);
- fac2_use= composit_check_compbuf(fac2_buf, fac2_type, out);
-
- xrad= out->xrad;
- yrad= out->yrad;
-
- for (y= -yrad; y<-yrad+out->y; y++) {
- for (x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) {
- src1fp= compbuf_get_pixel(src1_use, src1_col, color, x, y, xrad, yrad);
- src2fp= compbuf_get_pixel(src2_use, src2_col, color, x, y, xrad, yrad);
- fac1fp= compbuf_get_pixel(fac1_use, fac1, color, x, y, xrad, yrad);
- fac2fp= compbuf_get_pixel(fac2_use, fac2, color, x, y, xrad, yrad);
-
- func(node, outfp, src1fp, fac1fp, src2fp, fac2fp);
- }
- }
-
- if (src1_use!=src1_buf)
- free_compbuf(src1_use);
- if (src2_use!=src2_buf)
- free_compbuf(src2_use);
- if (fac1_use!=fac1_buf)
- free_compbuf(fac1_use);
- if (fac2_use!=fac2_buf)
- free_compbuf(fac2_use);
-}
-
-
-CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel)
-{
- CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
- float *valf, *rectf;
- int tot;
-
- /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
- valbuf->xof= cbuf->xof;
- valbuf->yof= cbuf->yof;
-
- valf= valbuf->rect;
-
- /* defaults to returning alpha channel */
- if ((channel < CHAN_R) || (channel > CHAN_A)) channel = CHAN_A;
-
- rectf= cbuf->rect + channel;
-
- for (tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4)
- *valf= *rectf;
-
- return valbuf;
-}
-
-void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel)
-{
- float *valf, *rectf;
- int tot;
-
- valf= valbuf->rect;
-
- /* defaults to returning alpha channel */
- if ((channel < CHAN_R) || (channel > CHAN_A)) channel = CHAN_A;
-
- rectf = cbuf->rect + channel;
-
- for (tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4)
- *rectf = *valf;
-}
-
-static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy)
-{
- CompBuf *outbuf;
- float *outfp;
- int xrad, yrad, x, y;
-
- outbuf= alloc_compbuf(newx, newy, CB_RGBA, 1);
-
- outfp= outbuf->rect;
- xrad= outbuf->xrad;
- yrad= outbuf->yrad;
-
- for (y= -yrad; y<-yrad+outbuf->y; y++)
- for (x= -xrad; x<-xrad+outbuf->x; x++, outfp+=outbuf->type)
- cbuf->rect_procedural(cbuf, outfp, (float)x/(float)xrad, (float)y/(float)yrad);
-
- return outbuf;
-}
-
-/* OCIO_TODO: this function is only used by legacy compositor system only, which would likely be removed soon,
- * keep check for old color management flag for now
- */
-void generate_preview(void *data, bNode *node, CompBuf *stackbuf)
-{
- RenderData *rd= data;
- bNodePreview *preview= node->preview;
- int xsize, ysize;
- int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
- int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
- int dither= 0;
- unsigned char *rect;
-
- if (preview && stackbuf) {
- CompBuf *cbuf, *stackbuf_use;
-
- if (stackbuf->rect==NULL && stackbuf->rect_procedural==NULL) return;
-
- stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA);
-
- if (stackbuf->x > stackbuf->y) {
- xsize= 140;
- ysize= (140*stackbuf->y)/stackbuf->x;
- }
- else {
- ysize= 140;
- xsize= (140*stackbuf->x)/stackbuf->y;
- }
-
- if (stackbuf_use->rect_procedural)
- cbuf= generate_procedural_preview(stackbuf_use, xsize, ysize);
- else
- cbuf= scalefast_compbuf(stackbuf_use, xsize, ysize);
-
- /* convert to byte for preview */
- rect= MEM_callocN(sizeof(unsigned char)*4*xsize*ysize, "bNodePreview.rect");
-
- IMB_buffer_byte_from_float(rect, cbuf->rect,
- 4, dither, IB_PROFILE_SRGB, profile_from, predivide,
- xsize, ysize, xsize, xsize);
-
- free_compbuf(cbuf);
- if (stackbuf_use!=stackbuf)
- free_compbuf(stackbuf_use);
-
- // BLI_lock_thread(LOCK_PREVIEW);
-
- if (preview->rect)
- MEM_freeN(preview->rect);
- preview->xsize= xsize;
- preview->ysize= ysize;
- preview->rect= rect;
-
- // BLI_unlock_thread(LOCK_PREVIEW);
- }
-}
-
-void do_rgba_to_yuva(bNode *UNUSED(node), float *out, float *in)
-{
- rgb_to_yuv(in[0], in[1], in[2], &out[0], &out[1], &out[2]);
- out[3]=in[3];
-}
-
-void do_rgba_to_hsva(bNode *UNUSED(node), float *out, float *in)
-{
- rgb_to_hsv(in[0], in[1], in[2], &out[0], &out[1], &out[2]);
- out[3]=in[3];
-}
-
-void do_rgba_to_ycca(bNode *UNUSED(node), float *out, float *in)
-{
- rgb_to_ycc(in[0], in[1], in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);
- out[3]=in[3];
-}
-
-void do_yuva_to_rgba(bNode *UNUSED(node), float *out, float *in)
-{
- yuv_to_rgb(in[0], in[1], in[2], &out[0], &out[1], &out[2]);
- out[3]=in[3];
-}
-
-void do_hsva_to_rgba(bNode *UNUSED(node), float *out, float *in)
-{
- hsv_to_rgb(in[0], in[1], in[2], &out[0], &out[1], &out[2]);
- out[3]=in[3];
-}
-
-void do_ycca_to_rgba(bNode *UNUSED(node), float *out, float *in)
-{
- ycc_to_rgb(in[0], in[1], in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);
- out[3]=in[3];
-}
-
-void do_copy_rgba(bNode *UNUSED(node), float *out, float *in)
-{
- copy_v4_v4(out, in);
-}
-
-void do_copy_rgb(bNode *UNUSED(node), float *out, float *in)
-{
- copy_v3_v3(out, in);
- out[3] = 1.0f;
-}
-
-void do_copy_value(bNode *UNUSED(node), float *out, float *in)
-{
- out[0] = in[0];
-}
-
-void do_copy_a_rgba(bNode *UNUSED(node), float *out, float *in, float *fac)
-{
- copy_v3_v3(out, in);
- out[3] = *fac;
-}
-
-/* only accepts RGBA buffers */
-void gamma_correct_compbuf(CompBuf *img, int inversed)
-{
- float *drect;
- int x;
-
- if (img->type!=CB_RGBA) return;
-
- drect= img->rect;
- if (inversed) {
- for (x=img->x*img->y; x>0; x--, drect+=4) {
- if (drect[0]>0.0f) drect[0] = sqrt(drect[0]); else drect[0] = 0.0f;
- if (drect[1]>0.0f) drect[1] = sqrt(drect[1]); else drect[1] = 0.0f;
- if (drect[2]>0.0f) drect[2] = sqrt(drect[2]); else drect[2] = 0.0f;
- }
- }
- else {
- for (x=img->x*img->y; x>0; x--, drect+=4) {
- if (drect[0]>0.0f) drect[0]*= drect[0]; else drect[0] = 0.0f;
- if (drect[1]>0.0f) drect[1]*= drect[1]; else drect[1] = 0.0f;
- if (drect[2]>0.0f) drect[2]*= drect[2]; else drect[2] = 0.0f;
- }
- }
-}
-
-void premul_compbuf(CompBuf *img, int inversed)
-{
- float *drect;
- int x;
-
- if (img->type!=CB_RGBA) return;
-
- drect= img->rect;
- if (inversed) {
- for (x=img->x*img->y; x>0; x--, drect+=4) {
- if (fabsf(drect[3]) < 1e-5f) {
- drect[0] = 0.0f;
- drect[1] = 0.0f;
- drect[2] = 0.0f;
- }
- else {
- drect[0] /= drect[3];
- drect[1] /= drect[3];
- drect[2] /= drect[3];
- }
- }
- }
- else {
- for (x=img->x*img->y; x>0; x--, drect+=4) {
- drect[0] *= drect[3];
- drect[1] *= drect[3];
- drect[2] *= drect[3];
- }
- }
-}
-
-
-
-/*
- * 2D Fast Hartley Transform, used for convolution
- */
-
-typedef float fREAL;
-
-// returns next highest power of 2 of x, as well it's log2 in L2
-static unsigned int nextPow2(unsigned int x, unsigned int* L2)
-{
- unsigned int pw, x_notpow2 = x & (x-1);
- *L2 = 0;
- while (x>>=1) ++(*L2);
- pw = 1 << (*L2);
- if (x_notpow2) { (*L2)++; pw<<=1; }
- return pw;
-}
-
-//------------------------------------------------------------------------------
-
-// from FXT library by Joerg Arndt, faster in order bitreversal
-// use: r = revbin_upd(r, h) where h = N>>1
-static unsigned int revbin_upd(unsigned int r, unsigned int h)
-{
- while (!((r^=h)&h)) h >>= 1;
- return r;
-}
-//------------------------------------------------------------------------------
-static void FHT(fREAL* data, unsigned int M, unsigned int inverse)
-{
- double tt, fc, dc, fs, ds, a = M_PI;
- fREAL t1, t2;
- int n2, bd, bl, istep, k, len = 1 << M, n = 1;
-
- int i, j = 0;
- unsigned int Nh = len >> 1;
- for (i=1;i<(len-1);++i) {
- j = revbin_upd(j, Nh);
- if (j>i) {
- t1 = data[i];
- data[i] = data[j];
- data[j] = t1;
- }
- }
-
- do {
- fREAL* data_n = &data[n];
-
- istep = n << 1;
- for (k=0; k<len; k+=istep) {
- t1 = data_n[k];
- data_n[k] = data[k] - t1;
- data[k] += t1;
- }
-
- n2 = n >> 1;
- if (n>2) {
- fc = dc = cos(a);
- fs = ds = sqrt(1.0 - fc*fc); //sin(a);
- bd = n-2;
- for (bl=1; bl<n2; bl++) {
- fREAL* data_nbd = &data_n[bd];
- fREAL* data_bd = &data[bd];
- for (k=bl; k<len; k+=istep) {
- t1 = fc*data_n[k] + fs*data_nbd[k];
- t2 = fs*data_n[k] - fc*data_nbd[k];
- data_n[k] = data[k] - t1;
- data_nbd[k] = data_bd[k] - t2;
- data[k] += t1;
- data_bd[k] += t2;
- }
- tt = fc*dc - fs*ds;
- fs = fs*dc + fc*ds;
- fc = tt;
- bd -= 2;
- }
- }
-
- if (n>1) {
- for (k=n2; k<len; k+=istep) {
- t1 = data_n[k];
- data_n[k] = data[k] - t1;
- data[k] += t1;
- }
- }
-
- n = istep;
- a *= 0.5;
- } while (n<len);
-
- if (inverse) {
- fREAL sc = (fREAL)1 / (fREAL)len;
- for (k=0; k<len; ++k)
- data[k] *= sc;
- }
-}
-//------------------------------------------------------------------------------
-/* 2D Fast Hartley Transform, Mx/My -> log2 of width/height,
- * nzp -> the row where zero pad data starts,
- * inverse -> see above */
-static void FHT2D(fREAL *data, unsigned int Mx, unsigned int My,
- unsigned int nzp, unsigned int inverse)
-{
- unsigned int i, j, Nx, Ny, maxy;
- fREAL t;
-
- Nx = 1 << Mx;
- Ny = 1 << My;
-
- // rows (forward transform skips 0 pad data)
- maxy = inverse ? Ny : nzp;
- for (j=0; j<maxy; ++j)
- FHT(&data[Nx*j], Mx, inverse);
-
- // transpose data
- if (Nx==Ny) { // square
- for (j=0; j<Ny; ++j)
- for (i=j+1; i<Nx; ++i) {
- unsigned int op = i + (j << Mx), np = j + (i << My);
- t=data[op], data[op]=data[np], data[np]=t;
- }
- }
- else { // rectangular
- unsigned int k, Nym = Ny-1, stm = 1 << (Mx + My);
- for (i=0; stm>0; i++) {
- #define PRED(k) (((k & Nym) << Mx) + (k >> My))
- for (j=PRED(i); j>i; j=PRED(j));
- if (j < i) continue;
- for (k=i, j=PRED(i); j!=i; k=j, j=PRED(j), stm--) {
- t=data[j], data[j]=data[k], data[k]=t;
- }
- #undef PRED
- stm--;
- }
- }
- // swap Mx/My & Nx/Ny
- i = Nx, Nx = Ny, Ny = i;
- i = Mx, Mx = My, My = i;
-
- // now columns == transposed rows
- for (j=0; j<Ny; ++j)
- FHT(&data[Nx*j], Mx, inverse);
-
- // finalize
- for (j=0; j<=(Ny >> 1); j++) {
- unsigned int jm = (Ny - j) & (Ny-1);
- unsigned int ji = j << Mx;
- unsigned int jmi = jm << Mx;
- for (i=0; i<=(Nx >> 1); i++) {
- unsigned int im = (Nx - i) & (Nx-1);
- fREAL A = data[ji + i];
- fREAL B = data[jmi + i];
- fREAL C = data[ji + im];
- fREAL D = data[jmi + im];
- fREAL E = (fREAL)0.5*((A + D) - (B + C));
- data[ji + i] = A - E;
- data[jmi + i] = B + E;
- data[ji + im] = C + E;
- data[jmi + im] = D - E;
- }
- }
-
-}
-
-//------------------------------------------------------------------------------
-
-/* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height */
-static void fht_convolve(fREAL* d1, fREAL* d2, unsigned int M, unsigned int N)
-{
- fREAL a, b;
- unsigned int i, j, k, L, mj, mL;
- unsigned int m = 1 << M, n = 1 << N;
- unsigned int m2 = 1 << (M-1), n2 = 1 << (N-1);
- unsigned int mn2 = m << (N-1);
-
- d1[0] *= d2[0];
- d1[mn2] *= d2[mn2];
- d1[m2] *= d2[m2];
- d1[m2 + mn2] *= d2[m2 + mn2];
- for (i=1; i<m2; i++) {
- k = m - i;
- a = d1[i]*d2[i] - d1[k]*d2[k];
- b = d1[k]*d2[i] + d1[i]*d2[k];
- d1[i] = (b + a)*(fREAL)0.5;
- d1[k] = (b - a)*(fREAL)0.5;
- a = d1[i + mn2]*d2[i + mn2] - d1[k + mn2]*d2[k + mn2];
- b = d1[k + mn2]*d2[i + mn2] + d1[i + mn2]*d2[k + mn2];
- d1[i + mn2] = (b + a)*(fREAL)0.5;
- d1[k + mn2] = (b - a)*(fREAL)0.5;
- }
- for (j=1; j<n2; j++) {
- L = n - j;
- mj = j << M;
- mL = L << M;
- a = d1[mj]*d2[mj] - d1[mL]*d2[mL];
- b = d1[mL]*d2[mj] + d1[mj]*d2[mL];
- d1[mj] = (b + a)*(fREAL)0.5;
- d1[mL] = (b - a)*(fREAL)0.5;
- a = d1[m2 + mj]*d2[m2 + mj] - d1[m2 + mL]*d2[m2 + mL];
- b = d1[m2 + mL]*d2[m2 + mj] + d1[m2 + mj]*d2[m2 + mL];
- d1[m2 + mj] = (b + a)*(fREAL)0.5;
- d1[m2 + mL] = (b - a)*(fREAL)0.5;
- }
- for (i=1; i<m2; i++) {
- k = m - i;
- for (j=1; j<n2; j++) {
- L = n - j;
- mj = j << M;
- mL = L << M;
- a = d1[i + mj]*d2[i + mj] - d1[k + mL]*d2[k + mL];
- b = d1[k + mL]*d2[i + mj] + d1[i + mj]*d2[k + mL];
- d1[i + mj] = (b + a)*(fREAL)0.5;
- d1[k + mL] = (b - a)*(fREAL)0.5;
- a = d1[i + mL]*d2[i + mL] - d1[k + mj]*d2[k + mj];
- b = d1[k + mj]*d2[i + mL] + d1[i + mL]*d2[k + mj];
- d1[i + mL] = (b + a)*(fREAL)0.5;
- d1[k + mj] = (b - a)*(fREAL)0.5;
- }
- }
-}
-
-//------------------------------------------------------------------------------
-
-void convolve(CompBuf* dst, CompBuf* in1, CompBuf* in2)
-{
- fREAL *data1, *data2, *fp;
- unsigned int w2, h2, hw, hh, log2_w, log2_h;
- fRGB wt, *colp;
- int x, y, ch;
- int xbl, ybl, nxb, nyb, xbsz, ybsz;
- int in2done = FALSE;
-
- CompBuf* rdst = alloc_compbuf(in1->x, in1->y, in1->type, 1);
-
- // convolution result width & height
- w2 = 2*in2->x - 1;
- h2 = 2*in2->y - 1;
- // FFT pow2 required size & log2
- w2 = nextPow2(w2, &log2_w);
- h2 = nextPow2(h2, &log2_h);
-
- // alloc space
- data1 = (fREAL*)MEM_callocN(3*w2*h2*sizeof(fREAL), "convolve_fast FHT data1");
- data2 = (fREAL*)MEM_callocN(w2*h2*sizeof(fREAL), "convolve_fast FHT data2");
-
- // normalize convolutor
- wt[0] = wt[1] = wt[2] = 0.f;
- for (y=0; y<in2->y; y++) {
- colp = (fRGB*)&in2->rect[y*in2->x*in2->type];
- for (x=0; x<in2->x; x++)
- add_v3_v3(wt, colp[x]);
- }
- if (wt[0] != 0.f) wt[0] = 1.f/wt[0];
- 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<in2->y; y++) {
- colp = (fRGB*)&in2->rect[y*in2->x*in2->type];
- for (x=0; x<in2->x; x++)
- mul_v3_v3(colp[x], wt);
- }
-
- // copy image data, unpacking interleaved RGBA into separate channels
- // only need to calc data1 once
-
- // block add-overlap
- hw = in2->x >> 1;
- hh = in2->y >> 1;
- xbsz = (w2 + 1) - in2->x;
- ybsz = (h2 + 1) - in2->y;
- nxb = in1->x / xbsz;
- if (in1->x % xbsz) nxb++;
- nyb = in1->y / ybsz;
- if (in1->y % ybsz) nyb++;
- for (ybl=0; ybl<nyb; ybl++) {
- for (xbl=0; xbl<nxb; xbl++) {
-
- // each channel one by one
- for (ch=0; ch<3; ch++) {
- fREAL* data1ch = &data1[ch*w2*h2];
-
- // only need to calc fht data from in2 once, can re-use for every block
- if (!in2done) {
- // in2, channel ch -> data1
- for (y=0; y<in2->y; y++) {
- fp = &data1ch[y*w2];
- colp = (fRGB*)&in2->rect[y*in2->x*in2->type];
- for (x=0; x<in2->x; x++)
- fp[x] = colp[x][ch];
- }
- }
-
- // in1, channel ch -> data2
- memset(data2, 0, w2*h2*sizeof(fREAL));
- for (y=0; y<ybsz; y++) {
- int yy = ybl*ybsz + y;
- if (yy >= in1->y) continue;
- fp = &data2[y*w2];
- colp = (fRGB*)&in1->rect[yy*in1->x*in1->type];
- for (x=0; x<xbsz; x++) {
- int xx = xbl*xbsz + x;
- if (xx >= in1->x) continue;
- fp[x] = colp[xx][ch];
- }
- }
-
- // forward FHT
- // zero pad data start is different for each == height+1
- if (!in2done) FHT2D(data1ch, log2_w, log2_h, in2->y+1, 0);
- FHT2D(data2, log2_w, log2_h, in2->y+1, 0);
-
- // FHT2D transposed data, row/col now swapped
- // convolve & inverse FHT
- fht_convolve(data2, data1ch, log2_h, log2_w);
- FHT2D(data2, log2_h, log2_w, 0, 1);
- // data again transposed, so in order again
-
- // overlap-add result
- for (y=0; y<(int)h2; y++) {
- const int yy = ybl*ybsz + y - hh;
- if ((yy < 0) || (yy >= in1->y)) continue;
- fp = &data2[y*w2];
- colp = (fRGB*)&rdst->rect[yy*in1->x*in1->type];
- for (x=0; x<(int)w2; x++) {
- const int xx = xbl*xbsz + x - hw;
- if ((xx < 0) || (xx >= in1->x)) continue;
- colp[xx][ch] += fp[x];
- }
- }
-
- }
- in2done = TRUE;
- }
- }
-
- MEM_freeN(data2);
- MEM_freeN(data1);
- memcpy(dst->rect, rdst->rect, sizeof(float)*dst->x*dst->y*dst->type);
- free_compbuf(rdst);
-}
-
-
-/*
- *
- * Utility functions qd_* should probably be integrated better with other functions here.
- *
- */
-// sets fcol to pixelcolor at (x, y)
-void qd_getPixel(CompBuf* src, int x, int y, float* col)
-{
- if (src->rect_procedural) {
- float bc[4];
- src->rect_procedural(src, bc, (float)x/(float)src->xrad, (float)y/(float)src->yrad);
-
- switch (src->type) {
- /* these fallthrough to get all the channels */
- case CB_RGBA: col[3]=bc[3];
- case CB_VEC3: col[2]=bc[2];
- case CB_VEC2: col[1]=bc[1];
- case CB_VAL: col[0]=bc[0];
- }
- }
- else if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
- float* bc = &src->rect[(x + y*src->x)*src->type];
- switch (src->type) {
- /* these fallthrough to get all the channels */
- case CB_RGBA: col[3]=bc[3];
- case CB_VEC3: col[2]=bc[2];
- case CB_VEC2: col[1]=bc[1];
- case CB_VAL: col[0]=bc[0];
- }
- }
- else {
- switch (src->type) {
- /* these fallthrough to get all the channels */
- case CB_RGBA: col[3]=0.0;
- case CB_VEC3: col[2]=0.0;
- case CB_VEC2: col[1]=0.0;
- case CB_VAL: col[0]=0.0;
- }
- }
-}
-
-// sets pixel (x, y) to color col
-void qd_setPixel(CompBuf* src, int x, int y, float* col)
-{
- if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
- float* bc = &src->rect[(x + y*src->x)*src->type];
- switch (src->type) {
- /* these fallthrough to get all the channels */
- case CB_RGBA: bc[3]=col[3];
- case CB_VEC3: bc[2]=col[2];
- case CB_VEC2: bc[1]=col[1];
- case CB_VAL: bc[0]=col[0];
- }
- }
-}
-
-// adds fcol to pixelcolor (x, y)
-void qd_addPixel(CompBuf* src, int x, int y, float* col)
-{
- if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
- float* bc = &src->rect[(x + y*src->x)*src->type];
- bc[0] += col[0], bc[1] += col[1], bc[2] += col[2];
- }
-}
-
-// multiplies pixel by factor value f
-void qd_multPixel(CompBuf* src, int x, int y, float f)
-{
- if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
- float* bc = &src->rect[(x + y*src->x)*src->type];
- bc[0] *= f, bc[1] *= f, bc[2] *= f;
- }
-}
-
-// bilinear interpolation with wraparound
-void qd_getPixelLerpWrap(CompBuf* src, float u, float v, float* col)
-{
- const float ufl = floor(u), vfl = floor(v);
- const int nx = (int)ufl % src->x, ny = (int)vfl % src->y;
- const int x1 = (nx < 0) ? (nx + src->x) : nx;
- const int y1 = (ny < 0) ? (ny + src->y) : ny;
- const int x2 = (x1 + 1) % src->x, y2 = (y1 + 1) % src->y;
- const float* c00 = &src->rect[(x1 + y1*src->x)*src->type];
- const float* c10 = &src->rect[(x2 + y1*src->x)*src->type];
- const float* c01 = &src->rect[(x1 + y2*src->x)*src->type];
- const float* c11 = &src->rect[(x2 + y2*src->x)*src->type];
- const float uf = u - ufl, vf = v - vfl;
- const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
- col[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
- if (src->type != CB_VAL) {
- col[1] = w00*c00[1] + w10*c10[1] + w01*c01[1] + w11*c11[1];
- col[2] = w00*c00[2] + w10*c10[2] + w01*c01[2] + w11*c11[2];
- col[3] = w00*c00[3] + w10*c10[3] + w01*c01[3] + w11*c11[3];
- }
-}
-
-// as above, without wrap around
-void qd_getPixelLerp(CompBuf* src, float u, float v, float* col)
-{
- const float ufl = floor(u), vfl = floor(v);
- const int x1 = (int)ufl, y1 = (int)vfl;
- const int x2 = (int)ceil(u), y2 = (int)ceil(v);
- if ((x2 >= 0) && (y2 >= 0) && (x1 < src->x) && (y1 < src->y)) {
- const float B[4] = {0, 0, 0, 0};
- const int ox1 = (x1 < 0), oy1 = (y1 < 0), ox2 = (x2 >= src->x), oy2 = (y2 >= src->y);
- const float* c00 = (ox1 || oy1) ? B : &src->rect[(x1 + y1*src->x)*src->type];
- const float* c10 = (ox2 || oy1) ? B : &src->rect[(x2 + y1*src->x)*src->type];
- const float* c01 = (ox1 || oy2) ? B : &src->rect[(x1 + y2*src->x)*src->type];
- const float* c11 = (ox2 || oy2) ? B : &src->rect[(x2 + y2*src->x)*src->type];
- const float uf = u - ufl, vf = v - vfl;
- const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
- col[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
- if (src->type != CB_VAL) {
- col[1] = w00*c00[1] + w10*c10[1] + w01*c01[1] + w11*c11[1];
- col[2] = w00*c00[2] + w10*c10[2] + w01*c01[2] + w11*c11[2];
- col[3] = w00*c00[3] + w10*c10[3] + w01*c01[3] + w11*c11[3];
- }
- }
- else col[0] = col[1] = col[2] = col[3] = 0.f;
-}
-
-// as above, sampling only one channel
-void qd_getPixelLerpChan(CompBuf* src, float u, float v, int chan, float* out)
-{
- const float ufl = floor(u), vfl = floor(v);
- const int x1 = (int)ufl, y1 = (int)vfl;
- const int x2 = (int)ceil(u), y2 = (int)ceil(v);
- if (chan >= src->type) chan = 0;
- if ((x2 >= 0) && (y2 >= 0) && (x1 < src->x) && (y1 < src->y)) {
- const float B[4] = {0, 0, 0, 0};
- const int ox1 = (x1 < 0), oy1 = (y1 < 0), ox2 = (x2 >= src->x), oy2 = (y2 >= src->y);
- const float* c00 = (ox1 || oy1) ? B : &src->rect[(x1 + y1*src->x)*src->type + chan];
- const float* c10 = (ox2 || oy1) ? B : &src->rect[(x2 + y1*src->x)*src->type + chan];
- const float* c01 = (ox1 || oy2) ? B : &src->rect[(x1 + y2*src->x)*src->type + chan];
- const float* c11 = (ox2 || oy2) ? B : &src->rect[(x2 + y2*src->x)*src->type + chan];
- const float uf = u - ufl, vf = v - vfl;
- const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
- out[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
- }
- else *out = 0.f;
-}
-
-
-CompBuf* qd_downScaledCopy(CompBuf* src, int scale)
-{
- CompBuf* fbuf;
- if (scale <= 1)
- fbuf = dupalloc_compbuf(src);
- else {
- int nw = src->x/scale, nh = src->y/scale;
- if ((2*(src->x % scale)) > scale) nw++;
- if ((2*(src->y % scale)) > scale) nh++;
- fbuf = alloc_compbuf(nw, nh, src->type, 1);
- {
- int x, y, xx, yy, sx, sy, mx, my;
- float colsum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- float fscale = 1.f/(float)(scale*scale);
- for (y=0; y<nh; y++) {
- fRGB* fcolp = (fRGB*)&fbuf->rect[y*fbuf->x*fbuf->type];
- yy = y*scale;
- my = yy + scale;
- if (my > src->y) my = src->y;
- for (x=0; x<nw; x++) {
- xx = x*scale;
- mx = xx + scale;
- if (mx > src->x) mx = src->x;
- zero_v3(colsum);
- for (sy=yy; sy<my; sy++) {
- fRGB* scolp = (fRGB*)&src->rect[sy*src->x*src->type];
- for (sx=xx; sx<mx; sx++)
- add_v3_v3(colsum, scolp[sx]);
- }
- mul_v3_fl(colsum, fscale);
- copy_v3_v3(fcolp[x], colsum);
- }
- }
- }
- }
- return fbuf;
-}
-
-// fast g.blur, per channel
-// xy var. bits 1 & 2 ca be used to blur in x or y direction separately
-void IIR_gauss(CompBuf* src, float sigma, int chan, int xy)
-{
- double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
- double *X, *Y, *W;
- const unsigned int src_width = src->x;
- const unsigned int src_height = src->y;
- unsigned int i, x, y, sz;
-
- // <0.5 not valid, though can have a possibly useful sort of sharpening effect
- if (sigma < 0.5f) return;
-
- if ((xy < 1) || (xy > 3)) xy = 3;
-
- // XXX The YVV macro defined below explicitly expects sources of at least 3x3 pixels,
- // so just skiping blur along faulty direction if src's def is below that limit!
- if (src_width < 3) xy &= ~(int) 1;
- if (src_height < 3) xy &= ~(int) 2;
- if (xy < 1) return;
-
- // see "Recursive Gabor Filtering" by Young/VanVliet
- // all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200
- if (sigma >= 3.556f)
- q = 0.9804f * (sigma - 3.556f) + 2.5091f;
- else // sigma >= 0.5
- q = (0.0561f * sigma + 0.5784f) * sigma - 0.2568f;
- q2 = q * q;
- sc = (1.1668 + q) * (3.203729649 + (2.21566 + q) * q);
- // no gabor filtering here, so no complex multiplies, just the regular coefs.
- // all negated here, so as not to have to recalc Triggs/Sdika matrix
- cf[1] = q * (5.788961737 + (6.76492 + 3.0 * q) * q) / sc;
- cf[2] = -q2 * (3.38246 + 3.0 * q) / sc;
- // 0 & 3 unchanged
- cf[3] = q2 * q / sc;
- cf[0] = 1.0 - cf[1] - cf[2] - cf[3];
-
- // Triggs/Sdika border corrections,
- // it seems to work, not entirely sure if it is actually totally correct,
- // Besides J.M.Geusebroek's anigauss.c (see http://www.science.uva.nl/~mark),
- // found one other implementation by Cristoph Lampert,
- // but neither seem to be quite the same, result seems to be ok so far anyway.
- // Extra scale factor here to not have to do it in filter,
- // though maybe this had something to with the precision errors
- sc = cf[0] / ((1.0 + cf[1] - cf[2] + cf[3]) * (1.0 - cf[1] - cf[2] - cf[3]) * (1.0 + cf[2] + (cf[1] - cf[3]) * cf[3]));
- tsM[0] = sc * (-cf[3] * cf[1] + 1.0 - cf[3] * cf[3] - cf[2]);
- tsM[1] = sc * ((cf[3] + cf[1]) * (cf[2] + cf[3] * cf[1]));
- tsM[2] = sc * (cf[3] * (cf[1] + cf[3] * cf[2]));
- tsM[3] = sc * (cf[1] + cf[3] * cf[2]);
- tsM[4] = sc * (-(cf[2] - 1.0) * (cf[2] + cf[3] * cf[1]));
- tsM[5] = sc * (-(cf[3] * cf[1] + cf[3] * cf[3] + cf[2] - 1.0) * cf[3]);
- tsM[6] = sc * (cf[3] * cf[1] + cf[2] + cf[1] * cf[1] - cf[2] * cf[2]);
- tsM[7] = sc * (cf[1] * cf[2] + cf[3] * cf[2] * cf[2] - cf[1] * cf[3] * cf[3] - cf[3] * cf[3] * cf[3] - cf[3] * cf[2] + cf[3]);
- tsM[8] = sc * (cf[3] * (cf[1] + cf[3] * cf[2]));
-
-#define YVV(L) \
-{ \
- W[0] = cf[0] * X[0] + cf[1] * X[0] + cf[2] * X[0] + cf[3] * X[0]; \
- W[1] = cf[0] * X[1] + cf[1] * W[0] + cf[2] * X[0] + cf[3] * X[0]; \
- W[2] = cf[0] * X[2] + cf[1] * W[1] + cf[2] * W[0] + cf[3] * X[0]; \
- for (i = 3; i < L; i++) { \
- W[i] = cf[0] * X[i] + cf[1] * W[i - 1] + cf[2] * W[i - 2] + cf[3] * W[i - 3]; \
- } \
- tsu[0] = W[L - 1] - X[L - 1]; \
- tsu[1] = W[L - 2] - X[L - 1]; \
- tsu[2] = W[L - 3] - X[L - 1]; \
- tsv[0] = tsM[0] * tsu[0] + tsM[1] * tsu[1] + tsM[2] * tsu[2] + X[L - 1]; \
- tsv[1] = tsM[3] * tsu[0] + tsM[4] * tsu[1] + tsM[5] * tsu[2] + X[L - 1]; \
- tsv[2] = tsM[6] * tsu[0] + tsM[7] * tsu[1] + tsM[8] * tsu[2] + X[L - 1]; \
- Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \
- Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \
- Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \
- /* 'i != UINT_MAX' is really 'i >= 0', but necessary for unsigned int wrapping */ \
- for (i = L - 4; i != UINT_MAX; i--) { \
- Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \
- } \
-} (void)0
-
- // intermediate buffers
- sz = MAX2(src_width, src_height);
- X = MEM_callocN(sz * sizeof(double), "IIR_gauss X buf");
- Y = MEM_callocN(sz * sizeof(double), "IIR_gauss Y buf");
- W = MEM_callocN(sz * sizeof(double), "IIR_gauss W buf");
- if (xy & 1) { // H
- for (y = 0; y < src_height; ++y) {
- const int yx = y * src_width;
- for (x = 0; x < src_width; ++x)
- X[x] = src->rect[(x + yx) * src->type + chan];
- YVV(src_width);
- for (x = 0; x < src_width; ++x)
- src->rect[(x + yx) * src->type + chan] = Y[x];
- }
- }
- if (xy & 2) { // V
- for (x = 0; x < src_width; ++x) {
- for (y = 0; y < src_height; ++y)
- X[y] = src->rect[(x + y * src_width) * src->type + chan];
- YVV(src_height);
- for (y = 0; y < src_height; ++y)
- src->rect[(x + y * src_width) * src->type + chan] = Y[y];
- }
- }
-
- MEM_freeN(X);
- MEM_freeN(W);
- MEM_freeN(Y);
-#undef YVV
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h
index f2719ee0779..a3c4bffe018 100644
--- a/source/blender/nodes/composite/node_composite_util.h
+++ b/source/blender/nodes/composite/node_composite_util.h
@@ -33,177 +33,30 @@
#ifndef __NODE_COMPOSITE_UTIL_H__
#define __NODE_COMPOSITE_UTIL_H__
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_camera_types.h" /* qdn: defocus node, need camera info */
-#include "DNA_color_types.h"
#include "DNA_ID.h"
-#include "DNA_image_types.h"
-#include "DNA_material_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_texture_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_rand.h"
-#include "BLI_threads.h"
-#include "BLI_utildefines.h"
-#include "BLI_utildefines.h"
#include "BLF_translation.h"
-#include "BKE_blender.h"
-#include "BKE_camera.h"
#include "BKE_colortools.h"
-#include "BKE_global.h"
#include "BKE_image.h"
-#include "BKE_main.h"
-#include "BKE_material.h"
-#include "BKE_movieclip.h"
-#include "BKE_node.h"
#include "BKE_texture.h"
#include "BKE_tracking.h"
-#include "BKE_library.h"
-#include "BKE_object.h"
-
#include "node_util.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "RE_pipeline.h"
-#include "RE_shader_ext.h"
-#include "RE_render_ext.h"
/* only for forward declarations */
#include "NOD_composite.h"
#define CMP_SCALE_MAX 12000
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* *************************** operations support *************************** */
-
-/* general signal that's in output sockets, and goes over the wires */
-typedef struct CompBuf {
- float *rect;
- int x, y, xrad, yrad;
- short type, malloc;
- rcti disprect; /* cropped part of image */
- int xof, yof; /* relative to center of target image */
-
- void (*rect_procedural)(struct CompBuf *, float *, float, float);
- float procedural_size[3], procedural_offset[3];
- int procedural_type;
- bNode *node; /* only in use for procedural bufs */
-
- struct CompBuf *next, *prev; /* for pass-on, works nicer than reference counting */
-} CompBuf;
-
-/* defines also used for pixel size */
-#define CB_RGBA 4
-#define CB_VEC4 4
-#define CB_VEC3 3
-#define CB_VEC2 2
-#define CB_VAL 1
-
-/* defines for RGBA channels */
-#define CHAN_R 0
-#define CHAN_G 1
-#define CHAN_B 2
-#define CHAN_A 3
-
-
-
-CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc);
-CompBuf *dupalloc_compbuf(CompBuf *cbuf);
-CompBuf *pass_on_compbuf(CompBuf *cbuf);
-void free_compbuf(CompBuf *cbuf);
-void print_compbuf(char *str, CompBuf *cbuf);
-void compbuf_set_node(struct CompBuf *cbuf, struct bNode *node);
-
-CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type);
-CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy);
-CompBuf *typecheck_compbuf(CompBuf *inbuf, int type);
-void typecheck_compbuf_color(float *out, float *in, int outtype, int intype);
-
-/* **************************************************** */
-
-float *compbuf_get_pixel(CompBuf *cbuf, float *defcol, float *use, int x, int y, int xrad, int yrad);
-
-/* Pixel-to-Pixel operation, 1 Image in, 1 out */
-void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col,
- void (*func)(bNode *, float *, float *),
- int src_type);
-/* Pixel-to-Pixel operation, 2 Images in, 1 out */
-void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col,
- CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *),
- int src_type, int fac_type);
-
-/* Pixel-to-Pixel operation, 3 Images in, 1 out */
-void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, float *src1_col, CompBuf *src2_buf, float *src2_col,
- CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *, float *),
- int src1_type, int src2_type, int fac_type);
-
-/* Pixel-to-Pixel operation, 4 Images in, 1 out */
-void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, float *src1_col, CompBuf *fac1_buf, float *fac1,
- CompBuf *src2_buf, float *src2_col, CompBuf *fac2_buf, float *fac2,
- void (*func)(bNode *, float *, float *, float *, float *, float *),
- int src1_type, int fac1_type, int src2_type, int fac2_type);
-
-CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel);
-void valbuf_to_rgbabuf(CompBuf *valbuf, CompBuf *cbuf, int channel);
-void generate_preview(void *data, bNode *node, CompBuf *stackbuf);
-
-void do_copy_rgba(bNode *node, float *out, float *in);
-void do_copy_rgb(bNode *node, float *out, float *in);
-void do_copy_value(bNode *node, float *out, float *in);
-void do_copy_a_rgba(bNode *node, float *out, float *in, float *fac);
-
-void do_rgba_to_yuva(bNode *node, float *out, float *in);
-void do_rgba_to_hsva(bNode *node, float *out, float *in);
-void do_rgba_to_ycca(bNode *node, float *out, float *in);
-void do_yuva_to_rgba(bNode *node, float *out, float *in);
-void do_hsva_to_rgba(bNode *node, float *out, float *in);
-void do_ycca_to_rgba(bNode *node, float *out, float *in);
-
-void gamma_correct_compbuf(CompBuf *img, int inversed);
-void premul_compbuf(CompBuf *img, int inversed);
-void convolve(CompBuf* dst, CompBuf* in1, CompBuf* in2);
-
-extern void node_ID_title_cb(void *node_v, void *unused_v);
-
-
-/* utility functions used by glare, tonemap and lens distortion */
-/* soms macros for color handling */
-typedef float fRGB[4];
-/* multiply c2 by color rgb, rgb as separate arguments */
-#define fRGB_rgbmult(c, r, g, b) { c[0]*=(r); c[1]*=(g); c[2]*=(b); } (void)0
-
-void qd_getPixel(CompBuf* src, int x, int y, float* col);
-void qd_setPixel(CompBuf* src, int x, int y, float* col);
-void qd_addPixel(CompBuf* src, int x, int y, float* col);
-void qd_multPixel(CompBuf* src, int x, int y, float f);
-void qd_getPixelLerpWrap(CompBuf* src, float u, float v, float* col);
-void qd_getPixelLerp(CompBuf* src, float u, float v, float* col);
-void qd_getPixelLerpChan(CompBuf* src, float u, float v, int chan, float* out);
-CompBuf* qd_downScaledCopy(CompBuf* src, int scale);
-void IIR_gauss(CompBuf* src, float sigma, int chan, int xy);
-/* end utility funcs */
-
-/* transformations */
-
-CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type);
-float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc);
-
-#endif
-
-#endif /* WITH_COMPOSITOR_LEGACY */
+#endif /* __NODE_COMPOSITE_UTIL_H__ */
diff --git a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c
index 72c2204d8c5..217670621a8 100644
--- a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c
+++ b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c
@@ -43,103 +43,6 @@ static bNodeSocketTemplate cmp_node_alphaover_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_alphaover_premul(bNode *UNUSED(node), float *out, float *src, float *over, float *fac)
-{
-
- /* Zero alpha values should still permit an add of RGB data */
- if (over[3]<0.0f) {
- copy_v4_v4(out, src);
- }
- else if (fac[0]==1.0f && over[3]>=1.0f) {
- copy_v4_v4(out, over);
- }
- else {
- float mul= 1.0f - fac[0]*over[3];
-
- out[0] = (mul*src[0]) + fac[0]*over[0];
- out[1] = (mul*src[1]) + fac[0]*over[1];
- out[2] = (mul*src[2]) + fac[0]*over[2];
- out[3] = (mul*src[3]) + fac[0]*over[3];
- }
-}
-
-/* result will be still premul, but the over part is premulled */
-static void do_alphaover_key(bNode *UNUSED(node), float *out, float *src, float *over, float *fac)
-{
-
- if (over[3]<=0.0f) {
- copy_v4_v4(out, src);
- }
- else if (fac[0]==1.0f && over[3]>=1.0f) {
- copy_v4_v4(out, over);
- }
- else {
- float premul= fac[0]*over[3];
- float mul= 1.0f - premul;
-
- out[0] = (mul*src[0]) + premul*over[0];
- out[1] = (mul*src[1]) + premul*over[1];
- out[2] = (mul*src[2]) + premul*over[2];
- out[3] = (mul*src[3]) + fac[0]*over[3];
- }
-}
-
-/* result will be still premul, but the over part is premulled */
-static void do_alphaover_mixed(bNode *node, float *out, float *src, float *over, float *fac)
-{
-
- if (over[3]<=0.0f) {
- copy_v4_v4(out, src);
- }
- else if (fac[0]==1.0f && over[3]>=1.0f) {
- copy_v4_v4(out, over);
- }
- else {
- NodeTwoFloats *ntf= node->storage;
- float addfac= 1.0f - ntf->x + over[3]*ntf->x;
- float premul= fac[0]*addfac;
- float mul= 1.0f - fac[0]*over[3];
-
- out[0] = (mul*src[0]) + premul*over[0];
- out[1] = (mul*src[1]) + premul*over[1];
- out[2] = (mul*src[2]) + premul*over[2];
- out[3] = (mul*src[3]) + fac[0]*over[3];
- }
-}
-
-
-static void node_composit_exec_alphaover(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: col col */
- /* stack order out: col */
- if (out[0]->hasoutput==0)
- return;
-
- /* input no image? then only color operation */
- if (in[1]->data==NULL && in[2]->data==NULL) {
- do_alphaover_premul(node, out[0]->vec, in[1]->vec, in[2]->vec, in[0]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
- NodeTwoFloats *ntf= node->storage;
-
- if (ntf->x != 0.0f)
- composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_mixed, CB_RGBA, CB_RGBA, CB_VAL);
- else if (node->custom1)
- composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_key, CB_RGBA, CB_RGBA, CB_VAL);
- else
- composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_premul, CB_RGBA, CB_RGBA, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_alphaover_init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->storage= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats");
@@ -149,14 +52,10 @@ void register_node_type_cmp_alphaover(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, CMP_NODE_ALPHAOVER, "AlphaOver", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
+ node_type_base(ttype, &ntype, CMP_NODE_ALPHAOVER, "Alpha Over", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_alphaover_in, cmp_node_alphaover_out);
- node_type_size(&ntype, 80, 40, 120);
node_type_init(&ntype, node_alphaover_init);
node_type_storage(&ntype, "NodeTwoFloats", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_alphaover);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c
index 7674ace42a3..b8bf379b14b 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c
@@ -43,221 +43,6 @@ static bNodeSocketTemplate cmp_node_bilateralblur_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-#define INIT_C3 \
- mean0 = 1; \
- mean1[0] = src[0]; \
- mean1[1] = src[1]; \
- mean1[2] = src[2]; \
- mean1[3] = src[3]; \
- (void)0
-
-/* finds color distances */
-#define COLOR_DISTANCE_C3(c1, c2) \
- ((c1[0] - c2[0]) * (c1[0] - c2[0]) + \
- (c1[1] - c2[1]) * (c1[1] - c2[1]) + \
- (c1[2] - c2[2]) * (c1[2] - c2[2]) + \
- (c1[3] - c2[3]) * (c1[3] - c2[3]))
-
-/* this is the main kernel function for comparing color distances
- * and adding them weighted to the final color */
-#define KERNEL_ELEMENT_C3(k) \
- temp_color = src + deltas[k]; \
- ref_color = ref + deltas[k]; \
- w = weight_tab[k] + \
- (double)COLOR_DISTANCE_C3(ref, ref_color) * i2sigma_color; \
- w = 1.0 / (w * w + 1); \
- mean0 += w; \
- mean1[0] += (double)temp_color[0] * w; \
- mean1[1] += (double)temp_color[1] * w; \
- mean1[2] += (double)temp_color[2] * w; \
- mean1[3] += (double)temp_color[3] * w; \
- (void)0
-
-/* write blurred values to image */
-#define UPDATE_OUTPUT_C3 \
- mean0 = 1.0 / mean0; \
- dest[x * pix + 0] = mean1[0] * mean0; \
- dest[x * pix + 1] = mean1[1] * mean0; \
- dest[x * pix + 2] = mean1[2] * mean0; \
- dest[x * pix + 3] = mean1[3] * mean0; \
- (void)0
-
-/* initializes deltas for fast access to neighbor pixels */
-#define INIT_3X3_DELTAS(deltas, step, nch) \
- ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \
- (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \
- (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \
- (deltas)[6] = (step), (deltas)[7] = (step) + (nch)); \
- (void)0
-
-
-/* code of this node was heavily inspired by the smooth function of opencv library.
- * The main change is an optional image input */
-static void node_composit_exec_bilateralblur(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- NodeBilateralBlurData *nbbd = node->storage;
- CompBuf *new, *source, *img = in[0]->data, *refimg = in[1]->data;
- double mean0, w, i2sigma_color, i2sigma_space;
- double mean1[4];
- double weight_tab[8];
- float *src, *dest, *ref, *temp_color, *ref_color;
- float sigma_color, sigma_space;
- int imgx, imgy, x, y, pix, i, step;
- int deltas[8];
- short found_determinator = 0;
-
- if (img == NULL || out[0]->hasoutput == 0)
- return;
-
- if (img->type != CB_RGBA) {
- img = typecheck_compbuf(in[0]->data, CB_RGBA);
- }
-
- imgx = img->x;
- imgy = img->y;
- pix = img->type;
- step = pix * imgx;
-
- if (refimg) {
- if (refimg->x == imgx && refimg->y == imgy) {
- if (ELEM3(refimg->type, CB_VAL, CB_VEC2, CB_VEC3)) {
- refimg = typecheck_compbuf(in[1]->data, CB_RGBA);
- found_determinator = 1;
- }
- }
- }
- else {
- refimg = img;
- }
-
- /* allocs */
- source = dupalloc_compbuf(img);
- new = alloc_compbuf(imgx, imgy, pix, 1);
-
- /* accept image offsets from other nodes */
- new->xof = img->xof;
- new->yof = img->yof;
-
- /* bilateral code properties */
- sigma_color = nbbd->sigma_color;
- sigma_space = nbbd->sigma_space;
-
- i2sigma_color = 1.0f / (sigma_color * sigma_color);
- i2sigma_space = 1.0f / (sigma_space * sigma_space);
-
- INIT_3X3_DELTAS(deltas, step, pix);
-
- weight_tab[0] = weight_tab[2] = weight_tab[4] = weight_tab[6] = i2sigma_space;
- weight_tab[1] = weight_tab[3] = weight_tab[5] = weight_tab[7] = i2sigma_space * 2;
-
- /* iterations */
- for (i = 0; i < nbbd->iter; i++) {
- src = source->rect;
- ref = refimg->rect;
- dest = new->rect;
- /*goes through image, there are more loops for 1st/last line and all other lines*/
- /*kernel element accumulates surrounding colors, which are then written with the update_output function*/
- for (x = 0; x < imgx; x++, src += pix, ref += pix) {
- INIT_C3;
-
- KERNEL_ELEMENT_C3(6);
-
- if (x > 0) {
- KERNEL_ELEMENT_C3(5);
- KERNEL_ELEMENT_C3(4);
- }
-
- if (x < imgx - 1) {
- KERNEL_ELEMENT_C3(7);
- KERNEL_ELEMENT_C3(0);
- }
-
- UPDATE_OUTPUT_C3;
- }
-
- dest += step;
-
- for (y = 1; y < imgy - 1; y++, dest += step, src += pix, ref += pix) {
- x = 0;
-
- INIT_C3;
-
- KERNEL_ELEMENT_C3(0);
- KERNEL_ELEMENT_C3(1);
- KERNEL_ELEMENT_C3(2);
- KERNEL_ELEMENT_C3(6);
- KERNEL_ELEMENT_C3(7);
-
- UPDATE_OUTPUT_C3;
-
- src += pix;
- ref += pix;
-
- for (x = 1; x < imgx - 1; x++, src += pix, ref += pix) {
- INIT_C3;
-
- KERNEL_ELEMENT_C3(0);
- KERNEL_ELEMENT_C3(1);
- KERNEL_ELEMENT_C3(2);
- KERNEL_ELEMENT_C3(3);
- KERNEL_ELEMENT_C3(4);
- KERNEL_ELEMENT_C3(5);
- KERNEL_ELEMENT_C3(6);
- KERNEL_ELEMENT_C3(7);
-
- UPDATE_OUTPUT_C3;
- }
-
- INIT_C3;
-
- KERNEL_ELEMENT_C3(2);
- KERNEL_ELEMENT_C3(3);
- KERNEL_ELEMENT_C3(4);
- KERNEL_ELEMENT_C3(5);
- KERNEL_ELEMENT_C3(6);
-
- UPDATE_OUTPUT_C3;
- }
-
- for (x = 0; x < imgx; x++, src += pix, ref += pix) {
- INIT_C3;
-
- KERNEL_ELEMENT_C3(2);
-
- if (x > 0) {
- KERNEL_ELEMENT_C3(3);
- KERNEL_ELEMENT_C3(4);
- }
- if (x < imgx - 1) {
- KERNEL_ELEMENT_C3(1);
- KERNEL_ELEMENT_C3(0);
- }
-
- UPDATE_OUTPUT_C3;
- }
-
- if (node->exec & NODE_BREAK) break;
-
- SWAP(CompBuf, *source, *new);
- }
-
- if (img != in[0]->data)
- free_compbuf(img);
-
- if (found_determinator == 1) {
- if (refimg != in[1]->data)
- free_compbuf(refimg);
- }
-
- out[0]->data = source;
-
- free_compbuf(new);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeBilateralBlurData *nbbd = MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data");
@@ -272,12 +57,8 @@ void register_node_type_cmp_bilateralblur(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_BILATERALBLUR, "Bilateral Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_bilateralblur_in, cmp_node_bilateralblur_out);
- node_type_size(&ntype, 150, 120, 200);
node_type_init(&ntype, node_composit_init_bilateralblur);
node_type_storage(&ntype, "NodeBilateralBlurData", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_bilateralblur);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.c b/source/blender/nodes/composite/nodes/node_composite_blur.c
index eb7f7763afb..20fce05a40e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_blur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_blur.c
@@ -44,686 +44,6 @@ static bNodeSocketTemplate cmp_node_blur_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static float *make_gausstab(int filtertype, int rad)
-{
- float *gausstab, sum, val;
- int i, n;
-
- n = 2 * rad + 1;
-
- gausstab = (float *) MEM_mallocN(n * sizeof(float), "gauss");
-
- sum = 0.0f;
- for (i = -rad; i <= rad; i++) {
- val = RE_filter_value(filtertype, (float)i / (float)rad);
- sum += val;
- gausstab[i + rad] = val;
- }
-
- sum = 1.0f / sum;
- for (i = 0; i < n; i++)
- gausstab[i] *= sum;
-
- return gausstab;
-}
-
-static float *make_bloomtab(int rad)
-{
- float *bloomtab, val;
- int i, n;
-
- n = 2 * rad + 1;
-
- bloomtab = (float *) MEM_mallocN(n * sizeof(float), "bloom");
-
- for (i = -rad; i <= rad; i++) {
- val = powf(1.0f - fabsf((float)i) / ((float)rad), 4.0f);
- bloomtab[i + rad] = val;
- }
-
- return bloomtab;
-}
-
-/* both input images of same type, either 4 or 1 channel */
-static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float scale)
-{
- NodeBlurData *nbd = node->storage;
- CompBuf *work;
- register float sum, val;
- float rval, gval, bval, aval;
- float *gausstab, *gausstabcent;
- int rad, imgx = img->x, imgy = img->y;
- int x, y, pix = img->type;
- int i, bigstep;
- float *src, *dest;
-
- /* helper image */
- work = alloc_compbuf(imgx, imgy, img->type, 1); /* allocs */
-
- /* horizontal */
- if (nbd->sizex == 0) {
- memcpy(work->rect, img->rect, sizeof(float) * img->type * imgx * imgy);
- }
- else {
- rad = scale * (float)nbd->sizex;
- if (rad > imgx / 2)
- rad = imgx / 2;
- else if (rad < 1)
- rad = 1;
-
- gausstab = make_gausstab(nbd->filtertype, rad);
- gausstabcent = gausstab + rad;
-
- for (y = 0; y < imgy; y++) {
- float *srcd = img->rect + pix * (y * img->x);
-
- dest = work->rect + pix * (y * img->x);
-
- for (x = 0; x < imgx; x++) {
- int minr = x - rad < 0 ? -x : -rad;
- int maxr = x + rad > imgx ? imgx - x : rad;
-
- src = srcd + pix * (x + minr);
-
- sum = gval = rval = bval = aval = 0.0f;
- for (i = minr; i < maxr; i++) {
- val = gausstabcent[i];
- sum += val;
- rval += val * (*src++);
- if (pix == 4) {
- gval += val * (*src++);
- bval += val * (*src++);
- aval += val * (*src++);
- }
- }
- sum = 1.0f / sum;
- *dest++ = rval * sum;
- if (pix == 4) {
- *dest++ = gval * sum;
- *dest++ = bval * sum;
- *dest++ = aval * sum;
- }
- }
- if (node->exec & NODE_BREAK)
- break;
- }
-
- /* vertical */
- MEM_freeN(gausstab);
- }
-
- if (nbd->sizey == 0) {
- memcpy(new->rect, work->rect, sizeof(float) * img->type * imgx * imgy);
- }
- else {
- rad = scale * (float)nbd->sizey;
- if (rad > imgy / 2)
- rad = imgy / 2;
- else if (rad < 1)
- rad = 1;
-
- gausstab = make_gausstab(nbd->filtertype, rad);
- gausstabcent = gausstab + rad;
-
- bigstep = pix * imgx;
- for (x = 0; x < imgx; x++) {
- float *srcd = work->rect + pix * x;
-
- dest = new->rect + pix * x;
-
- for (y = 0; y < imgy; y++) {
- int minr = y - rad < 0 ? -y : -rad;
- int maxr = y + rad > imgy ? imgy - y : rad;
-
- src = srcd + bigstep * (y + minr);
-
- sum = gval = rval = bval = aval = 0.0f;
- for (i = minr; i < maxr; i++) {
- val = gausstabcent[i];
- sum += val;
- rval += val * src[0];
- if (pix == 4) {
- gval += val * src[1];
- bval += val * src[2];
- aval += val * src[3];
- }
- src += bigstep;
- }
- sum = 1.0f / sum;
- dest[0] = rval * sum;
- if (pix == 4) {
- dest[1] = gval * sum;
- dest[2] = bval * sum;
- dest[3] = aval * sum;
- }
- dest += bigstep;
- }
- if (node->exec & NODE_BREAK)
- break;
- }
- MEM_freeN(gausstab);
- }
-
- free_compbuf(work);
-}
-
-/* reference has to be mapped 0-1, and equal in size */
-static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *UNUSED(ref), float UNUSED(fac), NodeBlurData *nbd)
-{
- CompBuf *wbuf;
- register float val;
- float radxf, radyf;
- float **maintabs;
- float *gausstabx, *gausstabcenty;
- float *gausstaby, *gausstabcentx;
- int radx, rady, imgx = img->x, imgy = img->y;
- int x, y;
- int i, j;
- float *src, *dest, *wb;
-
- wbuf = alloc_compbuf(imgx, imgy, CB_VAL, 1);
-
- /* horizontal */
- radx = (float)nbd->sizex;
- if (radx > imgx / 2)
- radx = imgx / 2;
- else if (radx < 1)
- radx = 1;
-
- /* vertical */
- rady = (float)nbd->sizey;
- if (rady > imgy / 2)
- rady = imgy / 2;
- else if (rady < 1)
- rady = 1;
-
- x = MAX2(radx, rady);
- maintabs = MEM_mallocN(x * sizeof(void *), "gauss array");
- for (i = 0; i < x; i++)
- maintabs[i] = make_bloomtab(i + 1);
-
- /* vars to store before we go */
-// refd= ref->rect;
- src = img->rect;
-
- radxf = (float)radx;
- radyf = (float)rady;
-
- for (y = 0; y < imgy; y++) {
- for (x = 0; x < imgx; x++, src += 4) { //, refd++) {
-
-// int refradx= (int)(refd[0]*radxf);
-// int refrady= (int)(refd[0]*radyf);
-
- int refradx = (int)(radxf * 0.3f * src[3] * (src[0] + src[1] + src[2]));
- int refrady = (int)(radyf * 0.3f * src[3] * (src[0] + src[1] + src[2]));
-
- if (refradx > radx) refradx = radx;
- else if (refradx < 1) refradx = 1;
- if (refrady > rady) refrady = rady;
- else if (refrady < 1) refrady = 1;
-
- if (refradx == 1 && refrady == 1) {
- wb = wbuf->rect + (y * imgx + x);
- dest = new->rect + 4 * (y * imgx + x);
- wb[0] += 1.0f;
- dest[0] += src[0];
- dest[1] += src[1];
- dest[2] += src[2];
- dest[3] += src[3];
- }
- else {
- int minxr = x - refradx < 0 ? -x : -refradx;
- int maxxr = x + refradx > imgx ? imgx - x : refradx;
- int minyr = y - refrady < 0 ? -y : -refrady;
- int maxyr = y + refrady > imgy ? imgy - y : refrady;
-
- float *destd = new->rect + 4 * ( (y + minyr) * imgx + x + minxr);
- float *wbufd = wbuf->rect + ( (y + minyr) * imgx + x + minxr);
-
- gausstabx = maintabs[refradx - 1];
- gausstabcentx = gausstabx + refradx;
- gausstaby = maintabs[refrady - 1];
- gausstabcenty = gausstaby + refrady;
-
- for (i = minyr; i < maxyr; i++, destd += 4 * imgx, wbufd += imgx) {
- dest = destd;
- wb = wbufd;
- for (j = minxr; j < maxxr; j++, dest += 4, wb++) {
-
- val = gausstabcenty[i] * gausstabcentx[j];
- wb[0] += val;
- dest[0] += val * src[0];
- dest[1] += val * src[1];
- dest[2] += val * src[2];
- dest[3] += val * src[3];
- }
- }
- }
- }
- }
-
- x = imgx * imgy;
- dest = new->rect;
- wb = wbuf->rect;
- while (x--) {
- val = 1.0f / wb[0];
- dest[0] *= val;
- dest[1] *= val;
- dest[2] *= val;
- dest[3] *= val;
- wb++;
- dest += 4;
- }
-
- free_compbuf(wbuf);
-
- x = MAX2(radx, rady);
- for (i = 0; i < x; i++)
- MEM_freeN(maintabs[i]);
- MEM_freeN(maintabs);
-
-}
-
-#if 0
-static float hexagon_filter(float fi, float fj)
-{
- fi = fabs(fi);
- fj = fabs(fj);
-
- if (fj > 0.33f) {
- fj = (fj - 0.33f) / 0.66f;
- if (fi + fj > 1.0f)
- return 0.0f;
- else
- return 1.0f;
- }
- else return 1.0f;
-}
-#endif
-
-/* uses full filter, no horizontal/vertical optimize possible */
-/* both images same type, either 1 or 4 channels */
-static void bokeh_single_image(bNode *node, CompBuf *new, CompBuf *img, float fac)
-{
- NodeBlurData *nbd = node->storage;
- register float val;
- float radxf, radyf;
- float *gausstab, *dgauss;
- int radx, rady, imgx = img->x, imgy = img->y;
- int x, y, pix = img->type;
- int i, j, n;
- float *src = NULL, *dest, *srcd = NULL;
-
- /* horizontal */
- radxf = fac * (float)nbd->sizex;
- if (radxf > imgx / 2.0f)
- radxf = imgx / 2.0f;
- else if (radxf < 1.0f)
- radxf = 1.0f;
-
- /* vertical */
- radyf = fac * (float)nbd->sizey;
- if (radyf > imgy / 2.0f)
- radyf = imgy / 2.0f;
- else if (radyf < 1.0f)
- radyf = 1.0f;
-
- radx = ceil(radxf);
- rady = ceil(radyf);
-
- n = (2 * radx + 1) * (2 * rady + 1);
-
- /* create a full filter image */
- gausstab = MEM_mallocN(sizeof(float) * n, "filter tab");
- dgauss = gausstab;
- val = 0.0f;
- for (j = -rady; j <= rady; j++) {
- for (i = -radx; i <= radx; i++, dgauss++) {
- float fj = (float)j / radyf;
- float fi = (float)i / radxf;
- float dist = sqrt(fj * fj + fi * fi);
-
- // *dgauss= hexagon_filter(fi, fj);
- *dgauss = RE_filter_value(nbd->filtertype, dist);
-
- val += *dgauss;
- }
- }
-
- if (val != 0.0f) {
- val = 1.0f / val;
- for (j = n - 1; j >= 0; j--)
- gausstab[j] *= val;
- }
- else gausstab[4] = 1.0f;
-
- for (y = -rady + 1; y < imgy + rady - 1; y++) {
-
- if (y <= 0) srcd = img->rect;
- else if (y < imgy) srcd += pix * imgx;
- else srcd = img->rect + pix * (imgy - 1) * imgx;
-
- for (x = -radx + 1; x < imgx + radx - 1; x++) {
- int minxr = x - radx < 0 ? -x : -radx;
- int maxxr = x + radx >= imgx ? imgx - x - 1 : radx;
- int minyr = y - rady < 0 ? -y : -rady;
- int maxyr = y + rady > imgy - 1 ? imgy - y - 1 : rady;
-
- float *destd = new->rect + pix * ( (y + minyr) * imgx + x + minxr);
- float *dgausd = gausstab + (minyr + rady) * (2 * radx + 1) + minxr + radx;
-
- if (x <= 0) src = srcd;
- else if (x < imgx) src += pix;
- else src = srcd + pix * (imgx - 1);
-
- for (i = minyr; i <= maxyr; i++, destd += pix * imgx, dgausd += 2 * radx + 1) {
- dest = destd;
- dgauss = dgausd;
- for (j = minxr; j <= maxxr; j++, dest += pix, dgauss++) {
- val = *dgauss;
- if (val != 0.0f) {
- dest[0] += val * src[0];
- if (pix > 1) {
- dest[1] += val * src[1];
- dest[2] += val * src[2];
- dest[3] += val * src[3];
- }
- }
- }
- }
- }
- if (node->exec & NODE_BREAK)
- break;
- }
-
- MEM_freeN(gausstab);
-}
-
-
-/* reference has to be mapped 0-1, and equal in size */
-static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf *ref)
-{
- NodeBlurData *nbd = node->storage;
- CompBuf *blurbuf, *ref_use;
- register float sum, val;
- float rval, gval, bval, aval, radxf, radyf;
- float **maintabs;
- float *gausstabx, *gausstabcenty;
- float *gausstaby, *gausstabcentx;
- int radx, rady, imgx = img->x, imgy = img->y;
- int x, y, pix = img->type;
- int i, j;
- float *src, *dest, *refd, *blurd;
- float defcol[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* default color for compbuf_get_pixel */
- float proccol[4]; /* local color if compbuf is procedural */
- int refradx, refrady;
-
- if (ref->x != img->x || ref->y != img->y)
- return;
-
- ref_use = typecheck_compbuf(ref, CB_VAL);
-
- /* trick is; we blur the reference image... but only works with clipped values*/
- blurbuf = alloc_compbuf(imgx, imgy, CB_VAL, 1);
- blurbuf->xof = ref_use->xof;
- blurbuf->yof = ref_use->yof;
- blurd = blurbuf->rect;
- refd = ref_use->rect;
- for (x = imgx * imgy; x > 0; x--, refd++, blurd++) {
- if (refd[0] < 0.0f) blurd[0] = 0.0f;
- else if (refd[0] > 1.0f) blurd[0] = 1.0f;
- else blurd[0] = refd[0];
- }
-
- blur_single_image(node, blurbuf, blurbuf, 1.0f);
-
- /* horizontal */
- radx = (float)nbd->sizex;
- if (radx > imgx / 2)
- radx = imgx / 2;
- else if (radx < 1)
- radx = 1;
-
- /* vertical */
- rady = (float)nbd->sizey;
- if (rady > imgy / 2)
- rady = imgy / 2;
- else if (rady < 1)
- rady = 1;
-
- x = MAX2(radx, rady);
- maintabs = MEM_mallocN(x * sizeof(void *), "gauss array");
- for (i = 0; i < x; i++)
- maintabs[i] = make_gausstab(nbd->filtertype, i + 1);
-
- dest = new->rect;
- radxf = (float)radx;
- radyf = (float)rady;
-
- for (y = 0; y < imgy; y++) {
- for (x = 0; x < imgx; x++, dest += pix) {
- refd = compbuf_get_pixel(blurbuf, defcol, proccol, x - blurbuf->xrad, y - blurbuf->yrad, blurbuf->xrad, blurbuf->yrad);
- refradx = (int)(refd[0] * radxf);
- refrady = (int)(refd[0] * radyf);
-
- if (refradx > radx) refradx = radx;
- else if (refradx < 1) refradx = 1;
- if (refrady > rady) refrady = rady;
- else if (refrady < 1) refrady = 1;
-
- if (refradx == 1 && refrady == 1) {
- src = img->rect + pix * (y * imgx + x);
- if (pix == 1)
- dest[0] = src[0];
- else
- copy_v4_v4(dest, src);
- }
- else {
- int minxr = x - refradx < 0 ? -x : -refradx;
- int maxxr = x + refradx > imgx ? imgx - x : refradx;
- int minyr = y - refrady < 0 ? -y : -refrady;
- int maxyr = y + refrady > imgy ? imgy - y : refrady;
-
- float *srcd = img->rect + pix * ( (y + minyr) * imgx + x + minxr);
-
- gausstabx = maintabs[refradx - 1];
- gausstabcentx = gausstabx + refradx;
- gausstaby = maintabs[refrady - 1];
- gausstabcenty = gausstaby + refrady;
-
- sum = gval = rval = bval = aval = 0.0f;
-
- for (i = minyr; i < maxyr; i++, srcd += pix * imgx) {
- src = srcd;
- for (j = minxr; j < maxxr; j++, src += pix) {
-
- val = gausstabcenty[i] * gausstabcentx[j];
- sum += val;
- rval += val * src[0];
- if (pix > 1) {
- gval += val * src[1];
- bval += val * src[2];
- aval += val * src[3];
- }
- }
- }
- sum = 1.0f / sum;
- dest[0] = rval * sum;
- if (pix > 1) {
- dest[1] = gval * sum;
- dest[2] = bval * sum;
- dest[3] = aval * sum;
- }
- }
- }
- if (node->exec & NODE_BREAK)
- break;
- }
-
- free_compbuf(blurbuf);
-
- x = MAX2(radx, rady);
- for (i = 0; i < x; i++)
- MEM_freeN(maintabs[i]);
- MEM_freeN(maintabs);
-
- if (ref_use != ref)
- free_compbuf(ref_use);
-}
-
-static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *new, *img = in[0]->data;
- NodeBlurData *nbd = node->storage;
-
- if (img == NULL) return;
-
- /* store image in size that is needed for absolute/relative conversions on ui level */
- nbd->image_in_width = img->x;
- nbd->image_in_height = img->y;
-
- if (out[0]->hasoutput == 0) return;
-
- if (nbd->relative) {
- if (nbd->aspect == CMP_NODE_BLUR_ASPECT_NONE) {
- nbd->sizex = (int)(nbd->percentx * 0.01f * nbd->image_in_width);
- nbd->sizey = (int)(nbd->percenty * 0.01f * nbd->image_in_height);
- }
- else if (nbd->aspect == CMP_NODE_BLUR_ASPECT_Y) {
- nbd->sizex = (int)(nbd->percentx * 0.01f * nbd->image_in_width);
- nbd->sizey = (int)(nbd->percenty * 0.01f * nbd->image_in_width);
- }
- else if (nbd->aspect == CMP_NODE_BLUR_ASPECT_X) {
- nbd->sizex = (int)(nbd->percentx * 0.01f * nbd->image_in_height);
- nbd->sizey = (int)(nbd->percenty * 0.01f * nbd->image_in_height);
- }
- }
-
- if (nbd->sizex == 0 && nbd->sizey == 0) {
- new = pass_on_compbuf(img);
- out[0]->data = new;
- }
- else if (nbd->filtertype == R_FILTER_FAST_GAUSS) {
- if (in[1]->vec[0] < 0.001f) { /* time node inputs can be a tiny value */
- new = pass_on_compbuf(img);
- }
- else {
- // TODO: can this be mapped with reference, too?
- const float sx = ((float)nbd->sizex * in[1]->vec[0]) / 2.0f, sy = ((float)nbd->sizey * in[1]->vec[0]) / 2.0f;
- int c;
-
- if ((img == NULL) || (out[0]->hasoutput == 0)) return;
-
- if (img->type == CB_VEC2)
- new = typecheck_compbuf(img, CB_VAL);
- else if (img->type == CB_VEC3)
- new = typecheck_compbuf(img, CB_RGBA);
- else
- new = dupalloc_compbuf(img);
-
- if ((sx == sy) && (sx > 0.f)) {
- for (c = 0; c < new->type; ++c)
- IIR_gauss(new, sx, c, 3);
- }
- else {
- if (sx > 0.f) {
- for (c = 0; c < new->type; ++c)
- IIR_gauss(new, sx, c, 1);
- }
- if (sy > 0.f) {
- for (c = 0; c < new->type; ++c)
- IIR_gauss(new, sy, c, 2);
- }
- }
- }
- out[0]->data = new;
- }
- else {
- /* All non fast gauss blur methods */
- if (img->type == CB_VEC2 || img->type == CB_VEC3) {
- img = typecheck_compbuf(in[0]->data, CB_RGBA);
- }
-
- /* if fac input, we do it different */
- if (in[1]->data) {
- CompBuf *gammabuf;
-
- /* make output size of input image */
- new = alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */
-
- /* accept image offsets from other nodes */
- new->xof = img->xof;
- new->yof = img->yof;
-
- if (nbd->gamma) {
- gammabuf = dupalloc_compbuf(img);
- gamma_correct_compbuf(gammabuf, 0);
- }
- else gammabuf = img;
-
- blur_with_reference(node, new, gammabuf, in[1]->data);
-
- if (nbd->gamma) {
- gamma_correct_compbuf(new, 1);
- free_compbuf(gammabuf);
- }
- if (node->exec & NODE_BREAK) {
- free_compbuf(new);
- new = NULL;
- }
- out[0]->data = new;
- }
- else {
-
- if (in[1]->vec[0] <= 0.001f) { /* time node inputs can be a tiny value */
- new = pass_on_compbuf(img);
- }
- else {
- CompBuf *gammabuf;
-
- /* make output size of input image */
- new = alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */
-
- /* accept image offsets from other nodes */
- new->xof = img->xof;
- new->yof = img->yof;
-
- if (nbd->gamma) {
- gammabuf = dupalloc_compbuf(img);
- gamma_correct_compbuf(gammabuf, 0);
- }
- else gammabuf = img;
-
- if (nbd->bokeh)
- bokeh_single_image(node, new, gammabuf, in[1]->vec[0]);
- else if (1)
- blur_single_image(node, new, gammabuf, in[1]->vec[0]);
- else /* bloom experimental... */
- bloom_with_reference(new, gammabuf, NULL, in[1]->vec[0], nbd);
-
- if (nbd->gamma) {
- gamma_correct_compbuf(new, 1);
- free_compbuf(gammabuf);
- }
- if (node->exec & NODE_BREAK) {
- free_compbuf(new);
- new = NULL;
- }
- }
- out[0]->data = new;
- }
- if (img != in[0]->data)
- free_compbuf(img);
- }
-
- generate_preview(data, node, out[0]->data);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_blur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeBlurData *data = MEM_callocN(sizeof(NodeBlurData), "node blur data");
@@ -737,12 +57,8 @@ void register_node_type_cmp_blur(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_BLUR, "Blur", NODE_CLASS_OP_FILTER, NODE_PREVIEW | NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_blur_in, cmp_node_blur_out);
- node_type_size(&ntype, 120, 80, 200);
node_type_init(&ntype, node_composit_init_blur);
node_type_storage(&ntype, "NodeBlurData", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_blur);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c
index 222ac7a5cdf..ea3162a9e55 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c
@@ -61,7 +61,6 @@ void register_node_type_cmp_bokehblur(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_BOKEHBLUR, "Bokeh Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_bokehblur_in, cmp_node_bokehblur_out);
- node_type_size(&ntype, 120, 80, 200);
node_type_init(&ntype, node_composit_init_bokehblur);
nodeRegisterType(ttype, &ntype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehimage.c b/source/blender/nodes/composite/nodes/node_composite_bokehimage.c
index 8324b77b2d1..b006280ca8a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bokehimage.c
+++ b/source/blender/nodes/composite/nodes/node_composite_bokehimage.c
@@ -36,7 +36,7 @@
#include "../node_composite_util.h"
/* **************** Bokeh image Tools ******************** */
-
+
static bNodeSocketTemplate cmp_node_bokehimage_out[] = {
{ SOCK_RGBA, 0, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ -1, 0, "" }
@@ -58,7 +58,6 @@ void register_node_type_cmp_bokehimage(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_BOKEHIMAGE, "Bokeh Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_bokehimage_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_bokehimage);
node_type_storage(&ntype, "NodeBokehImage", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.c b/source/blender/nodes/composite/nodes/node_composite_boxmask.c
index d3c6b2ccef0..eb2c58894f3 100644
--- a/source/blender/nodes/composite/nodes/node_composite_boxmask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.c
@@ -61,7 +61,6 @@ void register_node_type_cmp_boxmask(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MASK_BOX, "Box Mask", NODE_CLASS_MATTE, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_boxmask_in, cmp_node_boxmask_out);
- node_type_size(&ntype, 260, 110, 300);
node_type_init(&ntype, node_composit_init_boxmask);
node_type_storage(&ntype, "NodeBoxMask", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_brightness.c b/source/blender/nodes/composite/nodes/node_composite_brightness.c
index ecf572f59c7..025f5c03c7c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_brightness.c
+++ b/source/blender/nodes/composite/nodes/node_composite_brightness.c
@@ -47,54 +47,6 @@ static bNodeSocketTemplate cmp_node_brightcontrast_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_brightnesscontrast(bNode *UNUSED(node), float *out, float *in, float *in_brightness, float *in_contrast)
-{
- float i;
- int c;
- float a, b, v;
- float brightness = (*in_brightness) / 100.0f;
- float contrast = *in_contrast;
- float delta = contrast / 200.0f;
- a = 1.0f - delta * 2.0f;
- /*
- * The algorithm is by Werner D. Streidt
- * (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
- */
- if (contrast > 0) {
- a = 1.0f / a;
- b = a * (brightness - delta);
- }
- else {
- delta *= -1;
- b = a * (brightness + delta);
- }
-
- for (c=0; c<3; c++) {
- i = in[c];
- v = a*i + b;
- out[c] = v;
- }
-}
-
-static void node_composit_exec_brightcontrast(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (out[0]->hasoutput==0)
- return;
-
- if (in[0]->data) {
- CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
- stackbuf= dupalloc_compbuf(cbuf);
- composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, do_brightnesscontrast, CB_RGBA, CB_VAL, CB_VAL);
- out[0]->data = stackbuf;
- if (cbuf != in[0]->data)
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
void register_node_type_cmp_brightcontrast(bNodeTreeType *ttype)
{
@@ -102,10 +54,6 @@ void register_node_type_cmp_brightcontrast(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_brightcontrast_in, cmp_node_brightcontrast_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_brightcontrast);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_channelMatte.c b/source/blender/nodes/composite/nodes/node_composite_channelMatte.c
index 40dbbbb8dca..acb0566be7c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_channelMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_channelMatte.c
@@ -34,164 +34,17 @@
/* ******************* Channel Matte Node ********************************* */
-static bNodeSocketTemplate cmp_node_channel_matte_in[] ={
+static bNodeSocketTemplate cmp_node_channel_matte_in[] = {
{SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f},
{-1, 0, ""}
};
-static bNodeSocketTemplate cmp_node_channel_matte_out[] ={
+static bNodeSocketTemplate cmp_node_channel_matte_out[] = {
{SOCK_RGBA, 0, N_("Image")},
{SOCK_FLOAT, 0, N_("Matte")},
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_normalized_rgba_to_ycca2(bNode *UNUSED(node), float *out, float *in)
-{
- /*normalize to the range 0.0 to 1.0) */
- rgb_to_ycc(in[0], in[1], in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);
- out[0]=(out[0])/255.0f;
- out[1]=(out[1])/255.0f;
- out[2]=(out[2])/255.0f;
- out[3]=in[3];
-}
-
-static void do_normalized_ycca_to_rgba2(bNode *UNUSED(node), float *out, float *in)
-{
- /*un-normalize the normalize from above */
- in[0]=in[0]*255.0f;
- in[1]=in[1]*255.0f;
- in[2]=in[2]*255.0f;
- ycc_to_rgb(in[0], in[1], in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);
- out[3]=in[3];
-}
-
-
-static void do_channel_matte(bNode *node, float *out, float *in)
-{
- NodeChroma *c=(NodeChroma *)node->storage;
- float alpha=0.0;
-
- switch (c->algorithm) {
- case 0: { /* Alpha=key_channel-limit channel */
- int key_channel=node->custom2-1;
- int limit_channel=c->channel-1;
- alpha=in[key_channel]-in[limit_channel];
- break;
- }
- case 1: { /* Alpha=G-MAX(R, B) */
- switch (node->custom2) {
- case 1:
- {
- alpha=in[0]-MAX2(in[1], in[2]);
- break;
- }
- case 2:
- {
- alpha=in[1]-MAX2(in[0], in[2]);
- break;
- }
- case 3:
- {
- alpha=in[2]-MAX2(in[0], in[1]);
- break;
- }
- default:
- break;
- }
- break;
- }
- default:
- break;
- }
-
- /*flip because 0.0 is transparent, not 1.0*/
- alpha=1-alpha;
-
- /* test range*/
- if (alpha>c->t1) {
- alpha=in[3]; /*whatever it was prior */
- }
- else if (alpha<c->t2) {
- alpha=0.0;
- }
- else {/*blend */
- alpha=(alpha-c->t2)/(c->t1-c->t2);
- }
-
-
- /* don't make something that was more transparent less transparent */
- if (alpha<in[3]) {
- out[3]=alpha;
- }
- else {
- out[3]=in[3];
- }
-}
-
-static void node_composit_exec_channel_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *cbuf;
- CompBuf *outbuf;
-
- if (in[0]->hasinput==0) return;
- if (in[0]->data==NULL) return;
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
-
- cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
-
- outbuf=dupalloc_compbuf(cbuf);
-
- /*convert to colorspace*/
- switch (node->custom1) {
- case CMP_NODE_CHANNEL_MATTE_CS_RGB:
- break;
- case CMP_NODE_CHANNEL_MATTE_CS_HSV: /*HSV*/
- composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_rgba_to_hsva, CB_RGBA);
- break;
- case CMP_NODE_CHANNEL_MATTE_CS_YUV: /*YUV*/
- composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_rgba_to_yuva, CB_RGBA);
- break;
- case CMP_NODE_CHANNEL_MATTE_CS_YCC: /*YCC*/
- composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_normalized_rgba_to_ycca2, CB_RGBA);
- break;
- default:
- break;
- }
-
- /*use the selected channel information to do the key */
- composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_channel_matte, CB_RGBA);
-
- /*convert back to RGB colorspace in place*/
- switch (node->custom1) {
- case CMP_NODE_CHANNEL_MATTE_CS_RGB: /*RGB*/
- break;
- case CMP_NODE_CHANNEL_MATTE_CS_HSV: /*HSV*/
- composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_hsva_to_rgba, CB_RGBA);
- break;
- case CMP_NODE_CHANNEL_MATTE_CS_YUV: /*YUV*/
- composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_yuva_to_rgba, CB_RGBA);
- break;
- case CMP_NODE_CHANNEL_MATTE_CS_YCC: /*YCC*/
- composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_normalized_ycca_to_rgba2, CB_RGBA);
- break;
- default:
- break;
- }
-
- generate_preview(data, node, outbuf);
- out[0]->data=outbuf;
- if (out[1]->hasoutput)
- out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
-
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_channel_matte(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
@@ -213,12 +66,8 @@ void register_node_type_cmp_channel_matte(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_CHANNEL_MATTE, "Channel Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_channel_matte_in, cmp_node_channel_matte_out);
- node_type_size(&ntype, 200, 80, 250);
node_type_init(&ntype, node_composit_init_channel_matte);
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_channel_matte);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c
index f343f806d57..29782c3bc51 100644
--- a/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c
@@ -45,136 +45,6 @@ static bNodeSocketTemplate cmp_node_chroma_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_rgba_to_ycca_normalized(bNode *UNUSED(node), float *out, float *in)
-{
- rgb_to_ycc(in[0], in[1], in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);
-
- //normalize to 0..1.0
- out[0]=out[0]/255.0f;
- out[1]=out[1]/255.0f;
- out[2]=out[2]/255.0f;
-
- //rescale to -1.0..1.0
- out[0]=(out[0]*2.0f)-1.0f;
- out[1]=(out[1]*2.0f)-1.0f;
- out[2]=(out[2]*2.0f)-1.0f;
-
- // out[0]=((out[0])-16)/255.0;
- // out[1]=((out[1])-128)/255.0;
- // out[2]=((out[2])-128)/255.0;
- out[3]=in[3];
-}
-
-static void do_ycca_to_rgba_normalized(bNode *UNUSED(node), float *out, float *in)
-{
- /*un-normalize the normalize from above */
- in[0]=(in[0]+1.0f)/2.0f;
- in[1]=(in[1]+1.0f)/2.0f;
- in[2]=(in[2]+1.0f)/2.0f;
-
- in[0]=(in[0]*255.0f);
- in[1]=(in[1]*255.0f);
- in[2]=(in[2]*255.0f);
-
- // in[0]=(in[0]*255.0)+16;
- // in[1]=(in[1]*255.0)+128;
- // in[2]=(in[2]*255.0)+128;
- ycc_to_rgb(in[0], in[1], in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);
- out[3]=in[3];
-}
-
-static void do_chroma_key(bNode *node, float *out, float *in)
-{
- NodeChroma *c;
- float x, z, alpha;
- float theta, beta, angle, angle2;
- float kfg;
-
- c=node->storage;
-
- /* Algorithm from book "Video Demistified," does not include the spill reduction part */
-
- /* find theta, the angle that the color space should be rotated based on key chroma values*/
- theta=atan2(c->key[2], c->key[1]);
-
- /*rotate the cb and cr into x/z space */
- x=in[1]*cosf(theta)+in[2]*sinf(theta);
- z=in[2]*cosf(theta)-in[1]*sinf(theta);
-
- /*if within the acceptance angle */
- angle=c->t1; /* t1 is radians. */
-
- /* if kfg is <0 then the pixel is outside of the key color */
- kfg= x-(fabsf(z)/tanf(angle/2.0f));
-
- copy_v3_v3(out, in);
-
- if (kfg>0.0f) { /* found a pixel that is within key color */
- beta=atan2(z, x);
- angle2=c->t2; /* t2 is radians. */
-
- /* if beta is within the cutoff angle */
- if (fabsf(beta) < (angle2/2.0f)) {
- alpha=0.0;
- }
- else {
- alpha=1.0f-(kfg/c->fstrength);
- }
-
- /* don't make something that was more transparent less transparent */
- if (alpha<in[3]) {
- out[3]=alpha;
- }
- else {
- out[3]=in[3];
- }
- }
- else { /* make pixel just as transparent as it was before */
- out[3]=in[3];
- }
-}
-
-static void node_composit_exec_chroma_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *cbuf;
- CompBuf *chromabuf;
- NodeChroma *c;
-
- if (in[0]->hasinput==0) return;
- if (in[0]->data==NULL) return;
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
-
- cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
-
- chromabuf= dupalloc_compbuf(cbuf);
-
- c=node->storage;
-
- /*convert rgbbuf to normalized chroma space*/
- composit1_pixel_processor(node, chromabuf, cbuf, in[0]->vec, do_rgba_to_ycca_normalized, CB_RGBA);
- /*convert key to normalized chroma color space */
- do_rgba_to_ycca_normalized(node, c->key, in[1]->vec);
-
- /*per pixel chroma key*/
- composit1_pixel_processor(node, chromabuf, chromabuf, in[0]->vec, do_chroma_key, CB_RGBA);
-
- /*convert back*/
- composit1_pixel_processor(node, chromabuf, chromabuf, in[0]->vec, do_ycca_to_rgba_normalized, CB_RGBA);
-
- out[0]->data= chromabuf;
- if (out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(chromabuf, CHAN_A);
-
- generate_preview(data, node, chromabuf);
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_chroma_matte(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
@@ -192,12 +62,8 @@ void register_node_type_cmp_chroma_matte(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_CHROMA_MATTE, "Chroma Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_chroma_in, cmp_node_chroma_out);
- node_type_size(&ntype, 200, 80, 300);
node_type_init(&ntype, node_composit_init_chroma_matte);
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_chroma_matte);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorMatte.c b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c
index 07a6647d976..9905a2446b8 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c
@@ -45,77 +45,6 @@ static bNodeSocketTemplate cmp_node_color_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_color_key(bNode *node, float *out, float *in)
-{
- float h_wrap;
- NodeChroma *c;
- c=node->storage;
-
-
- copy_v3_v3(out, in);
-
- if (
- /* do hue last because it needs to wrap, and does some more checks */
-
- /* sat */ (fabsf(in[1]-c->key[1]) < c->t2) &&
- /* val */ (fabsf(in[2]-c->key[2]) < c->t3) &&
-
- /* multiply by 2 because it wraps on both sides of the hue,
- * otherwise 0.5 would key all hue's */
-
- /* hue */ ((h_wrap= 2.0f * fabsf(in[0]-c->key[0])) < c->t1 || (2.0f - h_wrap) < c->t1)
- ) {
- out[3]=0.0; /*make transparent*/
- }
-
- else { /*pixel is outside key color */
- out[3]=in[3]; /* make pixel just as transparent as it was before */
- }
-}
-
-static void node_composit_exec_color_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *cbuf;
- CompBuf *colorbuf;
- NodeChroma *c;
-
- if (in[0]->hasinput==0) return;
- if (in[0]->data==NULL) return;
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
-
- cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
-
- colorbuf= dupalloc_compbuf(cbuf);
-
- c=node->storage;
-
- /*convert rgbbuf to hsv*/
- composit1_pixel_processor(node, colorbuf, cbuf, in[0]->vec, do_rgba_to_hsva, CB_RGBA);
-
- /*convert key to hsv*/
- do_rgba_to_hsva(node, c->key, in[1]->vec);
-
-
- /*per pixel color key*/
- composit1_pixel_processor(node, colorbuf, colorbuf, in[0]->vec, do_color_key, CB_RGBA);
-
- /*convert back*/
- composit1_pixel_processor(node, colorbuf, colorbuf, in[0]->vec, do_hsva_to_rgba, CB_RGBA);
-
- out[0]->data= colorbuf;
- if (out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(colorbuf, CHAN_A);
-
- generate_preview(data, node, colorbuf);
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_color_matte(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node color");
@@ -133,12 +62,8 @@ void register_node_type_cmp_color_matte(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_COLOR_MATTE, "Color Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_color_in, cmp_node_color_out);
- node_type_size(&ntype, 200, 80, 300);
node_type_init(&ntype, node_composit_init_color_matte);
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_color_matte);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
index 44a5ac9e968..32fa446790e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
@@ -43,281 +43,6 @@ static bNodeSocketTemplate cmp_node_color_spill_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-#define AVG(a, b) ((a + b) / 2)
-
-
-static void do_simple_spillmap_red(bNode *node, float* out, float *in)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- out[0]=in[0]-( ncs->limscale * in[ncs->limchan] );
-}
-
-static void do_simple_spillmap_red_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
-
- out[0] = *fac * (in[0]-( ncs->limscale * in[ncs->limchan]));
-}
-
-static void do_simple_spillmap_green(bNode *node, float* out, float *in)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- out[0]=in[1]-( ncs->limscale * in[ncs->limchan] );
-}
-
-static void do_simple_spillmap_green_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
-
- out[0] = *fac * (in[1]-( ncs->limscale * in[ncs->limchan]));
-}
-
-static void do_simple_spillmap_blue(bNode *node, float* out, float *in)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- out[0]=in[2]-( ncs->limscale * in[ncs->limchan] );
-}
-
-static void do_simple_spillmap_blue_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
-
- out[0] = *fac * (in[2]-( ncs->limscale * in[ncs->limchan]));
-}
-
-static void do_average_spillmap_red(bNode *node, float* out, float *in)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- out[0]=in[0]-(ncs->limscale * AVG(in[1], in[2]) );
-}
-
-static void do_average_spillmap_red_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
-
- out[0] = *fac * (in[0]-(ncs->limscale * AVG(in[1], in[2]) ));
-}
-
-static void do_average_spillmap_green(bNode *node, float* out, float *in)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- out[0]=in[1]-(ncs->limscale * AVG(in[0], in[2]) );
-}
-
-static void do_average_spillmap_green_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
-
- out[0] = *fac * (in[0]-(ncs->limscale * AVG(in[0], in[2]) ));
-}
-
-static void do_average_spillmap_blue(bNode *node, float* out, float *in)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- out[0]=in[2]-(ncs->limscale * AVG(in[0], in[1]) );
-}
-
-static void do_average_spillmap_blue_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
-
- out[0] = *fac * (in[0]-(ncs->limscale * AVG(in[0], in[1]) ));
-}
-
-static void do_apply_spillmap_red(bNode *node, float* out, float *in, float *map)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- if (map[0]>0) {
- out[0]=in[0]-(ncs->uspillr*map[0]);
- out[1]=in[1]+(ncs->uspillg*map[0]);
- out[2]=in[2]+(ncs->uspillb*map[0]);
- }
- else {
- out[0]=in[0];
- out[1]=in[1];
- out[2]=in[2];
- }
-}
-
-static void do_apply_spillmap_green(bNode *node, float* out, float *in, float *map)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- if (map[0]>0) {
- out[0]=in[0]+(ncs->uspillr*map[0]);
- out[1]=in[1]-(ncs->uspillg*map[0]);
- out[2]=in[2]+(ncs->uspillb*map[0]);
- }
- else {
- out[0]=in[0];
- out[1]=in[1];
- out[2]=in[2];
- }
-}
-
-static void do_apply_spillmap_blue(bNode *node, float* out, float *in, float *map)
-{
- NodeColorspill *ncs;
- ncs=node->storage;
- if (map[0]>0) {
- out[0]=in[0]+(ncs->uspillr*map[0]);
- out[1]=in[1]+(ncs->uspillg*map[0]);
- out[2]=in[2]-(ncs->uspillb*map[0]);
- }
- else {
- out[0]=in[0];
- out[1]=in[1];
- out[2]=in[2];
- }
-}
-
-static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* Originally based on the information from the book "The Art and Science of Digital Composition" and
- * discussions from vfxtalk.com .*/
- CompBuf *cbuf;
- /* CompBuf *mask; */ /* UNUSED */
- CompBuf *rgbbuf;
- CompBuf *spillmap;
- NodeColorspill *ncs;
- ncs=node->storage;
-
- /* early out for missing connections */
- if (out[0]->hasoutput==0 ) return;
- if (in[0]->hasinput==0) return;
- if (in[0]->data==NULL) return;
-
- cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
- /* mask= */ /* UNUSED */ typecheck_compbuf(in[1]->data, CB_VAL);
- spillmap=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
- rgbbuf=dupalloc_compbuf(cbuf);
-
- switch (node->custom1) {
- case 1: /*red spill*/
- {
- switch (node->custom2) {
- case 0: /* simple limit */
- {
- if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_red, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_red_fac, CB_RGBA, CB_VAL);
- }
- break;
- }
- case 1: /* average limit */
- {
- if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_red, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_red_fac, CB_RGBA, CB_VAL);
- }
- break;
- }
- }
- if (ncs->unspill==0) {
- ncs->uspillr=1.0f;
- ncs->uspillg=0.0f;
- ncs->uspillb=0.0f;
- }
- composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_red, CB_RGBA, CB_VAL);
- break;
- }
- case 2: /*green spill*/
- {
- switch (node->custom2) {
- case 0: /* simple limit */
- {
- if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_green, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_green_fac, CB_RGBA, CB_VAL);
- }
- break;
- }
- case 1: /* average limit */
- {
- if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_green, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_green_fac, CB_RGBA, CB_VAL);
- }
- break;
- }
- }
- if (ncs->unspill==0) {
- ncs->uspillr=0.0f;
- ncs->uspillg=1.0f;
- ncs->uspillb=0.0f;
- }
- composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_green, CB_RGBA, CB_VAL);
- break;
- }
- case 3: /*blue spill*/
- {
- switch (node->custom2) {
- case 0: /* simple limit */
- {
- if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_blue, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_blue_fac, CB_RGBA, CB_VAL);
- }
- break;
- }
- case 1: /* average limit */
- {
- if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_blue, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_blue_fac, CB_RGBA, CB_VAL);
- }
- break;
- }
- }
- if (ncs->unspill==0) {
- ncs->uspillr=0.0f;
- ncs->uspillg=0.0f;
- ncs->uspillb=1.0f;
- }
- composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_blue, CB_RGBA, CB_VAL);
- break;
- }
- default:
- break;
- }
-
- out[0]->data=rgbbuf;
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
-
- free_compbuf(spillmap);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_color_spill(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeColorspill *ncs= MEM_callocN(sizeof(NodeColorspill), "node colorspill");
@@ -335,12 +60,8 @@ void register_node_type_cmp_color_spill(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_color_spill_in, cmp_node_color_spill_out);
- node_type_size(&ntype, 140, 80, 200);
node_type_init(&ntype, node_composit_init_color_spill);
node_type_storage(&ntype, "NodeColorspill", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_color_spill);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
index df49e537788..da9ce64d994 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
@@ -46,138 +46,6 @@ static bNodeSocketTemplate cmp_node_colorbalance_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* this function implements ASC-CDL according to the spec at http://www.asctech.org/
- * Slope
- * S = in * slope
- * Offset
- * O = S + offset
- * = (in * slope) + offset
- * Power
- * out = Clamp(O) ^ power
- * = Clamp((in * slope) + offset) ^ power
- */
-DO_INLINE float colorbalance_cdl(float in, float offset, float power, float slope)
-{
- float x = in * slope + offset;
-
- /* prevent NaN */
- CLAMP(x, 0.0f, 1.0f);
-
- return powf(x, power);
-}
-
-/* note: lift_lgg is just 2-lift, gamma_inv is 1.0/gamma */
-DO_INLINE float colorbalance_lgg(float in, float lift_lgg, float gamma_inv, float gain)
-{
- /* 1:1 match with the sequencer with linear/srgb conversions, the conversion isn't pretty
- * but best keep it this way, since testing for durian shows a similar calculation
- * without lin/srgb conversions gives bad results (over-saturated shadows) with colors
- * slightly below 1.0. some correction can be done but it ends up looking bad for shadows or lighter tones - campbell */
- float x= (((linearrgb_to_srgb(in) - 1.0f) * lift_lgg) + 1.0f) * gain;
-
- /* prevent NaN */
- if (x < 0.f) x = 0.f;
-
- return powf(srgb_to_linearrgb(x), gamma_inv);
-}
-
-static void do_colorbalance_cdl(bNode *node, float* out, float *in)
-{
- NodeColorBalance *n= (NodeColorBalance *)node->storage;
-
- out[0] = colorbalance_cdl(in[0], n->lift[0], n->gamma[0], n->gain[0]);
- out[1] = colorbalance_cdl(in[1], n->lift[1], n->gamma[1], n->gain[1]);
- out[2] = colorbalance_cdl(in[2], n->lift[2], n->gamma[2], n->gain[2]);
- out[3] = in[3];
-}
-
-static void do_colorbalance_cdl_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorBalance *n= (NodeColorBalance *)node->storage;
- const float mfac= 1.0f - *fac;
-
- out[0] = mfac*in[0] + *fac * colorbalance_cdl(in[0], n->lift[0], n->gamma[0], n->gain[0]);
- out[1] = mfac*in[1] + *fac * colorbalance_cdl(in[1], n->lift[1], n->gamma[1], n->gain[1]);
- out[2] = mfac*in[2] + *fac * colorbalance_cdl(in[2], n->lift[2], n->gamma[2], n->gain[2]);
- out[3] = in[3];
-}
-
-static void do_colorbalance_lgg(bNode *node, float* out, float *in)
-{
- NodeColorBalance *n= (NodeColorBalance *)node->storage;
-
- out[0] = colorbalance_lgg(in[0], n->lift_lgg[0], n->gamma_inv[0], n->gain[0]);
- out[1] = colorbalance_lgg(in[1], n->lift_lgg[1], n->gamma_inv[1], n->gain[1]);
- out[2] = colorbalance_lgg(in[2], n->lift_lgg[2], n->gamma_inv[2], n->gain[2]);
- out[3] = in[3];
-}
-
-static void do_colorbalance_lgg_fac(bNode *node, float* out, float *in, float *fac)
-{
- NodeColorBalance *n= (NodeColorBalance *)node->storage;
- const float mfac= 1.0f - *fac;
-
- out[0] = mfac*in[0] + *fac * colorbalance_lgg(in[0], n->lift_lgg[0], n->gamma_inv[0], n->gain[0]);
- out[1] = mfac*in[1] + *fac * colorbalance_lgg(in[1], n->lift_lgg[1], n->gamma_inv[1], n->gain[1]);
- out[2] = mfac*in[2] + *fac * colorbalance_lgg(in[2], n->lift_lgg[2], n->gamma_inv[2], n->gain[2]);
- out[3] = in[3];
-}
-
-static void node_composit_exec_colorbalance(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *cbuf= in[1]->data;
- CompBuf *stackbuf;
-
- /* stack order input: fac, image */
- /* stack order output: image */
- if (out[0]->hasoutput==0) return;
-
- if (in[0]->vec[0] == 0.f && in[0]->data == NULL) {
- out[0]->data = pass_on_compbuf(cbuf);
- return;
- }
-
- {
- NodeColorBalance *n= (NodeColorBalance *)node->storage;
- int c;
-
- for (c = 0; c < 3; c++) {
- n->lift_lgg[c] = 2.0f - n->lift[c];
- n->gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f/n->gamma[c] : 1000000.0f;
- }
- }
-
- if (cbuf) {
- stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* create output based on image input */
-
- if (node->custom1 == 0) {
- /* lift gamma gain */
- if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_colorbalance_lgg, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_colorbalance_lgg_fac, CB_RGBA, CB_VAL);
- }
- }
- else {
- /* offset/power/slope : ASC-CDL */
- if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f)) {
- composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_colorbalance_cdl, CB_RGBA);
- }
- else {
- composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_colorbalance_cdl_fac, CB_RGBA, CB_VAL);
- }
-
- }
-
- out[0]->data=stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_colorbalance(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeColorBalance *n= node->storage= MEM_callocN(sizeof(NodeColorBalance), "node colorbalance");
@@ -196,9 +64,6 @@ void register_node_type_cmp_colorbalance(bNodeTreeType *ttype)
node_type_size(&ntype, 400, 200, 400);
node_type_init(&ntype, node_composit_init_colorbalance);
node_type_storage(&ntype, "NodeColorBalance", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_colorbalance);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorcorrection.c b/source/blender/nodes/composite/nodes/node_composite_colorcorrection.c
index 526f8472992..19f2fad2e42 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorcorrection.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorcorrection.c
@@ -81,7 +81,7 @@ void register_node_type_cmp_colorcorrection(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_COLORCORRECTION, "Color Correction", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_colorcorrection_in, cmp_node_colorcorrection_out);
- node_type_size(&ntype, 400, 200, 500);
+ node_type_size(&ntype, 400, 200, 600);
node_type_init(&ntype, node_composit_init_colorcorrection);
node_type_storage(&ntype, "NodeColorCorrection", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c
index 10b81cdaaa0..7198798a152 100644
--- a/source/blender/nodes/composite/nodes/node_composite_common.c
+++ b/source/blender/nodes/composite/nodes/node_composite_common.c
@@ -32,187 +32,11 @@
#include "DNA_node_types.h"
-#include "BKE_node.h"
-
#include "node_composite_util.h"
#include "node_common.h"
#include "node_exec.h"
-#if 0
-static void PRINT_BUFFERS(bNodeTreeExec *exec)
-{
- bNodeTree *ntree= exec->nodetree;
- bNode *node;
- bNodeSocket *sock;
- bNodeStack *ns;
- int i;
-
- printf("-------------- DEBUG --------------\n");
- for (sock=ntree->inputs.first, i=0; sock; sock=sock->next, ++i) {
- ns = node_get_socket_stack(exec->stack, sock);
- printf("%d. Tree Input %s", i, sock->name);
- if (ns->external)
- printf(" (external)");
- printf(": data=%p\n", ns->data);
- }
- for (sock=ntree->outputs.first, i=0; sock; sock=sock->next, ++i) {
- ns = node_get_socket_stack(exec->stack, sock);
- printf("%d. Tree Output %s", i, sock->name);
- if (ns->external)
- printf(" (external)");
- printf(": data=%p\n", ns->data);
- }
- for (node=ntree->nodes.first; node; node=node->next) {
- printf("Node %s:\n", node->name);
- for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) {
- ns = node_get_socket_stack(exec->stack, sock);
- printf("\t%d. Input %s", i, sock->name);
- if (ns->external)
- printf(" (external)");
- printf(": data=%p\n", ns->data);
- }
- for (sock=node->outputs.first, i=0; sock; sock=sock->next, ++i) {
- ns = node_get_socket_stack(exec->stack, sock);
- printf("\t%d. Output %s", i, sock->name);
- if (ns->external)
- printf(" (external)");
- printf(": data=%p\n", ns->data);
- }
- }
-}
-#endif
-
-static void copy_stack(bNodeStack *to, bNodeStack *from)
-{
- if (to != from) {
- copy_v4_v4(to->vec, from->vec);
- to->data = from->data;
- to->datatype = from->datatype;
-
- /* tag as copy to prevent freeing */
- to->is_copy = 1;
- }
-}
-
-static void move_stack(bNodeStack *to, bNodeStack *from)
-{
- if (to != from) {
- copy_v4_v4(to->vec, from->vec);
- to->data = from->data;
- to->datatype = from->datatype;
- to->is_copy = from->is_copy;
-
- zero_v4(from->vec);
- from->data = NULL;
- from->datatype = 0;
- from->is_copy = 0;
- }
-}
-
-/**** GROUP ****/
-
-static void *group_initexec(bNode *node)
-{
- bNodeTree *ngroup = (bNodeTree *)node->id;
- bNodeTreeExec *exec;
- bNodeSocket *sock;
- bNodeStack *ns;
-
- if (!ngroup)
- return NULL;
-
- /* initialize the internal node tree execution */
- exec = ntreeCompositBeginExecTree(ngroup, 0);
-
- /* tag group outputs as external to prevent freeing */
- for (sock = ngroup->outputs.first; sock; sock = sock->next) {
- if (!(sock->flag & SOCK_INTERNAL)) {
- ns = node_get_socket_stack(exec->stack, sock);
- ns->external = 1;
- }
- }
-
- return exec;
-}
-
-static void group_freeexec(bNode *UNUSED(node), void *nodedata)
-{
- bNodeTreeExec *gexec = (bNodeTreeExec *)nodedata;
-
- if (gexec)
- ntreeCompositEndExecTree(gexec, 0);
-}
-
-/* Copy inputs to the internal stack.
- * This is a shallow copy, no buffers are duplicated here!
- */
-static void group_copy_inputs(bNode *node, bNodeStack **in, bNodeStack *gstack)
-{
- bNodeSocket *sock;
- bNodeStack *ns;
- int a;
- for (sock=node->inputs.first, a=0; sock; sock=sock->next, ++a) {
- if (sock->groupsock) {
- ns = node_get_socket_stack(gstack, sock->groupsock);
- copy_stack(ns, in[a]);
- }
- }
-}
-
-/* Copy internal results to the external outputs.
- */
-static void group_move_outputs(bNode *node, bNodeStack **out, bNodeStack *gstack)
-{
- bNodeSocket *sock;
- bNodeStack *ns;
- int a;
- for (sock = node->outputs.first, a = 0; sock; sock = sock->next, ++a) {
- if (sock->groupsock) {
- ns = node_get_socket_stack(gstack, sock->groupsock);
- move_stack(out[a], ns);
- }
- }
-}
-
-/* Free internal buffers */
-static void group_free_internal(bNodeTreeExec *gexec)
-{
- bNodeStack *ns;
- int i;
-
- for (i = 0, ns = gexec->stack; i < gexec->stacksize; ++i, ++ns) {
- if (!ns->external && !ns->is_copy) {
- if (ns->data) {
-#ifdef WITH_COMPOSITOR_LEGACY
- free_compbuf(ns->data);
-#endif
- ns->data = NULL;
- }
- }
- }
-}
-
-static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
-{
- bNodeTreeExec *exec= (bNodeTreeExec *)nodedata;
-
- if (!exec)
- return;
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
- inode->need_exec = 1;
- }
-
- group_copy_inputs(node, in, exec->stack);
- ntreeExecNodes(exec, data, thread);
- group_free_internal(exec);
- group_move_outputs(node, out, exec->stack);
-}
+#include "BKE_node.h"
void register_node_type_cmp_group(bNodeTreeType *ttype)
{
@@ -227,7 +51,7 @@ void register_node_type_cmp_group(bNodeTreeType *ttype)
node_type_template(&ntype, node_group_template);
node_type_update(&ntype, NULL, node_group_verify);
node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
- node_type_exec_new(&ntype, group_initexec, group_freeexec, group_execute);
nodeRegisterType(ttype, &ntype);
}
+
diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.c b/source/blender/nodes/composite/nodes/node_composite_composite.c
index cb932b6a8de..ea281a3f556 100644
--- a/source/blender/nodes/composite/nodes/node_composite_composite.c
+++ b/source/blender/nodes/composite/nodes/node_composite_composite.c
@@ -39,75 +39,12 @@ static bNodeSocketTemplate cmp_node_composite_in[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* applies to render pipeline */
-static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
-{
- /* image assigned to output */
- /* stack order input sockets: col, alpha, z */
-
- if (node->flag & NODE_DO_OUTPUT) { /* only one works on out */
- Scene *scene= (Scene *)node->id;
- RenderData *rd= data;
-
- if (scene && (rd->scemode & R_DOCOMP)) {
- Render *re= RE_GetRender(scene->id.name);
- RenderResult *rr= RE_AcquireResultWrite(re);
- if (rr) {
- CompBuf *outbuf, *zbuf=NULL;
-
- if (rr->rectf)
- MEM_freeN(rr->rectf);
- outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1);
-
- if (in[1]->data==NULL)
- composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA);
- else
- composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL);
-
- if (in[2]->data) {
- if (rr->rectz)
- MEM_freeN(rr->rectz);
- zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1);
- composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL);
- rr->rectz= zbuf->rect;
- zbuf->malloc= 0;
- free_compbuf(zbuf);
- }
- generate_preview(data, node, outbuf);
-
- /* we give outbuf to rr... */
- rr->rectf= outbuf->rect;
- outbuf->malloc= 0;
- free_compbuf(outbuf);
-
- /* signal for imageviewer to refresh (it converts to byte rects...) */
- BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
-
- RE_ReleaseResult(re);
- return;
- }
- else
- RE_ReleaseResult(re);
- }
- }
- if (in[0]->data)
- generate_preview(data, node, in[0]->data);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_composite(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, CMP_NODE_COMPOSITE, "Composite", NODE_CLASS_OUTPUT, NODE_PREVIEW);
+ node_type_base(ttype, &ntype, CMP_NODE_COMPOSITE, "Composite", NODE_CLASS_OUTPUT, NODE_OPTIONS | NODE_PREVIEW);
node_type_socket_templates(&ntype, cmp_node_composite_in, NULL);
- node_type_size(&ntype, 80, 60, 200);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_composite);
-#endif
/* Do not allow muting for this node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/composite/nodes/node_composite_crop.c b/source/blender/nodes/composite/nodes/node_composite_crop.c
index ad51fae1998..10af55480cd 100644
--- a/source/blender/nodes/composite/nodes/node_composite_crop.c
+++ b/source/blender/nodes/composite/nodes/node_composite_crop.c
@@ -43,68 +43,6 @@ static bNodeSocketTemplate cmp_node_crop_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_crop(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (in[0]->data) {
- NodeTwoXYs *ntxy= node->storage;
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf;
- int x, y;
- float *srcfp, *outfp;
- rcti outputrect;
-
- if (node->custom2) {
- ntxy->x1= cbuf->x* ntxy->fac_x1;
- ntxy->x2= cbuf->x* ntxy->fac_x2;
- ntxy->y1= cbuf->y* ntxy->fac_y1;
- ntxy->y2= cbuf->y* ntxy->fac_y2;
- }
-
- /* check input image size */
- if (cbuf->x <= ntxy->x1 + 1)
- ntxy->x1= cbuf->x - 1;
-
- if (cbuf->y <= ntxy->y1 + 1)
- ntxy->y1= cbuf->y - 1;
-
- if (cbuf->x <= ntxy->x2 + 1)
- ntxy->x2= cbuf->x - 1;
-
- if (cbuf->y <= ntxy->y2 + 1)
- ntxy->y2= cbuf->y - 1;
-
- /* figure out the minimums and maximums */
- outputrect.xmax=MAX2(ntxy->x1, ntxy->x2) + 1;
- outputrect.xmin=MIN2(ntxy->x1, ntxy->x2);
- outputrect.ymax=MAX2(ntxy->y1, ntxy->y2) + 1;
- outputrect.ymin=MIN2(ntxy->y1, ntxy->y2);
-
- if (node->custom1) {
- /* this option crops the image size too */
- stackbuf= get_cropped_compbuf(&outputrect, cbuf->rect, cbuf->x, cbuf->y, cbuf->type);
- }
- else {
- /* this option won't crop the size of the image as well */
- /* allocate memory for the output image */
- stackbuf = alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1);
-
- /* select the cropped part of the image and set it to the output */
- for (y=outputrect.ymin; y<outputrect.ymax; y++) {
- srcfp= cbuf->rect + (y * cbuf->x + outputrect.xmin) * cbuf->type;
- outfp= stackbuf->rect + (y * stackbuf->x + outputrect.xmin) * stackbuf->type;
- for (x=outputrect.xmin; x<outputrect.xmax; x++, outfp+= stackbuf->type, srcfp+= cbuf->type)
- memcpy(outfp, srcfp, sizeof(float)*stackbuf->type);
- }
- }
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_crop(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeTwoXYs *nxy= MEM_callocN(sizeof(NodeTwoXYs), "node xy data");
@@ -121,12 +59,8 @@ void register_node_type_cmp_crop(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_CROP, "Crop", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_crop_in, cmp_node_crop_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_crop);
node_type_storage(&ntype, "NodeTwoXYs", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_crop);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_curves.c b/source/blender/nodes/composite/nodes/node_composite_curves.c
index a1999ec8887..9f40159baf3 100644
--- a/source/blender/nodes/composite/nodes/node_composite_curves.c
+++ b/source/blender/nodes/composite/nodes/node_composite_curves.c
@@ -41,25 +41,6 @@ static bNodeSocketTemplate cmp_node_time_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_curves_time(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- RenderData *rd= data;
- /* stack order output: fac */
- float fac= 0.0f;
-
- if (node->custom1 < node->custom2)
- fac= (rd->cfra - node->custom1)/(float)(node->custom2-node->custom1);
-
- curvemapping_initialize(node->storage);
- fac = curvemapping_evaluateF(node->storage, 0, fac);
-
- out[0]->vec[0] = CLAMPIS(fac, 0.0f, 1.0f);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_curves_time(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->custom1= 1;
@@ -76,9 +57,6 @@ void register_node_type_cmp_curve_time(bNodeTreeType *ttype)
node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_curves_time);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_curves_time);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -96,19 +74,6 @@ static bNodeSocketTemplate cmp_node_curve_vec_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_curve_vec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order input: vec */
- /* stack order output: vec */
-
- curvemapping_initialize(node->storage);
- curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
@@ -123,9 +88,6 @@ void register_node_type_cmp_curve_vec(bNodeTreeType *ttype)
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_composit_init_curve_vec);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_curve_vec);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -145,67 +107,6 @@ static bNodeSocketTemplate cmp_node_curve_rgb_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_curves(bNode *node, float *out, float *in)
-{
- curvemapping_initialize(node->storage);
- curvemapping_evaluate_premulRGBF(node->storage, out, in);
- out[3] = in[3];
-}
-
-static void do_curves_fac(bNode *node, float *out, float *in, float *fac)
-{
- curvemapping_initialize(node->storage);
-
- if (*fac >= 1.0f)
- curvemapping_evaluate_premulRGBF(node->storage, out, in);
- else if (*fac <= 0.0f) {
- copy_v3_v3(out, in);
- }
- else {
- float col[4], mfac= 1.0f-*fac;
- curvemapping_evaluate_premulRGBF(node->storage, col, in);
- out[0] = mfac*in[0] + *fac*col[0];
- out[1] = mfac*in[1] + *fac*col[1];
- out[2] = mfac*in[2] + *fac*col[2];
- }
- out[3] = in[3];
-}
-
-static void node_composit_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order input: fac, image, black level, white level */
- /* stack order output: image */
-
- if (out[0]->hasoutput==0)
- return;
-
- curvemapping_initialize(node->storage);
-
- /* input no image? then only color operation */
- if (in[1]->data==NULL) {
- curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[1]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[1]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- curvemapping_set_black_white(node->storage, in[2]->vec, in[3]->vec);
-
- if (in[0]->data==NULL && in[0]->vec[0] == 1.0f)
- composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA);
- else
- composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac, CB_RGBA, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
@@ -220,9 +121,6 @@ void register_node_type_cmp_curve_rgb(bNodeTreeType *ttype)
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_composit_init_curve_rgb);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_curve_rgb);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c
index 27ce0f7c4a7..c05f1d6fcff 100644
--- a/source/blender/nodes/composite/nodes/node_composite_defocus.c
+++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c
@@ -44,830 +44,6 @@ static bNodeSocketTemplate cmp_node_defocus_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-// line coefs for point sampling & scancon. data.
-typedef struct BokehCoeffs {
- float x0, y0, dx, dy;
- float ls_x, ls_y;
- float min_x, min_y, max_x, max_y;
-} BokehCoeffs;
-
-// returns array of BokehCoeffs
-// returns length of array in 'len_bkh',
-// radius squared of inscribed disk in 'inradsq', needed in getWeight() test,
-// BKH[8] is the data returned for the bokeh shape & bkh_b[4] is it's 2d bound
-static void makeBokeh(char bktype, char ro, int* len_bkh, float* inradsq, BokehCoeffs BKH[8], float bkh_b[4])
-{
- float x0, x1, y0, y1, dx, dy, iDxy;
- /* ro now is in radians. */
- float w = MAX2(1e-6f, ro); // never reported stangely enough, but a zero offset causes missing center line...
- float wi = DEG2RADF(360.f/bktype);
- int i, ov, nv;
-
- // bktype must be at least 3 & <= 8
- bktype = (bktype<3) ? 3 : ((bktype>8) ? 8 : bktype);
- *len_bkh = bktype;
- *inradsq = -1.f;
-
- for (i=0; i<(*len_bkh); i++) {
- x0 = cos(w);
- y0 = sin(w);
- w += wi;
- x1 = cos(w);
- y1 = sin(w);
- if ((*inradsq)<0.f) {
- // radius squared of inscribed disk
- float idx=(x0+x1)*0.5f, idy=(y0+y1)*0.5f;
- *inradsq = idx*idx + idy*idy;
- }
- BKH[i].x0 = x0;
- BKH[i].y0 = y0;
- dx = x1-x0, dy = y1-y0;
- iDxy = 1.f / sqrtf(dx*dx + dy*dy);
- dx *= iDxy;
- dy *= iDxy;
- BKH[i].dx = dx;
- BKH[i].dy = dy;
- }
-
- // precalc scanconversion data
- // bokeh bound, not transformed, for scanconvert
- bkh_b[0] = bkh_b[2] = 1e10f; // xmin/ymin
- bkh_b[1] = bkh_b[3] = -1e10f; // xmax/ymax
- ov = (*len_bkh) - 1;
- for (nv=0; nv<(*len_bkh); nv++) {
- bkh_b[0] = MIN2(bkh_b[0], BKH[nv].x0); // xmin
- bkh_b[1] = MAX2(bkh_b[1], BKH[nv].x0); // xmax
- bkh_b[2] = MIN2(bkh_b[2], BKH[nv].y0); // ymin
- bkh_b[3] = MAX2(bkh_b[3], BKH[nv].y0); // ymax
- BKH[nv].min_x = MIN2(BKH[ov].x0, BKH[nv].x0);
- BKH[nv].max_x = MAX2(BKH[ov].x0, BKH[nv].x0);
- BKH[nv].min_y = MIN2(BKH[ov].y0, BKH[nv].y0);
- BKH[nv].max_y = MAX2(BKH[ov].y0, BKH[nv].y0);
- dy = BKH[nv].y0 - BKH[ov].y0;
- BKH[nv].ls_x = (BKH[nv].x0 - BKH[ov].x0) / ((dy==0.f) ? 1.f : dy);
- BKH[nv].ls_y = (BKH[nv].ls_x==0.f) ? 1.f : (1.f/BKH[nv].ls_x);
- ov = nv;
- }
-}
-
-// test if u/v inside shape & returns weight value
-static float getWeight(BokehCoeffs* BKH, int len_bkh, float u, float v, float rad, float inradsq)
-{
- BokehCoeffs* bc = BKH;
- float cdist, irad = (rad==0.f) ? 1.f : (1.f/rad);
- u *= irad;
- v *= irad;
-
- // early out test1: if point outside outer unit disk, it cannot be inside shape
- cdist = u*u + v*v;
- if (cdist>1.f) return 0.f;
-
- // early out test2: if point inside or on inner disk, point must be inside shape
- if (cdist<=inradsq) return 1.f;
-
- while (len_bkh--) {
- if ((bc->dy*(u - bc->x0) - bc->dx*(v - bc->y0)) > 0.f) return 0.f;
- bc++;
- }
- return 1.f;
-}
-
-// QMC.seq. for sampling, A.Keller, EMS
-static float RI_vdC(unsigned int bits, unsigned int r)
-{
- bits = ( bits << 16) | ( bits >> 16);
- bits = ((bits & 0x00ff00ff) << 8) | ((bits & 0xff00ff00) >> 8);
- bits = ((bits & 0x0f0f0f0f) << 4) | ((bits & 0xf0f0f0f0) >> 4);
- bits = ((bits & 0x33333333) << 2) | ((bits & 0xcccccccc) >> 2);
- bits = ((bits & 0x55555555) << 1) | ((bits & 0xaaaaaaaa) >> 1);
- bits ^= r;
- return (float)((double)bits / 4294967296.0);
-}
-
-// single channel IIR gaussian filtering
-// much faster than anything else, constant time independent of width
-// should extend to multichannel and make this a node, could be useful
-// note: this is an almost exact copy of 'IIR_gauss'
-static void IIR_gauss_single(CompBuf *buf, float sigma)
-{
- double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
- float *X, *Y, *W;
- const unsigned int src_width = buf->x;
- const unsigned int src_height = buf->y;
- unsigned int i, x, y, sz;
-
- // single channel only for now
- if (buf->type != CB_VAL) return;
-
- // <0.5 not valid, though can have a possibly useful sort of sharpening effect
- if (sigma < 0.5f) return;
-
- // see "Recursive Gabor Filtering" by Young/VanVliet
- // all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200
- if (sigma >= 3.556f)
- q = 0.9804f * (sigma - 3.556f) + 2.5091f;
- else // sigma >= 0.5
- q = (0.0561f * sigma + 0.5784f) * sigma - 0.2568f;
- q2 = q * q;
- sc = (1.1668 + q) * (3.203729649 + (2.21566 + q) * q);
- // no gabor filtering here, so no complex multiplies, just the regular coefs.
- // all negated here, so as not to have to recalc Triggs/Sdika matrix
- cf[1] = q * (5.788961737 + (6.76492 + 3.0 * q) * q) / sc;
- cf[2] = -q2 * (3.38246 + 3.0 * q) / sc;
- // 0 & 3 unchanged
- cf[3] = q2 * q / sc;
- cf[0] = 1.0 - cf[1] - cf[2] - cf[3];
-
- // Triggs/Sdika border corrections,
- // it seems to work, not entirely sure if it is actually totally correct,
- // Besides J.M.Geusebroek's anigauss.c (see http://www.science.uva.nl/~mark),
- // found one other implementation by Cristoph Lampert,
- // but neither seem to be quite the same, result seems to be ok so far anyway.
- // Extra scale factor here to not have to do it in filter,
- // though maybe this had something to with the precision errors
- sc = cf[0] / ((1.0 + cf[1] - cf[2] + cf[3]) * (1.0 - cf[1] - cf[2] - cf[3]) * (1.0 + cf[2] + (cf[1] - cf[3]) * cf[3]));
- tsM[0] = sc * (-cf[3] * cf[1] + 1.0 - cf[3] * cf[3] - cf[2]);
- tsM[1] = sc * ((cf[3] + cf[1]) * (cf[2] + cf[3] * cf[1]));
- tsM[2] = sc * (cf[3] * (cf[1] + cf[3] * cf[2]));
- tsM[3] = sc * (cf[1] + cf[3] * cf[2]);
- tsM[4] = sc * (-(cf[2] - 1.0) * (cf[2] + cf[3] * cf[1]));
- tsM[5] = sc * (-(cf[3] * cf[1] + cf[3] * cf[3] + cf[2] - 1.0) * cf[3]);
- tsM[6] = sc * (cf[3] * cf[1] + cf[2] + cf[1] * cf[1] - cf[2] * cf[2]);
- tsM[7] = sc * (cf[1] * cf[2] + cf[3] * cf[2] * cf[2] - cf[1] * cf[3] * cf[3] - cf[3] * cf[3] * cf[3] - cf[3] * cf[2] + cf[3]);
- tsM[8] = sc * (cf[3] * (cf[1] + cf[3] * cf[2]));
-
-#define YVV(L) \
-{ \
- W[0] = cf[0] * X[0] + cf[1] * X[0] + cf[2] * X[0] + cf[3] * X[0]; \
- W[1] = cf[0] * X[1] + cf[1] * W[0] + cf[2] * X[0] + cf[3] * X[0]; \
- W[2] = cf[0] * X[2] + cf[1] * W[1] + cf[2] * W[0] + cf[3] * X[0]; \
- for (i = 3; i < L; i++) { \
- W[i] = cf[0] * X[i] + cf[1] * W[i - 1] + cf[2] * W[i - 2] + cf[3] * W[i - 3]; \
- } \
- tsu[0] = W[L - 1] - X[L - 1]; \
- tsu[1] = W[L - 2] - X[L - 1]; \
- tsu[2] = W[L - 3] - X[L - 1]; \
- tsv[0] = tsM[0] * tsu[0] + tsM[1] * tsu[1] + tsM[2] * tsu[2] + X[L - 1]; \
- tsv[1] = tsM[3] * tsu[0] + tsM[4] * tsu[1] + tsM[5] * tsu[2] + X[L - 1]; \
- tsv[2] = tsM[6] * tsu[0] + tsM[7] * tsu[1] + tsM[8] * tsu[2] + X[L - 1]; \
- Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \
- Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \
- Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \
- /* 'i != UINT_MAX' is really 'i >= 0', but necessary for unsigned int wrapping */ \
- for (i = L - 4; i != UINT_MAX; i--) { \
- Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \
- } \
-} (void)0
-
- // intermediate buffers
- sz = MAX2(src_width, src_height);
- Y = MEM_callocN(sz * sizeof(float), "IIR_gauss Y buf");
- W = MEM_callocN(sz * sizeof(float), "IIR_gauss W buf");
- // H
- for (y = 0; y < src_height; y++) {
- X = &buf->rect[y * src_width];
- YVV(src_width);
- memcpy(X, Y, sizeof(float) * src_width);
- }
- // V
- X = MEM_callocN(src_height * sizeof(float), "IIR_gauss X buf");
- for (x = 0; x < src_width; x++) {
- for (y = 0; y < src_height; y++)
- X[y] = buf->rect[x + y * src_width];
- YVV(src_height);
- for (y = 0; y < src_height; y++)
- buf->rect[x + y * src_width] = Y[y];
- }
- MEM_freeN(X);
-
- MEM_freeN(W);
- MEM_freeN(Y);
-#undef YVV
-}
-
-static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf, float inpval, int no_zbuf)
-{
- NodeDefocus *nqd = node->storage;
- CompBuf *wts; // weights buffer
- CompBuf *crad; // CoC radius buffer
- BokehCoeffs BKH[8]; // bokeh shape data, here never > 8 pts.
- float bkh_b[4] = {0}; // shape 2D bound
- float cam_fdist=1, cam_invfdist=1, cam_lens=35;
- float cam_sensor = DEFAULT_SENSOR_WIDTH;
- float dof_sp, maxfgc, bk_hn_theta=0, inradsq=0;
- int y, len_bkh=0, ydone = FALSE;
- float aspect, aperture;
- int minsz;
- //float bcrad, nmaxc, scf;
-
- // get some required params from the current scene camera
- // (ton) this is wrong, needs fixed
- Scene *scene= (Scene*)node->id;
- Object* camob = (scene)? scene->camera: NULL;
- if (camob && camob->type==OB_CAMERA) {
- Camera* cam = (Camera*)camob->data;
- cam_lens = cam->lens;
- cam_fdist = BKE_camera_object_dof_distance(camob);
- cam_sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
- if (cam_fdist == 0.0f) cam_fdist = 1e10f; /* if the dof is 0.0 then set it be be far away */
- cam_invfdist = 1.f / cam_fdist;
- }
- // guess work here.. best match with raytraced result
- minsz = MIN2(img->x, img->y);
- dof_sp = (float)minsz / ((cam_sensor / 2.0f) / cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov);
-
- // aperture
- aspect = (img->x > img->y) ? (img->y / (float)img->x) : (img->x / (float)img->y);
- aperture = 0.5f * (cam_lens / (aspect * cam_sensor)) / nqd->fstop;
-
- // if not disk, make bokeh coefficients and other needed data
- if (nqd->bktype!=0) {
- makeBokeh(nqd->bktype, nqd->rotation, &len_bkh, &inradsq, BKH, bkh_b);
- bk_hn_theta = 0.5 * nqd->bktype * sin(2.0 * M_PI / nqd->bktype); // weight factor
- }
-
- // accumulated weights
- wts = alloc_compbuf(img->x, img->y, CB_VAL, 1);
- // CoC radius buffer
- crad = alloc_compbuf(img->x, img->y, CB_VAL, 1);
-
- // if 'no_zbuf' flag set (which is always set if input is not an image),
- // values are instead interpreted directly as blur radius values
- if (no_zbuf) {
- // to prevent *reaaallly* big radius values and impossible calculation times,
- // limit the maximum to half the image width or height, whichever is smaller
- float maxr = 0.5f*(float)MIN2(img->x, img->y);
- unsigned int p;
-
- for (p=0; p<(unsigned int)(img->x*img->y); p++) {
- crad->rect[p] = zbuf ? (zbuf->rect[p]*nqd->scale) : inpval;
- // bug #5921, limit minimum
- crad->rect[p] = MAX2(1e-5f, crad->rect[p]);
- crad->rect[p] = MIN2(crad->rect[p], maxr);
- // if maxblur!=0, limit maximum
- if (nqd->maxblur != 0.f) crad->rect[p] = MIN2(crad->rect[p], nqd->maxblur);
- }
- }
- else {
- float wt;
-
- // actual zbuffer.
- // separate foreground from background CoC's
- // then blur background and blend in again with foreground,
- // improves the 'blurred foreground overlapping in-focus midground' sharp boundary problem.
- // wts buffer here used for blendmask
- maxfgc = 0.f; // maximum foreground CoC radius
- for (y=0; y<img->y; y++) {
- unsigned int p = y * img->x;
- int x;
- for (x=0; x<img->x; x++) {
- unsigned int px = p + x;
- float iZ = (zbuf->rect[px]==0.f) ? 0.f : (1.f/zbuf->rect[px]);
- crad->rect[px] = 0.5f*(aperture*(dof_sp*(cam_invfdist - iZ) - 1.f));
- if (crad->rect[px] <= 0.f) {
- wts->rect[px] = 1.f;
- crad->rect[px] = -crad->rect[px];
- if (crad->rect[px] > maxfgc) maxfgc = crad->rect[px];
- }
- else crad->rect[px] = wts->rect[px] = 0;
- }
- }
-
- // fast blur...
- // bug #6656 part 1, probably when previous node_composite.c was split into separate files, it was not properly updated
- // to include recent cvs commits (well, at least not defocus node), so this part was missing...
- wt = min_ff(nqd->maxblur, aperture * 128.0f);
- IIR_gauss_single(crad, wt);
- IIR_gauss_single(wts, wt);
-
- // bug #6656 part 2a, although foreground blur is not based anymore on closest object,
- // the rescaling op below was still based on that anyway, and unlike the comment in below code,
- // the difference is therefore not always that small at all...
- // so for now commented out, not sure if this is going to cause other future problems, lets just wait and see...
- /*
- // find new maximum to scale it back to original
- // (could skip this, not strictly necessary, in general, difference is quite small, but just in case...)
- nmaxc = 0;
- for (p=0; p<(img->x*img->y); p++)
- if (crad->rect[p] > nmaxc) nmaxc = crad->rect[p];
- // rescale factor
- scf = (nmaxc==0.f) ? 1.f: (maxfgc / nmaxc);
- */
-
- // and blend...
- for (y=0; y<img->y; y++) {
- unsigned int p = y*img->x;
- int x;
-
- for (x=0; x<img->x; x++) {
- unsigned px = p + x;
- if (zbuf->rect[px]!=0.f) {
- float iZ = (zbuf->rect[px]==0.f) ? 0.f : (1.f/zbuf->rect[px]);
-
- // bug #6656 part 2b, do not rescale
- /*
- bcrad = 0.5f*fabs(aperture*(dof_sp*(cam_invfdist - iZ) - 1.f));
- // scale crad back to original maximum and blend
- crad->rect[px] = bcrad + wts->rect[px]*(scf*crad->rect[px] - bcrad);
- */
- crad->rect[px] = 0.5f*fabsf(aperture*(dof_sp*(cam_invfdist - iZ) - 1.f));
-
- // 'bug' #6615, limit minimum radius to 1 pixel, not really a solution, but somewhat mitigates the problem
- crad->rect[px] = MAX2(crad->rect[px], 0.5f);
- // if maxblur!=0, limit maximum
- if (nqd->maxblur != 0.f) crad->rect[px] = MIN2(crad->rect[px], nqd->maxblur);
- }
- else crad->rect[px] = 0.f;
- // clear weights for next part
- wts->rect[px] = 0.f;
- }
- // esc set by main calling process
- if (node->exec & NODE_BREAK)
- break;
- }
- }
-
- //------------------------------------------------------------------
- // main loop
-#ifndef __APPLE__ /* can crash on Mac, see bug #22856, disabled for now */
-#ifdef __INTEL_COMPILER /* icc doesn't like the compound statement -- internal error: 0_1506 */
- #pragma omp parallel for private(y) if (!nqd->preview) schedule(guided)
-#else
- #pragma omp parallel for private(y) if (!nqd->preview && img->y*img->x > 16384) schedule(guided)
-#endif
-#endif
- for (y=0; y<img->y; y++) {
- unsigned int p, p4, zp, cp, cp4;
- float *ctcol, u, v, ct_crad, cR2=0;
- int x, sx, sy;
-
- // some sort of visual feedback would be nice, or at least this text in the renderwin header
- // but for now just print some info in the console every 8 scanlines.
- #pragma omp critical
- {
- if (((ydone & 7)==0) || (ydone==(img->y-1))) {
- if (G.background==0) {
- printf("\rdefocus: Processing Line %d of %d ... ", ydone+1, img->y);
- fflush(stdout);
- }
- }
-
- ydone++;
- }
-
- // esc set by main calling process. don't break because openmp doesn't
- // allow it, just continue and do nothing
- if (node->exec & NODE_BREAK)
- continue;
-
- zp = y * img->x;
- for (x=0; x<img->x; x++) {
- cp = zp + x;
- cp4 = cp * img->type;
-
- // Circle of Confusion radius for current pixel
- cR2 = ct_crad = crad->rect[cp];
- // skip if zero (border render)
- if (ct_crad==0.f) {
- // related to bug #5921, forgot output image when skipping 0 radius values
- new->rect[cp4] = img->rect[cp4];
- if (new->type != CB_VAL) {
- new->rect[cp4+1] = img->rect[cp4+1];
- new->rect[cp4+2] = img->rect[cp4+2];
- new->rect[cp4+3] = img->rect[cp4+3];
- }
- continue;
- }
- cR2 *= cR2;
-
- // pixel color
- ctcol = &img->rect[cp4];
-
- if (!nqd->preview) {
- int xs, xe, ys, ye;
- float lwt, wtcol[4] = {0}, aacol[4] = {0};
- float wt;
-
- // shape weight
- if (nqd->bktype==0) // disk
- wt = 1.f/((float)M_PI*cR2);
- else
- wt = 1.f/(cR2*bk_hn_theta);
-
- // weighted color
- wtcol[0] = wt*ctcol[0];
- if (new->type != CB_VAL) {
- wtcol[1] = wt*ctcol[1];
- wtcol[2] = wt*ctcol[2];
- wtcol[3] = wt*ctcol[3];
- }
-
- // macro for background blur overlap test
- // unfortunately, since this is done per pixel,
- // it has a very significant negative impact on processing time...
- // (eg. aa disk blur without test: 112 sec, vs with test: 176 sec...)
- // iff center blur radius > threshold
- // and if overlap pixel in focus, do nothing, else add color/weigbt
- // (threshold constant is dependent on amount of blur)
- #define TESTBG1(c, w) {\
- if (ct_crad > nqd->bthresh) {\
- if (crad->rect[p] > nqd->bthresh) {\
- new->rect[p] += c[0];\
- wts->rect[p] += w;\
- }\
- }\
- else {\
- new->rect[p] += c[0];\
- wts->rect[p] += w;\
- }\
- }
- #define TESTBG4(c, w) {\
- if (ct_crad > nqd->bthresh) {\
- if (crad->rect[p] > nqd->bthresh) {\
- new->rect[p4] += c[0];\
- new->rect[p4+1] += c[1];\
- new->rect[p4+2] += c[2];\
- new->rect[p4+3] += c[3];\
- wts->rect[p] += w;\
- }\
- }\
- else {\
- new->rect[p4] += c[0];\
- new->rect[p4+1] += c[1];\
- new->rect[p4+2] += c[2];\
- new->rect[p4+3] += c[3];\
- wts->rect[p] += w;\
- }\
- }
- if (nqd->bktype == 0) {
- // Disk
- int _x, i, j, di;
- float Dj, T;
- // AA pixel
- #define AAPIX(a, b) {\
- int _ny = b;\
- if ((_ny >= 0) && (_ny < new->y)) {\
- int _nx = a;\
- if ((_nx >=0) && (_nx < new->x)) {\
- p = _ny*new->x + _nx;\
- if (new->type==CB_VAL) {\
- TESTBG1(aacol, lwt);\
- }\
- else {\
- p4 = p * new->type;\
- TESTBG4(aacol, lwt);\
- }\
- }\
- }\
- }
- // circle scanline
- #define CSCAN(a, b) {\
- int _ny = y + b;\
- if ((_ny >= 0) && (_ny < new->y)) {\
- xs = x - a + 1;\
- if (xs < 0) xs = 0;\
- xe = x + a;\
- if (xe > new->x) xe = new->x;\
- p = _ny*new->x + xs;\
- if (new->type==CB_VAL) {\
- for (_x=xs; _x<xe; _x++, p++) TESTBG1(wtcol, wt);\
- }\
- else {\
- p4 = p * new->type;\
- for (_x=xs; _x<xe; _x++, p++, p4+=new->type) TESTBG4(wtcol, wt);\
- }\
- }\
- }
-
- i = ceil(ct_crad);
- j = 0;
- T = 0;
- while (i > j) {
- Dj = sqrt(cR2 - j*j);
- Dj -= floorf(Dj);
- di = 0;
- if (Dj > T) { i--; di = 1; }
- T = Dj;
- aacol[0] = wtcol[0]*Dj;
- if (new->type != CB_VAL) {
- aacol[1] = wtcol[1]*Dj;
- aacol[2] = wtcol[2]*Dj;
- aacol[3] = wtcol[3]*Dj;
- }
- lwt = wt*Dj;
- if (i!=j) {
- // outer pixels
- AAPIX(x+j, y+i)
- AAPIX(x+j, y-i)
- if (j) {
- AAPIX(x-j, y+i) // BL
- AAPIX(x-j, y-i) // TL
- }
- if (di) { // only when i changed, interior of outer section
- CSCAN(j, i) // bottom
- CSCAN(j, -i) // top
- }
- }
- // lower mid section
- AAPIX(x+i, y+j)
- if (i) AAPIX(x-i, y+j)
- CSCAN(i, j)
- // upper mid section
- if (j) {
- AAPIX(x+i, y-j)
- if (i) AAPIX(x-i, y-j)
- CSCAN(i, -j)
- }
- j++;
- }
- #undef CSCAN
- #undef AAPIX
- }
- else {
- // n-agonal
- int ov, nv;
- float mind, maxd, lwt;
- ys = max_ii((int)floor(bkh_b[2] * ct_crad + y), 0);
- ye = min_ii((int)ceil(bkh_b[3] * ct_crad + y), new->y - 1);
- for (sy=ys; sy<=ye; sy++) {
- float fxs = 1e10f, fxe = -1e10f;
- float yf = (sy - y)/ct_crad;
- int found = 0;
- ov = len_bkh - 1;
- mind = maxd = 0;
- for (nv=0; nv<len_bkh; nv++) {
- if ((BKH[nv].max_y >= yf) && (BKH[nv].min_y <= yf)) {
- float tx = BKH[ov].x0 + BKH[nv].ls_x*(yf - BKH[ov].y0);
- if (tx < fxs) { fxs = tx; mind = BKH[nv].ls_x; }
- if (tx > fxe) { fxe = tx; maxd = BKH[nv].ls_x; }
- if (++found == 2) break;
- }
- ov = nv;
- }
- if (found) {
- fxs = fxs*ct_crad + x;
- fxe = fxe*ct_crad + x;
- xs = (int)floor(fxs), xe = (int)ceil(fxe);
- // AA hack for first and last x pixel, near vertical edges only
- if (fabsf(mind) <= 1.f) {
- if ((xs >= 0) && (xs < new->x)) {
- lwt = 1.f-(fxs - xs);
- aacol[0] = wtcol[0]*lwt;
- p = xs + sy*new->x;
- if (new->type==CB_VAL) {
- lwt *= wt;
- TESTBG1(aacol, lwt);
- }
- else {
- p4 = p * new->type;
- aacol[1] = wtcol[1]*lwt;
- aacol[2] = wtcol[2]*lwt;
- aacol[3] = wtcol[3]*lwt;
- lwt *= wt;
- TESTBG4(aacol, lwt);
- }
- }
- }
- if (fabsf(maxd) <= 1.f) {
- if ((xe >= 0) && (xe < new->x)) {
- lwt = 1.f-(xe - fxe);
- aacol[0] = wtcol[0]*lwt;
- p = xe + sy*new->x;
- if (new->type==CB_VAL) {
- lwt *= wt;
- TESTBG1(aacol, lwt);
- }
- else {
- p4 = p * new->type;
- aacol[1] = wtcol[1]*lwt;
- aacol[2] = wtcol[2]*lwt;
- aacol[3] = wtcol[3]*lwt;
- lwt *= wt;
- TESTBG4(aacol, lwt);
- }
- }
- }
- xs = MAX2(xs+1, 0);
- xe = MIN2(xe, new->x);
- // remaining interior scanline
- p = sy*new->x + xs;
- if (new->type==CB_VAL) {
- for (sx=xs; sx<xe; sx++, p++) TESTBG1(wtcol, wt);
- }
- else {
- p4 = p * new->type;
- for (sx=xs; sx<xe; sx++, p++, p4+=new->type) TESTBG4(wtcol, wt);
- }
- }
- }
-
- // now traverse in opposite direction, y scanlines,
- // but this time only draw the near horizontal edges,
- // applying same AA hack as above
- xs = MAX2((int)floor(bkh_b[0]*ct_crad + x), 0);
- xe = MIN2((int)ceil(bkh_b[1]*ct_crad + x), img->x - 1);
- for (sx=xs; sx<=xe; sx++) {
- float xf = (sx - x)/ct_crad;
- float fys = 1e10f, fye = -1e10f;
- int found = 0;
- ov = len_bkh - 1;
- mind = maxd = 0;
- for (nv=0; nv<len_bkh; nv++) {
- if ((BKH[nv].max_x >= xf) && (BKH[nv].min_x <= xf)) {
- float ty = BKH[ov].y0 + BKH[nv].ls_y*(xf - BKH[ov].x0);
- if (ty < fys) { fys = ty; mind = BKH[nv].ls_y; }
- if (ty > fye) { fye = ty; maxd = BKH[nv].ls_y; }
- if (++found == 2) break;
- }
- ov = nv;
- }
- if (found) {
- fys = fys*ct_crad + y;
- fye = fye*ct_crad + y;
- // near horizontal edges only, line slope <= 1
- if (fabsf(mind) <= 1.f) {
- int iys = (int)floor(fys);
- if ((iys >= 0) && (iys < new->y)) {
- lwt = 1.f - (fys - iys);
- aacol[0] = wtcol[0]*lwt;
- p = sx + iys*new->x;
- if (new->type==CB_VAL) {
- lwt *= wt;
- TESTBG1(aacol, lwt);
- }
- else {
- p4 = p * new->type;
- aacol[1] = wtcol[1]*lwt;
- aacol[2] = wtcol[2]*lwt;
- aacol[3] = wtcol[3]*lwt;
- lwt *= wt;
- TESTBG4(aacol, lwt);
- }
- }
- }
- if (fabsf(maxd) <= 1.f) {
- int iye = ceil(fye);
- if ((iye >= 0) && (iye < new->y)) {
- lwt = 1.f - (iye - fye);
- aacol[0] = wtcol[0]*lwt;
- p = sx + iye*new->x;
- if (new->type==CB_VAL) {
- lwt *= wt;
- TESTBG1(aacol, lwt);
- }
- else {
- p4 = p * new->type;
- aacol[1] = wtcol[1]*lwt;
- aacol[2] = wtcol[2]*lwt;
- aacol[3] = wtcol[3]*lwt;
- lwt *= wt;
- TESTBG4(aacol, lwt);
- }
- }
- }
- }
- }
-
- }
- #undef TESTBG4
- #undef TESTBG1
-
- }
- else {
- // sampled, simple rejection sampling here, good enough
- unsigned int maxsam, s, ui = BLI_rand()*BLI_rand();
- float wcor, cpr = BLI_frand(), lwt;
- if (no_zbuf)
- maxsam = nqd->samples; // no zbuffer input, use sample value directly
- else {
- // depth adaptive sampling hack, the more out of focus, the more samples taken, 16 minimum.
- maxsam = (int)(0.5f + nqd->samples*(1.f-(float)exp(-fabs(zbuf->rect[cp] - cam_fdist))));
- if (maxsam < 16) maxsam = 16;
- }
- wcor = 1.f/(float)maxsam;
- for (s=0; s<maxsam; ++s) {
- u = ct_crad*(2.f*RI_vdC(s, ui) - 1.f);
- v = ct_crad*(2.f*(s + cpr)/(float)maxsam - 1.f);
- sx = (int)(x + u + 0.5f), sy = (int)(y + v + 0.5f);
- if ((sx<0) || (sx >= new->x) || (sy<0) || (sy >= new->y)) continue;
- p = sx + sy*new->x;
- p4 = p * new->type;
- if (nqd->bktype==0) // Disk
- lwt = ((u*u + v*v)<=cR2) ? wcor : 0.f;
- else /* AA not needed here */
- lwt = wcor * getWeight(BKH, len_bkh, u, v, ct_crad, inradsq);
- // prevent background bleeding onto in-focus pixels, user-option
- if (ct_crad > nqd->bthresh) { // if center blur > threshold
- if (crad->rect[p] > nqd->bthresh) { // if overlap pixel in focus, do nothing, else add color/weigbt
- new->rect[p4] += ctcol[0] * lwt;
- if (new->type != CB_VAL) {
- new->rect[p4+1] += ctcol[1] * lwt;
- new->rect[p4+2] += ctcol[2] * lwt;
- new->rect[p4+3] += ctcol[3] * lwt;
- }
- wts->rect[p] += lwt;
- }
- }
- else {
- new->rect[p4] += ctcol[0] * lwt;
- if (new->type != CB_VAL) {
- new->rect[p4+1] += ctcol[1] * lwt;
- new->rect[p4+2] += ctcol[2] * lwt;
- new->rect[p4+3] += ctcol[3] * lwt;
- }
- wts->rect[p] += lwt;
- }
- }
- }
-
- }
- }
-
- // finally, normalize
- for (y=0; y<new->y; y++) {
- unsigned int p = y * new->x;
- unsigned int p4 = p * new->type;
- int x;
-
- for (x=0; x<new->x; x++) {
- float dv = (wts->rect[p]==0.f) ? 1.f : (1.f/wts->rect[p]);
- new->rect[p4] *= dv;
- if (new->type!=CB_VAL) {
- new->rect[p4+1] *= dv;
- new->rect[p4+2] *= dv;
- new->rect[p4+3] *= dv;
- }
- p++;
- p4 += new->type;
- }
- }
-
- free_compbuf(crad);
- free_compbuf(wts);
-
- printf("Done\n");
-}
-
-
-static void node_composit_exec_defocus(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *new, *old, *zbuf_use = NULL, *img = in[0]->data, *zbuf = in[1]->data;
- NodeDefocus *nqd = node->storage;
- int no_zbuf = nqd->no_zbuf;
-
- if ((img==NULL) || (out[0]->hasoutput==0)) return;
-
- // if image not valid type or fstop==infinite (128), nothing to do, pass in to out
- if (((img->type!=CB_RGBA) && (img->type!=CB_VAL)) || ((no_zbuf==0) && (nqd->fstop==128.f))) {
- out[0]->data = pass_on_compbuf(img);
- return;
- }
-
- if (zbuf!=NULL) {
- // Zbuf input, check to make sure, single channel, same size
- // doesn't have to be actual zbuffer, but must be value type
- if ((zbuf->x != img->x) || (zbuf->y != img->y)) {
- // could do a scale here instead...
- printf("Z input must be same size as image !\n");
- return;
- }
- zbuf_use = typecheck_compbuf(zbuf, CB_VAL);
- }
- else no_zbuf = 1; // no zbuffer input
-
- // ok, process
- old = img;
- if (nqd->gamco) {
- // gamma correct, blender func is simplified, fixed value & RGBA only,
- // should make user param. also depremul and premul afterwards, gamma
- // correction can't work with premul alpha
- old = dupalloc_compbuf(img);
- premul_compbuf(old, 1);
- gamma_correct_compbuf(old, 0);
- premul_compbuf(old, 0);
- }
-
- new = alloc_compbuf(old->x, old->y, old->type, 1);
- defocus_blur(node, new, old, zbuf_use, in[1]->vec[0]*nqd->scale, no_zbuf);
-
- if (nqd->gamco) {
- premul_compbuf(new, 1);
- gamma_correct_compbuf(new, 1);
- premul_compbuf(new, 0);
- free_compbuf(old);
- }
- if (node->exec & NODE_BREAK) {
- free_compbuf(new);
- new= NULL;
- }
- out[0]->data = new;
- if (zbuf_use && (zbuf_use != zbuf)) free_compbuf(zbuf_use);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
/* qdn: defocus node */
@@ -891,12 +67,8 @@ void register_node_type_cmp_defocus(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_DEFOCUS, "Defocus", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_defocus_in, cmp_node_defocus_out);
- node_type_size(&ntype, 150, 120, 200);
node_type_init(&ntype, node_composit_init_defocus);
node_type_storage(&ntype, "NodeDefocus", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_defocus);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_despeckle.c b/source/blender/nodes/composite/nodes/node_composite_despeckle.c
index 9d47e4bc276..816a1803e47 100644
--- a/source/blender/nodes/composite/nodes/node_composite_despeckle.c
+++ b/source/blender/nodes/composite/nodes/node_composite_despeckle.c
@@ -42,15 +42,6 @@ static bNodeSocketTemplate cmp_node_despeckle_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_despeckle(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
-{
- /* pass */
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_despeckle(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->custom3 = 0.5f;
@@ -63,11 +54,7 @@ void register_node_type_cmp_despeckle(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_DESPECKLE, "Despeckle", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_despeckle_in, cmp_node_despeckle_out);
- node_type_size(&ntype, 80, 40, 120);
node_type_init(&ntype, node_composit_init_despeckle);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_despeckle);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
index 014b72d3c60..29712d54e32 100644
--- a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c
@@ -45,91 +45,6 @@ static bNodeSocketTemplate cmp_node_diff_matte_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_diff_matte(bNode *node, float *outColor, float *inColor1, float *inColor2)
-{
- NodeChroma *c= (NodeChroma *)node->storage;
- float tolerance=c->t1;
- float fper=c->t2;
- /* get falloff amount over tolerance size */
- float falloff=(1.0f-fper) * tolerance;
- float difference;
- float alpha;
- float maxInputAlpha;
-
- /* average together the distances */
- difference= fabs(inColor2[0]-inColor1[0]) +
- fabs(inColor2[1]-inColor1[1]) +
- fabs(inColor2[2]-inColor1[2]);
- difference=difference/3.0f;
-
- copy_v3_v3(outColor, inColor1);
-
- if (difference <= tolerance) {
- if (difference <= falloff) {
- alpha = 0.0f;
- }
- else {
- /* alpha as percent (distance / tolerance), each modified by falloff amount (in pixels)*/
- alpha=(difference-falloff)/(tolerance-falloff);
- }
-
- /*only change if more transparent than either image */
- maxInputAlpha=max_ff(inColor1[3], inColor2[3]);
- if (alpha < maxInputAlpha) {
- /*clamp*/
- if (alpha < 0.0f) alpha = 0.0f;
- if (alpha > 1.0f) alpha = 1.0f;
- outColor[3] = alpha;
- }
- else { /* leave as before */
- outColor[3]=maxInputAlpha;
- }
- }
-}
-
-static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *outbuf= NULL;
- CompBuf *imbuf1= NULL;
- CompBuf *imbuf2= NULL;
- /* NodeChroma *c; */ /* UNUSED */
-
- /*is anything connected?*/
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
-
- /*must have an image imput*/
- if (in[0]->data==NULL) return;
-
-
- imbuf1=typecheck_compbuf(in[0]->data, CB_RGBA);
-
- /* if there's an image, use that, if not use the color */
- if (in[1]->data) {
- imbuf2=typecheck_compbuf(in[1]->data, CB_RGBA);
- }
-
- /* c=node->storage; */ /* UNUSED */
- outbuf=dupalloc_compbuf(imbuf1);
-
- /* note, processor gets a keyvals array passed on as buffer constant */
- composit2_pixel_processor(node, outbuf, imbuf1, in[0]->vec, imbuf2, in[1]->vec, do_diff_matte, CB_RGBA, CB_RGBA);
-
- out[0]->data=outbuf;
- if (out[1]->hasoutput)
- out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
- generate_preview(data, node, outbuf);
-
- if (imbuf1!=in[0]->data)
- free_compbuf(imbuf1);
-
- if (imbuf2!=in[1]->data)
- free_compbuf(imbuf2);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_diff_matte(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
@@ -144,12 +59,8 @@ void register_node_type_cmp_diff_matte(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_DIFF_MATTE, "Difference Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_diff_matte_in, cmp_node_diff_matte_out);
- node_type_size(&ntype, 200, 80, 250);
node_type_init(&ntype, node_composit_init_diff_matte);
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_diff_matte);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.c b/source/blender/nodes/composite/nodes/node_composite_dilate.c
index 9787c9f7145..fabc54f61b3 100644
--- a/source/blender/nodes/composite/nodes/node_composite_dilate.c
+++ b/source/blender/nodes/composite/nodes/node_composite_dilate.c
@@ -44,112 +44,6 @@ static bNodeSocketTemplate cmp_node_dilateerode_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void morpho_dilate(CompBuf *cbuf)
-{
- int x, y;
- float *p, *rectf = cbuf->rect;
-
- for (y = 0; y < cbuf->y; y++) {
- for (x = 0; x < cbuf->x - 1; x++) {
- p = rectf + cbuf->x * y + x;
- *p = max_ff(*p, *(p + 1));
- }
- }
-
- for (y = 0; y < cbuf->y; y++) {
- for (x = cbuf->x - 1; x >= 1; x--) {
- p = rectf + cbuf->x * y + x;
- *p = max_ff(*p, *(p - 1));
- }
- }
-
- for (x = 0; x < cbuf->x; x++) {
- for (y = 0; y < cbuf->y - 1; y++) {
- p = rectf + cbuf->x * y + x;
- *p = max_ff(*p, *(p + cbuf->x));
- }
- }
-
- for (x = 0; x < cbuf->x; x++) {
- for (y = cbuf->y - 1; y >= 1; y--) {
- p = rectf + cbuf->x * y + x;
- *p = max_ff(*p, *(p - cbuf->x));
- }
- }
-}
-
-static void morpho_erode(CompBuf *cbuf)
-{
- int x, y;
- float *p, *rectf = cbuf->rect;
-
- for (y = 0; y < cbuf->y; y++) {
- for (x = 0; x < cbuf->x - 1; x++) {
- p = rectf + cbuf->x * y + x;
- *p = min_ff(*p, *(p + 1));
- }
- }
-
- for (y = 0; y < cbuf->y; y++) {
- for (x = cbuf->x - 1; x >= 1; x--) {
- p = rectf + cbuf->x * y + x;
- *p = min_ff(*p, *(p - 1));
- }
- }
-
- for (x = 0; x < cbuf->x; x++) {
- for (y = 0; y < cbuf->y - 1; y++) {
- p = rectf + cbuf->x * y + x;
- *p = min_ff(*p, *(p + cbuf->x));
- }
- }
-
- for (x = 0; x < cbuf->x; x++) {
- for (y = cbuf->y - 1; y >= 1; y--) {
- p = rectf + cbuf->x * y + x;
- *p = min_ff(*p, *(p - cbuf->x));
- }
- }
-
-}
-
-static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: mask */
- /* stack order out: mask */
- if (out[0]->hasoutput == 0)
- return;
-
- /* input no image? then only color operation */
- if (in[0]->data == NULL) {
- zero_v4(out[0]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_VAL);
- CompBuf *stackbuf = dupalloc_compbuf(cbuf);
- short i;
-
- if (node->custom2 > 0) { // positive, dilate
- for (i = 0; i < node->custom2; i++)
- morpho_dilate(stackbuf);
- }
- else if (node->custom2 < 0) { // negative, erode
- for (i = 0; i > node->custom2; i--)
- morpho_erode(stackbuf);
- }
-
- if (cbuf != in[0]->data)
- free_compbuf(cbuf);
-
- out[0]->data = stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_dilateerode(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeDilateErode *data = MEM_callocN(sizeof(NodeDilateErode), "NodeDilateErode");
@@ -163,11 +57,7 @@ void register_node_type_cmp_dilateerode(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_DILATEERODE, "Dilate/Erode", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_dilateerode_in, cmp_node_dilateerode_out);
- node_type_size(&ntype, 130, 100, 320);
node_type_init(&ntype, node_composit_init_dilateerode);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_dilateerode);
-#endif
node_type_storage(&ntype, "NodeDilateErode", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c
index a343315264d..6197d78563c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c
@@ -42,90 +42,6 @@ static bNodeSocketTemplate cmp_node_dblur_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static CompBuf *dblur(bNode *node, CompBuf *img, int iterations, int wrap,
- float center_x, float center_y, float dist, float angle, float spin, float zoom)
-{
- if ((dist != 0.f) || (spin != 0.f) || (zoom != 0.f)) {
- void (*getpix)(CompBuf *, float, float, float *) = wrap ? qd_getPixelLerpWrap : qd_getPixelLerp;
- const float a = angle;
- const float itsc = 1.f / powf(2.f, (float)iterations);
- float D;
- float center_x_pix, center_y_pix;
- float tx, ty;
- float sc, rot;
- CompBuf *tmp;
- int i, j;
-
- tmp = dupalloc_compbuf(img);
-
- D = dist * sqrtf(img->x * img->x + img->y * img->y);
- center_x_pix = center_x * img->x;
- center_y_pix = center_y * img->y;
-
- tx = itsc * D * cosf(a);
- ty = -itsc * D * sinf(a);
- sc = itsc * zoom;
- rot = itsc * spin;
-
- /* blur the image */
- for (i = 0; i < iterations; ++i) {
- const float cs = cosf(rot), ss = sinf(rot);
- const float isc = 1.f / (1.f + sc);
- unsigned int x, y;
- float col[4] = {0, 0, 0, 0};
-
- for (y = 0; y < img->y; ++y) {
- const float v = isc * (y - center_y_pix) + ty;
-
- for (x = 0; x < img->x; ++x) {
- const float u = isc * (x - center_x_pix) + tx;
- unsigned int p = (x + y * img->x) * img->type;
-
- getpix(tmp, cs * u + ss * v + center_x_pix, cs * v - ss * u + center_y_pix, col);
-
- /* mix img and transformed tmp */
- for (j = 0; j < 4; ++j) {
- img->rect[p + j] = 0.5f * (img->rect[p + j] + col[j]);
- }
- }
- }
-
- /* copy img to tmp */
- if (i != (iterations - 1))
- memcpy(tmp->rect, img->rect, sizeof(float) * img->x * img->y * img->type);
-
- /* double transformations */
- tx *= 2.f, ty *= 2.f;
- sc *= 2.f, rot *= 2.f;
-
- if (node->exec & NODE_BREAK) break;
- }
-
- free_compbuf(tmp);
- }
-
- return img;
-}
-
-static void node_composit_exec_dblur(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- NodeDBlurData *ndbd = node->storage;
- CompBuf *new, *img = in[0]->data;
-
- if ((img == NULL) || (out[0]->hasoutput == 0)) return;
-
- if (img->type != CB_RGBA)
- new = typecheck_compbuf(img, CB_RGBA);
- else
- new = dupalloc_compbuf(img);
-
- out[0]->data = dblur(node, new, ndbd->iter, ndbd->wrap, ndbd->center_x, ndbd->center_y, ndbd->distance, ndbd->angle, ndbd->spin, ndbd->zoom);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_dblur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeDBlurData *ndbd = MEM_callocN(sizeof(NodeDBlurData), "node dblur data");
@@ -140,12 +56,8 @@ void register_node_type_cmp_dblur(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_DBLUR, "Directional Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_dblur_in, cmp_node_dblur_out);
- node_type_size(&ntype, 150, 120, 200);
node_type_init(&ntype, node_composit_init_dblur);
node_type_storage(&ntype, "NodeDBlurData", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_dblur);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_displace.c b/source/blender/nodes/composite/nodes/node_composite_displace.c
index c07ad0a0c97..251345d8a28 100644
--- a/source/blender/nodes/composite/nodes/node_composite_displace.c
+++ b/source/blender/nodes/composite/nodes/node_composite_displace.c
@@ -47,155 +47,12 @@ static bNodeSocketTemplate cmp_node_displace_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* minimum distance (in pixels) a pixel has to be displaced
- * in order to take effect */
-#define DISPLACE_EPSILON 0.01f
-
-static void do_displace(bNode *node, CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *UNUSED(veccol), CompBuf *xbuf, CompBuf *ybuf, float *xscale, float *yscale)
-{
- ImBuf *ibuf;
- int x, y;
- float p_dx, p_dy; /* main displacement in pixel space */
- float d_dx, d_dy;
- float dxt, dyt;
- float u, v;
- float xs, ys;
- float vec[3], vecdx[3], vecdy[3];
- float col[3];
-
- ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
- ibuf->rect_float= cbuf->rect;
-
- for (y=0; y < stackbuf->y; y++) {
- for (x=0; x < stackbuf->x; x++) {
- /* calc pixel coordinates */
- qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof, vec);
-
- if (xbuf)
- qd_getPixel(xbuf, x-xbuf->xof, y-xbuf->yof, &xs);
- else
- xs = xscale[0];
-
- if (ybuf)
- qd_getPixel(ybuf, x-ybuf->xof, y-ybuf->yof, &ys);
- else
- ys = yscale[0];
-
- /* clamp x and y displacement to triple image resolution -
- * to prevent hangs from huge values mistakenly plugged in eg. z buffers */
- CLAMP(xs, -stackbuf->x*4, stackbuf->x*4);
- CLAMP(ys, -stackbuf->y*4, stackbuf->y*4);
-
- p_dx = vec[0] * xs;
- p_dy = vec[1] * ys;
-
- /* if no displacement, then just copy this pixel */
- if (fabsf(p_dx) < DISPLACE_EPSILON && fabsf(p_dy) < DISPLACE_EPSILON) {
- qd_getPixel(cbuf, x-cbuf->xof, y-cbuf->yof, col);
- qd_setPixel(stackbuf, x, y, col);
- continue;
- }
-
- /* displaced pixel in uv coords, for image sampling */
- u = (x - cbuf->xof - p_dx + 0.5f) / (float)stackbuf->x;
- v = (y - cbuf->yof - p_dy + 0.5f) / (float)stackbuf->y;
-
-
- /* calc derivatives */
- qd_getPixel(vecbuf, x-vecbuf->xof+1, y-vecbuf->yof, vecdx);
- qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof+1, vecdy);
- d_dx = vecdx[0] * xs;
- d_dy = vecdy[1] * ys;
-
- /* clamp derivatives to minimum displacement distance in UV space */
- dxt = p_dx - d_dx;
- dyt = p_dy - d_dy;
-
- dxt = signf(dxt)*max_ff(fabsf(dxt), DISPLACE_EPSILON)/(float)stackbuf->x;
- dyt = signf(dyt)*max_ff(fabsf(dyt), DISPLACE_EPSILON)/(float)stackbuf->y;
-
- ibuf_sample(ibuf, u, v, dxt, dyt, col);
- qd_setPixel(stackbuf, x, y, col);
-
- if (node->exec & NODE_BREAK) break;
- }
-
- if (node->exec & NODE_BREAK) break;
- }
- IMB_freeImBuf(ibuf);
-
-
-/* simple method for reference, linear interpolation */
-#if 0
- int x, y;
- float dx, dy;
- float u, v;
- float vec[3];
- float col[3];
-
- for (y=0; y < stackbuf->y; y++) {
- for (x=0; x < stackbuf->x; x++) {
- qd_getPixel(vecbuf, x, y, vec);
-
- dx = vec[0] * (xscale[0]);
- dy = vec[1] * (yscale[0]);
-
- u = (x - dx + 0.5f) / (float)stackbuf->x;
- v = (y - dy + 0.5f) / (float)stackbuf->y;
-
- qd_getPixelLerp(cbuf, u*cbuf->x - 0.5f, v*cbuf->y - 0.5f, col);
- qd_setPixel(stackbuf, x, y, col);
- }
- }
-#endif
-}
-
-
-static void node_composit_exec_displace(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (out[0]->hasoutput==0)
- return;
-
- if (in[0]->data && in[1]->data) {
- CompBuf *cbuf= in[0]->data;
- CompBuf *vecbuf= in[1]->data;
- CompBuf *xbuf= in[2]->data;
- CompBuf *ybuf= in[3]->data;
- CompBuf *stackbuf;
-
- cbuf= typecheck_compbuf(cbuf, CB_RGBA);
- vecbuf= typecheck_compbuf(vecbuf, CB_VEC3);
- xbuf= typecheck_compbuf(xbuf, CB_VAL);
- ybuf= typecheck_compbuf(ybuf, CB_VAL);
-
- stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- do_displace(node, stackbuf, cbuf, vecbuf, in[1]->vec, xbuf, ybuf, in[2]->vec, in[3]->vec);
-
- out[0]->data= stackbuf;
-
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
- if (vecbuf!=in[1]->data)
- free_compbuf(vecbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_displace(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_DISPLACE, "Displace", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_displace_in, cmp_node_displace_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_displace);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
index 7e605865cd2..26f8055e7f2 100644
--- a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
@@ -45,147 +45,6 @@ static bNodeSocketTemplate cmp_node_distance_matte_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* note, keyvals is passed on from caller as stack array */
-/* might have been nicer as temp struct though... */
-static void do_distance_matte(bNode *node, float *out, float *in)
-{
- NodeChroma *c= (NodeChroma *)node->storage;
- float tolerance=c->t1;
- float fper=c->t2;
- /* get falloff amount over tolerance size */
- float falloff=(1.0f-fper) * tolerance;
- float distance;
- float alpha;
-
- distance=sqrt((c->key[0]-in[0])*(c->key[0]-in[0]) +
- (c->key[1]-in[1])*(c->key[1]-in[1]) +
- (c->key[2]-in[2])*(c->key[2]-in[2]));
-
- copy_v3_v3(out, in);
-
- if (distance <= tolerance) {
- if (distance <= falloff) {
- alpha = 0.0f;
- }
- else {
- /* alpha as percent (distance / tolerance), each modified by falloff amount (in pixels)*/
- alpha=(distance-falloff)/(tolerance-falloff);
- }
-
- /*only change if more transparent than before */
- if (alpha < in[3]) {
- /*clamp*/
- if (alpha < 0.0f) alpha = 0.0f;
- if (alpha > 1.0f) alpha = 1.0f;
- out[3]=alpha;
- }
- else { /* leave as before */
- out[3]=in[3];
- }
- }
-}
-
-static void do_chroma_distance_matte(bNode *node, float *out, float *in)
-{
- NodeChroma *c= (NodeChroma *)node->storage;
- float tolerance=c->t1;
- float fper=c->t2;
- /* get falloff amount over tolerance size */
- float falloff=(1.0f-fper) * tolerance;
- float y_key, cb_key, cr_key;
- float y_pix, cb_pix, cr_pix;
- float distance;
- float alpha;
-
- /*convert key to chroma colorspace */
- rgb_to_ycc(c->key[0], c->key[1], c->key[2], &y_key, &cb_key, &cr_key, BLI_YCC_JFIF_0_255);
- /* normalize the values */
- cb_key=cb_key/255.0f;
- cr_key=cr_key/255.0f;
-
- /*convert pixel to chroma colorspace */
- rgb_to_ycc(in[0], in[1], in[2], &y_pix, &cb_pix, &cr_pix, BLI_YCC_JFIF_0_255);
- /*normalize the values */
- cb_pix=cb_pix/255.0f;
- cr_pix=cr_pix/255.0f;
-
- distance=sqrt((cb_key-cb_pix)*(cb_key-cb_pix) +
- (cr_key-cr_pix)*(cr_key-cr_pix));
-
- copy_v3_v3(out, in);
-
- if (distance <= tolerance) {
- if (distance <= falloff) {
- alpha = 0.0f;
- }
- else {
- /* alpha as percent (distance / tolerance), each modified by falloff amount (in pixels)*/
- alpha=(distance-falloff)/(tolerance-falloff);
- }
-
- /*only change if more transparent than before */
- if (alpha < in[3]) {
- /*clamp*/
- if (alpha < 0.0f) alpha = 0.0f;
- if (alpha > 1.0f) alpha = 1.0f;
- out[3]=alpha;
- }
- else { /* leave as before */
- out[3]=in[3];
- }
- }
-}
-
-static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /*
- * Loosely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and
- * uses a different difference function (suggested in forums of vfxtalk.com).
- */
- CompBuf *workbuf;
- CompBuf *inbuf;
- NodeChroma *c;
-
- /*is anything connected?*/
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
- /*must have an image imput*/
- if (in[0]->data==NULL) return;
-
- inbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
-
- c=node->storage;
- workbuf=dupalloc_compbuf(inbuf);
-
- /*use the input color*/
- c->key[0] = in[1]->vec[0];
- c->key[1] = in[1]->vec[1];
- c->key[2] = in[1]->vec[2];
-
- /* work in RGB color space */
- if (c->channel == 1) {
- /* note, processor gets a keyvals array passed on as buffer constant */
- composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA);
- }
- /* work in YCbCr color space */
- else {
- composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_chroma_distance_matte, CB_RGBA);
- }
-
-
-
- out[0]->data=workbuf;
- if (out[1]->hasoutput)
- out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A);
- generate_preview(data, node, workbuf);
-
- if (inbuf!=in[0]->data)
- free_compbuf(inbuf);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_distance_matte(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
@@ -201,12 +60,8 @@ void register_node_type_cmp_distance_matte(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_DIST_MATTE, "Distance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_distance_matte_in, cmp_node_distance_matte_out);
- node_type_size(&ntype, 200, 80, 250);
node_type_init(&ntype, node_composit_init_distance_matte);
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_distance_matte);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c b/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c
index 3c1e3ee443e..d5dd63a4042 100644
--- a/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_doubleEdgeMask.c
@@ -42,1249 +42,12 @@ static bNodeSocketTemplate cmp_node_doubleedgemask_out[] = {
{ -1, 0, "" } // output socket array terminator
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_adjacentKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize)
-{
- int x;
- unsigned int isz=0; // inner edge size
- unsigned int osz=0; // outer edge size
- unsigned int gsz=0; // gradient fill area size
- /* Test the four corners */
- /* upper left corner */
- x=t-rw+1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or to the right, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- /* upper right corner */
- x=t;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or to the left, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- /* lower left corner */
- x=0;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel above, or to the right, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- /* lower right corner */
- x=rw-1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel above, or to the left, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
-
- /* Test the TOP row of pixels in buffer, except corners */
- for (x= t-1; x>=(t-rw)+2; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel to the right, or to the left, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
-
- /* Test the BOTTOM row of pixels in buffer, except corners */
- for (x= rw-2; x; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel to the right, or to the left, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
- /* Test the LEFT edge of pixels in buffer, except corners */
- for (x= t-(rw<<1)+1; x>=rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or above, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
-
- /* Test the RIGHT edge of pixels in buffer, except corners */
- for (x= t-rw; x>rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or above, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
-
- rsize[0]=isz; // fill in our return sizes for edges + fill
- rsize[1]=osz;
- rsize[2]=gsz;
-}
-
-static void do_adjacentBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize)
-{
- int x;
- unsigned int isz=0; // inner edge size
- unsigned int osz=0; // outer edge size
- unsigned int gsz=0; // gradient fill area size
- /* Test the four corners */
- /* upper left corner */
- x=t-rw+1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or to the right, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* upper right corner */
- x=t;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or to the left, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x-1] && lomask[x-1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* lower left corner */
- x=0;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel above, or to the right, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty above or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* lower right corner */
- x=rw-1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel above, or to the left, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x+rw] && lomask[x+rw]) || (!limask[x-1] && lomask[x-1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* Test the TOP row of pixels in buffer, except corners */
- for (x= t-1; x>=(t-rw)+2; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel to the left, or to the right, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
-
- /* Test the BOTTOM row of pixels in buffer, except corners */
- for (x= rw-2; x; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel to the left, or to the right, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-1] && lomask[x-1]) || (!limask[x+1] && lomask[x+1])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
- /* Test the LEFT edge of pixels in buffer, except corners */
- for (x= t-(rw<<1)+1; x>=rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or above, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
-
- /* Test the RIGHT edge of pixels in buffer, except corners */
- for (x= t-rw; x>rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if pixel underneath, or above, are empty in the inner mask,
- // but filled in the outer mask
- if ((!limask[x-rw] && lomask[x-rw]) || (!limask[x+rw] && lomask[x+rw])) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
-
- rsize[0]=isz; // fill in our return sizes for edges + fill
- rsize[1]=osz;
- rsize[2]=gsz;
-}
-
-static void do_allKeepBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize)
-{
- int x;
- unsigned int isz=0; // inner edge size
- unsigned int osz=0; // outer edge size
- unsigned int gsz=0; // gradient fill area size
- /* Test the four corners */
- /* upper left corner */
- x=t-rw+1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if the inner mask is empty underneath or to the right
- if (!limask[x-rw] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- /* upper right corner */
- x=t;
- // test if inner mask is filled
- if (limask[x]) {
- // test if the inner mask is empty underneath or to the left
- if (!limask[x-rw] || !limask[x-1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- /* lower left corner */
- x=0;
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty above or to the right
- if (!limask[x+rw] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- /* lower right corner */
- x=rw-1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty above or to the left
- if (!limask[x+rw] || !limask[x-1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
-
- /* Test the TOP row of pixels in buffer, except corners */
- for (x= t-1; x>=(t-rw)+2; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty to the left or to the right
- if (!limask[x-1] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
-
- /* Test the BOTTOM row of pixels in buffer, except corners */
- for (x= rw-2; x; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty to the left or to the right
- if (!limask[x-1] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
- /* Test the LEFT edge of pixels in buffer, except corners */
- for (x= t-(rw<<1)+1; x>=rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty underneath or above
- if (!limask[x-rw] || !limask[x+rw]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
-
- /* Test the RIGHT edge of pixels in buffer, except corners */
- for (x= t-rw; x>rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty underneath or above
- if (!limask[x-rw] || !limask[x+rw]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- }
-
- rsize[0]=isz; // fill in our return sizes for edges + fill
- rsize[1]=osz;
- rsize[2]=gsz;
-}
-
-static void do_allBleedBorders(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize)
-{
- int x;
- unsigned int isz=0; // inner edge size
- unsigned int osz=0; // outer edge size
- unsigned int gsz=0; // gradient fill area size
- /* Test the four corners */
- /* upper left corner */
- x=t-rw+1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if the inner mask is empty underneath or to the right
- if (!limask[x-rw] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* upper right corner */
- x=t;
- // test if inner mask is filled
- if (limask[x]) {
- // test if the inner mask is empty underneath or to the left
- if (!limask[x-rw] || !limask[x-1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x-1]) { // test if outer mask is empty above or to the left
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* lower left corner */
- x=0;
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty above or to the right
- if (!limask[x+rw] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x+rw] || !lomask[x+1]) { // test if outer mask is empty underneath or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* lower right corner */
- x=rw-1;
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty above or to the left
- if (!limask[x+rw] || !limask[x-1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x+rw] || !lomask[x-1]) { // test if outer mask is empty underneath or to the left
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- /* Test the TOP row of pixels in buffer, except corners */
- for (x= t-1; x>=(t-rw)+2; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty to the left or to the right
- if (!limask[x-1] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
-
- /* Test the BOTTOM row of pixels in buffer, except corners */
- for (x= rw-2; x; x--) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty to the left or to the right
- if (!limask[x-1] || !limask[x+1]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-1] || !lomask[x+1]) { // test if outer mask is empty to the left or to the right
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
- /* Test the LEFT edge of pixels in buffer, except corners */
- for (x= t-(rw<<1)+1; x>=rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty underneath or above
- if (!limask[x-rw] || !limask[x+rw]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
-
- /* Test the RIGHT edge of pixels in buffer, except corners */
- for (x= t-rw; x>rw; x-=rw) {
- // test if inner mask is filled
- if (limask[x]) {
- // test if inner mask is empty underneath or above
- if (!limask[x-rw] || !limask[x+rw]) {
- isz++; // increment inner edge size
- lres[x]=4; // flag pixel as inner edge
- }
- else {
- res[x]=1.0f; // pixel is just part of inner mask, and it's not an edge
- }
- }
- else if (lomask[x]) { // inner mask was empty, test if outer mask is filled
- if (!lomask[x-rw] || !lomask[x+rw]) { // test if outer mask is empty underneath or above
- osz++; // increment outer edge size
- lres[x]=3; // flag pixel as outer edge
- }
- else {
- gsz++; // increment the gradient pixel count
- lres[x]=2; // flag pixel as gradient
- }
- }
- }
-
- rsize[0]=isz; // fill in our return sizes for edges + fill
- rsize[1]=osz;
- rsize[2]=gsz;
-}
-
-static void do_allEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz)
-{
- int x; // x = pixel loop counter
- int a; // a = pixel loop counter
- int dx; // dx = delta x
- int pix_prevRow; // pix_prevRow = pixel one row behind the one we are testing in a loop
- int pix_nextRow; // pix_nextRow = pixel one row in front of the one we are testing in a loop
- int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop
- int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop
- /* Test all rows between the FIRST and LAST rows, excluding left and right edges */
- for (x= (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw, dx-=rw) {
- a=x-2;
- pix_prevRow=a+rw;
- pix_nextRow=a-rw;
- pix_prevCol=a+1;
- pix_nextCol=a-1;
- while (a>dx-2) {
- if (!limask[a]) { // if the inner mask is empty
- if (lomask[a]) { // if the outer mask is full
- /*
- * Next we test all 4 directions around the current pixel: next/prev/up/down
- * The test ensures that the outer mask is empty and that the inner mask
- * is also empty. If both conditions are true for any one of the 4 adjacent pixels
- * then the current pixel is counted as being a true outer edge pixel.
- */
- if ((!lomask[pix_nextCol] && !limask[pix_nextCol]) ||
- (!lomask[pix_prevCol] && !limask[pix_prevCol]) ||
- (!lomask[pix_nextRow] && !limask[pix_nextRow]) ||
- (!lomask[pix_prevRow] && !limask[pix_prevRow]))
- {
- in_osz++; // increment the outer boundary pixel count
- lres[a]=3; // flag pixel as part of outer edge
- }
- else { // it's not a boundary pixel, but it is a gradient pixel
- in_gsz++; // increment the gradient pixel count
- lres[a]=2; // flag pixel as gradient
- }
- }
-
- }
- else {
- if (!limask[pix_nextCol] || !limask[pix_prevCol] || !limask[pix_nextRow] || !limask[pix_prevRow]) {
- in_isz++; // increment the inner boundary pixel count
- lres[a]=4; // flag pixel as part of inner edge
- }
- else {
- res[a]=1.0f; // pixel is part of inner mask, but not at an edge
- }
- }
- a--;
- pix_prevRow--;
- pix_nextRow--;
- pix_prevCol--;
- pix_nextCol--;
- }
- }
-
- rsize[0]=in_isz; // fill in our return sizes for edges + fill
- rsize[1]=in_osz;
- rsize[2]=in_gsz;
-}
-
-static void do_adjacentEdgeDetection(unsigned int t, unsigned int rw, unsigned int *limask, unsigned int *lomask, unsigned int *lres, float *res, unsigned int *rsize, unsigned int in_isz, unsigned int in_osz, unsigned int in_gsz)
-{
- int x; // x = pixel loop counter
- int a; // a = pixel loop counter
- int dx; // dx = delta x
- int pix_prevRow; // pix_prevRow = pixel one row behind the one we are testing in a loop
- int pix_nextRow; // pix_nextRow = pixel one row in front of the one we are testing in a loop
- int pix_prevCol; // pix_prevCol = pixel one column behind the one we are testing in a loop
- int pix_nextCol; // pix_nextCol = pixel one column in front of the one we are testing in a loop
- /* Test all rows between the FIRST and LAST rows, excluding left and right edges */
- for (x= (t-rw)+1, dx=x-(rw-2); dx>rw; x-=rw, dx-=rw) {
- a=x-2;
- pix_prevRow=a+rw;
- pix_nextRow=a-rw;
- pix_prevCol=a+1;
- pix_nextCol=a-1;
- while (a>dx-2) {
- if (!limask[a]) { // if the inner mask is empty
- if (lomask[a]) { // if the outer mask is full
- /*
- * Next we test all 4 directions around the current pixel: next/prev/up/down
- * The test ensures that the outer mask is empty and that the inner mask
- * is also empty. If both conditions are true for any one of the 4 adjacent pixels
- * then the current pixel is counted as being a true outer edge pixel.
- */
- if ((!lomask[pix_nextCol] && !limask[pix_nextCol]) ||
- (!lomask[pix_prevCol] && !limask[pix_prevCol]) ||
- (!lomask[pix_nextRow] && !limask[pix_nextRow]) ||
- (!lomask[pix_prevRow] && !limask[pix_prevRow]))
- {
- in_osz++; // increment the outer boundary pixel count
- lres[a]=3; // flag pixel as part of outer edge
- }
- else { // it's not a boundary pixel, but it is a gradient pixel
- in_gsz++; // increment the gradient pixel count
- lres[a]=2; // flag pixel as gradient
- }
- }
-
- }
- else {
- if ((!limask[pix_nextCol] && lomask[pix_nextCol]) ||
- (!limask[pix_prevCol] && lomask[pix_prevCol]) ||
- (!limask[pix_nextRow] && lomask[pix_nextRow]) ||
- (!limask[pix_prevRow] && lomask[pix_prevRow]))
- {
- in_isz++; // increment the inner boundary pixel count
- lres[a]=4; // flag pixel as part of inner edge
- }
- else {
- res[a]=1.0f; // pixel is part of inner mask, but not at an edge
- }
- }
- a--;
- pix_prevRow--; // advance all four "surrounding" pixel pointers
- pix_nextRow--;
- pix_prevCol--;
- pix_nextCol--;
- }
- }
-
- rsize[0]=in_isz; // fill in our return sizes for edges + fill
- rsize[1]=in_osz;
- rsize[2]=in_gsz;
-}
-
-static void do_createEdgeLocationBuffer(unsigned int t, unsigned int rw, unsigned int *lres, float *res, unsigned short *gbuf, unsigned int *innerEdgeOffset, unsigned int *outerEdgeOffset, unsigned int isz, unsigned int gsz)
-{
- int x; // x = pixel loop counter
- int a; // a = temporary pixel index buffer loop counter
- unsigned int ud; // ud = unscaled edge distance
- unsigned int dmin; // dmin = minimum edge distance
-
- unsigned int rsl; // long used for finding fast 1.0/sqrt
- unsigned int gradientFillOffset;
- unsigned int innerAccum=0; // for looping inner edge pixel indexes, represents current position from offset
- unsigned int outerAccum=0; // for looping outer edge pixel indexes, represents current position from offset
- unsigned int gradientAccum=0; // for looping gradient pixel indexes, represents current position from offset
- /*
- * Here we compute the size of buffer needed to hold (row, col) coordinates
- * for each pixel previously determined to be either gradient, inner edge,
- * or outer edge.
- *
- * Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even
- * though gbuf[] is declared as unsigned short* (2 bytes) because we don't
- * store the pixel indexes, we only store x, y location of pixel in buffer.
- *
- * This does make the assumption that x and y can fit in 16 unsigned bits
- * so if Blender starts doing renders greater than 65536 in either direction
- * this will need to allocate gbuf[] as unsigned int* and allocate 8 bytes
- * per flagged pixel.
- *
- * In general, the buffer on-screen:
- *
- * Example: 9 by 9 pixel block
- *
- * . = pixel non-white in both outer and inner mask
- * o = pixel white in outer, but not inner mask, adjacent to "." pixel
- * g = pixel white in outer, but not inner mask, not adjacent to "." pixel
- * i = pixel white in inner mask, adjacent to "g" or "." pixel
- * F = pixel white in inner mask, only adjacent to other pixels white in the inner mask
- *
- *
- * ......... <----- pixel #80
- * ..oooo...
- * .oggggo..
- * .oggiggo.
- * .ogiFigo.
- * .oggiggo.
- * .oggggo..
- * ..oooo...
- * pixel #00 -----> .........
- *
- * gsz = 18 (18 "g" pixels above)
- * isz = 4 (4 "i" pixels above)
- * osz = 18 (18 "o" pixels above)
- *
- *
- * The memory in gbuf[] after filling will look like this:
- *
- * gradientFillOffset (0 pixels) innerEdgeOffset (18 pixels) outerEdgeOffset (22 pixels)
- * / / /
- * / / /
- * |X Y X Y X Y X Y > <X Y X Y > <X Y X Y X Y > <X Y X Y | <- (x, y)
- * +--------------------------------> <----------------> <------------------------> <----------------+
- * |0 2 4 6 8 10 12 14 > ... <68 70 72 74 > ... <80 82 84 86 88 90 > ... <152 154 156 158 | <- bytes
- * +--------------------------------> <----------------> <------------------------> <----------------+
- * |g0 g0 g1 g1 g2 g2 g3 g3 > <g17 g17 i0 i0 > <i2 i2 i3 i3 o0 o0 > <o16 o16 o17 o17 | <- pixel
- * / / /
- * / / /
- * / / /
- * +---------- gradientAccum (18) ---------+ +--- innerAccum (22) ---+ +--- outerAccum (40) ---+
- *
- *
- * Ultimately we do need the pixel's memory buffer index to set the output
- * pixel color, but it's faster to reconstruct the memory buffer location
- * each iteration of the final gradient calculation than it is to deconstruct
- * a memory location into x, y pairs each round.
- */
-
-
- gradientFillOffset=0; // since there are likely "more" of these, put it first. :)
- *innerEdgeOffset=gradientFillOffset+gsz; // set start of inner edge indexes
- *outerEdgeOffset=(*innerEdgeOffset)+isz; // set start of outer edge indexes
- /* set the accumulators to correct positions */ // set up some accumulator variables for loops
- gradientAccum = gradientFillOffset; // each accumulator variable starts at its respective
- innerAccum = *innerEdgeOffset; // section's offset so when we start filling, each
- outerAccum = *outerEdgeOffset; // section fills up it's allocated space in gbuf
- //uses dmin=row, rsl=col
- for (x=0, dmin=0; x<t; x+=rw, dmin++) {
- for (rsl=0; rsl<rw; rsl++) {
- a=x+rsl;
- if (lres[a]==2) { // it is a gradient pixel flagged by 2
- ud=gradientAccum<<1; // double the index to reach correct unsigned short location
- gbuf[ud]=dmin; // insert pixel's row into gradient pixel location buffer
- gbuf[ud+1]=rsl; // insert pixel's column into gradient pixel location buffer
- gradientAccum++; // increment gradient index buffer pointer
- }
- else if (lres[a]==3) { // it is an outer edge pixel flagged by 3
- ud=outerAccum<<1; // double the index to reach correct unsigned short location
- gbuf[ud]=dmin; // insert pixel's row into outer edge pixel location buffer
- gbuf[ud+1]=rsl; // insert pixel's column into outer edge pixel location buffer
- outerAccum++; // increment outer edge index buffer pointer
- res[a]=0.0f; // set output pixel intensity now since it won't change later
- }
- else if (lres[a]==4) { // it is an inner edge pixel flagged by 4
- ud=innerAccum<<1; // double int index to reach correct unsigned short location
- gbuf[ud]=dmin; // insert pixel's row into inner edge pixel location buffer
- gbuf[ud+1]=rsl; // insert pixel's column into inner edge pixel location buffer
- innerAccum++; // increment inner edge index buffer pointer
- res[a]=1.0f; // set output pixel intensity now since it won't change later
- }
- }
- }
-
-}
-
-static void do_fillGradientBuffer(unsigned int rw, float *res, unsigned short *gbuf, unsigned int isz, unsigned int osz, unsigned int gsz, unsigned int innerEdgeOffset, unsigned int outerEdgeOffset)
-{
- int x; // x = pixel loop counter
- int a; // a = temporary pixel index buffer loop counter
- int fsz; // size of the frame
- unsigned int rsl; // long used for finding fast 1.0/sqrt
- float rsf; // float used for finding fast 1.0/sqrt
- const float rsopf = 1.5f; // constant float used for finding fast 1.0/sqrt
-
- unsigned int gradientFillOffset;
- unsigned int t;
- unsigned int ud; // ud = unscaled edge distance
- unsigned int dmin; // dmin = minimum edge distance
- float odist; // odist = current outer edge distance
- float idist; // idist = current inner edge distance
- int dx; // dx = X-delta (used for distance proportion calculation)
- int dy; // dy = Y-delta (used for distance proportion calculation)
- /*
- * The general algorithm used to color each gradient pixel is:
- *
- * 1.) Loop through all gradient pixels.
- * A.) For each gradient pixel:
- * a.) Loop though all outside edge pixels, looking for closest one
- * to the gradient pixel we are in.
- * b.) Loop through all inside edge pixels, looking for closest one
- * to the gradient pixel we are in.
- * c.) Find proportion of distance from gradient pixel to inside edge
- * pixel compared to sum of distance to inside edge and distance to
- * outside edge.
- *
- * In an image where:
- * . = blank (black) pixels, not covered by inner mask or outer mask
- * + = desired gradient pixels, covered only by outer mask
- * * = white full mask pixels, covered by at least inner mask
- *
- * ...............................
- * ...............+++++++++++.....
- * ...+O++++++..++++++++++++++....
- * ..+++\++++++++++++++++++++.....
- * .+++++G+++++++++*******+++.....
- * .+++++|+++++++*********+++.....
- * .++***I****************+++.....
- * .++*******************+++......
- * .+++*****************+++.......
- * ..+++***************+++........
- * ....+++**********+++...........
- * ......++++++++++++.............
- * ...............................
- *
- * O = outside edge pixel
- * \
- * G = gradient pixel
- * |
- * I = inside edge pixel
- *
- * __
- * *note that IO does not need to be a straight line, in fact
- * many cases can arise where straight lines do not work
- * correctly.
- *
- * __ __ __
- * d.) Pixel color is assigned as |GO| / ( |GI| + |GO| )
- *
- * The implementation does not compute distance, but the reciprocal of the
- * distance. This is done to avoid having to compute a square root, as a
- * reciprocal square root can be computed faster. Therefore, the code computes
- * pixel color as |GI| / (|GI| + |GO|). Since these are reciprocals, GI serves the
- * purpose of GO for the proportion calculation.
- *
- * For the purposes of the minimum distance comparisons, we only check
- * the sums-of-squares against each other, since they are in the same
- * mathematical sort-order as if we did go ahead and take square roots
- *
- * Loop through all gradient pixels.
- */
-
- for (x= gsz-1; x>=0; x--) {
- gradientFillOffset=x<<1;
- t=gbuf[gradientFillOffset]; // calculate column of pixel indexed by gbuf[x]
- fsz=gbuf[gradientFillOffset+1]; // calculate row of pixel indexed by gbuf[x]
- dmin=0xffffffff; // reset min distance to edge pixel
- for (a=outerEdgeOffset+osz-1; a>=outerEdgeOffset; a--) { // loop through all outer edge buffer pixels
- ud=a<<1;
- dy=t-gbuf[ud]; // set dx to gradient pixel column - outer edge pixel row
- dx=fsz-gbuf[ud+1]; // set dy to gradient pixel row - outer edge pixel column
- ud=dx*dx+dy*dy; // compute sum of squares
- if (ud<dmin) { // if our new sum of squares is less than the current minimum
- dmin=ud; // set a new minimum equal to the new lower value
- }
- }
- odist=(float)(dmin); // cast outer min to a float
- rsf=odist*0.5f; //
- rsl=*(unsigned int*)&odist; // use some peculiar properties of the way bits are stored
- rsl=0x5f3759df-(rsl>>1); // in floats vs. unsigned ints to compute an approximate
- odist=*(float*)&rsl; // reciprocal square root
- odist=odist*(rsopf-(rsf*odist*odist)); // -- ** this line can be iterated for more accuracy ** --
- dmin=0xffffffff; // reset min distance to edge pixel
- for (a= innerEdgeOffset+isz-1; a>=innerEdgeOffset; a--) { // loop through all inside edge pixels
- ud=a<<1;
- dy=t-gbuf[ud]; // compute delta in Y from gradient pixel to inside edge pixel
- dx=fsz-gbuf[ud+1]; // compute delta in X from gradient pixel to inside edge pixel
- ud=dx*dx+dy*dy; // compute sum of squares
- if (ud<dmin) { // if our new sum of squares is less than the current minimum we've found
- dmin=ud; // set a new minimum equal to the new lower value
- }
- }
- idist=(float)(dmin); // cast inner min to a float
- rsf=idist*0.5f; //
- rsl=*(unsigned int*)&idist; //
- rsl=0x5f3759df-(rsl>>1); // see notes above
- idist=*(float*)&rsl; //
- idist=idist*(rsopf-(rsf*idist*idist)); //
- /*
- * Note once again that since we are using reciprocals of distance values our
- * proportion is already the correct intensity, and does not need to be
- * subtracted from 1.0 like it would have if we used real distances.
- */
-
- /*
- * Here we reconstruct the pixel's memory location in the CompBuf by
- * Pixel Index = Pixel Column + ( Pixel Row * Row Width )
- */
- res[gbuf[gradientFillOffset+1]+(gbuf[gradientFillOffset]*rw)]=(idist/(idist+odist)); //set intensity
- }
-
-}
-
-
-static void node_composit_exec_doubleedgemask(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
-
- float *imask; // imask = pointer to inner mask pixel buffer
- float *omask; // omask = pointer to outer mask pixel buffer
- float *res; // res = pointer to output mask
-
- unsigned int *lres; // lres = unsigned int pointer to output pixel buffer (for bit operations)
- unsigned int *limask; // limask = unsigned int pointer to inner mask (for bit operations)
- unsigned int *lomask; // lomask = unsigned int pointer to outer mask (for bit operations)
-
- int rw; // rw = pixel row width
- int t; // t = total number of pixels in buffer - 1 (used for loop starts)
- int fsz; // size of the frame
-
- unsigned int isz=0; // size (in pixels) of inside edge pixel index buffer
- unsigned int osz=0; // size (in pixels) of outside edge pixel index buffer
- unsigned int gsz=0; // size (in pixels) of gradient pixel index buffer
- unsigned int rsize[3]; // size storage to pass to helper functions
- unsigned int innerEdgeOffset=0; // offset into final buffer where inner edge pixel indexes start
- unsigned int outerEdgeOffset=0; // offset into final buffer where outer edge pixel indexes start
-
- unsigned short *gbuf; // gradient/inner/outer pixel location index buffer
-
- CompBuf *cbuf; // pointer, will be set to inner mask data
- CompBuf *dbuf; // pointer, will be set to outer mask data
- CompBuf *stackbuf; // pointer, will get allocated as output buffer
-
- if (out[0]->hasoutput==0) { // if the node's output socket is not connected to anything...
- return; // do not execute any further, just exit the node immediately
- }
-
- if (in[0]->data && in[1]->data) { // if both input sockets have some data coming in...
- cbuf= in[0]->data; // get a pointer to the inner mask data
- dbuf= in[1]->data; // get a pointer to the outer mask data
- if (cbuf->type!=CB_VAL || dbuf->type!=CB_VAL) { // if either input socket has an incorrect data type coming in
- return; // exit the node immediately
- }
-
- t=(cbuf->x*cbuf->y)-1; // determine size of the frame
-
- stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocate the output buffer
-
- imask= cbuf->rect; // set the inner mask
- omask= dbuf->rect; // set the outer mask
- res= stackbuf->rect; // set output pointer
- lres= (unsigned int*)res; // unsigned int pointer to output buffer (for bit level ops)
- limask=(unsigned int*)imask; // unsigned int pointer to input mask (for bit level ops)
- lomask=(unsigned int*)omask; // unsigned int pointer to output mask (for bit level ops)
- rw= cbuf->x; // width of a row of pixels
-
-
- /*
- * The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the
- * LEFT and RIGHT edges (excluding the corner pixels), and all OTHER rows.
- * This allows for quick computation of outer edge pixels where
- * a screen edge pixel is marked to be gradient.
- *
- * The pixel type (gradient vs inner-edge vs outer-edge) tests change
- * depending on the user selected "Inner Edge Mode" and the user selected
- * "Buffer Edge Mode" on the node's GUI. There are 4 sets of basically the
- * same algorithm:
- *
- * 1.) Inner Edge -> Adjacent Only
- * Buffer Edge -> Keep Inside
- *
- * 2.) Inner Edge -> Adjacent Only
- * Buffer Edge -> Bleed Out
- *
- * 3.) Inner Edge -> All
- * Buffer Edge -> Keep Inside
- *
- * 4.) Inner Edge -> All
- * Buffer Edge -> Bleed Out
- *
- * Each version has slightly different criteria for detecting an edge pixel.
- */
- if (node->custom2) { // if "adjacent only" inner edge mode is turned on
- if (node->custom1) { // if "keep inside" buffer edge mode is turned on
- do_adjacentKeepBorders(t, rw, limask, lomask, lres, res, rsize);
- }
- else { // "bleed out" buffer edge mode is turned on
- do_adjacentBleedBorders(t, rw, limask, lomask, lres, res, rsize);
- }
- isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass
- osz=rsize[1];
- gsz=rsize[2];
- // detect edges in all non-border pixels in the buffer
- do_adjacentEdgeDetection(t, rw, limask, lomask, lres, res, rsize, isz, osz, gsz);
- }
- else { // "all" inner edge mode is turned on
- if (node->custom1) { // if "keep inside" buffer edge mode is turned on
- do_allKeepBorders(t, rw, limask, lomask, lres, res, rsize);
- }
- else { // "bleed out" buffer edge mode is turned on
- do_allBleedBorders(t, rw, limask, lomask, lres, res, rsize);
- }
- isz=rsize[0]; // set up inner edge, outer edge, and gradient buffer sizes after border pass
- osz=rsize[1];
- gsz=rsize[2];
- // detect edges in all non-border pixels in the buffer
- do_allEdgeDetection(t, rw, limask, lomask, lres, res, rsize, isz, osz, gsz);
- }
-
- isz=rsize[0]; // set edge and gradient buffer sizes once again...
- osz=rsize[1]; // the sizes in rsize[] may have been modified
- gsz=rsize[2]; // by the do_*EdgeDetection() function.
-
- // quick check for existance of edges in the buffer...
- // if we don't have any one of the three sizes, the other two make no difference visually,
- // so we can just pass the inner input buffer back as output.
- if (!gsz || !isz || !osz) {
- out[0]->data= stackbuf; // point the node output buffer to our filled buffer
- return;
- }
-
-
- fsz=gsz+isz+osz; // calculate size of pixel index buffer needed
- gbuf= MEM_mallocN(fsz*sizeof(int), "grd buf"); // allocate edge/gradient pixel index buffer
-
- do_createEdgeLocationBuffer(t, rw, lres, res, gbuf, &innerEdgeOffset, &outerEdgeOffset, isz, gsz);
- do_fillGradientBuffer(rw, res, gbuf, isz, osz, gsz, innerEdgeOffset, outerEdgeOffset);
-
- MEM_freeN(gbuf); // free the gradient index buffer
- out[0]->data= stackbuf; // point the node output buffer to our filled buffer
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_doubleedgemask(bNodeTreeType *ttype)
{
static bNodeType ntype; // allocate a node type data structure
node_type_base(ttype, &ntype, CMP_NODE_DOUBLEEDGEMASK, "Double Edge Mask", NODE_CLASS_MATTE, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_doubleedgemask_in, cmp_node_doubleedgemask_out);
- node_type_size(&ntype, 210, 210, 210);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_doubleedgemask);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c
index 761b0b13f11..c2e34dc07a0 100644
--- a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c
@@ -61,7 +61,7 @@ void register_node_type_cmp_ellipsemask(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MASK_ELLIPSE, "Ellipse Mask", NODE_CLASS_MATTE, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_ellipsemask_in, cmp_node_ellipsemask_out);
- node_type_size(&ntype, 260, 110, 300);
+ node_type_size(&ntype, 260, 110, 320);
node_type_init(&ntype, node_composit_init_ellipsemask);
node_type_storage(&ntype, "NodeEllipseMask", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_filter.c b/source/blender/nodes/composite/nodes/node_composite_filter.c
index a27116ab077..3ecc7282632 100644
--- a/source/blender/nodes/composite/nodes/node_composite_filter.c
+++ b/source/blender/nodes/composite/nodes/node_composite_filter.c
@@ -43,197 +43,13 @@ static bNodeSocketTemplate cmp_node_filter_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac)
-{
- float *row1, *row2, *row3;
- float *fp, f1, f2, mfac= 1.0f-fac;
- int rowlen, x, y, c, pix= in->type;
-
- rowlen= in->x;
-
- for (y=0; y<in->y; y++) {
- /* setup rows */
- if (y==0) row1= in->rect;
- else row1= in->rect + pix*(y-1)*rowlen;
-
- row2= in->rect + y*pix*rowlen;
-
- if (y==in->y-1) row3= row2;
- else row3= row2 + pix*rowlen;
-
- fp= out->rect + pix*y*rowlen;
-
- if (pix==CB_RGBA) {
- copy_v4_v4(fp, row2);
- fp+= pix;
-
- for (x=2; x<rowlen; x++) {
- for (c=0; c<3; c++) {
- f1= filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8];
- f2= filter[0]*row1[0] + filter[3]*row1[4] + filter[6]*row1[8] + filter[1]*row2[0] + filter[4]*row2[4] + filter[7]*row2[8] + filter[2]*row3[0] + filter[5]*row3[4] + filter[8]*row3[8];
- fp[0] = mfac*row2[4] + fac*sqrt(f1*f1 + f2*f2);
- fp++; row1++; row2++; row3++;
- }
- fp[0] = row2[4];
- /* no alpha... will clear it completely */
- fp++; row1++; row2++; row3++;
- }
- copy_v4_v4(fp, row2+4);
- }
- else if (pix==CB_VAL) {
- fp+= pix;
- for (x=2; x<rowlen; x++) {
- f1= filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2];
- f2= filter[0]*row1[0] + filter[3]*row1[1] + filter[6]*row1[2] + filter[1]*row2[0] + filter[4]*row2[1] + filter[7]*row2[2] + filter[2]*row3[0] + filter[5]*row3[1] + filter[8]*row3[2];
- fp[0] = mfac*row2[1] + fac*sqrt(f1*f1 + f2*f2);
- fp++; row1++; row2++; row3++;
- }
- }
- }
-}
-
-static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac)
-{
- float *row1, *row2, *row3;
- float *fp, mfac= 1.0f-fac;
- int rowlen, x, y, c;
- int pixlen= in->type;
-
- rowlen= in->x;
-
- for (y=0; y<in->y; y++) {
- /* setup rows */
- if (y==0) row1= in->rect;
- else row1= in->rect + pixlen*(y-1)*rowlen;
-
- row2= in->rect + y*pixlen*rowlen;
-
- if (y==in->y-1) row3= row2;
- else row3= row2 + pixlen*rowlen;
-
- fp= out->rect + pixlen*(y)*rowlen;
-
- if (pixlen==1) {
- fp[0] = row2[0];
- fp+= 1;
-
- for (x=2; x<rowlen; x++) {
- fp[0] = mfac*row2[1] + fac*(filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2]);
- fp++; row1++; row2++; row3++;
- }
- fp[0] = row2[1];
- }
- else if (pixlen==2) {
- fp[0] = row2[0];
- fp[1] = row2[1];
- fp+= 2;
-
- for (x=2; x<rowlen; x++) {
- for (c=0; c<2; c++) {
- fp[0] = mfac*row2[2] + fac*(filter[0]*row1[0] + filter[1]*row1[2] + filter[2]*row1[4] + filter[3]*row2[0] + filter[4]*row2[2] + filter[5]*row2[4] + filter[6]*row3[0] + filter[7]*row3[2] + filter[8]*row3[4]);
- fp++; row1++; row2++; row3++;
- }
- }
- fp[0] = row2[2];
- fp[1] = row2[3];
- }
- else if (pixlen==3) {
- copy_v3_v3(fp, row2);
- fp+= 3;
-
- for (x=2; x<rowlen; x++) {
- for (c=0; c<3; c++) {
- fp[0] = mfac*row2[3] + fac*(filter[0]*row1[0] + filter[1]*row1[3] + filter[2]*row1[6] + filter[3]*row2[0] + filter[4]*row2[3] + filter[5]*row2[6] + filter[6]*row3[0] + filter[7]*row3[3] + filter[8]*row3[6]);
- fp++; row1++; row2++; row3++;
- }
- }
- copy_v3_v3(fp, row2+3);
- }
- else {
- copy_v4_v4(fp, row2);
- fp+= 4;
-
- for (x=2; x<rowlen; x++) {
- for (c=0; c<4; c++) {
- fp[0] = mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]);
- fp++; row1++; row2++; row3++;
- }
- }
- copy_v4_v4(fp, row2+4);
- }
- }
-}
-
-
-static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- static float soft[9] = {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
- float sharp[9] = {-1, -1, -1, -1, 9, -1, -1, -1, -1};
- float laplace[9] = {-1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f, 1.0f, -1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f};
- float sobel[9] = {1, 2, 1, 0, 0, 0, -1, -2, -1};
- float prewitt[9] = {1, 1, 1, 0, 0, 0, -1, -1, -1};
- float kirsch[9] = {5, 5, 5, -3, -3, -3, -2, -2, -2};
- float shadow[9] = {1, 2, 1, 0, 1, 0, -1, -2, -1};
-
- if (out[0]->hasoutput==0) return;
-
- /* stack order in: Image */
- /* stack order out: Image */
-
- if (in[1]->data) {
- /* make output size of first available input image */
- CompBuf *cbuf= in[1]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); /* allocs */
-
- /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
- stackbuf->xof= cbuf->xof;
- stackbuf->yof= cbuf->yof;
-
- switch (node->custom1) {
- case CMP_FILT_SOFT:
- do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]);
- break;
- case CMP_FILT_SHARP:
- do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]);
- break;
- case CMP_FILT_LAPLACE:
- do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]);
- break;
- case CMP_FILT_SOBEL:
- do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]);
- break;
- case CMP_FILT_PREWITT:
- do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]);
- break;
- case CMP_FILT_KIRSCH:
- do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]);
- break;
- case CMP_FILT_SHADOW:
- do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]);
- break;
- }
-
- out[0]->data= stackbuf;
-
- generate_preview(data, node, out[0]->data);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_filter(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_FILTER, "Filter", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_filter_in, cmp_node_filter_out);
- node_type_size(&ntype, 80, 40, 120);
node_type_label(&ntype, node_filter_label);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_filter);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_flip.c b/source/blender/nodes/composite/nodes/node_composite_flip.c
index 4aa98d173e7..f56805809c5 100644
--- a/source/blender/nodes/composite/nodes/node_composite_flip.c
+++ b/source/blender/nodes/composite/nodes/node_composite_flip.c
@@ -43,65 +43,12 @@ static bNodeSocketTemplate cmp_node_flip_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_flip(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (in[0]->data) {
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); /* note, this returns zero'd image */
- int i, src_pix, src_width, src_height, srcydelt, outydelt, x, y;
- float *srcfp, *outfp;
-
- src_pix= cbuf->type;
- src_width= cbuf->x;
- src_height= cbuf->y;
- srcfp= cbuf->rect;
- outfp= stackbuf->rect;
- srcydelt= src_width*src_pix;
- outydelt= srcydelt;
-
- if (node->custom1) { /*set up output pointer for y flip*/
- outfp+= (src_height-1)*outydelt;
- outydelt= -outydelt;
- }
-
- for (y=0; y<src_height; y++) {
- if (node->custom1 == 1) { /* no x flip so just copy line*/
- memcpy(outfp, srcfp, sizeof(float) * src_pix * src_width);
- srcfp+=srcydelt;
- }
- else {
- outfp += (src_width-1)*src_pix;
- for (x=0; x<src_width; x++) {
- for (i=0; i<src_pix; i++) {
- outfp[i] = srcfp[i];
- }
- outfp -= src_pix;
- srcfp += src_pix;
- }
- outfp += src_pix;
- }
- outfp += outydelt;
- }
-
- out[0]->data= stackbuf;
-
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_flip(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_FLIP, "Flip", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_flip_in, cmp_node_flip_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_flip);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_gamma.c b/source/blender/nodes/composite/nodes/node_composite_gamma.c
index b8c99894301..6da56165979 100644
--- a/source/blender/nodes/composite/nodes/node_composite_gamma.c
+++ b/source/blender/nodes/composite/nodes/node_composite_gamma.c
@@ -34,7 +34,7 @@
#include "node_composite_util.h"
/* **************** Gamma Tools ******************** */
-
+
static bNodeSocketTemplate cmp_node_gamma_in[] = {
{ SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Gamma"), 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f, PROP_UNSIGNED},
@@ -45,50 +45,12 @@ static bNodeSocketTemplate cmp_node_gamma_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_gamma(bNode *UNUSED(node), float *out, float *in, float *fac)
-{
- int i=0;
- for (i=0; i<3; i++) {
- /* check for negative to avoid nan's */
- out[i] = (in[i] > 0.0f)? powf(in[i], fac[0]): in[i];
- }
- out[3] = in[3];
-}
-static void node_composit_exec_gamma(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: Fac, Image */
- /* stack order out: Image */
- if (out[0]->hasoutput==0) return;
-
- /* input no image? then only color operation */
- if (in[0]->data==NULL) {
- do_gamma(node, out[0]->vec, in[0]->vec, in[1]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
-
- composit2_pixel_processor(node, stackbuf, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_gamma, CB_RGBA, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_gamma(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_gamma_in, cmp_node_gamma_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_gamma);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.c b/source/blender/nodes/composite/nodes/node_composite_glare.c
index 950d8a56f58..dde056de807 100644
--- a/source/blender/nodes/composite/nodes/node_composite_glare.c
+++ b/source/blender/nodes/composite/nodes/node_composite_glare.c
@@ -41,442 +41,6 @@ static bNodeSocketTemplate cmp_node_glare_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-// mix two images, src buffer does not have to be same size,
-static void mixImages(CompBuf *dst, CompBuf *src, float mix)
-{
- int x, y;
- fRGB c1, c2, *dcolp, *scolp;
- const float mf = 2.f - 2.f*fabsf(mix - 0.5f);
- if ((dst->x == src->x) && (dst->y == src->y)) {
- for (y=0; y<dst->y; y++) {
- dcolp = (fRGB*)&dst->rect[y*dst->x*dst->type];
- scolp = (fRGB*)&src->rect[y*dst->x*dst->type];
- for (x=0; x<dst->x; x++) {
- copy_v3_v3(c1, dcolp[x]);
- copy_v3_v3(c2, scolp[x]);
- c1[0] += mix*(c2[0] - c1[0]);
- c1[1] += mix*(c2[1] - c1[1]);
- c1[2] += mix*(c2[2] - c1[2]);
- if (c1[0] < 0.f) c1[0] = 0.f;
- if (c1[1] < 0.f) c1[1] = 0.f;
- if (c1[2] < 0.f) c1[2] = 0.f;
- mul_v3_fl(c1, mf);
- copy_v3_v3(dcolp[x], c1);
- }
- }
- }
- else {
- float xr = src->x / (float)dst->x;
- float yr = src->y / (float)dst->y;
- for (y=0; y<dst->y; y++) {
- dcolp = (fRGB*)&dst->rect[y*dst->x*dst->type];
- for (x=0; x<dst->x; x++) {
- copy_v3_v3(c1, dcolp[x]);
- qd_getPixelLerp(src, (x + 0.5f)*xr - 0.5f, (y + 0.5f)*yr - 0.5f, c2);
- c1[0] += mix*(c2[0] - c1[0]);
- c1[1] += mix*(c2[1] - c1[1]);
- c1[2] += mix*(c2[2] - c1[2]);
- if (c1[0] < 0.f) c1[0] = 0.f;
- if (c1[1] < 0.f) c1[1] = 0.f;
- if (c1[2] < 0.f) c1[2] = 0.f;
- mul_v3_fl(c1, mf);
- copy_v3_v3(dcolp[x], c1);
- }
- }
- }
-}
-
-
-// adds src to dst image, must be of same size
-static void addImage(CompBuf* dst, CompBuf* src, float scale)
-{
- if ((dst->x == src->x) && (dst->y == src->y)) {
- int p = dst->x*dst->y*dst->type;
- float *dcol = dst->rect, *scol = src->rect;
- while (p--) *dcol++ += *scol++ * scale;
- }
-}
-
-
-// returns possibly downscaled copy of all pixels above threshold
-static CompBuf* BTP(CompBuf* src, float threshold, int scaledown)
-{
- int x, y;
- CompBuf* bsrc = qd_downScaledCopy(src, scaledown);
- float* cr = bsrc->rect;
- for (y=0; y<bsrc->y; ++y)
- for (x=0; x<bsrc->x; ++x, cr+=4) {
- if (rgb_to_luma_y(cr) >= threshold) {
- cr[0] -= threshold, cr[1] -= threshold, cr[2] -= threshold;
- cr[0] = MAX2(cr[0], 0.f);
- cr[1] = MAX2(cr[1], 0.f);
- cr[2] = MAX2(cr[2], 0.f);
- }
- else cr[0] = cr[1] = cr[2] = 0.f;
- }
- return bsrc;
-}
-
-//--------------------------------------------------------------------------------------------
-// simple 4-point star filter
-
-static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
-{
- int x, y, i, xm, xp, ym, yp;
- float c[4] = {0, 0, 0, 0}, tc[4] = {0, 0, 0, 0};
- CompBuf *tbuf1, *tbuf2, *tsrc;
- const float f1 = 1.f - ndg->fade, f2 = (1.f - f1)*0.5f;
- //const float t3 = ndg->threshold*3.f;
- const float sc = (float)(1 << ndg->quality);
- const float isc = 1.f/sc;
-
- tsrc = BTP(src, ndg->threshold, (int)sc);
-
- tbuf1 = dupalloc_compbuf(tsrc);
- tbuf2 = dupalloc_compbuf(tsrc);
-
- for (i=0; i<ndg->iter; i++) {
- // (x || x-1, y-1) to (x || x+1, y+1)
- // F
- for (y=0; y<tbuf1->y; y++) {
- ym = y - i;
- yp = y + i;
- for (x=0; x<tbuf1->x; x++) {
- xm = x - i;
- xp = x + i;
- qd_getPixel(tbuf1, x, y, c);
- mul_v3_fl(c, f1);
- qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc);
- madd_v3_v3fl(c, tc, f2);
- qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc);
- madd_v3_v3fl(c, tc, f2);
- qd_setPixel(tbuf1, x, y, c);
- }
- }
- // B
- for (y=tbuf1->y-1; y>=0; y--) {
- ym = y - i;
- yp = y + i;
- for (x=tbuf1->x-1; x>=0; x--) {
- xm = x - i;
- xp = x + i;
- qd_getPixel(tbuf1, x, y, c);
- mul_v3_fl(c, f1);
- qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc);
- madd_v3_v3fl(c, tc, f2);
- qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc);
- madd_v3_v3fl(c, tc, f2);
- qd_setPixel(tbuf1, x, y, c);
- }
- }
- // (x-1, y || y+1) to (x+1, y || y-1)
- // F
- for (y=0; y<tbuf2->y; y++) {
- ym = y - i;
- yp = y + i;
- for (x=0; x<tbuf2->x; x++) {
- xm = x - i;
- xp = x + i;
- qd_getPixel(tbuf2, x, y, c);
- mul_v3_fl(c, f1);
- qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc);
- madd_v3_v3fl(c, tc, f2);
- qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc);
- madd_v3_v3fl(c, tc, f2);
- qd_setPixel(tbuf2, x, y, c);
- }
- }
- // B
- for (y=tbuf2->y-1; y>=0; y--) {
- ym = y - i;
- yp = y + i;
- for (x=tbuf2->x-1; x>=0; x--) {
- xm = x - i;
- xp = x + i;
- qd_getPixel(tbuf2, x, y, c);
- mul_v3_fl(c, f1);
- qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc);
- madd_v3_v3fl(c, tc, f2);
- qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc);
- madd_v3_v3fl(c, tc, f2);
- qd_setPixel(tbuf2, x, y, c);
- }
- }
- }
-
- for (y=0; y<tbuf1->y; ++y)
- for (x=0; x<tbuf1->x; ++x) {
- unsigned int p = (x + y*tbuf1->x)*tbuf1->type;
- tbuf1->rect[p] += tbuf2->rect[p];
- tbuf1->rect[p+1] += tbuf2->rect[p+1];
- tbuf1->rect[p+2] += tbuf2->rect[p+2];
- }
-
- for (y=0; y<dst->y; ++y) {
- const float m = 0.5f + 0.5f*ndg->mix;
- for (x=0; x<dst->x; ++x) {
- unsigned int p = (x + y*dst->x)*dst->type;
- qd_getPixelLerp(tbuf1, x*isc, y*isc, tc);
- dst->rect[p] = src->rect[p] + m*(tc[0] - src->rect[p]);
- dst->rect[p+1] = src->rect[p+1] + m*(tc[1] - src->rect[p+1]);
- dst->rect[p+2] = src->rect[p+2] + m*(tc[2] - src->rect[p+2]);
- }
- }
-
- free_compbuf(tbuf1);
- free_compbuf(tbuf2);
- free_compbuf(tsrc);
-}
-
-//--------------------------------------------------------------------------------------------
-// streak filter
-
-static void streaks(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
-{
- CompBuf *bsrc, *tsrc, *tdst, *sbuf;
- int x, y, n;
- unsigned int nump=0;
- fRGB c1, c2, c3, c4;
- float a, ang = DEG2RADF(360.0f)/(float)ndg->angle;
-
- bsrc = BTP(src, ndg->threshold, 1 << ndg->quality);
- tsrc = dupalloc_compbuf(bsrc); // sample from buffer
- tdst = alloc_compbuf(tsrc->x, tsrc->y, tsrc->type, 1); // sample to buffer
- sbuf = alloc_compbuf(tsrc->x, tsrc->y, tsrc->type, 1); // streak sum buffer
-
-
- for (a=0.f; a<DEG2RADF(360.0f); a+=ang) {
- const float an = a + ndg->angle_ofs;
- const float vx = cos((double)an), vy = sin((double)an);
- for (n=0; n<ndg->iter; ++n) {
- const float p4 = pow(4.0, (double)n);
- const float vxp = vx*p4, vyp = vy*p4;
- const float wt = pow((double)ndg->fade, (double)p4);
- const float cmo = 1.f - (float)pow((double)ndg->colmod, (double)n+1); // colormodulation amount relative to current pass
- float* tdstcol = tdst->rect;
- for (y=0; y<tsrc->y; ++y) {
- for (x=0; x<tsrc->x; ++x, tdstcol+=4) {
- // first pass no offset, always same for every pass, exact copy,
- // otherwise results in uneven brightness, only need once
- if (n==0) qd_getPixel(tsrc, x, y, c1); else c1[0]=c1[1]=c1[2]=0;
- qd_getPixelLerp(tsrc, x + vxp, y + vyp, c2);
- qd_getPixelLerp(tsrc, x + vxp*2.f, y + vyp*2.f, c3);
- qd_getPixelLerp(tsrc, x + vxp*3.f, y + vyp*3.f, c4);
- // modulate color to look vaguely similar to a color spectrum
- fRGB_rgbmult(c2, 1.f, cmo, cmo);
- fRGB_rgbmult(c3, cmo, cmo, 1.f);
- fRGB_rgbmult(c4, cmo, 1.f, cmo);
- tdstcol[0] = 0.5f*(tdstcol[0] + c1[0] + wt*(c2[0] + wt*(c3[0] + wt*c4[0])));
- tdstcol[1] = 0.5f*(tdstcol[1] + c1[1] + wt*(c2[1] + wt*(c3[1] + wt*c4[1])));
- tdstcol[2] = 0.5f*(tdstcol[2] + c1[2] + wt*(c2[2] + wt*(c3[2] + wt*c4[2])));
- }
- }
- memcpy(tsrc->rect, tdst->rect, sizeof(float)*tdst->x*tdst->y*tdst->type);
- }
-
- addImage(sbuf, tsrc, 1.f/(float)(6 - ndg->iter));
- memset(tdst->rect, 0, tdst->x*tdst->y*tdst->type*sizeof(float));
- memcpy(tsrc->rect, bsrc->rect, bsrc->x*bsrc->y*bsrc->type*sizeof(float));
- nump++;
- }
-
- mixImages(dst, sbuf, 0.5f + 0.5f*ndg->mix);
-
- free_compbuf(tsrc);
- free_compbuf(tdst);
- free_compbuf(sbuf);
- free_compbuf(bsrc);
-}
-
-
-//--------------------------------------------------------------------------------------------
-// Ghosts (lensflare)
-
-static float smoothMask(float x, float y)
-{
- float t;
- x = 2.f*x - 1.f, y = 2.f*y - 1.f;
- if ((t = 1.f - sqrtf(x*x + y*y)) <= 0.f) return 0.f;
- return t;
-}
-
-static void ghosts(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
-{
- // colormodulation and scale factors (cm & scalef) for 16 passes max: 64
- int x, y, n, p, np;
- fRGB c, tc, cm[64];
- float sc, isc, u, v, sm, s, t, ofs, scalef[64];
- CompBuf *tbuf1, *tbuf2, *gbuf;
- const float cmo = 1.f - ndg->colmod;
- const int qt = 1 << ndg->quality;
- const float s1 = 4.f/(float)qt, s2 = 2.f*s1;
-
- gbuf = BTP(src, ndg->threshold, qt);
- tbuf1 = dupalloc_compbuf(gbuf);
- IIR_gauss(tbuf1, s1, 0, 3);
- IIR_gauss(tbuf1, s1, 1, 3);
- IIR_gauss(tbuf1, s1, 2, 3);
- tbuf2 = dupalloc_compbuf(tbuf1);
- IIR_gauss(tbuf2, s2, 0, 3);
- IIR_gauss(tbuf2, s2, 1, 3);
- IIR_gauss(tbuf2, s2, 2, 3);
-
- if (ndg->iter & 1) ofs = 0.5f; else ofs = 0.f;
- for (x=0; x<(ndg->iter*4); x++) {
- y = x & 3;
- cm[x][0] = cm[x][1] = cm[x][2] = 1;
- if (y==1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo);
- if (y==2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f);
- if (y==3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo);
- scalef[x] = 2.1f*(1.f-(x+ofs)/(float)(ndg->iter*4));
- if (x & 1) scalef[x] = -0.99f/scalef[x];
- }
-
- sc = 2.13;
- isc = -0.97;
- for (y=0; y<gbuf->y; y++) {
- v = (float)(y+0.5f) / (float)gbuf->y;
- for (x=0; x<gbuf->x; x++) {
- u = (float)(x+0.5f) / (float)gbuf->x;
- s = (u-0.5f)*sc + 0.5f, t = (v-0.5f)*sc + 0.5f;
- qd_getPixelLerp(tbuf1, s*gbuf->x, t*gbuf->y, c);
- sm = smoothMask(s, t);
- mul_v3_fl(c, sm);
- s = (u-0.5f)*isc + 0.5f, t = (v-0.5f)*isc + 0.5f;
- qd_getPixelLerp(tbuf2, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, tc);
- sm = smoothMask(s, t);
- madd_v3_v3fl(c, tc, sm);
- qd_setPixel(gbuf, x, y, c);
- }
- }
-
- memset(tbuf1->rect, 0, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float));
- for (n=1; n<ndg->iter; n++) {
- for (y=0; y<gbuf->y; y++) {
- v = (float)(y+0.5f) / (float)gbuf->y;
- for (x=0; x<gbuf->x; x++) {
- u = (float)(x+0.5f) / (float)gbuf->x;
- tc[0] = tc[1] = tc[2] = 0.f;
- for (p=0;p<4;p++) {
- np = (n<<2) + p;
- s = (u-0.5f)*scalef[np] + 0.5f;
- t = (v-0.5f)*scalef[np] + 0.5f;
- qd_getPixelLerp(gbuf, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, c);
- mul_v3_v3(c, cm[np]);
- sm = smoothMask(s, t)*0.25f;
- madd_v3_v3fl(tc, c, sm);
- }
- p = (x + y*tbuf1->x)*tbuf1->type;
- tbuf1->rect[p] += tc[0];
- tbuf1->rect[p+1] += tc[1];
- tbuf1->rect[p+2] += tc[2];
- }
- }
- memcpy(gbuf->rect, tbuf1->rect, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float));
- }
-
- free_compbuf(tbuf1);
- free_compbuf(tbuf2);
-
- mixImages(dst, gbuf, 0.5f + 0.5f*ndg->mix);
- free_compbuf(gbuf);
-}
-
-//--------------------------------------------------------------------------------------------
-// Fog glow (convolution with kernel of exponential falloff)
-
-static void fglow(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
-{
- int x, y;
- float scale, u, v, r, w, d;
- fRGB fcol;
- CompBuf *tsrc, *ckrn;
- unsigned int sz = 1 << ndg->size;
- const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f;
-
- // temp. src image
- tsrc = BTP(src, ndg->threshold, 1 << ndg->quality);
- // make the convolution kernel
- ckrn = alloc_compbuf(sz, sz, CB_RGBA, 1);
-
- scale = 0.25f*sqrtf(sz*sz);
-
- for (y=0; y<sz; ++y) {
- v = 2.f*(y / (float)sz) - 1.f;
- for (x=0; x<sz; ++x) {
- u = 2.f*(x / (float)sz) - 1.f;
- r = (u*u + v*v)*scale;
- d = -sqrtf(sqrtf(sqrtf(r)))*9.f;
- fcol[0] = expf(d*cs_r), fcol[1] = expf(d*cs_g), fcol[2] = expf(d*cs_b);
- // linear window good enough here, visual result counts, not scientific analysis
- //w = (1.f-fabs(u))*(1.f-fabs(v));
- // actually, Hanning window is ok, cos^2 for some reason is slower
- w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI));
- mul_v3_fl(fcol, w);
- qd_setPixel(ckrn, x, y, fcol);
- }
- }
-
- convolve(tsrc, tsrc, ckrn);
- free_compbuf(ckrn);
- mixImages(dst, tsrc, 0.5f + 0.5f*ndg->mix);
- free_compbuf(tsrc);
-}
-
-//--------------------------------------------------------------------------------------------
-
-static void node_composit_exec_glare(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *new, *src, *img = in[0]->data;
- NodeGlare* ndg = node->storage;
-
- if ((img == NULL) || (out[0]->hasoutput == 0)) return;
-
- if (img->type != CB_RGBA) {
- new = typecheck_compbuf(img, CB_RGBA);
- src = typecheck_compbuf(img, CB_RGBA);
- }
- else {
- new = dupalloc_compbuf(img);
- src = dupalloc_compbuf(img);
- }
-
- {
- int x, y;
- for (y=0; y<new->y; ++y) {
- fRGB* col = (fRGB*)&new->rect[y*new->x*new->type];
- for (x=0; x<new->x; ++x) {
- col[x][0] = MAX2(col[x][0], 0.f);
- col[x][1] = MAX2(col[x][1], 0.f);
- col[x][2] = MAX2(col[x][2], 0.f);
- }
- }
- }
-
- switch (ndg->type) {
- case 0:
- star4(ndg, new, src);
- break;
- case 1:
- fglow(ndg, new, src);
- break;
- case 3:
- ghosts(ndg, new, src);
- break;
- case 2:
- default:
- streaks(ndg, new, src);
- break;
- }
-
- free_compbuf(src);
- out[0]->data = new;
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_glare(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeGlare *ndg = MEM_callocN(sizeof(NodeGlare), "node glare data");
@@ -499,12 +63,8 @@ void register_node_type_cmp_glare(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_GLARE, "Glare", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_glare_in, cmp_node_glare_out);
- node_type_size(&ntype, 150, 120, 200);
node_type_init(&ntype, node_composit_init_glare);
node_type_storage(&ntype, "NodeGlare", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_glare);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c b/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c
index d52e3d01a32..64ba24e082d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c
+++ b/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c
@@ -44,59 +44,6 @@ static bNodeSocketTemplate cmp_node_hue_sat_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_hue_sat_fac(bNode *node, float *out, float *in, float *fac)
-{
- NodeHueSat *nhs= node->storage;
-
- if (*fac!=0.0f && (nhs->hue!=0.5f || nhs->sat!=1.0f || nhs->val!=1.0f)) {
- float col[3], hsv[3], mfac= 1.0f - *fac;
-
- rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
- hsv[0]+= (nhs->hue - 0.5f);
- if (hsv[0]>1.0f) hsv[0]-=1.0f; else if (hsv[0]<0.0f) hsv[0]+= 1.0f;
- hsv[1]*= nhs->sat;
- hsv[2]*= nhs->val;
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
-
- out[0] = mfac*in[0] + *fac*col[0];
- out[1] = mfac*in[1] + *fac*col[1];
- out[2] = mfac*in[2] + *fac*col[2];
- out[3] = in[3];
- }
- else {
- copy_v4_v4(out, in);
- }
-}
-
-static void node_composit_exec_hue_sat(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: Fac, Image */
- /* stack order out: Image */
- if (out[0]->hasoutput==0) return;
-
- /* input no image? then only color operation */
- if (in[1]->data==NULL) {
- do_hue_sat_fac(node, out[0]->vec, in[1]->vec, in[0]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= dupalloc_compbuf(in[1]->data);
- CompBuf *stackbuf=typecheck_compbuf(cbuf, CB_RGBA);
-
- composit2_pixel_processor(node, stackbuf, stackbuf, in[1]->vec, in[0]->data, in[0]->vec, do_hue_sat_fac, CB_RGBA, CB_VAL);
-
- out[0]->data= stackbuf;
-
- /* get rid of intermediary cbuf if it's extra */
- if (stackbuf!=cbuf)
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_hue_sat(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeHueSat *nhs= MEM_callocN(sizeof(NodeHueSat), "node hue sat");
@@ -112,12 +59,8 @@ void register_node_type_cmp_hue_sat(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_hue_sat_in, cmp_node_hue_sat_out);
- node_type_size(&ntype, 150, 80, 250);
node_type_init(&ntype, node_composit_init_hue_sat);
node_type_storage(&ntype, "NodeHueSat", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_hue_sat);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_huecorrect.c b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c
index f751dbea8d2..738f2f511f7 100644
--- a/source/blender/nodes/composite/nodes/node_composite_huecorrect.c
+++ b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c
@@ -43,106 +43,6 @@ static bNodeSocketTemplate cmp_node_huecorrect_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_huecorrect(bNode *node, float *out, float *in)
-{
- float hsv[3], f;
-
- rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
-
- curvemapping_initialize(node->storage);
-
- /* adjust hue, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(node->storage, 0, hsv[0]);
- hsv[0] += f-0.5f;
-
- /* adjust saturation, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(node->storage, 1, hsv[0]);
- hsv[1] *= (f * 2.f);
-
- /* adjust value, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(node->storage, 2, hsv[0]);
- hsv[2] *= (f * 2.f);
-
- hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
- CLAMP(hsv[1], 0.f, 1.f);
-
- /* convert back to rgb */
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], out, out+1, out+2);
-
- out[3] = in[3];
-}
-
-static void do_huecorrect_fac(bNode *node, float *out, float *in, float *fac)
-{
- float hsv[3], rgb[3], f;
- const float mfac = 1.f-*fac;
-
- rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
-
- curvemapping_initialize(node->storage);
-
- /* adjust hue, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(node->storage, 0, hsv[0]);
- hsv[0] += f-0.5f;
-
- /* adjust saturation, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(node->storage, 1, hsv[0]);
- hsv[1] *= (f * 2.f);
-
- /* adjust value, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(node->storage, 2, hsv[0]);
- hsv[2] *= (f * 2.f);
-
- hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
- CLAMP(hsv[1], 0.f, 1.f);
-
- /* convert back to rgb */
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
-
- out[0] = mfac*in[0] + *fac*rgb[0];
- out[1] = mfac*in[1] + *fac*rgb[1];
- out[2] = mfac*in[2] + *fac*rgb[2];
- out[3] = in[3];
-}
-
-static void node_composit_exec_huecorrect(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *cbuf= in[1]->data;
- CompBuf *stackbuf;
-
- /* stack order input: fac, image, black level, white level */
- /* stack order output: image */
-
- if (out[0]->hasoutput==0)
- return;
-
- if (in[0]->vec[0] == 0.f && in[0]->data == NULL) {
- out[0]->data = pass_on_compbuf(cbuf);
- return;
- }
-
- /* input no image? then only color operation */
- if (in[1]->data==NULL) {
- do_huecorrect_fac(node, out[0]->vec, in[1]->vec, in[0]->vec);
- }
-
- if (cbuf) {
- stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* make output size of input image */
-
- if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f))
- composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_huecorrect, CB_RGBA);
- else
- composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_huecorrect_fac, CB_RGBA, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_huecorrect(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
CurveMapping *cumapping = node->storage= curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
@@ -165,12 +65,9 @@ void register_node_type_cmp_huecorrect(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_HUECORRECT, "Hue Correct", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_huecorrect_in, cmp_node_huecorrect_out);
- node_type_size(&ntype, 320, 140, 400);
+ node_type_size(&ntype, 320, 140, 500);
node_type_init(&ntype, node_composit_init_huecorrect);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_huecorrect);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_idMask.c b/source/blender/nodes/composite/nodes/node_composite_idMask.c
index ef0c5021192..89ef4ad3d01 100644
--- a/source/blender/nodes/composite/nodes/node_composite_idMask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_idMask.c
@@ -44,82 +44,12 @@ static bNodeSocketTemplate cmp_node_idmask_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* stackbuf should be zeroed */
-static void do_idmask(CompBuf *stackbuf, CompBuf *cbuf, float idnr)
-{
- float *rect;
- int x;
- char *abuf= MEM_mapallocN(cbuf->x*cbuf->y, "anti ali buf");
-
- rect= cbuf->rect;
- for (x= cbuf->x*cbuf->y - 1; x>=0; x--)
- if (rect[x]==idnr)
- abuf[x] = 255;
-
- antialias_tagbuf(cbuf->x, cbuf->y, abuf);
-
- rect= stackbuf->rect;
- for (x= cbuf->x*cbuf->y - 1; x>=0; x--)
- if (abuf[x]>1)
- rect[x] = (1.0f/255.0f)*(float)abuf[x];
-
- MEM_freeN(abuf);
-}
-
-/* full sample version */
-static void do_idmask_fsa(CompBuf *stackbuf, CompBuf *cbuf, float idnr)
-{
- float *rect, *rs;
- int x;
-
- rect= cbuf->rect;
- rs= stackbuf->rect;
- for (x= cbuf->x*cbuf->y - 1; x>=0; x--)
- if (rect[x]==idnr)
- rs[x] = 1.0f;
-
-}
-
-
-static void node_composit_exec_idmask(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- RenderData *rd= data;
-
- if (out[0]->hasoutput==0)
- return;
-
- if (in[0]->data) {
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf;
-
- if (cbuf->type!=CB_VAL)
- return;
-
- stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */;
-
- if ((rd->scemode & R_FULL_SAMPLE) || node->custom2 == 0)
- do_idmask_fsa(stackbuf, cbuf, (float)node->custom1);
- else
- do_idmask(stackbuf, cbuf, (float)node->custom1);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_idmask(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_ID_MASK, "ID Mask", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_idmask_in, cmp_node_idmask_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_idmask);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 88d78df190f..563ad2b74b2 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -29,7 +29,6 @@
* \ingroup cmpnodes
*/
-
#include "node_composite_util.h"
/* **************** IMAGE (and RenderResult, multilayer image) ******************** */
@@ -285,243 +284,6 @@ static void cmp_node_image_update(bNodeTree *ntree, bNode *node)
cmp_node_image_verify_outputs(ntree, node);
}
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* float buffer from the image with matching color management */
-float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
-{
- float *rect;
- int predivide= (ibuf->flags & IB_cm_predivide);
-
- *alloc= FALSE;
-
- /* OCIO_TODO: this is a part of legacy compositor system, don't bother with porting this code
- * to new color management system since this code would likely be simply removed soon
- */
- if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
- rect= ibuf->rect_float;
- }
- else {
- rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image");
-
- IMB_buffer_float_from_float(rect, ibuf->rect_float,
- 4, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
-
- *alloc= TRUE;
- }
-
- return rect;
-}
-
-/* note: this function is used for multilayer too, to ensure uniform
- * handling with BKE_image_acquire_ibuf() */
-static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
-{
- ImBuf *ibuf;
- CompBuf *stackbuf;
- int type;
-
- float *rect;
- int alloc= FALSE;
-
- ibuf= BKE_image_acquire_ibuf(ima, iuser, NULL);
- if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
- return NULL;
- }
-
- if (ibuf->rect_float == NULL) {
- IMB_float_from_rect(ibuf);
- }
-
- /* now we need a float buffer from the image with matching color management */
- /* XXX weak code, multilayer is excluded from this */
- if (ibuf->channels == 4 && ima->rr==NULL) {
- rect= node_composit_get_float_buffer(rd, ibuf, &alloc);
- }
- else {
- /* non-rgba passes can't use color profiles */
- rect= ibuf->rect_float;
- }
- /* done coercing into the correct color management */
-
-
- type= ibuf->channels;
-
- if (rd->scemode & R_COMP_CROP) {
- stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
- if (alloc)
- MEM_freeN(rect);
- }
- else {
- /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
- stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
- stackbuf->rect= rect;
- stackbuf->malloc= alloc;
- }
-
- /* code to respect the premul flag of images; I'm
- * not sure if this is a good idea for multilayer images,
- * since it never worked before for them.
- */
-#if 0
- if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
- //premul the image
- int i;
- float *pixel = stackbuf->rect;
-
- for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
- pixel[0] *= pixel[3];
- pixel[1] *= pixel[3];
- pixel[2] *= pixel[3];
- }
- }
-#endif
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
- return stackbuf;
-}
-
-static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
-{
- ImBuf *ibuf= BKE_image_acquire_ibuf((Image *)node->id, node->storage, NULL);
- CompBuf *zbuf= NULL;
-
- if (ibuf && ibuf->zbuf_float) {
- if (rd->scemode & R_COMP_CROP) {
- zbuf= get_cropped_compbuf(&rd->disprect, ibuf->zbuf_float, ibuf->x, ibuf->y, CB_VAL);
- }
- else {
- zbuf= alloc_compbuf(ibuf->x, ibuf->y, CB_VAL, 0);
- zbuf->rect= ibuf->zbuf_float;
- }
- }
-
- BKE_image_release_ibuf((Image *)node->id, ibuf, NULL);
-
- return zbuf;
-}
-
-/* check if layer is available, returns pass buffer */
-static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passindex)
-{
- RenderPass *rpass = BLI_findlink(&rl->passes, passindex);
- if (rpass) {
- CompBuf *cbuf;
-
- iuser->pass = passindex;
- BKE_image_multilayer_index(ima->rr, iuser);
- cbuf = node_composit_get_image(rd, ima, iuser);
-
- return cbuf;
- }
- return NULL;
-}
-
-static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- /* image assigned to output */
- /* stack order input sockets: col, alpha */
- if (node->id) {
- RenderData *rd= data;
- Image *ima= (Image *)node->id;
- ImageUser *iuser= (ImageUser *)node->storage;
- ImBuf *ibuf = NULL;
-
- /* first set the right frame number in iuser */
- BKE_image_user_frame_calc(iuser, rd->cfra, 0);
-
- /* force a load, we assume iuser index will be set OK anyway */
- if (ima->type==IMA_TYPE_MULTILAYER)
- ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
-
- if (ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
- RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
-
- if (rl) {
- bNodeSocket *sock;
- NodeImageLayer *sockdata;
- int out_index;
- CompBuf *combinedbuf= NULL, *firstbuf= NULL;
-
- for (sock=node->outputs.first, out_index=0; sock; sock=sock->next, ++out_index) {
- sockdata = sock->storage;
- if (out[out_index]->hasoutput) {
- CompBuf *stackbuf = out[out_index]->data = compbuf_multilayer_get(rd, rl, ima, iuser, sockdata->pass_index);
- if (stackbuf) {
- /* preview policy: take first 'Combined' pass if available,
- * otherwise just use the first layer.
- */
- if (!firstbuf) {
- firstbuf = stackbuf;
- }
- if (!combinedbuf &&
- (strcmp(sock->name, "Combined") == 0 || strcmp(sock->name, "Image") == 0))
- {
- combinedbuf = stackbuf;
- }
- }
- }
- }
-
- /* preview */
- if (combinedbuf)
- generate_preview(data, node, combinedbuf);
- else if (firstbuf)
- generate_preview(data, node, firstbuf);
- }
- }
- else {
- CompBuf *stackbuf = node_composit_get_image(rd, ima, iuser);
- if (stackbuf) {
- int num_outputs = BLI_countlist(&node->outputs);
-
- /*respect image premul option*/
- if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
- int i;
- float *pixel;
-
- /* first duplicate stackbuf->rect, since it's just a pointer
- * to the source imbuf, and we don't want to change that.*/
- stackbuf->rect = MEM_dupallocN(stackbuf->rect);
-
- /* since stackbuf now has allocated memory, rather than just a pointer,
- * mark it as allocated so it can be freed properly */
- stackbuf->malloc=1;
-
- /*premul the image*/
- pixel = stackbuf->rect;
- for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
- pixel[0] *= pixel[3];
- pixel[1] *= pixel[3];
- pixel[2] *= pixel[3];
- }
- }
-
- /* put image on stack */
- if (num_outputs > 0)
- out[0]->data= stackbuf;
-
- /* alpha output */
- if (num_outputs > 1 && out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
-
- /* Z output */
- if (num_outputs > 2 && out[2]->hasoutput)
- out[2]->data= node_composit_get_zimage(node, rd);
-
- /* preview */
- generate_preview(data, node, stackbuf);
- }
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_image(bNodeTree *ntree, bNode *node, bNodeTemplate *UNUSED(ntemp))
{
ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
@@ -562,13 +324,9 @@ void register_node_type_cmp_image(bNodeTreeType *ttype)
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS);
- node_type_size(&ntype, 120, 80, 300);
node_type_init(&ntype, node_composit_init_image);
node_type_storage(&ntype, "ImageUser", node_composit_free_image, node_composit_copy_image);
node_type_update(&ntype, cmp_node_image_update, NULL);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_image);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -576,151 +334,12 @@ void register_node_type_cmp_image(bNodeTreeType *ttype)
/* **************** RENDER RESULT ******************** */
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode)
-{
- float *fp= RE_RenderLayerGetPass(rl, passcode);
- if (fp) {
- CompBuf *buf;
- int buftype= CB_VEC3;
-
- if (ELEM4(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB, SCE_PASS_MIST, SCE_PASS_INDEXMA))
- buftype= CB_VAL;
- else if (passcode==SCE_PASS_VECTOR)
- buftype= CB_VEC4;
- else if (ELEM(passcode, SCE_PASS_COMBINED, SCE_PASS_RGBA))
- buftype= CB_RGBA;
-
- if (rd->scemode & R_COMP_CROP)
- buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype);
- else {
- buf= alloc_compbuf(rectx, recty, buftype, 0);
- buf->rect= fp;
- }
- return buf;
- }
- return NULL;
-}
-
-static void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out, int rectx, int recty)
-{
- if (out[RRES_OUT_Z]->hasoutput)
- out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_Z);
- if (out[RRES_OUT_VEC]->hasoutput)
- out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_VECTOR);
- if (out[RRES_OUT_NORMAL]->hasoutput)
- out[RRES_OUT_NORMAL]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_NORMAL);
- if (out[RRES_OUT_UV]->hasoutput)
- out[RRES_OUT_UV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_UV);
-
- if (out[RRES_OUT_RGBA]->hasoutput)
- out[RRES_OUT_RGBA]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RGBA);
- if (out[RRES_OUT_DIFF]->hasoutput)
- out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE);
- if (out[RRES_OUT_SPEC]->hasoutput)
- out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SPEC);
- if (out[RRES_OUT_SHADOW]->hasoutput)
- out[RRES_OUT_SHADOW]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SHADOW);
- if (out[RRES_OUT_AO]->hasoutput)
- out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_AO);
- if (out[RRES_OUT_REFLECT]->hasoutput)
- out[RRES_OUT_REFLECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFLECT);
- if (out[RRES_OUT_REFRACT]->hasoutput)
- out[RRES_OUT_REFRACT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFRACT);
- if (out[RRES_OUT_INDIRECT]->hasoutput)
- out[RRES_OUT_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDIRECT);
- if (out[RRES_OUT_INDEXOB]->hasoutput)
- out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
- if (out[RRES_OUT_INDEXMA]->hasoutput)
- out[RRES_OUT_INDEXMA]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXMA);
- if (out[RRES_OUT_MIST]->hasoutput)
- out[RRES_OUT_MIST]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_MIST);
- if (out[RRES_OUT_EMIT]->hasoutput)
- out[RRES_OUT_EMIT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_EMIT);
- if (out[RRES_OUT_ENV]->hasoutput)
- out[RRES_OUT_ENV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_ENVIRONMENT);
- if (out[RRES_OUT_DIFF_DIRECT]->hasoutput)
- out[RRES_OUT_DIFF_DIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE_DIRECT);
- if (out[RRES_OUT_DIFF_INDIRECT]->hasoutput)
- out[RRES_OUT_DIFF_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE_INDIRECT);
- if (out[RRES_OUT_DIFF_COLOR]->hasoutput)
- out[RRES_OUT_DIFF_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE_COLOR);
- if (out[RRES_OUT_GLOSSY_DIRECT]->hasoutput)
- out[RRES_OUT_GLOSSY_DIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_GLOSSY_DIRECT);
- if (out[RRES_OUT_GLOSSY_INDIRECT]->hasoutput)
- out[RRES_OUT_GLOSSY_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_GLOSSY_INDIRECT);
- if (out[RRES_OUT_GLOSSY_COLOR]->hasoutput)
- out[RRES_OUT_GLOSSY_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_GLOSSY_COLOR);
- if (out[RRES_OUT_TRANSM_DIRECT]->hasoutput)
- out[RRES_OUT_TRANSM_DIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_DIRECT);
- if (out[RRES_OUT_TRANSM_INDIRECT]->hasoutput)
- out[RRES_OUT_TRANSM_INDIRECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_INDIRECT);
- if (out[RRES_OUT_TRANSM_COLOR]->hasoutput)
- out[RRES_OUT_TRANSM_COLOR]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_TRANSM_COLOR);
-}
-
-static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- Scene *sce= (Scene *)node->id;
- Render *re= (sce)? RE_GetRender(sce->id.name): NULL;
- RenderData *rd= data;
- RenderResult *rr= NULL;
-
- if (re)
- rr= RE_AcquireResultRead(re);
-
- if (rr) {
- SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
- if (srl) {
- RenderLayer *rl= RE_GetRenderLayer(rr, srl->name);
- if (rl && rl->rectf) {
- CompBuf *stackbuf;
-
- /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */
- if (rd->scemode & R_COMP_CROP)
- stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA);
- else {
- stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0);
- stackbuf->rect= rl->rectf;
- }
- if (stackbuf==NULL) {
- printf("Error; Preview Panel in UV Window returns zero sized image\n");
- }
- else {
- stackbuf->xof= rr->xof;
- stackbuf->yof= rr->yof;
-
- /* put on stack */
- out[RRES_OUT_IMAGE]->data= stackbuf;
-
- if (out[RRES_OUT_ALPHA]->hasoutput)
- out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
-
- node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty);
-
- generate_preview(data, node, stackbuf);
- }
- }
- }
- }
-
- if (re)
- RE_ReleaseResult(re);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_rlayers(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_R_LAYERS, "Render Layers", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out);
- node_type_size(&ntype, 150, 100, 300);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_rlayers);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_inpaint.c b/source/blender/nodes/composite/nodes/node_composite_inpaint.c
index 25ecf428b4a..4844b35fb62 100644
--- a/source/blender/nodes/composite/nodes/node_composite_inpaint.c
+++ b/source/blender/nodes/composite/nodes/node_composite_inpaint.c
@@ -44,25 +44,12 @@ static bNodeSocketTemplate cmp_node_inpaint_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_inpaint(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
-{
- /* pass */
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_inpaint(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_INPAINT, "Inpaint", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_inpaint_in, cmp_node_inpaint_out);
- node_type_size(&ntype, 130, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_inpaint);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_invert.c b/source/blender/nodes/composite/nodes/node_composite_invert.c
index 2db6e42f603..0bfbe42868b 100644
--- a/source/blender/nodes/composite/nodes/node_composite_invert.c
+++ b/source/blender/nodes/composite/nodes/node_composite_invert.c
@@ -43,82 +43,6 @@ static bNodeSocketTemplate cmp_node_invert_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_invert(bNode *node, float *out, float *in)
-{
- if (node->custom1 & CMP_CHAN_RGB) {
- out[0] = 1.0f - in[0];
- out[1] = 1.0f - in[1];
- out[2] = 1.0f - in[2];
- }
- else {
- copy_v3_v3(out, in);
- }
-
- if (node->custom1 & CMP_CHAN_A)
- out[3] = 1.0f - in[3];
- else
- out[3] = in[3];
-}
-
-static void do_invert_fac(bNode *node, float *out, float *in, float *fac)
-{
- float col[4], facm;
-
- do_invert(node, col, in);
-
- /* blend inverted result against original input with fac */
- facm = 1.0f - fac[0];
-
- if (node->custom1 & CMP_CHAN_RGB) {
- col[0] = fac[0]*col[0] + (facm*in[0]);
- col[1] = fac[0]*col[1] + (facm*in[1]);
- col[2] = fac[0]*col[2] + (facm*in[2]);
- }
- if (node->custom1 & CMP_CHAN_A)
- col[3] = fac[0]*col[3] + (facm*in[3]);
-
- copy_v4_v4(out, col);
-}
-
-static void node_composit_exec_invert(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: fac, Image, Image */
- /* stack order out: Image */
- float *fac= in[0]->vec;
-
- if (out[0]->hasoutput==0) return;
-
- /* input no image? then only color operation */
- if (in[1]->data==NULL && in[0]->data==NULL) {
- do_invert_fac(node, out[0]->vec, in[1]->vec, fac);
- }
- else {
- /* make output size of first available input image, or then size of fac */
- CompBuf *cbuf= in[1]->data?in[1]->data:in[0]->data;
-
- /* if neither RGB or A toggled on, pass through */
- if (node->custom1 != 0) {
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- if (fac[0] < 1.0f || in[0]->data!=NULL)
- composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, fac, do_invert_fac, CB_RGBA, CB_VAL);
- else
- composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_invert, CB_RGBA);
- out[0]->data= stackbuf;
- return;
-
- }
- else {
- out[0]->data = pass_on_compbuf(cbuf);
- return;
- }
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_invert(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->custom1 |= CMP_CHAN_RGB;
@@ -131,11 +55,7 @@ void register_node_type_cmp_invert(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_invert_in, cmp_node_invert_out);
- node_type_size(&ntype, 120, 120, 140);
node_type_init(&ntype, node_composit_init_invert);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_invert);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c
index 6553df350ff..51e0e9a8e39 100644
--- a/source/blender/nodes/composite/nodes/node_composite_keying.c
+++ b/source/blender/nodes/composite/nodes/node_composite_keying.c
@@ -60,13 +60,6 @@ static bNodeSocketTemplate cmp_node_keying_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-static void node_composit_exec_keying(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
-{
- /* pass */
-}
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_keying(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeKeyingData *data;
@@ -91,12 +84,8 @@ void register_node_type_cmp_keying(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_KEYING, "Keying", NODE_CLASS_MATTE, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_keying_in, cmp_node_keying_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_keying);
node_type_storage(&ntype, "NodeKeyingData", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_keying);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c
index 96e905827cb..1974087e8e7 100644
--- a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c
+++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c
@@ -50,140 +50,6 @@ static bNodeSocketTemplate cmp_node_keyingscreen_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keyingscreen_data, MovieClip *clip, CompBuf *screenbuf)
-{
- MovieClipUser user = {0};
- MovieTracking *tracking = &clip->tracking;
- MovieTrackingTrack *track;
- VoronoiTriangulationPoint *triangulated_points;
- VoronoiSite *sites;
- ImBuf *ibuf;
- ListBase *tracksbase;
- ListBase edges = {NULL, NULL};
- int sites_total, triangulated_points_total, triangles_total;
- int (*triangles)[3];
- int i, x, y;
- float *rect = screenbuf->rect;
-
- if (keyingscreen_data->tracking_object[0]) {
- MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, keyingscreen_data->tracking_object);
-
- if (!object)
- return;
-
- tracksbase = BKE_tracking_object_get_tracks(tracking, object);
- }
- else
- tracksbase = BKE_tracking_get_active_tracks(tracking);
-
- sites_total = BLI_countlist(tracksbase);
-
- if (!sites_total)
- return;
-
- BKE_movieclip_user_set_frame(&user, rd->cfra);
- ibuf = BKE_movieclip_get_ibuf(clip, &user);
-
- sites = MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites");
- track = tracksbase->first;
- i = 0;
- while (track) {
- VoronoiSite *site = &sites[i];
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, rd->cfra);
- ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE);
- int j;
-
- zero_v3(site->color);
-
- if (pattern_ibuf) {
- for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) {
- if (pattern_ibuf->rect_float) {
- add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]);
- }
- else {
- unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect;
-
- site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f);
- site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f);
- site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f);
- }
- }
-
- mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y));
- IMB_freeImBuf(pattern_ibuf);
- }
-
- site->co[0] = marker->pos[0] * screenbuf->x;
- site->co[1] = marker->pos[1] * screenbuf->y;
-
- track = track->next;
- i++;
- }
-
- IMB_freeImBuf(ibuf);
-
- BLI_voronoi_compute(sites, sites_total, screenbuf->x, screenbuf->y, &edges);
-
- BLI_voronoi_triangulate(sites, sites_total, &edges, screenbuf->x, screenbuf->y,
- &triangulated_points, &triangulated_points_total,
- &triangles, &triangles_total);
-
- for (y = 0; y < screenbuf->y; y++) {
- for (x = 0; x < screenbuf->x; x++) {
- int index = 4 * (y * screenbuf->x + x);
-
- rect[index + 0] = rect[index + 1] = rect[index + 2] = 0.0f;
- rect[index + 3] = 1.0f;
-
- for (i = 0; i < triangles_total; i++) {
- int *triangle = triangles[i];
- VoronoiTriangulationPoint *a = &triangulated_points[triangle[0]],
- *b = &triangulated_points[triangle[1]],
- *c = &triangulated_points[triangle[2]];
- float co[2] = {x, y}, w[3];
-
- if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) {
- if (barycentric_inside_triangle_v2(w)) {
- rect[index + 0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2];
- rect[index + 1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2];
- rect[index + 2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2];
- }
- }
- }
- }
- }
-
- MEM_freeN(triangulated_points);
- MEM_freeN(triangles);
- MEM_freeN(sites);
- BLI_freelistN(&edges);
-}
-
-static void node_composit_exec_keyingscreen(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- NodeKeyingScreenData *keyingscreen_data = node->storage;
- RenderData *rd = data;
- CompBuf *screenbuf = NULL;
-
- if (node->id) {
- MovieClip *clip = (MovieClip *) node->id;
- MovieClipUser user = {0};
- int width, height;
-
- BKE_movieclip_user_set_frame(&user, rd->cfra);
- BKE_movieclip_get_size(clip, &user, &width, &height);
-
- screenbuf = alloc_compbuf(width, height, CB_RGBA, TRUE);
- compute_gradient_screen(rd, keyingscreen_data, clip, screenbuf);
- }
-
- out[0]->data = screenbuf;
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_keyingscreen(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeKeyingScreenData *data;
@@ -199,12 +65,8 @@ void register_node_type_cmp_keyingscreen(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_KEYINGSCREEN, "Keying Screen", NODE_CLASS_MATTE, NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_keyingscreen_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_keyingscreen);
node_type_storage(&ntype, "NodeKeyingScreenData", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_keyingscreen);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_lensdist.c b/source/blender/nodes/composite/nodes/node_composite_lensdist.c
index c3f64f0eacb..15d10e07946 100644
--- a/source/blender/nodes/composite/nodes/node_composite_lensdist.c
+++ b/source/blender/nodes/composite/nodes/node_composite_lensdist.c
@@ -43,149 +43,6 @@ static bNodeSocketTemplate cmp_node_lensdist_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* assumes *dst is type RGBA */
-static void lensDistort(CompBuf *dst, CompBuf *src, float kr, float kg, float kb, int jit, int proj, int fit)
-{
- int x, y, z;
- const float cx = 0.5f*(float)dst->x, cy = 0.5f*(float)dst->y;
-
- if (proj) {
- // shift
- CompBuf *tsrc = dupalloc_compbuf(src);
-
- for (z=0; z<tsrc->type; ++z)
- IIR_gauss(tsrc, (kr+0.5f)*(kr+0.5f), z, 1);
- kr *= 20.f;
-
- for (y=0; y<dst->y; y++) {
- fRGB *colp = (fRGB*)&dst->rect[y*dst->x*dst->type];
- const float v = (y + 0.5f)/(float)dst->y;
-
- for (x=0; x<dst->x; x++) {
- const float u = (x + 0.5f)/(float)dst->x;
-
- qd_getPixelLerpChan(tsrc, (u*dst->x + kr) - 0.5f, v*dst->y - 0.5f, 0, colp[x]);
- if (tsrc->type == CB_VAL)
- colp[x][1] = tsrc->rect[x + y*tsrc->x];
- else
- colp[x][1] = tsrc->rect[(x + y*tsrc->x)*tsrc->type + 1];
- qd_getPixelLerpChan(tsrc, (u*dst->x - kr) - 0.5f, v*dst->y - 0.5f, 2, colp[x]+2);
-
- /* set alpha */
- colp[x][3] = 1.0f;
- }
- }
- free_compbuf(tsrc);
- }
- else {
- // Spherical
- // Scale factor to make bottom/top & right/left sides fit in window after deform
- // so in the case of pincushion (kn < 0), corners will be outside window.
- // Now also optionally scales image such that black areas are not visible when distort factor is positive
- // (makes distorted corners match window corners, but really only valid if mk<=0.5)
- const float mk = MAX3(kr, kg, kb);
- const float sc = (fit && (mk > 0.f)) ? (1.f/(1.f + 2.f*mk)) : (1.f/(1.f + mk));
- const float drg = 4.f*(kg - kr), dgb = 4.f*(kb - kg);
-
- kr *= 4.f, kg *= 4.f, kb *= 4.f;
-
- for (y=0; y<dst->y; y++) {
- fRGB *colp = (fRGB*)&dst->rect[y*dst->x*dst->type];
- const float v = sc*((y + 0.5f) - cy)/cy;
-
- for (x=0; x<dst->x; x++) {
- int dr = 0, dg = 0, db = 0;
- float d, t, ln[6] = {0, 0, 0, 0, 0, 0};
- fRGB c1, tc = {0, 0, 0, 0};
- const float u = sc*((x + 0.5f) - cx)/cx;
- const float uv_dot = u * u + v * v;
- int sta = 0, mid = 0, end = 0;
-
- if ((t = 1.f - kr*uv_dot) >= 0.f) {
- d = 1.f/(1.f + sqrtf(t));
- ln[0] = (u*d + 0.5f)*dst->x - 0.5f, ln[1] = (v*d + 0.5f)*dst->y - 0.5f;
- sta = 1;
- }
- if ((t = 1.f - kg*uv_dot) >= 0.f) {
- d = 1.f/(1.f + sqrtf(t));
- ln[2] = (u*d + 0.5f)*dst->x - 0.5f, ln[3] = (v*d + 0.5f)*dst->y - 0.5f;
- mid = 1;
- }
- if ((t = 1.f - kb*uv_dot) >= 0.f) {
- d = 1.f/(1.f + sqrtf(t));
- ln[4] = (u*d + 0.5f)*dst->x - 0.5f, ln[5] = (v*d + 0.5f)*dst->y - 0.5f;
- end = 1;
- }
-
- if (sta && mid && end) {
- // RG
- const int dx = ln[2] - ln[0], dy = ln[3] - ln[1];
- const float dsf = sqrtf(dx*dx + dy*dy) + 1.f;
- const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
- const float sd = 1.f/(float)ds;
-
- for (z=0; z<ds; ++z) {
- const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd;
- t = 1.f - (kr + tz*drg)*uv_dot;
- d = 1.f / (1.f + sqrtf(t));
- qd_getPixelLerp(src, (u*d + 0.5f)*dst->x - 0.5f, (v*d + 0.5f)*dst->y - 0.5f, c1);
- if (src->type == CB_VAL) c1[1] = c1[2] = c1[0];
- tc[0] += (1.f-tz)*c1[0], tc[1] += tz*c1[1];
- dr++, dg++;
- }
- // GB
- {
- const int dx = ln[4] - ln[2], dy = ln[5] - ln[3];
- const float dsf = sqrtf(dx*dx + dy*dy) + 1.f;
- const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
- const float sd = 1.f/(float)ds;
-
- for (z=0; z<ds; ++z) {
- const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd;
- t = 1.f - (kg + tz*dgb)*uv_dot;
- d = 1.f / (1.f + sqrtf(t));
- qd_getPixelLerp(src, (u*d + 0.5f)*dst->x - 0.5f, (v*d + 0.5f)*dst->y - 0.5f, c1);
- if (src->type == CB_VAL) c1[1] = c1[2] = c1[0];
- tc[1] += (1.f-tz)*c1[1], tc[2] += tz*c1[2];
- dg++, db++;
- }
- }
- }
-
- if (dr) colp[x][0] = 2.f*tc[0] / (float)dr;
- if (dg) colp[x][1] = 2.f*tc[1] / (float)dg;
- if (db) colp[x][2] = 2.f*tc[2] / (float)db;
-
- /* set alpha */
- colp[x][3] = 1.0f;
- }
- }
- }
-}
-
-
-static void node_composit_exec_lensdist(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *new, *img = in[0]->data;
- NodeLensDist *nld = node->storage;
- const float k = MAX2(MIN2(in[1]->vec[0], 1.f), -0.999f);
- // smaller dispersion range for somewhat more control
- const float d = 0.25f*MAX2(MIN2(in[2]->vec[0], 1.f), 0.f);
- const float kr = MAX2(MIN2((k+d), 1.f), -0.999f), kb = MAX2(MIN2((k-d), 1.f), -0.999f);
-
- if ((img==NULL) || (out[0]->hasoutput==0)) return;
-
- new = alloc_compbuf(img->x, img->y, CB_RGBA, 1);
-
- lensDistort(new, img, (nld->proj ? d : kr), k, kb, nld->jit, nld->proj, nld->fit);
-
- out[0]->data = new;
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_lensdist(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeLensDist *nld = MEM_callocN(sizeof(NodeLensDist), "node lensdist data");
@@ -200,12 +57,8 @@ void register_node_type_cmp_lensdist(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_LENSDIST, "Lens Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_lensdist_in, cmp_node_lensdist_out);
- node_type_size(&ntype, 150, 120, 200);
node_type_init(&ntype, node_composit_init_lensdist);
node_type_storage(&ntype, "NodeLensDist", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_lensdist);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_levels.c b/source/blender/nodes/composite/nodes/node_composite_levels.c
index 57d94d6cb4d..f50a8838d74 100644
--- a/source/blender/nodes/composite/nodes/node_composite_levels.c
+++ b/source/blender/nodes/composite/nodes/node_composite_levels.c
@@ -45,274 +45,6 @@ static bNodeSocketTemplate cmp_node_view_levels_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void fill_bins(bNode *node, CompBuf* in, int* bins)
-{
- float value[4];
- int ivalue=0;
- int x, y;
-
- /*fill bins */
- for (y=0; y<in->y; y++) {
- for (x=0; x<in->x; x++) {
-
- /* get the pixel */
- qd_getPixel(in, x, y, value);
-
- if (value[3] > 0.0f) { /* don't count transparent pixels */
- switch (node->custom1) {
- case 1: { /* all colors */
- value[0] = rgb_to_bw(value);
- value[0]=value[0]*255; /* scale to 0-255 range */
- ivalue=(int)value[0];
- break;
- }
- case 2: { /* red channel */
- value[0]=value[0]*255; /* scale to 0-255 range */
- ivalue=(int)value[0];
- break;
- }
- case 3: { /* green channel */
- value[1]=value[1]*255; /* scale to 0-255 range */
- ivalue=(int)value[1];
- break;
- }
- case 4: /*blue channel */
- {
- value[2]=value[2]*255; /* scale to 0-255 range */
- ivalue=(int)value[2];
- break;
- }
- case 5: /* luminence */
- {
- rgb_to_yuv(value[0], value[1], value[2], &value[0], &value[1], &value[2]);
- value[0]=value[0]*255; /* scale to 0-255 range */
- ivalue=(int)value[0];
- break;
- }
- } /*end switch */
-
- /*clip*/
- if (ivalue<0) ivalue=0;
- if (ivalue>255) ivalue=255;
-
- /*put in the correct bin*/
- bins[ivalue]+=1;
- } /*end if alpha */
- }
- }
-}
-
-static float brightness_mean(bNode *node, CompBuf* in)
-{
- float sum=0.0;
- int numPixels=0.0;
- int x, y;
- float value[4];
-
- for (x=0; x< in->x; x++) {
- for (y=0; y < in->y; y++) {
-
- /* get the pixel */
- qd_getPixel(in, x, y, value);
-
- if (value[3] > 0.0f) { /* don't count transparent pixels */
- numPixels++;
- switch (node->custom1) {
- case 1:
- {
- value[0] = rgb_to_bw(value);
- sum+=value[0];
- break;
- }
- case 2:
- {
- sum+=value[0];
- break;
- }
- case 3:
- {
- sum+=value[1];
- break;
- }
- case 4:
- {
- sum+=value[2];
- break;
- }
- case 5:
- {
- rgb_to_yuv(value[0], value[1], value[2], &value[0], &value[1], &value[2]);
- sum+=value[0];
- break;
- }
- }
- }
- }
- }
-
- return sum/numPixels;
-}
-
-static float brightness_standard_deviation(bNode *node, CompBuf* in, float mean)
-{
- float sum=0.0;
- int numPixels=0.0;
- int x, y;
- float value[4];
-
- for (x=0; x< in->x; x++) {
- for (y=0; y < in->y; y++) {
-
- /* get the pixel */
- qd_getPixel(in, x, y, value);
-
- if (value[3] > 0.0f) { /* don't count transparent pixels */
- numPixels++;
- switch (node->custom1) {
- case 1:
- {
- value[0] = rgb_to_bw(value);
- sum+=(value[0]-mean)*(value[0]-mean);
- break;
- }
- case 2:
- {
- sum+=value[0];
- sum+=(value[0]-mean)*(value[0]-mean);
- break;
- }
- case 3:
- {
- sum+=value[1];
- sum+=(value[1]-mean)*(value[1]-mean);
- break;
- }
- case 4:
- {
- sum+=value[2];
- sum+=(value[2]-mean)*(value[2]-mean);
- break;
- }
- case 5:
- {
- rgb_to_yuv(value[0], value[1], value[2], &value[0], &value[1], &value[2]);
- sum+=(value[0]-mean)*(value[0]-mean);
- break;
- }
- }
- }
- }
- }
-
-
- return sqrt(sum/(float)(numPixels-1));
-}
-
-static void draw_histogram(bNode *node, CompBuf *out, int* bins)
-{
- int x, y;
- float color[4];
- float value;
- int max;
-
- /* find max value */
- max=0;
- for (x=0; x<256; x++) {
- if (bins[x]>max) max=bins[x];
- }
-
- /*draw histogram in buffer */
- for (x=0; x<out->x; x++) {
- for (y=0;y<out->y; y++) {
-
- /* get normalized value (0..255) */
- value=((float)bins[x]/(float)max)*255.0f;
-
- if (y < (int)value) { /*if the y value is below the height of the bar for this line then draw with the color */
- switch (node->custom1) {
- case 1: { /* draw in black */
- color[0]=0.0; color[1]=0.0; color[2]=0.0; color[3]=1.0;
- break;
- }
- case 2: { /* draw in red */
- color[0]=1.0; color[1]=0.0; color[2]=0.0; color[3]=1.0;
- break;
- }
- case 3: { /* draw in green */
- color[0]=0.0; color[1]=1.0; color[2]=0.0; color[3]=1.0;
- break;
- }
- case 4: { /* draw in blue */
- color[0]=0.0; color[1]=0.0; color[2]=1.0; color[3]=1.0;
- break;
- }
- case 5: { /* draw in white */
- color[0]=1.0; color[1]=1.0; color[2]=1.0; color[3]=1.0;
- break;
- }
- }
- }
- else {
- color[0]=0.8; color[1]=0.8; color[2]=0.8; color[3]=1.0;
- }
-
- /* set the color */
- qd_setPixel(out, x, y, color);
- }
- }
-}
-
-static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf* cbuf;
- CompBuf* histogram;
- float mean, std_dev;
- int bins[256];
- int x;
-
- if (in[0]->hasinput==0) return;
- if (in[0]->data==NULL) return;
-
- histogram=alloc_compbuf(256, 256, CB_RGBA, 1);
- cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
-
- /*initalize bins*/
- for (x=0; x<256; x++) {
- bins[x]=0;
- }
-
- /*fill bins */
- fill_bins(node, in[0]->data, bins);
-
- /* draw the histogram chart */
- draw_histogram(node, histogram, bins);
-
- /* calculate the average brightness and contrast */
- mean=brightness_mean(node, in[0]->data);
- std_dev=brightness_standard_deviation(node, in[0]->data, mean);
-
- /* Printf debuging ;) */
-#if 0
- printf("Mean: %f\n", mean);
- printf("Std Dev: %f\n", std_dev);
-#endif
-
- if (out[0]->hasoutput)
- out[0]->vec[0] = mean;
- if (out[1]->hasoutput)
- out[1]->vec[0] = std_dev;
-
- generate_preview(data, node, histogram);
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
- free_compbuf(histogram);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_view_levels(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->custom1=1; /*All channels*/
@@ -324,12 +56,8 @@ void register_node_type_cmp_view_levels(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_VIEW_LEVELS, "Levels", NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW);
node_type_socket_templates(&ntype, cmp_node_view_levels_in, cmp_node_view_levels_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_view_levels);
node_type_storage(&ntype, "ImageUser", NULL, NULL);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_view_levels);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c b/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c
index ed232933139..60a7f3014de 100644
--- a/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c
@@ -45,61 +45,6 @@ static bNodeSocketTemplate cmp_node_luma_matte_out[] = {
{-1, 0, ""}
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_luma_matte(bNode *node, float *out, float *in)
-{
- NodeChroma *c=(NodeChroma *)node->storage;
- float alpha;
-
- /* test range*/
- if (in[0]>c->t1) {
- alpha=1.0;
- }
- else if (in[0]<c->t2) {
- alpha=0.0;
- }
- else {/*blend */
- alpha=(in[0]-c->t2)/(c->t1-c->t2);
- }
-
- /* don't make something that was more transparent less transparent */
- if (alpha<in[3]) {
- out[3]=alpha;
- }
- else {
- out[3]=in[3];
- }
-
-}
-
-static void node_composit_exec_luma_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *cbuf;
- CompBuf *outbuf;
-
- if (in[0]->hasinput==0) return;
- if (in[0]->data==NULL) return;
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
-
- cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
-
- outbuf=dupalloc_compbuf(cbuf);
-
- composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_rgba_to_yuva, CB_RGBA);
- composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_luma_matte, CB_RGBA);
- composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_yuva_to_rgba, CB_RGBA);
-
- generate_preview(data, node, outbuf);
- out[0]->data=outbuf;
- if (out[1]->hasoutput)
- out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_luma_matte(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
@@ -114,12 +59,8 @@ void register_node_type_cmp_luma_matte(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_LUMA_MATTE, "Luminance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_luma_matte_in, cmp_node_luma_matte_out);
- node_type_size(&ntype, 200, 80, 250);
node_type_init(&ntype, node_composit_init_luma_matte);
node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_luma_matte);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_mapRange.c b/source/blender/nodes/composite/nodes/node_composite_mapRange.c
index f96e133b19f..07f34e79bd1 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mapRange.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mapRange.c
@@ -52,7 +52,6 @@ void register_node_type_cmp_map_range(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MAP_RANGE, "Map Range", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_map_range_in, cmp_node_map_range_out);
- node_type_size(&ntype, 120, 60, 150);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_mapUV.c b/source/blender/nodes/composite/nodes/node_composite_mapUV.c
index 40092a84367..fa4c8d7022c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mapUV.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mapUV.c
@@ -44,138 +44,12 @@ static bNodeSocketTemplate cmp_node_mapuv_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* foreach UV, use these values to read in cbuf and write to stackbuf */
-/* stackbuf should be zeroed */
-static void do_mapuv(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *uvbuf, float threshold)
-{
- ImBuf *ibuf;
- float *out= stackbuf->rect, *uv, *uvnext, *uvprev;
- float dx, dy, alpha;
- int x, y, sx, sy, row= 3*stackbuf->x;
-
- /* ibuf needed for sampling */
- ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
- ibuf->rect_float= cbuf->rect;
-
- /* vars for efficient looping */
- uv= uvbuf->rect;
- uvnext= uv+row;
- uvprev= uv-row;
- sx= stackbuf->x;
- sy= stackbuf->y;
-
- for (y=0; y<sy; y++) {
- for (x=0; x<sx; x++, out+=4, uv+=3, uvnext+=3, uvprev+=3) {
- if (x>0 && x<sx-1 && y>0 && y<sy-1) {
- if (uv[2]!=0.0f) {
- float uv_l, uv_r;
-
- /* adaptive sampling, red (U) channel */
-
- /* prevent alpha zero UVs to be used */
- uv_l= uv[-1]!=0.0f? fabsf(uv[0]-uv[-3]) : 0.0f;
- uv_r= uv[ 5]!=0.0f? fabsf(uv[0]-uv[ 3]) : 0.0f;
-
- //dx= 0.5f*(fabs(uv[0]-uv[-3]) + fabs(uv[0]-uv[3]));
- dx= 0.5f*(uv_l + uv_r);
-
- uv_l= uvprev[-1]!=0.0f? fabsf(uv[0]-uvprev[-3]) : 0.0f;
- uv_r= uvnext[-1]!=0.0f? fabsf(uv[0]-uvnext[-3]) : 0.0f;
-
- //dx+= 0.25f*(fabs(uv[0]-uvprev[-3]) + fabs(uv[0]-uvnext[-3]));
- dx+= 0.25f*(uv_l + uv_r);
-
- uv_l= uvprev[ 5]!=0.0f? fabsf(uv[0]-uvprev[+3]) : 0.0f;
- uv_r= uvnext[ 5]!=0.0f? fabsf(uv[0]-uvnext[+3]) : 0.0f;
-
- //dx+= 0.25f*(fabs(uv[0]-uvprev[+3]) + fabs(uv[0]-uvnext[+3]));
- dx+= 0.25f*(uv_l + uv_r);
-
- /* adaptive sampling, green (V) channel */
-
- uv_l= uv[-row+2]!=0.0f? fabsf(uv[1]-uv[-row+1]) : 0.0f;
- uv_r= uv[ row+2]!=0.0f? fabsf(uv[1]-uv[ row+1]) : 0.0f;
-
- //dy= 0.5f*(fabs(uv[1]-uv[-row+1]) + fabs(uv[1]-uv[row+1]));
- dy= 0.5f*(uv_l + uv_r);
-
- uv_l= uvprev[-1]!=0.0f? fabsf(uv[1]-uvprev[+1-3]) : 0.0f;
- uv_r= uvnext[-1]!=0.0f? fabsf(uv[1]-uvnext[+1-3]) : 0.0f;
-
- //dy+= 0.25f*(fabs(uv[1]-uvprev[+1-3]) + fabs(uv[1]-uvnext[+1-3]));
- dy+= 0.25f*(uv_l + uv_r);
-
- uv_l= uvprev[ 5]!=0.0f? fabsf(uv[1]-uvprev[+1+3]) : 0.0f;
- uv_r= uvnext[ 5]!=0.0f? fabsf(uv[1]-uvnext[+1+3]) : 0.0f;
-
- //dy+= 0.25f*(fabs(uv[1]-uvprev[+1+3]) + fabs(uv[1]-uvnext[+1+3]));
- dy+= 0.25f*(uv_l + uv_r);
-
- /* UV to alpha threshold */
- alpha= 1.0f - threshold*(dx+dy);
- if (alpha<0.0f) alpha= 0.0f;
- else alpha*= uv[2];
-
- /* should use mipmap */
- if (dx > 0.20f) dx= 0.20f;
- if (dy > 0.20f) dy= 0.20f;
-
- ibuf_sample(ibuf, uv[0], uv[1], dx, dy, out);
- /* premul */
- if (alpha<1.0f) {
- out[0]*= alpha;
- out[1]*= alpha;
- out[2]*= alpha;
- out[3]*= alpha;
- }
- }
- }
- }
- }
-
- IMB_freeImBuf(ibuf);
-}
-
-
-static void node_composit_exec_mapuv(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (out[0]->hasoutput==0)
- return;
-
- if (in[0]->data && in[1]->data) {
- CompBuf *cbuf= in[0]->data;
- CompBuf *uvbuf= in[1]->data;
- CompBuf *stackbuf;
-
- cbuf= typecheck_compbuf(cbuf, CB_RGBA);
- uvbuf= typecheck_compbuf(uvbuf, CB_VEC3);
- stackbuf= alloc_compbuf(uvbuf->x, uvbuf->y, CB_RGBA, 1); /* allocs */;
-
- do_mapuv(stackbuf, cbuf, uvbuf, 0.05f*(float)node->custom1);
-
- out[0]->data= stackbuf;
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
- if (uvbuf!=in[1]->data)
- free_compbuf(uvbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_mapuv(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_MAP_UV, "Map UV", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_mapuv_in, cmp_node_mapuv_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_mapuv);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_mapValue.c b/source/blender/nodes/composite/nodes/node_composite_mapValue.c
index 677d5bd5013..046eeaf4fc8 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mapValue.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mapValue.c
@@ -42,44 +42,6 @@ static bNodeSocketTemplate cmp_node_map_value_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_map_value(bNode *node, float *out, float *src)
-{
- TexMapping *texmap= node->storage;
-
- out[0] = (src[0] + texmap->loc[0])*texmap->size[0];
- if (texmap->flag & TEXMAP_CLIP_MIN)
- if (out[0]<texmap->min[0])
- out[0] = texmap->min[0];
- if (texmap->flag & TEXMAP_CLIP_MAX)
- if (out[0]>texmap->max[0])
- out[0] = texmap->max[0];
-}
-
-static void node_composit_exec_map_value(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: valbuf */
- /* stack order out: valbuf */
- if (out[0]->hasoutput==0) return;
-
- /* input no image? then only value operation */
- if (in[0]->data==NULL) {
- do_map_value(node, out[0]->vec, in[0]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
-
- composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_map_value, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_map_value(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->storage= add_tex_mapping();
@@ -91,12 +53,8 @@ void register_node_type_cmp_map_value(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MAP_VALUE, "Map Value", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_map_value_in, cmp_node_map_value_out);
- node_type_size(&ntype, 100, 60, 150);
node_type_init(&ntype, node_composit_init_map_value);
node_type_storage(&ntype, "TexMapping", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_map_value);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c
index 3463c1a8413..27534698422 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mask.c
@@ -45,51 +45,9 @@ static bNodeSocketTemplate cmp_node_mask_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-static void node_composit_exec_mask(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- if (node->id) {
- Mask *mask = (Mask *)node->id;
- MaskRasterHandle *mr_handle;
- CompBuf *stackbuf;
- RenderData *rd = data;
- float *res;
- int sx, sy;
-
- if (!out[0]->hasoutput) {
- /* the node's output socket is not connected to anything...
- * do not execute any further, just exit the node immediately
- */
- return;
- }
-
- sx = (rd->size * rd->xsch) / 100;
- sy = (rd->size * rd->ysch) / 100;
-
- /* allocate the output buffer */
- stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE);
- res = stackbuf->rect;
-
- /* mask raster begin */
- mr_handle = BKE_maskrasterize_handle_new();
- BKE_maskrasterize_handle_init(mr_handle, mask,
- sx, sy,
- TRUE,
- (node->custom1 & CMP_NODEFLAG_MASK_AA) != 0,
- (node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0);
- BKE_maskrasterize_buffer(mr_handle, sx, sy, res);
- BKE_maskrasterize_handle_free(mr_handle);
- /* mask raster end */
-
- /* pass on output and free */
- out[0]->data = stackbuf;
- }
-}
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_mask(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
- NodeMask *data = MEM_callocN(sizeof(NodeMask), STRINGIFY(NodeMask));
+ NodeMask *data = MEM_callocN(sizeof(NodeMask), "NodeMask");
data->size_x = data->size_y = 256;
node->storage = data;
@@ -103,11 +61,7 @@ void register_node_type_cmp_mask(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MASK, "Mask", NODE_CLASS_INPUT, NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_mask_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_mask);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_mask);
-#endif
node_type_storage(&ntype, "NodeMask", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_math.c b/source/blender/nodes/composite/nodes/node_composite_math.c
index 5bc67adf5fb..5f5369ce03a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_math.c
+++ b/source/blender/nodes/composite/nodes/node_composite_math.c
@@ -44,161 +44,6 @@ static bNodeSocketTemplate cmp_node_math_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_math(bNode *node, float *out, float *in, float *in2)
-{
- switch (node->custom1) {
- case 0: /* Add */
- out[0] = in[0] + in2[0];
- break;
- case 1: /* Subtract */
- out[0] = in[0] - in2[0];
- break;
- case 2: /* Multiply */
- out[0] = in[0] * in2[0];
- break;
- case 3: /* Divide */
- {
- if (in2[0]==0) /* We don't want to divide by zero. */
- out[0] = 0.0;
- else
- out[0] = in[0] / in2[0];
- }
- break;
- case 4: /* Sine */
- out[0] = sin(in[0]);
- break;
- case 5: /* Cosine */
- out[0] = cos(in[0]);
- break;
- case 6: /* Tangent */
- out[0] = tan(in[0]);
- break;
- case 7: /* Arc-Sine */
- {
- /* Can't do the impossible... */
- if (in[0] <= 1 && in[0] >= -1 )
- out[0] = asin(in[0]);
- else
- out[0] = 0.0;
- }
- break;
- case 8: /* Arc-Cosine */
- {
- /* Can't do the impossible... */
- if ( in[0] <= 1 && in[0] >= -1 )
- out[0] = acos(in[0]);
- else
- out[0] = 0.0;
- }
- break;
- case 9: /* Arc-Tangent */
- out[0] = atan(in[0]);
- break;
- case 10: /* Power */
- {
- /* Only raise negative numbers by full integers */
- if ( in[0] >= 0 ) {
- out[0] = pow(in[0], in2[0]);
- }
- else {
- float y_mod_1 = fabsf(fmodf(in2[0], 1.0f));
-
- /* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */
- if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
- out[0] = powf(in[0], floorf(in2[0] + 0.5f));
- }
- else {
- out[0] = 0.0f;
- }
- }
- }
- break;
- case 11: /* Logarithm */
- {
- /* Don't want any imaginary numbers... */
- if ( in[0] > 0 && in2[0] > 0 )
- out[0] = log(in[0]) / log(in2[0]);
- else
- out[0] = 0.0;
- }
- break;
- case 12: /* Minimum */
- {
- if ( in[0] < in2[0] )
- out[0] = in[0];
- else
- out[0] = in2[0];
- }
- break;
- case 13: /* Maximum */
- {
- if ( in[0] > in2[0] )
- out[0] = in[0];
- else
- out[0] = in2[0];
- }
- break;
- case 14: /* Round */
- {
- /* round by the second value */
- if ( in2[0] != 0.0f )
- out[0] = floorf(in[0] / in2[0] + 0.5f) * in2[0];
- else
- out[0] = floorf(in[0] + 0.5f);
- }
- break;
- case 15: /* Less Than */
- {
- if ( in[0] < in2[0] )
- out[0] = 1.0f;
- else
- out[0] = 0.0f;
- }
- break;
- case 16: /* Greater Than */
- {
- if ( in[0] > in2[0] )
- out[0] = 1.0f;
- else
- out[0] = 0.0f;
- }
- break;
- }
-}
-
-static void node_composit_exec_math(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *cbuf=in[0]->data;
- CompBuf *cbuf2=in[1]->data;
- CompBuf *stackbuf;
-
- /* check for inputs and outputs for early out*/
- if (out[0]->hasoutput==0) return;
-
- /* no image-color operation */
- if (in[0]->data==NULL && in[1]->data==NULL) {
- do_math(node, out[0]->vec, in[0]->vec, in[1]->vec);
- return;
- }
-
- /* create output based on first input */
- if (cbuf) {
- stackbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
- }
- /* and if it doesn't exist use the second input since we
- * know that one of them must exist at this point*/
- else {
- stackbuf=alloc_compbuf(cbuf2->x, cbuf2->y, CB_VAL, 1);
- }
-
- /* operate in case there's valid size */
- composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_math, CB_VAL, CB_VAL);
- out[0]->data= stackbuf;
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
void register_node_type_cmp_math(bNodeTreeType *ttype)
{
@@ -206,11 +51,7 @@ void register_node_type_cmp_math(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_math_in, cmp_node_math_out);
- node_type_size(&ntype, 120, 110, 160);
node_type_label(&ntype, node_math_label);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_math);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_mixrgb.c b/source/blender/nodes/composite/nodes/node_composite_mixrgb.c
index 5d3ee480612..23e4fc90457 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mixrgb.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mixrgb.c
@@ -43,48 +43,6 @@ static bNodeSocketTemplate cmp_node_mix_rgb_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_mix_rgb(bNode *node, float *out, float *in1, float *in2, float *fac)
-{
- float col[3];
-
- copy_v3_v3(col, in1);
- if (node->custom2)
- ramp_blend(node->custom1, col, in2[3]*fac[0], in2);
- else
- ramp_blend(node->custom1, col, fac[0], in2);
- copy_v3_v3(out, col);
- out[3] = in1[3];
-}
-
-static void node_composit_exec_mix_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: fac, Image, Image */
- /* stack order out: Image */
- float *fac= in[0]->vec;
-
- if (out[0]->hasoutput==0) return;
-
- /* input no image? then only color operation */
- if (in[1]->data==NULL && in[2]->data==NULL) {
- do_mix_rgb(node, out[0]->vec, in[1]->vec, in[2]->vec, fac);
- }
- else {
- /* make output size of first available input image */
- CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, fac, do_mix_rgb, CB_RGBA, CB_RGBA, CB_VAL);
-
- out[0]->data= stackbuf;
-
- generate_preview(data, node, out[0]->data);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
/* custom1 = mix type */
void register_node_type_cmp_mix_rgb(bNodeTreeType *ttype)
{
@@ -92,11 +50,7 @@ void register_node_type_cmp_mix_rgb(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_mix_rgb_in, cmp_node_mix_rgb_out);
- node_type_size(&ntype, 110, 60, 120);
node_type_label(&ntype, node_blend_label);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_mix_rgb);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c
index 370cff5e0d7..39d46e053bf 100644
--- a/source/blender/nodes/composite/nodes/node_composite_movieclip.c
+++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c
@@ -42,106 +42,6 @@ static bNodeSocketTemplate cmp_node_movieclip_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static CompBuf *node_composit_get_movieclip(RenderData *rd, MovieClip *clip, MovieClipUser *user)
-{
- ImBuf *orig_ibuf, *ibuf;
- CompBuf *stackbuf;
- int type;
-
- float *rect;
- int alloc = FALSE;
-
- orig_ibuf = BKE_movieclip_get_ibuf(clip, user);
-
- if (orig_ibuf == NULL || (orig_ibuf->rect == NULL && orig_ibuf->rect_float == NULL)) {
- IMB_freeImBuf(orig_ibuf);
- return NULL;
- }
-
- ibuf = IMB_dupImBuf(orig_ibuf);
- IMB_freeImBuf(orig_ibuf);
-
- if (ibuf->rect_float == NULL || (ibuf->userflags & IB_RECT_INVALID)) {
- IMB_float_from_rect(ibuf);
- ibuf->userflags &= ~IB_RECT_INVALID;
- }
-
- /* now we need a float buffer from the image with matching color management */
- if (ibuf->channels == 4) {
- rect = node_composit_get_float_buffer(rd, ibuf, &alloc);
- }
- else {
- /* non-rgba passes can't use color profiles */
- rect = ibuf->rect_float;
- }
- /* done coercing into the correct color management */
-
- if (!alloc) {
- rect = MEM_dupallocN(rect);
- alloc = TRUE;
- }
-
- type = ibuf->channels;
-
- if (rd->scemode & R_COMP_CROP) {
- stackbuf = get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
- if (alloc)
- MEM_freeN(rect);
- }
- else {
- /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
- stackbuf = alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
- stackbuf->rect = rect;
- stackbuf->malloc = alloc;
- }
-
- IMB_freeImBuf(ibuf);
-
- return stackbuf;
-}
-
-static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- if (node->id) {
- RenderData *rd = data;
- MovieClip *clip = (MovieClip *)node->id;
- MovieClipUser *user = (MovieClipUser *)node->storage;
- CompBuf *stackbuf = NULL;
-
- BKE_movieclip_user_set_frame(user, rd->cfra);
-
- stackbuf = node_composit_get_movieclip(rd, clip, user);
-
- if (stackbuf) {
- MovieTrackingStabilization *stab = &clip->tracking.stabilization;
-
- /* put image on stack */
- out[0]->data = stackbuf;
-
- if (stab->flag & TRACKING_2D_STABILIZATION) {
- float loc[2], scale, angle;
- int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, rd->cfra);
-
- BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, stackbuf->x, stackbuf->y,
- loc, &scale, &angle);
-
- out[1]->vec[0] = loc[0];
- out[2]->vec[0] = loc[1];
-
- out[3]->vec[0] = scale;
- out[4]->vec[0] = angle;
- }
-
- /* generate preview */
- generate_preview(data, node, stackbuf);
- }
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
MovieClipUser *user = MEM_callocN(sizeof(MovieClipUser), "node movie clip user");
@@ -156,12 +56,8 @@ void register_node_type_cmp_movieclip(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out);
- node_type_size(&ntype, 120, 80, 300);
node_type_init(&ntype, init);
node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_movieclip);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
index 9f4cd467c94..198ffbb2857 100644
--- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
+++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
@@ -30,9 +30,6 @@
* \ingroup cmpnodes
*/
-#include "BLF_translation.h"
-
-
#include "node_composite_util.h"
/* **************** Translate ******************** */
@@ -47,66 +44,6 @@ static bNodeSocketTemplate cmp_node_moviedistortion_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-static void node_composit_exec_moviedistortion(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (in[0]->data) {
- if (node->id) {
- MovieClip *clip = (MovieClip *)node->id;
- CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA);
- CompBuf *stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
- ImBuf *ibuf;
-
- ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
-
- if (ibuf) {
- RenderData *rd = data;
- ImBuf *obuf;
- MovieTracking *tracking = &clip->tracking;
- int width, height;
- float overscan = 0.0f;
- MovieClipUser user = {0};
-
- BKE_movieclip_user_set_frame(&user, rd->cfra);
-
- ibuf->rect_float = cbuf->rect;
-
- BKE_movieclip_get_size(clip, &user, &width, &height);
-
- if (!node->storage)
- node->storage = BKE_tracking_distortion_new();
-
- if (node->custom1 == 0)
- obuf = BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 1);
- else
- obuf = BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 0);
-
- stackbuf->rect = obuf->rect_float;
- stackbuf->malloc = TRUE;
-
- obuf->mall &= ~IB_rectfloat;
- obuf->rect_float = NULL;
-
- IMB_freeImBuf(ibuf);
- IMB_freeImBuf(obuf);
- }
-
- /* pass on output and free */
- out[0]->data = stackbuf;
-
- if (cbuf != in[0]->data)
- free_compbuf(cbuf);
- }
- else {
- CompBuf *cbuf = in[0]->data;
- CompBuf *stackbuf = pass_on_compbuf(cbuf);
-
- out[0]->data = stackbuf;
- }
- }
-}
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static const char *label(bNode *node)
{
if (node->custom1 == 0)
@@ -135,11 +72,7 @@ void register_node_type_cmp_moviedistortion(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_MOVIEDISTORTION, "Movie Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_moviedistortion_in, cmp_node_moviedistortion_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_label(&ntype, label);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_moviedistortion);
-#endif
node_type_storage(&ntype, NULL, storage_free, storage_copy);
diff --git a/source/blender/nodes/composite/nodes/node_composite_normal.c b/source/blender/nodes/composite/nodes/node_composite_normal.c
index d104e8f03e6..88db5d36810 100644
--- a/source/blender/nodes/composite/nodes/node_composite_normal.c
+++ b/source/blender/nodes/composite/nodes/node_composite_normal.c
@@ -45,44 +45,6 @@ static bNodeSocketTemplate cmp_node_normal_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_normal(bNode *node, float *out, float *in)
-{
- bNodeSocket *sock= node->outputs.first;
- float *nor= ((bNodeSocketValueVector*)sock->default_value)->value;
-
- /* render normals point inside... the widget points outside */
- out[0] = -dot_v3v3(nor, in);
-}
-
-/* generates normal, does dot product */
-static void node_composit_exec_normal(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- bNodeSocket *sock= node->outputs.first;
- float *nor= ((bNodeSocketValueVector*)sock->default_value)->value;
- /* stack order input: normal */
- /* stack order output: normal, value */
-
- /* input no image? then only vector op */
- if (in[0]->data==NULL) {
- copy_v3_v3(out[0]->vec, nor);
- /* render normals point inside... the widget points outside */
- out[1]->vec[0] = -dot_v3v3(out[0]->vec, in[0]->vec);
- }
- else if (out[1]->hasoutput) {
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
-
- composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_normal, CB_VEC3);
-
- out[1]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
bNodeSocket *sock= node->outputs.first;
@@ -100,10 +62,6 @@ void register_node_type_cmp_normal(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_normal_in, cmp_node_normal_out);
node_type_init(&ntype, init);
- node_type_size(&ntype, 100, 60, 200);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_normal);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_normalize.c b/source/blender/nodes/composite/nodes/node_composite_normalize.c
index 19b543dce5d..db811666900 100644
--- a/source/blender/nodes/composite/nodes/node_composite_normalize.c
+++ b/source/blender/nodes/composite/nodes/node_composite_normalize.c
@@ -43,79 +43,12 @@ static bNodeSocketTemplate cmp_node_normalize_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_normalize(bNode *UNUSED(node), float *out, float *src, float *min, float *mult)
-{
- float res;
- res = (src[0] - min[0]) * mult[0];
- if (res > 1.0f) {
- out[0] = 1.0f;
- }
- else if (res < 0.0f) {
- out[0] = 0.0f;
- }
- else {
- out[0] = res;
- }
-}
-
-/* The code below assumes all data is inside range +- this, and that input buffer is single channel */
-#define BLENDER_ZMAX 10000.0f
-
-static void node_composit_exec_normalize(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: valbuf */
- /* stack order out: valbuf */
- if (out[0]->hasoutput==0) return;
-
- /* Input has no image buffer? Then pass the value */
- if (in[0]->data==NULL) {
- copy_v4_v4(out[0]->vec, in[0]->vec);
- }
- else {
- float min = 1.0f+BLENDER_ZMAX;
- float max = -1.0f-BLENDER_ZMAX;
- float mult = 1.0f;
- float *val;
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data;
- int tot= cbuf->x*cbuf->y;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
-
- for (val = cbuf->rect; tot; tot--, val++) {
- if ((*val > max) && (*val <= BLENDER_ZMAX)) {
- max = *val;
- }
- if ((*val < min) && (*val >= -BLENDER_ZMAX)) {
- min = *val;
- }
- }
- /* In the rare case of flat buffer, which would cause a divide by 0, just pass the input to the output */
- if ((max-min) != 0.0f) {
- mult = 1.0f/(max-min);
- composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL);
- }
- else {
- memcpy(stackbuf->rect, cbuf->rect, sizeof(float) * cbuf->x * cbuf->y);
- }
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_normalize(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_NORMALIZE, "Normalize", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_normalize_in, cmp_node_normalize_out);
- node_type_size(&ntype, 100, 60, 150);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_normalize);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
index 214617c91e5..dff09b93845 100644
--- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c
+++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
@@ -225,196 +225,15 @@ static void update_output_file(bNodeTree *UNUSED(ntree), bNode *node)
}
}
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* write input data into individual files */
-static void exec_output_file_singlelayer(RenderData *rd, bNode *node, bNodeStack **in)
-{
- Main *bmain= G.main; /* TODO, have this passed along */
- NodeImageMultiFile *nimf= node->storage;
- bNodeSocket *sock;
- int i;
- int has_preview = 0;
-
- for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) {
- if (in[i]->data) {
- NodeImageMultiFileSocket *sockdata = sock->storage;
- ImageFormatData *format = (sockdata->use_node_format ? &nimf->format : &sockdata->format);
- char path[FILE_MAX];
- char filename[FILE_MAX];
- CompBuf *cbuf = NULL;
- ImBuf *ibuf;
-
- switch (format->planes) {
- case R_IMF_PLANES_BW:
- cbuf = typecheck_compbuf(in[i]->data, CB_VAL);
- break;
- case R_IMF_PLANES_RGB:
- cbuf = typecheck_compbuf(in[i]->data, CB_VEC3);
- break;
- case R_IMF_PLANES_RGBA:
- cbuf = typecheck_compbuf(in[i]->data, CB_RGBA);
- break;
- }
-
- ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, format->planes, 0);
- /* XXX have to set this explicitly it seems */
- switch (format->planes) {
- case R_IMF_PLANES_BW: ibuf->channels = 1; break;
- case R_IMF_PLANES_RGB: ibuf->channels = 3; break;
- case R_IMF_PLANES_RGBA: ibuf->channels = 4; break;
- }
- ibuf->rect_float = cbuf->rect;
- ibuf->dither = rd->dither_intensity;
-
- /* get full path */
- BLI_join_dirfile(path, FILE_MAX, nimf->base_path, sockdata->path);
- BKE_makepicstring(filename, path, bmain->name, rd->cfra, format->imtype, (rd->scemode & R_EXTENSION), TRUE);
-
- if (0 == BKE_imbuf_write(ibuf, filename, format))
- printf("Cannot save Node File Output to %s\n", filename);
- else
- printf("Saved: %s\n", filename);
-
- IMB_freeImBuf(ibuf);
-
- /* simply pick the first valid input for preview */
- if (!has_preview) {
- generate_preview(rd, node, cbuf);
- has_preview = 1;
- }
-
- if (in[i]->data != cbuf)
- free_compbuf(cbuf);
- }
- }
-}
-
-/* write input data into layers */
-static void exec_output_file_multilayer(RenderData *rd, bNode *node, bNodeStack **in)
-{
- Main *bmain= G.main; /* TODO, have this passed along */
- NodeImageMultiFile *nimf= node->storage;
- void *exrhandle= IMB_exr_get_handle();
- char filename[FILE_MAX];
- bNodeSocket *sock;
- int i;
- /* Must have consistent pixel size for exr file, simply take the first valid input size. */
- int rectx = -1;
- int recty = -1;
- int has_preview = 0;
-
- BKE_makepicstring(filename, nimf->base_path, bmain->name, rd->cfra, R_IMF_IMTYPE_MULTILAYER, (rd->scemode & R_EXTENSION), TRUE);
- BLI_make_existing_file(filename);
-
- for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) {
- if (in[i]->data) {
- NodeImageMultiFileSocket *sockdata = sock->storage;
- CompBuf *cbuf = in[i]->data;
- char channelname[EXR_TOT_MAXNAME]; /* '.' and single character channel name is appended */
- char *channelname_ext;
-
- if (cbuf->rect_procedural) {
- printf("Error writing multilayer EXR: Procedural buffer not supported\n");
- continue;
- }
- if (rectx < 0) {
- rectx = cbuf->x;
- recty = cbuf->y;
- }
- else if (cbuf->x != rectx || cbuf->y != recty) {
- printf("Error: Multilayer EXR output node %s expects same resolution for all input buffers. Layer %s skipped.\n", node->name, sock->name);
- continue;
- }
-
- BLI_strncpy(channelname, sockdata->layer, sizeof(channelname)-2);
- channelname_ext = channelname + strlen(channelname);
-
- /* create channels */
- switch (cbuf->type) {
- case CB_VAL:
- strcpy(channelname_ext, ".V");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 1, rectx, cbuf->rect);
- break;
- case CB_VEC2:
- strcpy(channelname_ext, ".X");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 2, 2*rectx, cbuf->rect);
- strcpy(channelname_ext, ".Y");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 2, 2*rectx, cbuf->rect+1);
- break;
- case CB_VEC3:
- strcpy(channelname_ext, ".X");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 3, 3*rectx, cbuf->rect);
- strcpy(channelname_ext, ".Y");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 3, 3*rectx, cbuf->rect+1);
- strcpy(channelname_ext, ".Z");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 3, 3*rectx, cbuf->rect+2);
- break;
- case CB_RGBA:
- strcpy(channelname_ext, ".R");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect);
- strcpy(channelname_ext, ".G");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect+1);
- strcpy(channelname_ext, ".B");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect+2);
- strcpy(channelname_ext, ".A");
- IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect+3);
- break;
- }
-
- /* simply pick the first valid input for preview */
- if (!has_preview) {
- generate_preview(rd, node, cbuf);
- has_preview = 1;
- }
- }
- }
-
- /* when the filename has no permissions, this can fail */
- if (IMB_exr_begin_write(exrhandle, filename, rectx, recty, nimf->format.exr_codec)) {
- IMB_exr_write_channels(exrhandle);
- }
- else {
- /* TODO, get the error from openexr's exception */
- /* XXX nice way to do report? */
- printf("Error Writing Render Result, see console\n");
- }
-
- IMB_exr_close(exrhandle);
-}
-
-static void node_composit_exec_outputfile(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
-{
- RenderData *rd= data;
- NodeImageMultiFile *nimf= node->storage;
-
- if (G.is_rendering == FALSE) {
- /* only output files when rendering a sequence -
- * otherwise, it overwrites the output files just
- * scrubbing through the timeline when the compositor updates */
- return;
- }
-
- if (nimf->format.imtype==R_IMF_IMTYPE_MULTILAYER)
- exec_output_file_multilayer(rd, node, in);
- else
- exec_output_file_singlelayer(rd, node, in);
-}
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_output_file(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_OUTPUT_FILE, "File Output", NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW);
node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 140, 80, 300);
node_type_init(&ntype, init_output_file);
node_type_storage(&ntype, "NodeImageMultiFile", free_output_file, copy_output_file);
node_type_update(&ntype, update_output_file, NULL);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_outputfile);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_pixelate.c b/source/blender/nodes/composite/nodes/node_composite_pixelate.c
index 5eac4867a23..3b65a2cdbd5 100644
--- a/source/blender/nodes/composite/nodes/node_composite_pixelate.c
+++ b/source/blender/nodes/composite/nodes/node_composite_pixelate.c
@@ -51,7 +51,6 @@ void register_node_type_cmp_pixelate(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_PIXELATE, "Pixelate", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_pixelate_in, cmp_node_pixelate_out);
- node_type_size(&ntype, 130, 100, 130);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_premulkey.c b/source/blender/nodes/composite/nodes/node_composite_premulkey.c
index 7f7b7692b02..01eb3607760 100644
--- a/source/blender/nodes/composite/nodes/node_composite_premulkey.c
+++ b/source/blender/nodes/composite/nodes/node_composite_premulkey.c
@@ -44,37 +44,12 @@ static bNodeSocketTemplate cmp_node_premulkey_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_premulkey(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (out[0]->hasoutput==0)
- return;
-
- if (in[0]->data) {
- CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
-
- stackbuf= dupalloc_compbuf(cbuf);
- premul_compbuf(stackbuf, node->custom1 == 1);
-
- out[0]->data = stackbuf;
- if (cbuf != in[0]->data)
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_premulkey(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_PREMULKEY, "Alpha Convert", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_premulkey_in, cmp_node_premulkey_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_premulkey);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_rgb.c b/source/blender/nodes/composite/nodes/node_composite_rgb.c
index 54fba650783..30b23a4c146 100644
--- a/source/blender/nodes/composite/nodes/node_composite_rgb.c
+++ b/source/blender/nodes/composite/nodes/node_composite_rgb.c
@@ -39,18 +39,6 @@ static bNodeSocketTemplate cmp_node_rgb_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_rgb(void *UNUSED(data), bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- bNodeSocket *sock= node->outputs.first;
- float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value;
-
- copy_v4_v4(out[0]->vec, col);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_rgb(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
bNodeSocket *sock= node->outputs.first;
@@ -69,10 +57,7 @@ void register_node_type_cmp_rgb(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_RGB, "RGB", NODE_CLASS_INPUT, NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_rgb_out);
node_type_init(&ntype, node_composit_init_rgb);
- node_type_size(&ntype, 140, 80, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_rgb);
-#endif
+ node_type_size_preset(&ntype, NODE_SIZE_SMALL);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.c b/source/blender/nodes/composite/nodes/node_composite_rotate.c
index 9a76764b97e..6b5521ea4d2 100644
--- a/source/blender/nodes/composite/nodes/node_composite_rotate.c
+++ b/source/blender/nodes/composite/nodes/node_composite_rotate.c
@@ -44,87 +44,6 @@ static bNodeSocketTemplate cmp_node_rotate_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* only supports RGBA nodes now */
-static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
-
- if (out[0]->hasoutput==0)
- return;
-
- if (in[0]->data) {
- CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* note, this returns zero'd image */
- float rad, u, v, s, c, centx, centy, miny, maxy, minx, maxx;
- int x, y, yo, xo;
- ImBuf *ibuf, *obuf;
-
- rad= in[1]->vec[0];
-
-
- s= sin(rad);
- c= cos(rad);
- centx= cbuf->x/2;
- centy= cbuf->y/2;
-
- minx= -centx;
- maxx= -centx + (float)cbuf->x;
- miny= -centy;
- maxy= -centy + (float)cbuf->y;
-
-
- ibuf=IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
- obuf=IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0);
-
- if (ibuf && obuf) {
- ibuf->rect_float=cbuf->rect;
- obuf->rect_float=stackbuf->rect;
-
- for (y=miny; y<maxy; y++) {
- yo= y+(int)centy;
-
- for (x=minx; x<maxx;x++) {
- u=c*x + y*s + centx;
- v=-s*x + c*y + centy;
- xo= x+(int)centx;
-
- switch (node->custom1) {
- case 0:
- neareast_interpolation(ibuf, obuf, u, v, xo, yo);
- break;
- case 1:
- bilinear_interpolation(ibuf, obuf, u, v, xo, yo);
- break;
- case 2:
- bicubic_interpolation(ibuf, obuf, u, v, xo, yo);
- break;
- }
-
- }
- }
-
- /* rotate offset vector too, but why negative rad, ehh?? Has to be replaced with [3][3] matrix once (ton) */
- s= sin(-rad);
- c= cos(-rad);
- centx= (float)cbuf->xof; centy= (float)cbuf->yof;
- stackbuf->xof= (int)( c*centx + s*centy);
- stackbuf->yof= (int)(-s*centx + c*centy);
-
- IMB_freeImBuf(ibuf);
- IMB_freeImBuf(obuf);
- }
-
- /* pass on output and free */
- out[0]->data= stackbuf;
- if (cbuf!=in[0]->data) {
- free_compbuf(cbuf);
- }
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_rotate(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->custom1= 1; /* Bilinear Filter*/
@@ -136,11 +55,7 @@ void register_node_type_cmp_rotate(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_rotate_in, cmp_node_rotate_out);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_rotate);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_rotate);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c
index 2224d653c37..6c2c6c37cb7 100644
--- a/source/blender/nodes/composite/nodes/node_composite_scale.c
+++ b/source/blender/nodes/composite/nodes/node_composite_scale.c
@@ -45,157 +45,12 @@ static bNodeSocketTemplate cmp_node_scale_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* only supports RGBA nodes now */
-/* node->custom1 stores if input values are absolute or relative scale */
-static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (out[0]->hasoutput == 0)
- return;
-
- if (in[0]->data) {
- RenderData *rd = data;
- CompBuf *stackbuf, *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA);
- ImBuf *ibuf;
- int newx, newy;
- float ofsx = 0.0f, ofsy = 0.0f;
-
- if (node->custom1 == CMP_SCALE_RELATIVE) {
- newx = MAX2((int)(in[1]->vec[0] * cbuf->x), 1);
- newy = MAX2((int)(in[2]->vec[0] * cbuf->y), 1);
- }
- else if (node->custom1 == CMP_SCALE_SCENEPERCENT) {
- newx = cbuf->x * (rd->size / 100.0f);
- newy = cbuf->y * (rd->size / 100.0f);
- }
- else if (node->custom1 == CMP_SCALE_RENDERPERCENT) {
-
- if (node->custom3 != 0.0f || node->custom4 != 0.0f) {
- const float w_dst = (rd->xsch * rd->size) / 100;
- const float h_dst = (rd->ysch * rd->size) / 100;
-
- if (w_dst > h_dst) {
- ofsx = node->custom3 * w_dst;
- ofsy = node->custom4 * w_dst;
- }
- else {
- ofsx = node->custom3 * h_dst;
- ofsy = node->custom4 * h_dst;
- }
- }
-
- /* supports framing options */
- if (node->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) {
- /* apply aspect from clip */
- const float w_src = cbuf->x;
- const float h_src = cbuf->y;
-
- /* destination aspect is already applied from the camera frame */
- const float w_dst = (rd->xsch * rd->size) / 100;
- const float h_dst = (rd->ysch * rd->size) / 100;
-
- const float asp_src = w_src / h_src;
- const float asp_dst = w_dst / h_dst;
-
- if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
- if ((asp_src > asp_dst) == ((node->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0)) {
- /* fit X */
- const float div = asp_src / asp_dst;
- newx = w_dst * div;
- newy = h_dst;
- }
- else {
- /* fit Y */
- const float div = asp_dst / asp_src;
- newx = w_dst;
- newy = h_dst * div;
- }
- }
- else {
- /* same as below - no aspect correction needed */
- newx = w_dst;
- newy = h_dst;
- }
- }
- else {
- /* stretch */
- newx = (rd->xsch * rd->size) / 100;
- newy = (rd->ysch * rd->size) / 100;
- }
- }
- else { /* CMP_SCALE_ABSOLUTE */
- newx = MAX2((int)in[1]->vec[0], 1);
- newy = MAX2((int)in[2]->vec[0], 1);
- }
- newx = MIN2(newx, CMP_SCALE_MAX);
- newy = MIN2(newy, CMP_SCALE_MAX);
-
- ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
- if (ibuf) {
- ibuf->rect_float = cbuf->rect;
- IMB_scaleImBuf(ibuf, newx, newy);
-
- if (ibuf->rect_float == cbuf->rect) {
- /* no scaling happened. */
- stackbuf = pass_on_compbuf(in[0]->data);
- }
- else {
- stackbuf = alloc_compbuf(newx, newy, CB_RGBA, 0);
- stackbuf->rect = ibuf->rect_float;
- stackbuf->malloc = 1;
- }
-
- ibuf->rect_float = NULL;
- ibuf->mall &= ~IB_rectfloat;
- IMB_freeImBuf(ibuf);
-
- /* also do the translation vector */
- stackbuf->xof = (int)(ofsx + (((float)newx / (float)cbuf->x) * (float)cbuf->xof));
- stackbuf->yof = (int)(ofsy + (((float)newy / (float)cbuf->y) * (float)cbuf->yof));
- }
- else {
- stackbuf = dupalloc_compbuf(cbuf);
- printf("Scaling to %dx%d failed\n", newx, newy);
- }
-
- out[0]->data = stackbuf;
- if (cbuf != in[0]->data)
- free_compbuf(cbuf);
- }
- else if (node->custom1 == CMP_SCALE_ABSOLUTE) {
- CompBuf *stackbuf;
- int a, x, y;
- float *fp;
-
- x = MAX2((int)in[1]->vec[0], 1);
- y = MAX2((int)in[2]->vec[0], 1);
-
- stackbuf = alloc_compbuf(x, y, CB_RGBA, 1);
- fp = stackbuf->rect;
-
- a = stackbuf->x * stackbuf->y;
- while (a--) {
- copy_v4_v4(fp, in[0]->vec);
- fp += 4;
- }
-
- out[0]->data = stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_scale(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_SCALE, "Scale", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_scale_in, cmp_node_scale_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_scale);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c
index f1a75493718..d463f35a07a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c
@@ -46,73 +46,12 @@ static bNodeSocketTemplate cmp_node_sephsva_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_sephsva(bNode *UNUSED(node), float *out, float *in)
-{
- float h, s, v;
-
- rgb_to_hsv(in[0], in[1], in[2], &h, &s, &v);
-
- out[0] = h;
- out[1] = s;
- out[2] = v;
- out[3] = in[3];
-}
-
-static void node_composit_exec_sephsva(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: bw channels */
- /* stack order in: col */
-
- /* input no image? then only color operation */
- if (in[0]->data==NULL) {
- float h, s, v;
-
- rgb_to_hsv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &h, &s, &v);
-
- out[0]->vec[0] = h;
- out[1]->vec[0] = s;
- out[2]->vec[0] = v;
- out[3]->vec[0] = in[0]->vec[3];
- }
- else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) {
- /* create new buffer so input buffer doesn't get corrupted */
- CompBuf *cbuf= dupalloc_compbuf(in[0]->data);
- CompBuf *cbuf2= typecheck_compbuf(cbuf, CB_RGBA);
-
- /* convert the RGB stackbuf to an HSV representation */
- composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sephsva, CB_RGBA);
-
- /* separate each of those channels */
- if (out[0]->hasoutput)
- out[0]->data= valbuf_from_rgbabuf(cbuf2, CHAN_R);
- if (out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(cbuf2, CHAN_G);
- if (out[2]->hasoutput)
- out[2]->data= valbuf_from_rgbabuf(cbuf2, CHAN_B);
- if (out[3]->hasoutput)
- out[3]->data= valbuf_from_rgbabuf(cbuf2, CHAN_A);
-
- /*not used anymore */
- if (cbuf2!=cbuf)
- free_compbuf(cbuf2);
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_sephsva(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_SEPHSVA, "Separate HSVA", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, cmp_node_sephsva_in, cmp_node_sephsva_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_sephsva);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -131,63 +70,12 @@ static bNodeSocketTemplate cmp_node_combhsva_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_comb_hsva(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
-{
- float r, g, b;
- hsv_to_rgb(in1[0], in2[0], in3[0], &r, &g, &b);
-
- out[0] = r;
- out[1] = g;
- out[2] = b;
- out[3] = in4[0];
-}
-
-static void node_composit_exec_combhsva(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: 1 rgba channels */
- /* stack order in: 4 value channels */
-
- /* input no image? then only color operation in HSV */
- if ((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) {
- hsv_to_rgb(in[0]->vec[0], in[1]->vec[0], in[2]->vec[0],
- &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
- out[0]->vec[3] = in[3]->vec[0];
- }
- else {
- /* make output size of first available input image */
- CompBuf *cbuf;
- CompBuf *stackbuf;
-
- /* allocate a CompBuf the size of the first available input */
- if (in[0]->data) cbuf = in[0]->data;
- else if (in[1]->data) cbuf = in[1]->data;
- else if (in[2]->data) cbuf = in[2]->data;
- else cbuf = in[3]->data;
-
- stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec,
- in[2]->data, in[2]->vec, in[3]->data, in[3]->vec,
- do_comb_hsva, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_combhsva(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_COMBHSVA, "Combine HSVA", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_combhsva_in, cmp_node_combhsva_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_combhsva);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c
index 83b2c731020..03b43f5073f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c
@@ -45,52 +45,12 @@ static bNodeSocketTemplate cmp_node_seprgba_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_seprgba(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: bw channels */
- /* stack order in: col */
-
- /* input no image? then only color operation */
- if (in[0]->data==NULL) {
- out[0]->vec[0] = in[0]->vec[0];
- out[1]->vec[0] = in[0]->vec[1];
- out[2]->vec[0] = in[0]->vec[2];
- out[3]->vec[0] = in[0]->vec[3];
- }
- else {
- /* make sure we get right rgba buffer */
- CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
-
- /* don't do any pixel processing, just copy the stack directly (faster, I presume) */
- if (out[0]->hasoutput)
- out[0]->data= valbuf_from_rgbabuf(cbuf, CHAN_R);
- if (out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(cbuf, CHAN_G);
- if (out[2]->hasoutput)
- out[2]->data= valbuf_from_rgbabuf(cbuf, CHAN_B);
- if (out[3]->hasoutput)
- out[3]->data= valbuf_from_rgbabuf(cbuf, CHAN_A);
-
- if (cbuf!=in[0]->data)
- free_compbuf(cbuf);
-
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_seprgba(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_SEPRGBA, "Separate RGBA", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, cmp_node_seprgba_in, cmp_node_seprgba_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_seprgba);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -110,61 +70,12 @@ static bNodeSocketTemplate cmp_node_combrgba_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_combrgba(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
-{
- out[0] = in1[0];
- out[1] = in2[0];
- out[2] = in3[0];
- out[3] = in4[0];
-}
-
-static void node_composit_exec_combrgba(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: 1 rgba channels */
- /* stack order in: 4 value channels */
-
- /* input no image? then only color operation */
- if ((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) {
- out[0]->vec[0] = in[0]->vec[0];
- out[0]->vec[1] = in[1]->vec[0];
- out[0]->vec[2] = in[2]->vec[0];
- out[0]->vec[3] = in[3]->vec[0];
- }
- else {
- /* make output size of first available input image */
- CompBuf *cbuf;
- CompBuf *stackbuf;
-
- /* allocate a CompBuf the size of the first available input */
- if (in[0]->data) cbuf = in[0]->data;
- else if (in[1]->data) cbuf = in[1]->data;
- else if (in[2]->data) cbuf = in[2]->data;
- else cbuf = in[3]->data;
-
- stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec,
- in[2]->data, in[2]->vec, in[3]->data, in[3]->vec,
- do_combrgba, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_combrgba(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_COMBRGBA, "Combine RGBA", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_combrgba_in, cmp_node_combrgba_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_combrgba);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c
index 982d674708c..16aba1ba408 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c
@@ -46,109 +46,6 @@ static bNodeSocketTemplate cmp_node_sepycca_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_sepycca_601(bNode *UNUSED(node), float *out, float *in)
-{
- float y, cb, cr;
-
- rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_ITU_BT601);
-
- /*divided by 255 to normalize for viewing in */
- out[0] = y/255.0f;
- out[1] = cb/255.0f;
- out[2] = cr/255.0f;
- out[3] = in[3];
-}
-
-static void do_sepycca_709(bNode *UNUSED(node), float *out, float *in)
-{
- float y, cb, cr;
-
- rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_ITU_BT709);
-
- /*divided by 255 to normalize for viewing in */
- out[0] = y/255.0f;
- out[1] = cb/255.0f;
- out[2] = cr/255.0f;
- out[3] = in[3];
-}
-
-static void do_sepycca_jfif(bNode *UNUSED(node), float *out, float *in)
-{
- float y, cb, cr;
-
- rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
-
- /*divided by 255 to normalize for viewing in */
- out[0] = y/255.0f;
- out[1] = cb/255.0f;
- out[2] = cr/255.0f;
- out[3] = in[3];
-}
-
-static void node_composit_exec_sepycca(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* input no image? then only color operation */
- if (in[0]->data==NULL) {
- float y, cb, cr;
-
- switch (node->custom1) {
- case 1:
- rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT709);
- break;
- case 2:
- rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
- break;
- case 0:
- default:
- rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT601);
- break;
- }
-
- /*divided by 255 to normalize for viewing in */
- out[0]->vec[0] = y/255.0f;
- out[1]->vec[0] = cb/255.0f;
- out[2]->vec[0] = cr/255.0f;
- out[3]->vec[0] = in[0]->vec[3];
- }
- else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) {
- /* make copy of buffer so input buffer doesn't get corrupted */
- CompBuf *cbuf= dupalloc_compbuf(in[0]->data);
- CompBuf *cbuf2=typecheck_compbuf(cbuf, CB_RGBA);
-
- /* convert the RGB stackbuf to an HSV representation */
- switch (node->custom1) {
- case 1:
- composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_709, CB_RGBA);
- break;
- case 2:
- composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_jfif, CB_RGBA);
- break;
- case 0:
- default:
- composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_601, CB_RGBA);
- break;
- }
-
- /* separate each of those channels */
- if (out[0]->hasoutput)
- out[0]->data= valbuf_from_rgbabuf(cbuf2, CHAN_R);
- if (out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(cbuf2, CHAN_G);
- if (out[2]->hasoutput)
- out[2]->data= valbuf_from_rgbabuf(cbuf2, CHAN_B);
- if (out[3]->hasoutput)
- out[3]->data= valbuf_from_rgbabuf(cbuf2, CHAN_A);
-
- /*not used anymore */
- if (cbuf2!=cbuf)
- free_compbuf(cbuf2);
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
void register_node_type_cmp_sepycca(bNodeTreeType *ttype)
{
@@ -156,10 +53,6 @@ void register_node_type_cmp_sepycca(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_SEPYCCA, "Separate YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_sepycca_in, cmp_node_sepycca_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_sepycca);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -179,138 +72,12 @@ static bNodeSocketTemplate cmp_node_combycca_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_comb_ycca_601(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
-{
- float r, g, b;
- float y, cb, cr;
-
- /*need to un-normalize the data*/
- y=in1[0]*255;
- cb=in2[0]*255;
- cr=in3[0]*255;
-
- ycc_to_rgb(y, cb, cr, &r, &g, &b, BLI_YCC_ITU_BT601);
-
- out[0] = r;
- out[1] = g;
- out[2] = b;
- out[3] = in4[0];
-}
-
-static void do_comb_ycca_709(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
-{
- float r, g, b;
- float y, cb, cr;
-
- /*need to un-normalize the data*/
- y=in1[0]*255;
- cb=in2[0]*255;
- cr=in3[0]*255;
-
- ycc_to_rgb(y, cb, cr, &r, &g, &b, BLI_YCC_ITU_BT709);
-
- out[0] = r;
- out[1] = g;
- out[2] = b;
- out[3] = in4[0];
-}
-
-static void do_comb_ycca_jfif(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
-{
- float r, g, b;
- float y, cb, cr;
-
- /*need to un-normalize the data*/
- y=in1[0]*255;
- cb=in2[0]*255;
- cr=in3[0]*255;
-
- ycc_to_rgb(y, cb, cr, &r, &g, &b, BLI_YCC_JFIF_0_255);
-
- out[0] = r;
- out[1] = g;
- out[2] = b;
- out[3] = in4[0];
-}
-
-static void node_composit_exec_combycca(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: 1 ycca channels */
- /* stack order in: 4 value channels */
-
- /* input no image? then only color operation */
- if ((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) {
- float y = in[0]->vec[0] * 255;
- float cb = in[1]->vec[0] * 255;
- float cr = in[2]->vec[0] * 255;
-
- switch (node->custom1) {
- case 1:
- ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_ITU_BT709);
- break;
- case 2:
- ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_JFIF_0_255);
- break;
- case 0:
- default:
- ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_ITU_BT601);
- break;
- }
-
- out[0]->vec[3] = in[3]->vec[0];
- }
- else {
- /* make output size of first available input image */
- CompBuf *cbuf;
- CompBuf *stackbuf;
-
- /* allocate a CompBuf the size of the first available input */
- if (in[0]->data) cbuf = in[0]->data;
- else if (in[1]->data) cbuf = in[1]->data;
- else if (in[2]->data) cbuf = in[2]->data;
- else cbuf = in[3]->data;
-
- stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
-
- switch (node->custom1) {
- case 1:
- composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec,
- in[2]->data, in[2]->vec, in[3]->data, in[3]->vec,
- do_comb_ycca_709, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
- break;
-
- case 2:
- composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec,
- in[2]->data, in[2]->vec, in[3]->data, in[3]->vec,
- do_comb_ycca_jfif, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
- break;
- case 0:
- default:
- composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec,
- in[2]->data, in[2]->vec, in[3]->data, in[3]->vec,
- do_comb_ycca_601, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
- break;
- }
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_combycca(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_COMBYCCA, "Combine YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_combycca_in, cmp_node_combycca_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_combycca);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c
index 0a9575971b4..7d7ec166fd4 100644
--- a/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c
+++ b/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c
@@ -46,63 +46,6 @@ static bNodeSocketTemplate cmp_node_sepyuva_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_sepyuva(bNode *UNUSED(node), float *out, float *in)
-{
- float y, u, v;
-
- rgb_to_yuv(in[0], in[1], in[2], &y, &u, &v);
-
- out[0] = y;
- out[1] = u;
- out[2] = v;
- out[3] = in[3];
-}
-
-static void node_composit_exec_sepyuva(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: bw channels */
- /* stack order in: col */
-
- /* input no image? then only color operation */
- if (in[0]->data==NULL) {
- float y, u, v;
-
- rgb_to_yuv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &u, &v);
-
- out[0]->vec[0] = y;
- out[1]->vec[0] = u;
- out[2]->vec[0] = v;
- out[3]->vec[0] = in[0]->vec[3];
- }
- else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) {
- /* make copy of buffer so input image doesn't get corrupted */
- CompBuf *cbuf= dupalloc_compbuf(in[0]->data);
- CompBuf *cbuf2=typecheck_compbuf(cbuf, CB_RGBA);
-
- /* convert the RGB stackbuf to an YUV representation */
- composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepyuva, CB_RGBA);
-
- /* separate each of those channels */
- if (out[0]->hasoutput)
- out[0]->data= valbuf_from_rgbabuf(cbuf2, CHAN_R);
- if (out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(cbuf2, CHAN_G);
- if (out[2]->hasoutput)
- out[2]->data= valbuf_from_rgbabuf(cbuf2, CHAN_B);
- if (out[3]->hasoutput)
- out[3]->data= valbuf_from_rgbabuf(cbuf2, CHAN_A);
-
- /*not used anymore */
- if (cbuf2!=cbuf)
- free_compbuf(cbuf2);
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_sepyuva(bNodeTreeType *ttype)
{
@@ -110,10 +53,6 @@ void register_node_type_cmp_sepyuva(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_SEPYUVA, "Separate YUVA", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, cmp_node_sepyuva_in, cmp_node_sepyuva_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_sepyuva);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -133,64 +72,12 @@ static bNodeSocketTemplate cmp_node_combyuva_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_comb_yuva(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
-{
- float r, g, b;
- yuv_to_rgb(in1[0], in2[0], in3[0], &r, &g, &b);
-
- out[0] = r;
- out[1] = g;
- out[2] = b;
- out[3] = in4[0];
-}
-
-static void node_composit_exec_combyuva(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: 1 rgba channels */
- /* stack order in: 4 value channels */
-
- /* input no image? then only color operation */
- if ((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) {
- out[0]->vec[0] = in[0]->vec[0];
- out[0]->vec[1] = in[1]->vec[0];
- out[0]->vec[2] = in[2]->vec[0];
- out[0]->vec[3] = in[3]->vec[0];
- }
- else {
- /* make output size of first available input image */
- CompBuf *cbuf;
- CompBuf *stackbuf;
-
- /* allocate a CompBuf the size of the first available input */
- if (in[0]->data) cbuf = in[0]->data;
- else if (in[1]->data) cbuf = in[1]->data;
- else if (in[2]->data) cbuf = in[2]->data;
- else cbuf = in[3]->data;
-
- stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec,
- in[2]->data, in[2]->vec, in[3]->data, in[3]->vec,
- do_comb_yuva, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_combyuva(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_COMBYUVA, "Combine YUVA", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_combyuva_in, cmp_node_combyuva_out);
- node_type_size(&ntype, 80, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_combyuva);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_setalpha.c b/source/blender/nodes/composite/nodes/node_composite_setalpha.c
index 59c104869fe..d36acc6c054 100644
--- a/source/blender/nodes/composite/nodes/node_composite_setalpha.c
+++ b/source/blender/nodes/composite/nodes/node_composite_setalpha.c
@@ -43,51 +43,12 @@ static bNodeSocketTemplate cmp_node_setalpha_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_setalpha(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: RGBA image */
- /* stack order in: col, alpha */
-
- /* input no image? then only color operation */
- if (in[0]->data==NULL && in[1]->data==NULL) {
- out[0]->vec[0] = in[0]->vec[0];
- out[0]->vec[1] = in[0]->vec[1];
- out[0]->vec[2] = in[0]->vec[2];
- out[0]->vec[3] = in[1]->vec[0];
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data?in[0]->data:in[1]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- if (in[1]->data==NULL && in[1]->vec[0]==1.0f) {
- /* pass on image */
- composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_copy_rgb, CB_RGBA);
- }
- else {
- /* send an compbuf or a value to set as alpha - composit2_pixel_processor handles choosing the right one */
- composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL);
- }
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
-
void register_node_type_cmp_setalpha(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_SETALPHA, "Set Alpha", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_setalpha_in, cmp_node_setalpha_out);
- node_type_size(&ntype, 120, 40, 140);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_setalpha);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
index 41fb0e822ed..38a6981613a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
@@ -39,110 +39,6 @@ static bNodeSocketTemplate cmp_node_splitviewer_in[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_copy_split_rgba(bNode *UNUSED(node), float *out, float *in1, float *in2, float *fac)
-{
- if (*fac==0.0f) {
- copy_v4_v4(out, in1);
- }
- else {
- copy_v4_v4(out, in2);
- }
-}
-
-static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
-{
- /* image assigned to output */
- /* stack order input sockets: image image */
-
- if (in[0]->data==NULL || in[1]->data==NULL)
- return;
-
- if (node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
- Image *ima= (Image *)node->id;
- RenderData *rd= data;
- ImBuf *ibuf;
- CompBuf *cbuf, *buf1, *buf2, *mask;
- int x, y;
- float offset;
- void *lock;
-
- buf1= typecheck_compbuf(in[0]->data, CB_RGBA);
- buf2= typecheck_compbuf(in[1]->data, CB_RGBA);
-
- BKE_image_user_frame_calc(node->storage, rd->cfra, 0);
-
- /* always returns for viewer image, but we check nevertheless */
- ibuf= BKE_image_acquire_ibuf(ima, node->storage, &lock);
- if (ibuf==NULL) {
- printf("node_composit_exec_viewer error\n");
- BKE_image_release_ibuf(ima, ibuf, lock);
- return;
- }
-
- /* free all in ibuf */
- imb_freerectImBuf(ibuf);
- imb_freerectfloatImBuf(ibuf);
- IMB_freezbuffloatImBuf(ibuf);
-
- /* make ibuf, and connect to ima */
- ibuf->x= buf1->x;
- ibuf->y= buf1->y;
- imb_addrectfloatImBuf(ibuf);
-
- ima->ok= IMA_OK_LOADED;
-
- /* output buf */
- cbuf= alloc_compbuf(buf1->x, buf1->y, CB_RGBA, 0); /* no alloc*/
- cbuf->rect= ibuf->rect_float;
-
- /* mask buf */
- mask= alloc_compbuf(buf1->x, buf1->y, CB_VAL, 1);
-
-
- /* Check which offset mode is selected and limit offset if needed */
- if (node->custom2 == 0) {
- offset = buf1->x / 100.0f * node->custom1;
- CLAMP(offset, 0, buf1->x);
- }
- else {
- offset = buf1->y / 100.0f * node->custom1;
- CLAMP(offset, 0, buf1->y);
- }
-
- if (node->custom2 == 0) {
- for (y=0; y<buf1->y; y++) {
- float *fac= mask->rect + y*buf1->x;
- for (x=offset; x>0; x--, fac++)
- *fac= 1.0f;
- }
- }
- else {
- for (y=0; y<offset; y++) {
- float *fac= mask->rect + y*buf1->x;
- for (x=buf1->x; x>0; x--, fac++)
- *fac= 1.0f;
- }
- }
-
- composit3_pixel_processor(node, cbuf, buf1, in[0]->vec, buf2, in[1]->vec, mask, NULL, do_copy_split_rgba, CB_RGBA, CB_RGBA, CB_VAL);
-
- BKE_image_release_ibuf(ima, ibuf, lock);
-
- generate_preview(data, node, cbuf);
- free_compbuf(cbuf);
- free_compbuf(mask);
-
- if (in[0]->data != buf1)
- free_compbuf(buf1);
- if (in[1]->data != buf2)
- free_compbuf(buf2);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_splitviewer(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
@@ -157,14 +53,10 @@ void register_node_type_cmp_splitviewer(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, CMP_NODE_SPLITVIEWER, "SplitViewer", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS);
+ node_type_base(ttype, &ntype, CMP_NODE_SPLITVIEWER, "Split Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_splitviewer_in, NULL);
- node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_splitviewer);
node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_splitviewer);
-#endif
/* Do not allow muting for this node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
index 1787e075a14..6b345b4c15c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
+++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
@@ -45,42 +45,12 @@ static bNodeSocketTemplate cmp_node_stabilize2d_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (in[0]->data && node->id) {
- RenderData *rd = data;
- MovieClip *clip = (MovieClip *)node->id;
- CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA);
- CompBuf *stackbuf;
- float loc[2], scale, angle;
- int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, rd->cfra);
-
- BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, cbuf->x, cbuf->y, loc, &scale, &angle);
-
- stackbuf = node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1);
-
- /* pass on output and free */
- out[0]->data = stackbuf;
-
- if (cbuf != in[0]->data)
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_stabilize2d(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_STABILIZE2D, "Stabilize 2D", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_stabilize2d_in, cmp_node_stabilize2d_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_stabilize2d);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_switch.c b/source/blender/nodes/composite/nodes/node_composite_switch.c
index 7f9127c969f..49fa61a8397 100644
--- a/source/blender/nodes/composite/nodes/node_composite_switch.c
+++ b/source/blender/nodes/composite/nodes/node_composite_switch.c
@@ -52,7 +52,7 @@ void register_node_type_cmp_switch(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_SWITCH, "Switch", NODE_CLASS_LAYOUT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_switch_in, cmp_node_switch_out);
- node_type_size(&ntype, 110, 60, 120);
+ node_type_size_preset(&ntype, NODE_SIZE_SMALL);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_texture.c b/source/blender/nodes/composite/nodes/node_composite_texture.c
index b6518c48638..515093fc3e1 100644
--- a/source/blender/nodes/composite/nodes/node_composite_texture.c
+++ b/source/blender/nodes/composite/nodes/node_composite_texture.c
@@ -44,118 +44,12 @@ static bNodeSocketTemplate cmp_node_texture_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/* called without rect allocated */
-static void texture_procedural(CompBuf *cbuf, float *out, float xco, float yco)
-{
- bNode *node= cbuf->node;
- TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
- float vec[3], *size, nor[3] = {0.0f, 0.0f, 0.0f}, col[4];
- int retval, type= cbuf->procedural_type;
-
- size= cbuf->procedural_size;
-
- vec[0] = size[0]*(xco + cbuf->procedural_offset[0]);
- vec[1] = size[1]*(yco + cbuf->procedural_offset[1]);
- vec[2] = size[2]*cbuf->procedural_offset[2];
-
- retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres);
-
- if (type==CB_VAL) {
- if (texres.talpha)
- col[0] = texres.ta;
- else
- col[0] = texres.tin;
- }
- else if (type==CB_RGBA) {
- if (texres.talpha)
- col[3] = texres.ta;
- else
- col[3] = texres.tin;
-
- if ((retval & TEX_RGB)) {
- copy_v3_v3(col, &texres.tr);
- }
- else {
- copy_v3_fl(col, col[3]);
- }
- }
- else {
- copy_v3_v3(col, nor);
- }
-
- typecheck_compbuf_color(out, col, cbuf->type, cbuf->procedural_type);
-}
-
-/* texture node outputs get a small rect, to make sure all other nodes accept it */
-/* only the pixel-processor nodes do something with it though */
-static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* outputs: value, color, normal */
-
- if (node->id) {
- RenderData *rd= data;
- short sizex, sizey;
-
- /* first make the preview image */
- CompBuf *prevbuf= alloc_compbuf(140, 140, CB_RGBA, 1); /* alloc */
-
- prevbuf->rect_procedural= texture_procedural;
- prevbuf->node= node;
- copy_v3_v3(prevbuf->procedural_offset, in[0]->vec);
- copy_v3_v3(prevbuf->procedural_size, in[1]->vec);
- prevbuf->procedural_type= CB_RGBA;
- composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
-
- generate_preview(data, node, prevbuf);
- free_compbuf(prevbuf);
-
- /* texture procedural buffer type doesnt work well, we now render a buffer in scene size */
- sizex = (rd->size*rd->xsch)/100;
- sizey = (rd->size*rd->ysch)/100;
-
- if (out[0]->hasoutput) {
- CompBuf *stackbuf= alloc_compbuf(sizex, sizey, CB_VAL, 1); /* alloc */
-
- stackbuf->rect_procedural= texture_procedural;
- stackbuf->node= node;
- copy_v3_v3(stackbuf->procedural_offset, in[0]->vec);
- copy_v3_v3(stackbuf->procedural_size, in[1]->vec);
- stackbuf->procedural_type= CB_VAL;
- composit1_pixel_processor(node, stackbuf, stackbuf, out[0]->vec, do_copy_value, CB_VAL);
- stackbuf->rect_procedural= NULL;
-
- out[0]->data= stackbuf;
- }
- if (out[1]->hasoutput) {
- CompBuf *stackbuf= alloc_compbuf(sizex, sizey, CB_RGBA, 1); /* alloc */
-
- stackbuf->rect_procedural= texture_procedural;
- stackbuf->node= node;
- copy_v3_v3(stackbuf->procedural_offset, in[0]->vec);
- copy_v3_v3(stackbuf->procedural_size, in[1]->vec);
- stackbuf->procedural_type= CB_RGBA;
- composit1_pixel_processor(node, stackbuf, stackbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
- stackbuf->rect_procedural= NULL;
-
- out[1]->data= stackbuf;
- }
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_texture(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW);
node_type_socket_templates(&ntype, cmp_node_texture_in, cmp_node_texture_out);
- node_type_size(&ntype, 120, 80, 240);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_texture);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_tonemap.c b/source/blender/nodes/composite/nodes/node_composite_tonemap.c
index 00b1a5514dc..fd3a217b150 100644
--- a/source/blender/nodes/composite/nodes/node_composite_tonemap.c
+++ b/source/blender/nodes/composite/nodes/node_composite_tonemap.c
@@ -41,114 +41,6 @@ static bNodeSocketTemplate cmp_node_tonemap_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static float avgLogLum(CompBuf *src, float* auto_key, float* Lav, float* Cav)
-{
- float lsum = 0;
- int p = src->x*src->y;
- fRGB* bc = (fRGB*)src->rect;
- float avl, maxl = -1e10f, minl = 1e10f;
- const float sc = 1.f/(src->x*src->y);
- *Lav = 0.f;
- while (p--) {
- float L = rgb_to_luma_y(bc[0]);
- *Lav += L;
- add_v3_v3(Cav, bc[0]);
- lsum += (float)log((double)MAX2(L, 0.0) + 1e-5);
- maxl = (L > maxl) ? L : maxl;
- minl = (L < minl) ? L : minl;
- bc++;
- }
- *Lav *= sc;
- mul_v3_fl(Cav, sc);
- maxl = log((double)maxl + 1e-5); minl = log((double)minl + 1e-5f); avl = lsum*sc;
- *auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.f;
- return exp((double)avl);
-}
-
-
-static void tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src)
-{
- int x, y;
- float dr, dg, db, al, igm = (ntm->gamma==0.f) ? 1 : (1.f / ntm->gamma);
- float auto_key, Lav, Cav[3] = {0, 0, 0};
-
- al = avgLogLum(src, &auto_key, &Lav, Cav);
- al = (al == 0.f) ? 0.f : (ntm->key / al);
-
- if (ntm->type == 1) {
- // Reinhard/Devlin photoreceptor
- const float f = exp((double)-ntm->f);
- const float m = (ntm->m > 0.f) ? ntm->m : (0.3f + 0.7f*pow((double)auto_key, 1.4));
- const float ic = 1.f - ntm->c, ia = 1.f - ntm->a;
- if (ntm->m == 0.f) printf("tonemap node, M: %g\n", m);
- for (y=0; y<src->y; ++y) {
- fRGB* sp = (fRGB*)&src->rect[y*src->x*src->type];
- fRGB* dp = (fRGB*)&dst->rect[y*src->x*src->type];
- for (x=0; x<src->x; ++x) {
- const float L = rgb_to_luma_y(sp[x]);
- float I_l = sp[x][0] + ic*(L - sp[x][0]);
- float I_g = Cav[0] + ic*(Lav - Cav[0]);
- float I_a = I_l + ia*(I_g - I_l);
- dp[x][0] /= (dp[x][0] + pow((double)f*I_a, (double)m));
- I_l = sp[x][1] + ic*(L - sp[x][1]);
- I_g = Cav[1] + ic*(Lav - Cav[1]);
- I_a = I_l + ia*(I_g - I_l);
- dp[x][1] /= (dp[x][1] + pow((double)f*I_a, (double)m));
- I_l = sp[x][2] + ic*(L - sp[x][2]);
- I_g = Cav[2] + ic*(Lav - Cav[2]);
- I_a = I_l + ia*(I_g - I_l);
- dp[x][2] /= (dp[x][2] + pow((double)f*I_a, (double)m));
- }
- }
- return;
- }
-
- // Reinhard simple photographic tm (simplest, not using whitepoint var)
- for (y=0; y<src->y; y++) {
- fRGB* sp = (fRGB*)&src->rect[y*src->x*src->type];
- fRGB* dp = (fRGB*)&dst->rect[y*src->x*src->type];
- for (x=0; x<src->x; x++) {
- copy_v4_v4(dp[x], sp[x]);
- mul_v3_fl(dp[x], al);
- dr = dp[x][0] + ntm->offset;
- dg = dp[x][1] + ntm->offset;
- db = dp[x][2] + ntm->offset;
- dp[x][0] /= ((dr == 0.f) ? 1.f : dr);
- dp[x][1] /= ((dg == 0.f) ? 1.f : dg);
- dp[x][2] /= ((db == 0.f) ? 1.f : db);
- if (igm != 0.f) {
- dp[x][0] = pow((double)MAX2(dp[x][0], 0.0), igm);
- dp[x][1] = pow((double)MAX2(dp[x][1], 0.0), igm);
- dp[x][2] = pow((double)MAX2(dp[x][2], 0.0), igm);
- }
- }
- }
-}
-
-
-static void node_composit_exec_tonemap(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- CompBuf *new, *img = in[0]->data;
-
- if ((img==NULL) || (out[0]->hasoutput==0)) return;
-
- if (img->type != CB_RGBA)
- img = typecheck_compbuf(img, CB_RGBA);
-
- new = dupalloc_compbuf(img);
-
- tonemap(node->storage, new, img);
-
- out[0]->data = new;
-
- if (img!=in[0]->data)
- free_compbuf(img);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_tonemap(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeTonemap *ntm = MEM_callocN(sizeof(NodeTonemap), "node tonemap data");
@@ -171,12 +63,8 @@ void register_node_type_cmp_tonemap(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_TONEMAP, "Tonemap", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_tonemap_in, cmp_node_tonemap_out);
- node_type_size(&ntype, 150, 120, 200);
node_type_init(&ntype, node_composit_init_tonemap);
node_type_storage(&ntype, "NodeTonemap", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_tonemap);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_trackpos.c b/source/blender/nodes/composite/nodes/node_composite_trackpos.c
index 4364ca61ba1..8014e879894 100644
--- a/source/blender/nodes/composite/nodes/node_composite_trackpos.c
+++ b/source/blender/nodes/composite/nodes/node_composite_trackpos.c
@@ -39,15 +39,6 @@ static bNodeSocketTemplate cmp_node_trackpos_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_trackpos(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
-{
- /* pass */
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeTrackPosData *data = MEM_callocN(sizeof(NodeTrackPosData), "node track position data");
@@ -61,12 +52,8 @@ void register_node_type_cmp_trackpos(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_TRACKPOS, "Track Position", NODE_CLASS_INPUT, NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_trackpos_out);
- node_type_size(&ntype, 120, 80, 300);
node_type_init(&ntype, init);
node_type_storage(&ntype, "NodeTrackPosData", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_trackpos);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c
index a8ef0286f2f..3ed8bdb9995 100644
--- a/source/blender/nodes/composite/nodes/node_composite_transform.c
+++ b/source/blender/nodes/composite/nodes/node_composite_transform.c
@@ -48,99 +48,12 @@ static bNodeSocketTemplate cmp_node_transform_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type)
-{
- CompBuf *stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, TRUE);
- ImBuf *ibuf, *obuf;
- float mat[4][4], lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
- float svec[3] = {scale, scale, scale}, loc[2] = {x, y};
-
- unit_m4(rmat);
- unit_m4(lmat);
- unit_m4(smat);
- unit_m4(cmat);
-
- /* image center as rotation center */
- cmat[3][0] = (float)cbuf->x/2.0f;
- cmat[3][1] = (float)cbuf->y/2.0f;
- invert_m4_m4(icmat, cmat);
-
- size_to_mat4(smat, svec); /* scale matrix */
- add_v2_v2(lmat[3], loc); /* tranlation matrix */
- rotate_m4(rmat, 'Z', angle); /* rotation matrix */
-
- /* compose transformation matrix */
- mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL);
-
- invert_m4(mat);
-
- ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
- obuf = IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0);
-
- if (ibuf && obuf) {
- int i, j;
-
- ibuf->rect_float = cbuf->rect;
- obuf->rect_float = stackbuf->rect;
-
- for (j = 0; j < cbuf->y; j++) {
- for (i = 0; i < cbuf->x; i++) {
- float vec[3] = {i, j, 0};
-
- mul_v3_m4v3(vec, mat, vec);
-
- switch (filter_type) {
- case 0:
- neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
- break;
- case 1:
- bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
- break;
- case 2:
- bicubic_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
- break;
- }
- }
- }
-
- IMB_freeImBuf(ibuf);
- IMB_freeImBuf(obuf);
- }
-
- /* pass on output and free */
- return stackbuf;
-}
-
-static void node_composit_exec_transform(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- if (in[0]->data) {
- CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA);
- CompBuf *stackbuf;
-
- stackbuf = node_composit_transform(cbuf, in[1]->vec[0], in[2]->vec[0], in[3]->vec[0], in[4]->vec[0], node->custom1);
-
- /* pass on output and free */
- out[0]->data = stackbuf;
-
- if (cbuf != in[0]->data)
- free_compbuf(cbuf);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_transform(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_TRANSFORM, "Transform", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_transform_in, cmp_node_transform_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_transform);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_translate.c b/source/blender/nodes/composite/nodes/node_composite_translate.c
index 1c2963a2f08..5d555cdcda9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_translate.c
+++ b/source/blender/nodes/composite/nodes/node_composite_translate.c
@@ -46,33 +46,20 @@ static bNodeSocketTemplate cmp_node_translate_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_translate(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **in, bNodeStack **out)
+static void node_composit_init_translate(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
- if (in[0]->data) {
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= pass_on_compbuf(cbuf);
-
- stackbuf->xof+= (int)floor(in[1]->vec[0]);
- stackbuf->yof+= (int)floor(in[2]->vec[0]);
-
- out[0]->data= stackbuf;
- }
+ NodeTranslateData *data = MEM_callocN(sizeof(NodeTranslateData), "node translate data");
+ node->storage = data;
}
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_translate(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_translate_in, cmp_node_translate_out);
- node_type_size(&ntype, 140, 100, 320);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_translate);
-#endif
+ node_type_init(&ntype, node_composit_init_translate);
+ node_type_storage(&ntype, "NodeTranslateData", node_free_standard_storage, node_copy_standard_storage);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_valToRgb.c b/source/blender/nodes/composite/nodes/node_composite_valToRgb.c
index 5c111998b18..5a23507bcc7 100644
--- a/source/blender/nodes/composite/nodes/node_composite_valToRgb.c
+++ b/source/blender/nodes/composite/nodes/node_composite_valToRgb.c
@@ -44,44 +44,6 @@ static bNodeSocketTemplate cmp_node_valtorgb_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_colorband_composit(bNode *node, float *out, float *in)
-{
- do_colorband(node->storage, in[0], out);
-}
-
-static void node_composit_exec_valtorgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order in: fac */
- /* stack order out: col, alpha */
-
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0)
- return;
-
- if (node->storage) {
- /* input no image? then only color operation */
- if (in[0]->data==NULL) {
- do_colorband(node->storage, in[0]->vec[0], out[0]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
-
- composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_colorband_composit, CB_VAL);
-
- out[0]->data= stackbuf;
-
- if (out[1]->hasoutput)
- out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
-
- }
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
node->storage= add_colorband(1);
@@ -93,12 +55,9 @@ void register_node_type_cmp_valtorgb(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_valtorgb_in, cmp_node_valtorgb_out);
- node_type_size(&ntype, 240, 200, 300);
+ node_type_size(&ntype, 240, 200, 320);
node_type_init(&ntype, node_composit_init_valtorgb);
node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_valtorgb);
-#endif
nodeRegisterType(ttype, &ntype);
}
@@ -115,48 +74,13 @@ static bNodeSocketTemplate cmp_node_rgbtobw_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_rgbtobw(bNode *UNUSED(node), float *out, float *in)
-{
- out[0] = rgb_to_bw(in);
-}
-
-static void node_composit_exec_rgbtobw(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- /* stack order out: bw */
- /* stack order in: col */
-
- if (out[0]->hasoutput==0)
- return;
-
- /* input no image? then only color operation */
- if (in[0]->data==NULL) {
- do_rgbtobw(node, out[0]->vec, in[0]->vec);
- }
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
-
- composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_rgbtobw, CB_RGBA);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_rgbtobw(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, cmp_node_rgbtobw_in, cmp_node_rgbtobw_out);
- node_type_size(&ntype, 80, 40, 120);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_rgbtobw);
-#endif
+ node_type_size_preset(&ntype, NODE_SIZE_SMALL);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_value.c b/source/blender/nodes/composite/nodes/node_composite_value.c
index 2c65fe6be19..306170baf93 100644
--- a/source/blender/nodes/composite/nodes/node_composite_value.c
+++ b/source/blender/nodes/composite/nodes/node_composite_value.c
@@ -49,18 +49,6 @@ static void node_composit_init_value(bNodeTree *UNUSED(ntree), bNode *node, bNod
dval->max = FLT_MAX;
}
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_value(void *UNUSED(data), bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
-{
- bNodeSocket *sock= node->outputs.first;
- float val= ((bNodeSocketValueFloat*)sock->default_value)->value;
-
- out[0]->vec[0] = val;
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_value(bNodeTreeType *ttype)
{
static bNodeType ntype;
@@ -68,10 +56,7 @@ void register_node_type_cmp_value(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_VALUE, "Value", NODE_CLASS_INPUT, NODE_OPTIONS);
node_type_socket_templates(&ntype, NULL, cmp_node_value_out);
node_type_init(&ntype, node_composit_init_value);
- node_type_size(&ntype, 80, 40, 120);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_value);
-#endif
+ node_type_size_preset(&ntype, NODE_SIZE_SMALL);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_vecBlur.c b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c
index 62c2c02836a..35fb4a944db 100644
--- a/source/blender/nodes/composite/nodes/node_composite_vecBlur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c
@@ -45,48 +45,6 @@ static bNodeSocketTemplate cmp_node_vecblur_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_vecblur(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
-{
- NodeBlurData *nbd = node->storage;
- CompBuf *new, *img = in[0]->data, *vecbuf = in[2]->data, *zbuf = in[1]->data;
-
- if (img == NULL || vecbuf == NULL || zbuf == NULL || out[0]->hasoutput == 0)
- return;
- if (vecbuf->x != img->x || vecbuf->y != img->y) {
- printf("ERROR: cannot do different sized vecbuf yet\n");
- return;
- }
- if (vecbuf->type != CB_VEC4) {
- printf("ERROR: input should be vecbuf\n");
- return;
- }
- if (zbuf->type != CB_VAL) {
- printf("ERROR: input should be zbuf\n");
- return;
- }
- if (zbuf->x != img->x || zbuf->y != img->y) {
- printf("ERROR: cannot do different sized zbuf yet\n");
- return;
- }
-
- /* allow the input image to be of another type */
- img = typecheck_compbuf(in[0]->data, CB_RGBA);
-
- new = dupalloc_compbuf(img);
-
- /* call special zbuffer version */
- RE_zbuf_accumulate_vecblur(nbd, img->x, img->y, new->rect, img->rect, vecbuf->rect, zbuf->rect);
-
- out[0]->data = new;
-
- if (img != in[0]->data)
- free_compbuf(img);
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_vecblur(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
NodeBlurData *nbd = MEM_callocN(sizeof(NodeBlurData), "node blur data");
@@ -102,12 +60,8 @@ void register_node_type_cmp_vecblur(bNodeTreeType *ttype)
node_type_base(ttype, &ntype, CMP_NODE_VECBLUR, "Vector Blur", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_vecblur_in, cmp_node_vecblur_out);
- node_type_size(&ntype, 120, 80, 200);
node_type_init(&ntype, node_composit_init_vecblur);
node_type_storage(&ntype, "NodeBlurData", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_vecblur);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c
index 1c27cc21b06..211ebe54eb0 100644
--- a/source/blender/nodes/composite/nodes/node_composite_viewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c
@@ -41,90 +41,6 @@ static bNodeSocketTemplate cmp_node_viewer_in[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
-{
- /* image assigned to output */
- /* stack order input sockets: col, alpha, z */
-
- if (node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */
- RenderData *rd = data;
- Image *ima = (Image *)node->id;
- ImBuf *ibuf;
- CompBuf *cbuf, *tbuf;
- int rectx, recty;
- void *lock;
-
- BKE_image_user_frame_calc(node->storage, rd->cfra, 0);
-
- /* always returns for viewer image, but we check nevertheless */
- ibuf = BKE_image_acquire_ibuf(ima, node->storage, &lock);
- if (ibuf == NULL) {
- printf("node_composit_exec_viewer error\n");
- BKE_image_release_ibuf(ima, ibuf, lock);
- return;
- }
-
- /* free all in ibuf */
- imb_freerectImBuf(ibuf);
- imb_freerectfloatImBuf(ibuf);
- IMB_freezbuffloatImBuf(ibuf);
-
- /* get size */
- tbuf = in[0]->data ? in[0]->data : (in[1]->data ? in[1]->data : in[2]->data);
- if (tbuf == NULL) {
- rectx = 320; recty = 256;
- }
- else {
- rectx = tbuf->x;
- recty = tbuf->y;
- }
-
- /* make ibuf, and connect to ima */
- ibuf->x = rectx;
- ibuf->y = recty;
- imb_addrectfloatImBuf(ibuf);
-
- ima->ok = IMA_OK_LOADED;
-
- /* now we combine the input with ibuf */
- cbuf = alloc_compbuf(rectx, recty, CB_RGBA, 0); /* no alloc*/
- cbuf->rect = ibuf->rect_float;
-
- /* when no alpha, we can simply copy */
- if (in[1]->data == NULL) {
- composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA);
- }
- else
- composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL);
-
- /* zbuf option */
- if (in[2]->data) {
- CompBuf *zbuf = alloc_compbuf(rectx, recty, CB_VAL, 1);
- ibuf->zbuf_float = zbuf->rect;
- ibuf->mall |= IB_zbuffloat;
-
- composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL);
-
- /* free compbuf, but not the rect */
- zbuf->malloc = 0;
- free_compbuf(zbuf);
- }
-
- BKE_image_release_ibuf(ima, ibuf, lock);
-
- generate_preview(data, node, cbuf);
- free_compbuf(cbuf);
-
- }
- else if (in[0]->data) {
- generate_preview(data, node, in[0]->data);
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
{
ImageUser *iuser = MEM_callocN(sizeof(ImageUser), "node image user");
@@ -140,14 +56,10 @@ void register_node_type_cmp_viewer(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, CMP_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW);
+ node_type_base(ttype, &ntype, CMP_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_OPTIONS | NODE_PREVIEW);
node_type_socket_templates(&ntype, cmp_node_viewer_in, NULL);
- node_type_size(&ntype, 80, 60, 200);
node_type_init(&ntype, node_composit_init_viewer);
node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_viewer);
-#endif
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/composite/nodes/node_composite_zcombine.c b/source/blender/nodes/composite/nodes/node_composite_zcombine.c
index 8e639aaa357..ba81174e103 100644
--- a/source/blender/nodes/composite/nodes/node_composite_zcombine.c
+++ b/source/blender/nodes/composite/nodes/node_composite_zcombine.c
@@ -48,193 +48,12 @@ static bNodeSocketTemplate cmp_node_zcombine_out[] = {
{ -1, 0, "" }
};
-#ifdef WITH_COMPOSITOR_LEGACY
-
-static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2)
-{
- float alpha;
- float malpha;
-
- if (*z1 <= *z2) {
- if (node->custom1) {
- // use alpha in combine operation
- alpha= src1[3];
- malpha= 1.0f - alpha;
- out[0] = malpha*src2[0] + alpha*src1[0];
- out[1] = malpha*src2[1] + alpha*src1[1];
- out[2] = malpha*src2[2] + alpha*src1[2];
- out[3] = malpha*src2[3] + alpha*src1[3];
- }
- else {
- // do combination based solely on z value
- copy_v4_v4(out, src1);
- }
- }
- else {
- if (node->custom1) {
- // use alpha in combine operation
- alpha= src2[3];
- malpha= 1.0f - alpha;
- out[0] = malpha*src1[0] + alpha*src2[0];
- out[1] = malpha*src1[1] + alpha*src2[1];
- out[2] = malpha*src1[2] + alpha*src2[2];
- out[3] = malpha*src1[3] + alpha*src2[3];
- }
- else {
- // do combination based solely on z value
- copy_v4_v4(out, src1);
- }
-
- if (node->custom2)
- *z1= *z2;
- }
-}
-
-static void do_zcombine_mask(bNode *node, float *out, float *z1, float *z2)
-{
- if (*z1 > *z2) {
- *out= 1.0f;
- if (node->custom2)
- *z1= *z2;
- }
-}
-
-static void do_zcombine_add(bNode *node, float *out, float *col1, float *col2, float *acol)
-{
- float alpha;
- float malpha;
-
- if (node->custom1) {
- // use alpha in combine operation, antialiased mask in used here just as hint for the z value
- if (*acol>0.0f) {
- alpha= col2[3];
- malpha= 1.0f - alpha;
-
-
- out[0] = malpha*col1[0] + alpha*col2[0];
- out[1] = malpha*col1[1] + alpha*col2[1];
- out[2] = malpha*col1[2] + alpha*col2[2];
- out[3] = malpha*col1[3] + alpha*col2[3];
- }
- else {
- alpha= col1[3];
- malpha= 1.0f - alpha;
-
-
- out[0] = malpha*col2[0] + alpha*col1[0];
- out[1] = malpha*col2[1] + alpha*col1[1];
- out[2] = malpha*col2[2] + alpha*col1[2];
- out[3] = malpha*col2[3] + alpha*col1[3];
- }
- }
- else {
- // do combination based solely on z value but with antialiased mask
- alpha = *acol;
- malpha= 1.0f - alpha;
-
- out[0] = malpha*col1[0] + alpha*col2[0];
- out[1] = malpha*col1[1] + alpha*col2[1];
- out[2] = malpha*col1[2] + alpha*col2[2];
- out[3] = malpha*col1[3] + alpha*col2[3];
- }
-}
-
-static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
-{
- RenderData *rd= data;
- CompBuf *cbuf= in[0]->data;
- CompBuf *zbuf;
-
- /* stack order in: col z col z */
- /* stack order out: col z */
- if (out[0]->hasoutput==0 && out[1]->hasoutput==0)
- return;
-
- /* no input image; do nothing now */
- if (in[0]->data==NULL) {
- return;
- }
-
- if (out[1]->hasoutput) {
- /* copy or make a buffer for for the first z value, here we write result in */
- if (in[1]->data)
- zbuf= dupalloc_compbuf(in[1]->data);
- else {
- float *zval;
- int tot= cbuf->x*cbuf->y;
-
- zbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
- for (zval= zbuf->rect; tot; tot--, zval++)
- *zval= in[1]->vec[0];
- }
- /* lazy coder hack */
- node->custom2= 1;
- out[1]->data= zbuf;
- }
- else {
- node->custom2= 0;
- zbuf= in[1]->data;
- }
-
- if (rd->scemode & R_FULL_SAMPLE) {
- /* make output size of first input image */
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
-
- composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, zbuf, in[1]->vec, in[2]->data, in[2]->vec,
- in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL);
-
- out[0]->data= stackbuf;
- }
- else {
- /* make output size of first input image */
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
- CompBuf *mbuf;
- float *fp;
- int x;
- char *aabuf;
-
-
- /* make a mask based on comparison, optionally write zvalue */
- mbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
- composit2_pixel_processor(node, mbuf, zbuf, in[1]->vec, in[3]->data, in[3]->vec, do_zcombine_mask, CB_VAL, CB_VAL);
-
- /* convert to char */
- aabuf= MEM_mallocN(cbuf->x*cbuf->y, "aa buf");
- fp= mbuf->rect;
- for (x= cbuf->x*cbuf->y-1; x>=0; x--)
- if (fp[x]==0.0f) aabuf[x] = 0;
- else aabuf[x] = 255;
-
- antialias_tagbuf(cbuf->x, cbuf->y, aabuf);
-
- /* convert to float */
- fp= mbuf->rect;
- for (x= cbuf->x*cbuf->y-1; x>=0; x--)
- if (aabuf[x]>1)
- fp[x] = (1.0f/255.0f)*(float)aabuf[x];
-
- composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[2]->data, in[2]->vec, mbuf, NULL,
- do_zcombine_add, CB_RGBA, CB_RGBA, CB_VAL);
- /* free */
- free_compbuf(mbuf);
- MEM_freeN(aabuf);
-
- out[0]->data= stackbuf;
- }
-}
-
-#endif /* WITH_COMPOSITOR_LEGACY */
-
void register_node_type_cmp_zcombine(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_ZCOMBINE, "Z Combine", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_zcombine_in, cmp_node_zcombine_out);
- node_type_size(&ntype, 80, 40, 120);
-#ifdef WITH_COMPOSITOR_LEGACY
- node_type_exec(&ntype, node_composit_exec_zcombine);
-#endif
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 86ef8a14c12..d59061dfc0a 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -197,7 +197,7 @@ void node_group_remove_socket(bNodeTree *ngroup, bNodeSocket *gsock, int in_out)
/* groups display their internal tree name as label */
const char *node_group_label(bNode *node)
{
- return (node->id)? node->id->name+2: IFACE_("Missing Datablock");
+ return (node->id)? node->id->name + 2: IFACE_("Missing Datablock");
}
int node_group_valid(bNodeTree *ntree, bNodeTemplate *ntemp)
@@ -305,7 +305,7 @@ void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *i
{
/* check inputs and outputs, and remove or insert them */
if (node->id==id) {
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup= (bNodeTree *)node->id;
group_verify_socket_list(ntree, node, &node->inputs, SOCK_IN, &ngroup->inputs);
group_verify_socket_list(ntree, node, &node->outputs, SOCK_OUT, &ngroup->outputs);
}
@@ -314,7 +314,7 @@ void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *i
struct bNodeTree *node_group_edit_get(bNode *node)
{
if (node->flag & NODE_GROUP_EDIT)
- return (bNodeTree*)node->id;
+ return (bNodeTree *)node->id;
else
return NULL;
}
@@ -322,7 +322,7 @@ struct bNodeTree *node_group_edit_get(bNode *node)
struct bNodeTree *node_group_edit_set(bNode *node, int edit)
{
if (edit) {
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup= (bNodeTree *)node->id;
if (ngroup) {
if (ngroup->id.lib)
ntreeMakeLocal(ngroup);
@@ -339,7 +339,7 @@ struct bNodeTree *node_group_edit_set(bNode *node, int edit)
void node_group_edit_clear(bNode *node)
{
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup= (bNodeTree *)node->id;
bNode *inode;
node->flag &= ~NODE_GROUP_EDIT;
diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c
index 3cc7ebf9337..7a8b8c940c9 100644
--- a/source/blender/nodes/intern/node_exec.c
+++ b/source/blender/nodes/intern/node_exec.c
@@ -114,13 +114,13 @@ static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeSocket *sock)
if (sock->default_value) {
switch (sock->type) {
case SOCK_FLOAT:
- ns->vec[0] = ((bNodeSocketValueFloat*)sock->default_value)->value;
+ ns->vec[0] = ((bNodeSocketValueFloat *)sock->default_value)->value;
break;
case SOCK_VECTOR:
- copy_v3_v3(ns->vec, ((bNodeSocketValueVector*)sock->default_value)->value);
+ copy_v3_v3(ns->vec, ((bNodeSocketValueVector *)sock->default_value)->value);
break;
case SOCK_RGBA:
- copy_v4_v4(ns->vec, ((bNodeSocketValueRGBA*)sock->default_value)->value);
+ copy_v4_v4(ns->vec, ((bNodeSocketValueRGBA *)sock->default_value)->value);
break;
}
}
@@ -258,7 +258,7 @@ void ntree_exec_end(bNodeTreeExec *exec)
MEM_freeN(exec);
}
-/**** Compositor/Material/Texture trees ****/
+/**** Material/Texture trees ****/
bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
{
@@ -287,33 +287,7 @@ void ntreeReleaseThreadStack(bNodeThreadStack *nts)
nts->used = 0;
}
-void ntreeExecNodes(bNodeTreeExec *exec, void *callerdata, int thread)
-{
- bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
- bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
- bNodeExec *nodeexec;
- bNode *node;
- int n;
-
- /* nodes are presorted, so exec is in order of list */
-
- for (n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
- node = nodeexec->node;
- if (node->need_exec) {
- node_get_stack(node, exec->stack, nsin, nsout);
- /* Handle muted nodes...
- * If the mute func is not set, assume the node should never be muted,
- * and hence execute it!
- */
- if (node->typeinfo->execfunc)
- node->typeinfo->execfunc(callerdata, node, nsin, nsout);
- else if (node->typeinfo->newexecfunc)
- node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout);
- }
- }
-}
-
-void ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
+bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
{
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
@@ -331,10 +305,15 @@ void ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *call
* If the mute func is not set, assume the node should never be muted,
* and hence execute it!
*/
+// if (node->typeinfo->compatibility == NODE_NEW_SHADING)
+// return false;
if (node->typeinfo->execfunc)
node->typeinfo->execfunc(callerdata, node, nsin, nsout);
else if (node->typeinfo->newexecfunc)
node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout);
}
}
+
+ /* signal to that all went OK, for render */
+ return true;
}
diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h
index e985795de71..5febda036e0 100644
--- a/source/blender/nodes/intern/node_exec.h
+++ b/source/blender/nodes/intern/node_exec.h
@@ -77,10 +77,8 @@ void node_get_stack(struct bNode *node, struct bNodeStack *stack, struct bNodeSt
struct bNodeTreeExec *ntree_exec_begin(struct bNodeTree *ntree);
void ntree_exec_end(struct bNodeTreeExec *exec);
-void ntreeExecNodes(struct bNodeTreeExec *exec, void *callerdata, int thread);
-
struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread);
void ntreeReleaseThreadStack(struct bNodeThreadStack *nts);
-void ntreeExecThreadNodes(struct bNodeTreeExec *exec, struct bNodeThreadStack *nts, void *callerdata, int thread);
+bool ntreeExecThreadNodes(struct bNodeTreeExec *exec, struct bNodeThreadStack *nts, void *callerdata, int thread);
#endif
diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h
index 3134baa283c..6b783915816 100644
--- a/source/blender/nodes/intern/node_util.h
+++ b/source/blender/nodes/intern/node_util.h
@@ -65,13 +65,3 @@ const char *node_filter_label(struct bNode *node);
void node_update_internal_links_default(struct bNodeTree *ntree, struct bNode *node);
#endif
-
-// this is needed for inlining behavior
-#if defined _MSC_VER
-# define DO_INLINE __inline
-#elif defined (__sun) || defined (__sun__)
-# define DO_INLINE
-#else
-# define DO_INLINE static inline
-#endif
-
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index b7dc83d7d79..8fde0b9c342 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -248,7 +248,8 @@ void ntreeShaderEndExecTree(bNodeTreeExec *exec, int use_tree_data)
}
}
-void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
+/* only for Blender internal */
+bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
{
ShaderCallData scd;
/**
@@ -258,6 +259,7 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
Material *mat = shi->mat;
bNodeThreadStack *nts = NULL;
bNodeTreeExec *exec = ntree->execdata;
+ int compat;
/* convert caller data to struct */
scd.shi = shi;
@@ -277,13 +279,17 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
}
nts = ntreeGetThreadStack(exec, shi->thread);
- ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
+ compat = ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
ntreeReleaseThreadStack(nts);
// \note: set material back to preserved material
shi->mat = mat;
+
/* better not allow negative for now */
if (shr->combined[0] < 0.0f) shr->combined[0] = 0.0f;
if (shr->combined[1] < 0.0f) shr->combined[1] = 0.0f;
if (shr->combined[2] < 0.0f) shr->combined[2] = 0.0f;
+
+ /* if compat is zero, it has been using non-compatible nodes */
+ return compat;
}
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 6130fe72af3..1123a0dc44a 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -46,7 +46,7 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
if (ns->sockettype==SOCK_FLOAT)
*in= *from;
else
- *in= 0.333333f*(from[0]+from[1]+from[2]);
+ *in= (from[0]+from[1]+from[2]) / 3.0f;
}
else if (type_in==SOCK_VECTOR) {
if (ns->sockettype==SOCK_FLOAT) {
@@ -139,49 +139,49 @@ void nodeShaderSynchronizeID(bNode *node, int copyto)
if (copyto) {
switch (a) {
case MAT_IN_COLOR:
- copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA*)sock->default_value)->value); break;
+ copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
case MAT_IN_SPEC:
- copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break;
+ copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
case MAT_IN_REFL:
- ma->ref= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->ref= ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_MIR:
- copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break;
+ copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
case MAT_IN_AMB:
- ma->amb= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->amb = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_EMIT:
- ma->emit= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->emit = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_SPECTRA:
- ma->spectra= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->spectra = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_RAY_MIRROR:
- ma->ray_mirror= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->ray_mirror = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_ALPHA:
- ma->alpha= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->alpha = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_TRANSLUCENCY:
- ma->translucency= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->translucency = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
}
}
else {
switch (a) {
case MAT_IN_COLOR:
- copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->r); break;
+ copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->r); break;
case MAT_IN_SPEC:
- copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->specr); break;
+ copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->specr); break;
case MAT_IN_REFL:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->ref; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value= ma->ref; break;
case MAT_IN_MIR:
- copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->mirr); break;
+ copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->mirr); break;
case MAT_IN_AMB:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->amb; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->amb; break;
case MAT_IN_EMIT:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->emit; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->emit; break;
case MAT_IN_SPECTRA:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->spectra; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->spectra; break;
case MAT_IN_RAY_MIRROR:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->ray_mirror; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->ray_mirror; break;
case MAT_IN_ALPHA:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->alpha; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->alpha; break;
case MAT_IN_TRANSLUCENCY:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->translucency; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->translucency; break;
}
}
}
@@ -221,6 +221,7 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs)
{
+ copy_v4_v4(ns->vec, gs->vec);
ns->data= gs->link;
ns->sockettype= gs->sockettype;
}
@@ -259,7 +260,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
break;
if (node)
- ntree= (bNodeTree*)node->id;
+ ntree = (bNodeTree *)node->id;
for (node= ntree->nodes.first; node; node= node->next)
if (node->flag & NODE_ACTIVE_TEXTURE)
@@ -276,7 +277,7 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs)
bNodeStack *stack;
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
- GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
+ GPUNodeStack gpuin[MAX_SOCKET + 1], gpuout[MAX_SOCKET + 1];
int do_it;
stack= exec->stack;
@@ -320,7 +321,7 @@ void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in
float domax= (texmap->flag & TEXMAP_CLIP_MAX) != 0;
if (domin || domax || !(texmap->flag & TEXMAP_UNIT_MATRIX)) {
- GPUNodeLink *tmat = GPU_uniform((float*)texmap->mat);
+ GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat);
GPUNodeLink *tmin = GPU_uniform(texmap->min);
GPUNodeLink *tmax = GPU_uniform(texmap->max);
GPUNodeLink *tdomin = GPU_uniform(&domin);
diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h
index e4dc74e8d40..9c911501435 100644
--- a/source/blender/nodes/shader/node_shader_util.h
+++ b/source/blender/nodes/shader/node_shader_util.h
@@ -49,6 +49,12 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_rand.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
#include "BKE_blender.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
@@ -63,12 +69,6 @@
#include "NOD_shader.h"
#include "node_util.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_rand.h"
-#include "BLI_threads.h"
-#include "BLI_utildefines.h"
-
#include "BLF_translation.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/nodes/shader/nodes/node_shader_brightness.c b/source/blender/nodes/shader/nodes/node_shader_brightness.c
index 9c23a29cae9..fa77fce4c88 100644
--- a/source/blender/nodes/shader/nodes/node_shader_brightness.c
+++ b/source/blender/nodes/shader/nodes/node_shader_brightness.c
@@ -43,6 +43,11 @@ static bNodeSocketTemplate sh_node_brightcontrast_out[] = {
{ -1, 0, "" }
};
+static int gpu_shader_brightcontrast(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, "brightness_contrast", in, out);
+}
+
void register_node_type_sh_brightcontrast(bNodeTreeType *ttype)
{
static bNodeType ntype;
@@ -54,7 +59,7 @@ void register_node_type_sh_brightcontrast(bNodeTreeType *ttype)
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL);
- node_type_gpu(&ntype, NULL);
+ node_type_gpu(&ntype, gpu_shader_brightcontrast);
nodeRegisterType(ttype, &ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
index 688d77d8350..9c784709de3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ b/source/blender/nodes/shader/nodes/node_shader_common.c
@@ -33,6 +33,8 @@
#include "DNA_node_types.h"
+#include "BLI_utildefines.h"
+
#include "BKE_node.h"
#include "node_shader_util.h"
@@ -70,7 +72,7 @@ static void move_stack(bNodeStack *to, bNodeStack *from)
static void *group_initexec(bNode *node)
{
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup = (bNodeTree *)node->id;
bNodeTreeExec *exec;
if (!ngroup)
@@ -84,7 +86,7 @@ static void *group_initexec(bNode *node)
static void group_freeexec(bNode *UNUSED(node), void *nodedata)
{
- bNodeTreeExec*gexec= (bNodeTreeExec*)nodedata;
+ bNodeTreeExec*gexec = (bNodeTreeExec *)nodedata;
ntreeShaderEndExecTree(gexec, 0);
}
@@ -121,7 +123,7 @@ static void group_move_outputs(bNode *node, bNodeStack **out, bNodeStack *gstack
static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
+ bNodeTreeExec *exec = (bNodeTreeExec *)nodedata;
bNodeThreadStack *nts;
if (!exec)
@@ -177,7 +179,7 @@ static void group_gpu_move_outputs(bNode *node, GPUNodeStack *out, bNodeStack *g
static int gpu_group_execute(GPUMaterial *mat, bNode *node, void *nodedata, GPUNodeStack *in, GPUNodeStack *out)
{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
+ bNodeTreeExec *exec = (bNodeTreeExec *)nodedata;
group_gpu_copy_inputs(node, in, exec->stack);
ntreeExecGPUNodes(exec, mat, (node->flag & NODE_GROUP_EDIT));
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 9fa654c9740..216e10a7e9a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -74,7 +74,7 @@ void register_node_type_sh_curve_vec(bNodeTreeType *ttype)
static bNodeType ntype;
node_type_base(ttype, &ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
- node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out);
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_shader_init_curve_vec);
@@ -132,7 +132,7 @@ void register_node_type_sh_curve_rgb(bNodeTreeType *ttype)
static bNodeType ntype;
node_type_base(ttype, &ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
- node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out);
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_shader_init_curve_rgb);
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.c b/source/blender/nodes/shader/nodes/node_shader_gamma.c
index c49554c44be..365bac77004 100644
--- a/source/blender/nodes/shader/nodes/node_shader_gamma.c
+++ b/source/blender/nodes/shader/nodes/node_shader_gamma.c
@@ -29,7 +29,7 @@
#include "node_shader_util.h"
/* **************** Gamma Tools ******************** */
-
+
static bNodeSocketTemplate sh_node_gamma_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 1.0f, 1.0f, 1.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Gamma"), 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f, PROP_UNSIGNED},
diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.c b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
new file mode 100644
index 00000000000..5cd4c8bd1d3
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
@@ -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) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+static bNodeSocketTemplate outputs[] = {
+ { SOCK_FLOAT, 0, N_("Is Strand"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Intercept"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Thickness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, N_("Tangent Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+/* node type definition */
+void register_node_type_sh_hair_info(bNodeTreeType *ttype)
+{
+ static bNodeType ntype;
+
+ node_type_base(ttype, &ntype, SH_NODE_HAIR_INFO, "Hair Info", NODE_CLASS_INPUT, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, NULL, outputs);
+ node_type_size(&ntype, 150, 60, 200);
+ node_type_init(&ntype, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
+ node_type_exec(&ntype, NULL);
+ node_type_gpu(&ntype, NULL);
+
+ nodeRegisterType(ttype, &ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index cedd3a4910c..396c1ac60bf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -77,7 +77,7 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, G
TexMapping *texmap= node->storage;
float domin= (texmap->flag & TEXMAP_CLIP_MIN) != 0;
float domax= (texmap->flag & TEXMAP_CLIP_MAX) != 0;
- GPUNodeLink *tmat = GPU_uniform((float*)texmap->mat);
+ GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat);
GPUNodeLink *tmin = GPU_uniform(texmap->min);
GPUNodeLink *tmax = GPU_uniform(texmap->max);
GPUNodeLink *tdomin = GPU_uniform(&domin);
diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c
index 2902bf143c8..a36f35c646d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_material.c
+++ b/source/blender/nodes/shader/nodes/node_shader_material.c
@@ -145,7 +145,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
/* make alpha output give results even if transparency is only enabled on
* the material linked in this not and not on the parent material */
mode = shi->mode;
- if(shi->mat->mode & MA_TRANSP)
+ if (shi->mat->mode & MA_TRANSP)
shi->mode |= MA_TRANSP;
shi->nodes= 1; /* temp hack to prevent trashadow recursion */
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
index b77c7d07407..ec238b62408 100644
--- a/source/blender/nodes/shader/nodes/node_shader_texture.c
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -72,7 +72,7 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b
if (in[0]->datatype==NS_OSA_VECTORS) {
float *fp= in[0]->data;
- retval= multitex_nodes((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres, thread, which_output, NULL, NULL);
+ retval = multitex_nodes((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
}
else if (in[0]->datatype==NS_OSA_VALUES) {
float *fp= in[0]->data;
@@ -80,14 +80,14 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b
dxt[0] = fp[0]; dxt[1] = dxt[2] = 0.0f;
dyt[0] = fp[1]; dyt[1] = dyt[2] = 0.0f;
- retval= multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL);
+ retval = multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
}
else
- retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL);
+ retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
}
else {
copy_v3_v3(vec, shi->lo);
- retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL);
+ retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
}
/* stupid exception */
diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h
index 16dbc2f7bfb..3b2a7e14f69 100644
--- a/source/blender/nodes/texture/node_texture_util.h
+++ b/source/blender/nodes/texture/node_texture_util.h
@@ -48,6 +48,12 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_rand.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
#include "BKE_blender.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
@@ -56,19 +62,12 @@
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_texture.h"
-
#include "BKE_library.h"
#include "node_util.h"
#include "NOD_texture.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_rand.h"
-#include "BLI_threads.h"
-#include "BLI_utildefines.h"
-
#include "BLF_translation.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c
index 41bfd0ae00a..aa427ff3587 100644
--- a/source/blender/nodes/texture/nodes/node_texture_common.c
+++ b/source/blender/nodes/texture/nodes/node_texture_common.c
@@ -33,6 +33,8 @@
#include "DNA_node_types.h"
+#include "BLI_utildefines.h"
+
#include "BKE_node.h"
#include "node_texture_util.h"
diff --git a/source/blender/nodes/texture/nodes/node_texture_compose.c b/source/blender/nodes/texture/nodes/node_texture_compose.c
index 25da4f19e52..43a8ba1babf 100644
--- a/source/blender/nodes/texture/nodes/node_texture_compose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_compose.c
@@ -61,7 +61,7 @@ void register_node_type_tex_compose(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, TEX_NODE_COMPOSE, "Compose RGBA", NODE_CLASS_OP_COLOR, 0);
+ node_type_base(ttype, &ntype, TEX_NODE_COMPOSE, "Combine RGBA", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size(&ntype, 100, 60, 150);
node_type_exec(&ntype, exec);
diff --git a/source/blender/nodes/texture/nodes/node_texture_decompose.c b/source/blender/nodes/texture/nodes/node_texture_decompose.c
index a2875c31d9e..0866428ca6c 100644
--- a/source/blender/nodes/texture/nodes/node_texture_decompose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_decompose.c
@@ -82,7 +82,7 @@ void register_node_type_tex_decompose(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, TEX_NODE_DECOMPOSE, "Decompose RGBA", NODE_CLASS_OP_COLOR, 0);
+ node_type_base(ttype, &ntype, TEX_NODE_DECOMPOSE, "Separate RGBA", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size(&ntype, 100, 60, 150);
node_type_exec(&ntype, exec);
diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c
index 8876d98b9b2..de2dac22d81 100644
--- a/source/blender/nodes/texture/nodes/node_texture_proc.c
+++ b/source/blender/nodes/texture/nodes/node_texture_proc.c
@@ -69,7 +69,7 @@ static void do_proc(float *result, TexParams *p, const float col1[4], const floa
texres.nor = NULL;
textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
- &texres, thread, 0, p->shi, p->mtex);
+ &texres, thread, 0, p->shi, p->mtex, NULL);
if (is_normal)
return;
diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c
index cc7367a7632..f839f485976 100644
--- a/source/blender/nodes/texture/nodes/node_texture_texture.c
+++ b/source/blender/nodes/texture/nodes/node_texture_texture.c
@@ -78,7 +78,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
texres.nor = nor;
textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex,
- &texres, thread, 0, p->shi, p->mtex);
+ &texres, thread, 0, p->shi, p->mtex, NULL);
if (textype & TEX_RGB) {
copy_v4_v4(out, &texres.tr);
diff --git a/source/blender/opencl/SConscript b/source/blender/opencl/SConscript
deleted file mode 100644
index e91a99d5075..00000000000
--- a/source/blender/opencl/SConscript
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/python
-Import ('env')
-
-sources = env.Glob('intern/*.c')
-
-incs = '.'
-
-env.BlenderLib ( 'bf_opencl', sources, Split(incs), libtype=['core','player'], priority = [192,192] )
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 9bd45d2b759..0f5be095e0f 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -66,7 +66,7 @@ void BPY_python_end(void);
/* 2.5 UI Scripts */
int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports);
-int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump);
+int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump);
void BPY_text_free_code(struct Text *text);
void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
void BPY_modules_load_user(struct bContext *C);
@@ -87,6 +87,11 @@ void BPY_context_update(struct bContext *C);
void BPY_id_release(struct ID *id);
+/* I18n for addons */
+#ifdef WITH_INTERNATIONAL
+const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *msgid);
+#endif
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index 012bc279cfb..c28987eb156 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
# TODO, split into 3 files.
@@ -46,16 +71,103 @@ if env['WITH_BF_PYTHON_SAFETY']:
if env['BF_BUILDINFO']:
defs.append('BUILD_DATE')
-if env['WITH_BF_INTERNATIONAL']:
- defs.append('WITH_INTERNATIONAL')
-if env['WITH_BF_CYCLES']:
- defs.append('WITH_CYCLES')
+# Audaspace is always on currently
+
+if env['WITH_BF_BULLET']:
+ defs.append('WITH_BULLET')
+
+# AVI is always on currently
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
incs += ' ' + env['BF_FFMPEG_INC']
-
+
+if env['WITH_BF_QUICKTIME']:
+ defs.append('WITH_QUICKTIME')
+
+if env['WITH_BF_SNDFILE']:
+ defs.append('WITH_SNDFILE')
+
+if env['WITH_BF_COMPOSITOR']:
+ defs.append('WITH_COMPOSITOR')
+
+if env['WITH_BF_CYCLES']:
+ defs.append('WITH_CYCLES')
+
+if env['WITH_BF_CYCLES_OSL']:
+ defs.append('WITH_CYCLES_OSL')
+
+if env['WITH_BF_GAMEENGINE']:
+ defs.append('WITH_GAMEENGINE')
+
+if env['WITH_BF_CINEON']:
+ defs.append('WITH_CINEON')
+
+if env['WITH_BF_DDS']:
+ defs.append('WITH_DDS')
+
+if env['WITH_BF_FRAMESERVER']:
+ defs.append('WITH_FRAMESERVER')
+
+if env['WITH_BF_HDR']:
+ defs.append('WITH_HDR')
+
+if env['WITH_BF_OPENEXR']:
+ defs.append('WITH_OPENEXR')
+
+if env['WITH_BF_OPENJPEG']:
+ defs.append('WITH_OPENJPEG')
+
+if env['WITH_BF_REDCODE']:
+ defs.append('WITH_REDCODE')
+
+if env['WITH_BF_TIFF']:
+ defs.append('WITH_TIFF')
+
+# NDof is always on currently
+
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
+if env['WITH_BF_OPENAL']:
+ defs.append('WITH_OPENAL')
+
+if env['WITH_BF_SDL']:
+ defs.append('WITH_SDL')
+
+if env['WITH_BF_JACK']:
+ defs.append('WITH_JACK')
+
+if env['WITH_BF_LIBMV']:
+ defs.append('WITH_LIBMV')
+
+if env['WITH_BF_BOOLEAN']:
+ defs.append('WITH_MOD_BOOLEAN')
+
+if env['WITH_BF_FLUID']:
+ defs.append('WITH_MOD_FLUID')
+
+if env['WITH_BF_OCEANSIM']:
+ defs.append('WITH_OCEANSIM')
+
+if env['WITH_BF_REMESH']:
+ defs.append('WITH_MOD_REMESH')
+
+if env['WITH_BF_SMOKE']:
+ defs.append('WITH_SMOKE')
+
+if env['WITH_BF_COLLADA']:
+ defs.append('WITH_COLLADA')
+
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OCIO')
+
+if env['WITH_BF_PLAYER']:
+ defs.append('WITH_PLAYER')
+
+
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c
index 18f5d895132..47e6baf8e93 100644
--- a/source/blender/python/bmesh/bmesh_py_api.c
+++ b/source/blender/python/bmesh/bmesh_py_api.c
@@ -98,7 +98,7 @@ static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value)
}
PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
-".. method:: update_edit_mesh(mesh, tessface=True)\n"
+".. method:: update_edit_mesh(mesh, tessface=True, destructive=True)\n"
"\n"
" Update the mesh after changes to the BMesh in editmode, \n"
" optionally recalculating n-gon tessellation.\n"
@@ -107,14 +107,20 @@ PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
" :type mesh: :class:`bpy.types.Mesh`\n"
" :arg tessface: Option to recalculate n-gon tessellation.\n"
" :type tessface: boolean\n"
+" :arg destructive: Use when grometry has been added or removed.\n"
+" :type destructive: boolean\n"
);
-static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args)
+static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
+ static const char *kwlist[] = {"mesh", "tessface", "destructive", NULL};
PyObject *py_me;
Mesh *me;
- int do_tessface = TRUE;
+ int do_tessface = true;
+ int is_destructive = true;
- if (!PyArg_ParseTuple(args, "O|i:update_edit_mesh", &py_me, &do_tessface)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O|ii:update_edit_mesh", (char **)kwlist,
+ &py_me, &do_tessface, &is_destructive))
+ {
return NULL;
}
@@ -131,13 +137,8 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args)
}
{
- /* XXX, not great - infact this function could just not use the context at all
- * postpone that change until after release: BMESH_TODO - campbell */
- extern struct bContext *BPy_GetContext(void);
- extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, const short do_tessface);
-
- struct bContext *C = BPy_GetContext();
- EDBM_update_generic(C, me->edit_btmesh, do_tessface);
+ extern void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_destructive);
+ EDBM_update_generic(me->edit_btmesh, do_tessface, is_destructive);
}
Py_RETURN_NONE;
@@ -146,7 +147,7 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args)
static struct PyMethodDef BPy_BM_methods[] = {
{"new", (PyCFunction)bpy_bm_new, METH_NOARGS, bpy_bm_new_doc},
{"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc},
- {"update_edit_mesh", (PyCFunction)bpy_bm_update_edit_mesh, METH_VARARGS, bpy_bm_update_edit_mesh_doc},
+ {"update_edit_mesh", (PyCFunction)bpy_bm_update_edit_mesh, METH_VARARGS | METH_KEYWORDS, bpy_bm_update_edit_mesh_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index ded35363287..fad3e4a35cd 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -48,11 +48,13 @@
static int bpy_bm_op_as_py_error(BMesh *bm)
{
if (BMO_error_occurred(bm)) {
+ /* note: we could have multiple errors */
const char *errmsg;
if (BMO_error_get(bm, &errmsg, NULL)) {
PyErr_Format(PyExc_RuntimeError,
"bmesh operator: %.200s",
errmsg);
+ BMO_error_clear(bm);
return -1;
}
}
@@ -214,7 +216,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec
return -1;
}
else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) ||
- (ELEM(size, 3, 4) == FALSE))
+ (ELEM(size, 3, 4) == false))
{
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix",
@@ -319,7 +321,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec
elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX,
&elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP),
- TRUE, TRUE, slot_name);
+ true, true, slot_name);
/* error is set above */
if (elem_array == NULL) {
@@ -523,7 +525,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec
*
* \note Don't throw any exceptions and should always return a valid (PyObject *).
*/
-static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
+static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
{
PyObject *item = NULL;
@@ -692,6 +694,9 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
{
BPY_BM_CHECK_OBJ(py_bm);
bm = py_bm->bm;
+
+ /* could complain about entering with exceptions... */
+ BMO_error_clear(bm);
}
else {
PyErr_SetString(PyExc_TypeError,
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 5db9962e690..b96c522d407 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -50,6 +50,8 @@
#include "bmesh_py_types_customdata.h"
#include "bmesh_py_types_meshdata.h"
+static void bm_dealloc_editmode_warn(BPy_BMesh *self);
+
/* Common Flags
* ************ */
@@ -120,11 +122,11 @@ static int bpy_bm_elem_hflag_set(BPy_BMElem *self, PyObject *value, void *flag)
param = PyLong_AsLong(value);
- if (param == TRUE) {
+ if (param == true) {
BM_elem_flag_enable(self->ele, hflag);
return 0;
}
- else if (param == FALSE) {
+ else if (param == false) {
BM_elem_flag_disable(self->ele, hflag);
return 0;
}
@@ -412,6 +414,14 @@ static PyObject *bpy_bmedge_is_manifold_get(BPy_BMEdge *self)
return PyBool_FromLong(BM_edge_is_manifold(self->e));
}
+PyDoc_STRVAR(bpy_bmedge_is_contiguous_doc,
+"True when this edge is manifold, between two faces with the same winding (read-only).\n\n:type: boolean"
+);
+static PyObject *bpy_bmedge_is_contiguous_get(BPy_BMEdge *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+ return PyBool_FromLong(BM_edge_is_contiguous(self->e));
+}
PyDoc_STRVAR(bpy_bmedge_is_wire_doc,
"True when this edge is not connected to any faces (read-only).\n\n:type: boolean"
@@ -559,6 +569,15 @@ static PyObject *bpy_bmloop_link_loop_radial_prev_get(BPy_BMLoop *self)
return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev);
}
+PyDoc_STRVAR(bpy_bm_is_convex_doc,
+"True when this loop is at the convex corner of a face, depends on a valid face normal (read-only).\n\n:type: :class:`BMLoop`"
+);
+static PyObject *bpy_bm_is_convex_get(BPy_BMLoop *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+ return PyBool_FromLong(BM_loop_is_convex(self->l));
+}
+
/* ElemSeq
* ^^^^^^^ */
@@ -669,10 +688,11 @@ static PyGetSetDef bpy_bmedge_getseters[] = {
{(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_link_loops_doc, (void *)BM_LOOPS_OF_EDGE},
/* readonly checks */
- {(char *)"is_manifold", (getter)bpy_bmedge_is_manifold_get, (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL},
- {(char *)"is_wire", (getter)bpy_bmedge_is_wire_get, (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL},
+ {(char *)"is_manifold", (getter)bpy_bmedge_is_manifold_get, (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL},
+ {(char *)"is_contiguous", (getter)bpy_bmedge_is_contiguous_get, (setter)NULL, (char *)bpy_bmedge_is_contiguous_doc, NULL},
+ {(char *)"is_wire", (getter)bpy_bmedge_is_wire_get, (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL},
{(char *)"is_boundary", (getter)bpy_bmedge_is_boundary_get, (setter)NULL, (char *)bpy_bmedge_is_boundary_doc, NULL},
- {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
+ {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -721,7 +741,8 @@ static PyGetSetDef bpy_bmloop_getseters[] = {
{(char *)"link_loop_radial_prev", (getter)bpy_bmloop_link_loop_radial_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_prev_doc, NULL},
/* readonly checks */
- {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
+ {(char *)"is_convex", (getter)bpy_bm_is_convex_get, (setter)NULL, (char *)bpy_bm_is_convex_doc, NULL},
+ {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -813,6 +834,8 @@ static PyObject *bpy_bmesh_free(BPy_BMesh *self)
if (self->bm) {
BMesh *bm = self->bm;
+ bm_dealloc_editmode_warn(self);
+
if ((self->flag & BPY_BMFLAG_IS_WRAPPED) == 0) {
BM_mesh_free(bm);
}
@@ -854,7 +877,7 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
bm = self->bm;
- BM_mesh_bm_to_me(bm, me, FALSE);
+ BM_mesh_bm_to_me(bm, me, false);
/* we could have the user do this but if they forget blender can easy crash
* since the references arrays for the objects derived meshes are now invalid */
@@ -884,9 +907,9 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
Object *ob;
struct Scene *scene;
BMesh *bm;
- int use_deform = TRUE;
- int use_render = FALSE;
- int use_cage = FALSE;
+ int use_deform = true;
+ int use_render = false;
+ int use_cage = false;
DerivedMesh *dm;
const int mask = CD_MASK_BMESH;
@@ -984,7 +1007,7 @@ static PyObject *bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject *
BMesh *bm;
PyObject *py_mesh;
Mesh *me;
- int use_shape_key = FALSE;
+ int use_shape_key = false;
int shape_key_index = 0;
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|ii:from_mesh", (char **)kwlist,
@@ -1032,7 +1055,7 @@ static PyObject *bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value)
BPY_BM_CHECK_OBJ(self);
param = PyLong_AsLong(value);
- if (param != FALSE && param != TRUE) {
+ if (param != false && param != true) {
PyErr_SetString(PyExc_TypeError,
"expected a boolean type 0/1");
return NULL;
@@ -1056,7 +1079,7 @@ PyDoc_STRVAR(bpy_bmesh_normal_update_doc,
static PyObject *bpy_bmesh_normal_update(BPy_BMesh *self, PyObject *args)
{
- int skip_hidden = FALSE;
+ int skip_hidden = false;
BPY_BM_CHECK_OBJ(self);
@@ -1163,7 +1186,7 @@ static PyObject *bpy_bm_elem_select_set(BPy_BMElem *self, PyObject *value)
BPY_BM_CHECK_OBJ(self);
param = PyLong_AsLong(value);
- if (param != FALSE && param != TRUE) {
+ if (param != false && param != true) {
PyErr_SetString(PyExc_TypeError,
"expected a boolean type 0/1");
return NULL;
@@ -1191,7 +1214,7 @@ static PyObject *bpy_bm_elem_hide_set(BPy_BMElem *self, PyObject *value)
BPY_BM_CHECK_OBJ(self);
param = PyLong_AsLong(value);
- if (param != FALSE && param != TRUE) {
+ if (param != false && param != true) {
PyErr_SetString(PyExc_TypeError,
"expected a boolean type 0/1");
return NULL;
@@ -1258,7 +1281,7 @@ static PyObject *bpy_bmvert_copy_from_vert_interp(BPy_BMVert *self, PyObject *ar
vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2,
&vert_seq_len, BM_VERT,
- TRUE, TRUE, "BMVert.copy_from_vert_interp(...)");
+ true, true, "BMVert.copy_from_vert_interp(...)");
if (vert_array == NULL) {
return NULL;
@@ -1508,8 +1531,8 @@ static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw)
static const char *kwlist[] = {"verts", "edges", NULL};
BMesh *bm = self->bm;
- int do_verts = TRUE;
- int do_edges = TRUE;
+ int do_verts = true;
+ int do_edges = true;
BMFace *f_cpy;
BPY_BM_CHECK_OBJ(self);
@@ -1616,6 +1639,21 @@ static PyObject *bpy_bmface_normal_update(BPy_BMFace *self)
}
+PyDoc_STRVAR(bpy_bmface_normal_flip_doc,
+".. method:: normal_flip()\n"
+"\n"
+" Reverses winding of a face, which flips its normal.\n"
+);
+static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+
+ BM_face_normal_flip(self->bm, self->f);
+
+ Py_RETURN_NONE;
+}
+
+
/* Loop
* ---- */
@@ -1634,8 +1672,8 @@ PyDoc_STRVAR(bpy_bmloop_copy_from_face_interp_doc,
static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *args)
{
BPy_BMFace *py_face = NULL;
- int do_vertex = TRUE;
- int do_multires = TRUE;
+ int do_vertex = true;
+ int do_multires = true;
BPY_BM_CHECK_OBJ(self);
@@ -1803,7 +1841,7 @@ static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args)
vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2,
&vert_seq_len, BM_VERT,
- TRUE, TRUE, "edges.new(...)");
+ true, true, "edges.new(...)");
if (vert_array == NULL) {
return NULL;
@@ -1881,7 +1919,7 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args)
vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 3, PY_SSIZE_T_MAX,
&vert_seq_len, BM_VERT,
- TRUE, TRUE, "faces.new(...)");
+ true, true, "faces.new(...)");
if (vert_array == NULL) {
return NULL;
@@ -2034,7 +2072,7 @@ static PyObject *bpy_bmedgeseq_get__method(BPy_BMElemSeq *self, PyObject *args)
vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2,
&vert_seq_len, BM_VERT,
- TRUE, TRUE, "edges.get(...)");
+ true, true, "edges.get(...)");
if (vert_array == NULL) {
return NULL;
@@ -2086,7 +2124,7 @@ static PyObject *bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args)
vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 1, PY_SSIZE_T_MAX,
&vert_seq_len, BM_VERT,
- TRUE, TRUE, "faces.get(...)");
+ true, true, "faces.get(...)");
if (vert_array == NULL) {
return NULL;
@@ -2213,7 +2251,7 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec
{
static const char *kwlist[] = {"key", "reverse", NULL};
PyObject *keyfunc = NULL; /* optional */
- int reverse = FALSE; /* optional */
+ int do_reverse = false; /* optional */
const char htype = bm_iter_itype_htype_map[self->itype];
int n_elem;
@@ -2238,7 +2276,7 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec
if (!PyArg_ParseTupleAndKeywords(args, kw,
"|Oi:BMElemSeq.sort",
(char **)kwlist,
- &keyfunc, &reverse))
+ &keyfunc, &do_reverse))
{
return NULL;
}
@@ -2308,7 +2346,7 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec
range_vn_i(elem_idx, n_elem, 0);
/* Sort the index array according to the order of the 'keys' array */
- if (reverse)
+ if (do_reverse)
elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_descending;
else
elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_ascending;
@@ -2424,6 +2462,7 @@ static struct PyMethodDef bpy_bmface_methods[] = {
{"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc},
{"normal_update", (PyCFunction)bpy_bmface_normal_update, METH_NOARGS, bpy_bmface_normal_update_doc},
+ {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc},
{NULL, NULL, 0, NULL}
};
@@ -2585,7 +2624,7 @@ static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t s
{
BMIter iter;
int count = 0;
- int ok;
+ bool ok;
PyObject *list;
PyObject *item;
@@ -2597,14 +2636,14 @@ static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t s
ok = BM_iter_init(&iter, self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL);
- BLI_assert(ok == TRUE);
+ BLI_assert(ok == true);
- if (UNLIKELY(ok == FALSE)) {
+ if (UNLIKELY(ok == false)) {
return list;
}
/* first loop up-until the start */
- for (ok = TRUE; ok; ok = (BM_iter_step(&iter) != NULL)) {
+ for (ok = true; ok; ok = (BM_iter_step(&iter) != NULL)) {
if (count == start) {
break;
}
@@ -2778,6 +2817,8 @@ static void bpy_bmesh_dealloc(BPy_BMesh *self)
/* have have been freed by bmesh */
if (bm) {
+ bm_dealloc_editmode_warn(self);
+
BM_data_layer_free(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
BM_data_layer_free(bm, &bm->edata, CD_BM_ELEM_PYPTR);
BM_data_layer_free(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
@@ -3403,7 +3444,7 @@ int bpy_bm_generic_valid_check(BPy_BMGeneric *self)
* function where the actual error will be caused by
* the previous action. */
#if 0
- if (BM_mesh_validate(self->bm) == FALSE) {
+ if (BM_mesh_validate(self->bm) == false) {
PyErr_Format(PyExc_ReferenceError,
"BMesh used by %.200s has become invalid",
Py_TYPE(self)->tp_name);
@@ -3448,7 +3489,7 @@ void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
*/
void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
const char htype,
- const char do_unique_check, const char do_bm_check,
+ const bool do_unique_check, const bool do_bm_check,
const char *error_prefix)
{
BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
@@ -3515,17 +3556,17 @@ void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_
if (do_unique_check) {
/* check for double verts! */
- int ok = TRUE;
+ bool ok = true;
for (i = 0; i < seq_len; i++) {
- if (UNLIKELY(BM_elem_flag_test(alloc[i], BM_ELEM_INTERNAL_TAG) == FALSE)) {
- ok = FALSE;
+ if (UNLIKELY(BM_elem_flag_test(alloc[i], BM_ELEM_INTERNAL_TAG) == false)) {
+ ok = false;
}
/* ensure we don't leave this enabled */
BM_elem_flag_disable(alloc[i], BM_ELEM_INTERNAL_TAG);
}
- if (ok == FALSE) {
+ if (ok == false) {
PyErr_Format(PyExc_ValueError,
"%s: found the same %.200s used multiple times",
error_prefix, BPy_BMElem_StringFromHType(htype));
@@ -3588,3 +3629,51 @@ char *BPy_BMElem_StringFromHType(const char htype)
static char ret[32];
return BPy_BMElem_StringFromHType_ex(htype, ret);
}
+
+
+/* -------------------------------------------------------------------- */
+/* keep at bottom */
+/* BAD INCLUDES */
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_tessmesh.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "MEM_guardedalloc.h"
+
+/* there are cases where this warning isnt needed, otherwise it could be made into an error */
+static void bm_dealloc_warn(const char *mesh_name)
+{
+ PySys_WriteStdout("Modified BMesh '%.200s' from a wrapped editmesh is freed without a call "
+ "to bmesh.update_edit_mesh(mesh, destructive=True), this is will likely cause a crash\n",
+ mesh_name);
+}
+
+/* this function is called on free, it should stay quite fast */
+static void bm_dealloc_editmode_warn(BPy_BMesh *self)
+{
+ if (self->flag & BPY_BMFLAG_IS_WRAPPED) {
+ /* likely editmesh */
+ BMesh *bm = self->bm;
+ Scene *scene;
+ for (scene = G.main->scene.first; scene; scene = scene->id.next) {
+ Base *base = scene->basact;
+ if (base && base->object->type == OB_MESH) {
+ Mesh *me = base->object->data;
+ BMEditMesh *em = me->edit_btmesh;
+ if (em && em->bm == bm) {
+ /* not foolproof, scripter may have added/removed verts */
+ if (((em->vert_index && (MEM_allocN_len(em->vert_index) / sizeof(*em->vert_index)) != bm->totvert)) ||
+ ((em->edge_index && (MEM_allocN_len(em->edge_index) / sizeof(*em->edge_index)) != bm->totedge)) ||
+ ((em->face_index && (MEM_allocN_len(em->face_index) / sizeof(*em->face_index)) != bm->totface)))
+ {
+ bm_dealloc_warn(me->id.name + 2);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h
index d15918a3c11..8e6d04ec9ba 100644
--- a/source/blender/python/bmesh/bmesh_py_types.h
+++ b/source/blender/python/bmesh/bmesh_py_types.h
@@ -160,7 +160,7 @@ PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele); /* just checks ty
void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
const char htype,
- const char do_unique_check, const char do_bm_check,
+ const bool do_unique_check, const bool do_bm_check,
const char *error_prefix);
PyObject *BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t elem_len);
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index fd31f3c40cc..4a8f8d49f35 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -981,7 +981,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
case CD_PROP_STR:
{
MStringProperty *mstring = value;
- ret = PyBytes_FromStringAndSize(mstring->s, BLI_strnlen(mstring->s, sizeof(mstring->s)));
+ ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len);
break;
}
case CD_MTEXPOLY:
@@ -1067,13 +1067,17 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
case CD_PROP_STR:
{
MStringProperty *mstring = value;
- const char *tmp_val = PyBytes_AsString(py_value);
- if (UNLIKELY(tmp_val == NULL)) {
+ char *tmp_val;
+ Py_ssize_t tmp_val_len;
+ if (UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) {
PyErr_Format(PyExc_TypeError, "expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name);
ret = -1;
}
else {
- BLI_strncpy(mstring->s, tmp_val, min_ii(PyBytes_Size(py_value), sizeof(mstring->s)));
+ if (tmp_val_len > sizeof(mstring->s))
+ tmp_val_len = sizeof(mstring->s);
+ memcpy(mstring->s, tmp_val, tmp_val_len);
+ mstring->s_len = tmp_val_len;
}
break;
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index b0870578f5a..f59676252d4 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -187,10 +187,10 @@ static int bpy_bmloopuv_flag_set(BPy_BMLoopUV *self, PyObject *value, void *flag
const int flag = GET_INT_FROM_POINTER(flag_p);
switch (PyLong_AsLong(value)) {
- case TRUE:
+ case true:
self->data->flag |= flag;
return 0;
- case FALSE:
+ case false:
self->data->flag &= ~flag;
return 0;
default:
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index dfcfbeb0ab5..33cb1f5d0fb 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -107,7 +107,7 @@ static PyObject *bpy_bmeditselseq_add(BPy_BMEditSelSeq *self, BPy_BMElem *value)
if ((BPy_BMVert_Check(value) ||
BPy_BMEdge_Check(value) ||
- BPy_BMFace_Check(value)) == FALSE)
+ BPy_BMFace_Check(value)) == false)
{
PyErr_Format(PyExc_TypeError,
"Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
@@ -132,7 +132,7 @@ static PyObject *bpy_bmeditselseq_remove(BPy_BMEditSelSeq *self, BPy_BMElem *val
if ((BPy_BMVert_Check(value) ||
BPy_BMEdge_Check(value) ||
- BPy_BMFace_Check(value)) == FALSE)
+ BPy_BMFace_Check(value)) == false)
{
PyErr_Format(PyExc_TypeError,
"Expected a BMVert/BMedge/BMFace not a %.200s", Py_TYPE(value)->tp_name);
@@ -141,7 +141,7 @@ static PyObject *bpy_bmeditselseq_remove(BPy_BMEditSelSeq *self, BPy_BMElem *val
BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "select_history.remove()");
- if (BM_select_history_remove(self->bm, value->ele) == FALSE) {
+ if (BM_select_history_remove(self->bm, value->ele) == false) {
PyErr_SetString(PyExc_ValueError,
"Element not found in selection history");
return NULL;
@@ -196,7 +196,7 @@ static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keyn
static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssize_t start, Py_ssize_t stop)
{
int count = 0;
- int ok;
+ bool ok;
PyObject *list;
PyObject *item;
@@ -210,12 +210,12 @@ static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssi
ok = (ese != NULL);
- if (UNLIKELY(ok == FALSE)) {
+ if (UNLIKELY(ok == false)) {
return list;
}
/* first loop up-until the start */
- for (ok = TRUE; ok; ok = ((ese = ese->next) != NULL)) {
+ for (ok = true; ok; ok = ((ese = ese->next) != NULL)) {
if (count == start) {
break;
}
@@ -429,7 +429,7 @@ int BPy_BMEditSel_Assign(BPy_BMesh *self, PyObject *value)
value_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX,
&value_len, BM_VERT | BM_EDGE | BM_FACE,
- TRUE, TRUE, "BMesh.select_history = value");
+ true, true, "BMesh.select_history = value");
if (value_array == NULL) {
return -1;
diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c
index f85c3347104..7c0adcfc997 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.c
+++ b/source/blender/python/bmesh/bmesh_py_utils.c
@@ -90,7 +90,7 @@ static PyObject *bpy_bm_utils_vert_collapse_edge(PyObject *UNUSED(self), PyObjec
bm = py_edge->bm;
- e_new = BM_vert_collapse_edge(bm, py_edge->e, py_vert->v, TRUE);
+ e_new = BM_vert_collapse_edge(bm, py_edge->e, py_vert->v, true);
if (e_new) {
return BPy_BMEdge_CreatePyObject(bm, e_new);
@@ -106,7 +106,7 @@ static PyObject *bpy_bm_utils_vert_collapse_edge(PyObject *UNUSED(self), PyObjec
PyDoc_STRVAR(bpy_bm_utils_vert_collapse_faces_doc,
".. method:: vert_collapse_faces(vert, edge, fac, join_faces)\n"
"\n"
-" Split an edge, return the newly created data.\n"
+" Collapses a vertex that has only two manifold edges onto a vertex it shares an edge with.\n"
"\n"
" :arg vert: The vert that will be collapsed.\n"
" :type vert: :class:`bmesh.types.BMVert`\n"
@@ -156,14 +156,14 @@ static PyObject *bpy_bm_utils_vert_collapse_faces(PyObject *UNUSED(self), PyObje
bm = py_edge->bm;
- e_new = BM_vert_collapse_faces(bm, py_edge->e, py_vert->v, CLAMPIS(fac, 0.0f, 1.0f), do_join_faces, TRUE);
+ e_new = BM_vert_collapse_faces(bm, py_edge->e, py_vert->v, CLAMPIS(fac, 0.0f, 1.0f), do_join_faces, true);
if (e_new) {
return BPy_BMEdge_CreatePyObject(bm, e_new);
}
else {
PyErr_SetString(PyExc_ValueError,
- "vert_collapse_edge(vert, edge): no new edge created, internal error");
+ "vert_collapse_faces(vert, edge): no new edge created, internal error");
return NULL;
}
}
@@ -239,7 +239,7 @@ static PyObject *bpy_bm_utils_vert_separate(PyObject *UNUSED(self), PyObject *ar
edge_array = BPy_BMElem_PySeq_As_Array(&bm, edge_seq, 0, PY_SSIZE_T_MAX,
&edge_array_len, BM_EDGE,
- TRUE, TRUE, "vert_separate(...)");
+ true, true, "vert_separate(...)");
if (edge_array == NULL) {
return NULL;
@@ -338,7 +338,7 @@ PyDoc_STRVAR(bpy_bm_utils_edge_rotate_doc,
static PyObject *bpy_bm_utils_edge_rotate(PyObject *UNUSED(self), PyObject *args)
{
BPy_BMEdge *py_edge;
- int do_ccw = FALSE;
+ int do_ccw = false;
BMesh *bm;
BMEdge *e_new = NULL;
@@ -396,7 +396,7 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args,
/* optional */
PyObject *py_coords = NULL;
- int edge_exists = TRUE;
+ int edge_exists = true;
BPy_BMEdge *py_edge_example = NULL;
float *coords;
@@ -426,8 +426,8 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args,
}
/* this doubles for checking that the verts are in the same mesh */
- if (BM_vert_in_face(py_face->f, py_vert_a->v) == FALSE ||
- BM_vert_in_face(py_face->f, py_vert_b->v) == FALSE)
+ if (BM_vert_in_face(py_face->f, py_vert_a->v) == false ||
+ BM_vert_in_face(py_face->f, py_vert_b->v) == false)
{
PyErr_SetString(PyExc_ValueError,
"face_split(...): one of the verts passed is not found in the face");
@@ -496,7 +496,7 @@ static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *args)
BMFace **face_array;
Py_ssize_t face_seq_len = 0;
BMFace *f_new;
- int do_remove = TRUE;
+ int do_remove = true;
if (!PyArg_ParseTuple(args, "O|i:face_join", &py_face_array, &do_remove)) {
return NULL;
@@ -504,7 +504,7 @@ static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *args)
face_array = BPy_BMElem_PySeq_As_Array(&bm, py_face_array, 2, PY_SSIZE_T_MAX,
&face_seq_len, BM_FACE,
- TRUE, TRUE, "face_join(...)");
+ true, true, "face_join(...)");
if (face_array == NULL) {
return NULL; /* error will be set */
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index 8d146bedb48..0c0ad50ebe4 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -66,7 +66,7 @@ static PyObject *imp_reload_orig = NULL;
*
* However Python's alternative is to use import hooks,
* which are implemented in a way that we can't use our own importer as a
- * fall-back (instead we must try and fail - raise an exception evert time).
+ * fall-back (instead we must try and fail - raise an exception every time).
* Since importing from blenders text-blocks is not the common case
* I prefer to use Pythons import by default and fall-back to
* Blenders - which we can only do by intercepting import calls I'm afraid.
diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h
index 1592ec52b4c..56cdf677ccb 100644
--- a/source/blender/python/generic/bpy_internal_import.h
+++ b/source/blender/python/generic/bpy_internal_import.h
@@ -48,9 +48,9 @@ struct Text;
void bpy_import_init(PyObject *builtins);
-PyObject* bpy_text_import(struct Text *text);
-PyObject* bpy_text_import_name(const char *name, int *found);
-PyObject* bpy_text_reimport(PyObject *module, int *found);
+PyObject *bpy_text_import(struct Text *text);
+PyObject *bpy_text_import_name(const char *name, int *found);
+PyObject *bpy_text_reimport(PyObject *module, int *found);
/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 53112d46098..a0e2f1a0854 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -836,6 +836,11 @@ static PyObject *BPy_IDGroup_to_dict(BPy_IDProperty *self)
return BPy_IDGroup_MapDataToPy(self->prop);
}
+static PyObject *BPy_IDGroup_clear(BPy_IDProperty *self)
+{
+ IDP_ClearProperty(self->prop);
+ Py_RETURN_NONE;
+}
/* Matches python dict.get(key, [default]) */
static PyObject *BPy_IDGroup_Get(BPy_IDProperty *self, PyObject *args)
@@ -875,6 +880,8 @@ static struct PyMethodDef BPy_IDGroup_methods[] = {
"idprop.get(k[,d]) -> idprop[k] if k in idprop, else d. d defaults to None"},
{"to_dict", (PyCFunction)BPy_IDGroup_to_dict, METH_NOARGS,
"return a purely python version of the group"},
+ {"clear", (PyCFunction)BPy_IDGroup_clear, METH_NOARGS,
+ "clear all members from this group"},
{NULL, NULL, 0, NULL}
};
@@ -1447,6 +1454,8 @@ static PyObject *BPyInit_idprop_types(void)
submodule = PyModule_Create(&IDProp_types_module_def);
+ IDProp_Init_Types();
+
#define MODULE_TYPE_ADD(s, t) \
PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t)
@@ -1490,7 +1499,7 @@ PyObject *BPyInit_idprop(void)
mod = PyModule_Create(&IDProp_module_def);
- /* bmesh.types */
+ /* idprop.types */
PyModule_AddObject(mod, "types", (submodule = BPyInit_idprop_types()));
PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
Py_INCREF(submodule);
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index f62fdaf09db..56d9e2ac0dd 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -33,6 +33,8 @@
#include <Python.h>
#include <frameobject.h>
+#include "BLI_utildefines.h" /* for bool */
+
#include "py_capi_utils.h"
/* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */
@@ -44,7 +46,7 @@
/* array utility function */
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
- const PyTypeObject *type, const short is_double, const char *error_prefix)
+ const PyTypeObject *type, const bool is_double, const char *error_prefix)
{
PyObject *value_fast;
Py_ssize_t value_len;
@@ -112,6 +114,54 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
return 0;
}
+/* array utility function */
+PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type,
+ const bool is_double, const char *error_prefix)
+{
+ PyObject *tuple;
+ int i;
+
+ tuple = PyTuple_New(length);
+
+ /* for each type */
+ if (type == &PyFloat_Type) {
+ if (is_double) {
+ const double *array_double = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i]));
+ }
+ }
+ else {
+ const float *array_float = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i]));
+ }
+ }
+ }
+ else if (type == &PyLong_Type) {
+ /* could use is_double for 'long int' but no use now */
+ const int *array_int = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i]));
+ }
+ }
+ else if (type == &PyBool_Type) {
+ const int *array_bool = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i]));
+ }
+ }
+ else {
+ Py_DECREF(tuple);
+ PyErr_Format(PyExc_TypeError,
+ "%s: internal error %s is invalid",
+ error_prefix, type->tp_name);
+ return NULL;
+ }
+
+ return tuple;
+}
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var)
@@ -241,6 +291,23 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
return item;
}
+PyObject *PyC_FrozenSetFromStrings(const char **strings)
+{
+ const char **str;
+ PyObject *ret;
+
+ ret = PyFrozenSet_New(NULL);
+
+ for (str = strings; *str; str++) {
+ PyObject *py_str = PyUnicode_FromString(*str);
+ PySet_Add(ret, py_str);
+ Py_DECREF(py_str);
+ }
+
+ return ret;
+}
+
+
/* similar to PyErr_Format(),
*
* implementation - we cant actually preprend the existing exception,
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 935a5f9030b..239858032de 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -33,11 +33,14 @@ void PyC_LineSpit(void);
void PyC_StackSpit(void);
PyObject * PyC_ExceptionBuffer(void);
PyObject * PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
+PyObject * PyC_FrozenSetFromStrings(const char **strings);
PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...);
void PyC_FileAndNum(const char **filename, int *lineno);
void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
- const PyTypeObject *type, const short is_double, const char *error_prefix);
+ const PyTypeObject *type, const bool is_double, const char *error_prefix);
+PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type,
+ const bool is_double, const char *error_prefix);
/* follow http://www.python.org/dev/peps/pep-0383/ */
PyObject * PyC_UnicodeFromByte(const char *str);
@@ -53,7 +56,7 @@ void PyC_MainModule_Restore(PyObject *main_mod);
void PyC_SetHomePath(const char *py_path_bundle);
-#define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
+#define PYC_INTERPRETER_ACTIVE (((PyThreadState *)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
void *PyC_RNA_AsPointer(PyObject *value, const char *type_name);
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 61c49027d9a..b531e08f8d4 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -47,7 +47,9 @@ set(SRC
bpy.c
bpy_app.c
bpy_app_ffmpeg.c
+ bpy_app_build_options.c
bpy_app_handlers.c
+ bpy_app_translations.c
bpy_driver.c
bpy_interface.c
bpy_interface_atexit.c
@@ -55,6 +57,7 @@ set(SRC
bpy_library.c
bpy_operator.c
bpy_operator_wrap.c
+ bpy_path.c
bpy_props.c
bpy_rna.c
bpy_rna_anim.c
@@ -68,12 +71,15 @@ set(SRC
bpy.h
bpy_app.h
bpy_app_ffmpeg.h
+ bpy_app_build_options.h
bpy_app_handlers.h
+ bpy_app_translations.h
bpy_driver.h
bpy_intern_string.h
bpy_library.h
bpy_operator.h
bpy_operator_wrap.h
+ bpy_path.h
bpy_props.h
bpy_rna.h
bpy_rna_anim.h
@@ -96,24 +102,140 @@ if(WITH_PYTHON_SAFETY)
add_definitions(-DWITH_PYTHON_SAFETY)
endif()
+
+
if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE)
endif()
-if(WITH_CYCLES)
- add_definitions(-DWITH_CYCLES)
+if(WITH_BULLET)
+ add_definitions(-DWITH_BULLET)
endif()
-if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+if(WITH_CODEC_AVI)
+ add_definitions(-DWITH_AVI)
endif()
if(WITH_CODEC_FFMPEG)
list(APPEND INC_SYS
${FFMPEG_INCLUDE_DIRS}
)
-
add_definitions(-DWITH_FFMPEG)
endif()
+if(WITH_CODEC_QUICKTIME)
+ add_definitions(-DWITH_QUICKTIME)
+endif()
+
+if(WITH_CODEC_SNDFILE)
+ add_definitions(-DWITH_SNDFILE)
+endif()
+
+if(WITH_COMPOSITOR)
+ add_definitions(-DWITH_COMPOSITOR)
+endif()
+
+if(WITH_CYCLES)
+ add_definitions(-DWITH_CYCLES)
+endif()
+
+if(WITH_CYCLES_OSL)
+ add_definitions(-DWITH_CYCLES_OSL)
+endif()
+
+if(WITH_GAMEENGINE)
+ add_definitions(-DWITH_GAMEENGINE)
+endif()
+
+if(WITH_IMAGE_CINEON)
+ add_definitions(-DWITH_CINEON)
+endif()
+
+if(WITH_IMAGE_DDS)
+ add_definitions(-DWITH_DDS)
+endif()
+
+if(WITH_IMAGE_FRAMESERVER)
+ add_definitions(-DWITH_FRAMESERVER)
+endif()
+
+if(WITH_IMAGE_HDR)
+ add_definitions(-DWITH_HDR)
+endif()
+
+if(WITH_IMAGE_OPENEXR)
+ add_definitions(-DWITH_OPENEXR)
+endif()
+
+if(WITH_IMAGE_OPENJPEG)
+ add_definitions(-DWITH_OPENJPEG)
+endif()
+
+if(WITH_IMAGE_REDCODE)
+ add_definitions(-DWITH_REDCODE)
+endif()
+
+if(WITH_IMAGE_TIFF)
+ add_definitions(-DWITH_TIFF)
+endif()
+
+if(WITH_INPUT_NDOF)
+ add_definitions(-DWITH_INPUT_NDOF)
+endif()
+
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
+if(WITH_OPENAL)
+ add_definitions(-DWITH_OPENAL)
+endif()
+
+if(WITH_SDL)
+ add_definitions(-DWITH_SDL)
+endif()
+
+if(WITH_JACK)
+ add_definitions(-DWITH_JACK)
+endif()
+
+if(WITH_LIBMV)
+ add_definitions(-DWITH_LIBMV)
+endif()
+
+if(WITH_MOD_BOOLEAN)
+ add_definitions(-DWITH_MOD_BOOLEAN)
+endif()
+
+if(WITH_MOD_FLUID)
+ add_definitions(-DWITH_MOD_FLUID)
+endif()
+
+if(WITH_MOD_OCEANSIM)
+ add_definitions(-DWITH_OCEANSIM)
+endif()
+
+if(WITH_MOD_REMESH)
+ add_definitions(-DWITH_MOD_REMESH)
+endif()
+
+if(WITH_MOD_SMOKE)
+ add_definitions(-DWITH_SMOKE)
+endif()
+
+if(WITH_OPENCOLLADA)
+ add_definitions(-DWITH_COLLADA)
+endif()
+
+if(WITH_OPENCOLORIO)
+ add_definitions(-DWITH_OCIO)
+endif()
+
+if(WITH_PLAYER)
+ add_definitions(-DWITH_PLAYER)
+endif()
+
+
+
+
blender_add_lib(bf_python "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 3ed662f41d7..c4d68290da3 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -35,19 +35,19 @@
#include "RNA_types.h"
#include "RNA_access.h"
-#include "bpy.h"
-#include "bpy_util.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BKE_bpath.h"
+#include "BLI_utildefines.h"
+
+#include "bpy.h"
+#include "bpy_util.h"
#include "bpy_rna.h"
#include "bpy_app.h"
#include "bpy_props.h"
#include "bpy_library.h"
#include "bpy_operator.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-#include "BLI_bpath.h"
-#include "BLI_utildefines.h"
-
#include "BKE_main.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "BKE_blender.h"
@@ -94,7 +94,7 @@ static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), cons
PyObject *item = PyUnicode_DecodeFSDefault(path_src);
PyList_Append(list, item);
Py_DECREF(item);
- return FALSE; /* never edits the path */
+ return false; /* never edits the path */
}
PyDoc_STRVAR(bpy_blend_paths_doc,
@@ -116,9 +116,9 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
int flag = 0;
PyObject *list;
- int absolute = FALSE;
- int packed = FALSE;
- int local = FALSE;
+ int absolute = false;
+ int packed = false;
+ int local = false;
static const char *kwlist[] = {"absolute", "packed", "local", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|iii:blend_paths",
@@ -127,13 +127,13 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
return NULL;
}
- if (absolute) flag |= BLI_BPATH_TRAVERSE_ABS;
- if (!packed) flag |= BLI_BPATH_TRAVERSE_SKIP_PACKED;
- if (local) flag |= BLI_BPATH_TRAVERSE_SKIP_LIBRARY;
+ if (absolute) flag |= BKE_BPATH_TRAVERSE_ABS;
+ if (!packed) flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED;
+ if (local) flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY;
list = PyList_New(0);
- BLI_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list);
+ BKE_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list);
return list;
}
@@ -205,7 +205,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return NULL;
}
- path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE);
+ path = BLI_get_folder_version(folder_id, (major * 100) + minor, false);
return PyUnicode_DecodeFSDefault(path ? path : "");
}
@@ -234,6 +234,7 @@ static PyObject *bpy_import_test(const char *modname)
return mod;
}
+
/******************************************************************************
* Description: Creates the bpy module and adds it to sys.modules for importing
******************************************************************************/
@@ -293,6 +294,9 @@ void BPy_init_modules(void)
PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
+ /* register bpy/rna classmethod callbacks */
+ BPY_rna_register_cb();
+
/* utility func's that have nowhere else to go */
PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index b1eeff8b3ae..5195f821d56 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -34,6 +34,9 @@
#include "bpy_app.h"
#include "bpy_app_ffmpeg.h"
+#include "bpy_app_build_options.h"
+
+#include "bpy_app_translations.h"
#include "bpy_app_handlers.h"
#include "bpy_driver.h"
@@ -83,8 +86,10 @@ static PyStructSequence_Field app_info_fields[] = {
/* submodules */
{(char *)"ffmpeg", (char *)"FFmpeg library information backend"},
+ {(char *)"build_options", (char *)"A set containing most important enabled optional build features"},
{(char *)"handlers", (char *)"Application handler callbacks"},
- {NULL}
+ {(char *)"translations", (char *)"Application and addons internationalization API"},
+ {NULL},
};
static PyStructSequence_Desc app_info_desc = {
@@ -148,7 +153,9 @@ static PyObject *make_app_info(void)
#endif
SetObjItem(BPY_app_ffmpeg_struct());
+ SetObjItem(BPY_app_build_options_struct());
SetObjItem(BPY_app_handlers_struct());
+ SetObjItem(BPY_app_translations_struct());
#undef SetIntItem
#undef SetStrItem
@@ -179,7 +186,7 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos
const int flag = GET_INT_FROM_POINTER(closure);
const int param = PyObject_IsTrue(value);
- if (param < 0) {
+ if (param == -1) {
PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
return -1;
}
diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c
new file mode 100644
index 00000000000..6db0a52bdf0
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_build_options.c
@@ -0,0 +1,303 @@
+/*
+ * ***** 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
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_app_build_options.c
+ * \ingroup pythonintern
+ */
+
+#include <Python.h>
+#include "BLI_utildefines.h"
+
+#include "bpy_app_build_options.h"
+
+static PyTypeObject BlenderAppBuildOptionsType;
+
+static PyStructSequence_Field app_builtopts_info_fields[] = {
+ /* names mostly follow CMake options, lowercase, after WITH_ */
+ {(char *)"bullet", NULL},
+ {(char *)"codec_avi", NULL},
+ {(char *)"codec_ffmpeg", NULL},
+ {(char *)"codec_quicktime", NULL},
+ {(char *)"codec_sndfile", NULL},
+ {(char *)"compositor", NULL},
+ {(char *)"cycles", NULL},
+ {(char *)"cycles_osl", NULL},
+ {(char *)"gameengine", NULL},
+ {(char *)"image_cineon", NULL},
+ {(char *)"image_dds", NULL},
+ {(char *)"image_frameserver", NULL},
+ {(char *)"image_hdr", NULL},
+ {(char *)"image_openexr", NULL},
+ {(char *)"image_openjpeg", NULL},
+ {(char *)"image_redcode", NULL},
+ {(char *)"image_tiff", NULL},
+ {(char *)"input_ndof", NULL},
+ {(char *)"audaspace", NULL},
+ {(char *)"international", NULL},
+ {(char *)"openal", NULL},
+ {(char *)"sdl", NULL},
+ {(char *)"jack", NULL},
+ {(char *)"libmv", NULL},
+ {(char *)"mod_boolean", NULL},
+ {(char *)"mod_fluid", NULL},
+ {(char *)"mod_oceansim", NULL},
+ {(char *)"mod_remesh", NULL},
+ {(char *)"mod_smoke", NULL},
+ {(char *)"collada", NULL},
+ {(char *)"opencolorio", NULL},
+ {(char *)"player", NULL},
+ {NULL}
+};
+
+
+static PyStructSequence_Desc app_builtopts_info_desc = {
+ (char *)"bpy.app.build_options", /* name */
+ (char *)"This module contains information about options blender is built with", /* doc */
+ app_builtopts_info_fields, /* fields */
+ (sizeof(app_builtopts_info_fields) / sizeof(PyStructSequence_Field)) - 1
+};
+
+static PyObject *make_builtopts_info(void)
+{
+ PyObject *builtopts_info;
+ int pos = 0;
+
+ builtopts_info = PyStructSequence_New(&BlenderAppBuildOptionsType);
+ if (builtopts_info == NULL) {
+ return NULL;
+ }
+
+#define SetObjIncref(item) \
+ PyStructSequence_SET_ITEM(builtopts_info, pos++, (Py_IncRef(item), item))
+
+#ifdef WITH_BULLET
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_AVI
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_FFMPEG
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_QUICKTIME
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_SNDFILE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_COMPOSITOR
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_CYCLES
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_CYCLES_OSL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_GAMEENGINE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_CINEON
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_DDS
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_FRAMESERVER
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_HDR
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OPENEXR
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OPENJPEG
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_REDCODE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_TIFF
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_INPUT_NDOF
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_AUDASPACE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_INTERNATIONAL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OPENAL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_SDL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_JACK
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_LIBMV
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_MOD_BOOLEAN
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_MOD_FLUID
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OCEANSIM
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_MOD_REMESH
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_SMOKE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_COLLADA
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OCIO
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_PLAYER
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#undef SetObjIncref
+
+ return builtopts_info;
+}
+
+PyObject *BPY_app_build_options_struct(void)
+{
+ PyObject *ret;
+
+ PyStructSequence_InitType(&BlenderAppBuildOptionsType, &app_builtopts_info_desc);
+
+ ret = make_builtopts_info();
+
+ /* prevent user from creating new instances */
+ BlenderAppBuildOptionsType.tp_init = NULL;
+ BlenderAppBuildOptionsType.tp_new = NULL;
+ BlenderAppBuildOptionsType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
+
+ return ret;
+}
diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.cpp b/source/blender/python/intern/bpy_app_build_options.h
index 0b8f89ceed2..82a1417ea2c 100644
--- a/source/gameengine/Physics/common/PHY_IGraphicController.cpp
+++ b/source/blender/python/intern/bpy_app_build_options.h
@@ -15,24 +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.
*
- * 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.
+ * Contributor(s): Bastien Montagne
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file gameengine/Physics/common/PHY_IGraphicController.cpp
- * \ingroup phys
+/** \file blender/python/intern/bpy_app_build_options.h
+ * \ingroup pythonintern
*/
-#include "PHY_IGraphicController.h"
-
-PHY_IGraphicController::~PHY_IGraphicController()
-{
+#ifndef __BPY_APP_BUILD_OPTIONS_H__
+#define __BPY_APP_BUILD_OPTIONS_H__
-}
+PyObject *BPY_app_build_options_struct(void);
+#endif /* __BPY_APP_BUILD_OPTIONS_H__ */
diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c
index 5ae2a11710a..3bf3dec3872 100644
--- a/source/blender/python/intern/bpy_app_ffmpeg.c
+++ b/source/blender/python/intern/bpy_app_ffmpeg.c
@@ -41,16 +41,16 @@ static PyTypeObject BlenderAppFFmpegType;
#define DEF_FFMPEG_LIB_VERSION(lib) \
{(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \
- {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")},
+ {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}
static PyStructSequence_Field app_ffmpeg_info_fields[] = {
{(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")},
- DEF_FFMPEG_LIB_VERSION(avcodec)
- DEF_FFMPEG_LIB_VERSION(avdevice)
- DEF_FFMPEG_LIB_VERSION(avformat)
- DEF_FFMPEG_LIB_VERSION(avutil)
- DEF_FFMPEG_LIB_VERSION(swscale)
+ DEF_FFMPEG_LIB_VERSION(avcodec),
+ DEF_FFMPEG_LIB_VERSION(avdevice),
+ DEF_FFMPEG_LIB_VERSION(avformat),
+ DEF_FFMPEG_LIB_VERSION(avutil),
+ DEF_FFMPEG_LIB_VERSION(swscale),
{NULL}
};
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
new file mode 100644
index 00000000000..7c89972b486
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_translations.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.
+ *
+ * Contributor(s): Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_app_translations.c
+ * \ingroup pythonintern
+ *
+ * This file defines a singleton py object accessed via 'bpy.app.translations',
+ * which exposes various data and functions useful in i18n work.
+ * Most notably, it allows to extend main translations with py dicts.
+ */
+
+#include <Python.h>
+/* XXX Why bloody hell isn't that included in Python.h???? */
+#include <structmember.h>
+
+#include "BLI_string.h"
+#include "BLI_ghash.h"
+#include "BLI_utildefines.h"
+
+#include "BPY_extern.h"
+#include "bpy_app_translations.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLF_translation.h"
+
+#include "RNA_types.h"
+#include "RNA_access.h"
+
+
+typedef struct
+{
+ PyObject_HEAD
+ /* The string used to separate context from actual message in PY_TRANSLATE RNA props. */
+ const char *context_separator;
+ /* A "named tuple" (StructSequence actually...) containing all C-defined contexts. */
+ PyObject *contexts;
+ /* A readonly mapping {C context id: python id} (actually, a MappingProxy). */
+ PyObject *contexts_C_to_py;
+ /* A py dict containing all registered py dicts (order is more or less random, first match wins!). */
+ PyObject *py_messages;
+} BlenderAppTranslations;
+
+/* Our singleton instance pointer */
+static BlenderAppTranslations *_translations = NULL;
+
+#ifdef WITH_INTERNATIONAL
+
+/***** Helpers for ghash *****/
+typedef struct GHashKey {
+ const char *msgctxt;
+ const char *msgid;
+} GHashKey;
+
+static GHashKey *_ghashutil_keyalloc(const void *msgctxt, const void *msgid)
+{
+ GHashKey *key = MEM_mallocN(sizeof(GHashKey), "Py i18n GHashKey");
+ key->msgctxt = BLI_strdup(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT_BPY);
+ key->msgid = BLI_strdup(msgid);
+ return key;
+}
+
+static unsigned int _ghashutil_keyhash(const void *ptr)
+{
+ const GHashKey *key = ptr;
+ unsigned int hash = BLI_ghashutil_strhash(key->msgctxt);
+ return hash ^ BLI_ghashutil_strhash(key->msgid);
+}
+
+static int _ghashutil_keycmp(const void *a, const void *b)
+{
+ const GHashKey *A = a;
+ const GHashKey *B = b;
+
+ /* Note: comparing msgid first, most of the time it will be enough! */
+ int cmp = BLI_ghashutil_strcmp(A->msgid, B->msgid);
+ if (cmp == 0)
+ return BLI_ghashutil_strcmp(A->msgctxt, B->msgctxt);
+ return cmp;
+}
+
+static void _ghashutil_keyfree(void *ptr)
+{
+ const GHashKey *key = ptr;
+
+ /* We assume both msgctxt and msgid were BLI_strdup'ed! */
+ MEM_freeN((void *)key->msgctxt);
+ MEM_freeN((void *)key->msgid);
+ MEM_freeN((void *)key);
+}
+
+static void _ghashutil_valfree(void *ptr)
+{
+ MEM_freeN(ptr);
+}
+
+/***** Python's messages cache *****/
+
+/* We cache all messages available for a given locale from all py dicts into a single ghash.
+ * Changing of locale is not so common, while looking for a message translation is, so let's try to optimize
+ * the later as much as we can!
+ * Note changing of locale, as well as (un)registering a message dict, invalidate that cache.
+ */
+static GHash *_translations_cache = NULL;
+
+static void _clear_translations_cache(void)
+{
+ if (_translations_cache) {
+ BLI_ghash_free(_translations_cache, _ghashutil_keyfree, _ghashutil_valfree);
+ }
+ _translations_cache = NULL;
+}
+
+static void _build_translations_cache(PyObject *py_messages, const char *locale)
+{
+ PyObject *uuid, *uuid_dict;
+ Py_ssize_t pos = 0;
+ char *language = NULL, *language_country = NULL, *language_variant = NULL;
+
+ /* For each py dict, we'll search for full locale, then language+country, then language+variant,
+ * then only language keys... */
+ BLF_locale_explode(locale, &language, NULL, NULL, &language_country, &language_variant);
+
+ /* Clear the cached ghash if needed, and create a new one. */
+ _clear_translations_cache();
+ _translations_cache = BLI_ghash_new(_ghashutil_keyhash, _ghashutil_keycmp, __func__);
+
+ /* Iterate over all py dicts. */
+ while (PyDict_Next(py_messages, &pos, &uuid, &uuid_dict)) {
+ PyObject *lang_dict;
+
+#if 0
+ PyObject_Print(uuid_dict, stdout, 0);
+ printf("\n");
+#endif
+
+ /* Try to get first complete locale, then language+country, then language+variant, then only language */
+ lang_dict = PyDict_GetItemString(uuid_dict, locale);
+ if (!lang_dict && language_country) {
+ lang_dict = PyDict_GetItemString(uuid_dict, language_country);
+ locale = language_country;
+ }
+ if (!lang_dict && language_variant) {
+ lang_dict = PyDict_GetItemString(uuid_dict, language_variant);
+ locale = language_variant;
+ }
+ if (!lang_dict && language) {
+ lang_dict = PyDict_GetItemString(uuid_dict, language);
+ locale = language;
+ }
+
+ if (lang_dict) {
+ PyObject *pykey, *trans;
+ Py_ssize_t ppos = 0;
+
+ if (!PyDict_Check(lang_dict)) {
+ printf("WARNING! In translations' dict of \"");
+ PyObject_Print(uuid, stdout, Py_PRINT_RAW);
+ printf("\":\n");
+ printf(" Each language key must have a dictionary as value, \"%s\" is not valid, skipping: ",
+ locale);
+ PyObject_Print(lang_dict, stdout, Py_PRINT_RAW);
+ printf("\n");
+ continue;
+ }
+
+ /* Iterate over all translations of the found language dict, and populate our ghash cache. */
+ while (PyDict_Next(lang_dict, &ppos, &pykey, &trans)) {
+ GHashKey *key;
+ const char *msgctxt = NULL, *msgid = NULL;
+ bool invalid_key = false;
+
+ if ((PyTuple_CheckExact(pykey) == false) || (PyTuple_GET_SIZE(pykey) != 2)) {
+ invalid_key = true;
+ }
+ else {
+ PyObject *tmp = PyTuple_GET_ITEM(pykey, 0);
+ if (tmp == Py_None) {
+ msgctxt = BLF_I18NCONTEXT_DEFAULT_BPY;
+ }
+ else if (PyUnicode_Check(tmp)) {
+ msgctxt = _PyUnicode_AsString(tmp);
+ }
+ else {
+ invalid_key = true;
+ }
+
+ tmp = PyTuple_GET_ITEM(pykey, 1);
+ if (PyUnicode_Check(tmp)) {
+ msgid = _PyUnicode_AsString(tmp);
+ }
+ else {
+ invalid_key = true;
+ }
+ }
+
+ if (invalid_key) {
+ printf("WARNING! In translations' dict of \"");
+ PyObject_Print(uuid, stdout, Py_PRINT_RAW);
+ printf("\", %s language:\n", locale);
+ printf(" Keys must be tuples of (msgctxt [string or None], msgid [string]), "
+ "this one is not valid, skipping: ");
+ PyObject_Print(pykey, stdout, Py_PRINT_RAW);
+ printf("\n");
+ continue;
+ }
+ if (PyUnicode_Check(trans) == false) {
+ printf("WARNING! In translations' dict of \"");
+ PyObject_Print(uuid, stdout, Py_PRINT_RAW);
+ printf("\":\n");
+ printf(" Values must be strings, this one is not valid, skipping: ");
+ PyObject_Print(trans, stdout, Py_PRINT_RAW);
+ printf("\n");
+ continue;
+ }
+
+ key = _ghashutil_keyalloc(msgctxt, msgid);
+
+ /* Do not overwrite existing keys! */
+ if (BLI_ghash_lookup(_translations_cache, (void *)key)) {
+ continue;
+ }
+
+ BLI_ghash_insert(_translations_cache, key, BLI_strdup(_PyUnicode_AsString(trans)));
+ }
+ }
+ }
+
+ /* Clean up! */
+ if (language)
+ MEM_freeN(language);
+ if (language_country)
+ MEM_freeN(language_country);
+ if (language_variant)
+ MEM_freeN(language_variant);
+}
+
+const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *msgid)
+{
+#define STATIC_LOCALE_SIZE 32 /* Should be more than enough! */
+
+ GHashKey *key;
+ static char locale[STATIC_LOCALE_SIZE] = "";
+ const char *tmp;
+
+ /* Just in case, should never happen! */
+ if (!_translations)
+ return msgid;
+
+ tmp = BLF_lang_get();
+ if (strcmp(tmp, locale) || !_translations_cache) {
+ PyGILState_STATE _py_state;
+
+ BLI_strncpy(locale, tmp, STATIC_LOCALE_SIZE);
+
+ /* Locale changed or cache does not exist, refresh the whole cache! */
+ /* This func may be called from C (i.e. outside of python interpreter 'context'). */
+ _py_state = PyGILState_Ensure();
+
+ _build_translations_cache(_translations->py_messages, locale);
+
+ PyGILState_Release(_py_state);
+ }
+
+ /* And now, simply create the key (context, messageid) and find it in the cached dict! */
+ key = _ghashutil_keyalloc(msgctxt, msgid);
+
+ tmp = BLI_ghash_lookup(_translations_cache, key);
+
+ _ghashutil_keyfree((void *)key);
+
+ return tmp ? tmp : msgid;
+
+#undef STATIC_LOCALE_SIZE
+}
+
+#endif /* WITH_INTERNATIONAL */
+
+PyDoc_STRVAR(app_translations_py_messages_register_doc,
+".. method:: register(module_name, translations_dict)\n"
+"\n"
+" Registers an addon's UI translations.\n"
+"\n"
+" Note: Does nothing when Blender is built without internationalization support.\n"
+"\n"
+" :arg module_name: The name identifying the addon.\n"
+" :type module_name: string\n"
+" :arg translations_dict: A dictionary built like that:\n"
+" {locale: {msg_key: msg_translation, ...}, ...}\n"
+" :type translations_dict: dict\n"
+"\n"
+);
+static PyObject *app_translations_py_messages_register(BlenderAppTranslations *self, PyObject *args, PyObject *kw)
+{
+#ifdef WITH_INTERNATIONAL
+ static const char *kwlist[] = {"module_name", "translations_dict", NULL};
+ PyObject *module_name, *uuid_dict;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!:bpy.app.translations.register", (char **)kwlist, &PyUnicode_Type,
+ &module_name, &PyDict_Type, &uuid_dict))
+ {
+ return NULL;
+ }
+
+ if (PyDict_Contains(self->py_messages, module_name)) {
+ PyErr_Format(PyExc_ValueError,
+ "bpy.app.translations.register: translations message cache already contains some data for "
+ "addon '%s'", (const char *)_PyUnicode_AsString(module_name));
+ return NULL;
+ }
+
+ PyDict_SetItem(self->py_messages, module_name, uuid_dict);
+
+ /* Clear cached messages dict! */
+ _clear_translations_cache();
+#else
+ (void)self;
+ (void)args;
+ (void)kw;
+#endif
+
+ /* And we are done! */
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(app_translations_py_messages_unregister_doc,
+".. method:: unregister(module_name)\n"
+"\n"
+" Unregisters an addon's UI translations.\n"
+"\n"
+" Note: Does nothing when Blender is built without internationalization support.\n"
+"\n"
+" :arg module_name: The name identifying the addon.\n"
+" :type module_name: string\n"
+"\n"
+);
+static PyObject *app_translations_py_messages_unregister(BlenderAppTranslations *self, PyObject *args, PyObject *kw)
+{
+#ifdef WITH_INTERNATIONAL
+ static const char *kwlist[] = {"module_name", NULL};
+ PyObject *module_name;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O!:bpy.app.translations.unregister", (char **)kwlist, &PyUnicode_Type,
+ &module_name))
+ {
+ return NULL;
+ }
+
+ if (PyDict_Contains(self->py_messages, module_name)) {
+ PyDict_DelItem(self->py_messages, module_name);
+ /* Clear cached messages ghash! */
+ _clear_translations_cache();
+ }
+#else
+ (void)self;
+ (void)args;
+ (void)kw;
+#endif
+
+ /* And we are done! */
+ Py_RETURN_NONE;
+}
+
+/***** C-defined contexts *****/
+/* This is always available (even when WITH_INTERNATIONAL is not defined). */
+
+static PyTypeObject BlenderAppTranslationsContextsType;
+
+static BLF_i18n_contexts_descriptor _contexts[] = BLF_I18NCONTEXTS_DESC;
+
+/* These fields are just empty placeholders, actual values get set in app_translations_struct().
+ * This allows us to avoid many handwriting, and above all, to keep all context definition stuff in BLF_translation.h!
+ */
+static PyStructSequence_Field
+app_translations_contexts_fields[sizeof(_contexts) / sizeof(BLF_i18n_contexts_descriptor)] = {{NULL}};
+
+static PyStructSequence_Desc app_translations_contexts_desc = {
+ (char *)"bpy.app.translations.contexts", /* name */
+ (char *)"This named tuple contains all pre-defined translation contexts", /* doc */
+ app_translations_contexts_fields, /* fields */
+ (sizeof(app_translations_contexts_fields) / sizeof(PyStructSequence_Field)) - 1
+};
+
+static PyObject *app_translations_contexts_make(void)
+{
+ PyObject *translations_contexts;
+ BLF_i18n_contexts_descriptor *ctxt;
+ int pos = 0;
+
+ translations_contexts = PyStructSequence_New(&BlenderAppTranslationsContextsType);
+ if (translations_contexts == NULL) {
+ return NULL;
+ }
+
+#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)
+
+ for (ctxt = _contexts; ctxt->c_id; ctxt++) {
+ if (ctxt->value) {
+ SetObjString(ctxt->value);
+ }
+ else {
+ SetObjNone();
+ }
+ }
+
+#undef SetObjString
+#undef SetObjNone
+
+ return translations_contexts;
+}
+
+/***** Main BlenderAppTranslations Py object definition *****/
+
+PyDoc_STRVAR(app_translations_contexts_doc,
+ "A named tuple containing all pre-defined translation contexts.\n"
+ "WARNING: Never use a (new) context starting with \"" BLF_I18NCONTEXT_DEFAULT_BPY "\", it would be internally "
+ "assimilated as the default one!\n"
+);
+
+PyDoc_STRVAR(app_translations_contexts_C_to_py_doc,
+ "A readonly dict mapping contexts' C-identifiers to their py-identifiers."
+);
+
+PyMemberDef app_translations_members[] = {
+ {(char *)"contexts", T_OBJECT_EX, offsetof(BlenderAppTranslations, contexts), READONLY,
+ app_translations_contexts_doc},
+ {(char *)"contexts_C_to_py", T_OBJECT_EX, offsetof(BlenderAppTranslations, contexts_C_to_py), READONLY,
+ app_translations_contexts_C_to_py_doc},
+ {NULL}
+};
+
+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)."
+);
+static PyObject *app_translations_locale_get(PyObject *UNUSED(self), void *UNUSED(userdata))
+{
+ return PyUnicode_FromString(BLF_lang_get());
+}
+
+/* Note: defining as getter, as (even if quite unlikely), this *may* change during runtime... */
+PyDoc_STRVAR(app_translations_locales_doc, "All locales currently known by Blender (i.e. available as translations).");
+static PyObject *app_translations_locales_get(PyObject *UNUSED(self), void *UNUSED(userdata))
+{
+ PyObject *ret;
+ EnumPropertyItem *it, *items = BLF_RNA_lang_enum_properties();
+ int num_locales = 0, pos = 0;
+
+ if (items) {
+ /* This is not elegant, but simple! */
+ for (it = items; it->identifier; it++) {
+ if (it->value)
+ num_locales++;
+ }
+ }
+
+ ret = PyTuple_New(num_locales);
+
+ if (items) {
+ for (it = items; it->identifier; it++) {
+ if (it->value)
+ PyTuple_SET_ITEM(ret, pos++, PyUnicode_FromString(it->description));
+ }
+ }
+
+ return ret;
+}
+
+PyGetSetDef app_translations_getseters[] = {
+ /* {name, getter, setter, doc, userdata} */
+ {(char *)"locale", (getter)app_translations_locale_get, NULL, app_translations_locale_doc, NULL},
+ {(char *)"locales", (getter)app_translations_locales_get, NULL, app_translations_locales_doc, NULL},
+ {NULL}
+};
+
+/* pgettext helper. */
+static PyObject *_py_pgettext(PyObject *args, PyObject *kw, const char *(*_pgettext)(const char *, const char *))
+{
+ static const char *kwlist[] = {"msgid", "msgctxt", NULL};
+
+#ifdef WITH_INTERNATIONAL
+ char *msgid, *msgctxt = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw,
+ "s|z:bpy.app.translations.pgettext",
+ (char **)kwlist, &msgid, &msgctxt))
+ {
+ return NULL;
+ }
+
+ return PyUnicode_FromString((*_pgettext)(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT, msgid));
+#else
+ PyObject *msgid, *msgctxt;
+ (void)_pgettext;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw,
+ "O|O:bpy.app.translations.pgettext",
+ (char **)kwlist, &msgid, &msgctxt))
+ {
+ return NULL;
+ }
+
+ Py_INCREF(msgid);
+
+ return msgid;
+#endif
+}
+
+PyDoc_STRVAR(app_translations_pgettext_doc,
+".. method:: pgettext(msgid, msgctxt)\n"
+"\n"
+" Try to translate the given msgid (with optional msgctxt).\n"
+" NOTE: The (msgid, msgctxt) parameter orders has been switched compared to gettext function, to allow\n"
+" single-parameter calls (context then defaults to BLF_I18NCONTEXT_DEFAULT).\n"
+" NOTE: You should really rarely need to use this function in regular addon code, as all translation should be\n"
+" handled by Blender internal code. The only exception are string containing formatting (like \"File: %r\"),\n"
+" but you should rather use pgettext_iface/_tip in those cases!\n"
+" Note: Does nothing when Blender is built without internationalization support (hence always returns msgid).\n"
+"\n"
+" :arg msgid: The string to translate.\n"
+" :type msgid: string\n"
+" :arg msgctxt: The translation context.\n"
+" :type msgctxt: string or None\n"
+" :default msgctxt: BLF_I18NCONTEXT_DEFAULT value.\n"
+" :return: The translated string (or msgid if no translation was found).\n"
+"\n"
+);
+static PyObject *app_translations_pgettext(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ return _py_pgettext(args, kw, BLF_pgettext);
+}
+
+PyDoc_STRVAR(app_translations_pgettext_iface_doc,
+".. method:: pgettext_iface(msgid, msgctxt)\n"
+"\n"
+" Try to translate the given msgid (with optional msgctxt), if labels' translation is enabled.\n"
+" NOTE: See pgettext notes.\n"
+"\n"
+" :arg msgid: The string to translate.\n"
+" :type msgid: string\n"
+" :arg msgctxt: The translation context.\n"
+" :type msgctxt: string or None\n"
+" :default msgctxt: BLF_I18NCONTEXT_DEFAULT value.\n"
+" :return: The translated string (or msgid if no translation was found).\n"
+"\n"
+);
+static PyObject *app_translations_pgettext_iface(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ return _py_pgettext(args, kw, BLF_translate_do_iface);
+}
+
+PyDoc_STRVAR(app_translations_pgettext_tip_doc,
+".. method:: pgettext(msgid, msgctxt)\n"
+"\n"
+" Try to translate the given msgid (with optional msgctxt), if tooltips' translation is enabled.\n"
+" NOTE: See pgettext notes.\n"
+"\n"
+" :arg msgid: The string to translate.\n"
+" :type msgid: string\n"
+" :arg msgctxt: The translation context.\n"
+" :type msgctxt: string or None\n"
+" :default msgctxt: BLF_I18NCONTEXT_DEFAULT value.\n"
+" :return: The translated string (or msgid if no translation was found).\n"
+"\n"
+);
+static PyObject *app_translations_pgettext_tip(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ return _py_pgettext(args, kw, BLF_translate_do_tooltip);
+}
+
+PyDoc_STRVAR(app_translations_locale_explode_doc,
+".. method:: locale_explode(locale)\n"
+"\n"
+" Return all components and their combinations of the given ISO locale string.\n"
+"\n"
+" >>> bpy.app.translations.locale_explode(\"sr_RS@latin\")\n"
+" (\"sr\", \"RS\", \"latin\", \"sr_RS\", \"sr@latin\")\n"
+"\n"
+" For non-complete locales, missing elements will be None.\n"
+"\n"
+" :arg locale: The ISO locale string to explode.\n"
+" :type msgid: string\n"
+" :return: A tuple (language, country, variant, language_country, language@variant).\n"
+"\n"
+);
+static PyObject *app_translations_locale_explode(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ static const char *kwlist[] = {"locale", NULL};
+ const char *locale;
+ char *language, *country, *variant, *language_country, *language_variant;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "s:bpy.app.translations.locale_explode", (char **)kwlist, &locale)) {
+ return NULL;
+ }
+
+ BLF_locale_explode(locale, &language, &country, &variant, &language_country, &language_variant);
+
+ return Py_BuildValue("sssss", language, country, variant, language_country, language_variant);
+}
+
+PyMethodDef app_translations_methods[] = {
+ /* Can't use METH_KEYWORDS alone, see http://bugs.python.org/issue11587 */
+ {(char *)"register", (PyCFunction)app_translations_py_messages_register, METH_VARARGS | METH_KEYWORDS,
+ app_translations_py_messages_register_doc},
+ {(char *)"unregister", (PyCFunction)app_translations_py_messages_unregister, METH_VARARGS | METH_KEYWORDS,
+ app_translations_py_messages_unregister_doc},
+ {(char *)"pgettext", (PyCFunction)app_translations_pgettext, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+ app_translations_pgettext_doc},
+ {(char *)"pgettext_iface", (PyCFunction)app_translations_pgettext_iface, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+ app_translations_pgettext_iface_doc},
+ {(char *)"pgettext_tip", (PyCFunction)app_translations_pgettext_tip, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+ app_translations_pgettext_tip_doc},
+ {(char *)"locale_explode", (PyCFunction)app_translations_locale_explode, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+ app_translations_locale_explode_doc},
+ {NULL}
+};
+
+static PyObject *app_translations_new(PyTypeObject *type, PyObject *UNUSED(args), PyObject *UNUSED(kw))
+{
+/* printf("%s (%p)\n", __func__, _translations); */
+
+ if (!_translations) {
+ _translations = (BlenderAppTranslations *)type->tp_alloc(type, 0);
+ if (_translations) {
+ PyObject *py_ctxts;
+ BLF_i18n_contexts_descriptor *ctxt;
+
+ _translations->contexts = app_translations_contexts_make();
+
+ py_ctxts = PyDict_New();
+ for (ctxt = _contexts; ctxt->c_id; ctxt++) {
+ PyObject *val = PyUnicode_FromString(ctxt->py_id);
+ PyDict_SetItemString(py_ctxts, ctxt->c_id, val);
+ Py_DECREF(val);
+ }
+ _translations->contexts_C_to_py = PyDictProxy_New(py_ctxts);
+ Py_DECREF(py_ctxts); /* The actual dict is only owned by its proxy */
+
+ _translations->py_messages = PyDict_New();
+ }
+ }
+
+ return (PyObject *)_translations;
+}
+
+static void app_translations_free(void *obj)
+{
+ PyObject_Del(obj);
+#ifdef WITH_INTERNATIONAL
+ _clear_translations_cache();
+#endif
+}
+
+PyDoc_STRVAR(app_translations_doc,
+" This object contains some data/methods regarding internationalization in Blender, and allows every py script\n"
+" to feature translations for its own UI messages.\n"
+"\n"
+" WARNING: Most of this object should only be useful if you actually manipulate i18n stuff from Python.\n"
+" If you are a regular addon, you should only bother about :contexts: and :context_sep: members, and the \n"
+" :register:/:unregister: functions!"
+"\n"
+" To add translations to your python script, you must define a dictionary formatted like that:\n"
+" {locale: {msg_key: msg_translation, ...}, ...}\n"
+" where:\n"
+" locale is either a lang iso code (e.g. 'fr'), a lang+country code (e.g. 'pt_BR'),\n"
+" a lang+variant code (e.g. 'sr@latin'), or a full code (e.g. 'uz_UZ@cyrilic').\n"
+" msg_key is a tuple (context, org message) - use, as much as possible, the predefined :contexts:.\n"
+" msg_translation is the translated message in given language!"
+" Then, call bpy.app.translations.register(__name__, your_dict) in your register() function, and \n"
+" bpy.app.translations.unregister(__name__) in your unregister() one.\n"
+"\n"
+" bl_i18n_utils module has several functions to help you collect strings to translate, and generate the needed\n"
+" python code (the translation dictionary), as well as optional intermediary po files if you want some...\n"
+" See its documentation for more details.\n"
+"\n"
+);
+static PyTypeObject BlenderAppTranslationsType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /* tp_name */
+ (char *)"bpy.app._translations_type",
+ /* tp_basicsize */
+ sizeof(BlenderAppTranslations),
+ 0, /* tp_itemsize */
+ /* methods */
+ /* No destructor, this is a singleton! */
+ NULL, /* tp_dealloc */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
+ NULL, /* tp_repr */
+
+ /* Method suites for standard classes */
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ app_translations_doc, /* char *tp_doc; Documentation string */
+
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ app_translations_methods, /* struct PyMethodDef *tp_methods; */
+ app_translations_members, /* struct PyMemberDef *tp_members; */
+ app_translations_getseters, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ /* newfunc tp_new; */
+ (newfunc)app_translations_new,
+ /* Low-level free-memory routine */
+ app_translations_free, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
+
+PyObject *BPY_app_translations_struct(void)
+{
+ PyObject *ret;
+
+ /* Let's finalize our contexts structseq definition! */
+ {
+ BLF_i18n_contexts_descriptor *ctxt;
+ PyStructSequence_Field *desc;
+
+ /* We really populate the contexts' fields here! */
+ for (ctxt = _contexts, desc = app_translations_contexts_desc.fields; ctxt->c_id; ctxt++, desc++) {
+ desc->name = (char *)ctxt->py_id;
+ desc->doc = NULL;
+ }
+ desc->name = desc->doc = NULL; /* End sentinel! */
+
+ PyStructSequence_InitType(&BlenderAppTranslationsContextsType, &app_translations_contexts_desc);
+ }
+
+ if (PyType_Ready(&BlenderAppTranslationsType) < 0)
+ return NULL;
+
+ ret = PyObject_CallObject((PyObject *)&BlenderAppTranslationsType, NULL);
+
+ /* prevent user from creating new instances */
+ BlenderAppTranslationsType.tp_new = NULL;
+ /* without this we can't do set(sys.modules) [#29635] */
+ BlenderAppTranslationsType.tp_hash = (hashfunc)_Py_HashPointer;
+
+ return ret;
+}
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.cpp b/source/blender/python/intern/bpy_app_translations.h
index 58b94df6221..704307574d0 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.cpp
+++ b/source/blender/python/intern/bpy_app_translations.h
@@ -15,24 +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.
*
- * 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.
+ * Contributor(s): Bastien Montagne
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file gameengine/Physics/common/PHY_IPhysicsController.cpp
- * \ingroup phys
+/** \file blender/python/intern/bpy_app_translations.h
+ * \ingroup pythonintern
*/
-#include "PHY_IPhysicsController.h"
-
-PHY_IPhysicsController::~PHY_IPhysicsController()
-{
+#ifndef __BPY_APP_TRANSLATIONS_H__
+#define __BPY_APP_TRANSLATIONS_H__
-}
+PyObject *BPY_app_translations_struct(void);
+#endif /* __BPY_APP_TRANSLATIONS_H__ */
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 9a79616c23b..c49794ad37a 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -122,7 +122,7 @@ static void bpy_pydriver_update_dict(const float evaltime)
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
- int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */
+ bool use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -175,7 +175,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
PyObject *expr_code;
PyGILState_STATE gilstate;
- int use_gil;
+ bool use_gil;
DriverVar *dvar;
double result = 0.0; /* default return */
@@ -193,7 +193,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
return 0.0f;
}
- use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
if (use_gil)
gilstate = PyGILState_Ensure();
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index cdecf64c93c..90199a403dc 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -39,11 +39,21 @@
#include "MEM_guardedalloc.h"
+#include "BLI_path_util.h"
+#include "BLI_fileops.h"
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_utildefines.h"
+#include "BLI_threads.h"
+
#include "RNA_types.h"
#include "bpy.h"
#include "gpu.h"
#include "bpy_rna.h"
+#include "bpy_path.h"
#include "bpy_util.h"
#include "bpy_traceback.h"
#include "bpy_intern_string.h"
@@ -51,15 +61,6 @@
#include "DNA_space_types.h"
#include "DNA_text_types.h"
-#include "BLI_path_util.h"
-#include "BLI_fileops.h"
-#include "BLI_listbase.h"
-#include "BLI_math_base.h"
-#include "BLI_string.h"
-#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
-#include "BLI_threads.h"
-
#include "BKE_context.h"
#include "BKE_text.h"
#include "BKE_main.h"
@@ -165,7 +166,7 @@ void BPY_text_free_code(Text *text)
{
if (text->compiled) {
PyGILState_STATE gilstate;
- int use_gil = !PYC_INTERPRETER_ACTIVE;
+ bool use_gil = !PYC_INTERPRETER_ACTIVE;
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -212,6 +213,7 @@ static struct _inittab bpy_internal_modules[] = {
{(char *)"mathutils", PyInit_mathutils},
// {(char *)"mathutils.geometry", PyInit_mathutils_geometry},
// {(char *)"mathutils.noise", PyInit_mathutils_noise},
+ {(char *)"_bpy_path", BPyInit__bpy_path},
{(char *)"bgl", BPyInit_bgl},
{(char *)"blf", BPyInit_blf},
{(char *)"bmesh", BPyInit_bmesh},
@@ -269,7 +271,8 @@ void BPY_python_start(int argc, const char **argv)
Py_Initialize();
/* THIS IS BAD: see http://bugs.python.org/issue16129 */
-#if 1
+ /* this clobbers the stdout on exit (no 'MEM_printmemlist_stats') */
+#if 0
/* until python provides a reliable way to set the env var */
PyRun_SimpleString("import sys, io\n"
"sys.__backup_stdio__ = sys.__stdout__, sys.__stderr__\n" /* else we loose the FD's [#32720] */
@@ -307,11 +310,33 @@ void BPY_python_start(int argc, const char **argv)
(void)argv;
/* must run before python initializes */
- PyImport_ExtendInittab(bpy_internal_modules);
+ /* broken in py3.3, load explicitly below */
+ // PyImport_ExtendInittab(bpy_internal_modules);
#endif
bpy_intern_string_init();
+
+#ifdef WITH_PYTHON_MODULE
+ {
+ /* Manually load all modules */
+ struct _inittab *inittab_item;
+ PyObject *sys_modules = PyImport_GetModuleDict();
+
+ for (inittab_item = bpy_internal_modules; inittab_item->name; inittab_item++) {
+ PyObject *mod = inittab_item->initfunc();
+ if (mod) {
+ PyDict_SetItemString(sys_modules, inittab_item->name, mod);
+ }
+ else {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ // Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */
+ }
+ }
+#endif
+
/* bpy.* and lets us import it */
BPy_init_modules();
@@ -375,8 +400,8 @@ static void python_script_error_jump_text(struct Text *text)
python_script_error_jump(text->id.name + 2, &lineno, &offset);
if (lineno != -1) {
/* select the line with the error */
- txt_move_to(text, lineno - 1, INT_MAX, FALSE);
- txt_move_to(text, lineno - 1, offset, TRUE);
+ txt_move_to(text, lineno - 1, INT_MAX, false);
+ txt_move_to(text, lineno - 1, offset, true);
}
}
@@ -394,7 +419,7 @@ typedef struct {
#endif
static int python_script_exec(bContext *C, const char *fn, struct Text *text,
- struct ReportList *reports, const short do_jump)
+ struct ReportList *reports, const bool do_jump)
{
Main *bmain_old = CTX_data_main(C);
PyObject *main_mod = NULL;
@@ -511,11 +536,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text,
/* Can run a file or text block */
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
{
- return python_script_exec(C, filepath, NULL, reports, FALSE);
+ return python_script_exec(C, filepath, NULL, reports, false);
}
-int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump)
+int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump)
{
return python_script_exec(C, NULL, text, reports, do_jump);
}
@@ -716,12 +741,12 @@ void BPY_modules_load_user(bContext *C)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
{
PyGILState_STATE gilstate;
- int use_gil = !PYC_INTERPRETER_ACTIVE;
+ bool use_gil = !PYC_INTERPRETER_ACTIVE;
PyObject *pyctx;
PyObject *item;
PointerRNA *ptr = NULL;
- int done = FALSE;
+ bool done = false;
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -740,7 +765,8 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
//result->ptr = ((BPy_StructRNA *)item)->ptr;
CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data);
- done = TRUE;
+ CTX_data_type_set(result, CTX_DATA_TYPE_POINTER);
+ done = true;
}
else if (PySequence_Check(item)) {
PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion");
@@ -770,12 +796,12 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
}
Py_DECREF(seq_fast);
-
- done = TRUE;
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ done = true;
}
}
- if (done == 0) {
+ if (done == false) {
if (item) printf("PyContext '%s' not a valid type\n", member);
else printf("PyContext '%s' not found\n", member);
}
@@ -817,7 +843,7 @@ typedef struct {
} dealloc_obj;
/* call once __file__ is set */
-void bpy_module_delay_init(PyObject *bpy_proxy)
+static void bpy_module_delay_init(PyObject *bpy_proxy)
{
const int argc = 1;
const char *argv[2];
@@ -856,6 +882,9 @@ static void dealloc_obj_dealloc(PyObject *self)
}
PyMODINIT_FUNC
+PyInit_bpy(void);
+
+PyMODINIT_FUNC
PyInit_bpy(void)
{
PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def);
@@ -899,3 +928,20 @@ static void bpy_module_free(void *UNUSED(mod))
}
#endif
+
+
+/* EVIL, define text.c functions here... */
+extern int text_check_identifier_unicode(const unsigned int ch);
+extern int text_check_identifier_nodigit_unicode(const unsigned int ch);
+extern int text_check_identifier(const char ch);
+extern int text_check_identifier_nodigit(const char ch);
+
+int text_check_identifier_unicode(const unsigned int ch)
+{
+ return (ch < 255 && text_check_identifier((char)ch)) || Py_UNICODE_ISALNUM(ch);
+}
+
+int text_check_identifier_nodigit_unicode(const unsigned int ch)
+{
+ return (ch < 255 && text_check_identifier_nodigit((char)ch)) || Py_UNICODE_ISALPHA(ch);
+}
diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c
index 13d8cedf907..d1d33a01e55 100644
--- a/source/blender/python/intern/bpy_interface_atexit.c
+++ b/source/blender/python/intern/bpy_interface_atexit.c
@@ -31,13 +31,13 @@
#include <Python.h>
+#include "BLI_utildefines.h"
+
#include "bpy_util.h"
#include "bpy.h" /* own include */
#include "WM_api.h"
-#include "BLI_utildefines.h"
-
static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw))
{
/* close down enough of blender at least not to crash */
diff --git a/source/blender/python/intern/bpy_intern_string.c b/source/blender/python/intern/bpy_intern_string.c
index 70ea57bb33f..294f230ce99 100644
--- a/source/blender/python/intern/bpy_intern_string.c
+++ b/source/blender/python/intern/bpy_intern_string.c
@@ -35,6 +35,7 @@
PyObject *bpy_intern_str_register;
PyObject *bpy_intern_str_unregister;
PyObject *bpy_intern_str_bl_rna;
+PyObject *bpy_intern_str_bl_property;
PyObject *bpy_intern_str_order;
PyObject *bpy_intern_str_attr;
PyObject *bpy_intern_str___slots__;
@@ -46,6 +47,7 @@ void bpy_intern_string_init(void)
bpy_intern_str_register = PyUnicode_FromString("register");
bpy_intern_str_unregister = PyUnicode_FromString("unregister");
bpy_intern_str_bl_rna = PyUnicode_FromString("bl_rna");
+ bpy_intern_str_bl_property = PyUnicode_FromString("bl_property");
bpy_intern_str_order = PyUnicode_FromString("order");
bpy_intern_str_attr = PyUnicode_FromString("attr");
bpy_intern_str___slots__ = PyUnicode_FromString("__slots__");
@@ -58,6 +60,7 @@ void bpy_intern_string_exit(void)
Py_DECREF(bpy_intern_str_register);
Py_DECREF(bpy_intern_str_unregister);
Py_DECREF(bpy_intern_str_bl_rna);
+ Py_DECREF(bpy_intern_str_bl_property);
Py_DECREF(bpy_intern_str_order);
Py_DECREF(bpy_intern_str_attr);
Py_DECREF(bpy_intern_str___slots__);
diff --git a/source/blender/python/intern/bpy_intern_string.h b/source/blender/python/intern/bpy_intern_string.h
index 0b7ca2cd47b..2e0d18d8b7f 100644
--- a/source/blender/python/intern/bpy_intern_string.h
+++ b/source/blender/python/intern/bpy_intern_string.h
@@ -30,6 +30,7 @@ void bpy_intern_string_exit(void);
extern PyObject *bpy_intern_str_register;
extern PyObject *bpy_intern_str_unregister;
extern PyObject *bpy_intern_str_bl_rna;
+extern PyObject *bpy_intern_str_bl_property;
extern PyObject *bpy_intern_str_order;
extern PyObject *bpy_intern_str_attr;
extern PyObject *bpy_intern_str___slots__;
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index 7571fe0f75e..ec6322a1a11 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -244,7 +244,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports);
if (self->blo_handle == NULL) {
- if (BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) {
+ if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) {
PyErr_Format(PyExc_IOError,
"load: %s failed to open blend file",
self->abspath);
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 55ef217e781..ee885684e03 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -35,6 +35,9 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+
#include "BPY_extern.h"
#include "bpy_operator.h"
#include "bpy_operator_wrap.h"
@@ -42,9 +45,6 @@
#include "bpy_util.h"
#include "../generic/bpy_internal_import.h"
-#include "BLI_utildefines.h"
-#include "BLI_string.h"
-
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -85,7 +85,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str))
return NULL;
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -147,7 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
/* note that context is an int, python does the conversion in this case */
int context = WM_OP_EXEC_DEFAULT;
- int is_undo = FALSE;
+ int is_undo = false;
/* XXX Todo, work out a better solution for passing on context,
* could make a tuple from self and pack the name and Context into it... */
@@ -164,7 +164,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -209,7 +209,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
CTX_py_dict_set(C, (void *)context_dict);
Py_XINCREF(context_dict); /* so we done loose it */
- if (WM_operator_poll_context((bContext *)C, ot, context) == FALSE) {
+ if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
const char *msg = CTX_wm_operator_poll_msg_get(C);
PyErr_Format(PyExc_RuntimeError,
"Operator bpy.ops.%.200s.poll() %.200s",
@@ -248,7 +248,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
}
#endif
- error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE);
+ error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);
/* operator output is nice to have in the terminal/console too */
if (reports->list.first) {
@@ -328,7 +328,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args))
return NULL;
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -392,7 +392,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument");
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname);
return NULL;
@@ -408,7 +408,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = TRUE;
+ pyrna->freeptr = true;
#endif
return (PyObject *)pyrna;
}
@@ -425,7 +425,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument");
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname);
return NULL;
@@ -444,7 +444,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = TRUE;
+ pyrna->freeptr = true;
#endif
op->ptr = &pyrna->ptr;
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 1caec294aa0..9d92ff51213 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -29,10 +29,8 @@
* functionality.
*/
-
#include <Python.h>
-#include "bpy_operator_wrap.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -42,6 +40,8 @@
#include "RNA_define.h"
#include "bpy_rna.h"
+#include "bpy_intern_string.h"
+#include "bpy_operator_wrap.h" /* own include */
static void operator_properties_init(wmOperatorType *ot)
{
@@ -57,6 +57,66 @@ static void operator_properties_init(wmOperatorType *ot)
PyErr_Print(); /* failed to register operator props */
PyErr_Clear();
}
+
+ /* set the default property: ot->prop */
+ {
+ /* picky developers will notice that 'bl_property' won't work with inheritance
+ * get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */
+ PyTypeObject *py_class = ot->ext.data;
+ PyObject *py_class_dict = py_class->tp_dict;
+ PyObject *bl_property = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_property);
+ const char *prop_id;
+ bool prop_raise_error;
+
+ if (bl_property) {
+ if (PyUnicode_Check(bl_property)) {
+ /* since the property is explicitly given, raise an error if its not found */
+ prop_id = _PyUnicode_AsString(bl_property);
+ prop_raise_error = true;
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.bl_property should be a string, not %.200s",
+ ot->idname, Py_TYPE(bl_property)->tp_name);
+
+ /* this could be done cleaner, for now its OK */
+ PyErr_Print();
+ PyErr_Clear();
+
+ prop_id = NULL;
+ prop_raise_error = false;
+ }
+ }
+ else {
+ /* fallback to hard-coded string (pre 2.66, could be deprecated) */
+ prop_id = "type";
+ prop_raise_error = false;
+ }
+
+ if (prop_id) {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
+ prop = RNA_struct_find_property(&ptr, prop_id);
+ if (prop) {
+ ot->prop = prop;
+ }
+ else {
+ if (prop_raise_error) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.bl_property '%.200s' not found",
+ ot->idname, prop_id);
+
+ /* this could be done cleaner, for now its OK */
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+ }
+ }
+ /* end 'ot->prop' assignment */
+
}
void operator_wrapper(wmOperatorType *ot, void *userdata)
@@ -68,18 +128,6 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
ot->srna = srna; /* restore */
operator_properties_init(ot);
-
- /* XXX - not nice, set the first enum as searchable, should have a way for python to set */
- {
- PointerRNA ptr;
- PropertyRNA *prop;
-
- RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
- prop = RNA_struct_find_property(&ptr, "type");
- if (prop) {
- ot->prop = prop;
- }
- }
}
void macro_wrapper(wmOperatorType *ot, void *userdata)
@@ -112,7 +160,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &opname))
return NULL;
- if (WM_operatortype_find(opname, TRUE) == NULL) {
+ if (WM_operatortype_find(opname, true) == NULL) {
PyErr_Format(PyExc_ValueError,
"Macro Define: '%s' is not a valid operator id",
opname);
@@ -123,7 +171,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
srna = srna_from_self(macro, "Macro Define:");
macroname = RNA_struct_identifier(srna);
- ot = WM_operatortype_find(macroname, TRUE);
+ ot = WM_operatortype_find(macroname, true);
if (!ot) {
PyErr_Format(PyExc_ValueError,
diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c
new file mode 100644
index 00000000000..1d554b60bbe
--- /dev/null
+++ b/source/blender/python/intern/bpy_path.c
@@ -0,0 +1,67 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_path.c
+ * \ingroup pythonintern
+ *
+ * This file defines '_bpy_path' module, Some 'C' funtionality used by 'bpy.path'
+ */
+
+#include <Python.h>
+
+#include "BLI_utildefines.h"
+
+#include "bpy_path.h"
+
+#include "../generic/py_capi_utils.h"
+
+/* #include "IMB_imbuf_types.h" */
+extern const char *imb_ext_image[];
+extern const char *imb_ext_movie[];
+extern const char *imb_ext_audio[];
+
+/*----------------------------MODULE INIT-------------------------*/
+static struct PyModuleDef _bpy_path_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "_bpy_path", /* m_name */
+ NULL, /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyObject *BPyInit__bpy_path(void)
+{
+ PyObject *submodule;
+
+ submodule = PyModule_Create(&_bpy_path_module_def);
+
+ PyModule_AddObject(submodule, "extensions_image", PyC_FrozenSetFromStrings(imb_ext_image));
+ PyModule_AddObject(submodule, "extensions_movie", PyC_FrozenSetFromStrings(imb_ext_movie));
+ PyModule_AddObject(submodule, "extensions_audio", PyC_FrozenSetFromStrings(imb_ext_audio));
+
+ return submodule;
+}
+
diff --git a/source/blender/python/intern/bpy_path.h b/source/blender/python/intern/bpy_path.h
new file mode 100644
index 00000000000..a0f31202264
--- /dev/null
+++ b/source/blender/python/intern/bpy_path.h
@@ -0,0 +1,33 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_path.h
+ * \ingroup pythonintern
+ */
+
+
+#ifndef __BPY_PATH_H__
+#define __BPY_PATH_H__
+
+PyObject *BPyInit__bpy_path(void);
+
+#endif
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index bd033736865..830c2c8de3a 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -33,12 +33,12 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+
#include "bpy_props.h"
#include "bpy_rna.h"
#include "bpy_util.h"
-#include "BLI_utildefines.h"
-
#include "BKE_idprop.h"
#include "RNA_access.h"
@@ -50,9 +50,11 @@
#include "../generic/py_capi_utils.h"
/* initial definition of callback slots we'll probably have more then 1 */
-#define BPY_DATA_CB_SLOT_SIZE 1
+#define BPY_DATA_CB_SLOT_SIZE 3
#define BPY_DATA_CB_SLOT_UPDATE 0
+#define BPY_DATA_CB_SLOT_GET 1
+#define BPY_DATA_CB_SLOT_SET 2
extern BPy_StructRNA *bpy_context_module;
@@ -72,13 +74,15 @@ static EnumPropertyItem property_flag_enum_items[] = {
{0, NULL, 0, NULL, NULL}};
/* subtypes */
+/* XXX Keep in sync with rna_rna.c's property_subtype_items ???
+ * Currently it is not...
+ */
static EnumPropertyItem property_subtype_string_items[] = {
{PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
{PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
{PROP_FILENAME, "FILE_NAME", 0, "Filename", ""},
{PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""},
- {PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
- {PROP_PASSWORD, "PASSWORD", 0, "Password", 0},
+ {PROP_PASSWORD, "PASSWORD", 0, "Password", "A string that is displayed hidden ('********')"},
{PROP_NONE, "NONE", 0, "None", ""},
{0, NULL, 0, NULL, NULL}};
@@ -197,7 +201,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc
BLI_assert(py_data != NULL);
if (!is_write_ok) {
- pyrna_write_set(TRUE);
+ pyrna_write_set(true);
}
bpy_context_set(C, &gilstate);
@@ -230,25 +234,1280 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc
bpy_context_clear(C, &gilstate);
if (!is_write_ok) {
- pyrna_write_set(FALSE);
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = false;
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = false;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = false;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = false;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyBool_Type, false, "BoolVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = 0;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyLong_Type, false, "IntVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ float value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+ else {
+ value = PyFloat_AsDouble(ret);
+
+ if (value == -1.0f && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
}
+
+ return value;
}
-static int bpy_prop_callback_check(PyObject *py_func, int argcount)
+static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0.0f;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0.0f;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyFloat_Type, false, "FloatVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value[0] = '\0';
+ }
+ else if (!PyUnicode_Check(ret)) {
+ PyErr_Format(PyExc_TypeError,
+ "return value must be a string, not %.200s",
+ Py_TYPE(ret)->tp_name);
+ printf_func_error(py_func);
+ value[0] = '\0';
+ Py_DECREF(ret);
+ }
+ else {
+ Py_ssize_t length;
+ const char *buffer = _PyUnicode_AsStringAndSize(ret, &length);
+ memcpy(value, buffer, length + 1);
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int length;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ length = 0;
+ }
+ else if (!PyUnicode_Check(ret)) {
+ PyErr_Format(PyExc_TypeError,
+ "return value must be a string, not %.200s",
+ Py_TYPE(ret)->tp_name);
+ printf_func_error(py_func);
+ length = 0;
+ Py_DECREF(ret);
+ }
+ else {
+ Py_ssize_t length_ssize_t = 0;
+ _PyUnicode_AsStringAndSize(ret, &length_ssize_t);
+ length = length_ssize_t;
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return length;
+}
+
+static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ PyObject *py_value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_value = PyUnicode_FromString(value);
+ if (!py_value) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be a string");
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_value);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = RNA_property_enum_get_default(ptr, prop);
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = RNA_property_enum_get_default(ptr, prop);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+/* utility function we need for parsing int's in an if statement */
+static int py_long_as_int(PyObject *py_long, int *r_int)
+{
+ if (PyLong_CheckExact(py_long)) {
+ *r_int = (int)PyLong_AS_LONG(py_long);
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+#if 0
+/* copies orig to buf, then sets orig to buf, returns copy length */
+static size_t strswapbufcpy(char *buf, const char **orig)
+{
+ const char *src = *orig;
+ char *dst = buf;
+ size_t i = 0;
+ *orig = buf;
+ while ((*dst = *src)) { dst++; src++; i++; }
+ return i + 1; /* include '\0' */
+}
+#endif
+
+static int icon_id_from_name(const char *name)
+{
+ EnumPropertyItem *item;
+ int id;
+
+ if (name[0]) {
+ for (item = icon_items, id = 0; item->identifier; item++, id++)
+ if (strcmp(item->name, name) == 0)
+ return item->value;
+ }
+
+ return 0;
+}
+
+static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
+{
+ EnumPropertyItem *items;
+ PyObject *item;
+ const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
+ Py_ssize_t totbuf = 0;
+ int i;
+ short def_used = 0;
+ const char *def_cmp = NULL;
+
+ if (is_enum_flag) {
+ if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
+ PyErr_SetString(PyExc_TypeError,
+ "EnumProperty(...): maximum "
+ STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
+ " members for a ENUM_FLAG type property");
+ return NULL;
+ }
+ if (def && !PySet_Check(def)) {
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(...): default option must be a 'set' "
+ "type when ENUM_FLAG is enabled, not a '%.200s'",
+ Py_TYPE(def)->tp_name);
+ return NULL;
+ }
+ }
+ else {
+ if (def) {
+ def_cmp = _PyUnicode_AsString(def);
+ if (def_cmp == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(...): default option must be a 'str' "
+ "type when ENUM_FLAG is disabled, not a '%.200s'",
+ Py_TYPE(def)->tp_name);
+ return NULL;
+ }
+ }
+ }
+
+ /* blank value */
+ *defvalue = 0;
+
+ items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
+
+ for (i = 0; i < seq_len; i++) {
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ const char *tmp_icon = NULL;
+ Py_ssize_t item_size;
+ Py_ssize_t id_str_size;
+ Py_ssize_t name_str_size;
+ Py_ssize_t desc_str_size;
+
+ item = PySequence_Fast_GET_ITEM(seq_fast, i);
+
+ if ((PyTuple_CheckExact(item)) &&
+ (item_size = PyTuple_GET_SIZE(item)) &&
+ (item_size >= 3 && item_size <= 5) &&
+ (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
+ (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
+ (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
+ /* TODO, number isn't ensured to be unique from the script author */
+ (item_size != 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1) &&
+ (item_size != 5 || ((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) {
+ if (item_size < 4) {
+ tmp.value = 1 << i;
+ }
+
+ if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
+ *defvalue |= tmp.value;
+ def_used++;
+ }
+ }
+ else {
+ if (item_size < 4) {
+ tmp.value = i;
+ }
+
+ if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
+ *defvalue = tmp.value;
+ def_used++; /* only ever 1 */
+ }
+ }
+
+ if (tmp_icon)
+ tmp.icon = icon_id_from_name(tmp_icon);
+
+ items[i] = tmp;
+
+ /* calculate combine string length */
+ totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
+ }
+ else {
+ MEM_freeN(items);
+ PyErr_SetString(PyExc_TypeError,
+ "EnumProperty(...): expected a tuple containing "
+ "(identifier, name, description) and optionally an "
+ "icon name and unique number");
+ return NULL;
+ }
+
+ }
+
+ if (is_enum_flag) {
+ /* strict check that all set members were used */
+ if (def && def_used != PySet_GET_SIZE(def)) {
+ MEM_freeN(items);
+
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(..., default={...}): set has %d unused member(s)",
+ PySet_GET_SIZE(def) - def_used);
+ return NULL;
+ }
+ }
+ else {
+ if (def && def_used == 0) {
+ MEM_freeN(items);
+
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(..., default=\'%s\'): not found in enum members",
+ def_cmp);
+ return NULL;
+ }
+ }
+
+ /* disabled duplicating strings because the array can still be freed and
+ * the strings from it referenced, for now we can't support dynamically
+ * created strings from python. */
+#if 0
+ /* this would all work perfectly _but_ the python strings may be freed
+ * immediately after use, so we need to duplicate them, ugh.
+ * annoying because it works most of the time without this. */
+ {
+ EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
+ "enum_items_from_py2");
+ EnumPropertyItem *items_ptr = items_dup;
+ char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
+ memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
+ for (i = 0; i < seq_len; i++, items_ptr++) {
+ buf += strswapbufcpy(buf, &items_ptr->identifier);
+ buf += strswapbufcpy(buf, &items_ptr->name);
+ buf += strswapbufcpy(buf, &items_ptr->description);
+ }
+ MEM_freeN(items);
+ items = items_dup;
+ }
+ /* end string duplication */
+#endif
+
+ return items;
+}
+
+static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
+{
+ PyGILState_STATE gilstate;
+
+ PyObject *py_func = RNA_property_enum_py_data_get(prop);
+ PyObject *self = NULL;
+ PyObject *args;
+ PyObject *items; /* returned from the function call */
+
+ EnumPropertyItem *eitems = NULL;
+ int err = 0;
+
+ bpy_context_set(C, &gilstate);
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ /* now get the context */
+ PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
+ Py_INCREF(bpy_context_module);
+
+ items = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (items == NULL) {
+ err = -1;
+ }
+ else {
+ PyObject *items_fast;
+ int defvalue_dummy = 0;
+
+ if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
+ "return value from the callback was not a sequence")))
+ {
+ err = -1;
+ }
+ else {
+ eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy,
+ (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
+
+ Py_DECREF(items_fast);
+
+ if (!eitems) {
+ err = -1;
+ }
+ }
+
+ Py_DECREF(items);
+ }
+
+ if (err != -1) { /* worked */
+ *free = 1;
+ }
+ else {
+ printf_func_error(py_func);
+
+ eitems = DummyRNA_NULL_items;
+ }
+
+
+ bpy_context_clear(C, &gilstate);
+ return eitems;
+}
+
+static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
{
if (py_func && py_func != Py_None) {
if (!PyFunction_Check(py_func)) {
PyErr_Format(PyExc_TypeError,
- "update keyword: expected a function type, not a %.200s",
- Py_TYPE(py_func)->tp_name);
+ "%s keyword: expected a function type, not a %.200s",
+ keyword, Py_TYPE(py_func)->tp_name);
return -1;
}
else {
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
if (f_code->co_argcount != argcount) {
PyErr_Format(PyExc_TypeError,
- "update keyword: expected a function taking %d arguments, not %d",
- argcount, f_code->co_argcount);
+ "%s keyword: expected a function taking %d arguments, not %d",
+ keyword, argcount, f_code->co_argcount);
return -1;
}
}
@@ -257,32 +1516,215 @@ static int bpy_prop_callback_check(PyObject *py_func, int argcount)
return 0;
}
+static PyObject **bpy_prop_py_data_get(struct PropertyRNA *prop)
+{
+ PyObject **py_data = RNA_property_py_data_get(prop);
+ if (!py_data) {
+ py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
+ RNA_def_py_data(prop, py_data);
+ }
+ return py_data;
+}
-static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb)
+static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *update_cb)
{
/* assume this is already checked for type and arg length */
if (update_cb && update_cb != Py_None) {
- PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb;
- RNA_def_py_data(prop, py_data);
RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
}
+}
- return 0;
+static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ BooleanPropertyGetFunc rna_get_cb = NULL;
+ BooleanPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_boolean_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_boolean_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_boolean_funcs_runtime(prop, rna_get_cb, rna_set_cb);
}
-/* utility function we need for parsing int's in an if statement */
-static int py_long_as_int(PyObject *py_long, int *r_int)
+static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
{
- if (PyLong_CheckExact(py_long)) {
- *r_int = (int)PyLong_AS_LONG(py_long);
- return 0;
+ BooleanArrayPropertyGetFunc rna_get_cb = NULL;
+ BooleanArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_boolean_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
}
- else {
- return -1;
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_boolean_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_cb, rna_set_cb);
+}
+
+static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ IntPropertyGetFunc rna_get_cb = NULL;
+ IntPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_int_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_int_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_int_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ IntArrayPropertyGetFunc rna_get_cb = NULL;
+ IntArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_int_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_int_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
}
+
+ RNA_def_property_int_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ FloatPropertyGetFunc rna_get_cb = NULL;
+ FloatPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_float_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_float_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_float_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ FloatArrayPropertyGetFunc rna_get_cb = NULL;
+ FloatArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_float_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_float_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_float_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ StringPropertyGetFunc rna_get_cb = NULL;
+ StringPropertyLengthFunc rna_length_cb = NULL;
+ StringPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_string_get_cb;
+ rna_length_cb = bpy_prop_string_length_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_string_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_string_funcs_runtime(prop, rna_get_cb, rna_length_cb, rna_set_cb);
+}
+
+static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb, PyObject *itemf_cb)
+{
+ EnumPropertyGetFunc rna_get_cb = NULL;
+ EnumPropertyItemFunc rna_itemf_cb = NULL;
+ EnumPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_enum_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_enum_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ if (itemf_cb && itemf_cb != Py_None) {
+ rna_itemf_cb = bpy_prop_enum_itemf_cb;
+ RNA_def_property_enum_py_data(prop, (void *)itemf_cb);
+
+ /* watch out!, if a user is tricky they can probably crash blender
+ * if they manage to free the callback, take care! */
+ /* Py_INCREF(itemf_cb); */
+ }
+
+ RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb);
}
/* this define runs at the start of each function and deals with
@@ -386,7 +1828,9 @@ PyDoc_STRVAR(BPy_BoolProperty_doc,
"default=False, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new boolean property definition.\n"
"\n"
@@ -406,7 +1850,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "options", "subtype", "update", NULL};
+ "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int def = 0;
@@ -416,20 +1860,28 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiO!sO:BoolProperty",
+ "s#|ssiO!sOOO:BoolProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -443,7 +1895,8 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_boolean(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -457,7 +1910,9 @@ PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector boolean property definition.\n"
"\n"
@@ -483,7 +1938,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "options", "subtype", "size", "update", NULL};
+ "options", "subtype", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int def[PYRNA_STACK_ARRAY] = {0};
@@ -495,13 +1950,15 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOO!siO:BoolVectorProperty",
+ "s#|ssOO!siOOO:BoolVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&PySet_Type, &pyopts, &pysubtype, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -515,10 +1972,16 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -534,7 +1997,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -550,7 +2014,9 @@ PyDoc_STRVAR(BPy_IntProperty_doc,
"step=1, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new int property definition.\n"
"\n"
@@ -571,7 +2037,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "options", "subtype", "update", NULL};
+ "step", "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0;
@@ -581,21 +2047,29 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiiiiiiO!sO:IntProperty",
+ "s#|ssiiiiiiO!sOOO:IntProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
&step, &PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -611,7 +2085,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_int(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -626,7 +2101,9 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector int property definition.\n"
"\n"
@@ -653,7 +2130,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "options", "subtype", "size", "update", NULL};
+ "step", "options", "subtype", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1;
@@ -666,15 +2143,17 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOiiiiiO!siO:IntVectorProperty",
+ "s#|ssOiiiiiO!siOOO:IntVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &PySet_Type, &pyopts,
&pysubtype, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -688,10 +2167,16 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -708,7 +2193,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_int_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -726,7 +2212,9 @@ PyDoc_STRVAR(BPy_FloatProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"unit='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new float property definition.\n"
"\n"
@@ -748,7 +2236,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "precision", "options", "subtype", "unit", "update", NULL};
+ "step", "precision", "options", "subtype",
+ "unit", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f;
@@ -761,15 +2250,17 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssffffffiO!ssO:FloatProperty",
+ "s#|ssffffffiO!ssOOO:FloatProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
&pyopts, &pysubtype, &pyunit,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -781,7 +2272,13 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -797,7 +2294,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_float(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -814,7 +2312,9 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector float property definition.\n"
"\n"
@@ -842,7 +2342,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "precision", "options", "subtype", "unit", "size", "update", NULL};
+ "step", "precision", "options", "subtype",
+ "unit", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3;
@@ -857,15 +2358,17 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOfffffiO!ssiO:FloatVectorProperty",
+ "s#|ssOfffffiO!ssiOOO:FloatVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
&pyopts, &pysubtype, &pyunit, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -884,10 +2387,16 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -904,7 +2413,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_float_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -917,7 +2427,9 @@ PyDoc_STRVAR(BPy_StringProperty_doc,
"maxlen=0, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new string property definition.\n"
"\n"
@@ -937,7 +2449,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "maxlen", "options", "subtype", "update", NULL};
+ "maxlen", "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "", *def = "";
int id_len;
int maxlen = 0;
@@ -947,20 +2459,28 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|sssiO!sO:StringProperty",
+ "s#|sssiO!sOOO:StringProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&maxlen, &PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -975,246 +2495,22 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_string(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
}
-#if 0
-/* copies orig to buf, then sets orig to buf, returns copy length */
-static size_t strswapbufcpy(char *buf, const char **orig)
-{
- const char *src = *orig;
- char *dst = buf;
- size_t i = 0;
- *orig = buf;
- while ((*dst = *src)) { dst++; src++; i++; }
- return i + 1; /* include '\0' */
-}
-#endif
-
-static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
-{
- EnumPropertyItem *items;
- PyObject *item;
- const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
- Py_ssize_t totbuf = 0;
- int i;
- short def_used = 0;
- const char *def_cmp = NULL;
-
- if (is_enum_flag) {
- if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
- PyErr_SetString(PyExc_TypeError,
- "EnumProperty(...): maximum "
- STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
- " members for a ENUM_FLAG type property");
- return NULL;
- }
- if (def && !PySet_Check(def)) {
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(...): default option must be a 'set' "
- "type when ENUM_FLAG is enabled, not a '%.200s'",
- Py_TYPE(def)->tp_name);
- return NULL;
- }
- }
- else {
- if (def) {
- def_cmp = _PyUnicode_AsString(def);
- if (def_cmp == NULL) {
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(...): default option must be a 'str' "
- "type when ENUM_FLAG is disabled, not a '%.200s'",
- Py_TYPE(def)->tp_name);
- return NULL;
- }
- }
- }
-
- /* blank value */
- *defvalue = 0;
-
- items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
-
- for (i = 0; i < seq_len; i++) {
- EnumPropertyItem tmp = {0, "", 0, "", ""};
- Py_ssize_t item_size;
- Py_ssize_t id_str_size;
- Py_ssize_t name_str_size;
- Py_ssize_t desc_str_size;
-
- item = PySequence_Fast_GET_ITEM(seq_fast, i);
-
- if ((PyTuple_CheckExact(item)) &&
- (item_size = PyTuple_GET_SIZE(item)) &&
- (item_size == 3 || item_size == 4) &&
- (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
- (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
- (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
- /* TODO, number isn't ensured to be unique from the script author */
- (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1))
- {
- if (is_enum_flag) {
- if (item_size < 4) {
- tmp.value = 1 << i;
- }
-
- if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
- *defvalue |= tmp.value;
- def_used++;
- }
- }
- else {
- if (item_size < 4) {
- tmp.value = i;
- }
-
- if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
- *defvalue = tmp.value;
- def_used++; /* only ever 1 */
- }
- }
-
- items[i] = tmp;
-
- /* calculate combine string length */
- totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
- }
- else {
- MEM_freeN(items);
- PyErr_SetString(PyExc_TypeError,
- "EnumProperty(...): expected a tuple containing "
- "(identifier, name, description) and optionally a "
- "unique number");
- return NULL;
- }
-
- }
-
- if (is_enum_flag) {
- /* strict check that all set members were used */
- if (def && def_used != PySet_GET_SIZE(def)) {
- MEM_freeN(items);
-
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(..., default={...}): set has %d unused member(s)",
- PySet_GET_SIZE(def) - def_used);
- return NULL;
- }
- }
- else {
- if (def && def_used == 0) {
- MEM_freeN(items);
-
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(..., default=\'%s\'): not found in enum members",
- def_cmp);
- return NULL;
- }
- }
-
- /* disabled duplicating strings because the array can still be freed and
- * the strings from it referenced, for now we can't support dynamically
- * created strings from python. */
-#if 0
- /* this would all work perfectly _but_ the python strings may be freed
- * immediately after use, so we need to duplicate them, ugh.
- * annoying because it works most of the time without this. */
- {
- EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
- "enum_items_from_py2");
- EnumPropertyItem *items_ptr = items_dup;
- char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
- memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
- for (i = 0; i < seq_len; i++, items_ptr++) {
- buf += strswapbufcpy(buf, &items_ptr->identifier);
- buf += strswapbufcpy(buf, &items_ptr->name);
- buf += strswapbufcpy(buf, &items_ptr->description);
- }
- MEM_freeN(items);
- items = items_dup;
- }
- /* end string duplication */
-#endif
-
- return items;
-}
-
-static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
-{
- PyGILState_STATE gilstate;
-
- PyObject *py_func = RNA_property_enum_py_data_get(prop);
- PyObject *self = NULL;
- PyObject *args;
- PyObject *items; /* returned from the function call */
-
- EnumPropertyItem *eitems = NULL;
- int err = 0;
-
- bpy_context_set(C, &gilstate);
-
- args = PyTuple_New(2);
- self = pyrna_struct_as_instance(ptr);
- PyTuple_SET_ITEM(args, 0, self);
-
- /* now get the context */
- PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
- Py_INCREF(bpy_context_module);
-
- items = PyObject_CallObject(py_func, args);
-
- Py_DECREF(args);
-
- if (items == NULL) {
- err = -1;
- }
- else {
- PyObject *items_fast;
- int defvalue_dummy = 0;
-
- if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
- "return value from the callback was not a sequence")))
- {
- err = -1;
- }
- else {
- eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy,
- (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
-
- Py_DECREF(items_fast);
-
- if (!eitems) {
- err = -1;
- }
- }
-
- Py_DECREF(items);
- }
-
- if (err != -1) { /* worked */
- *free = 1;
- }
- else {
- printf_func_error(py_func);
-
- eitems = DummyRNA_NULL_items;
- }
-
-
- bpy_context_clear(C, &gilstate);
- return eitems;
-}
-
PyDoc_STRVAR(BPy_EnumProperty_doc,
".. function:: EnumProperty(items, "
"name=\"\", "
"description=\"\", "
"default=\"\", "
"options={'ANIMATABLE'}, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new enumerator property definition.\n"
"\n"
@@ -1227,13 +2523,15 @@ BPY_PROPDEF_DESC_DOC
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'ENUM_FLAG', 'LIBRARY_EDITABLE'].\n"
" :type options: set\n"
" :arg items: sequence of enum items formatted:\n"
-" [(identifier, name, description, number), ...] where the identifier is used\n"
+" [(identifier, name, description, icon, number), ...] where the identifier is used\n"
" for python access and other values are used for the interface.\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"
" This function must take 2 arguments (self, context)\n"
-" :type items: sequence of string triplets or a function\n"
+" WARNING: Do not use generators here (they will work the first time, but will lead to empty values\n"
+" in some unload/reload scenarii)!\n"
+" :type items: sequence of string triples or a function\n"
BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
@@ -1244,7 +2542,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "items", "name", "description", "default",
- "options", "update", NULL};
+ "options", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
PyObject *def = NULL;
int id_len;
@@ -1254,22 +2552,30 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
- short is_itemf = FALSE;
+ bool is_itemf = false;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#O|ssOO!O:EnumProperty",
+ "s#O|ssOO!OOO:EnumProperty",
(char **)kwlist, &id, &id_len,
&items, &name, &description,
&def, &PySet_Type, &pyopts,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -1290,7 +2596,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- is_itemf = TRUE;
+ is_itemf = true;
eitems = DummyRNA_NULL_items;
}
else {
@@ -1312,25 +2618,17 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description);
else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description);
- if (is_itemf) {
- RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
- RNA_def_enum_py_data(prop, (void *)items);
-
- /* watch out!, if a user is tricky they can probably crash blender
- * if they manage to free the callback, take care! */
- /* Py_INCREF(items); */
- }
-
if (pyopts) {
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL));
RNA_def_property_duplicate_pointers(srna, prop);
- if (is_itemf == FALSE) {
+ if (is_itemf == false) {
/* note: this must be postponed until after #RNA_def_property_duplicate_pointers
* otherwise if this is a generator it may free the strings before we copy them */
Py_DECREF(items_fast);
@@ -1422,7 +2720,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if (!ptype)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
}
@@ -1433,7 +2731,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -1498,12 +2796,17 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject
}
PyDoc_STRVAR(BPy_RemoveProperty_doc,
-".. function:: RemoveProperty(attr)\n"
+".. function:: RemoveProperty(cls, attr="")\n"
"\n"
" Removes a dynamically defined property.\n"
"\n"
-" :arg attr: Property name.\n"
+" :arg cls: The class containing the property (must be a positional argument).\n"
+" :type cls: type\n"
+" :arg attr: Property name (must be passed as a keyword).\n"
" :type attr: string\n"
+"\n"
+".. note:: Typically this function doesn't need to be accessed directly.\n"
+" Instead use ``del cls.attr``\n"
);
static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -1518,7 +2821,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw
return ret;
}
else if (PyTuple_GET_SIZE(args) > 1) {
- PyErr_SetString(PyExc_ValueError, "all args must be keywords");
+ PyErr_SetString(PyExc_ValueError, "expected one positional arg, one keyword arg");
return NULL;
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index a0df8988068..19ec35ae357 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -37,6 +37,12 @@
#include "RNA_types.h"
+#include "BLI_dynstr.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+#include "BLI_math_rotation.h"
+#include "BLI_utildefines.h"
+
#include "BPY_extern.h"
#include "bpy_rna.h"
@@ -50,12 +56,6 @@
# include "MEM_guardedalloc.h"
#endif
-#include "BLI_dynstr.h"
-#include "BLI_string.h"
-#include "BLI_listbase.h"
-#include "BLI_math_rotation.h"
-#include "BLI_utildefines.h"
-
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
# include "BLI_ghash.h"
#endif
@@ -309,9 +309,9 @@ void BPY_id_release(struct ID *id)
}
#ifdef USE_PEDANTIC_WRITE
-static short rna_disallow_writes = FALSE;
+static bool rna_disallow_writes = false;
-static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
+static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
{
ID *id = ptr->id.data;
if (id) {
@@ -329,30 +329,30 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
"%.200s, %.200s datablock, error setting %.200s.%.200s",
id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
#endif /* USE_PEDANTIC_WRITE */
#ifdef USE_PEDANTIC_WRITE
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
return !rna_disallow_writes;
}
-void pyrna_write_set(int val)
+void pyrna_write_set(bool val)
{
rna_disallow_writes = !val;
}
#else /* USE_PEDANTIC_WRITE */
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
- return TRUE;
+ return true;
}
-void pyrna_write_set(int UNUSED(val))
+void pyrna_write_set(bool UNUSED(val))
{
/* nothing */
}
@@ -644,7 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -655,7 +655,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -1123,7 +1123,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
{
EnumPropertyItem *item;
const char *result;
- int free = FALSE;
+ int free = false;
RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
if (item) {
@@ -1187,7 +1187,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
return -1;
}
- if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) {
+ if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
return -1;
}
@@ -1202,7 +1202,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj
{
EnumPropertyItem *item;
int ret;
- int free = FALSE;
+ int free = false;
*r_value = 0;
@@ -1282,7 +1282,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
}
else {
EnumPropertyItem *enum_item;
- int free = FALSE;
+ int free = false;
/* don't throw error here, can't trust blender 100% to give the
* right values, python code should not generate error for that */
@@ -1478,7 +1478,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
}
-static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
+static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
{
BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
pyfunc->ptr = *ptr;
@@ -1510,12 +1510,18 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* prefer not to have an exception here
* however so many poll functions return None or a valid Object.
* its a hassle to convert these into a bool before returning, */
- if (RNA_property_flag(prop) & PROP_OUTPUT)
+ if (RNA_property_flag(prop) & PROP_OUTPUT) {
param = PyObject_IsTrue(value);
- else
+ }
+ else {
param = PyLong_AsLong(value);
- if (param < 0) {
+ if (UNLIKELY(param & ~1)) { /* only accept 0/1 */
+ param = -1; /* error out below */
+ }
+ }
+
+ if (param == -1) {
PyErr_Format(PyExc_TypeError,
"%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
error_prefix, RNA_struct_identifier(ptr->type),
@@ -1617,9 +1623,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
}
else {
-
/* Unicode String */
-
#ifdef USE_STRING_COERCE
PyObject *value_coerce = NULL;
if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
@@ -1628,12 +1632,6 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
else {
param = _PyUnicode_AsString(value);
-#ifdef WITH_INTERNATIONAL
- if (subtype == PROP_TRANSLATE) {
- param = IFACE_(param);
- }
-#endif /* WITH_INTERNATIONAL */
-
}
#else /* USE_STRING_COERCE */
param = _PyUnicode_AsString(value);
@@ -1676,13 +1674,13 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* type checkins is done by each function */
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
/* set of enum items, concatenate all values with OR */
- if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
+ if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
return -1;
}
}
else {
/* simple enum string */
- if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
+ if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
return -1;
}
}
@@ -1771,7 +1769,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
else {
BPy_StructRNA *param = (BPy_StructRNA *)value;
- int raise_error = FALSE;
+ bool raise_error = false;
if (data) {
if (flag & PROP_RNAPTR) {
@@ -1798,7 +1796,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
*((void **)data) = param->ptr.data;
}
else {
- raise_error = TRUE;
+ raise_error = true;
}
}
else {
@@ -2189,7 +2187,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
else {
PyObject *keylib = PyTuple_GET_ITEM(key, 1);
Library *lib;
- int found = FALSE;
+ bool found = false;
if (keylib == Py_None) {
lib = NULL;
@@ -2226,7 +2224,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
{
ID *id = itemptr.data; /* always an ID */
if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
- found = TRUE;
+ found = true;
if (r_ptr) {
*r_ptr = itemptr;
}
@@ -2236,7 +2234,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_END;
/* we may want to fail silently as with collection.get() */
- if ((found == FALSE) && err_not_found) {
+ if ((found == false) && err_not_found) {
/* only runs for getitem access so use fixed string */
PyErr_SetString(PyExc_KeyError,
"bpy_prop_collection[key, lib]: not found");
@@ -2249,7 +2247,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
}
static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
- const char *err_prefix, const short err_not_found)
+ const char *err_prefix, const bool err_not_found)
{
PointerRNA ptr;
const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
@@ -2442,7 +2440,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
else if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair(self, key,
- "bpy_prop_collection[id, lib]", TRUE);
+ "bpy_prop_collection[id, lib]", true);
}
else {
PyErr_Format(PyExc_TypeError,
@@ -2859,7 +2857,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
- "(id, lib) in bpy_prop_collection", FALSE, NULL);
+ "(id, lib) in bpy_prop_collection", false, NULL);
}
else {
@@ -4199,7 +4197,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
}
else if (PyTuple_Check(key_ob)) {
PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob,
- "bpy_prop_collection.get((id, lib))", FALSE);
+ "bpy_prop_collection.get((id, lib))", false);
if (ret) {
return ret;
}
@@ -4261,12 +4259,12 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
/* values to assign */
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed)
{
PropertyRNA *prop;
*raw_type = PROP_RAW_UNSET;
*attr_tot = 0;
- *attr_signed = FALSE;
+ *attr_signed = false;
/* note: this is fail with zero length lists, so don't let this get caled in that case */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
@@ -4274,7 +4272,7 @@ static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
prop = RNA_struct_find_property(&itemptr, attr);
*raw_type = RNA_property_raw_type(prop);
*attr_tot = RNA_property_array_length(&itemptr, prop);
- *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE : TRUE;
+ *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? false : true;
break;
}
RNA_PROP_END;
@@ -4285,7 +4283,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
/* values to assign */
const char **attr, PyObject **seq, int *tot, int *size,
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed
)
{
#if 0
@@ -4293,7 +4291,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
int target_tot;
#endif
- *size = *attr_tot = *attr_signed = FALSE;
+ *size = *attr_tot = 0;
+ *attr_signed = false;
*raw_type = PROP_RAW_UNSET;
if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) {
@@ -4338,7 +4337,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
return 0;
}
-static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
+static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
{
char f = format ? *format : 'B'; /* B is assumed when not set */
@@ -4366,16 +4365,18 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons
static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
{
PyObject *item = NULL;
- int i = 0, ok = 0, buffer_is_compat;
+ int i = 0, ok = 0;
+ bool buffer_is_compat;
void *array = NULL;
/* get/set both take the same args currently */
const char *attr;
PyObject *seq;
- int tot, size, attr_tot, attr_signed;
+ int tot, size, attr_tot;
+ bool attr_signed;
RawPropertyType raw_type;
- if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0)
+ if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1)
return NULL;
if (tot == 0)
@@ -4384,7 +4385,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if (set) { /* get the array from python */
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4435,7 +4436,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
}
}
else {
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4515,7 +4516,7 @@ PyDoc_STRVAR(pyrna_prop_collection_foreach_get_doc,
"\n"
" .. code-block:: python\n"
"\n"
-" collection.foreach_get(someseq, attr)\n"
+" collection.foreach_get(attr, someseq)\n"
"\n"
" # Python equivalent\n"
" for i in range(len(seq)): someseq[i] = getattr(collection, attr)\n"
@@ -4535,7 +4536,7 @@ PyDoc_STRVAR(pyrna_prop_collection_foreach_set_doc,
"\n"
" .. code-block:: python\n"
"\n"
-" collection.foreach_set(seq, attr)\n"
+" collection.foreach_set(attr, seq)\n"
"\n"
" # Python equivalent\n"
" for i in range(len(seq)): setattr(collection[i], attr, seq[i])\n"
@@ -4618,8 +4619,14 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
/* experimental */
+ /* unused for now */
+#if 0
{"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
{"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
+
+ {"callback_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_CLASS, NULL},
+ {"callback_remove", (PyCFunction)pyrna_callback_classmethod_remove, METH_VARARGS | METH_CLASS, NULL},
+#endif
{NULL, NULL, 0, NULL}
};
@@ -4933,7 +4940,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
ParameterIterator iter;
PropertyRNA *parm;
PyObject *ret, *item;
- int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg;
+ int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0;
+ bool kw_arg;
PropertyRNA *pret_single = NULL;
void *retdata_single = NULL;
@@ -5014,7 +5022,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (i < pyargs_len) {
item = PyTuple_GET_ITEM(args, i);
- kw_arg = FALSE;
+ kw_arg = false;
}
else if (kw != NULL) {
#if 0
@@ -5025,7 +5033,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (item)
kw_tot++; /* make sure invalid keywords are not given */
- kw_arg = TRUE;
+ kw_arg = true;
}
i++; /* current argument */
@@ -5062,7 +5070,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
char error_prefix[512];
PyErr_Clear(); /* re-raise */
- if (kw_arg == TRUE)
+ if (kw_arg == true)
BLI_snprintf(error_prefix, sizeof(error_prefix),
"%.200s.%.200s(): error with keyword argument \"%.200s\" - ",
RNA_struct_identifier(self_ptr->type),
@@ -5097,12 +5105,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
DynStr *good_args = BLI_dynstr_new();
const char *arg_name, *bad_args_str, *good_args_str;
- int found = FALSE, first = TRUE;
+ bool found = false, first = true;
while (PyDict_Next(kw, &pos, &key, &value)) {
arg_name = _PyUnicode_AsString(key);
- found = FALSE;
+ found = false;
if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/
PyErr_Clear();
@@ -5113,22 +5121,22 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
for (; iter.valid; RNA_parameter_list_next(&iter)) {
parm = iter.parm;
if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) {
- found = TRUE;
+ found = true;
break;
}
}
RNA_parameter_list_end(&iter);
- if (found == FALSE) {
+ if (found == false) {
BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
- first = FALSE;
+ first = false;
}
}
}
/* list good args */
- first = TRUE;
+ first = true;
RNA_parameter_list_begin(&parms, &iter);
for (; iter.valid; RNA_parameter_list_next(&iter)) {
@@ -5137,7 +5145,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
continue;
BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
- first = FALSE;
+ first = false;
}
RNA_parameter_list_end(&iter);
@@ -5167,7 +5175,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
BKE_reports_init(&reports, RPT_STORE);
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
- err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE));
+ err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
/* return value */
if (err != -1) {
@@ -5230,7 +5238,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure)
PyObject *ret;
char *args;
- args = RNA_function_as_string_keywords(NULL, self->func, NULL, TRUE, TRUE);
+ args = RNA_function_as_string_keywords(NULL, self->func, NULL, true, true);
ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
RNA_struct_identifier(self->ptr.type),
@@ -5962,7 +5970,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
{
- if (self->iter.valid == FALSE) {
+ if (self->iter.valid == false) {
PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop");
return NULL;
}
@@ -6029,6 +6037,27 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item);
Py_DECREF(item);
+ /* add staticmethods and classmethods */
+ {
+ const PointerRNA func_ptr = {{NULL}, srna, NULL};
+ const ListBase *lb;
+ Link *link;
+
+ lb = RNA_struct_type_functions(srna);
+ for (link = lb->first; link; link = link->next) {
+ FunctionRNA *func = (FunctionRNA *)link;
+ const int flag = RNA_function_flag(func);
+ if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */
+ (flag & FUNC_REGISTER) == false) /* is not for registration */
+ {
+ /* we may want to set the type of this later */
+ PyObject *func_py = pyrna_func_to_py(&func_ptr, func);
+ PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py);
+ Py_DECREF(func_py);
+ }
+ }
+ }
+
/* done with rna instance */
}
@@ -6229,7 +6258,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
pyrna->ptr = *ptr;
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = FALSE;
+ pyrna->freeptr = false;
#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
@@ -6309,15 +6338,15 @@ PyObject *pyrna_id_CreatePyObject(ID *id)
}
}
-int pyrna_id_FromPyObject(PyObject *obj, ID **id)
+bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
{
if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) {
*id = ((BPy_StructRNA *)obj)->ptr.id.data;
- return TRUE;
+ return true;
}
else {
*id = NULL;
- return FALSE;
+ return false;
}
}
@@ -6502,6 +6531,9 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE;
+/**
+ * Accessed from Python as 'bpy.types'
+ */
PyObject *BPY_rna_types(void)
{
BPy_BaseTypeRNA *self;
@@ -6528,7 +6560,7 @@ PyObject *BPY_rna_types(void)
return (PyObject *)self;
}
-StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix)
+StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
{
BPy_StructRNA *py_srna = NULL;
StructRNA *srna;
@@ -6602,7 +6634,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyErr_Clear();
- srna = pyrna_struct_as_srna(self, 0, error_prefix);
+ srna = pyrna_struct_as_srna(self, false, error_prefix);
if (!PyErr_Occurred()) {
PyErr_Restore(error_type, error_value, error_traceback);
@@ -6759,7 +6791,9 @@ static int rna_function_arg_count(FunctionRNA *func)
const ListBase *lb = RNA_function_defined_parameters(func);
PropertyRNA *parm;
Link *link;
- int count = (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1;
+ int flag = RNA_function_flag(func);
+ int is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
+ int count = is_staticmethod ? 0 : 1;
for (link = lb->first; link; link = link->next) {
parm = (PropertyRNA *)link;
@@ -6781,7 +6815,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
PyObject *py_class = (PyObject *)py_data;
PyObject *base_class = RNA_struct_py_type_get(srna);
PyObject *item;
- int i, flag, arg_count, func_arg_count;
+ int i, flag, is_staticmethod, arg_count, func_arg_count;
const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */
if (srna_base) {
@@ -6804,6 +6838,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
for (link = lb->first; link; link = link->next) {
func = (FunctionRNA *)link;
flag = RNA_function_flag(func);
+ is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
if (!(flag & FUNC_REGISTER))
continue;
@@ -6814,7 +6849,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
i++;
if (item == NULL) {
- if ((flag & FUNC_REGISTER_OPTIONAL) == 0) {
+ if ((flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER)) == 0) {
PyErr_Format(PyExc_AttributeError,
"expected %.200s, %.200s class to have an \"%.200s\" attribute",
class_type, py_class_name,
@@ -6826,7 +6861,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
}
else {
Py_DECREF(item); /* no need to keep a ref, the class owns it (technically we should keep a ref but...) */
- if (flag & FUNC_NO_SELF) {
+ if (is_staticmethod) {
if (PyMethod_Check(item) == 0) {
PyErr_Format(PyExc_TypeError,
"expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s",
@@ -6850,9 +6885,9 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
/* note, the number of args we check for and the number of args we give to
- * @classmethods are different (quirk of python),
+ * @staticmethods are different (quirk of python),
* this is why rna_function_arg_count() doesn't return the value -1*/
- if (flag & FUNC_NO_SELF)
+ if (is_staticmethod)
func_arg_count++;
if (arg_count != func_arg_count) {
@@ -6937,8 +6972,10 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
PropertyRNA *parm;
ParameterIterator iter;
PointerRNA funcptr;
- int err = 0, i, flag, ret_len = 0;
- const char is_static = (RNA_function_flag(func) & FUNC_NO_SELF) != 0;
+ int err = 0, i, ret_len = 0;
+ int flag = RNA_function_flag(func);
+ const char is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
+ const char is_classmethod = (flag & FUNC_NO_SELF) && (flag & FUNC_USE_SELF_TYPE);
/* annoying!, need to check if the screen gets set to NULL which is a
* hint that the file was actually re-loaded. */
@@ -6973,7 +7010,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
bpy_context_set(C, &gilstate);
- if (!is_static) {
+ if (!(is_staticmethod || is_classmethod)) {
/* some datatypes (operator, render engine) can store PyObjects for re-use */
if (ptr->data) {
void **instance = RNA_struct_instance(ptr);
@@ -7013,7 +7050,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (py_class->tp_init) {
#ifdef USE_PEDANTIC_WRITE
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */
+ rna_disallow_writes = is_operator ? false : true; /* only operators can write on __init__ */
#endif
/* true in most cases even when the class its self doesn't define an __init__ function. */
@@ -7032,7 +7069,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
#else
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = TRUE;
+ rna_disallow_writes = true;
/* 'almost' all the time calling the class isn't needed.
* We could just do... */
@@ -7064,18 +7101,21 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
}
- if (err != -1 && (is_static || py_class_instance)) { /* Initializing the class worked, now run its invoke function */
+ if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) { /* Initializing the class worked, now run its invoke function */
PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func));
-// flag = RNA_function_flag(func);
if (item) {
RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */
- if (is_static) {
+ if (is_staticmethod) {
i = 0;
}
+ else if (is_classmethod) {
+ PyTuple_SET_ITEM(args, 0, (PyObject *)py_class);
+ i = 1;
+ }
else {
PyTuple_SET_ITEM(args, 0, py_class_instance);
i = 1;
@@ -7105,7 +7145,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = is_readonly ? TRUE : FALSE;
+ rna_disallow_writes = is_readonly ? true : false;
#endif
/* *** Main Caller *** */
@@ -7114,7 +7154,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
/* *** Done Calling *** */
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = FALSE;
+ rna_disallow_writes = false;
#endif
RNA_parameter_list_end(&iter);
@@ -7209,7 +7249,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (err != 0) {
ReportList *reports;
/* alert the user, else they wont know unless they see the console. */
- if ((!is_static) &&
+ if ((!is_staticmethod) && (!is_classmethod) &&
(ptr->data) &&
(RNA_struct_is_a(ptr->type, &RNA_Operator)) &&
(is_valid_wm == (CTX_wm_manager(C) != NULL)))
@@ -7332,8 +7372,9 @@ PyDoc_STRVAR(pyrna_register_class_doc,
".. method:: register_class(cls)\n"
"\n"
" Register a subclass of a blender type in (:class:`bpy.types.Panel`,\n"
-" :class:`bpy.types.Menu`, :class:`bpy.types.Header`, :class:`bpy.types.Operator`,\n"
-" :class:`bpy.types.KeyingSetInfo`, :class:`bpy.types.RenderEngine`).\n"
+" :class:`bpy.types.UIList`, :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n"
+" :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n"
+" :class:`bpy.types.RenderEngine`).\n"
"\n"
" If the class has a *register* class method it will be called\n"
" before registration.\n"
@@ -7378,7 +7419,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
}
/* warning: gets parent classes srna, only for the register function */
- srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):");
+ srna = pyrna_struct_as_srna(py_class, true, "register_class(...):");
if (srna == NULL)
return NULL;
@@ -7414,7 +7455,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
srna_new = reg(CTX_data_main(C), &reports, py_class, identifier,
bpy_class_validate, bpy_class_call, bpy_class_free);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
/* python errors validating are not converted into reports so the check above will fail.
@@ -7521,7 +7562,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
return NULL;
}
- srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):");
+ srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):");
if (srna == NULL)
return NULL;
@@ -7592,3 +7633,39 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
Py_RETURN_NONE;
}
+
+/* currently this is fairly limited, we would need to make some way to split up
+ * pyrna_callback_classmethod_... if we want more then one callback per type */
+typedef struct BPyRNA_CallBack {
+ PyMethodDef py_method;
+ StructRNA *bpy_srna;
+} PyRNA_CallBack;
+
+static struct BPyRNA_CallBack pyrna_cb_methods[] = {
+ {{"draw_handler_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_STATIC, ""}, &RNA_Space},
+ {{"draw_handler_remove", (PyCFunction)pyrna_callback_classmethod_remove, METH_VARARGS | METH_STATIC, ""}, &RNA_Space},
+ {{NULL, NULL, 0, NULL}, NULL}
+};
+
+void BPY_rna_register_cb(void)
+{
+ int i;
+
+ for (i = 0; pyrna_cb_methods[i].bpy_srna; i++) {
+ PyObject *cls;
+ PyObject *func;
+ PyObject *classmethod;
+ PyObject *args = PyTuple_New(1);
+
+ cls = pyrna_srna_Subtype(pyrna_cb_methods[i].bpy_srna);
+ func = PyCFunction_New(&pyrna_cb_methods[i].py_method, NULL);
+ PyTuple_SET_ITEM(args, 0, func);
+ classmethod = PyObject_CallObject((PyObject *)&PyClassMethod_Type, args);
+
+ PyObject_SetAttrString(cls, pyrna_cb_methods[i].py_method.ml_name, classmethod);
+
+ Py_DECREF(classmethod);
+ Py_DECREF(args); /* clears 'func' too */
+ Py_DECREF(cls);
+ }
+}
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 880ef4c2185..424452ef6fe 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -115,7 +115,7 @@ typedef struct {
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
#ifdef PYRNA_FREE_SUPPORT
- int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
+ bool freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
#endif /* PYRNA_FREE_SUPPORT */
} BPy_StructRNA;
@@ -164,20 +164,21 @@ typedef struct {
#define BPy_BaseTypeRNA BPy_PropertyRNA
StructRNA *srna_from_self(PyObject *self, const char *error_prefix);
-StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix);
+StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix);
void BPY_rna_init(void);
PyObject *BPY_rna_module(void);
void BPY_update_rna_module(void);
/*PyObject *BPY_rna_doc(void);*/
PyObject *BPY_rna_types(void);
+void BPY_rna_register_cb(void);
PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr);
PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop);
/* extern'd by other modules which don't deal closely with RNA */
PyObject *pyrna_id_CreatePyObject(struct ID *id);
-int pyrna_id_FromPyObject(PyObject *obj, struct ID **id);
+bool pyrna_id_FromPyObject(PyObject *obj, struct ID **id);
/* operators also need this to set args */
int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix);
@@ -204,8 +205,8 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop);
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value);
-int pyrna_write_check(void);
-void pyrna_write_set(int val);
+bool pyrna_write_check(void);
+void pyrna_write_set(bool val);
void pyrna_invalidate(BPy_DummyPointerRNA *self);
int pyrna_struct_validity_check(BPy_StructRNA *pysrna);
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 69839514a12..a19f8e2d8ed 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -44,6 +44,7 @@
#include "BKE_fcurve.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -147,21 +148,28 @@ static int pyrna_struct_anim_args_parse(
/* internal use for insert and delete */
static int pyrna_struct_keyframe_parse(
PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
- const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
+ const char **path_full, int *index, float *cfra, const char **group_name, int *options) /* return values */
{
- static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
+ static const char *kwlist[] = {"data_path", "index", "frame", "group", "options", NULL};
+ PyObject *pyoptions = NULL;
const char *path;
- /* note, parse_str MUST start with 's|ifs' */
- if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
+ /* note, parse_str MUST start with 's|ifsO!' */
+ if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name,
+ &PySet_Type, &pyoptions)) {
return -1;
+ }
- if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
+ if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1)
return -1;
if (*cfra == FLT_MAX)
*cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
+ /* flag may be null (no option currently for remove keyframes e.g.). */
+ if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1))
+ return -1;
+
return 0; /* success */
}
@@ -172,12 +180,19 @@ char pyrna_struct_keyframe_insert_doc[] =
"\n"
" :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
" :type data_path: string\n"
-" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel if the property is not an array.\n"
+" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel "
+ "if the property is not an array.\n"
" :type index: int\n"
" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
" :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
+" :arg options: Some optional flags:\n"
+" 'NEEDED': Only insert keyframes where they're needed in the relevant F-Curves.\n"
+" 'VISUAL': Insert keyframes based on 'visual transforms'.\n"
+" 'XYZ_TO_RGB': Color for newly added transformation F-Curves (Location, Rotation, Scale) "
+ "and also Color is based on the transform axis.\n"
+" :type flag: set\n"
" :return: Success of keyframe insertion.\n"
" :rtype: boolean\n"
;
@@ -188,12 +203,13 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
int index = -1;
float cfra = FLT_MAX;
const char *group_name = NULL;
+ int options = 0;
PYRNA_STRUCT_CHECK_OBJ(self);
if (pyrna_struct_keyframe_parse(&self->ptr, args, kw,
- "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()",
- &path_full, &index, &cfra, &group_name) == -1)
+ "s|ifsO!:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()",
+ &path_full, &index, &cfra, &group_name, &options) == -1)
{
return NULL;
}
@@ -203,10 +219,10 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
BKE_reports_init(&reports, RPT_STORE);
- result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
+ result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options);
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -240,9 +256,9 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
PYRNA_STRUCT_CHECK_OBJ(self);
if (pyrna_struct_keyframe_parse(&self->ptr, args, kw,
- "s|ifs:bpy_struct.keyframe_delete()",
+ "s|ifsO!:bpy_struct.keyframe_delete()",
"bpy_struct.keyframe_insert()",
- &path_full, &index, &cfra, &group_name) == -1)
+ &path_full, &index, &cfra, &group_name, NULL) == -1)
{
return NULL;
}
@@ -255,7 +271,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -285,7 +301,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
return NULL;
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
+ if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
return NULL;
}
else {
@@ -297,7 +313,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
if (result) {
@@ -361,7 +377,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
return NULL;
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
+ if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
return NULL;
}
else {
@@ -374,7 +390,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index f7114115a91..1043f68dbdb 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -32,23 +32,34 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+
#include "bpy_rna.h"
#include "bpy_rna_callback.h"
#include "bpy_util.h"
-#include "BLI_utildefines.h"
-
+#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
#include "BKE_context.h"
+#include "BKE_screen.h"
+
#include "ED_space_api.h"
/* use this to stop other capsules from being mis-used */
#define RNA_CAPSULE_ID "RNA_HANDLE"
#define RNA_CAPSULE_ID_INVALID "RNA_HANDLE_REMOVED"
+static EnumPropertyItem region_draw_mode_items[] = {
+ {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
+ {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
+ {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customdata)
{
PyObject *cb_func, *cb_args, *result;
@@ -56,8 +67,8 @@ static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customd
bpy_context_set((bContext *)C, &gilstate);
- cb_func = PyTuple_GET_ITEM((PyObject *)customdata, 0);
- cb_args = PyTuple_GET_ITEM((PyObject *)customdata, 1);
+ cb_func = PyTuple_GET_ITEM((PyObject *)customdata, 1);
+ cb_args = PyTuple_GET_ITEM((PyObject *)customdata, 2);
result = PyObject_CallObject(cb_func, cb_args);
if (result) {
@@ -71,6 +82,7 @@ static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customd
bpy_context_clear((bContext *)C, &gilstate);
}
+#if 0
PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
{
void *handle;
@@ -89,13 +101,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
if (cb_event_str) {
- static EnumPropertyItem region_draw_mode_items[] = {
- {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
- {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
- {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
- {0, NULL, 0, NULL, NULL}};
-
- if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) {
+ if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) {
return NULL;
}
}
@@ -136,6 +142,163 @@ PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle);
}
+ else {
+ PyErr_SetString(PyExc_TypeError, "callback_remove(): type does not support callbacks");
+ return NULL;
+ }
+
+ /* don't allow reuse */
+ PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID);
+
+ Py_RETURN_NONE;
+}
+#endif
+
+/* reverse of rna_Space_refine() */
+static eSpace_Type rna_Space_refine_reverse(StructRNA *srna)
+{
+ if (srna == &RNA_SpaceView3D) return SPACE_VIEW3D;
+ if (srna == &RNA_SpaceGraphEditor) return SPACE_IPO;
+ if (srna == &RNA_SpaceOutliner) return SPACE_OUTLINER;
+ if (srna == &RNA_SpaceProperties) return SPACE_BUTS;
+ if (srna == &RNA_SpaceFileBrowser) return SPACE_FILE;
+ if (srna == &RNA_SpaceImageEditor) return SPACE_IMAGE;
+ if (srna == &RNA_SpaceInfo) return SPACE_INFO;
+ if (srna == &RNA_SpaceSequenceEditor) return SPACE_SEQ;
+ if (srna == &RNA_SpaceTextEditor) return SPACE_TEXT;
+ if (srna == &RNA_SpaceDopeSheetEditor) return SPACE_ACTION;
+ if (srna == &RNA_SpaceNLA) return SPACE_NLA;
+ if (srna == &RNA_SpaceTimeline) return SPACE_TIME;
+ if (srna == &RNA_SpaceNodeEditor) return SPACE_NODE;
+ if (srna == &RNA_SpaceLogicEditor) return SPACE_LOGIC;
+ if (srna == &RNA_SpaceConsole) return SPACE_CONSOLE;
+ if (srna == &RNA_SpaceUserPreferences) return SPACE_USERPREF;
+ if (srna == &RNA_SpaceClipEditor) return SPACE_CLIP;
+ return -1;
+}
+
+PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args)
+{
+ void *handle;
+ PyObject *cls;
+ PyObject *cb_func, *cb_args;
+ char *cb_regiontype_str;
+ char *cb_event_str;
+ int cb_event;
+ int cb_regiontype;
+ StructRNA *srna;
+
+ if (PyTuple_GET_SIZE(args) < 2) {
+ PyErr_SetString(PyExc_ValueError, "handler_add(handle): expected at least 2 args");
+ return NULL;
+ }
+
+ cls = PyTuple_GET_ITEM(args, 0);
+ if (!(srna = pyrna_struct_as_srna(cls, false, "handler_add"))) {
+ return NULL;
+ }
+ cb_func = PyTuple_GET_ITEM(args, 1);
+ if (!PyCallable_Check(cb_func)) {
+ PyErr_SetString(PyExc_TypeError, "first argument isn't callable");
+ return NULL;
+ }
+
+ /* class spesific callbacks */
+ if (RNA_struct_is_a(srna, &RNA_Space)) {
+ if (!PyArg_ParseTuple(args, "OOO!ss:Space.draw_handler_add",
+ &cls, &cb_func, /* already assigned, no matter */
+ &PyTuple_Type, &cb_args, &cb_regiontype_str, &cb_event_str))
+ {
+ return NULL;
+ }
+
+ if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) {
+ return NULL;
+ }
+ else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") == -1) {
+ return NULL;
+ }
+ else {
+ const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
+ if (spaceid == -1) {
+ PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
+ return NULL;
+ }
+ else {
+ SpaceType *st = BKE_spacetype_from_id(spaceid);
+ ARegionType *art = BKE_regiontype_from_id(st, cb_regiontype);
+
+ handle = ED_region_draw_cb_activate(art, cb_region_draw, (void *)args, cb_event);
+ Py_INCREF(args);
+ }
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "callback_add(): type does not support callbacks");
+ return NULL;
+ }
+
+ return PyCapsule_New((void *)handle, RNA_CAPSULE_ID, NULL);
+}
+
+PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *args)
+{
+ PyObject *cls;
+ PyObject *py_handle;
+ void *handle;
+ void *customdata;
+ StructRNA *srna;
+ char *cb_regiontype_str;
+ int cb_regiontype;
+
+ if (PyTuple_GET_SIZE(args) < 2) {
+ PyErr_SetString(PyExc_ValueError, "callback_remove(handle): expected at least 2 args");
+ return NULL;
+ }
+
+ cls = PyTuple_GET_ITEM(args, 0);
+ if (!(srna = pyrna_struct_as_srna(cls, false, "callback_remove"))) {
+ return NULL;
+ }
+ py_handle = PyTuple_GET_ITEM(args, 1);
+ handle = PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID);
+ if (handle == NULL) {
+ PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed");
+ return NULL;
+ }
+
+ if (RNA_struct_is_a(srna, &RNA_Space)) {
+ if (!PyArg_ParseTuple(args, "OO!s:Space.draw_handler_remove",
+ &cls, &PyCapsule_Type, &py_handle, /* already assigned, no matter */
+ &cb_regiontype_str))
+ {
+ return NULL;
+ }
+
+ customdata = ED_region_draw_cb_customdata(handle);
+ Py_DECREF((PyObject *)customdata);
+
+ if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") == -1) {
+ return NULL;
+ }
+ else {
+ const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
+ if (spaceid == -1) {
+ PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
+ return NULL;
+ }
+ else {
+ SpaceType *st = BKE_spacetype_from_id(spaceid);
+ ARegionType *art = BKE_regiontype_from_id(st, cb_regiontype);
+
+ ED_region_draw_cb_exit(art, handle);
+ }
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "callback_remove(): type does not support callbacks");
+ return NULL;
+ }
/* don't allow reuse */
PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID);
diff --git a/source/blender/python/intern/bpy_rna_callback.h b/source/blender/python/intern/bpy_rna_callback.h
index 7824d2b082d..4b801f35654 100644
--- a/source/blender/python/intern/bpy_rna_callback.h
+++ b/source/blender/python/intern/bpy_rna_callback.h
@@ -28,5 +28,10 @@
struct BPy_StructRNA;
struct PyObject;
+#if 0
PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args);
PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args);
+#endif
+
+PyObject *pyrna_callback_classmethod_add(PyObject *cls, PyObject *args);
+PyObject *pyrna_callback_classmethod_remove(PyObject *cls, PyObject *args);
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index b7994eeccdc..b0b0f346944 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -29,9 +29,13 @@
#include <Python.h>
-#include "bpy_util.h"
+#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
+
+#include "bpy_util.h"
+
#include "MEM_guardedalloc.h"
+
#include "BKE_report.h"
#include "BKE_context.h"
@@ -59,13 +63,13 @@ char *BPy_enum_as_string(EnumPropertyItem *item)
return cstring;
}
-short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear)
+short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
{
char *report_str;
report_str = BKE_reports_string(reports, RPT_ERROR);
- if (clear) {
+ if (clear == true) {
BKE_reports_clear(reports);
}
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index b5f679b741f..b007e123cfc 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -39,7 +39,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item);
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
/* error reporting */
-short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear);
+short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
short BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 05306f230d1..da2888045d0 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -1025,13 +1025,13 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
int col;
if (self->wrapped == Py_WRAP) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.resize_4x4(): "
"cannot resize wrapped data - make a copy and resize that");
return NULL;
}
if (self->cb_user) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.resize_4x4(): "
"cannot resize owned data - make a copy and resize that");
return NULL;
@@ -1080,7 +1080,7 @@ static PyObject *Matrix_to_4x4(MatrixObject *self)
}
/* TODO, 2x2 matrix */
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_4x4(): "
"inappropriate matrix size");
return NULL;
@@ -1102,7 +1102,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self)
return NULL;
if ((self->num_row < 3) || (self->num_col < 3)) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_3x3(): inappropriate matrix size");
return NULL;
}
@@ -1126,7 +1126,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self)
return NULL;
if ((self->num_row < 3) || self->num_col < 4) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_translation(): "
"inappropriate matrix size");
return NULL;
@@ -1156,7 +1156,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
/*must be 3-4 cols, 3-4 rows, square matrix */
if ((self->num_row < 3) || (self->num_col < 3)) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_scale(): "
"inappropriate matrix size, 3x3 minimum size");
return NULL;
@@ -1194,7 +1194,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.invert(ed): "
"only square matrices are supported");
return NULL;
@@ -1222,7 +1222,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
break;
}
default:
- PyErr_Format(PyExc_TypeError,
+ PyErr_Format(PyExc_ValueError,
"Matrix invert(ed): size (%d) unsupported",
(int)self->num_col);
return NULL;
@@ -1281,7 +1281,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.adjugate(d): "
"only square matrices are supported");
return NULL;
@@ -1311,7 +1311,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self)
break;
}
default:
- PyErr_Format(PyExc_TypeError,
+ PyErr_Format(PyExc_ValueError,
"Matrix adjugate(d): size (%d) unsupported",
(int)self->num_col);
return NULL;
@@ -1357,7 +1357,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
return NULL;
if (self->num_row != 3 || self->num_col != 3) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.rotate(): "
"must have 3x3 dimensions");
return NULL;
@@ -1390,7 +1390,7 @@ static PyObject *Matrix_decompose(MatrixObject *self)
float size[3];
if (self->num_row != 4 || self->num_col != 4) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.decompose(): "
"inappropriate matrix size - expects 4x4 matrix");
return NULL;
@@ -1476,7 +1476,7 @@ static PyObject *Matrix_determinant(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.determinant(): "
"only square matrices are supported");
return NULL;
@@ -1498,7 +1498,7 @@ static PyObject *Matrix_transpose(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.transpose(d): "
"only square matrices are supported");
return NULL;
@@ -1533,6 +1533,53 @@ static PyObject *Matrix_transposed(MatrixObject *self)
return matrix__apply_to_copy((PyNoArgsFunction)Matrix_transpose, self);
}
+/*---------------------------matrix.normalize() ------------------*/
+PyDoc_STRVAR(Matrix_normalize_doc,
+".. method:: normalize()\n"
+"\n"
+" Normalize each of the matrix columns.\n"
+);
+static PyObject *Matrix_normalize(MatrixObject *self)
+{
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.normalize(): "
+ "only square matrices are supported");
+ return NULL;
+ }
+
+ if (self->num_col == 3) {
+ normalize_m3((float (*)[3])self->matrix);
+ }
+ else if (self->num_col == 4) {
+ normalize_m4((float (*)[4])self->matrix);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.normalize(): "
+ "can only use a 3x3 or 4x4 matrix");
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(Matrix_normalized_doc,
+".. method:: normalized()\n"
+"\n"
+" Return a column normalized matrix\n"
+"\n"
+" :return: a column normalized matrix\n"
+" :rtype: :class:`Matrix`\n"
+);
+static PyObject *Matrix_normalized(MatrixObject *self)
+{
+ return matrix__apply_to_copy((PyNoArgsFunction)Matrix_normalize, self);
+}
+
/*---------------------------matrix.zero() -----------------------*/
PyDoc_STRVAR(Matrix_zero_doc,
".. method:: zero()\n"
@@ -1568,7 +1615,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.identity(): "
"only square matrices are supported");
return NULL;
@@ -1924,7 +1971,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
return NULL;
if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
@@ -1956,7 +2003,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
return NULL;
if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
@@ -2371,6 +2418,8 @@ static struct PyMethodDef Matrix_methods[] = {
/* operate on original or copy */
{"transpose", (PyCFunction) Matrix_transpose, METH_NOARGS, Matrix_transpose_doc},
{"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc},
+ {"normalize", (PyCFunction) Matrix_normalize, METH_NOARGS, Matrix_normalize_doc},
+ {"normalized", (PyCFunction) Matrix_normalized, METH_NOARGS, Matrix_normalized_doc},
{"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc},
{"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc},
{"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc},
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 1db0538eb07..91cff67fc49 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -251,6 +251,86 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
}
}
+/* Line-Line intersection using algorithm from mathworld.wolfram.com */
+
+PyDoc_STRVAR(M_Geometry_intersect_sphere_sphere_2d_doc,
+".. function:: intersect_sphere_sphere_2d(p_a, radius_a, p_b, radius_b)\n"
+"\n"
+" Returns 2 points on between intersecting circles.\n"
+"\n"
+" :arg p_a: Center of the first circle\n"
+" :type p_a: :class:`mathutils.Vector`\n"
+" :arg radius_a: Radius of the first circle\n"
+" :type radius_a: float\n"
+" :arg p_b: Center of the second circle\n"
+" :type p_b: :class:`mathutils.Vector`\n"
+" :arg radius_b: Radius of the second circle\n"
+" :type radius_b: float\n"
+" :rtype: tuple of :class:`mathutils.Vector`'s or None when there is no intersection\n"
+);
+static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), PyObject *args)
+{
+ PyObject *ret;
+ VectorObject *vec_a, *vec_b;
+ float *v_a, *v_b;
+ 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))
+ {
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback(vec_a) == -1 ||
+ BaseMath_ReadCallback(vec_b) == -1)
+ {
+ 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);
+
+ if (/* out of range */
+ (dist > rad_a + rad_b) ||
+ /* fully-contained in the other */
+ (dist < abs(rad_a - rad_b)) ||
+ /* co-incident */
+ (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);
+ }
+ else {
+ const float dist_delta = ((rad_a * rad_a) - (rad_b * rad_b) + (dist * dist)) / (2.0f * dist);
+ const float h = powf(fabsf((rad_a * rad_a) - (dist_delta * dist_delta)), 0.5f);
+ float i_cent[2];
+ float i1[2], i2[2];
+
+ i_cent[0] = v_a[0] + ((v_ab[0] * dist_delta) / dist);
+ i_cent[1] = v_a[1] + ((v_ab[1] * dist_delta) / dist);
+
+ i1[0] = i_cent[0] + h * v_ab[1] / dist;
+ i1[1] = i_cent[1] - h * v_ab[0] / dist;
+
+ 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));
+ }
+
+ return ret;
+}
+
PyDoc_STRVAR(M_Geometry_normal_doc,
".. function:: normal(v1, v2, v3, v4=None)\n"
"\n"
@@ -1102,7 +1182,7 @@ static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject
return NULL;
}
- dims = MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
+ 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];
@@ -1376,6 +1456,7 @@ static PyMethodDef M_Geometry_methods[] = {
{"intersect_line_sphere", (PyCFunction) M_Geometry_intersect_line_sphere, METH_VARARGS, M_Geometry_intersect_line_sphere_doc},
{"intersect_line_sphere_2d", (PyCFunction) M_Geometry_intersect_line_sphere_2d, METH_VARARGS, M_Geometry_intersect_line_sphere_2d_doc},
{"distance_point_to_plane", (PyCFunction) M_Geometry_distance_point_to_plane, METH_VARARGS, M_Geometry_distance_point_to_plane_doc},
+ {"intersect_sphere_sphere_2d", (PyCFunction) M_Geometry_intersect_sphere_sphere_2d, METH_VARARGS, M_Geometry_intersect_sphere_sphere_2d_doc},
{"area_tri", (PyCFunction) M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc},
{"normal", (PyCFunction) M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc},
{"barycentric_transform", (PyCFunction) M_Geometry_barycentric_transform, METH_VARARGS, M_Geometry_barycentric_transform_doc},
diff --git a/source/blender/quicktime/SConscript b/source/blender/quicktime/SConscript
index db1d4a4f1ab..a32f325de24 100644
--- a/source/blender/quicktime/SConscript
+++ b/source/blender/quicktime/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index e0858cd5ec2..4a8a06134c8 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -61,8 +61,8 @@
#import <QTKit/QTKit.h>
#include <AudioToolbox/AudioToolbox.h>
-#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) || !__LP64__
-#error 64 bit build & OSX 10.5 minimum are needed for QTKit
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
+#error OSX 10.5 minimum is needed for QTKit
#endif
#include "quicktime_import.h"
@@ -557,7 +557,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
[qtexport->movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
[qtexport->movie setAttribute:@"Made with Blender" forKey:QTMovieCopyrightAttribute];
- qtexport->frameDuration = QTMakeTime(rd->frs_sec_base*1000, rd->frs_sec*1000);
+ qtexport->frameDuration = QTMakeTime(rd->frs_sec_base * 1000, rd->frs_sec * 1000);
/* specifying the codec attributes : try to retrieve them from render data first*/
if (rd->qtcodecsettings.codecType) {
diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c
index 1c4ab5a4b0e..c85df29de92 100644
--- a/source/blender/quicktime/apple/quicktime_export.c
+++ b/source/blender/quicktime/apple/quicktime_export.c
@@ -905,7 +905,7 @@ int fromcocoa_request_qtcodec_settings(bContext *C, wmOperator *op)
void SCENE_OT_render_data_set_quicktime_codec(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Change codec";
+ ot->name = "Change Codec";
ot->description = "Change Quicktime codec Settings";
ot->idname = "SCENE_OT_render_data_set_quicktime_codec";
diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h
index a3469ddafde..55323c05278 100644
--- a/source/blender/quicktime/quicktime_export.h
+++ b/source/blender/quicktime/quicktime_export.h
@@ -65,14 +65,14 @@ void filepath_qt(char *string, struct RenderData *rd);
void quicktime_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); //used by RNA for defaults values init, if needed
/*Video codec type*/
int quicktime_get_num_videocodecs(void);
-QuicktimeCodecTypeDesc* quicktime_get_videocodecType_desc(int indexValue);
+QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue);
int quicktime_rnatmpvalue_from_videocodectype(int codecType);
int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue);
#ifdef USE_QTKIT
/*Audio codec type*/
int quicktime_get_num_audiocodecs(void);
-QuicktimeCodecTypeDesc* quicktime_get_audiocodecType_desc(int indexValue);
+QuicktimeCodecTypeDesc *quicktime_get_audiocodecType_desc(int indexValue);
int quicktime_rnatmpvalue_from_audiocodectype(int codecType);
int quicktime_audiocodecType_from_rnatmpvalue(int rnatmpvalue);
#endif
@@ -87,7 +87,7 @@ void makeqtstring(struct RenderData *rd, char *string); //for playanim.c
-#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 && __LP64__)
+#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__)
//Include the quicktime codec types constants that are missing in QTKitDefines.h
enum {
kRawCodecType = 'raw ',
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index a2d6e27bcb7..eb81e7f2049 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -54,12 +54,14 @@ set(SRC
intern/raytrace/rayobject_qbvh.cpp
intern/raytrace/rayobject_rtbuild.cpp
intern/raytrace/rayobject_vbvh.cpp
+ intern/source/bake.c
intern/source/convertblender.c
intern/source/envmap.c
intern/source/external_engine.c
intern/source/gammaCorrectionTables.c
intern/source/imagetexture.c
intern/source/initrender.c
+ intern/source/multires_bake.c
intern/source/occlusion.c
intern/source/pipeline.c
intern/source/pixelblending.c
@@ -83,6 +85,7 @@ set(SRC
intern/source/zbuf.c
extern/include/RE_engine.h
+ extern/include/RE_multires_bake.h
extern/include/RE_pipeline.h
extern/include/RE_render_ext.h
extern/include/RE_shader_ext.h
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index 8a044b19a79..992dd8c8262 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/source/*.c')
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index d2ffc3a0e26..b687acae1f7 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -61,6 +61,8 @@ struct Scene;
#define RE_ENGINE_DO_DRAW 4
#define RE_ENGINE_DO_UPDATE 8
#define RE_ENGINE_RENDERING 16
+#define RE_ENGINE_HIGHLIGHT_TILES 32
+#define RE_ENGINE_USED_FOR_VIEWPORT 64
extern ListBase R_engines;
@@ -104,6 +106,7 @@ typedef struct RenderEngine {
} RenderEngine;
RenderEngine *RE_engine_create(RenderEngineType *type);
+RenderEngine *RE_engine_create_ex(RenderEngineType *type, int use_for_viewport);
void RE_engine_free(RenderEngine *engine);
void RE_layer_load_from_file(struct RenderLayer *layer, struct ReportList *reports, const char *filename, int x, int y);
@@ -130,5 +133,7 @@ void RE_engines_exit(void);
RenderEngineType *RE_engines_find(const char *idname);
+void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r);
+
#endif /* __RE_ENGINE_H__ */
diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h
new file mode 100644
index 00000000000..04cfe55e3a3
--- /dev/null
+++ b/source/blender/render/extern/include/RE_multires_bake.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) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Morten Mikkelsen,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file RE_multires_bake.h
+ * \ingroup render
+ */
+
+#ifndef __RE_MULTIRES_BAKE_H__
+#define __RE_MULTIRES_BAKE_H__
+
+struct MultiresBakeRender;
+
+typedef struct MultiresBakeRender {
+ DerivedMesh *lores_dm, *hires_dm;
+ int simple, lvl, tot_lvl, bake_filter;
+ short mode, use_lores_mesh;
+
+ int number_of_rays;
+ float bias;
+
+ int tot_obj, tot_image;
+ ListBase image;
+
+ int baked_objects, baked_faces;
+
+ int raytrace_structure;
+ int octree_resolution;
+ int threads;
+
+ short *stop;
+ short *do_update;
+ float *progress;
+} MultiresBakeRender;
+
+void RE_multires_bake_images(struct MultiresBakeRender *bkr);
+
+#endif
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index ecdd1774221..f97e5ac3c59 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -198,7 +198,7 @@ void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipe
void RE_SetPixelSize(struct Render *re, float pixsize);
/* option to set viewmatrix before making dbase */
-void RE_SetView (struct Render *re, float mat[][4]);
+void RE_SetView (struct Render *re, float mat[4][4]);
/* make or free the dbase */
void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view);
@@ -273,8 +273,8 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd);
void RE_Database_Baking(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, const int type, struct Object *actob);
-void RE_DataBase_GetView(struct Render *re, float mat[][4]);
-void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]);
+void RE_DataBase_GetView(struct Render *re, float mat[4][4]);
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]);
struct Scene *RE_GetScene(struct Render *re);
int RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports);
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index 2a9a1becc42..2dfbdd0d6f5 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -49,10 +49,11 @@ struct RNode;
struct Render;
struct MTex;
struct ImBuf;
+struct ImagePool;
struct DerivedMesh;
/* 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);
+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);
/* 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 10045a8f7e1..d686de21517 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -184,19 +184,24 @@ typedef struct ShadeInput {
} ShadeInput;
+typedef struct BakeImBufuserData {
+ float *displacement_buffer;
+ char *mask_buffer;
+} BakeImBufuserData;
/* node shaders... */
struct Tex;
struct MTex;
struct ImBuf;
+struct ImagePool;
/* this one uses nodes */
-int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres);
+int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool);
/* nodes disabled */
-int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres);
+int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool);
/* 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);
+ const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, struct ImagePool *pool);
/* shaded view and bake */
struct Render;
@@ -206,6 +211,7 @@ struct Object;
int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update, float *progress);
struct Image *RE_bake_shade_get_image(void);
void RE_bake_ibuf_filter(struct ImBuf *ibuf, char *mask, const int filter);
+void RE_bake_ibuf_normalize_displacement(struct ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max);
#define BAKE_RESULT_OK 0
#define BAKE_RESULT_NO_OBJECTS 1
diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h
index d0f346f7402..a6c6d46e2e9 100644
--- a/source/blender/render/intern/include/envmap.h
+++ b/source/blender/render/intern/include/envmap.h
@@ -44,9 +44,10 @@
struct Render;
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);
+int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool);
#endif /* __ENVMAP_H__ */
diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h
index bb2e7e7f9f9..19759bf3e97 100644
--- a/source/blender/render/intern/include/pixelblending.h
+++ b/source/blender/render/intern/include/pixelblending.h
@@ -38,8 +38,8 @@
*/
void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w);
void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize);
-void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y);
-void mask_array(unsigned int mask, float filt[][3]);
+void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y);
+void mask_array(unsigned int mask, float filt[3][3]);
/**
* Alpha-over blending for floats.
diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h
index 30d574694b2..faf8c5f54f5 100644
--- a/source/blender/render/intern/include/pixelshading.h
+++ b/source/blender/render/intern/include/pixelshading.h
@@ -32,6 +32,8 @@
#ifndef __PIXELSHADING_H__
#define __PIXELSHADING_H__
+struct ImagePool;
+
/**
* Render the pixel at (x,y) for object ap. Apply the jitter mask.
* Output is given in float collector[4]. The type vector:
diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h
index 07fc7d7a6ed..e9514b8585e 100644
--- a/source/blender/render/intern/include/rayobject.h
+++ b/source/blender/render/intern/include/rayobject.h
@@ -56,7 +56,7 @@ int RE_rayobject_raycast(RayObject *r, struct Isect *i);
/* Acceleration Structures */
RayObject *RE_rayobject_octree_create(int ocres, int size);
-RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob);
+RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob);
RayObject *RE_rayobject_empty_create(void);
RayObject *RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */
@@ -87,6 +87,8 @@ typedef struct RayFace {
RayObject *RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr);
+RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4);
+
/* RayObject representing faces directly from a given VlakRen structure. Thus
* allowing to save memory, but making code triangle intersection dependent on
* render structures. */
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 5d61417cbaf..61b39a59b0b 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -91,7 +91,7 @@ void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd
struct ImBuf *ibuf);
void render_result_rect_fill_zero(struct RenderResult *rr);
-void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd,
+void render_result_rect_get_pixels(struct RenderResult *rr,
unsigned int *rect, int rectx, int recty,
const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings);
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 6ed8d6a7b6c..d65da586b9a 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -62,6 +62,7 @@ struct RayFace;
struct RenderEngine;
struct ReportList;
struct Main;
+struct ImagePool;
#define TABLEINITSIZE 1024
@@ -104,13 +105,19 @@ typedef struct RenderPart {
rcti disprect; /* part coordinates within total picture */
int rectx, recty; /* the size */
- short crop, ready; /* crop is amount of pixels we crop, for filter */
+ short crop, status; /* crop is amount of pixels we crop, for filter */
short sample, nr; /* sample can be used by zbuffers, nr is partnr */
short thread; /* thread id */
char *clipflag; /* clipflags for part zbuffering */
} RenderPart;
+enum {
+ PART_STATUS_NONE = 0,
+ PART_STATUS_IN_PROGRESS = 1,
+ PART_STATUS_READY = 2
+};
+
/* controls state of render, everything that's read-only during render stage */
struct Render
{
@@ -198,7 +205,6 @@ struct Render
ListBase strandsurface;
/* use this instead of R.r.cfra */
- float cfra;
float mblur_offs, field_offs;
/* render database */
@@ -255,6 +261,8 @@ struct Render
RenderStats i;
struct ReportList *reports;
+
+ struct ImagePool *pool;
};
/* ------------------------------------------------------------------------- */
@@ -368,6 +376,7 @@ struct halosort {
/* ------------------------------------------------------------------------- */
struct Material;
struct MTFace;
+struct ImagePool;
typedef struct RadFace {
float unshot[3], totrad[3];
@@ -397,6 +406,7 @@ typedef struct HaloRen {
int pixels;
unsigned int lay;
struct Material *mat;
+ struct ImagePool *pool;
} HaloRen;
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 30712250440..88b639c4ba9 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -83,6 +83,8 @@ int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct Rend
/* -------- ray.c ------- */
+struct RayObject *RE_rayobject_create(int type, int size, int octree_resolution);
+
extern void freeraytree(Render *re);
extern void makeraytree(Render *re);
struct RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi);
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
index 5213f14d773..1e81ca20d03 100644
--- a/source/blender/render/intern/include/renderdatabase.h
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -59,12 +59,16 @@ typedef struct VertTableNode {
float *tangent;
float *stress;
float *winspeed;
+ /* Index of vertex in source mesh (before modifiers). */
+ int *origindex;
} VertTableNode;
typedef struct VlakTableNode {
struct VlakRen *vlak;
struct MTFace *mtface;
struct MCol *mcol;
+ /* Index of mpoly in source mesh (before tessellation). */
+ int *origindex;
int totmtface, totmcol;
float *surfnor;
float *tangent;
@@ -87,8 +91,8 @@ void free_renderdata_tables(struct Render *re);
void free_renderdata_vertnodes(struct VertTableNode *vertnodes);
void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes);
-void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets);
-int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]);
+void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), int do_pano, float xoffs, int do_buckets);
+int clip_render_object(float boundbox[2][3], float bounds[4], float mat[4][4]);
/* functions are not exported... so wrong names */
@@ -106,7 +110,7 @@ struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, s
struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert);
struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay);
-struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4], int lay);
+struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[4][4], int lay);
void RE_makeRenderInstances(struct Render *re);
float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify);
@@ -114,9 +118,11 @@ float *RE_vertren_get_rad(struct ObjectRen *obr, struct VertRen *ver, int verify
float *RE_vertren_get_strand(struct ObjectRen *obr, struct VertRen *ver, int verify);
float *RE_vertren_get_tangent(struct ObjectRen *obr, struct VertRen *ver, int verify);
float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ver, int verify);
+int *RE_vertren_get_origindex(struct ObjectRen *obr, VertRen *ver, int verify);
struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
+int *RE_vlakren_get_origindex(struct ObjectRen *obr, VlakRen *vlak, int verify);
float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify);
float *RE_vlakren_get_nmap_tangent(struct ObjectRen *obr, VlakRen *ren, int verify);
RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify);
diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h
index 720354219e9..d9594864bff 100644
--- a/source/blender/render/intern/include/strand.h
+++ b/source/blender/render/intern/include/strand.h
@@ -92,10 +92,10 @@ struct StrandShadeCache;
typedef struct StrandShadeCache StrandShadeCache;
void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
-void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
+void render_strand_segment(struct Render *re, float winmat[4][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
void strand_minmax(struct StrandRen *strand, float min[3], float max[3], const float width);
-struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset);
+struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[4][4], int timeoffset);
void free_strand_surface(struct Render *re);
struct StrandShadeCache *strand_shade_cache_create(void);
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index 4b9fa2d2042..2dc12f39db7 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -60,6 +60,7 @@ struct TexResult;
struct Tex;
struct Image;
struct ImBuf;
+struct ImagePool;
/* texture.h */
@@ -76,9 +77,9 @@ 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);
-int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres);
-void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float result[4]);
+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);
+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/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index e873111e6bf..162fa3b7e88 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -49,17 +49,17 @@ void fillrect(int *rect, int x, int y, int val);
* Converts a world coordinate into a homogeneous coordinate in view
* coordinates.
*/
-void projectvert(const float v1[3], float winmat[][4], float adr[4]);
-void projectverto(const float v1[3], float winmat[][4], float adr[4]);
+void projectvert(const float v1[3], float winmat[4][4], float adr[4]);
+void projectverto(const float v1[3], float winmat[4][4], float adr[4]);
int testclip(const float v[3]);
-void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
-void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]);
+void zbuffer_shadow(struct Render *re, float winmat[4][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
+void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[4][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]);
void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart *, struct ZSpan *, int, void*), void *data);
unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist);
void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int));
-int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache);
+int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache);
typedef struct APixstr {
unsigned short mask[4]; /* jitter mask */
@@ -136,8 +136,8 @@ void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec,
float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4);
/* exported to shadeinput.c */
-void zbuf_make_winmat(Render *re, float winmat[][4]);
-void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]);
+void zbuf_make_winmat(Render *re, float winmat[4][4]);
+void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]);
/* sould not really be exposed, bad! */
void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]);
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index c3babf99d51..b31aff82777 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -90,6 +90,11 @@ RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRe
return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0);
}
+RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
+{
+ return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4);
+}
+
/* VlakPrimitive */
RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp
index f797f7a4311..01e592cba0c 100644
--- a/source/blender/render/intern/raytrace/rayobject_instance.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp
@@ -75,7 +75,7 @@ typedef struct InstanceRayObject {
} InstanceRayObject;
-RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob)
+RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob)
{
InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
assert(RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */
@@ -173,13 +173,13 @@ static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
static void RE_rayobject_instance_free(RayObject *o)
{
- InstanceRayObject *obj = (InstanceRayObject*)o;
+ InstanceRayObject *obj = (InstanceRayObject *)o;
MEM_freeN(obj);
}
static float RE_rayobject_instance_cost(RayObject *o)
{
- InstanceRayObject *obj = (InstanceRayObject*)o;
+ InstanceRayObject *obj = (InstanceRayObject *)o;
return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE;
}
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index afb8fe6c3b5..e4fd5a6d41e 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -223,7 +223,7 @@ static Node *addnode(Octree *oc)
return oc->adrnode[index] + (oc->nodecount & 4095);
}
-static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3])
+static int face_in_node(RayFace *face, short x, short y, short z, float rtf[4][3])
{
static float nor[3], d;
float fx, fy, fz;
@@ -321,12 +321,12 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short
calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]);
}
-static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3])
+static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[4][3], float rtf[4][3])
{
int ocx1, ocx2, ocy1, ocy2;
int x, y, dx = 0, dy = 0;
float ox1, ox2, oy1, oy2;
- float labda, labdao, labdax, labday, ldx, ldy;
+ float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy;
ocx1 = rts[b1][c1];
ocy1 = rts[b1][c2];
@@ -345,40 +345,40 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa
if (ox1 != ox2) {
if (ox2 - ox1 > 0.0f) {
- labdax = (ox1 - ocx1 - 1.0f) / (ox1 - ox2);
+ lambda_x = (ox1 - ocx1 - 1.0f) / (ox1 - ox2);
ldx = -1.0f / (ox1 - ox2);
dx = 1;
}
else {
- labdax = (ox1 - ocx1) / (ox1 - ox2);
+ lambda_x = (ox1 - ocx1) / (ox1 - ox2);
ldx = 1.0f / (ox1 - ox2);
dx = -1;
}
}
else {
- labdax = 1.0f;
+ lambda_x = 1.0f;
ldx = 0;
}
if (oy1 != oy2) {
if (oy2 - oy1 > 0.0f) {
- labday = (oy1 - ocy1 - 1.0f) / (oy1 - oy2);
+ lambda_y = (oy1 - ocy1 - 1.0f) / (oy1 - oy2);
ldy = -1.0f / (oy1 - oy2);
dy = 1;
}
else {
- labday = (oy1 - ocy1) / (oy1 - oy2);
+ lambda_y = (oy1 - ocy1) / (oy1 - oy2);
ldy = 1.0f / (oy1 - oy2);
dy = -1;
}
}
else {
- labday = 1.0f;
+ lambda_y = 1.0f;
ldy = 0;
}
x = ocx1; y = ocy1;
- labda = MIN2(labdax, labday);
+ lambda = MIN2(lambda_x, lambda_y);
while (TRUE) {
@@ -389,26 +389,26 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa
ocface[oc->ocres * x + y] = 1;
}
- labdao = labda;
- if (labdax == labday) {
- labdax += ldx;
+ lambda_o = lambda;
+ if (lambda_x == lambda_y) {
+ lambda_x += ldx;
x += dx;
- labday += ldy;
+ lambda_y += ldy;
y += dy;
}
else {
- if (labdax < labday) {
- labdax += ldx;
+ if (lambda_x < lambda_y) {
+ lambda_x += ldx;
x += dx;
}
else {
- labday += ldy;
+ lambda_y += ldy;
y += dy;
}
}
- labda = MIN2(labdax, labday);
- if (labda == labdao) break;
- if (labda >= 1.0f) break;
+ lambda = MIN2(lambda_x, lambda_y);
+ if (lambda == lambda_o) break;
+ if (lambda >= 1.0f) break;
}
ocface[oc->ocres * ocx2 + ocy2] = 1;
}
@@ -542,13 +542,13 @@ static void octree_fill_rayface(Octree *oc, RayFace *face)
oc2 = rts[1][c];
oc3 = rts[2][c];
if (!RE_rayface_isQuad(face)) {
- ocmin[c] = MIN3(oc1, oc2, oc3);
- ocmax[c] = MAX3(oc1, oc2, oc3);
+ ocmin[c] = min_iii(oc1, oc2, oc3);
+ ocmax[c] = max_iii(oc1, oc2, oc3);
}
else {
oc4 = rts[3][c];
- ocmin[c] = MIN4(oc1, oc2, oc3, oc4);
- ocmax[c] = MAX4(oc1, oc2, oc3, oc4);
+ ocmin[c] = min_iiii(oc1, oc2, oc3, oc4);
+ ocmax[c] = max_iiii(oc1, oc2, oc3, oc4);
}
if (ocmax[c] > oc->ocres - 1) ocmax[c] = oc->ocres - 1;
if (ocmin[c] < 0) ocmin[c] = 0;
@@ -667,10 +667,12 @@ static void RE_rayobject_octree_done(RayObject *tree)
oc->ocface = NULL;
MEM_freeN(oc->ro_nodes);
oc->ro_nodes = NULL;
-
+
+#if 0
printf("%f %f - %f\n", oc->min[0], oc->max[0], oc->ocfacx);
printf("%f %f - %f\n", oc->min[1], oc->max[1], oc->ocfacy);
printf("%f %f - %f\n", oc->min[2], oc->max[2], oc->ocfacz);
+#endif
}
static void RE_rayobject_octree_bb(RayObject *tree, float *min, float *max)
@@ -851,8 +853,8 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
OcVal ocval;
float vec1[3], vec2[3], start[3], end[3];
float u1, u2, ox1, ox2, oy1, oy2, oz1, oz2;
- float labdao, labdax, ldx, labday, ldy, labdaz, ldz, ddalabda;
- float olabda = 0;
+ float lambda_o, lambda_x, ldx, lambda_y, ldy, lambda_z, ldz, dda_lambda;
+ float o_lambda = 0;
int dx, dy, dz;
int xo, yo, zo, c1 = 0;
int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2;
@@ -871,7 +873,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
copy_v3_v3(start, is->start);
madd_v3_v3v3fl(end, is->start, is->dir, is->dist);
ldx = is->dir[0] * is->dist;
- olabda = is->dist;
+ o_lambda = is->dist;
u1 = 0.0f;
u2 = 1.0f;
@@ -939,68 +941,68 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
float dox, doy, doz;
int eqval;
- /* calc labda en ld */
+ /* calc lambda en ld */
dox = ox1 - ox2;
doy = oy1 - oy2;
doz = oz1 - oz2;
if (dox < -FLT_EPSILON) {
ldx = -1.0f / dox;
- labdax = (ocx1 - ox1 + 1.0f) * ldx;
+ lambda_x = (ocx1 - ox1 + 1.0f) * ldx;
dx = 1;
}
else if (dox > FLT_EPSILON) {
ldx = 1.0f / dox;
- labdax = (ox1 - ocx1) * ldx;
+ lambda_x = (ox1 - ocx1) * ldx;
dx = -1;
}
else {
- labdax = 1.0f;
+ lambda_x = 1.0f;
ldx = 0;
dx = 0;
}
if (doy < -FLT_EPSILON) {
ldy = -1.0f / doy;
- labday = (ocy1 - oy1 + 1.0f) * ldy;
+ lambda_y = (ocy1 - oy1 + 1.0f) * ldy;
dy = 1;
}
else if (doy > FLT_EPSILON) {
ldy = 1.0f / doy;
- labday = (oy1 - ocy1) * ldy;
+ lambda_y = (oy1 - ocy1) * ldy;
dy = -1;
}
else {
- labday = 1.0f;
+ lambda_y = 1.0f;
ldy = 0;
dy = 0;
}
if (doz < -FLT_EPSILON) {
ldz = -1.0f / doz;
- labdaz = (ocz1 - oz1 + 1.0f) * ldz;
+ lambda_z = (ocz1 - oz1 + 1.0f) * ldz;
dz = 1;
}
else if (doz > FLT_EPSILON) {
ldz = 1.0f / doz;
- labdaz = (oz1 - ocz1) * ldz;
+ lambda_z = (oz1 - ocz1) * ldz;
dz = -1;
}
else {
- labdaz = 1.0f;
+ lambda_z = 1.0f;
ldz = 0;
dz = 0;
}
xo = ocx1; yo = ocy1; zo = ocz1;
- ddalabda = MIN3(labdax, labday, labdaz);
+ dda_lambda = min_fff(lambda_x, lambda_y, lambda_z);
vec2[0] = ox1;
vec2[1] = oy1;
vec2[2] = oz1;
/* this loop has been constructed to make sure the first and last node of ray
- * are always included, even when ddalabda==1.0f or larger */
+ * are always included, even when dda_lambda==1.0f or larger */
while (TRUE) {
@@ -1010,83 +1012,83 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
/* calculate ray intersection with octree node */
copy_v3_v3(vec1, vec2);
// dox, y, z is negative
- vec2[0] = ox1 - ddalabda * dox;
- vec2[1] = oy1 - ddalabda * doy;
- vec2[2] = oz1 - ddalabda * doz;
+ vec2[0] = ox1 - dda_lambda * dox;
+ vec2[1] = oy1 - dda_lambda * doy;
+ vec2[2] = oz1 - dda_lambda * doz;
calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2);
- //is->dist = (u1+ddalabda*(u2-u1))*olabda;
+ //is->dist = (u1 + dda_lambda * (u2 - u1)) * o_lambda;
if (testnode(oc, is, no, ocval) )
found = 1;
- if (is->dist < (u1 + ddalabda * (u2 - u1)) * olabda)
+ if (is->dist < (u1 + dda_lambda * (u2 - u1)) * o_lambda)
return found;
}
- labdao = ddalabda;
+ lambda_o = dda_lambda;
/* traversing octree nodes need careful detection of smallest values, with proper
- * exceptions for equal labdas */
- eqval = (labdax == labday);
- if (labday == labdaz) eqval += 2;
- if (labdax == labdaz) eqval += 4;
+ * exceptions for equal lambdas */
+ eqval = (lambda_x == lambda_y);
+ if (lambda_y == lambda_z) eqval += 2;
+ if (lambda_x == lambda_z) eqval += 4;
if (eqval) { // only 4 cases exist!
if (eqval == 7) { // x=y=z
- xo += dx; labdax += ldx;
- yo += dy; labday += ldy;
- zo += dz; labdaz += ldz;
+ xo += dx; lambda_x += ldx;
+ yo += dy; lambda_y += ldy;
+ zo += dz; lambda_z += ldz;
}
else if (eqval == 1) { // x=y
- if (labday < labdaz) {
- xo += dx; labdax += ldx;
- yo += dy; labday += ldy;
+ if (lambda_y < lambda_z) {
+ xo += dx; lambda_x += ldx;
+ yo += dy; lambda_y += ldy;
}
else {
- zo += dz; labdaz += ldz;
+ zo += dz; lambda_z += ldz;
}
}
else if (eqval == 2) { // y=z
- if (labdax < labday) {
- xo += dx; labdax += ldx;
+ if (lambda_x < lambda_y) {
+ xo += dx; lambda_x += ldx;
}
else {
- yo += dy; labday += ldy;
- zo += dz; labdaz += ldz;
+ yo += dy; lambda_y += ldy;
+ zo += dz; lambda_z += ldz;
}
}
else { // x=z
- if (labday < labdax) {
- yo += dy; labday += ldy;
+ if (lambda_y < lambda_x) {
+ yo += dy; lambda_y += ldy;
}
else {
- xo += dx; labdax += ldx;
- zo += dz; labdaz += ldz;
+ xo += dx; lambda_x += ldx;
+ zo += dz; lambda_z += ldz;
}
}
}
else { // all three different, just three cases exist
- eqval = (labdax < labday);
- if (labday < labdaz) eqval += 2;
- if (labdax < labdaz) eqval += 4;
+ eqval = (lambda_x < lambda_y);
+ if (lambda_y < lambda_z) eqval += 2;
+ if (lambda_x < lambda_z) eqval += 4;
if (eqval == 7 || eqval == 5) { // x smallest
- xo += dx; labdax += ldx;
+ xo += dx; lambda_x += ldx;
}
else if (eqval == 2 || eqval == 6) { // y smallest
- yo += dy; labday += ldy;
+ yo += dy; lambda_y += ldy;
}
else { // z smallest
- zo += dz; labdaz += ldz;
+ zo += dz; lambda_z += ldz;
}
}
- ddalabda = MIN3(labdax, labday, labdaz);
- if (ddalabda == labdao) break;
+ dda_lambda = min_fff(lambda_x, lambda_y, lambda_z);
+ if (dda_lambda == lambda_o) break;
/* to make sure the last node is always checked */
- if (labdao >= 1.0f) break;
+ if (lambda_o >= 1.0f) break;
}
}
diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
index d03bdb74407..3e80deefecd 100644
--- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
@@ -38,12 +38,12 @@ int tot_hints = 0;
#include "MEM_guardedalloc.h"
-#include "BKE_global.h"
-
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
+#include "BKE_global.h"
+
#include "rayintersection.h"
#include "rayobject.h"
#include "rayobject_rtbuild.h"
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
new file mode 100644
index 00000000000..7c5d6038e0a
--- /dev/null
+++ b/source/blender/render/intern/source/bake.c
@@ -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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
+ * Contributors: Vertex color baking, Copyright 2011 AutoCRC
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/bake.c
+ * \ingroup render
+ */
+
+
+/* system includes */
+#include <stdio.h>
+#include <string.h>
+
+/* External modules: */
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
+
+/* local include */
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "shading.h"
+#include "zbuf.h"
+
+#include "PIL_time.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
+/* ************************* bake ************************ */
+
+
+typedef struct BakeShade {
+ ShadeSample ssamp;
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+
+ ZSpan *zspan;
+ Image *ima;
+ ImBuf *ibuf;
+
+ int rectx, recty, quad, type, vdone;
+ bool ready;
+
+ float dir[3];
+ Object *actob;
+
+ /* Output: vertex color or image data. If vcol is not NULL, rect and
+ * rect_float should be NULL. */
+ MPoly *mpoly;
+ MLoop *mloop;
+ MLoopCol *vcol;
+
+ unsigned int *rect;
+ float *rect_float;
+
+ /* displacement buffer used for normalization with unknown maximal distance */
+ bool use_displacement_buffer;
+ float *displacement_buffer;
+ float displacement_min, displacement_max;
+
+ bool use_mask;
+ char *rect_mask; /* bake pixel mask */
+
+ float dxco[3], dyco[3];
+
+ short *do_update;
+
+ struct ColorSpace *rect_colorspace;
+} BakeShade;
+
+static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v)
+{
+ if (quad)
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
+
+ /* cache for shadow */
+ shi->samplenr = R.shadowsamplenr[shi->thread]++;
+
+ shi->mask = 0xFFFF; /* all samples */
+
+ shi->u = -u;
+ shi->v = -v;
+ shi->xs = x;
+ shi->ys = y;
+
+ shade_input_set_uv(shi);
+ shade_input_set_normals(shi);
+
+ /* no normal flip */
+ if (shi->flippednor)
+ shade_input_flip_normals(shi);
+
+ /* set up view vector to look right at the surface (note that the normal
+ * is negated in the renderer so it does not need to be done here) */
+ shi->view[0] = shi->vn[0];
+ shi->view[1] = shi->vn[1];
+ shi->view[2] = shi->vn[2];
+}
+
+static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang)
+{
+ BakeShade *bs = handle;
+ ShadeSample *ssamp = &bs->ssamp;
+ ShadeResult shr;
+ VlakRen *vlr = shi->vlr;
+
+ shade_input_init_material(shi);
+
+ if (bs->type == RE_BAKE_AO) {
+ ambient_occlusion(shi);
+
+ if (R.r.bake_flag & R_BAKE_NORMALIZE) {
+ copy_v3_v3(shr.combined, shi->ao);
+ }
+ else {
+ zero_v3(shr.combined);
+ environment_lighting_apply(shi, &shr);
+ }
+ }
+ else {
+ if (bs->type == RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
+ shi->r = shi->g = shi->b = 1.0f;
+
+ shade_input_set_shade_texco(shi);
+
+ /* only do AO for a full bake (and obviously AO bakes)
+ * AO for light bakes is a leftover and might not be needed */
+ if (ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT))
+ shade_samples_do_AO(ssamp);
+
+ if (shi->mat->nodetree && shi->mat->use_nodes) {
+ ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
+ shi->mat = vlr->mat; /* shi->mat is being set in nodetree */
+ }
+ else
+ shade_material_loop(shi, &shr);
+
+ if (bs->type == RE_BAKE_NORMALS) {
+ float nor[3];
+
+ copy_v3_v3(nor, shi->vn);
+
+ if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) {
+ /* pass */
+ }
+ else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
+ float mat[3][3], imat[3][3];
+
+ /* bitangent */
+ if (tvn && ttang) {
+ copy_v3_v3(mat[0], ttang);
+ cross_v3_v3v3(mat[1], tvn, ttang);
+ mul_v3_fl(mat[1], ttang[3]);
+ copy_v3_v3(mat[2], tvn);
+ }
+ else {
+ copy_v3_v3(mat[0], shi->nmaptang);
+ cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang);
+ mul_v3_fl(mat[1], shi->nmaptang[3]);
+ copy_v3_v3(mat[2], shi->nmapnorm);
+ }
+
+ invert_m3_m3(imat, mat);
+ mul_m3_v3(imat, nor);
+ }
+ else if (R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
+ mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */
+ else if (R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
+ mul_mat3_m4_v3(R.viewinv, nor);
+
+ normalize_v3(nor); /* in case object has scaling */
+
+ /* The invert of the red channel is to make
+ * the normal map compliant with the outside world.
+ * It needs to be done because in Blender
+ * the normal used in the renderer points inward. It is generated
+ * this way in calc_vertexnormals(). Should this ever change
+ * this negate must be removed. */
+ shr.combined[0] = (-nor[0]) / 2.0f + 0.5f;
+ shr.combined[1] = nor[1] / 2.0f + 0.5f;
+ shr.combined[2] = nor[2] / 2.0f + 0.5f;
+ }
+ else if (bs->type == RE_BAKE_TEXTURE) {
+ copy_v3_v3(shr.combined, &shi->r);
+ shr.alpha = shi->alpha;
+ }
+ else if (bs->type == RE_BAKE_SHADOW) {
+ copy_v3_v3(shr.combined, shr.shad);
+ shr.alpha = shi->alpha;
+ }
+ else if (bs->type == RE_BAKE_SPEC_COLOR) {
+ copy_v3_v3(shr.combined, &shi->specr);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_SPEC_INTENSITY) {
+ copy_v3_fl(shr.combined, shi->spec);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_MIRROR_COLOR) {
+ copy_v3_v3(shr.combined, &shi->mirr);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_MIRROR_INTENSITY) {
+ copy_v3_fl(shr.combined, shi->ray_mirror);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_ALPHA) {
+ copy_v3_fl(shr.combined, shi->alpha);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_EMIT) {
+ copy_v3_fl(shr.combined, shi->emit);
+ shr.alpha = 1.0f;
+ }
+ }
+
+ if (bs->rect_float && !bs->vcol) {
+ float *col = bs->rect_float + 4 * (bs->rectx * y + x);
+ copy_v3_v3(col, shr.combined);
+ if (bs->type == RE_BAKE_ALL || bs->type == RE_BAKE_TEXTURE) {
+ col[3] = shr.alpha;
+ }
+ else {
+ col[3] = 1.0;
+ }
+ }
+ else {
+ /* Target is char (LDR). */
+ unsigned char col[4];
+
+ if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
+ float rgb[3];
+
+ copy_v3_v3(rgb, shr.combined);
+ if (R.scene_color_manage) {
+ /* Vertex colors have no way to specify color space, so they
+ * default to sRGB. */
+ if (!bs->vcol)
+ IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace);
+ else
+ linearrgb_to_srgb_v3_v3(rgb, rgb);
+ }
+ rgb_float_to_uchar(col, rgb);
+ }
+ else {
+ rgb_float_to_uchar(col, shr.combined);
+ }
+
+ if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
+ col[3] = FTOCHAR(shr.alpha);
+ }
+ else {
+ col[3] = 255;
+ }
+
+ if (bs->vcol) {
+ /* Vertex color baking. Vcol has no useful alpha channel (it exists
+ * but is used only for vertex painting). */
+ bs->vcol->r = col[0];
+ bs->vcol->g = col[1];
+ bs->vcol->b = col[2];
+ }
+ else {
+ unsigned char *imcol = (unsigned char *)(bs->rect + bs->rectx * y + x);
+ copy_v4_v4_char((char *)imcol, (char *)col);
+ }
+
+ }
+
+ if (bs->rect_mask) {
+ bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED;
+ }
+}
+
+static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y)
+{
+ BakeShade *bs = handle;
+ float disp;
+
+ if (R.r.bake_flag & R_BAKE_NORMALIZE) {
+ if (R.r.bake_maxdist)
+ disp = (dist + R.r.bake_maxdist) / (R.r.bake_maxdist * 2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
+ else
+ disp = dist;
+ }
+ else {
+ disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
+ }
+
+ if (bs->displacement_buffer) {
+ float *displacement = bs->displacement_buffer + (bs->rectx * y + x);
+ *displacement = disp;
+ bs->displacement_min = min_ff(bs->displacement_min, disp);
+ bs->displacement_max = max_ff(bs->displacement_max, disp);
+ }
+
+ if (bs->rect_float && !bs->vcol) {
+ float *col = bs->rect_float + 4 * (bs->rectx * y + x);
+ col[0] = col[1] = col[2] = disp;
+ col[3] = 1.0f;
+ }
+ else {
+ /* Target is char (LDR). */
+ unsigned char col[4];
+ col[0] = col[1] = col[2] = FTOCHAR(disp);
+ col[3] = 255;
+
+ if (bs->vcol) {
+ /* Vertex color baking. Vcol has no useful alpha channel (it exists
+ * but is used only for vertex painting). */
+ bs->vcol->r = col[0];
+ bs->vcol->g = col[1];
+ bs->vcol->b = col[2];
+ }
+ else {
+ char *imcol = (char *)(bs->rect + bs->rectx * y + x);
+ copy_v4_v4_char((char *)imcol, (char *)col);
+ }
+ }
+ if (bs->rect_mask) {
+ bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED;
+ }
+}
+
+static int bake_intersect_tree(RayObject *raytree, Isect *isect, float *start, float *dir, float sign, float *hitco, float *dist)
+{
+ float maxdist;
+ int hit;
+
+ /* might be useful to make a user setting for maxsize*/
+ if (R.r.bake_maxdist > 0.0f)
+ maxdist = R.r.bake_maxdist;
+ else
+ maxdist = RE_RAYTRACE_MAXDIST + R.r.bake_biasdist;
+
+ /* 'dir' is always normalized */
+ madd_v3_v3v3fl(isect->start, start, dir, -R.r.bake_biasdist);
+
+ mul_v3_v3fl(isect->dir, dir, sign);
+
+ isect->dist = maxdist;
+
+ hit = RE_rayobject_raycast(raytree, isect);
+ if (hit) {
+ madd_v3_v3v3fl(hitco, isect->start, isect->dir, isect->dist);
+
+ *dist = isect->dist;
+ }
+
+ return hit;
+}
+
+static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
+{
+ VlakRen *vlr = bs->vlr;
+ float A, d1, d2, d3, *v1, *v2, *v3;
+
+ if (bs->quad) {
+ v1 = vlr->v1->co;
+ v2 = vlr->v3->co;
+ v3 = vlr->v4->co;
+ }
+ else {
+ v1 = vlr->v1->co;
+ v2 = vlr->v2->co;
+ v3 = vlr->v3->co;
+ }
+
+ /* formula derived from barycentric coordinates:
+ * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
+ * then taking u and v partial derivatives to get dxco and dyco */
+ A = (uv2[0] - uv1[0]) * (uv3[1] - uv1[1]) - (uv3[0] - uv1[0]) * (uv2[1] - uv1[1]);
+
+ if (fabsf(A) > FLT_EPSILON) {
+ A = 0.5f / A;
+
+ d1 = uv2[1] - uv3[1];
+ d2 = uv3[1] - uv1[1];
+ d3 = uv1[1] - uv2[1];
+ bs->dxco[0] = (v1[0] * d1 + v2[0] * d2 + v3[0] * d3) * A;
+ bs->dxco[1] = (v1[1] * d1 + v2[1] * d2 + v3[1] * d3) * A;
+ bs->dxco[2] = (v1[2] * d1 + v2[2] * d2 + v3[2] * d3) * A;
+
+ d1 = uv3[0] - uv2[0];
+ d2 = uv1[0] - uv3[0];
+ d3 = uv2[0] - uv1[0];
+ bs->dyco[0] = (v1[0] * d1 + v2[0] * d2 + v3[0] * d3) * A;
+ bs->dyco[1] = (v1[1] * d1 + v2[1] * d2 + v3[1] * d3) * A;
+ bs->dyco[2] = (v1[2] * d1 + v2[2] * d2 + v3[2] * d3) * A;
+ }
+ else {
+ bs->dxco[0] = bs->dxco[1] = bs->dxco[2] = 0.0f;
+ bs->dyco[0] = bs->dyco[1] = bs->dyco[2] = 0.0f;
+ }
+
+ if (bs->obi->flag & R_TRANSFORMED) {
+ mul_m3_v3(bs->obi->nmat, bs->dxco);
+ mul_m3_v3(bs->obi->nmat, bs->dyco);
+ }
+}
+
+static void do_bake_shade(void *handle, int x, int y, float u, float v)
+{
+ BakeShade *bs = handle;
+ VlakRen *vlr = bs->vlr;
+ ObjectInstanceRen *obi = bs->obi;
+ Object *ob = obi->obr->ob;
+ float l, *v1, *v2, *v3, tvn[3], ttang[4];
+ int quad;
+ ShadeSample *ssamp = &bs->ssamp;
+ ShadeInput *shi = ssamp->shi;
+
+ /* fast threadsafe break test */
+ if (R.test_break(R.tbh))
+ return;
+
+ /* setup render coordinates */
+ if (bs->quad) {
+ v1 = vlr->v1->co;
+ v2 = vlr->v3->co;
+ v3 = vlr->v4->co;
+ }
+ else {
+ v1 = vlr->v1->co;
+ v2 = vlr->v2->co;
+ v3 = vlr->v3->co;
+ }
+
+ l = 1.0f - u - v;
+
+ /* shrink barycentric coordinates inwards slightly to avoid some issues
+ * where baking selected to active might just miss the other face at the
+ * near the edge of a face */
+ if (bs->actob) {
+ const float eps = 1.0f - 1e-4f;
+ float invsum;
+
+ u = (u - 0.5f) * eps + 0.5f;
+ v = (v - 0.5f) * eps + 0.5f;
+ l = (l - 0.5f) * eps + 0.5f;
+
+ invsum = 1.0f / (u + v + l);
+
+ u *= invsum;
+ v *= invsum;
+ l *= invsum;
+ }
+
+ /* renderco */
+ shi->co[0] = l * v3[0] + u * v1[0] + v * v2[0];
+ shi->co[1] = l * v3[1] + u * v1[1] + v * v2[1];
+ shi->co[2] = l * v3[2] + u * v1[2] + v * v2[2];
+
+ /* avoid self shadow with vertex bake from adjacent faces [#33729] */
+ if ((bs->vcol != NULL) && (bs->actob == NULL)) {
+ madd_v3_v3fl(shi->co, vlr->n, 0.0001f);
+ }
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_v3(obi->mat, shi->co);
+
+ copy_v3_v3(shi->dxco, bs->dxco);
+ copy_v3_v3(shi->dyco, bs->dyco);
+
+ quad = bs->quad;
+ bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
+
+ if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
+ shade_input_set_shade_texco(shi);
+ copy_v3_v3(tvn, shi->nmapnorm);
+ copy_v4_v4(ttang, shi->nmaptang);
+ }
+
+ /* if we are doing selected to active baking, find point on other face */
+ if (bs->actob) {
+ Isect isec, minisec;
+ float co[3], minco[3], dist, mindist = 0.0f;
+ int hit, sign, dir = 1;
+
+ /* intersect with ray going forward and backward*/
+ hit = 0;
+ memset(&minisec, 0, sizeof(minisec));
+ minco[0] = minco[1] = minco[2] = 0.0f;
+
+ copy_v3_v3(bs->dir, shi->vn);
+
+ for (sign = -1; sign <= 1; sign += 2) {
+ memset(&isec, 0, sizeof(isec));
+ isec.mode = RE_RAY_MIRROR;
+
+ isec.orig.ob = obi;
+ isec.orig.face = vlr;
+ isec.userdata = bs->actob;
+ isec.check = RE_CHECK_VLR_BAKE;
+ isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+
+ if (bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
+ if (!hit || len_squared_v3v3(shi->co, co) < len_squared_v3v3(shi->co, minco)) {
+ minisec = isec;
+ mindist = dist;
+ copy_v3_v3(minco, co);
+ hit = 1;
+ dir = sign;
+ }
+ }
+ }
+
+ if (bs->type == RE_BAKE_DISPLACEMENT) {
+ if (hit)
+ bake_displacement(handle, shi, (dir == -1) ? mindist : -mindist, x, y);
+ else
+ bake_displacement(handle, shi, 0.0f, x, y);
+ return;
+ }
+
+ /* if hit, we shade from the new point, otherwise from point one starting face */
+ if (hit) {
+ obi = (ObjectInstanceRen *)minisec.hit.ob;
+ vlr = (VlakRen *)minisec.hit.face;
+ quad = (minisec.isect == 2);
+ copy_v3_v3(shi->co, minco);
+
+ u = -minisec.u;
+ v = -minisec.v;
+ bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
+ }
+ }
+
+ if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
+ bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
+ else
+ bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
+}
+
+static int get_next_bake_face(BakeShade *bs)
+{
+ ObjectRen *obr;
+ VlakRen *vlr;
+ MTFace *tface;
+ static int v = 0, vdone = false;
+ static ObjectInstanceRen *obi = NULL;
+
+ if (bs == NULL) {
+ vlr = NULL;
+ v = vdone = false;
+ obi = R.instancetable.first;
+ return 0;
+ }
+
+ BLI_lock_thread(LOCK_CUSTOM1);
+
+ for (; obi; obi = obi->next, v = 0) {
+ obr = obi->obr;
+
+ for (; v < obr->totvlak; v++) {
+ vlr = RE_findOrAddVlak(obr, v);
+
+ if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
+ if (R.r.bake_flag & R_BAKE_VCOL) {
+ /* Gather face data for vertex color bake */
+ Mesh *me;
+ int *origindex, vcollayer;
+ CustomDataLayer *cdl;
+
+ if (obr->ob->type != OB_MESH)
+ continue;
+ me = obr->ob->data;
+
+ origindex = RE_vlakren_get_origindex(obr, vlr, 0);
+ if (origindex == NULL)
+ continue;
+ if (*origindex >= me->totpoly) {
+ /* Small hack for Array modifier, which gives false
+ original indices - z0r */
+ continue;
+ }
+#if 0
+ /* Only shade selected faces. */
+ if ((me->mface[*origindex].flag & ME_FACE_SEL) == 0)
+ continue;
+#endif
+
+ vcollayer = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL);
+ if (vcollayer == -1)
+ continue;
+
+ cdl = &me->ldata.layers[vcollayer];
+ bs->mpoly = me->mpoly + *origindex;
+ bs->vcol = ((MLoopCol *)cdl->data) + bs->mpoly->loopstart;
+ bs->mloop = me->mloop + bs->mpoly->loopstart;
+
+ /* Tag mesh for reevaluation. */
+ DAG_id_tag_update(&me->id, 0);
+ }
+ else {
+ Image *ima = NULL;
+ ImBuf *ibuf = NULL;
+ const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
+ const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
+
+ tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
+
+ if (!tface || !tface->tpage)
+ continue;
+
+ ima = tface->tpage;
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
+ if (ibuf == NULL)
+ continue;
+
+ if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ continue;
+ }
+
+ if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ continue;
+ }
+
+ if (ima->flag & IMA_USED_FOR_RENDER) {
+ ima->id.flag &= ~LIB_DOIT;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ continue;
+ }
+
+ /* find the image for the first time? */
+ if (ima->id.flag & LIB_DOIT) {
+ ima->id.flag &= ~LIB_DOIT;
+
+ /* we either fill in float or char, this ensures things go fine */
+ if (ibuf->rect_float)
+ imb_freerectImBuf(ibuf);
+ /* clear image */
+ if (R.r.bake_flag & R_BAKE_CLEAR) {
+ if (R.r.bake_mode == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
+ else
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+ }
+ /* might be read by UI to set active image for display */
+ R.bakebuf = ima;
+ }
+
+ /* Tag image for redraw. */
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+
+ bs->obi = obi;
+ bs->vlr = vlr;
+ bs->vdone++; /* only for error message if nothing was rendered */
+ v++;
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return 1;
+ }
+ }
+ }
+
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return 0;
+}
+
+static void bake_single_vertex(BakeShade *bs, VertRen *vert, float u, float v)
+{
+ int *origindex, i;
+ MLoopCol *basevcol;
+ MLoop *mloop;
+
+ origindex = RE_vertren_get_origindex(bs->obi->obr, vert, 0);
+ if (!origindex || *origindex == ORIGINDEX_NONE)
+ return;
+
+ /* Search for matching vertex index and apply shading. */
+ for (i = 0; i < bs->mpoly->totloop; i++) {
+ mloop = bs->mloop + i;
+ if (mloop->v != *origindex)
+ continue;
+ basevcol = bs->vcol;
+ bs->vcol = basevcol + i;
+ do_bake_shade(bs, 0, 0, u, v);
+ bs->vcol = basevcol;
+ break;
+ }
+}
+
+/* Bake all vertices of a face. Actually, this still works on a face-by-face
+ * basis, and each vertex on each face is shaded. Vertex colors are a property
+ * of loops, not vertices. */
+static void shade_verts(BakeShade *bs)
+{
+ VlakRen *vlr = bs->vlr;
+
+ /* Disable baking to image; write to vcol instead. vcol pointer is set in
+ * bake_single_vertex. */
+ bs->ima = NULL;
+ bs->rect = NULL;
+ bs->rect_float = NULL;
+ bs->displacement_buffer = NULL;
+ bs->displacement_min = FLT_MAX;
+ bs->displacement_max = -FLT_MAX;
+
+ bs->quad = 0;
+
+ /* No anti-aliasing for vertices. */
+ zero_v3(bs->dxco);
+ zero_v3(bs->dyco);
+
+ /* Shade each vertex of the face. u and v are barycentric coordinates; since
+ * we're only interested in vertices, these will be 0 or 1. */
+ if ((vlr->flag & R_FACE_SPLIT) == 0) {
+ /* Processing triangle face, whole quad, or first half of split quad. */
+
+ bake_single_vertex(bs, bs->vlr->v1, 1.0f, 0.0f);
+ bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
+ bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
+
+ if (vlr->v4) {
+ bs->quad = 1;
+ bake_single_vertex(bs, bs->vlr->v4, 0.0f, 0.0f);
+ }
+ }
+ else {
+ /* Processing second half of split quad. Only one vertex to go. */
+ if (vlr->flag & R_DIVIDE_24) {
+ bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
+ }
+ else {
+ bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
+ }
+ }
+}
+
+/* already have tested for tface and ima and zspan */
+static void shade_tface(BakeShade *bs)
+{
+ VlakRen *vlr = bs->vlr;
+ ObjectInstanceRen *obi = bs->obi;
+ ObjectRen *obr = obi->obr;
+ MTFace *tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
+ Image *ima = tface->tpage;
+ float vec[4][2];
+ int a, i1, i2, i3;
+
+ /* check valid zspan */
+ if (ima != bs->ima) {
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
+ bs->ima = ima;
+ bs->ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ /* note, these calls only free/fill contents of zspan struct, not zspan itself */
+ zbuf_free_span(bs->zspan);
+ zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
+ }
+
+ bs->rectx = bs->ibuf->x;
+ bs->recty = bs->ibuf->y;
+ bs->rect = bs->ibuf->rect;
+ bs->rect_colorspace = bs->ibuf->rect_colorspace;
+ bs->rect_float = bs->ibuf->rect_float;
+ bs->vcol = NULL;
+ bs->quad = 0;
+ bs->rect_mask = NULL;
+ bs->displacement_buffer = NULL;
+
+ if (bs->use_mask || bs->use_displacement_buffer) {
+ BakeImBufuserData *userdata = bs->ibuf->userdata;
+ if (userdata == NULL) {
+ BLI_lock_thread(LOCK_CUSTOM1);
+ userdata = bs->ibuf->userdata;
+ if (userdata == NULL) /* since the thread was locked, its possible another thread alloced the value */
+ userdata = MEM_callocN(sizeof(BakeImBufuserData), "BakeImBufuserData");
+
+ if (bs->use_mask) {
+ if (userdata->mask_buffer == NULL) {
+ userdata->mask_buffer = MEM_callocN(sizeof(char) * bs->rectx * bs->recty, "BakeMask");
+ }
+ }
+
+ if (bs->use_displacement_buffer)
+ userdata->displacement_buffer = MEM_callocN(sizeof(float) * bs->rectx * bs->recty, "BakeDisp");
+
+ bs->ibuf->userdata = userdata;
+
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ }
+
+ bs->rect_mask = userdata->mask_buffer;
+ bs->displacement_buffer = userdata->displacement_buffer;
+ }
+
+ /* get pixel level vertex coordinates */
+ for (a = 0; a < 4; a++) {
+ /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
+ * where a pixel gets in between 2 faces or the middle of a quad,
+ * camera aligned quads also have this problem but they are less common.
+ * Add a small offset to the UVs, fixes bug #18685 - Campbell */
+ vec[a][0] = tface->uv[a][0] * (float)bs->rectx - (0.5f + 0.001f);
+ vec[a][1] = tface->uv[a][1] * (float)bs->recty - (0.5f + 0.002f);
+ }
+
+ /* UV indices have to be corrected for possible quad->tria splits */
+ i1 = 0; i2 = 1; i3 = 2;
+ vlr_set_uv_indices(vlr, &i1, &i2, &i3);
+ bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
+ zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
+
+ if (vlr->v4) {
+ bs->quad = 1;
+ bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
+ zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
+ }
+}
+
+static void *do_bake_thread(void *bs_v)
+{
+ BakeShade *bs = bs_v;
+
+ while (get_next_bake_face(bs)) {
+ if (R.r.bake_flag & R_BAKE_VCOL) {
+ shade_verts(bs);
+ }
+ else {
+ shade_tface(bs);
+ }
+
+ /* fast threadsafe break test */
+ if (R.test_break(R.tbh))
+ break;
+
+ /* access is not threadsafe but since its just true/false probably ok
+ * only used for interactive baking */
+ if (bs->do_update) {
+ *bs->do_update = true;
+ }
+ }
+ bs->ready = true;
+
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
+ return NULL;
+}
+
+void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter)
+{
+ /* must check before filtering */
+ const short is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf);
+
+ /* Margin */
+ if (filter) {
+ IMB_filter_extend(ibuf, mask, filter);
+ }
+
+ /* if the bake results in new alpha then change the image setting */
+ if (is_new_alpha) {
+ ibuf->planes = R_IMF_PLANES_RGBA;
+ }
+ else {
+ if (filter && ibuf->planes != R_IMF_PLANES_RGBA) {
+ /* clear alpha added by filtering */
+ IMB_rectfill_alpha(ibuf, 1.0f);
+ }
+ }
+}
+
+void RE_bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max)
+{
+ int i;
+ float *current_displacement = displacement;
+ char *current_mask = mask;
+ float max_distance;
+
+ max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max));
+
+ for (i = 0; i < ibuf->x * ibuf->y; i++) {
+ if (*current_mask == FILTER_MASK_USED) {
+ float normalized_displacement;
+
+ if (max_distance > 1e-5f)
+ normalized_displacement = (*current_displacement + max_distance) / (max_distance * 2);
+ else
+ normalized_displacement = 0.5f;
+
+ if (ibuf->rect_float) {
+ /* currently baking happens to RGBA only */
+ float *fp = ibuf->rect_float + i * 4;
+ fp[0] = fp[1] = fp[2] = normalized_displacement;
+ fp[3] = 1.0f;
+ }
+
+ if (ibuf->rect) {
+ unsigned char *cp = (unsigned char *) (ibuf->rect + i);
+ cp[0] = cp[1] = cp[2] = FTOCHAR(normalized_displacement);
+ cp[3] = 255;
+ }
+ }
+
+ current_displacement++;
+ current_mask++;
+ }
+}
+
+/* using object selection tags, the faces with UV maps get baked */
+/* render should have been setup */
+/* returns 0 if nothing was handled */
+int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress)
+{
+ BakeShade *handles;
+ ListBase threads;
+ Image *ima;
+ int a, vdone = false, result = BAKE_RESULT_OK;
+ bool use_mask = false;
+ bool use_displacement_buffer = false;
+
+ re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene);
+
+ /* initialize render global */
+ R = *re;
+ R.bakebuf = NULL;
+
+ /* initialize static vars */
+ get_next_bake_face(NULL);
+
+ /* do we need a mask? */
+ if (re->r.bake_filter)
+ use_mask = true;
+
+ /* do we need buffer to store displacements */
+ if (type == RE_BAKE_DISPLACEMENT) {
+ if ((R.r.bake_flag & R_BAKE_NORMALIZE) && R.r.bake_maxdist == 0.0f) {
+ use_displacement_buffer = true;
+ use_mask = true;
+ }
+ }
+
+ /* baker uses this flag to detect if image was initialized */
+ if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
+ for (ima = G.main->image.first; ima; ima = ima->id.next) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ ima->id.flag |= LIB_DOIT;
+ ima->flag &= ~IMA_USED_FOR_RENDER;
+ if (ibuf) {
+ ibuf->userdata = NULL; /* use for masking if needed */
+ }
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ }
+
+ BLI_init_threads(&threads, do_bake_thread, re->r.threads);
+
+ handles = MEM_callocN(sizeof(BakeShade) * re->r.threads, "BakeShade");
+
+ /* get the threads running */
+ for (a = 0; a < re->r.threads; a++) {
+ /* set defaults in handles */
+ handles[a].ssamp.shi[0].lay = re->lay;
+
+ if (type == RE_BAKE_SHADOW) {
+ handles[a].ssamp.shi[0].passflag = SCE_PASS_SHADOW;
+ }
+ else {
+ handles[a].ssamp.shi[0].passflag = SCE_PASS_COMBINED;
+ }
+ handles[a].ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC);
+ handles[a].ssamp.shi[0].thread = a;
+ handles[a].ssamp.tot = 1;
+
+ handles[a].type = type;
+ handles[a].actob = actob;
+ if (R.r.bake_flag & R_BAKE_VCOL)
+ handles[a].zspan = NULL;
+ else
+ handles[a].zspan = MEM_callocN(sizeof(ZSpan), "zspan for bake");
+
+ handles[a].use_mask = use_mask;
+ handles[a].use_displacement_buffer = use_displacement_buffer;
+
+ handles[a].do_update = do_update; /* use to tell the view to update */
+
+ handles[a].displacement_min = FLT_MAX;
+ handles[a].displacement_max = -FLT_MAX;
+
+ BLI_insert_thread(&threads, &handles[a]);
+ }
+
+ /* wait for everything to be done */
+ a = 0;
+ while (a != re->r.threads) {
+ PIL_sleep_ms(50);
+
+ /* calculate progress */
+ for (vdone = false, a = 0; a < re->r.threads; a++)
+ vdone += handles[a].vdone;
+ if (progress)
+ *progress = (float)(vdone / (float)re->totvlak);
+
+ for (a = 0; a < re->r.threads; a++) {
+ if (handles[a].ready == false) {
+ break;
+ }
+ }
+ }
+
+ /* filter and refresh images */
+ if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
+ float displacement_min = FLT_MAX, displacement_max = -FLT_MAX;
+
+ if (use_displacement_buffer) {
+ for (a = 0; a < re->r.threads; a++) {
+ displacement_min = min_ff(displacement_min, handles[a].displacement_min);
+ displacement_max = max_ff(displacement_max, handles[a].displacement_max);
+ }
+ }
+
+ for (ima = G.main->image.first; ima; ima = ima->id.next) {
+ if ((ima->id.flag & LIB_DOIT) == 0) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ BakeImBufuserData *userdata;
+
+ if (ima->flag & IMA_USED_FOR_RENDER)
+ result = BAKE_RESULT_FEEDBACK_LOOP;
+
+ if (!ibuf)
+ continue;
+
+ userdata = (BakeImBufuserData *)ibuf->userdata;
+ if (userdata) {
+ RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, re->r.bake_filter);
+
+ if (use_displacement_buffer) {
+ RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ displacement_min, displacement_max);
+ }
+ }
+
+ ibuf->userflags |= IB_BITMAPDIRTY;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ }
+
+ /* calculate return value */
+ for (a = 0; a < re->r.threads; a++) {
+ zbuf_free_span(handles[a].zspan);
+ MEM_freeN(handles[a].zspan);
+ }
+ }
+
+ MEM_freeN(handles);
+
+ BLI_end_threads(&threads);
+
+ if (vdone == 0) {
+ result = BAKE_RESULT_NO_OBJECTS;
+ }
+
+ return result;
+}
+
+struct Image *RE_bake_shade_get_image(void)
+{
+ return R.bakebuf;
+}
+
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 386086333e0..00a4da2e9c4 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -150,6 +150,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h
har->hasize= hasize;
har->zd= 0.0;
+ har->pool = re->pool;
return har;
}
@@ -161,7 +162,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h
*/
void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
- void (*vertexfunc)(float*), void (*termfunc)(void))
+ void (*vertexfunc)(float *), void (*termfunc)(void))
{
extern unsigned char hash[512];
ObjectRen *obr= NULL;
@@ -759,7 +760,7 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, f
/* note; autosmooth happens in object space still, after applying autosmooth we rotate */
/* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */
-static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int degr)
+static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int degr)
{
ASvert *asv, *asverts;
ASface *asf;
@@ -2186,7 +2187,7 @@ static short test_for_displace(Render *re, Object *ob)
return 0;
}
-static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[][4], float imat[][3])
+static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[4][4], float imat[3][3])
{
MTFace *tface;
short texco= shi->mat->texco;
@@ -2285,7 +2286,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
return;
}
-static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[][4], float imat[][3])
+static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[4][4], float imat[3][3])
{
ShadeInput shi;
@@ -2340,7 +2341,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
}
}
-static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float imat[][3])
+static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float imat[3][3])
{
VertRen *vr;
VlakRen *vlr;
@@ -2820,7 +2821,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
ListBase disp={NULL, NULL};
Material **matar;
float *data, *fp, *orco=NULL;
- float n[3], mat[4][4];
+ float n[3], mat[4][4], nmat[4][4];
int nr, startvert, a, b;
int need_orco=0, totmat;
@@ -2835,6 +2836,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
mult_m4_m4m4(mat, re->viewmat, ob->obmat);
invert_m4_m4(ob->imat, mat);
+ /* local object -> world space transform for normals */
+ copy_m4_m4(nmat, mat);
+ transpose_m4(nmat);
+ invert_m4(nmat);
+
/* material array */
totmat= ob->totcol+1;
matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar");
@@ -2859,7 +2865,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
}
else {
if (need_orco) {
- orco= get_object_orco(re, ob);
+ orco = get_object_orco(re, ob);
}
while (dl) {
@@ -2891,13 +2897,20 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
zero_v3(n);
index= dl->index;
for (a=0; a<dl->parts; a++, index+=3) {
+ int v1 = index[0], v2 = index[1], v3 = index[2];
+ float *co1 = &dl->verts[v1 * 3],
+ *co2 = &dl->verts[v2 * 3],
+ *co3 = &dl->verts[v3 * 3];
+
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
- vlr->v1= RE_findOrAddVert(obr, startvert+index[0]);
- vlr->v2= RE_findOrAddVert(obr, startvert+index[1]);
- vlr->v3= RE_findOrAddVert(obr, startvert+index[2]);
+ vlr->v1= RE_findOrAddVert(obr, startvert + v1);
+ vlr->v2= RE_findOrAddVert(obr, startvert + v2);
+ vlr->v3= RE_findOrAddVert(obr, startvert + v3);
vlr->v4= NULL;
- if (area_tri_v3(vlr->v3->co, vlr->v2->co, vlr->v1->co)>FLT_EPSILON10) {
- normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+
+ /* to prevent float accuracy issues, we calculate normal in local object space (not world) */
+ if (area_tri_v3(co3, co2, co1)>FLT_EPSILON10) {
+ normal_tri_v3(tmp, co3, co2, co1);
add_v3_v3(n, tmp);
}
@@ -2906,6 +2919,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
vlr->ec= 0;
}
+ /* transform normal to world space */
+ mul_m4_v3(nmat, n);
normalize_v3(n);
/* vertex normals */
@@ -3158,7 +3173,12 @@ static void init_camera_inside_volumes(Render *re)
{
ObjectInstanceRen *obi;
VolumeOb *vo;
- float co[3] = {0.f, 0.f, 0.f};
+ /* coordinates are all in camera space, so camera coordinate is zero. we also
+ * add an offset for the clip start, however note that with clip start it's
+ * actually impossible to do a single 'inside' test, since there will not be
+ * a single point where all camera rays start from, though for small clip start
+ * they will be close together. */
+ float co[3] = {0.f, 0.f, -re->clipsta};
for (vo= re->volumes.first; vo; vo= vo->next) {
for (obi= re->instancetable.first; obi; obi= obi->next) {
@@ -3212,7 +3232,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataMask mask;
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
float *orco=0;
- int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0;
+ int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0, need_origindex=0;
int a, a1, ok, vertofs;
int end, do_autosmooth = FALSE, totvert = 0;
int use_original_normals = FALSE;
@@ -3262,6 +3282,10 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
need_nmap_tangent= 1;
}
+ /* origindex currently only used when baking to vertex colors */
+ if (re->flag & R_BAKING && re->r.bake_flag & R_BAKE_VCOL)
+ need_origindex= 1;
+
/* check autosmooth and displacement, we then have to skip only-verts optimize */
do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
if (do_autosmooth)
@@ -3299,6 +3323,15 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
make_render_halos(re, obr, me, totvert, mvert, ma, orco);
}
else {
+ const int *index_vert_orig = NULL;
+ const int *index_mf_to_mpoly = NULL;
+ const int *index_mp_to_orig = NULL;
+ if (need_origindex) {
+ index_vert_orig = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ /* double lookup for faces -> polys */
+ index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ }
for (a=0; a<totvert; a++, mvert++) {
ver= RE_findOrAddVert(obr, obr->totvert++);
@@ -3315,6 +3348,18 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
ver->orco= orco;
orco+=3;
}
+
+ if (need_origindex) {
+ int *origindex;
+ origindex = RE_vertren_get_origindex(obr, ver, 1);
+
+ /* Use orig index array if it's available (e.g. in the presence
+ * of modifiers). */
+ if (index_vert_orig)
+ *origindex = index_vert_orig[a];
+ else
+ *origindex = a;
+ }
}
if (!timeoffset) {
@@ -3436,6 +3481,21 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
}
}
+
+ if (need_origindex) {
+ /* Find original index of mpoly for this tessface. Options:
+ - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
+ - OR Tesselated mesh; look up from tessface -> mpoly
+ - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
+ int *origindex;
+ origindex = RE_vlakren_get_origindex(obr, vlr, 1);
+ if (index_mf_to_mpoly && index_mp_to_orig)
+ *origindex = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a);
+ else if (index_mf_to_mpoly)
+ *origindex = index_mf_to_mpoly[a];
+ else
+ *origindex = a;
+ }
}
}
}
@@ -3520,7 +3580,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
/* Lamps and Shadowbuffers */
/* ------------------------------------------------------------------------- */
-static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
+static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4])
{
struct ShadBuf *shb;
float viewinv[4][4];
@@ -3955,18 +4015,10 @@ static void set_renderlayer_lightgroups(Render *re, Scene *sce)
void init_render_world(Render *re)
{
int a;
- char *cp;
if (re->scene && re->scene->world) {
re->wrld= *(re->scene->world);
-
- cp= (char *)&re->wrld.fastcol;
-
- cp[0]= 255.0f*re->wrld.horr;
- cp[1]= 255.0f*re->wrld.horg;
- cp[2]= 255.0f*re->wrld.horb;
- cp[3]= 1;
-
+
copy_v3_v3(re->grvec, re->viewmat[2]);
normalize_v3(re->grvec);
copy_m3_m4(re->imat, re->viewinv);
@@ -4710,7 +4762,7 @@ static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Obj
if (totmaterial) {
for (a= 0; a<*totmaterial; a++) {
- ma= give_current_material(obd, a);
+ ma= give_current_material(obd, a + 1);
if (ma && (ma->material_type == MA_TYPE_HALO))
return 0;
}
@@ -5022,8 +5074,8 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
* following calls don't depend on 'RE_SetCamera' */
RE_SetCamera(re, camera);
- normalize_m4(camera->obmat);
- invert_m4_m4(mat, camera->obmat);
+ normalize_m4_m4(mat, camera->obmat);
+ invert_m4(mat);
RE_SetView(re, mat);
camera->recalc= OB_RECALC_OB; /* force correct matrix for scaled cameras */
}
@@ -5136,7 +5188,7 @@ void RE_DataBase_ApplyWindow(Render *re)
project_renderdata(re, projectverto, 0, 0, 0);
}
-void RE_DataBase_GetView(Render *re, float mat[][4])
+void RE_DataBase_GetView(Render *re, float mat[4][4])
{
copy_m4_m4(mat, re->viewmat);
}
@@ -5172,8 +5224,8 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la
/* if no camera, viewmat should have been set! */
if (camera) {
- normalize_m4(camera->obmat);
- invert_m4_m4(mat, camera->obmat);
+ normalize_m4_m4(mat, camera->obmat);
+ invert_m4(mat);
RE_SetView(re, mat);
}
@@ -5712,8 +5764,8 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
/* if no camera, set unit */
if (camera) {
- normalize_m4(camera->obmat);
- invert_m4_m4(mat, camera->obmat);
+ normalize_m4_m4(mat, camera->obmat);
+ invert_m4(mat);
RE_SetView(re, mat);
}
else {
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index c3126e57b53..9adae6f49ba 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -210,7 +210,7 @@ static void envmap_free_render_copy(Render *envre)
/* ------------------------------------------------------------------------- */
-static void envmap_transmatrix(float mat[][4], int part)
+static void envmap_transmatrix(float mat[4][4], int part)
{
float tmat[4][4], eul[3], rotmat[4][4];
@@ -247,7 +247,7 @@ static void envmap_transmatrix(float mat[][4], int part)
/* ------------------------------------------------------------------------- */
-static void env_rotate_scene(Render *re, float mat[][4], int mode)
+static void env_rotate_scene(Render *re, float mat[4][4], int mode)
{
GroupObject *go;
ObjectRen *obr;
@@ -587,53 +587,53 @@ void make_envmaps(Render *re)
static int envcube_isect(EnvMap *env, const float vec[3], float answ[2])
{
- float labda;
+ float lambda;
int face;
if (env->type == ENV_PLANE) {
face = 1;
- labda = 1.0f / vec[2];
- answ[0] = env->viewscale * labda * vec[0];
- answ[1] = -env->viewscale * labda * vec[1];
+ lambda = 1.0f / vec[2];
+ answ[0] = env->viewscale * lambda * vec[0];
+ answ[1] = -env->viewscale * lambda * vec[1];
}
else {
/* which face */
if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) {
face = 0;
- labda = -1.0f / vec[2];
- answ[0] = labda * vec[0];
- answ[1] = labda * vec[1];
+ lambda = -1.0f / vec[2];
+ answ[0] = lambda * vec[0];
+ answ[1] = lambda * vec[1];
}
else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) {
face = 1;
- labda = 1.0f / vec[2];
- answ[0] = labda * vec[0];
- answ[1] = -labda * vec[1];
+ lambda = 1.0f / vec[2];
+ answ[0] = lambda * vec[0];
+ answ[1] = -lambda * vec[1];
}
else if (vec[1] >= fabsf(vec[0])) {
face = 2;
- labda = 1.0f / vec[1];
- answ[0] = labda * vec[0];
- answ[1] = labda * vec[2];
+ lambda = 1.0f / vec[1];
+ answ[0] = lambda * vec[0];
+ answ[1] = lambda * vec[2];
}
else if (vec[0] <= -fabsf(vec[1])) {
face = 3;
- labda = -1.0f / vec[0];
- answ[0] = labda * vec[1];
- answ[1] = labda * vec[2];
+ lambda = -1.0f / vec[0];
+ answ[0] = lambda * vec[1];
+ answ[1] = lambda * vec[2];
}
else if (vec[1] <= -fabsf(vec[0])) {
face = 4;
- labda = -1.0f / vec[1];
- answ[0] = -labda * vec[0];
- answ[1] = labda * vec[2];
+ lambda = -1.0f / vec[1];
+ answ[0] = -lambda * vec[0];
+ answ[1] = lambda * vec[2];
}
else {
face = 5;
- labda = 1.0f / vec[0];
- answ[0] = -labda * vec[1];
- answ[1] = labda * vec[2];
+ lambda = 1.0f / vec[0];
+ answ[0] = -lambda * vec[1];
+ answ[1] = lambda * vec[2];
}
}
@@ -668,7 +668,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)
+int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool)
{
extern Render R; /* only in this call */
/* texvec should be the already reflected normal */
@@ -687,12 +687,12 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
env->ima = tex->ima;
if (env->ima && env->ima->ok) {
if (env->cube[1] == NULL) {
- ImBuf *ibuf_ima = BKE_image_acquire_ibuf(env->ima, NULL, NULL);
+ ImBuf *ibuf_ima = BKE_image_pool_acquire_ibuf(env->ima, NULL, pool);
if (ibuf_ima)
envmap_split_ima(env, ibuf_ima);
else
env->ok = 0;
- BKE_image_release_ibuf(env->ima, ibuf_ima, NULL);
+ BKE_image_pool_release_ibuf(env->ima, ibuf_ima, pool);
}
}
}
@@ -720,7 +720,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);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres, pool);
/* edges? */
@@ -737,7 +737,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);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1, pool);
}
else texr1.tr = texr1.tg = texr1.tb = texr1.ta = 0.0;
@@ -750,7 +750,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);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2, pool);
}
else texr2.tr = texr2.tg = texr2.tb = texr2.ta = 0.0;
@@ -766,7 +766,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
}
}
else {
- imagewrap(tex, NULL, ibuf, sco, texres);
+ imagewrap(tex, NULL, ibuf, sco, texres, pool);
}
return 1;
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 6fdf11ba48c..22a49bcbbc3 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -1,4 +1,5 @@
/*
+
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -128,9 +129,20 @@ int RE_engine_is_external(Render *re)
RenderEngine *RE_engine_create(RenderEngineType *type)
{
+ return RE_engine_create_ex(type, FALSE);
+}
+
+RenderEngine *RE_engine_create_ex(RenderEngineType *type, int use_for_viewport)
+{
RenderEngine *engine = MEM_callocN(sizeof(RenderEngine), "RenderEngine");
engine->type = type;
+ if (use_for_viewport) {
+ engine->flag |= RE_ENGINE_USED_FOR_VIEWPORT;
+
+ BLI_begin_threaded_malloc();
+ }
+
return engine;
}
@@ -142,6 +154,10 @@ void RE_engine_free(RenderEngine *engine)
}
#endif
+ if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) {
+ BLI_end_threaded_malloc();
+ }
+
if (engine->text)
MEM_freeN(engine->text);
@@ -150,6 +166,23 @@ void RE_engine_free(RenderEngine *engine)
/* Render Results */
+static RenderPart *get_part_from_result(Render *re, RenderResult *result)
+{
+ RenderPart *pa;
+
+ for (pa = re->parts.first; pa; pa = pa->next) {
+ if (result->tilerect.xmin == pa->disprect.xmin - re->disprect.xmin &&
+ result->tilerect.ymin == pa->disprect.ymin - re->disprect.ymin &&
+ result->tilerect.xmax == pa->disprect.xmax - re->disprect.xmin &&
+ result->tilerect.ymax == pa->disprect.ymax - re->disprect.ymin)
+ {
+ return pa;
+ }
+ }
+
+ return NULL;
+}
+
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername)
{
Render *re = engine->re;
@@ -179,12 +212,19 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
/* can be NULL if we CLAMP the width or height to 0 */
if (result) {
+ RenderPart *pa;
+
BLI_addtail(&engine->fullresult, result);
result->tilerect.xmin += re->disprect.xmin;
result->tilerect.xmax += re->disprect.xmin;
result->tilerect.ymin += re->disprect.ymin;
result->tilerect.ymax += re->disprect.ymin;
+
+ pa = get_part_from_result(re, result);
+
+ if (pa)
+ pa->status = PART_STATUS_IN_PROGRESS;
}
return result;
@@ -203,7 +243,6 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel)
{
Render *re = engine->re;
- RenderPart *pa;
if (!result) {
return;
@@ -212,15 +251,10 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel
/* merge. on break, don't merge in result for preview renders, looks nicer */
if (!cancel) {
/* for exr tile render, detect tiles that are done */
- for (pa = re->parts.first; pa; pa = pa->next) {
- if (result->tilerect.xmin == pa->disprect.xmin &&
- result->tilerect.ymin == pa->disprect.ymin &&
- result->tilerect.xmax == pa->disprect.xmax &&
- result->tilerect.ymax == pa->disprect.ymax)
- {
- pa->ready = 1;
- }
- }
+ RenderPart *pa = get_part_from_result(re, result);
+
+ if (pa)
+ pa->status = PART_STATUS_READY;
if (re->result->do_exr_tile)
render_result_exr_file_merge(re->result, result);
@@ -310,6 +344,47 @@ void RE_engine_report(RenderEngine *engine, int type, const char *msg)
BKE_report(engine->reports, type, msg);
}
+void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
+{
+ RenderPart *pa;
+ int total_tiles = 0;
+ rcti *tiles = NULL;
+ int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS;
+
+ if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
+ *total_tiles_r = 0;
+ *tiles_r = NULL;
+ return;
+ }
+
+ for (pa = re->parts.first; pa; pa = pa->next) {
+ if (pa->status == PART_STATUS_IN_PROGRESS) {
+ if (total_tiles >= allocation_size) {
+ if (tiles == NULL)
+ tiles = MEM_mallocN(allocation_step * sizeof(rcti), "current engine tiles");
+ else
+ tiles = MEM_reallocN(tiles, (total_tiles + allocation_step) * sizeof(rcti));
+
+ allocation_size += allocation_step;
+ }
+
+ tiles[total_tiles] = pa->disprect;
+
+ if (pa->crop) {
+ tiles[total_tiles].xmin += pa->crop;
+ tiles[total_tiles].ymin += pa->crop;
+ tiles[total_tiles].xmax -= pa->crop;
+ tiles[total_tiles].ymax -= pa->crop;
+ }
+
+ total_tiles++;
+ }
+ }
+
+ *total_tiles_r = total_tiles;
+ *tiles_r = tiles;
+}
+
/* Render */
int RE_engine_render(Render *re, int do_all)
@@ -354,9 +429,7 @@ int RE_engine_render(Render *re, int do_all)
if (!engine) {
engine = RE_engine_create(type);
-
- if (persistent_data)
- re->engine = engine;
+ re->engine = engine;
}
engine->flag |= RE_ENGINE_RENDERING;
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index cd06839b004..12286fc9999 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -102,10 +102,15 @@ static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y)
col[1] = ((float)rect[1])*(1.0f/255.0f);
col[2] = ((float)rect[2])*(1.0f/255.0f);
col[3] = ((float)rect[3])*(1.0f/255.0f);
+
+ /* bytes are internally straight, however render pipeline seems to expect premul */
+ col[0] *= col[3];
+ col[1] *= col[3];
+ col[2] *= col[3];
}
}
-int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres)
+int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres, struct ImagePool *pool)
{
float fx, fy, val1, val2, val3;
int x, y, retval;
@@ -125,13 +130,13 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
return retval;
- ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
+ ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
ima->flag|= IMA_USED_FOR_RENDER;
}
if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
@@ -159,14 +164,14 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
}
else {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
if ((xs+ys) & 1) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
@@ -183,14 +188,14 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (tex->extend == TEX_CLIPCUBE) {
if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0f || texvec[2]>1.0f) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
else if ( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
@@ -219,7 +224,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
}
/* keep this before interpolation [#29761] */
- if (tex->imaflag & TEX_USEALPHA) {
+ if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
texres->talpha = TRUE;
}
@@ -286,7 +291,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (texres->talpha) texres->tin= texres->ta;
else if (tex->imaflag & TEX_CALCALPHA) {
- texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb);
+ texres->ta = texres->tin = max_fff(texres->tr, texres->tg, texres->tb);
}
else texres->ta= texres->tin= 1.0;
@@ -299,10 +304,10 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
texres->tg*= fx;
texres->tb*= fx;
}
-
+
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
+
BRICONTRGB;
return retval;
@@ -710,9 +715,10 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf
}
else {
char *rect = (char *)(ibuf->rect + x + y*ibuf->x);
- col[0] = rect[0]*(1.f/255.f);
- col[1] = rect[1]*(1.f/255.f);
- col[2] = rect[2]*(1.f/255.f);
+ float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f);
+ col[0] = rect[0] * inv_alpha_fac;
+ col[1] = rect[1] * inv_alpha_fac;
+ col[2] = rect[2] * inv_alpha_fac;
col[3] = clip ? 0.f : rect[3]*(1.f/255.f);
}
return clip;
@@ -1036,12 +1042,16 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
BLI_unlock_thread(LOCK_IMAGE);
}
+ /* if no mipmap could be made, fall back on non-mipmap render */
+ if (ibuf->mipmap[0] == NULL) {
+ tex->imaflag &= ~TEX_MIPMAP;
+ }
}
}
}
-static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres)
+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)
{
TexResult texr;
float fx, fy, minx, maxx, miny, maxy;
@@ -1072,12 +1082,12 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
if (ima) { /* hack for icon render */
if ((ima->ibufs.first == NULL) && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval;
- ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
+ ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
}
if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
@@ -1088,7 +1098,10 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
+ if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_CALCALPHA) == 0)
+ texres->talpha = 1;
+ }
texr.talpha = texres->talpha;
if (tex->imaflag & TEX_IMAROT) {
@@ -1112,10 +1125,10 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
/* pixel coordinates */
- minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
- maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
/* tex_sharper has been removed */
minx = (maxx - minx)*0.5f;
@@ -1194,12 +1207,12 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
else {
if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
fx -= xs;
@@ -1219,14 +1232,14 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
if (tex->extend == TEX_CLIPCUBE) {
if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
@@ -1416,7 +1429,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
if (tex->imaflag & TEX_CALCALPHA)
- texres->ta = texres->tin = texres->ta * MAX3(texres->tr, texres->tg, texres->tb);
+ texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
else
texres->tin = texres->ta;
if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
@@ -1450,7 +1463,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
BRICONTRGB;
@@ -1458,7 +1471,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)
+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)
{
TexResult texr;
float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2];
@@ -1472,7 +1485,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);
+ return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool);
texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
@@ -1488,24 +1501,21 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
return retval;
- ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
+ ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
ima->flag|= IMA_USED_FOR_RENDER;
}
if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if (tex->imaflag & TEX_USEALPHA) {
- if (tex->imaflag & TEX_CALCALPHA) {
- /* pass */
- }
- else {
+ if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_CALCALPHA) == 0) {
texres->talpha = TRUE;
}
}
@@ -1535,10 +1545,10 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* pixel coordinates */
- minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
- maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
/* tex_sharper has been removed */
minx= (maxx-minx)/2.0f;
@@ -1608,14 +1618,14 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
}
else {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
if ((xs + ys) & 1) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
@@ -1652,14 +1662,14 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->extend == TEX_CLIPCUBE) {
if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f || texvec[2]<-1.0f || texvec[2]>1.0f) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
}
@@ -1826,7 +1836,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
}
if (tex->imaflag & TEX_CALCALPHA) {
- texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
+ texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
}
else texres->tin= texres->ta;
@@ -1855,17 +1865,17 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
}
if (ima)
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
BRICONTRGB;
return retval;
}
-void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4])
+void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4], struct ImagePool *pool)
{
TexResult texres;
- ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, NULL, pool);
if (UNLIKELY(ibuf == NULL)) {
zero_v4(result);
@@ -1884,7 +1894,7 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu
ima->flag|= IMA_USED_FOR_RENDER;
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, pool);
}
void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 3ea74abbcc2..0d957f8019f 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -515,7 +515,7 @@ void RE_SetPixelSize(Render *re, float pixsize)
re->viewdy = re->ycor * pixsize;
}
-void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4])
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4])
{
re->r.cfra = frame;
RE_SetCamera(re, camera);
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
new file mode 100644
index 00000000000..e81359e8fca
--- /dev/null
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -0,0 +1,1298 @@
+/*
+ * ***** 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) 2012 by Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Morten Mikkelsen,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/multires_bake.c
+ * \ingroup render
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
+
+#include "BKE_ccg.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_multires.h"
+#include "BKE_modifier.h"
+#include "BKE_subsurf.h"
+
+#include "RE_multires_bake.h"
+#include "RE_pipeline.h"
+#include "RE_shader_ext.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "rendercore.h"
+
+typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *thread_data,
+ void *bake_data, ImBuf *ibuf, const int face_index, const int lvl,
+ const float st[2], float tangmat[3][3], const int x, const int y);
+
+typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
+typedef void (*MFreeBakeData)(void *bake_data);
+
+typedef struct MultiresBakeResult {
+ float height_min, height_max;
+} MultiresBakeResult;
+
+typedef struct {
+ MVert *mvert;
+ MFace *mface;
+ MTFace *mtface;
+ float *pvtangent;
+ float *precomputed_normals;
+ int w, h;
+ int face_index;
+ int i0, i1, i2;
+ DerivedMesh *lores_dm, *hires_dm;
+ int lvl;
+ void *thread_data;
+ void *bake_data;
+ ImBuf *ibuf;
+ MPassKnownData pass_data;
+} MResolvePixelData;
+
+typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
+
+typedef struct {
+ int w, h;
+ char *texels;
+ const MResolvePixelData *data;
+ MFlushPixel flush_pixel;
+} MBakeRast;
+
+typedef struct {
+ float *heights;
+ Image *ima;
+ DerivedMesh *ssdm;
+ const int *orig_index_mf_to_mpoly;
+ const int *orig_index_mp_to_orig;
+} MHeightBakeData;
+
+typedef struct {
+ const int *orig_index_mf_to_mpoly;
+ const int *orig_index_mp_to_orig;
+} MNormalBakeData;
+
+typedef struct {
+ int number_of_rays;
+ float bias;
+
+ unsigned short *permutation_table_1;
+ unsigned short *permutation_table_2;
+
+ RayObject *raytree;
+ RayFace *rayfaces;
+
+ const int *orig_index_mf_to_mpoly;
+ const int *orig_index_mp_to_orig;
+} MAOBakeData;
+
+static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
+{
+ unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2,
+ data->mface[face_num].v3, data->mface[face_num].v4};
+ const int smoothnormal = (data->mface[face_num].flag & ME_SMOOTH);
+
+ if (!smoothnormal) { /* flat */
+ if (data->precomputed_normals) {
+ copy_v3_v3(norm, &data->precomputed_normals[3 * face_num]);
+ }
+ else {
+ float nor[3];
+ float *p0, *p1, *p2;
+ const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3;
+
+ p0 = data->mvert[indices[0]].co;
+ p1 = data->mvert[indices[1]].co;
+ p2 = data->mvert[indices[2]].co;
+
+ if (iGetNrVerts == 4) {
+ float *p3 = data->mvert[indices[3]].co;
+ normal_quad_v3(nor, p0, p1, p2, p3);
+ }
+ else {
+ normal_tri_v3(nor, p0, p1, p2);
+ }
+
+ copy_v3_v3(norm, nor);
+ }
+ }
+ else {
+ short *no = data->mvert[indices[vert_index]].no;
+
+ normal_short_to_float_v3(norm, no);
+ normalize_v3(norm);
+ }
+}
+
+static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
+{
+ BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata;
+
+ memset(bake_rast, 0, sizeof(MBakeRast));
+
+ bake_rast->texels = userdata->mask_buffer;
+ bake_rast->w = ibuf->x;
+ bake_rast->h = ibuf->y;
+ bake_rast->data = data;
+ bake_rast->flush_pixel = flush_pixel;
+}
+
+static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
+{
+ float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
+ float *st0, *st1, *st2;
+ float *tang0, *tang1, *tang2;
+ float no0[3], no1[3], no2[3];
+ float fUV[2], from_tang[3][3], to_tang[3][3];
+ float u, v, w, sign;
+ int r;
+
+ const int i0 = data->i0;
+ const int i1 = data->i1;
+ const int i2 = data->i2;
+
+ st0 = data->mtface[data->face_index].uv[i0];
+ st1 = data->mtface[data->face_index].uv[i1];
+ st2 = data->mtface[data->face_index].uv[i2];
+
+ multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */
+ multiresbake_get_normal(data, no1, data->face_index, i1);
+ multiresbake_get_normal(data, no2, data->face_index, i2);
+
+ resolve_tri_uv(fUV, st, st0, st1, st2);
+
+ u = fUV[0];
+ v = fUV[1];
+ w = 1 - u - v;
+
+ if (data->pvtangent) {
+ tang0 = data->pvtangent + data->face_index * 16 + i0 * 4;
+ tang1 = data->pvtangent + data->face_index * 16 + i1 * 4;
+ tang2 = data->pvtangent + data->face_index * 16 + i2 * 4;
+
+ /* the sign is the same at all face vertices for any non degenerate face.
+ * Just in case we clamp the interpolated value though. */
+ sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f;
+
+ /* this sequence of math is designed specifically as is with great care
+ * to be compatible with our shader. Please don't change without good reason. */
+ for (r = 0; r < 3; r++) {
+ from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w;
+ from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w;
+ }
+
+ cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */
+ mul_v3_fl(from_tang[1], sign);
+ invert_m3_m3(to_tang, from_tang);
+ }
+ else {
+ zero_m3(to_tang);
+ }
+
+ data->pass_data(data->lores_dm, data->hires_dm, data->thread_data, data->bake_data,
+ data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
+}
+
+static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
+{
+ const int w = bake_rast->w;
+ const int h = bake_rast->h;
+
+ if (x >= 0 && x < w && y >= 0 && y < h) {
+ if ((bake_rast->texels[y * w + x]) == 0) {
+ bake_rast->texels[y * w + x] = FILTER_MASK_USED;
+ flush_pixel(bake_rast->data, x, y);
+ }
+ }
+}
+
+static void rasterize_half(const MBakeRast *bake_rast,
+ const float s0_s, const float t0_s, const float s1_s, const float t1_s,
+ const float s0_l, const float t0_l, const float s1_l, const float t1_l,
+ const int y0_in, const int y1_in, const int is_mid_right)
+{
+ const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0;
+ const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0;
+ const int w = bake_rast->w;
+ const int h = bake_rast->h;
+ int y, y0, y1;
+
+ if (y1_in <= 0 || y0_in >= h)
+ return;
+
+ y0 = y0_in < 0 ? 0 : y0_in;
+ y1 = y1_in >= h ? h : y1_in;
+
+ for (y = y0; y < y1; y++) {
+ /*-b(x-x0) + a(y-y0) = 0 */
+ int iXl, iXr, x;
+ float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s;
+ float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l;
+
+ if (is_mid_right != 0)
+ SWAP(float, x_l, x_r);
+
+ iXl = (int)ceilf(x_l);
+ iXr = (int)ceilf(x_r);
+
+ if (iXr > 0 && iXl < w) {
+ iXl = iXl < 0 ? 0 : iXl;
+ iXr = iXr >= w ? w : iXr;
+
+ for (x = iXl; x < iXr; x++)
+ set_rast_triangle(bake_rast, x, y);
+ }
+ }
+}
+
+static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
+{
+ const int w = bake_rast->w;
+ const int h = bake_rast->h;
+ float slo = st0_in[0] * w - 0.5f;
+ float tlo = st0_in[1] * h - 0.5f;
+ float smi = st1_in[0] * w - 0.5f;
+ float tmi = st1_in[1] * h - 0.5f;
+ float shi = st2_in[0] * w - 0.5f;
+ float thi = st2_in[1] * h - 0.5f;
+ int is_mid_right = 0, ylo, yhi, yhi_beg;
+
+ /* skip degenerates */
+ if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi))
+ return;
+
+ /* sort by T */
+ if (tlo > tmi && tlo > thi) {
+ SWAP(float, shi, slo);
+ SWAP(float, thi, tlo);
+ }
+ else if (tmi > thi) {
+ SWAP(float, shi, smi);
+ SWAP(float, thi, tmi);
+ }
+
+ if (tlo > tmi) {
+ SWAP(float, slo, smi);
+ SWAP(float, tlo, tmi);
+ }
+
+ /* check if mid point is to the left or to the right of the lo-hi edge */
+ is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0;
+ ylo = (int) ceilf(tlo);
+ yhi_beg = (int) ceilf(tmi);
+ yhi = (int) ceilf(thi);
+
+ /*if (fTmi>ceilf(fTlo))*/
+ rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
+ rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
+}
+
+static int multiresbake_test_break(MultiresBakeRender *bkr)
+{
+ if (!bkr->stop) {
+ /* this means baker is executed outside from job system */
+ return 0;
+ }
+
+ return *bkr->stop || G.is_break;
+}
+
+/* **** Threading routines **** */
+
+typedef struct MultiresBakeQueue {
+ int cur_face;
+ int tot_face;
+ SpinLock spin;
+} MultiresBakeQueue;
+
+typedef struct MultiresBakeThread {
+ /* this data is actually shared between all the threads */
+ MultiresBakeQueue *queue;
+ MultiresBakeRender *bkr;
+ Image *image;
+ void *bake_data;
+
+ /* thread-specific data */
+ MBakeRast bake_rast;
+ MResolvePixelData data;
+
+ /* displacement-specific data */
+ float height_min, height_max;
+} MultiresBakeThread;
+
+static int multires_bake_queue_next_face(MultiresBakeQueue *queue)
+{
+ int face = -1;
+
+ /* TODO: it could worth making it so thread will handle neighbor faces
+ * for better memory cache utilization
+ */
+
+ BLI_spin_lock(&queue->spin);
+ if (queue->cur_face < queue->tot_face) {
+ face = queue->cur_face;
+ queue->cur_face++;
+ }
+ BLI_spin_unlock(&queue->spin);
+
+ return face;
+}
+
+static void *do_multires_bake_thread(void *data_v)
+{
+ MultiresBakeThread *handle = (MultiresBakeThread *) data_v;
+ MResolvePixelData *data = &handle->data;
+ MBakeRast *bake_rast = &handle->bake_rast;
+ MultiresBakeRender *bkr = handle->bkr;
+ int f;
+
+ while ((f = multires_bake_queue_next_face(handle->queue)) >= 0) {
+ MTFace *mtfate = &data->mtface[f];
+ int verts[3][2], nr_tris, t;
+
+ if (multiresbake_test_break(bkr))
+ break;
+
+ if (mtfate->tpage != handle->image)
+ continue;
+
+ data->face_index = f;
+
+ /* might support other forms of diagonal splits later on such as
+ * split by shortest diagonal.*/
+ verts[0][0] = 0;
+ verts[1][0] = 1;
+ verts[2][0] = 2;
+
+ verts[0][1] = 0;
+ verts[1][1] = 2;
+ verts[2][1] = 3;
+
+ nr_tris = data->mface[f].v4 != 0 ? 2 : 1;
+ for (t = 0; t < nr_tris; t++) {
+ data->i0 = verts[0][t];
+ data->i1 = verts[1][t];
+ data->i2 = verts[2][t];
+
+ bake_rasterize(bake_rast, mtfate->uv[data->i0], mtfate->uv[data->i1], mtfate->uv[data->i2]);
+
+ /* tag image buffer for refresh */
+ if (data->ibuf->rect_float)
+ data->ibuf->userflags |= IB_RECT_INVALID;
+
+ data->ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ }
+
+ /* update progress */
+ BLI_spin_lock(&handle->queue->spin);
+ bkr->baked_faces++;
+
+ if (bkr->do_update)
+ *bkr->do_update = TRUE;
+
+ if (bkr->progress)
+ *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / handle->queue->tot_face) / bkr->tot_obj;
+ BLI_spin_unlock(&handle->queue->spin);
+ }
+
+ return NULL;
+}
+
+/* some of arrays inside ccgdm are lazy-initialized, which will generally
+ * require lock around accessing such data
+ * this function will ensure all arrays are allocated before threading started
+ */
+static void init_ccgdm_arrays(DerivedMesh *dm)
+{
+ CCGElem **grid_data;
+ CCGKey key;
+ int grid_size;
+ int *grid_offset;
+
+ grid_size = dm->getGridSize(dm);
+ grid_data = dm->getGridData(dm);
+ grid_offset = dm->getGridOffset(dm);
+ dm->getGridKey(dm, &key);
+
+ (void) grid_size;
+ (void) grid_data;
+ (void) grid_offset;
+}
+
+static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_tangent, MPassKnownData passKnownData,
+ MInitBakeData initBakeData, MFreeBakeData freeBakeData, MultiresBakeResult *result)
+{
+ DerivedMesh *dm = bkr->lores_dm;
+ const int lvl = bkr->lvl;
+ const int tot_face = dm->getNumTessFaces(dm);
+
+ if (tot_face > 0) {
+ MultiresBakeThread *handles;
+ MultiresBakeQueue queue;
+
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ MVert *mvert = dm->getVertArray(dm);
+ MFace *mface = dm->getTessFaceArray(dm);
+ MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
+ float *precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ float *pvtangent = NULL;
+
+ ListBase threads;
+ int i, tot_thread = bkr->threads > 0 ? bkr->threads : BLI_system_thread_count();
+
+ void *bake_data = NULL;
+
+ if (require_tangent) {
+ if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
+ DM_add_tangent_layer(dm);
+
+ pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT);
+ }
+
+ /* all threads shares the same custom bake data */
+ if (initBakeData)
+ bake_data = initBakeData(bkr, ima);
+
+ if (tot_thread > 1)
+ BLI_init_threads(&threads, do_multires_bake_thread, tot_thread);
+
+ handles = MEM_callocN(tot_thread * sizeof(MultiresBakeThread), "do_multires_bake handles");
+
+ init_ccgdm_arrays(bkr->hires_dm);
+
+ /* faces queue */
+ queue.cur_face = 0;
+ queue.tot_face = tot_face;
+ BLI_spin_init(&queue.spin);
+
+ /* fill in threads handles */
+ for (i = 0; i < tot_thread; i++) {
+ MultiresBakeThread *handle = &handles[i];
+
+ handle->bkr = bkr;
+ handle->image = ima;
+ handle->queue = &queue;
+
+ handle->data.mface = mface;
+ handle->data.mvert = mvert;
+ handle->data.mtface = mtface;
+ handle->data.pvtangent = pvtangent;
+ handle->data.precomputed_normals = precomputed_normals; /* don't strictly need this */
+ handle->data.w = ibuf->x;
+ handle->data.h = ibuf->y;
+ handle->data.lores_dm = dm;
+ handle->data.hires_dm = bkr->hires_dm;
+ handle->data.lvl = lvl;
+ handle->data.pass_data = passKnownData;
+ handle->data.thread_data = handle;
+ handle->data.bake_data = bake_data;
+ handle->data.ibuf = ibuf;
+
+ handle->height_min = FLT_MAX;
+ handle->height_max = -FLT_MAX;
+
+ init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel);
+
+ if (tot_thread > 1)
+ BLI_insert_thread(&threads, handle);
+ }
+
+ /* run threads */
+ if (tot_thread > 1)
+ BLI_end_threads(&threads);
+ else
+ do_multires_bake_thread(&handles[0]);
+
+ /* construct bake result */
+ result->height_min = handles[0].height_min;
+ result->height_max = handles[0].height_max;
+
+ for (i = 1; i < tot_thread; i++) {
+ result->height_min = min_ff(result->height_min, handles[i].height_min);
+ result->height_max = max_ff(result->height_max, handles[i].height_max);
+ }
+
+ BLI_spin_end(&queue.spin);
+
+ /* finalize baking */
+ if (freeBakeData)
+ freeBakeData(bake_data);
+
+ MEM_freeN(handles);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+}
+
+/* mode = 0: interpolate normals,
+ * mode = 1: interpolate coord */
+static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
+{
+ int x0, x1, y0, y1;
+ float u, v;
+ float data[4][3];
+
+ x0 = (int) crn_x;
+ x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1);
+
+ y0 = (int) crn_y;
+ y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1);
+
+ u = crn_x - x0;
+ v = crn_y - y0;
+
+ if (mode == 0) {
+ copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0));
+ copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0));
+ copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1));
+ copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1));
+ }
+ else {
+ copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0));
+ copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0));
+ copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1));
+ copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
+ }
+
+ interp_bilinear_quad_v3(data, u, v, res);
+}
+
+static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,
+ const int *index_mf_to_mpoly, const int *index_mp_to_orig,
+ const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
+{
+ MFace mface;
+ CCGElem **grid_data;
+ CCGKey key;
+ float crn_x, crn_y;
+ int grid_size, S, face_side;
+ int *grid_offset, g_index;
+
+ lodm->getTessFace(lodm, face_index, &mface);
+
+ grid_size = hidm->getGridSize(hidm);
+ grid_data = hidm->getGridData(hidm);
+ grid_offset = hidm->getGridOffset(hidm);
+ hidm->getGridKey(hidm, &key);
+
+ face_side = (grid_size << 1) - 1;
+
+ if (lvl == 0) {
+ g_index = grid_offset[face_index];
+ S = mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y);
+ }
+ else {
+ int side = (1 << (lvl - 1)) + 1;
+ int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index);
+ int loc_offs = face_index % (1 << (2 * lvl));
+ int cell_index = loc_offs % ((side - 1) * (side - 1));
+ int cell_side = (grid_size - 1) / (side - 1);
+ int row = cell_index / (side - 1);
+ int col = cell_index % (side - 1);
+
+ S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[grid_index];
+ g_index = grid_offset[grid_index];
+
+ crn_y = (row * cell_side) + u * cell_side;
+ crn_x = (col * cell_side) + v * cell_side;
+ }
+
+ CLAMP(crn_x, 0.0f, grid_size);
+ CLAMP(crn_y, 0.0f, grid_size);
+
+ if (n != NULL)
+ interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n);
+
+ if (co != NULL)
+ interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co);
+}
+
+/* mode = 0: interpolate normals,
+ * mode = 1: interpolate coord */
+static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+ float data[4][3];
+
+ if (mode == 0) {
+ dm->getVertNo(dm, mface->v1, data[0]);
+ dm->getVertNo(dm, mface->v2, data[1]);
+ dm->getVertNo(dm, mface->v3, data[2]);
+ dm->getVertNo(dm, mface->v4, data[3]);
+ }
+ else {
+ dm->getVertCo(dm, mface->v1, data[0]);
+ dm->getVertCo(dm, mface->v2, data[1]);
+ dm->getVertCo(dm, mface->v3, data[2]);
+ dm->getVertCo(dm, mface->v4, data[3]);
+ }
+
+ interp_bilinear_quad_v3(data, u, v, res);
+}
+
+/* mode = 0: interpolate normals,
+ * mode = 1: interpolate coord */
+static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+ float data[3][3];
+
+ if (mode == 0) {
+ dm->getVertNo(dm, mface->v1, data[0]);
+ dm->getVertNo(dm, mface->v2, data[1]);
+ dm->getVertNo(dm, mface->v3, data[2]);
+ }
+ else {
+ dm->getVertCo(dm, mface->v1, data[0]);
+ dm->getVertCo(dm, mface->v2, data[1]);
+ dm->getVertCo(dm, mface->v3, data[2]);
+ }
+
+ interp_barycentric_tri_v3(data, u, v, res);
+}
+
+/* **************** Displacement Baker **************** */
+
+static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
+{
+ MHeightBakeData *height_data;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ DerivedMesh *lodm = bkr->lores_dm;
+ BakeImBufuserData *userdata = ibuf->userdata;
+
+ if (userdata->displacement_buffer == NULL)
+ userdata->displacement_buffer = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights");
+
+ height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
+
+ height_data->ima = ima;
+ height_data->heights = userdata->displacement_buffer;
+
+ if (!bkr->use_lores_mesh) {
+ SubsurfModifierData smd = {{NULL}};
+ int ss_lvl = bkr->tot_lvl - bkr->lvl;
+
+ CLAMP(ss_lvl, 0, 6);
+
+ if (ss_lvl > 0) {
+ smd.levels = smd.renderLevels = ss_lvl;
+ smd.flags |= eSubsurfModifierFlag_SubsurfUv;
+
+ if (bkr->simple)
+ smd.subdivType = ME_SIMPLE_SUBSURF;
+
+ height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0);
+ init_ccgdm_arrays(height_data->ssdm);
+ }
+ }
+
+ height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+ height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ return (void *)height_data;
+}
+
+static void free_heights_data(void *bake_data)
+{
+ MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
+
+ if (height_data->ssdm)
+ height_data->ssdm->release(height_data->ssdm);
+
+ MEM_freeN(height_data);
+}
+
+/* MultiresBake callback for heights baking
+ * general idea:
+ * - find coord of point with specified UV in hi-res mesh (let's call it p1)
+ * - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
+ * mesh to make texture smoother) let's call this point p0 and n.
+ * - height wound be dot(n, p1-p0) */
+static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *thread_data_v, void *bake_data,
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
+ float UNUSED(tangmat[3][3]), const int x, const int y)
+{
+ MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+ MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
+ MultiresBakeThread *thread_data = (MultiresBakeThread *) thread_data_v;
+ float uv[2], *st0, *st1, *st2, *st3;
+ int pixel = ibuf->x * y + x;
+ float vec[3], p0[3], p1[3], n[3], len;
+
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ st0 = mtface[face_index].uv[0];
+ st1 = mtface[face_index].uv[1];
+ st2 = mtface[face_index].uv[2];
+
+ if (mface.v4) {
+ st3 = mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ }
+ else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm,
+ height_data->orig_index_mf_to_mpoly, height_data->orig_index_mp_to_orig,
+ lvl, face_index, uv[0], uv[1], p1, 0);
+
+ if (height_data->ssdm) {
+ get_ccgdm_data(lores_dm, height_data->ssdm,
+ height_data->orig_index_mf_to_mpoly, height_data->orig_index_mp_to_orig,
+ 0, face_index, uv[0], uv[1], p0, n);
+ }
+ else {
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ if (mface.v4) {
+ interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+ interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+ }
+ else {
+ interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+ interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+ }
+ }
+
+ sub_v3_v3v3(vec, p1, p0);
+ len = dot_v3v3(n, vec);
+
+ height_data->heights[pixel] = len;
+
+ thread_data->height_min = min_ff(thread_data->height_min, len);
+ thread_data->height_max = max_ff(thread_data->height_max, len);
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + pixel * 4;
+ rrgbf[0] = rrgbf[1] = rrgbf[2] = len;
+ rrgbf[3] = 1.0f;
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + pixel * 4;
+ rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(len);
+ rrgb[3] = 255;
+ }
+}
+
+/* **************** Normal Maps Baker **************** */
+
+static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
+{
+ MNormalBakeData *normal_data;
+ DerivedMesh *lodm = bkr->lores_dm;
+
+ normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
+
+ normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+ normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+
+ return (void *)normal_data;
+}
+
+static void free_normal_data(void *bake_data)
+{
+ MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
+
+ MEM_freeN(normal_data);
+}
+
+/* MultiresBake callback for normals' baking
+ * general idea:
+ * - find coord and normal of point with specified UV in hi-res mesh
+ * - multiply it by tangmat
+ * - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
+static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *UNUSED(thread_data),
+ void *bake_data, ImBuf *ibuf, const int face_index, const int lvl,
+ const float st[2], float tangmat[3][3], const int x, const int y)
+{
+ MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+ MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
+ float uv[2], *st0, *st1, *st2, *st3;
+ int pixel = ibuf->x * y + x;
+ float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
+
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ st0 = mtface[face_index].uv[0];
+ st1 = mtface[face_index].uv[1];
+ st2 = mtface[face_index].uv[2];
+
+ if (mface.v4) {
+ st3 = mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ }
+ else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm,
+ normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig,
+ lvl, face_index, uv[0], uv[1], NULL, n);
+
+ mul_v3_m3v3(vec, tangmat, n);
+ normalize_v3(vec);
+ mul_v3_fl(vec, 0.5);
+ add_v3_v3(vec, tmp);
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + pixel * 4;
+ rrgbf[0] = vec[0];
+ rrgbf[1] = vec[1];
+ rrgbf[2] = vec[2];
+ rrgbf[3] = 1.0f;
+ }
+ else {
+ unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
+ rgb_float_to_uchar(rrgb, vec);
+ rrgb[3] = 255;
+ }
+}
+
+/* **************** Ambient Occlusion Baker **************** */
+
+// must be a power of two
+#define MAX_NUMBER_OF_AO_RAYS 1024
+
+static unsigned short ao_random_table_1[MAX_NUMBER_OF_AO_RAYS];
+static unsigned short ao_random_table_2[MAX_NUMBER_OF_AO_RAYS];
+
+static void init_ao_random(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_NUMBER_OF_AO_RAYS; i++) {
+ ao_random_table_1[i] = rand() & 0xffff;
+ ao_random_table_2[i] = rand() & 0xffff;
+ }
+}
+
+static unsigned short get_ao_random1(const int i)
+{
+ return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
+}
+
+static unsigned short get_ao_random2(const int i)
+{
+ return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
+}
+
+static void build_permutation_table(unsigned short permutation[], unsigned short temp_permutation[],
+ const int number_of_rays, const int is_first_perm_table)
+{
+ int i, k;
+
+ for (i = 0; i < number_of_rays; i++)
+ temp_permutation[i] = i;
+
+ for (i = 0; i < number_of_rays; i++) {
+ const unsigned int nr_entries_left = number_of_rays - i;
+ unsigned short rnd = is_first_perm_table != FALSE ? get_ao_random1(i) : get_ao_random2(i);
+ const unsigned short entry = rnd % nr_entries_left;
+
+ /* pull entry */
+ permutation[i] = temp_permutation[entry];
+
+ /* delete entry */
+ for (k = entry; k < nr_entries_left - 1; k++) {
+ temp_permutation[k] = temp_permutation[k + 1];
+ }
+ }
+
+ /* verify permutation table
+ * every entry must appear exactly once
+ */
+#if 0
+ for (i = 0; i < number_of_rays; i++) temp_permutation[i] = 0;
+ for (i = 0; i < number_of_rays; i++) ++temp_permutation[permutation[i]];
+ for (i = 0; i < number_of_rays; i++) BLI_assert(temp_permutation[i] == 1);
+#endif
+}
+
+static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
+{
+ DerivedMesh *hidm = bkr->hires_dm;
+ RayObject *raytree;
+ RayFace *face;
+ CCGElem **grid_data;
+ CCGKey key;
+ int num_grids, grid_size /*, face_side */, num_faces;
+ int i;
+
+ num_grids = hidm->getNumGrids(hidm);
+ grid_size = hidm->getGridSize(hidm);
+ grid_data = hidm->getGridData(hidm);
+ hidm->getGridKey(hidm, &key);
+
+ /* face_side = (grid_size << 1) - 1; */ /* UNUSED */
+ num_faces = num_grids * (grid_size - 1) * (grid_size - 1);
+
+ raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution);
+ face = ao_data->rayfaces = (RayFace *) MEM_callocN(num_faces * sizeof(RayFace), "ObjectRen faces");
+
+ for (i = 0; i < num_grids; i++) {
+ int x, y;
+ for (x = 0; x < grid_size - 1; x++) {
+ for (y = 0; y < grid_size - 1; y++) {
+ float co[4][3];
+
+ copy_v3_v3(co[0], CCG_grid_elem_co(&key, grid_data[i], x, y));
+ copy_v3_v3(co[1], CCG_grid_elem_co(&key, grid_data[i], x, y + 1));
+ copy_v3_v3(co[2], CCG_grid_elem_co(&key, grid_data[i], x + 1, y + 1));
+ copy_v3_v3(co[3], CCG_grid_elem_co(&key, grid_data[i], x + 1, y));
+
+ RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]);
+ RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));
+
+ face++;
+ }
+ }
+ }
+
+ RE_rayobject_done(raytree);
+}
+
+static void *init_ao_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
+{
+ MAOBakeData *ao_data;
+ DerivedMesh *lodm = bkr->lores_dm;
+ unsigned short *temp_permutation_table;
+ size_t permutation_size;
+
+ init_ao_random();
+
+ ao_data = MEM_callocN(sizeof(MAOBakeData), "MultiresBake aoData");
+
+ ao_data->number_of_rays = bkr->number_of_rays;
+ ao_data->bias = bkr->bias;
+
+ ao_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+ ao_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+
+ create_ao_raytree(bkr, ao_data);
+
+ /* initialize permutation tables */
+ permutation_size = sizeof(unsigned short) * bkr->number_of_rays;
+ ao_data->permutation_table_1 = MEM_callocN(permutation_size, "multires AO baker perm1");
+ ao_data->permutation_table_2 = MEM_callocN(permutation_size, "multires AO baker perm2");
+ temp_permutation_table = MEM_callocN(permutation_size, "multires AO baker temp perm");
+
+ build_permutation_table(ao_data->permutation_table_1, temp_permutation_table, bkr->number_of_rays, 1);
+ build_permutation_table(ao_data->permutation_table_2, temp_permutation_table, bkr->number_of_rays, 0);
+
+ MEM_freeN(temp_permutation_table);
+
+ return (void *)ao_data;
+}
+
+static void free_ao_data(void *bake_data)
+{
+ MAOBakeData *ao_data = (MAOBakeData *) bake_data;
+
+ RE_rayobject_free(ao_data->raytree);
+ MEM_freeN(ao_data->rayfaces);
+
+ MEM_freeN(ao_data->permutation_table_1);
+ MEM_freeN(ao_data->permutation_table_2);
+
+ MEM_freeN(ao_data);
+}
+
+/* builds an X and a Y axis from the given Z axis */
+static void build_coordinate_frame(float axisX[3], float axisY[3], const float axisZ[3])
+{
+ const float faX = fabsf(axisZ[0]);
+ const float faY = fabsf(axisZ[1]);
+ const float faZ = fabsf(axisZ[2]);
+
+ if (faX <= faY && faX <= faZ) {
+ const float len = sqrtf(axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]);
+ axisY[0] = 0; axisY[1] = axisZ[2] / len; axisY[2] = -axisZ[1] / len;
+ cross_v3_v3v3(axisX, axisY, axisZ);
+ }
+ else if (faY <= faZ) {
+ const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[2] * axisZ[2]);
+ axisX[0] = axisZ[2] / len; axisX[1] = 0; axisX[2] = -axisZ[0] / len;
+ cross_v3_v3v3(axisY, axisZ, axisX);
+ }
+ else {
+ const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1]);
+ axisX[0] = axisZ[1] / len; axisX[1] = -axisZ[0] / len; axisX[2] = 0;
+ cross_v3_v3v3(axisY, axisZ, axisX);
+ }
+}
+
+/* return FALSE if nothing was hit and TRUE otherwise */
+static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_direction[3])
+{
+ Isect isect = {{0}};
+
+ isect.dist = RE_RAYTRACE_MAXDIST;
+ copy_v3_v3(isect.start, ray_start);
+ copy_v3_v3(isect.dir, ray_direction);
+ isect.lay = -1;
+
+ normalize_v3(isect.dir);
+
+ return RE_rayobject_raycast(ao_data->raytree, &isect);
+}
+
+static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *UNUSED(thread_data),
+ void *bake_data, ImBuf *ibuf, const int face_index, const int lvl,
+ const float st[2], float UNUSED(tangmat[3][3]), const int x, const int y)
+{
+ MAOBakeData *ao_data = (MAOBakeData *) bake_data;
+ MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+
+ int i, k, perm_offs;
+ float pos[3], nrm[3];
+ float cen[3];
+ float axisX[3], axisY[3], axisZ[3];
+ float shadow = 0;
+ float value;
+ int pixel = ibuf->x * y + x;
+ float uv[2], *st0, *st1, *st2, *st3;
+
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ st0 = mtface[face_index].uv[0];
+ st1 = mtface[face_index].uv[1];
+ st2 = mtface[face_index].uv[2];
+
+ if (mface.v4) {
+ st3 = mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ }
+ else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm,
+ ao_data->orig_index_mf_to_mpoly, ao_data->orig_index_mp_to_orig,
+ lvl, face_index, uv[0], uv[1], pos, nrm);
+
+ /* offset ray origin by user bias along normal */
+ for (i = 0; i < 3; i++)
+ cen[i] = pos[i] + ao_data->bias * nrm[i];
+
+ /* build tangent frame */
+ for (i = 0; i < 3; i++)
+ axisZ[i] = nrm[i];
+
+ build_coordinate_frame(axisX, axisY, axisZ);
+
+ /* static noise */
+ perm_offs = (get_ao_random2(get_ao_random1(x) + y)) & (MAX_NUMBER_OF_AO_RAYS - 1);
+
+ /* importance sample shadow rays (cosine weighted) */
+ for (i = 0; i < ao_data->number_of_rays; i++) {
+ int hit_something;
+
+ /* use N-Rooks to distribute our N ray samples across
+ * a multi-dimensional domain (2D)
+ */
+ const unsigned short I = ao_data->permutation_table_1[(i + perm_offs) % ao_data->number_of_rays];
+ const unsigned short J = ao_data->permutation_table_2[i];
+
+ const float JitPh = (get_ao_random2(I + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS);
+ const float JitTh = (get_ao_random1(J + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS);
+ const float SiSqPhi = (I + JitPh) / ao_data->number_of_rays;
+ const float Theta = (float)(2 * M_PI) * ((J + JitTh) / ao_data->number_of_rays);
+
+ /* this gives results identical to the so-called cosine
+ * weighted distribution relative to the north pole.
+ */
+ float SiPhi = sqrt(SiSqPhi);
+ float CoPhi = SiSqPhi < 1.0f ? sqrtf(1.0f - SiSqPhi) : 0;
+ float CoThe = cos(Theta);
+ float SiThe = sin(Theta);
+
+ const float dx = CoThe * CoPhi;
+ const float dy = SiThe * CoPhi;
+ const float dz = SiPhi;
+
+ /* transform ray direction out of tangent frame */
+ float dv[3];
+ for (k = 0; k < 3; k++)
+ dv[k] = axisX[k] * dx + axisY[k] * dy + axisZ[k] * dz;
+
+ hit_something = trace_ao_ray(ao_data, cen, dv);
+
+ if (hit_something != 0)
+ shadow += 1;
+ }
+
+ value = 1.0f - (shadow / ao_data->number_of_rays);
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + pixel * 4;
+ rrgbf[0] = rrgbf[1] = rrgbf[2] = value;
+ rrgbf[3] = 1.0f;
+ }
+ else {
+ unsigned char *rrgb = (unsigned char *) ibuf->rect + pixel * 4;
+ rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(value);
+ rrgb[3] = 255;
+ }
+}
+
+/* **************** Common functions public API relates on **************** */
+
+static void count_images(MultiresBakeRender *bkr)
+{
+ int a, totface;
+ DerivedMesh *dm = bkr->lores_dm;
+ MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+
+ bkr->image.first = bkr->image.last = NULL;
+ bkr->tot_image = 0;
+
+ totface = dm->getNumTessFaces(dm);
+
+ for (a = 0; a < totface; a++)
+ mtface[a].tpage->id.flag &= ~LIB_DOIT;
+
+ for (a = 0; a < totface; a++) {
+ Image *ima = mtface[a].tpage;
+ if ((ima->id.flag & LIB_DOIT) == 0) {
+ LinkData *data = BLI_genericNodeN(ima);
+ BLI_addtail(&bkr->image, data);
+ bkr->tot_image++;
+ ima->id.flag |= LIB_DOIT;
+ }
+ }
+
+ for (a = 0; a < totface; a++)
+ mtface[a].tpage->id.flag &= ~LIB_DOIT;
+}
+
+static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
+{
+ LinkData *link;
+
+ for (link = bkr->image.first; link; link = link->next) {
+ Image *ima = (Image *)link->data;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
+ if (ibuf->x > 0 && ibuf->y > 0) {
+ BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData), "MultiresBake userdata");
+ userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
+ ibuf->userdata = userdata;
+
+ switch (bkr->mode) {
+ case RE_BAKE_NORMALS:
+ do_multires_bake(bkr, ima, TRUE, apply_tangmat_callback, init_normal_data, free_normal_data, result);
+ break;
+ case RE_BAKE_DISPLACEMENT:
+ do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data, free_heights_data, result);
+ break;
+ case RE_BAKE_AO:
+ do_multires_bake(bkr, ima, FALSE, apply_ao_callback, init_ao_data, free_ao_data, result);
+ break;
+ }
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ ima->id.flag |= LIB_DOIT;
+ }
+}
+
+static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
+{
+ LinkData *link;
+ int use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT;
+
+ for (link = bkr->image.first; link; link = link->next) {
+ Image *ima = (Image *)link->data;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata;
+
+ if (ibuf->x <= 0 || ibuf->y <= 0)
+ continue;
+
+ if (use_displacement_buffer) {
+ RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ result->height_min, result->height_max);
+ }
+
+ RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter);
+
+ ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
+
+ if (ibuf->rect_float)
+ ibuf->userflags |= IB_RECT_INVALID;
+
+ if (ibuf->mipmap[0]) {
+ ibuf->userflags |= IB_MIPMAP_INVALID;
+ imb_freemipmapImBuf(ibuf);
+ }
+
+ if (ibuf->userdata) {
+ if (userdata->displacement_buffer)
+ MEM_freeN(userdata->displacement_buffer);
+
+ MEM_freeN(userdata->mask_buffer);
+ MEM_freeN(userdata);
+ ibuf->userdata = NULL;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+}
+
+void RE_multires_bake_images(MultiresBakeRender *bkr)
+{
+ MultiresBakeResult result;
+
+ count_images(bkr);
+ bake_images(bkr, &result);
+ finish_images(bkr, &result);
+}
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index a7308821843..747362a7974 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -1520,8 +1520,8 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
return 0;
/* require intensities not being too different */
- mino = MIN4(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
- maxo = MAX4(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+ mino = min_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+ maxo = max_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
if (maxo - mino > 0.05f)
return 0;
@@ -1793,9 +1793,9 @@ void sample_occ(Render *re, ShadeInput *shi)
copy_v3_v3(sample->ao, shi->ao);
copy_v3_v3(sample->env, shi->env);
copy_v3_v3(sample->indirect, shi->indirect);
- sample->intensity = MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
- sample->intensity = MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2]));
- sample->intensity = MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
+ sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2]));
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco);
sample->filled = 1;
}
@@ -1888,9 +1888,9 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
copy_v3_v3(sample->ao, shi->ao);
copy_v3_v3(sample->env, shi->env);
copy_v3_v3(sample->indirect, shi->indirect);
- sample->intensity = MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
- sample->intensity = MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2]));
- sample->intensity = MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
+ sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2]));
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco);
sample->x = shi->xs;
sample->y = shi->ys;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 6b5b9716f3b..1d04d5a117b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -45,6 +45,16 @@
#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_rect.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
+#include "BLI_fileops.h"
+#include "BLI_threads.h"
+#include "BLI_rand.h"
+#include "BLI_callbacks.h"
+
#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
#include "BKE_camera.h"
#include "BKE_global.h"
@@ -57,16 +67,6 @@
#include "BKE_sequencer.h"
#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
-#include "BLI_math.h"
-#include "BLI_rect.h"
-#include "BLI_listbase.h"
-#include "BLI_string.h"
-#include "BLI_path_util.h"
-#include "BLI_fileops.h"
-#include "BLI_threads.h"
-#include "BLI_rand.h"
-#include "BLI_callbacks.h"
-
#include "PIL_time.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@@ -336,7 +336,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
RenderResult rres;
RE_AcquireResultImage(re, &rres);
- render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings);
+ render_result_rect_get_pixels(&rres, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings);
RE_ReleaseResultImage(re);
}
@@ -469,7 +469,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
re->recty = winy;
}
- if (re->rectx < 2 || re->recty < 2 || (BKE_imtype_is_movie(rd->im_format.imtype) &&
+ if (re->rectx < 1 || re->recty < 1 || (BKE_imtype_is_movie(rd->im_format.imtype) &&
(re->rectx < 16 || re->recty < 16) ))
{
BKE_report(re->reports, RPT_ERROR, "Image too small");
@@ -582,7 +582,7 @@ void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)
re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend);
}
-void RE_SetView(Render *re, float mat[][4])
+void RE_SetView(Render *re, float mat[4][4])
{
/* re->ok flag? */
copy_m4_m4(re->viewmat, mat);
@@ -655,7 +655,9 @@ static int render_display_draw_enabled(Render *re)
static void *do_part_thread(void *pa_v)
{
RenderPart *pa = pa_v;
-
+
+ pa->status = PART_STATUS_IN_PROGRESS;
+
/* need to return nicely all parts on esc */
if (R.test_break(R.tbh) == 0) {
@@ -671,6 +673,10 @@ static void *do_part_thread(void *pa_v)
else
zbufshade_tile(pa);
+ /* we do actually write pixels, but don't allocate/deallocate anything,
+ * so it is safe with other threads reading at the same time */
+ BLI_rw_mutex_lock(&R.resultmutex, THREAD_LOCK_READ);
+
/* merge too on break! */
if (R.result->do_exr_tile) {
render_result_exr_file_merge(R.result, pa->result);
@@ -684,9 +690,11 @@ static void *do_part_thread(void *pa_v)
render_result_merge(R.result, pa->result);
}
}
+
+ BLI_rw_mutex_unlock(&R.resultmutex);
}
- pa->ready = 1;
+ pa->status = PART_STATUS_READY;
return NULL;
}
@@ -717,24 +725,33 @@ float panorama_pixel_rot(Render *re)
return phi;
}
-/* call when all parts stopped rendering, to find the next Y slice */
-/* if slice found, it rotates the dbase */
-static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
+/* for panorama, we render per Y slice, and update
+ * camera parameters when we go the next slice */
+static bool find_next_pano_slice(Render *re, int *slice, int *minx, rctf *viewplane)
{
RenderPart *pa, *best = NULL;
+ bool found = false;
*minx = re->winx;
+ if (!(re->r.mode & R_PANORAMA)) {
+ /* for regular render, just one 'slice' */
+ found = (*slice == 0);
+ (*slice)++;
+ return found;
+ }
+
/* most left part of the non-rendering parts */
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready == 0 && pa->nr == 0) {
+ if (pa->status == PART_STATUS_NONE && pa->nr == 0) {
if (pa->disprect.xmin < *minx) {
+ found = true;
best = pa;
*minx = pa->disprect.xmin;
}
}
}
-
+
if (best) {
float phi = panorama_pixel_rot(re);
@@ -752,7 +769,10 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
R.panosi = sin(R.panodxp * phi);
R.panoco = cos(R.panodxp * phi);
}
- return best;
+
+ (*slice)++;
+
+ return found;
}
static RenderPart *find_next_part(Render *re, int minx)
@@ -765,7 +785,7 @@ static RenderPart *find_next_part(Render *re, int minx)
/* find center of rendered parts, image center counts for 1 too */
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready) {
+ if (pa->status == PART_STATUS_READY) {
centx += BLI_rcti_cent_x(&pa->disprect);
centy += BLI_rcti_cent_y(&pa->disprect);
tot++;
@@ -776,7 +796,7 @@ static RenderPart *find_next_part(Render *re, int minx)
/* closest of the non-rendering parts */
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready == 0 && pa->nr == 0) {
+ if (pa->status == PART_STATUS_NONE && pa->nr == 0) {
long long int distx = centx - BLI_rcti_cent_x(&pa->disprect);
long long int disty = centy - BLI_rcti_cent_y(&pa->disprect);
distx = (long long int)sqrt(distx * distx + disty * disty);
@@ -807,33 +827,60 @@ static void print_part_stats(Render *re, RenderPart *pa)
re->i.infostr = NULL;
}
+typedef struct RenderThread {
+ ThreadQueue *workqueue;
+ ThreadQueue *donequeue;
+
+ int number;
+} RenderThread;
+
+static void *do_render_thread(void *thread_v)
+{
+ RenderThread *thread = thread_v;
+ RenderPart *pa;
+
+ while ((pa = BLI_thread_queue_pop(thread->workqueue))) {
+ pa->thread = thread->number;
+ do_part_thread(pa);
+ BLI_thread_queue_push(thread->donequeue, pa);
+
+ if(R.test_break(R.tbh))
+ break;
+ }
+
+ return NULL;
+}
+
static void threaded_tile_processor(Render *re)
{
+ RenderThread thread[BLENDER_MAX_THREADS];
+ ThreadQueue *workqueue, *donequeue;
ListBase threads;
- RenderPart *pa, *nextpa;
+ RenderPart *pa;
rctf viewplane = re->viewplane;
- int rendering = 1, counter = 1, drawtimer = 0, hasdrawn, minx = 0;
+ double lastdraw, elapsed, redrawtime = 1.0f;
+ int totpart = 0, minx = 0, slice = 0, a, wait;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
/* first step; free the entire render result, make new, and/or prepare exr buffer saving */
if (re->result == NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
render_result_free(re->result);
-
+
if (re->sss_points && render_display_draw_enabled(re))
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
else if (re->r.scemode & R_FULL_SAMPLE)
re->result = render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR);
else
re->result = render_result_new(re, &re->disprect, 0,
- (re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM, RR_ALL_LAYERS);
+ (re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM, RR_ALL_LAYERS);
}
BLI_rw_mutex_unlock(&re->resultmutex);
if (re->result == NULL)
return;
-
+
/* warning; no return here without closing exr file */
RE_parts_init(re, TRUE);
@@ -841,53 +888,46 @@ static void threaded_tile_processor(Render *re)
if (re->result->do_exr_tile)
render_result_exr_file_begin(re);
- BLI_init_threads(&threads, do_part_thread, re->r.threads);
-
/* assuming no new data gets added to dbase... */
R = *re;
/* set threadsafe break */
R.test_break = thread_break;
- /* timer loop demands to sleep when no parts are left, so we enter loop with a part */
- if (re->r.mode & R_PANORAMA)
- nextpa = find_next_pano_slice(re, &minx, &viewplane);
- else
- nextpa = find_next_part(re, 0);
-
- while (rendering) {
-
- if (re->test_break(re->tbh))
- PIL_sleep_ms(50);
- else if (nextpa && BLI_available_threads(&threads)) {
- drawtimer = 0;
- nextpa->nr = counter++; /* for nicest part, and for stats */
- nextpa->thread = BLI_available_thread_index(&threads); /* sample index */
- BLI_insert_thread(&threads, nextpa);
-
- nextpa = find_next_part(re, minx);
+ /* create and fill work queue */
+ workqueue = BLI_thread_queue_init();
+ donequeue = BLI_thread_queue_init();
+
+ /* for panorama we loop over slices */
+ while (find_next_pano_slice(re, &slice, &minx, &viewplane)) {
+ /* gather parts into queue */
+ while ((pa = find_next_part(re, minx))) {
+ pa->nr = totpart + 1; /* for nicest part, and for stats */
+ totpart++;
+ BLI_thread_queue_push(workqueue, pa);
}
- else if (re->r.mode & R_PANORAMA) {
- if (nextpa == NULL && BLI_available_threads(&threads) == re->r.threads)
- nextpa = find_next_pano_slice(re, &minx, &viewplane);
- else {
- PIL_sleep_ms(50);
- drawtimer++;
- }
- }
- else {
- PIL_sleep_ms(50);
- drawtimer++;
+
+ BLI_thread_queue_nowait(workqueue);
+
+ /* start all threads */
+ BLI_init_threads(&threads, do_render_thread, re->r.threads);
+
+ for (a = 0; a < re->r.threads; a++) {
+ thread[a].workqueue = workqueue;
+ thread[a].donequeue = donequeue;
+ thread[a].number = a;
+ BLI_insert_thread(&threads, &thread[a]);
}
- /* check for ready ones to display, and if we need to continue */
- rendering = 0;
- hasdrawn = 0;
- for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready) {
-
- BLI_remove_thread(&threads, pa);
-
+ /* wait for results to come back */
+ lastdraw = PIL_check_seconds_timer();
+
+ while (1) {
+ elapsed = PIL_check_seconds_timer() - lastdraw;
+ wait = (redrawtime - elapsed)*1000;
+
+ /* handle finished part */
+ if ((pa=BLI_thread_queue_pop_timeout(donequeue, wait))) {
if (pa->result) {
if (render_display_draw_enabled(re))
re->display_draw(re->ddh, pa->result, NULL);
@@ -897,27 +937,40 @@ static void threaded_tile_processor(Render *re)
pa->result = NULL;
re->i.partsdone++;
re->progress(re->prh, re->i.partsdone / (float)re->i.totpart);
- hasdrawn = 1;
}
+
+ totpart--;
}
- else {
- rendering = 1;
- if (pa->nr && pa->result && drawtimer > 20) {
- if (render_display_draw_enabled(re))
- re->display_draw(re->ddh, pa->result, &pa->result->renrect);
- hasdrawn = 1;
- }
+
+ /* check for render cancel */
+ if ((g_break=re->test_break(re->tbh)))
+ break;
+
+ /* or done with parts */
+ if (totpart == 0)
+ break;
+
+ /* redraw in progress parts */
+ elapsed = PIL_check_seconds_timer() - lastdraw;
+ if (elapsed > redrawtime) {
+ if (render_display_draw_enabled(re))
+ for (pa = re->parts.first; pa; pa = pa->next)
+ if ((pa->status == PART_STATUS_IN_PROGRESS) && pa->nr && pa->result)
+ re->display_draw(re->ddh, pa->result, &pa->result->renrect);
+
+ lastdraw = PIL_check_seconds_timer();
}
}
- if (hasdrawn)
- drawtimer = 0;
-
- /* on break, wait for all slots to get freed */
- if ( (g_break = re->test_break(re->tbh)) && BLI_available_threads(&threads) == re->r.threads)
- rendering = 0;
+ BLI_end_threads(&threads);
+
+ if ((g_break=re->test_break(re->tbh)))
+ break;
}
+ BLI_thread_queue_free(donequeue);
+ BLI_thread_queue_free(workqueue);
+
if (re->result->do_exr_tile) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
render_result_exr_file_end(re);
@@ -927,7 +980,6 @@ static void threaded_tile_processor(Render *re)
/* unset threadsafety */
g_break = 0;
- BLI_end_threads(&threads);
RE_parts_free(re);
re->viewplane = viewplane; /* restore viewplane, modified by pano render */
}
@@ -942,6 +994,9 @@ void RE_TileProcessor(Render *re)
static void do_render_3d(Render *re)
{
+ float cfra;
+ int cfra_backup;
+
/* try external */
if (RE_engine_render(re, 0))
return;
@@ -949,9 +1004,13 @@ static void do_render_3d(Render *re)
/* internal */
RE_parts_clamp(re);
-// re->cfra= cfra; /* <- unused! */
- re->scene->r.subframe = re->mblur_offs + re->field_offs;
-
+ /* add motion blur and fields offset to frames */
+ cfra_backup = re->scene->r.cfra;
+
+ cfra = re->scene->r.cfra + re->mblur_offs + re->field_offs;
+ re->scene->r.cfra = floorf(cfra);
+ re->scene->r.subframe = cfra - floorf(cfra);
+
/* lock drawing in UI during data phase */
if (re->draw_lock)
re->draw_lock(re->dlh, 1);
@@ -976,6 +1035,7 @@ static void do_render_3d(Render *re)
/* free all render verts etc */
RE_Database_Free(re);
+ re->scene->r.cfra = cfra_backup;
re->scene->r.subframe = 0.f;
}
@@ -1084,7 +1144,7 @@ static void do_render_blur_3d(Render *re)
blurfac = 1.0f / (float)(re->r.mblur_samples - blur);
- merge_renderresult_blur(rres, re->result, blurfac, re->r.alphamode & R_ALPHAKEY);
+ merge_renderresult_blur(rres, re->result, blurfac, FALSE);
if (re->test_break(re->tbh)) break;
}
@@ -1229,7 +1289,7 @@ static void do_render_fields_blur_3d(Render *re)
Object *camera = RE_GetCamera(re);
/* also check for camera here */
if (camera == NULL) {
- printf("ERROR: Cannot render, no camera\n");
+ BKE_report(re->reports, RPT_ERROR, "Cannot render, no camera");
G.is_break = TRUE;
return;
}
@@ -1312,6 +1372,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
resc->main = re->main;
resc->scene = sce;
resc->lay = sce->lay;
+ resc->scene_color_manage = BKE_scene_check_color_management_enabled(sce);
/* ensure scene has depsgraph, base flags etc OK */
BKE_scene_set_background(re->main, sce);
@@ -1345,6 +1406,19 @@ static int composite_needs_render(Scene *sce, int this_scene)
return 0;
}
+static bool rlayer_node_uses_alpha(bNodeTree *ntree, bNode *node)
+{
+ bNodeSocket *sock;
+
+ for (sock = node->outputs.first; sock; sock = sock->next) {
+ /* Weak! but how to make it better? */
+ if (!strcmp(sock->name, "Alpha") && nodeCountSocketLinks(ntree, sock) > 0)
+ return true;
+ }
+
+ return false;
+}
+
static void tag_scenes_for_render(Render *re)
{
bNode *node;
@@ -1362,6 +1436,21 @@ static void tag_scenes_for_render(Render *re)
for (node = re->scene->nodetree->nodes.first; node; node = node->next) {
if (node->type == CMP_NODE_R_LAYERS) {
if (node->id) {
+ if (!MAIN_VERSION_ATLEAST(re->main, 265, 5)) {
+ if (rlayer_node_uses_alpha(re->scene->nodetree, node)) {
+ Scene *scene = (Scene*) node->id;
+
+ if (scene->r.alphamode != R_ALPHAPREMUL) {
+ BKE_reportf(re->reports, RPT_WARNING, "Setting scene %s alpha mode to Premul\n", scene->id.name + 2);
+
+ /* also print, so feedback is immediate */
+ printf("2.66 versioning fix: setting scene %s alpha mode to Premul\n", scene->id.name + 2);
+
+ scene->r.alphamode = R_ALPHAPREMUL;
+ }
+ }
+ }
+
if (node->id != (ID *)re->scene)
node->id->flag |= LIB_DOIT;
}
@@ -1789,7 +1878,12 @@ static void do_render_all_options(Render *re)
re->display_draw(re->ddh, re->result, NULL);
}
else {
+ re->pool = BKE_image_pool_new();
+
do_render_composite_fields_blur_3d(re);
+
+ BKE_image_pool_free(re->pool);
+ re->pool = NULL;
}
re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
@@ -2109,7 +2203,7 @@ 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.imtype, scene->r.scemode & R_EXTENSION, FALSE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, FALSE);
/* reports only used for Movie */
do_write_image_or_movie(re, bmain, scene, NULL, name);
@@ -2168,7 +2262,7 @@ 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.imtype, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
if (re->r.im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
if (re->result) {
@@ -2196,7 +2290,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, R_IMF_IMTYPE_JPEG90);
+ BKE_add_image_extension(name, &imf);
ibuf->planes = 24;
IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, &scene->view_settings,
@@ -2301,7 +2395,7 @@ 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.imtype, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
if (scene->r.mode & R_NO_OVERWRITE && BLI_exists(name)) {
printf("skipping existing frame \"%s\"\n", name);
@@ -2375,6 +2469,8 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL);
+ re->pool = BKE_image_pool_new();
+
re->main = bmain;
re->scene = sce;
re->scene_color_manage = BKE_scene_check_color_management_enabled(sce);
@@ -2384,6 +2480,9 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
RE_SetCamera(re, camera);
do_render_3d(re);
+
+ BKE_image_pool_free(re->pool);
+ re->pool = NULL;
}
/* note; repeated win/disprect calc... solve that nicer, also in compo */
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index 74de8a1291f..66fd2209881 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -120,7 +120,7 @@ void addalphaAddfacFloat(float dest[4], const float source[4], char addfac)
else
#endif
dest[0] = c;
-
+
c = (m * dest[1]) + source[1];
#ifdef RE_FLOAT_COLOR_CLIPPING
if (c >= RE_FULL_COLOR_FLOAT) dest[1] = RE_FULL_COLOR_FLOAT;
@@ -206,7 +206,7 @@ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int ro
}
-void mask_array(unsigned int mask, float filt[][3])
+void mask_array(unsigned int mask, float filt[3][3])
{
float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2;
unsigned int maskand = (mask & 255);
@@ -244,7 +244,7 @@ void mask_array(unsigned int mask, float filt[][3])
* </pre>
*/
-void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y)
+void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y)
{
float *fpoin[3][3];
float val, r, g, b, al, lfilt[3][3];
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 3420648cb52..8a023a2c009 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -286,7 +286,7 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
/* fill in col */
float t, zn, radist, ringf=0.0f, linef=0.0f, alpha, si, co;
int a;
-
+
if (R.wrld.mode & WO_MIST) {
if (har->type & HA_ONLYSKY) {
/* stars but no mist */
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index a540cdb85d5..3ca4015ff7b 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -447,7 +447,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
turb = BLI_gTurbulence(pd->noise_size, texvec[0]+age, texvec[1]+age, texvec[2]+age, pd->noise_depth, 0, pd->noise_basis);
}
else if (pd->noise_influence == TEX_PD_NOISE_TIME) {
- time = R.cfra / (float)R.r.efra;
+ time = R.r.cfra / (float)R.r.efra;
turb = BLI_gTurbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth, 0, pd->noise_basis);
//turb = BLI_turbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth);
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 127e0bc07b9..fe23f31c6d7 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -81,7 +81,7 @@ extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
static int test_break(void *data)
{
- Render *re = (Render*)data;
+ Render *re = (Render *)data;
return re->test_break(re->tbh);
}
@@ -94,7 +94,7 @@ static void RE_rayobject_config_control(RayObject *r, Render *re)
}
}
-static RayObject* RE_rayobject_create(Render *re, int type, int size)
+RayObject *RE_rayobject_create(int type, int size, int octree_resolution)
{
RayObject * res = NULL;
@@ -117,7 +117,7 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size)
if (type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres
- res = RE_rayobject_octree_create(re->r.ocres, size);
+ res = RE_rayobject_octree_create(octree_resolution, size);
else if (type == R_RAYSTRUCTURE_BLIBVH)
res = RE_rayobject_blibvh_create(size);
else if (type == R_RAYSTRUCTURE_VBVH)
@@ -129,10 +129,18 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size)
else
res = RE_rayobject_vbvh_create(size); //Fallback
+ return res;
+}
+
+static RayObject* rayobject_create(Render *re, int type, int size)
+{
+ RayObject * res = NULL;
+
+ res = RE_rayobject_create(type, size, re->r.ocres);
if (res)
RE_rayobject_config_control(res, re);
-
+
return res;
}
@@ -240,11 +248,11 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
return NULL;
//Create Ray cast accelaration structure
- raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces );
+ raytree = rayobject_create( re, re->r.raytrace_structure, faces );
if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
- vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives");
+ vlakprimitive = obr->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "ObjectRen primitives");
else
- face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
+ face = obr->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "ObjectRen faces");
obr->rayobi = obi;
@@ -334,13 +342,13 @@ static void makeraytree_single(Render *re)
}
//Create raytree
- raytree = re->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces+special );
+ raytree = re->raytree = rayobject_create( re, re->r.raytrace_structure, faces+special );
if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) {
- vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives");
+ vlakprimitive = re->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "Raytrace vlak-primitives");
}
else {
- face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");
+ face = re->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "Render ray faces");
}
for (obi=re->instancetable.first; obi; obi=obi->next)
@@ -425,14 +433,18 @@ void makeraytree(Render *re)
* This is ONLY needed to kept a bogus behavior of SUN and HEMI lights */
INIT_MINMAX(min, max);
RE_rayobject_merge_bb(re->raytree, min, max);
+ if (min[0] > max[0]) { /* empty raytree */
+ zero_v3(min);
+ zero_v3(max);
+ }
for (i=0; i<3; i++) {
+ /* TODO: explain why add top both min and max??? */
min[i] += 0.01f;
max[i] += 0.01f;
sub[i] = max[i]-min[i];
}
- re->maxdist = dot_v3v3(sub, sub);
- if (re->maxdist > 0.0f) re->maxdist= sqrt(re->maxdist);
+ re->maxdist = len_v3(sub);
re->i.infostr= "Raytree finished";
re->stats_draw(re->sdh, &re->i);
@@ -488,8 +500,8 @@ static void shade_ray_set_derivative(ShadeInput *shi)
void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
{
- ObjectInstanceRen *obi= (ObjectInstanceRen*)is->hit.ob;
- VlakRen *vlr= (VlakRen*)is->hit.face;
+ ObjectInstanceRen *obi = (ObjectInstanceRen *)is->hit.ob;
+ VlakRen *vlr = (VlakRen *)is->hit.face;
/* set up view vector */
copy_v3_v3(shi->view, is->dir);
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index f8281586038..c779b01afaa 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -35,11 +35,6 @@
#include "MEM_guardedalloc.h"
-#include "BKE_image.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_report.h"
-
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
@@ -48,6 +43,11 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BKE_image.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
@@ -434,7 +434,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop;
/* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
rr->crop = crop;
-
+
/* tilerect is relative coordinates within render disprect. do not subtract crop yet */
rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
@@ -924,7 +924,7 @@ static void save_empty_result_tiles(Render *re)
IMB_exrtile_clear_channels(rl->exrhandle);
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready == 0) {
+ if (pa->status != PART_STATUS_READY) {
int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
@@ -1077,8 +1077,7 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
{
- int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) ? IB_cm_predivide : 0;
- ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags);
+ ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, 0);
/* if not exists, BKE_imbuf_write makes one */
ibuf->rect = (unsigned int *)rr->rect32;
@@ -1095,6 +1094,10 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) {
IMB_float_from_rect(ibuf);
}
+ else {
+ /* ensure no float buffer remained from previous frame */
+ ibuf->rect_float = NULL;
+ }
}
/* color -> grayscale */
@@ -1148,17 +1151,15 @@ void render_result_rect_fill_zero(RenderResult *rr)
rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
}
-void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty,
+void render_result_rect_get_pixels(RenderResult *rr, unsigned int *rect, int rectx, int recty,
const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
{
if (rr->rect32) {
memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty);
}
else if (rr->rectf) {
- int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
-
IMB_display_buffer_transform_apply((unsigned char *) rect, rr->rectf, rr->rectx, rr->recty, 4,
- view_settings, display_settings, predivide);
+ view_settings, display_settings, TRUE);
}
else
/* else fill with black */
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index e6daa5f9094..15ca865643b 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -171,9 +171,9 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres)
do_colorband(tex->coba, texres->nor[2], col);
fac3= (col[0]+col[1]+col[2]);
- texres->nor[0]= 0.3333f*(fac0 - fac1);
- texres->nor[1]= 0.3333f*(fac0 - fac2);
- texres->nor[2]= 0.3333f*(fac0 - fac3);
+ texres->nor[0]= (fac0 - fac1) / 3.0f;
+ texres->nor[1]= (fac0 - fac2) / 3.0f;
+ texres->nor[2]= (fac0 - fac3) / 3.0f;
return;
}
@@ -1099,7 +1099,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)
+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)
{
float tmpvec[3];
int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */
@@ -1137,12 +1137,12 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
retval = texnoise(tex, texres);
break;
case TEX_IMAGE:
- if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres);
- else retval = imagewrap(tex, tex->ima, NULL, texvec, texres);
+ if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres, pool);
+ else retval = imagewrap(tex, tex->ima, NULL, texvec, texres, pool);
BKE_image_tag_time(tex->ima); /* tag image as having being used */
break;
case TEX_ENVMAP:
- retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres);
+ retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres, pool);
break;
case TEX_MUSGRAVE:
/* newnoise: musgrave types */
@@ -1214,7 +1214,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
/* this is called from the shader and texture nodes */
int multitex_nodes(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)
+ const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool)
{
if (tex==NULL) {
memset(texres, 0, sizeof(TexResult));
@@ -1230,16 +1230,16 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
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);
+ rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool);
if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace);
- BKE_image_release_ibuf(tex->ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
}
}
else {
@@ -1263,28 +1263,28 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
}
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);
+ rgbnor = multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output, pool);
{
- ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace);
- BKE_image_release_ibuf(tex->ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
}
}
return rgbnor;
}
else {
- return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
+ return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool);
}
}
/* 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)
+static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool)
{
Tex *tex = mtex->tex;
@@ -1295,24 +1295,24 @@ 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);
+ return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output, pool);
}
}
/* Warning, if the texres's values are not declared zero, check the return value to be sure
* the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */
-int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres)
+int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool)
{
- return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL);
+ return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool);
}
/* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */
-int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres)
+int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool)
{
int use_nodes= tex->use_nodes, retval;
tex->use_nodes = FALSE;
- retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL);
+ retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool);
tex->use_nodes= use_nodes;
return retval;
@@ -1339,7 +1339,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_MUL:
fact*= facg;
- facm= 1.0f-facg;
+ facm= 1.0f-fact;
in[0]= (facm+fact*tex[0])*out[0];
in[1]= (facm+fact*tex[1])*out[1];
in[2]= (facm+fact*tex[2])*out[2];
@@ -1347,7 +1347,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_SCREEN:
fact*= facg;
- facm= 1.0f-facg;
+ facm= 1.0f-fact;
in[0]= 1.0f - (facm+fact*(1.0f-tex[0])) * (1.0f-out[0]);
in[1]= 1.0f - (facm+fact*(1.0f-tex[1])) * (1.0f-out[1]);
in[2]= 1.0f - (facm+fact*(1.0f-tex[2])) * (1.0f-out[2]);
@@ -1355,7 +1355,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_OVERLAY:
fact*= facg;
- facm= 1.0f-facg;
+ facm= 1.0f-fact;
if (out[0] < 0.5f)
in[0] = out[0] * (facm + 2.0f*fact*tex[0]);
@@ -1699,7 +1699,8 @@ 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])
+ 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)
{
TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */
float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
@@ -1727,12 +1728,12 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
/* in case we have no proper derivatives, fall back to
* computing du/dv it based on image size */
- ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
if (ibuf) {
du = 1.f/(float)ibuf->x;
dv = 1.f/(float)ibuf->y;
}
- BKE_image_release_ibuf(tex->ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
}
else if (shi->osatex) {
/* we have derivatives, can compute proper du/dv */
@@ -1745,15 +1746,15 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
else { /* 3d procedural, estimate from all dx/dy elems */
const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
- du = MAX3(adx[0], adx[1], adx[2]);
- dv = MAX3(ady[0], ady[1], ady[2]);
+ du = max_fff(adx[0], adx[1], adx[2]);
+ dv = max_fff(ady[0], ady[1], ady[2]);
}
}
/* center, main return value */
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres);
- cd = fromrgb ? (texres->tr + texres->tg + texres->tb)*0.33333333f : texres->tin;
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool);
+ cd = fromrgb ? (texres->tr + texres->tg + texres->tb) / 3.0f : texres->tin;
if (mtex->texco == TEXCO_UV) {
/* for the uv case, use the same value for both du/dv,
@@ -1766,16 +1767,16 @@ 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);
- ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
/* +v val */
tco[0] = co[0] + compat_bump->dudnv*du;
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);
- vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
}
else {
float tu[3], tv[3];
@@ -1808,16 +1809,16 @@ 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);
- ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
/* +v val */
tco[0] = co[0] + tv[0]*dv;
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);
- vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
}
/* bumped normal */
@@ -1858,7 +1859,7 @@ 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])
+ float texvec[3], float dxt[3], float dyt[3], struct ImagePool *pool)
{
TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */
@@ -1905,20 +1906,20 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
/* resolve image dimensions */
if (found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
if (ibuf) {
dimx = ibuf->x;
dimy = ibuf->y;
aspect = ((float) dimy) / dimx;
}
- BKE_image_release_ibuf(tex->ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
}
if (found_deriv_map) {
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);
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool);
if (shi->obr->ob->derivedFinal) {
auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
@@ -1960,14 +1961,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);
+ rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres, pool);
Hll = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin;
/* use ttexr for the other 2 taps */
- multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr);
+ multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr, pool);
Hlr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr);
+ multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr, pool);
Hul = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
dHdx = Hscale*(Hlr - Hll);
@@ -1998,17 +1999,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);
+ rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres, pool);
/* Hc = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin; */ /* UNUSED */
/* use ttexr for the other taps */
- multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr);
+ multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr, pool);
Hl = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr);
+ multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr, pool);
Hr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr);
+ multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr, pool);
Hd = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr);
+ multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr, pool);
Hu = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
dHdx = Hscale*(Hr - Hl);
@@ -2285,20 +2286,22 @@ void do_material_tex(ShadeInput *shi, Render *re)
if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
if (use_compat_bump) {
rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex,
- &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt);
+ &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt,
+ re->pool);
}
else if (use_ntap_bump) {
rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex,
- &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt);
+ &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt,
+ re->pool);
}
else {
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres);
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool);
}
}
else {
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres);
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool);
}
/* texture output */
@@ -2402,13 +2405,13 @@ void do_material_tex(ShadeInput *shi, Render *re)
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, re->pool);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, re->pool);
}
if (mtex->mapto & MAP_COL) {
@@ -2737,7 +2740,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, 0, mtex->which_output); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */
+ rgbnor = multitex(tex, texvec, NULL, NULL, 0, &texres, 0, mtex->which_output, re->pool); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */
/* texture output */
@@ -2904,7 +2907,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);
+ rgb = multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output, har->pool);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -2936,13 +2939,13 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
/* inverse gamma correction */
if (mtex->tex->type==TEX_IMAGE) {
Image *ima = mtex->tex->ima;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &mtex->tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &mtex->tex->iuser, har->pool);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, har->pool);
}
fact= texres.tin*mtex->colfac;
@@ -3109,7 +3112,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);
+ rgb = multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output, R.pool);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -3157,13 +3160,13 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, R.pool);
}
if (mtex->mapto & WOMAP_HORIZ) {
@@ -3324,7 +3327,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);
+ rgb = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output, R.pool);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -3373,13 +3376,13 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_pool_release_ibuf(ima, ibuf, R.pool);
}
/* lamp colors were premultiplied with this */
@@ -3395,7 +3398,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)
+int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *pool)
{
Tex *tex;
TexResult texr;
@@ -3421,7 +3424,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);
+ rgb = multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output, pool);
if (rgb) {
texr.tin = rgb_to_bw(&texr.tr);
@@ -3485,8 +3488,8 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
texr.nor= NULL;
- if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr);
- else imagewrap(tex, ima, NULL, texvec, &texr);
+ if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr, R.pool);
+ else imagewrap(tex, ima, NULL, texvec, &texr, R.pool);
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 3431c3ff5de..2d0f575b3e3 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -51,9 +51,12 @@
#include "DNA_image_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_group_types.h"
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -710,9 +713,11 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
if (pass[3]==0.0f) {
copy_v4_v4(pass, col);
+ pass[3] = 1.0f;
}
else {
addAlphaUnderFloat(pass, col);
+ pass[3] = 1.0f;
}
}
}
@@ -981,29 +986,6 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
}
}
-static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
-{
- RenderLayer *rlpp[RE_MAX_OSA];
- int y, sample, totsample;
-
- totsample= get_sample_layers(pa, rl, rlpp);
-
- for (sample= 0; sample<totsample; sample++) {
- float *rectf= rlpp[sample]->rectf;
-
- for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
- if (rectf[3] >= 1.0f) {
- /* pass */
- }
- else if (rectf[3] > 0.0f) {
- rectf[0] /= rectf[3];
- rectf[1] /= rectf[3];
- rectf[2] /= rectf[3];
- }
- }
- }
-}
-
/* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */
static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
{
@@ -1156,7 +1138,7 @@ static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dma
dest[3]+= source[3];
return;
- }
+ }
dest[0]= (mul*dest[0]) + source[0];
dest[1]= (mul*dest[1]) + source[1];
@@ -1172,7 +1154,7 @@ typedef struct ZbufSolidData {
static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
{
- ZbufSolidData *sdata= (ZbufSolidData*)data;
+ ZbufSolidData *sdata = (ZbufSolidData *)data;
ListBase *lb= sdata->psmlist;
intptr_t *rd= pa->rectdaps;
int *ro= zspan->recto;
@@ -1312,10 +1294,6 @@ void zbufshadeDA_tile(RenderPart *pa)
/* clamp alpha to 0..1 range, can go outside due to filter */
clamp_alpha_rgb_range(pa, rl);
- /* de-premul alpha */
- if (R.r.alphamode & R_ALPHAKEY)
- convert_to_key_alpha(pa, rl);
-
/* free stuff within loop! */
MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
freeps(&psmlist);
@@ -1476,10 +1454,6 @@ void zbufshade_tile(RenderPart *pa)
if (rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
- /* de-premul alpha */
- if (R.r.alphamode & R_ALPHAKEY)
- convert_to_key_alpha(pa, rl);
-
if (edgerect) MEM_freeN(edgerect);
edgerect= NULL;
@@ -1740,7 +1714,7 @@ void zbufshade_sss_tile(RenderPart *pa)
#if 0
if (rs) {
/* for each sample in this pixel, shade it */
- for (ps=(PixStr*)*rs; ps; ps=ps->next) {
+ for (ps = (PixStr *)(*rs); ps; ps=ps->next) {
ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
ObjectRen *obr= obi->obr;
vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
@@ -2016,783 +1990,3 @@ void add_halo_flare(Render *re)
R.r.mode= mode;
}
-/* ************************* bake ************************ */
-
-
-typedef struct BakeShade {
- ShadeSample ssamp;
- ObjectInstanceRen *obi;
- VlakRen *vlr;
-
- ZSpan *zspan;
- Image *ima;
- ImBuf *ibuf;
-
- int rectx, recty, quad, type, vdone, ready;
-
- float dir[3];
- Object *actob;
-
- unsigned int *rect;
- float *rect_float;
-
- int use_mask;
- char *rect_mask; /* bake pixel mask */
-
- float dxco[3], dyco[3];
-
- short *do_update;
-
- struct ColorSpace *rect_colorspace;
-} BakeShade;
-
-static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v)
-{
- if (quad)
- shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
- else
- shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
-
- /* cache for shadow */
- shi->samplenr= R.shadowsamplenr[shi->thread]++;
-
- shi->mask= 0xFFFF; /* all samples */
-
- shi->u= -u;
- shi->v= -v;
- shi->xs= x;
- shi->ys= y;
-
- shade_input_set_uv(shi);
- shade_input_set_normals(shi);
-
- /* no normal flip */
- if (shi->flippednor)
- shade_input_flip_normals(shi);
-
- /* set up view vector to look right at the surface (note that the normal
- * is negated in the renderer so it does not need to be done here) */
- shi->view[0]= shi->vn[0];
- shi->view[1]= shi->vn[1];
- shi->view[2]= shi->vn[2];
-}
-
-static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang)
-{
- BakeShade *bs= handle;
- ShadeSample *ssamp= &bs->ssamp;
- ShadeResult shr;
- VlakRen *vlr= shi->vlr;
-
- shade_input_init_material(shi);
-
- if (bs->type==RE_BAKE_AO) {
- ambient_occlusion(shi);
-
- if (R.r.bake_flag & R_BAKE_NORMALIZE) {
- copy_v3_v3(shr.combined, shi->ao);
- }
- else {
- zero_v3(shr.combined);
- environment_lighting_apply(shi, &shr);
- }
- }
- else {
- if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
- shi->r = shi->g = shi->b = 1.0f;
-
- shade_input_set_shade_texco(shi);
-
- /* only do AO for a full bake (and obviously AO bakes)
- * AO for light bakes is a leftover and might not be needed */
- if ( ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT))
- shade_samples_do_AO(ssamp);
-
- if (shi->mat->nodetree && shi->mat->use_nodes) {
- ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
- shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
- }
- else
- shade_material_loop(shi, &shr);
-
- if (bs->type==RE_BAKE_NORMALS) {
- float nor[3];
-
- copy_v3_v3(nor, shi->vn);
-
- if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) {
- /* pass */
- }
- else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
- float mat[3][3], imat[3][3];
-
- /* bitangent */
- if (tvn && ttang) {
- copy_v3_v3(mat[0], ttang);
- cross_v3_v3v3(mat[1], tvn, ttang);
- mul_v3_fl(mat[1], ttang[3]);
- copy_v3_v3(mat[2], tvn);
- }
- else {
- copy_v3_v3(mat[0], shi->nmaptang);
- cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang);
- mul_v3_fl(mat[1], shi->nmaptang[3]);
- copy_v3_v3(mat[2], shi->nmapnorm);
- }
-
- invert_m3_m3(imat, mat);
- mul_m3_v3(imat, nor);
- }
- else if (R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
- mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */
- else if (R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
- mul_mat3_m4_v3(R.viewinv, nor);
-
- normalize_v3(nor); /* in case object has scaling */
-
- /* The invert of the red channel is to make
- * the normal map compliant with the outside world.
- * It needs to be done because in Blender
- * the normal used in the renderer points inward. It is generated
- * this way in calc_vertexnormals(). Should this ever change
- * this negate must be removed. */
- shr.combined[0]= (-nor[0])/2.0f + 0.5f;
- shr.combined[1]= nor[1]/2.0f + 0.5f;
- shr.combined[2]= nor[2]/2.0f + 0.5f;
- }
- else if (bs->type==RE_BAKE_TEXTURE) {
- shr.combined[0]= shi->r;
- shr.combined[1]= shi->g;
- shr.combined[2]= shi->b;
- shr.alpha = shi->alpha;
- }
- else if (bs->type==RE_BAKE_SHADOW) {
- copy_v3_v3(shr.combined, shr.shad);
- shr.alpha = shi->alpha;
- }
- else if (bs->type==RE_BAKE_SPEC_COLOR) {
- shr.combined[0]= shi->specr;
- shr.combined[1]= shi->specg;
- shr.combined[2]= shi->specb;
- shr.alpha = 1.0f;
- }
- else if (bs->type==RE_BAKE_SPEC_INTENSITY) {
- shr.combined[0]=
- shr.combined[1]=
- shr.combined[2]= shi->spec;
- shr.alpha = 1.0f;
- }
- else if (bs->type==RE_BAKE_MIRROR_COLOR) {
- shr.combined[0]= shi->mirr;
- shr.combined[1]= shi->mirg;
- shr.combined[2]= shi->mirb;
- shr.alpha = 1.0f;
- }
- else if (bs->type==RE_BAKE_MIRROR_INTENSITY) {
- shr.combined[0]=
- shr.combined[1]=
- shr.combined[2]= shi->ray_mirror;
- shr.alpha = 1.0f;
- }
- else if (bs->type==RE_BAKE_ALPHA) {
- shr.combined[0]=
- shr.combined[1]=
- shr.combined[2]= shi->alpha;
- shr.alpha = 1.0f;
- }
- else if (bs->type==RE_BAKE_EMIT) {
- shr.combined[0]=
- shr.combined[1]=
- shr.combined[2]= shi->emit;
- shr.alpha = 1.0f;
- }
- }
-
- if (bs->rect_float) {
- float *col= bs->rect_float + 4*(bs->rectx*y + x);
- copy_v3_v3(col, shr.combined);
- if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
- col[3]= shr.alpha;
- }
- else {
- col[3]= 1.0;
- }
- }
- else {
- unsigned char *col= (unsigned char *)(bs->rect + bs->rectx*y + x);
-
- if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
- float rgb[3];
-
- copy_v3_v3(rgb, shr.combined);
- if (R.scene_color_manage)
- IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace);
- rgb_float_to_uchar(col, rgb);
- }
- else {
- rgb_float_to_uchar(col, shr.combined);
- }
-
- if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
- col[3]= FTOCHAR(shr.alpha);
- }
- else {
- col[3]= 255;
- }
- }
-
- if (bs->rect_mask) {
- bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
- }
-}
-
-static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y)
-{
- BakeShade *bs= handle;
- float disp;
-
- if (R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) {
- disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
- }
- else {
- disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
- }
-
- if (bs->rect_float) {
- float *col= bs->rect_float + 4*(bs->rectx*y + x);
- col[0] = col[1] = col[2] = disp;
- col[3]= 1.0f;
- }
- else {
- char *col= (char *)(bs->rect + bs->rectx*y + x);
- col[0] = col[1] = col[2] = FTOCHAR(disp);
- col[3]= 255;
- }
- if (bs->rect_mask) {
- bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
- }
-}
-
-static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
-{
- float maxdist;
- int hit;
-
- /* might be useful to make a user setting for maxsize*/
- if (R.r.bake_maxdist > 0.0f)
- maxdist= R.r.bake_maxdist;
- else
- maxdist= RE_RAYTRACE_MAXDIST + R.r.bake_biasdist;
-
- /* 'dir' is always normalized */
- madd_v3_v3v3fl(isect->start, start, dir, -R.r.bake_biasdist);
-
- mul_v3_v3fl(isect->dir, dir, sign);
-
- isect->dist = maxdist;
-
- hit = RE_rayobject_raycast(raytree, isect);
- if (hit) {
- madd_v3_v3v3fl(hitco, isect->start, isect->dir, isect->dist);
-
- *dist= isect->dist;
- }
-
- return hit;
-}
-
-static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
-{
- VlakRen *vlr= bs->vlr;
- float A, d1, d2, d3, *v1, *v2, *v3;
-
- if (bs->quad) {
- v1= vlr->v1->co;
- v2= vlr->v3->co;
- v3= vlr->v4->co;
- }
- else {
- v1= vlr->v1->co;
- v2= vlr->v2->co;
- v3= vlr->v3->co;
- }
-
- /* formula derived from barycentric coordinates:
- * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
- * then taking u and v partial derivatives to get dxco and dyco */
- A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]);
-
- if (fabsf(A) > FLT_EPSILON) {
- A= 0.5f/A;
-
- d1= uv2[1] - uv3[1];
- d2= uv3[1] - uv1[1];
- d3= uv1[1] - uv2[1];
- bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
- bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
- bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
-
- d1= uv3[0] - uv2[0];
- d2= uv1[0] - uv3[0];
- d3= uv2[0] - uv1[0];
- bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
- bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
- bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
- }
- else {
- bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f;
- bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f;
- }
-
- if (bs->obi->flag & R_TRANSFORMED) {
- mul_m3_v3(bs->obi->nmat, bs->dxco);
- mul_m3_v3(bs->obi->nmat, bs->dyco);
- }
-}
-
-static void do_bake_shade(void *handle, int x, int y, float u, float v)
-{
- BakeShade *bs= handle;
- VlakRen *vlr= bs->vlr;
- ObjectInstanceRen *obi= bs->obi;
- Object *ob= obi->obr->ob;
- float l, *v1, *v2, *v3, tvn[3], ttang[4];
- int quad;
- ShadeSample *ssamp= &bs->ssamp;
- ShadeInput *shi= ssamp->shi;
-
- /* fast threadsafe break test */
- if (R.test_break(R.tbh))
- return;
-
- /* setup render coordinates */
- if (bs->quad) {
- v1= vlr->v1->co;
- v2= vlr->v3->co;
- v3= vlr->v4->co;
- }
- else {
- v1= vlr->v1->co;
- v2= vlr->v2->co;
- v3= vlr->v3->co;
- }
-
- l= 1.0f-u-v;
-
- /* shrink barycentric coordinates inwards slightly to avoid some issues
- * where baking selected to active might just miss the other face at the
- * near the edge of a face */
- if (bs->actob) {
- const float eps = 1.0f - 1e-4f;
- float invsum;
-
- u = (u - 0.5f)*eps + 0.5f;
- v = (v - 0.5f)*eps + 0.5f;
- l = (l - 0.5f)*eps + 0.5f;
-
- invsum = 1.0f/(u + v + l);
-
- u *= invsum;
- v *= invsum;
- l *= invsum;
- }
-
- /* renderco */
- shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
- shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
- shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
-
- if (obi->flag & R_TRANSFORMED)
- mul_m4_v3(obi->mat, shi->co);
-
- copy_v3_v3(shi->dxco, bs->dxco);
- copy_v3_v3(shi->dyco, bs->dyco);
-
- quad= bs->quad;
- bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
-
- if (bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
- shade_input_set_shade_texco(shi);
- copy_v3_v3(tvn, shi->nmapnorm);
- copy_v4_v4(ttang, shi->nmaptang);
- }
-
- /* if we are doing selected to active baking, find point on other face */
- if (bs->actob) {
- Isect isec, minisec;
- float co[3], minco[3], dist, mindist=0.0f;
- int hit, sign, dir=1;
-
- /* intersect with ray going forward and backward*/
- hit= 0;
- memset(&minisec, 0, sizeof(minisec));
- minco[0]= minco[1]= minco[2]= 0.0f;
-
- copy_v3_v3(bs->dir, shi->vn);
-
- for (sign=-1; sign<=1; sign+=2) {
- memset(&isec, 0, sizeof(isec));
- isec.mode= RE_RAY_MIRROR;
-
- isec.orig.ob = obi;
- isec.orig.face = vlr;
- isec.userdata= bs->actob;
- isec.check = RE_CHECK_VLR_BAKE;
- isec.skip = RE_SKIP_VLR_NEIGHBOUR;
-
- if (bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
- if (!hit || len_squared_v3v3(shi->co, co) < len_squared_v3v3(shi->co, minco)) {
- minisec= isec;
- mindist= dist;
- copy_v3_v3(minco, co);
- hit= 1;
- dir = sign;
- }
- }
- }
-
- if (bs->type==RE_BAKE_DISPLACEMENT) {
- if (hit)
- bake_displacement(handle, shi, (dir==-1)? mindist:-mindist, x, y);
- else
- bake_displacement(handle, shi, 0.0f, x, y);
- return;
- }
-
- /* if hit, we shade from the new point, otherwise from point one starting face */
- if (hit) {
- obi= (ObjectInstanceRen*)minisec.hit.ob;
- vlr= (VlakRen*)minisec.hit.face;
- quad= (minisec.isect == 2);
- copy_v3_v3(shi->co, minco);
-
- u= -minisec.u;
- v= -minisec.v;
- bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
- }
- }
-
- if (bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
- bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
- else
- bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
-}
-
-static int get_next_bake_face(BakeShade *bs)
-{
- ObjectRen *obr;
- VlakRen *vlr;
- MTFace *tface;
- static int v= 0, vdone = FALSE;
- static ObjectInstanceRen *obi= NULL;
-
- if (bs==NULL) {
- vlr= NULL;
- v= vdone = FALSE;
- obi= R.instancetable.first;
- return 0;
- }
-
- BLI_lock_thread(LOCK_CUSTOM1);
-
- for (; obi; obi=obi->next, v=0) {
- obr= obi->obr;
-
- for (; v<obr->totvlak; v++) {
- vlr= RE_findOrAddVlak(obr, v);
-
- if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
- tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
-
- if (tface && tface->tpage) {
- Image *ima= tface->tpage;
- ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
- const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
- const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
-
- if (ibuf==NULL)
- continue;
-
- if (ibuf->rect==NULL && ibuf->rect_float==NULL) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- continue;
- }
-
- if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- continue;
- }
-
- if (ima->flag & IMA_USED_FOR_RENDER) {
- ima->id.flag &= ~LIB_DOIT;
- BKE_image_release_ibuf(ima, ibuf, NULL);
- continue;
- }
-
- /* find the image for the first time? */
- if (ima->id.flag & LIB_DOIT) {
- ima->id.flag &= ~LIB_DOIT;
-
- /* we either fill in float or char, this ensures things go fine */
- if (ibuf->rect_float)
- imb_freerectImBuf(ibuf);
- /* clear image */
- if (R.r.bake_flag & R_BAKE_CLEAR)
- IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
-
- /* might be read by UI to set active image for display */
- R.bakebuf= ima;
- }
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- bs->obi= obi;
- bs->vlr= vlr;
-
- bs->vdone++; /* only for error message if nothing was rendered */
- v++;
-
- BLI_unlock_thread(LOCK_CUSTOM1);
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
- return 1;
- }
- }
- }
- }
-
- BLI_unlock_thread(LOCK_CUSTOM1);
- return 0;
-}
-
-/* already have tested for tface and ima and zspan */
-static void shade_tface(BakeShade *bs)
-{
- VlakRen *vlr= bs->vlr;
- ObjectInstanceRen *obi= bs->obi;
- ObjectRen *obr= obi->obr;
- MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
- Image *ima= tface->tpage;
- float vec[4][2];
- int a, i1, i2, i3;
-
- /* check valid zspan */
- if (ima!=bs->ima) {
- BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
-
- bs->ima= ima;
- bs->ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
- /* note, these calls only free/fill contents of zspan struct, not zspan itself */
- zbuf_free_span(bs->zspan);
- zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
- }
-
- bs->rectx= bs->ibuf->x;
- bs->recty= bs->ibuf->y;
- bs->rect= bs->ibuf->rect;
- bs->rect_colorspace= bs->ibuf->rect_colorspace;
- bs->rect_float= bs->ibuf->rect_float;
- bs->quad= 0;
-
- if (bs->use_mask) {
- if (bs->ibuf->userdata==NULL) {
- BLI_lock_thread(LOCK_CUSTOM1);
- if (bs->ibuf->userdata==NULL) /* since the thread was locked, its possible another thread alloced the value */
- bs->ibuf->userdata = (void *)MEM_callocN(sizeof(char)*bs->rectx*bs->recty, "BakeMask");
- bs->rect_mask= (char *)bs->ibuf->userdata;
- BLI_unlock_thread(LOCK_CUSTOM1);
- }
- else {
- bs->rect_mask= (char *)bs->ibuf->userdata;
- }
- }
-
- /* get pixel level vertex coordinates */
- for (a=0; a<4; a++) {
- /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
- * where a pixel gets in between 2 faces or the middle of a quad,
- * camera aligned quads also have this problem but they are less common.
- * Add a small offset to the UVs, fixes bug #18685 - Campbell */
- vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001f);
- vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002f);
- }
-
- /* UV indices have to be corrected for possible quad->tria splits */
- i1= 0; i2= 1; i3= 2;
- vlr_set_uv_indices(vlr, &i1, &i2, &i3);
- bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
- zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
-
- if (vlr->v4) {
- bs->quad= 1;
- bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
- zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
- }
-}
-
-static void *do_bake_thread(void *bs_v)
-{
- BakeShade *bs= bs_v;
-
- while (get_next_bake_face(bs)) {
- shade_tface(bs);
-
- /* fast threadsafe break test */
- if (R.test_break(R.tbh))
- break;
-
- /* access is not threadsafe but since its just true/false probably ok
- * only used for interactive baking */
- if (bs->do_update)
- *bs->do_update= TRUE;
- }
- bs->ready= 1;
-
- BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
-
- return NULL;
-}
-
-void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter)
-{
- /* must check before filtering */
- const short is_new_alpha= (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf);
-
- /* Margin */
- if (filter) {
- IMB_filter_extend(ibuf, mask, filter);
- }
-
- /* if the bake results in new alpha then change the image setting */
- if (is_new_alpha) {
- ibuf->planes= R_IMF_PLANES_RGBA;
- }
- else {
- if (filter && ibuf->planes != R_IMF_PLANES_RGBA) {
- /* clear alpha added by filtering */
- IMB_rectfill_alpha(ibuf, 1.0f);
- }
- }
-}
-
-/* using object selection tags, the faces with UV maps get baked */
-/* render should have been setup */
-/* returns 0 if nothing was handled */
-int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress)
-{
- BakeShade *handles;
- ListBase threads;
- Image *ima;
- int a, vdone = FALSE, use_mask = FALSE, result = BAKE_RESULT_OK;
-
- re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene);
-
- /* initialize render global */
- R= *re;
- R.bakebuf= NULL;
-
- /* initialize static vars */
- get_next_bake_face(NULL);
-
- /* do we need a mask? */
- if (re->r.bake_filter)
- use_mask = TRUE;
-
- /* baker uses this flag to detect if image was initialized */
- for (ima= G.main->image.first; ima; ima= ima->id.next) {
- ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
- ima->id.flag |= LIB_DOIT;
- ima->flag&= ~IMA_USED_FOR_RENDER;
- if (ibuf) {
- ibuf->userdata = NULL; /* use for masking if needed */
- }
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
-
- BLI_init_threads(&threads, do_bake_thread, re->r.threads);
-
- handles= MEM_callocN(sizeof(BakeShade)*re->r.threads, "BakeShade");
-
- /* get the threads running */
- for (a=0; a<re->r.threads; a++) {
- /* set defaults in handles */
- handles[a].ssamp.shi[0].lay= re->lay;
-
- if (type==RE_BAKE_SHADOW) {
- handles[a].ssamp.shi[0].passflag= SCE_PASS_SHADOW;
- }
- else {
- handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED;
- }
- handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
- handles[a].ssamp.shi[0].thread= a;
- handles[a].ssamp.tot= 1;
-
- handles[a].type= type;
- handles[a].actob= actob;
- handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
-
- handles[a].use_mask = use_mask;
-
- handles[a].do_update = do_update; /* use to tell the view to update */
-
- BLI_insert_thread(&threads, &handles[a]);
- }
-
- /* wait for everything to be done */
- a= 0;
- while (a!=re->r.threads) {
- PIL_sleep_ms(50);
-
- /* calculate progress */
- for (vdone = FALSE, a=0; a<re->r.threads; a++)
- vdone+= handles[a].vdone;
- if (progress)
- *progress = (float)(vdone / (float)re->totvlak);
-
- for (a=0; a<re->r.threads; a++) {
- if (handles[a].ready==0)
- break;
- }
- }
-
- /* filter and refresh images */
- for (ima= G.main->image.first; ima; ima= ima->id.next) {
- if ((ima->id.flag & LIB_DOIT)==0) {
- ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
-
- if (ima->flag & IMA_USED_FOR_RENDER)
- result= BAKE_RESULT_FEEDBACK_LOOP;
-
- if (!ibuf)
- continue;
-
- RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
-
- ibuf->userflags |= IB_BITMAPDIRTY;
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
- }
-
- /* calculate return value */
- for (a=0; a<re->r.threads; a++) {
- zbuf_free_span(handles[a].zspan);
- MEM_freeN(handles[a].zspan);
- }
-
- MEM_freeN(handles);
-
- BLI_end_threads(&threads);
-
- if (vdone==0)
- result= BAKE_RESULT_NO_OBJECTS;
-
- return result;
-}
-
-struct Image *RE_bake_shade_get_image(void)
-{
- return R.bakebuf;
-}
-
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 44daaf516e1..0a8af1c368b 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -105,6 +105,8 @@
#define RE_MTFACE_ELEMS 1
#define RE_MCOL_ELEMS 4
#define RE_UV_ELEMS 2
+#define RE_VLAK_ORIGINDEX_ELEMS 1
+#define RE_VERT_ORIGINDEX_ELEMS 1
#define RE_SURFNOR_ELEMS 3
#define RE_RADFACE_ELEMS 1
#define RE_SIMPLIFY_ELEMS 2
@@ -192,10 +194,26 @@ float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
return winspeed + ver->index*RE_WINSPEED_ELEMS;
}
+int *RE_vertren_get_origindex(ObjectRen *obr, VertRen *ver, int verify)
+{
+ int *origindex;
+ int nr= ver->index>>8;
+
+ origindex= obr->vertnodes[nr].origindex;
+ if (origindex==NULL) {
+ if (verify)
+ origindex= obr->vertnodes[nr].origindex= MEM_mallocN(256*RE_VERT_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
+ else
+ return NULL;
+ }
+ return origindex + (ver->index & 255)*RE_VERT_ORIGINDEX_ELEMS;
+}
+
VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
{
VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
float *fp1, *fp2;
+ int *int1, *int2;
int index= v1->index;
*v1= *ver;
@@ -221,6 +239,11 @@ VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
fp2= RE_vertren_get_tangent(obr, v1, 1);
memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
}
+ int1= RE_vertren_get_origindex(obr, ver, 0);
+ if (int1) {
+ int2= RE_vertren_get_origindex(obr, v1, 1);
+ memcpy(int2, int1, RE_VERT_ORIGINDEX_ELEMS*sizeof(int));
+ }
return v1;
}
@@ -332,6 +355,21 @@ MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int
return node->mcol + index*RE_MCOL_ELEMS;
}
+int *RE_vlakren_get_origindex(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ int *origindex;
+ int nr= vlak->index>>8;
+
+ origindex= obr->vlaknodes[nr].origindex;
+ if (origindex==NULL) {
+ if (verify)
+ origindex= obr->vlaknodes[nr].origindex= MEM_callocN(256*RE_VLAK_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
+ else
+ return NULL;
+ }
+ return origindex + (vlak->index & 255)*RE_VLAK_ORIGINDEX_ELEMS;
+}
+
float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
{
float *surfnor;
@@ -370,7 +408,7 @@ RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
radface= obr->vlaknodes[nr].radface;
if (radface==NULL) {
if (verify)
- radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table");
+ radface = obr->vlaknodes[nr].radface= MEM_callocN(256 * RE_RADFACE_ELEMS * sizeof(void *), "radface table");
else
return NULL;
}
@@ -383,6 +421,7 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
MTFace *mtface, *mtface1;
MCol *mcol, *mcol1;
float *surfnor, *surfnor1, *tangent, *tangent1;
+ int *origindex, *origindex1;
RadFace **radface, **radface1;
int i, index = vlr1->index;
char *name;
@@ -400,6 +439,13 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
}
+ origindex= RE_vlakren_get_origindex(obr, vlr, 0);
+ if (origindex) {
+ origindex1= RE_vlakren_get_origindex(obr, vlr1, 1);
+ /* Just an int, but memcpy for consistency. */
+ memcpy(origindex1, origindex, sizeof(int)*RE_VLAK_ORIGINDEX_ELEMS);
+ }
+
surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
if (surfnor) {
surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
@@ -725,6 +771,8 @@ void free_renderdata_vertnodes(VertTableNode *vertnodes)
MEM_freeN(vertnodes[a].stress);
if (vertnodes[a].winspeed)
MEM_freeN(vertnodes[a].winspeed);
+ if (vertnodes[a].origindex)
+ MEM_freeN(vertnodes[a].origindex);
}
MEM_freeN(vertnodes);
@@ -743,6 +791,8 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
MEM_freeN(vlaknodes[a].mtface);
if (vlaknodes[a].mcol)
MEM_freeN(vlaknodes[a].mcol);
+ if (vlaknodes[a].origindex)
+ MEM_freeN(vlaknodes[a].origindex);
if (vlaknodes[a].surfnor)
MEM_freeN(vlaknodes[a].surfnor);
if (vlaknodes[a].tangent)
@@ -888,9 +938,9 @@ HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
// TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
temp=obr->bloha;
- obr->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(obr->blohalen+TABLEINITSIZE), "Bloha");
- if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void*));
- memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
+ obr->bloha = (HaloRen**)MEM_callocN(sizeof(void *) * (obr->blohalen + TABLEINITSIZE), "Bloha");
+ if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void *));
+ memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE * sizeof(void *));
obr->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
if (temp) MEM_freeN(temp);
}
@@ -1001,7 +1051,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
}
}
- externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0);
+ externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool);
yn= tin*mtex->colfac;
//zn= tin*mtex->alphafac;
@@ -1020,6 +1070,8 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
}
}
+ har->pool = re->pool;
+
return har;
}
@@ -1130,7 +1182,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);
+ hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool);
//yn= tin*mtex->colfac;
//zn= tin*mtex->alphafac;
@@ -1173,6 +1225,8 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
//}
}
+ har->pool = re->pool;
+
return har;
}
@@ -1221,7 +1275,9 @@ static int panotestclip(Render *re, int do_pano, float v[4])
* - shadow buffering (shadbuf.c)
*/
-void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets))
+void project_renderdata(Render *re,
+ void (*projectfunc)(const float *, float mat[4][4], float *),
+ int do_pano, float xoffs, int UNUSED(do_buckets))
{
ObjectRen *obr;
HaloRen *har = NULL;
@@ -1308,7 +1364,7 @@ void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat
/* ------------------------------------------------------------------------- */
-ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay)
+ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[4][4], int lay)
{
ObjectInstanceRen *obi;
float mat3[3][3];
@@ -1363,7 +1419,7 @@ void RE_makeRenderInstances(Render *re)
re->instancetable= newlist;
}
-int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4])
+int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4])
{
float mat[4][4], vec[4];
int a, fl, flag = -1;
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index a7f6b40981d..1a24055c7f4 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -38,10 +38,6 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
-#include "BKE_global.h"
-#include "BKE_scene.h"
-
-
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_jitter.h"
@@ -49,6 +45,9 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BKE_global.h"
+#include "BKE_scene.h"
+
#include "PIL_time.h"
#include "renderpipeline.h"
@@ -812,7 +811,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
static void *do_shadow_thread(void *re_v)
{
- Render *re= (Render*)re_v;
+ Render *re = (Render *)re_v;
LampRen *lar;
do {
@@ -1302,7 +1301,7 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
ShadBuf *shb= lar->shb;
ShadSampleBuf *shsample;
float co[4], siz;
- float labda, labdao, labdax, labday, ldx, ldy;
+ float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy;
float zf, xf1, yf1, zf1, xf2, yf2, zf2;
float count, lightcount;
int x, y, z, xs1, ys1;
@@ -1336,68 +1335,68 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
if (xf1 != xf2) {
if (xf2-xf1 > 0.0f) {
- labdax= (xf1-xs1-1.0f)/(xf1-xf2);
+ lambda_x= (xf1-xs1-1.0f)/(xf1-xf2);
ldx= -shb->shadhalostep/(xf1-xf2);
dx= shb->shadhalostep;
}
else {
- labdax= (xf1-xs1)/(xf1-xf2);
+ lambda_x= (xf1-xs1)/(xf1-xf2);
ldx= shb->shadhalostep/(xf1-xf2);
dx= -shb->shadhalostep;
}
}
else {
- labdax= 1.0;
+ lambda_x= 1.0;
ldx= 0.0;
}
if (yf1 != yf2) {
if (yf2-yf1 > 0.0f) {
- labday= (yf1-ys1-1.0f)/(yf1-yf2);
+ lambda_y= (yf1-ys1-1.0f)/(yf1-yf2);
ldy= -shb->shadhalostep/(yf1-yf2);
dy= shb->shadhalostep;
}
else {
- labday= (yf1-ys1)/(yf1-yf2);
+ lambda_y= (yf1-ys1)/(yf1-yf2);
ldy= shb->shadhalostep/(yf1-yf2);
dy= -shb->shadhalostep;
}
}
else {
- labday= 1.0;
+ lambda_y= 1.0;
ldy= 0.0;
}
x= xs1;
y= ys1;
- labda= count= lightcount= 0.0;
+ lambda= count= lightcount= 0.0;
/* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */
while (1) {
- labdao= labda;
+ lambda_o= lambda;
- if (labdax==labday) {
- labdax+= ldx;
+ if (lambda_x==lambda_y) {
+ lambda_x+= ldx;
x+= dx;
- labday+= ldy;
+ lambda_y+= ldy;
y+= dy;
}
else {
- if (labdax<labday) {
- labdax+= ldx;
+ if (lambda_x<lambda_y) {
+ lambda_x+= ldx;
x+= dx;
}
else {
- labday+= ldy;
+ lambda_y+= ldy;
y+= dy;
}
}
- labda = min_ff(labdax, labday);
- if (labda==labdao || labda>=1.0f) break;
+ lambda = min_ff(lambda_x, lambda_y);
+ if (lambda==lambda_o || lambda>=1.0f) break;
- zf= zf1 + labda*(zf2-zf1);
+ zf= zf1 + lambda*(zf2-zf1);
count+= (float)shb->totbuf;
if (zf<= -1.0f) lightcount += 1.0f; /* close to the spot */
@@ -1686,21 +1685,21 @@ static int point_behind_strand(const float p[3], BSPFace *face)
return 1;
}
else {
- float labda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len;
+ float lambda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len;
- if (labda > -face->radline_end && labda < 1.0f+face->radline_end) {
+ if (lambda > -face->radline_end && lambda < 1.0f+face->radline_end) {
/* hesse for dist: */
//dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len);
- pt[0]= labda*face->rc[0]+face->vec1[0];
- pt[1]= labda*face->rc[1]+face->vec1[1];
+ pt[0]= lambda*face->rc[0]+face->vec1[0];
+ pt[1]= lambda*face->rc[1]+face->vec1[1];
rc[0]= pt[0]-p[0];
rc[1]= pt[1]-p[1];
dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]);
if (dist < face->radline) {
- float zval= face->vec1[2] + labda*face->rc[2];
+ float zval= face->vec1[2] + lambda*face->rc[2];
if (p[2] > zval)
return 1;
}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index db93a21de2d..bf0087d0292 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -151,6 +151,7 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
/* do a shade, finish up some passes, apply mist */
void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
{
+ bool compat = false;
float alpha;
/* ------ main shading loop -------- */
@@ -158,10 +159,11 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
memset(&shi->raycounter, 0, sizeof(shi->raycounter));
#endif
- if (shi->mat->nodetree && shi->mat->use_nodes) {
- ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
- }
- else {
+ if (shi->mat->nodetree && shi->mat->use_nodes)
+ compat = ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
+
+ /* also run this when node shaders fail, due to incompatible shader nodes */
+ if (compat == false) {
/* copy all relevant material vars, note, keep this synced with render_types.h */
shade_input_init_material(shi);
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 597196f464b..2d26ebe2b91 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -1884,7 +1884,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* note: shi->mode! */
if (shi->mode & MA_TRANSP && (shi->mode & (MA_ZTRANSP|MA_RAYTRANSP))) {
if (shi->spectra!=0.0f) {
- float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
+ float t = max_fff(shr->spec[0], shr->spec[1], shr->spec[2]);
t *= shi->spectra;
if (t>1.0f) t= 1.0f;
shi->alpha= (1.0f-t)*shi->alpha+t;
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 2fe8adaa1ee..8b83ca4b6c3 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -476,13 +476,13 @@ static int compare_strand_segment(const void *poin1, const void *poin2)
return 1;
}
-static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco)
+static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco)
{
projectvert(co, winmat, hoco);
hoco_to_zco(zspan, zco, hoco);
}
-static void strand_project_point(float winmat[][4], float winx, float winy, StrandPoint *spoint)
+static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint)
{
float div;
@@ -522,7 +522,7 @@ static APixstrand *addpsAstrand(ZSpan *zspan)
static void do_strand_fillac(void *handle, int x, int y, float u, float v, float z)
{
- StrandPart *spart= (StrandPart*)handle;
+ StrandPart *spart= (StrandPart *)handle;
StrandShadeCache *cache= spart->cache;
StrandSegment *sseg= spart->segment;
APixstrand *apn, *apnew;
@@ -603,7 +603,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float
}
/* width is calculated in hoco space, to ensure strands are visible */
-static int strand_test_clip(float winmat[][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy)
+static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy)
{
float hoco[4];
int clipflag= 0;
@@ -663,7 +663,7 @@ static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan *
zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac);
}
-static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
+static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
{
if (spart) {
float t= p2->t;
@@ -676,14 +676,14 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St
else {
float hoco1[4], hoco2[4];
int a, obi, index;
-
+
obi= sseg->obi - re->objectinstance;
index= sseg->strand->index;
projectvert(p1->co, winmat, hoco1);
projectvert(p2->co, winmat, hoco2);
-
+
for (a=0; a<totzspan; a++) {
#if 0
/* render both strand and single pixel wire to counter aliasing */
@@ -696,7 +696,7 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St
}
}
-static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
+static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
{
StrandPoint p;
StrandBuffer *buffer= sseg->buffer;
@@ -745,7 +745,7 @@ static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *s
return 1;
}
-void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
+void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
{
StrandBuffer *buffer= sseg->buffer;
StrandPoint *p1= &sseg->point1;
@@ -783,7 +783,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp
}
/* render call to fill in strands */
-int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
+int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
{
ObjectRen *obr;
ObjectInstanceRen *obi;
@@ -976,7 +976,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
/* *************** */
-StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset)
+StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset)
{
StrandSurface *mesh;
MFace *mface;
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 8757be740f3..a9db197ed48 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -354,7 +354,7 @@ static void ms_diffuse(Render *re, int do_test_break, float *x0, float *x, float
static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
{
const float diff = ma->vol.ms_diff * 0.001f; /* compensate for scaling for a nicer UI range */
- const int simframes = (int)(ma->vol.ms_spread * (float)MAX3(vp->res[0], vp->res[1], vp->res[2]));
+ const int simframes = (int)(ma->vol.ms_spread * (float)max_iii(vp->res[0], vp->res[1], vp->res[2]));
const int shade_type = ma->vol.shade_type;
float fac = ma->vol.ms_intensity;
@@ -493,7 +493,7 @@ typedef struct VolPrecacheQueue {
*/
static void *vol_precache_part(void *data)
{
- VolPrecacheQueue *queue = (VolPrecacheQueue*)data;
+ VolPrecacheQueue *queue = (VolPrecacheQueue *)data;
VolPrecachePart *pa;
while ((pa = BLI_thread_queue_pop(queue->work))) {
@@ -652,7 +652,7 @@ static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen
global_bounds_obi(re, obi, bbmin, bbmax);
sub_v3_v3v3(dim, bbmax, bbmin);
- div = MAX3(dim[0], dim[1], dim[2]);
+ div = max_fff(dim[0], dim[1], dim[2]);
dim[0] /= div;
dim[1] /= div;
dim[2] /= div;
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 77d6644479a..92099060bf5 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -185,7 +185,7 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
for (y = 0; y < ibuf->y; y++) {
for (x = 0; x < ibuf->x; x++) {
/* currently averaged to monchrome */
- vd->dataset[BLI_VOXEL_INDEX(x, y, z, vd->resol)] = (rf[0] + rf[1] + rf[2]) * 0.333f;
+ vd->dataset[BLI_VOXEL_INDEX(x, y, z, vd->resol)] = (rf[0] + rf[1] + rf[2]) / 3.0f;
rf += 4;
}
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index c52fb84a7f8..a0267cd65b7 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -1600,8 +1600,8 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
/**
* (clip pyramid)
- * Sets labda: flag, and parametrize the clipping of vertices in
- * viewspace coordinates. labda = -1 means no clipping, labda in [0, 1] means a clipping.
+ * Sets lambda: flag, and parametrize the clipping of vertices in
+ * viewspace coordinates. lambda = -1 means no clipping, lambda in [0, 1] means a clipping.
* Note: uses globals.
* \param v1 start coordinate s
* \param v2 target coordinate t
@@ -1611,13 +1611,13 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
* \param a index for coordinate (x, y, or z)
*/
-static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop)
+static void clippyra(float *lambda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop)
{
float da, dw, u1=0.0, u2=1.0;
float v13;
- labda[0]= -1.0;
- labda[1]= -1.0;
+ lambda[0]= -1.0;
+ lambda[1]= -1.0;
da= v2[a]-v1[a];
/* prob; we clip slightly larger, osa renders add 2 pixels on edges, should become variable? */
@@ -1641,16 +1641,16 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
if (cliptestf(da, -dw, v13, -v1[a], &u1, &u2)) {
*b3=1;
if (u2<1.0f) {
- labda[1]= u2;
+ lambda[1]= u2;
*b2=1;
}
- else labda[1]=1.0; /* u2 */
+ else lambda[1]=1.0; /* u2 */
if (u1>0.0f) {
- labda[0] = u1;
+ lambda[0] = u1;
*b2 = 1;
}
else {
- labda[0] = 0.0;
+ lambda[0] = 0.0;
}
}
}
@@ -1658,8 +1658,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
/**
* (make vertex pyramide clip)
- * Checks labda and uses this to make decision about clipping the line
- * segment from v1 to v2. labda is the factor by which the vector is
+ * Checks lambda and uses this to make decision about clipping the line
+ * segment from v1 to v2. lambda is the factor by which the vector is
* cut. ( calculate s + l * ( t - s )). The result is appended to the
* vertex list of this face.
*
@@ -1671,12 +1671,12 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
* \param clve vertex vector.
*/
-static void makevertpyra(float *vez, float *labda, float **trias, float *v1, float *v2, int *b1, int *clve)
+static void makevertpyra(float *vez, float *lambda, float **trias, float *v1, float *v2, int *b1, int *clve)
{
float l1, l2, *adr;
- l1= labda[0];
- l2= labda[1];
+ l1= lambda[0];
+ l2= lambda[1];
if (l1!= -1.0f) {
if (l1!= 0.0f) {
@@ -1708,7 +1708,7 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo
/* ------------------------------------------------------------------------- */
-void projectverto(const float v1[3], float winmat[][4], float adr[4])
+void projectverto(const float v1[3], float winmat[4][4], float adr[4])
{
/* calcs homogenic coord of vertex v1 */
float x, y, z;
@@ -1726,7 +1726,7 @@ void projectverto(const float v1[3], float winmat[][4], float adr[4])
/* ------------------------------------------------------------------------- */
-void projectvert(const float v1[3], float winmat[][4], float adr[4])
+void projectvert(const float v1[3], float winmat[4][4], float adr[4])
{
/* calcs homogenic coord of vertex v1 */
float x, y, z;
@@ -1761,7 +1761,7 @@ static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size)
cache[i].index= -1;
}
-static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[][4], float *co, float *ho)
+static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *co, float *ho)
{
int cindex= index & 255;
@@ -1790,7 +1790,7 @@ static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bound
bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy;
}
-static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho)
+static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *bounds, float *co, float *ho)
{
float vec[3];
int cindex= index & 255;
@@ -1819,7 +1819,7 @@ static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][
}
}
-void zbuf_render_project(float winmat[][4], const float co[3], float ho[4])
+void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4])
{
float vec[3];
@@ -1827,7 +1827,7 @@ void zbuf_render_project(float winmat[][4], const float co[3], float ho[4])
projectvert(vec, winmat, ho);
}
-void zbuf_make_winmat(Render *re, float winmat[][4])
+void zbuf_make_winmat(Render *re, float winmat[4][4])
{
if (re->r.mode & R_PANORAMA) {
float panomat[4][4]= MAT4_UNITY;
@@ -1847,7 +1847,7 @@ void zbuf_make_winmat(Render *re, float winmat[][4])
void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3)
{
- float *vlzp[32][3], labda[3][2];
+ float *vlzp[32][3], lambda[3][2];
float vez[400], *trias[40];
if (c1 | c2 | c3) { /* not in middle */
@@ -1887,9 +1887,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3,
else if (b==1) arg= 0;
else arg= 1;
- clippyra(labda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop);
- clippyra(labda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop);
- clippyra(labda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop);
+ clippyra(lambda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop);
+ clippyra(lambda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop);
+ clippyra(lambda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop);
if (b2==0 && b3==1) {
/* completely 'in', but we copy because of last for () loop in this section */;
@@ -1905,9 +1905,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3,
}
else {
b1=0;
- makevertpyra(vez, labda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve);
- makevertpyra(vez, labda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve);
- makevertpyra(vez, labda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve);
+ makevertpyra(vez, lambda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve);
+ makevertpyra(vez, lambda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve);
+ makevertpyra(vez, lambda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve);
/* after front clip done: now set clip flags */
if (b==0) {
@@ -2296,7 +2296,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
}
}
-void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity)
+void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, int size, float jitx, float jity)
{
ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspan;
@@ -3261,7 +3261,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample)
* Do accumulation z buffering.
*/
-static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow)
+static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow)
{
ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspans[16], *zspan; /* MAX_OSA */
@@ -3459,7 +3459,7 @@ static int zbuffer_abuf_render(RenderPart *pa, APixstr *APixbuf, APixstrand *APi
return doztra;
}
-void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2])
+void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[4][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2])
{
RenderPart pa;
int lay= -1;
@@ -4148,8 +4148,17 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
}
if (addpassflag & SCE_PASS_INDEXMA) {
ObjectRen *obr = R.objectinstance[zrow[totface-1].obi].obr;
- VlakRen *vr = obr->vlaknodes->vlak;
- Material *mat = vr->mat;
+ Material *mat = NULL;
+
+ if (zrow[totface-1].segment == -1) {
+ if (obr->vlaknodes)
+ mat = obr->vlaknodes->vlak->mat;
+ }
+ else {
+ if (obr->strandbuf)
+ mat = obr->strandbuf->ma;
+ }
+
if (mat) {
for (a= 0; a<totfullsample; a++)
add_transp_material_index(rlpp[a], od, mat);
diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript
index 68fdbec2cfa..6db0e142ac4 100644
--- a/source/blender/windowmanager/SConscript
+++ b/source/blender/windowmanager/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import os
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 8d885bf6d6f..a1437b70090 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -56,11 +56,13 @@ struct wmOperatorType;
struct wmOperator;
struct rcti;
struct PointerRNA;
+struct PropertyRNA;
struct EnumPropertyItem;
struct MenuType;
struct wmDropBox;
struct wmDrag;
struct ImBuf;
+struct ImageFormatData;
typedef struct wmJob wmJob;
@@ -68,6 +70,7 @@ typedef struct wmJob wmJob;
void WM_init_state_size_set (int stax, int stay, int sizx, int sizy);
void WM_init_state_fullscreen_set(void);
void WM_init_state_normal_set(void);
+void WM_init_native_pixels(int do_it);
void WM_init (struct bContext *C, int argc, const char **argv);
void WM_exit_ext (struct bContext *C, const short do_python);
@@ -92,21 +95,23 @@ void WM_check (struct bContext *C);
struct wmWindow *WM_window_open (struct bContext *C, struct rcti *rect);
+int WM_window_pixels_x (struct wmWindow *win);
+int WM_window_pixels_y (struct wmWindow *win);
+
/* defines for 'type' WM_window_open_temp */
#define WM_WINDOW_RENDER 0
#define WM_WINDOW_USERPREFS 1
#define WM_WINDOW_FILESEL 2
void WM_window_open_temp (struct bContext *C, struct rcti *position, int type);
+
+ /* returns true if draw method is triple buffer */
+int WM_is_draw_triple(struct wmWindow *win);
/* files */
-int WM_homefile_read_exec(struct bContext *C, struct wmOperator *op);
-int WM_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory);
-int WM_homefile_write_exec(struct bContext *C, struct wmOperator *op);
void WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports);
-int WM_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports);
void WM_autosave_init(struct wmWindowManager *wm);
/* mouse cursors */
@@ -126,6 +131,7 @@ void *WM_paint_cursor_activate(struct wmWindowManager *wm,
void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle);
void WM_cursor_warp (struct wmWindow *win, int x, int y);
+float WM_cursor_pressure (const struct wmWindow *win);
/* event map */
int WM_userdef_event_map(int kmitype);
@@ -140,12 +146,15 @@ struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers,
void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap);
-struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBase *handlers,
- int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
- void (*remove)(struct bContext *C, void *userdata), void *userdata);
+struct wmEventHandler *WM_event_add_ui_handler(
+ const struct bContext *C, ListBase *handlers,
+ int (*func)(struct bContext *C, const struct wmEvent *event, void *userdata),
+ void (*remove)(struct bContext *C, void *userdata), void *userdata);
+
void WM_event_remove_ui_handler(ListBase *handlers,
- int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
- void (*remove)(struct bContext *C, void *userdata), void *userdata, int postpone);
+ int (*func)(struct bContext *C, const struct wmEvent *event, void *userdata),
+ void (*remove)(struct bContext *C, void *userdata),
+ void *userdata, int postpone);
void WM_event_remove_area_handler(struct ListBase *handlers, void *area);
struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
@@ -162,7 +171,7 @@ int WM_modal_tweak_exit(struct wmEvent *evt, int tweak_event);
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference);
void WM_main_add_notifier(unsigned int type, void *reference);
-void wm_event_add (struct wmWindow *win, struct wmEvent *event_to_add); /* XXX only for warning */
+void wm_event_add(struct wmWindow *win, const struct wmEvent *event_to_add);
/* at maximum, every timestep seconds it triggers event_type events */
struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *win, int event_type, double timestep);
@@ -178,7 +187,7 @@ int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wm
int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
/* invoke callback, file selector "filepath" unset + exec */
int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const char imtype);
+int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
@@ -193,12 +202,13 @@ int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, con
/* operator api */
void WM_operator_free (struct wmOperator *op);
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 *idnamem, int quiet);
struct GHashIterator *WM_operatortype_iter(void);
-void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*));
-void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
-void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
+void WM_operatortype_append(void (*opfunc)(struct wmOperatorType *));
+void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
+void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
int WM_operatortype_remove(const char *idname);
struct wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag);
@@ -253,9 +263,17 @@ int WM_operator_last_properties_store(struct wmOperator *op);
/* operator as a python command (resultuing string must be freed) */
char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args);
+char *WM_prop_pystring_assign(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
void WM_operator_bl_idname(char *to, const char *from);
void WM_operator_py_idname(char *to, const char *from);
+/* *************** uilist types ******************** */
+void WM_uilisttype_init(void);
+struct uiListType *WM_uilisttype_find(const char *idname, int quiet);
+int WM_uilisttype_add(struct uiListType *ult);
+void WM_uilisttype_freelink(struct uiListType *ult);
+void WM_uilisttype_free(void);
+
/* *************** menu types ******************** */
void WM_menutype_init(void);
struct MenuType *WM_menutype_find(const char *idname, int quiet);
@@ -293,12 +311,14 @@ void WM_event_fileselect_event(struct bContext *C, void *ophandle, int eventval
void WM_event_print(struct wmEvent *event);
#endif
+void WM_operator_region_active_win_set(struct bContext *C);
+
/* drag and drop */
struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value);
void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy);
struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, struct wmEvent *event),
- void (*copy)(struct wmDrag *, struct wmDropBox *));
+ void (*copy)(struct wmDrag *, struct wmDropBox *));
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
/* Set a subwindow active in pixelspace view, with optional scissor subset */
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
index 43369154dbb..49ee759bbf2 100644
--- a/source/blender/windowmanager/WM_keymap.h
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -64,7 +64,7 @@ wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, in
int val, int modifier, int keymodifier);
int WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
-char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len);
+int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len);
wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid);
wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid);
@@ -81,6 +81,7 @@ wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, st
wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname);
wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value);
wmKeyMapItem *WM_modalkeymap_add_item_str(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value);
+wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue);
void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname);
/* Keymap Editor */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 347f46c8166..bbaa655025b 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -188,7 +188,7 @@ enum {
#define WM_UI_HANDLER_CONTINUE 0
#define WM_UI_HANDLER_BREAK 1
-typedef int (*wmUIHandlerFunc)(struct bContext *C, struct wmEvent *event, void *userdata);
+typedef int (*wmUIHandlerFunc)(struct bContext *C, const struct wmEvent *event, void *userdata);
typedef void (*wmUIHandlerRemoveFunc)(struct bContext *C, void *userdata);
/* ************** Notifiers ****************** */
@@ -407,6 +407,9 @@ typedef struct wmGesture {
/* customdata for circle is recti, (xmin, ymin) is center, xmax radius */
/* customdata for lasso is short array */
/* customdata for straight line is a recti: (xmin,ymin) is start, (xmax, ymax) is end */
+
+ /* free pointer to use for operator allocs (if set, its freed on exit)*/
+ void *userdata;
} wmGesture;
/* ************** wmEvent ************************ */
@@ -442,7 +445,10 @@ typedef struct wmEvent {
/* keymap item, set by handler (weak?) */
const char *keymap_idname;
-
+
+ /* tablet info, only use when the tablet is active */
+ struct wmTabletData *tablet_data;
+
/* custom data */
short custom; /* custom data type, stylus, 6dof, see wm_event_types.h */
short customdatafree;
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 8fe387765ce..a01f7301ec2 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -149,7 +149,88 @@ void WM_operator_stack_clear(wmWindowManager *wm)
WM_main_add_notifier(NC_WM | ND_HISTORY, NULL);
}
-/* ****************************************** */
+/**
+ * This function is needed in the case when an addon id disabled
+ * while a modal operator it defined is running.
+ */
+void WM_operator_handlers_clear(wmWindowManager *wm, wmOperatorType *ot)
+{
+ wmWindow *win;
+ for (win = wm->windows.first; win; win = win->next) {
+ ListBase *lb[2] = {&win->handlers, &win->modalhandlers};
+ wmEventHandler *handler;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ for (handler = lb[i]->first; handler; handler = handler->next) {
+ if (handler->op && handler->op->type == ot) {
+ /* don't run op->cancel because it needs the context,
+ * assume whoever unregisters the operator will cleanup */
+ handler->flag |= WM_HANDLER_DO_FREE;
+ WM_operator_free(handler->op);
+ handler->op = NULL;
+ }
+ }
+ }
+ }
+}
+
+/* ************ uiListType handling ************** */
+
+static GHash *uilisttypes_hash = NULL;
+
+uiListType *WM_uilisttype_find(const char *idname, int quiet)
+{
+ uiListType *ult;
+
+ if (idname[0]) {
+ ult = BLI_ghash_lookup(uilisttypes_hash, idname);
+ if (ult) {
+ return ult;
+ }
+ }
+
+ if (!quiet) {
+ printf("search for unknown uilisttype %s\n", idname);
+ }
+
+ return NULL;
+}
+
+int WM_uilisttype_add(uiListType *ult)
+{
+ BLI_ghash_insert(uilisttypes_hash, (void *)ult->idname, ult);
+ return 1;
+}
+
+void WM_uilisttype_freelink(uiListType *ult)
+{
+ BLI_ghash_remove(uilisttypes_hash, ult->idname, NULL, (GHashValFreeFP)MEM_freeN);
+}
+
+/* called on initialize WM_init() */
+void WM_uilisttype_init(void)
+{
+ uilisttypes_hash = BLI_ghash_str_new("uilisttypes_hash gh");
+}
+
+void WM_uilisttype_free(void)
+{
+ GHashIterator *iter = BLI_ghashIterator_new(uilisttypes_hash);
+
+ for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ uiListType *ult = BLI_ghashIterator_getValue(iter);
+ if (ult->ext.free) {
+ ult->ext.free(ult->ext.data);
+ }
+ }
+ BLI_ghashIterator_free(iter);
+
+ BLI_ghash_free(uilisttypes_hash, NULL, (GHashValFreeFP)MEM_freeN);
+ uilisttypes_hash = NULL;
+}
+
+/* ************ MenuType handling ************** */
static GHash *menutypes_hash = NULL;
diff --git a/source/blender/windowmanager/intern/wm_apple.c b/source/blender/windowmanager/intern/wm_apple.c
index a7bd43986dd..842fc353699 100644
--- a/source/blender/windowmanager/intern/wm_apple.c
+++ b/source/blender/windowmanager/intern/wm_apple.c
@@ -77,7 +77,7 @@ static int checkAppleVideoCard(void)
if ((theErr == 0) && (value != 0)) {
theErr = CGLDescribeRenderer(rend, j, kCGLRPCompliant, &value);
if ((theErr == 0) && (value != 0)) {
- /*fprintf(stderr,"make it big\n");*/
+ /*fprintf(stderr, "make it big\n");*/
CGLDestroyRendererInfo(rend);
macPrefState = 8;
return 1;
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index ebde6407a48..794bfdde114 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -188,12 +188,26 @@ void WM_cursor_grab_enable(wmWindow *win, int wrap, int hide, int bounds[4])
* It helps not to get a stuck WM when hitting a breakpoint
* */
GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
-
- if (hide) mode = GHOST_kGrabHide;
- else if (wrap) mode = GHOST_kGrabWrap;
+ float fac = GHOST_GetNativePixelSize(win->ghostwin);
+
+ /* in case pixel coords differ from window/mouse coords */
+ if (bounds) {
+ bounds[0] /= fac;
+ bounds[1] /= fac;
+ bounds[2] /= fac;
+ bounds[3] /= fac;
+ }
+
+ if (hide) {
+ mode = GHOST_kGrabHide;
+ }
+ else if (wrap) {
+ mode = GHOST_kGrabWrap;
+ }
if ((G.debug & G_DEBUG) == 0) {
- if (win && win->ghostwin) {
+ if (win->ghostwin) {
const GHOST_TabletData *tabletdata = GHOST_GetTabletData(win->ghostwin);
+
/* Note: There is no tabletdata on Windows if no tablet device is connected. */
if (!tabletdata)
GHOST_SetCursorGrab(win->ghostwin, mode, bounds, NULL);
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index a92ed65392c..6044e3fb771 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -49,6 +49,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_screen.h"
#include "GHOST_C-api.h"
@@ -431,22 +432,22 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
triple->target = GL_TEXTURE_RECTANGLE_ARB;
triple->nx = 1;
triple->ny = 1;
- triple->x[0] = win->sizex;
- triple->y[0] = win->sizey;
+ triple->x[0] = WM_window_pixels_x(win);
+ triple->y[0] = WM_window_pixels_y(win);
}
else if (GPU_non_power_of_two_support()) {
triple->target = GL_TEXTURE_2D;
triple->nx = 1;
triple->ny = 1;
- triple->x[0] = win->sizex;
- triple->y[0] = win->sizey;
+ triple->x[0] = WM_window_pixels_x(win);
+ triple->y[0] = WM_window_pixels_y(win);
}
else {
triple->target = GL_TEXTURE_2D;
triple->nx = 0;
triple->ny = 0;
- split_width(win->sizex, MAX_N_TEX, triple->x, &triple->nx);
- split_width(win->sizey, MAX_N_TEX, triple->y, &triple->ny);
+ split_width(WM_window_pixels_x(win), MAX_N_TEX, triple->x, &triple->nx);
+ split_width(WM_window_pixels_y(win), MAX_N_TEX, triple->y, &triple->ny);
}
/* generate texture names */
@@ -491,7 +492,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
return 1;
}
-static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple)
+static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
{
float halfx, halfy, ratiox, ratioy;
int x, y, sizex, sizey, offx, offy;
@@ -500,8 +501,8 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple)
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
- sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x];
- sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y];
+ sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x];
+ sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y];
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
@@ -519,7 +520,7 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple)
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
- glColor3f(1.0f, 1.0f, 1.0f);
+ glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(offx, offy);
@@ -546,8 +547,8 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
- sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x];
- sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y];
+ sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x];
+ sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y];
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
glCopyTexSubImage2D(triple->target, 0, 0, 0, offx, offy, sizex, sizey);
@@ -557,6 +558,20 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
glBindTexture(triple->target, 0);
}
+static void wm_draw_region_blend(wmWindow *win, ARegion *ar)
+{
+ float fac = ED_region_blend_factor(ar);
+
+ /* region blend always is 1, except when blend timer is running */
+ if (fac < 1.0f) {
+ wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct);
+
+ glEnable(GL_BLEND);
+ wm_triple_draw_textures(win, win->drawdata, 1.0f - fac);
+ glDisable(GL_BLEND);
+ }
+}
+
static void wm_method_draw_triple(bContext *C, wmWindow *win)
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -572,7 +587,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
wmSubWindowSet(win, screen->mainwin);
- wm_triple_draw_textures(win, win->drawdata);
+ wm_triple_draw_textures(win, win->drawdata, 1.0f);
}
else {
win->drawdata = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple");
@@ -591,11 +606,14 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->swinid && ar->do_draw) {
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
- ED_area_overdraw_flush(sa, ar);
- CTX_wm_region_set(C, NULL);
- copytex = 1;
+
+ if (ar->overlap == 0) {
+ CTX_wm_region_set(C, ar);
+ ED_region_do_draw(C, ar);
+ ED_area_overdraw_flush(sa, ar);
+ CTX_wm_region_set(C, NULL);
+ copytex = 1;
+ }
}
}
@@ -610,10 +628,27 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
wm_triple_copy_textures(win, triple);
}
+ /* draw overlapping area regions (always like popups) */
+ for (sa = screen->areabase.first; sa; sa = sa->next) {
+ CTX_wm_area_set(C, sa);
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->swinid && ar->overlap) {
+ CTX_wm_region_set(C, ar);
+ ED_region_do_draw(C, ar);
+ CTX_wm_region_set(C, NULL);
+
+ wm_draw_region_blend(win, ar);
+ }
+ }
+
+ CTX_wm_area_set(C, NULL);
+ }
+
/* after area regions so we can do area 'overlay' drawing */
ED_screen_draw(win);
- /* draw overlapping regions */
+ /* draw floating regions (menus) */
for (ar = screen->regionbase.first; ar; ar = ar->next) {
if (ar->swinid) {
CTX_wm_menu_set(C, ar);
@@ -652,9 +687,9 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
if (wm->drags.first) {
wm_drags_draw(C, win, NULL);
}
-
}
+
/****************** main update call **********************/
/* quick test to prevent changing window drawable */
@@ -734,6 +769,14 @@ static int wm_automatic_draw_method(wmWindow *win)
return win->drawmethod;
}
+int WM_is_draw_triple(wmWindow *win)
+{
+ /* function can get called before this variable is set in drawing code below */
+ if (win->drawmethod != U.wmdrawmethod)
+ win->drawmethod = U.wmdrawmethod;
+ return USER_DRAW_TRIPLE == wm_automatic_draw_method(win);
+}
+
void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar)
{
/* for draw triple gestures, paint cursors don't need region redraw */
@@ -753,11 +796,11 @@ void wm_draw_update(bContext *C)
GPU_free_unused_buffers();
for (win = wm->windows.first; win; win = win->next) {
- int state = GHOST_GetWindowState(win->ghostwin);;
+ int state = GHOST_GetWindowState(win->ghostwin);
if (state == GHOST_kWindowStateMinimized) {
/* do not update minimized windows, it gives issues on intel drivers (see [#33223])
- * anyway, it seems logical to skip update for invisile windows
+ * anyway, it seems logical to skip update for invisible windows
*/
continue;
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index c0e3b19c716..206297d2c95 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -66,6 +66,8 @@
#include "RNA_access.h"
+#include "BIF_gl.h"
+
#include "UI_interface.h"
#include "PIL_time.h"
@@ -82,16 +84,21 @@
# include "RNA_enum_types.h"
#endif
+static void update_tablet_data(wmWindow *win, wmEvent *event);
+
static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports,
short context, short poll_only);
/* ************ event management ************** */
-void wm_event_add(wmWindow *win, wmEvent *event_to_add)
+void wm_event_add(wmWindow *win, const wmEvent *event_to_add)
{
- wmEvent *event = MEM_callocN(sizeof(wmEvent), "wmEvent");
+ wmEvent *event = MEM_mallocN(sizeof(wmEvent), "wmEvent");
*event = *event_to_add;
+
+ update_tablet_data(win, event);
+
BLI_addtail(&win->queue, event);
}
@@ -106,6 +113,11 @@ void wm_event_free(wmEvent *event)
MEM_freeN(event->customdata);
}
}
+
+ if (event->tablet_data) {
+ MEM_freeN(event->tablet_data);
+ }
+
MEM_freeN(event);
}
@@ -270,7 +282,7 @@ void wm_event_do_notifiers(bContext *C)
/* XXX context in notifiers? */
CTX_wm_window_set(C, win);
- /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name+2, note->category); */
+ /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name + 2, note->category); */
ED_screen_do_listen(C, note);
for (ar = win->screen->regionbase.first; ar; ar = ar->next) {
@@ -338,7 +350,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
ARegion *region = CTX_wm_region(C);
ARegion *menu = CTX_wm_menu(C);
static int do_wheel_ui = TRUE;
- int is_wheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
+ int is_wheel = ELEM3(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN);
int retval;
/* UI code doesn't handle return values - it just always returns break.
@@ -441,6 +453,22 @@ static void wm_operator_print(bContext *C, wmOperator *op)
MEM_freeN(buf);
}
+/**
+ * Sets the active region for this space from the context.
+ *
+ * \see #BKE_area_find_region_active_win
+ */
+void WM_operator_region_active_win_set(bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ if (sa) {
+ ARegion *ar = CTX_wm_region(C);
+ if (ar && ar->regiontype == RGN_TYPE_WINDOW) {
+ sa->region_active_win = BLI_findindex(&sa->regionbase, ar);
+ }
+ }
+}
+
/* for debugging only, getting inspecting events manually is tedious */
#ifndef NDEBUG
@@ -561,10 +589,16 @@ static void wm_operator_finished(bContext *C, wmOperator *op, int repeat)
MEM_freeN(buf);
}
- if (wm_operator_register_check(wm, op->type))
+ if (wm_operator_register_check(wm, op->type)) {
+ /* take ownership of reports (in case python provided own) */
+ op->reports->flag |= RPT_FREE;
+
wm_operator_register(C, op);
- else
+ WM_operator_region_active_win_set(C);
+ }
+ else {
WM_operator_free(op);
+ }
}
}
@@ -904,6 +938,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event,
wm_operator_finished(C, op, 0);
}
else if (retval & OPERATOR_RUNNING_MODAL) {
+ /* take ownership of reports (in case python provided own) */
+ op->reports->flag |= RPT_FREE;
+
/* grab cursor during blocking modal ops (X11)
* Also check for macro
*/
@@ -1033,7 +1070,14 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA
}
if (!(ar && ar->regiontype == type) && area) {
- ARegion *ar1 = BKE_area_find_region_type(area, type);
+ ARegion *ar1;
+ if (type == RGN_TYPE_WINDOW) {
+ ar1 = BKE_area_find_region_active_win(area);
+ }
+ else {
+ ar1 = BKE_area_find_region_type(area, type);
+ }
+
if (ar1)
CTX_wm_region_set(C, ar1);
}
@@ -1132,13 +1176,6 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, short context,
if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--;
- /* keep the reports around if needed later */
- if ((retval & OPERATOR_RUNNING_MODAL) ||
- ((retval & OPERATOR_FINISHED) && wm_operator_register_check(CTX_wm_manager(C), ot)))
- {
- reports->flag |= RPT_FREE; /* let blender manage freeing */
- }
-
return retval;
}
@@ -1343,6 +1380,15 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve
}
}
}
+ else {
+ /* modal keymap checking returns handled events fine, but all hardcoded modal
+ * handling typically swallows all events (OPERATOR_RUNNING_MODAL).
+ * This bypass just disables support for double clicks in hardcoded modal handlers */
+ if (event->val == KM_DBL_CLICK) {
+ event->prevval = event->val;
+ event->val = KM_PRESS;
+ }
+ }
}
/* bad hacking event system... better restore event type for checking of KM_CLICK for example */
@@ -1355,6 +1401,8 @@ static void wm_event_modalmap_end(wmEvent *event)
event->val = event->prevval;
event->prevval = 0;
}
+ else if (event->prevval == KM_DBL_CLICK)
+ event->val = KM_DBL_CLICK;
}
@@ -1394,20 +1442,10 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
if (ot->flag & OPTYPE_UNDO)
wm->op_undo_depth--;
- /* putting back screen context, reval can pass trough after modal failures! */
- if ((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
- CTX_wm_area_set(C, area);
- CTX_wm_region_set(C, region);
- }
- else {
- /* this special cases is for areas and regions that get removed */
- CTX_wm_area_set(C, NULL);
- CTX_wm_region_set(C, NULL);
- }
-
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED))
wm_operator_reports(C, op, retval, FALSE);
+ /* important to run 'wm_operator_finished' before NULLing the context members */
if (retval & OPERATOR_FINISHED) {
wm_operator_finished(C, op, 0);
handler->op = NULL;
@@ -1417,6 +1455,17 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
handler->op = NULL;
}
+ /* putting back screen context, reval can pass trough after modal failures! */
+ if ((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+ }
+ else {
+ /* this special cases is for areas and regions that get removed */
+ CTX_wm_area_set(C, NULL);
+ CTX_wm_region_set(C, NULL);
+ }
+
/* remove modal handler, operator itself should have been canceled and freed */
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
WM_cursor_grab_disable(CTX_wm_window(C), NULL);
@@ -1640,9 +1689,9 @@ static int wm_action_not_handled(int action)
static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers)
{
#ifndef NDEBUG
- const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS)
+ const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) &&
/* comment this out to flood the console! (if you really want to test) */
- && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)
+ !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)
;
#endif
wmWindowManager *wm = CTX_wm_manager(C);
@@ -1716,6 +1765,10 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
break;
}
else {
+ if (action & WM_HANDLER_HANDLED)
+ if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS))
+ printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname);
+
#ifndef NDEBUG
if (do_debug_handler) {
printf("%s: un-handled '%s'...", __func__, kmi->idname);
@@ -2180,6 +2233,13 @@ 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));
+ }
+ }
}
/* ********** filesector handling ************ */
@@ -2632,9 +2692,12 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
wmtab->Xtilt = td->Xtilt;
wmtab->Ytilt = td->Ytilt;
- event->custom = EVT_DATA_TABLET;
- event->customdata = wmtab;
- event->customdatafree = 1;
+ event->tablet_data = wmtab;
+ // printf("%s: using tablet %.5f\n", __func__, wmtab->Pressure);
+ }
+ else {
+ event->tablet_data = NULL;
+ // printf("%s: not using tablet\n", __func__);
}
}
@@ -2689,8 +2752,10 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
if (wm->windows.first == wm->windows.last)
return NULL;
- /* top window bar... */
- if (mx < 0 || my < 0 || mx > win->sizex || my > win->sizey + 30) {
+ /* in order to use window size and mouse position (pixels), we have to use a WM function */
+
+ /* check if outside, include top window bar... */
+ if (mx < 0 || my < 0 || mx > WM_window_pixels_x(win) || my > WM_window_pixels_y(win) + 30) {
wmWindow *owin;
wmEventHandler *handler;
@@ -2701,18 +2766,21 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
return NULL;
/* to desktop space */
- mx += (int)win->posx;
- my += (int)win->posy;
+ mx += (int) (U.pixelsize * win->posx);
+ my += (int) (U.pixelsize * win->posy);
/* check other windows to see if it has mouse inside */
for (owin = wm->windows.first; owin; owin = owin->next) {
if (owin != win) {
- if (mx - owin->posx >= 0 && my - owin->posy >= 0 &&
- mx - owin->posx <= owin->sizex && my - owin->posy <= owin->sizey)
+ int posx = (int) (U.pixelsize * owin->posx);
+ int posy = (int) (U.pixelsize * owin->posy);
+
+ if (mx - posx >= 0 && owin->posy >= 0 &&
+ mx - posx <= WM_window_pixels_x(owin) && my - posy <= WM_window_pixels_y(owin))
{
- evt->x = mx - (int)owin->posx;
- evt->y = my - (int)owin->posy;
+ evt->x = mx - (int)(U.pixelsize * owin->posx);
+ evt->y = my - (int)(U.pixelsize * owin->posy);
return owin;
}
@@ -2722,6 +2790,24 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
return NULL;
}
+static bool wm_event_is_double_click(wmEvent *event, wmEvent *event_state)
+{
+ if ((event->type == event_state->prevtype) &&
+ (event_state->prevval == KM_RELEASE) &&
+ (event->val == KM_PRESS))
+ {
+ if ((ISMOUSE(event->type) == false) || ((ABS(event->x - event_state->prevclickx)) <= 2 &&
+ (ABS(event->y - event_state->prevclicky)) <= 2))
+ {
+ if ((PIL_check_seconds_timer() - event_state->prevclicktime) * 1000 < U.dbl_click_time) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
/* windows store own event queues, no bContext here */
/* time is in 1000s of seconds, from ghost */
void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int UNUSED(time), void *customdata)
@@ -2731,18 +2817,16 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
/* initialize and copy state (only mouse x y and modifiers) */
event = *evt;
-
+
switch (type) {
/* mouse move, also to inactive window (X11 does this) */
case GHOST_kEventCursorMove:
{
GHOST_TEventCursorData *cd = customdata;
wmEvent *lastevent = win->queue.last;
- int cx, cy;
- GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy);
- evt->x = cx;
- evt->y = (win->sizey - 1) - cy;
+ evt->x = cd->x;
+ evt->y = cd->y;
event.x = evt->x;
event.y = evt->y;
@@ -2755,7 +2839,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
if (lastevent && lastevent->type == MOUSEMOVE)
lastevent->type = INBETWEEN_MOUSEMOVE;
- update_tablet_data(win, &event);
wm_event_add(win, &event);
/* also add to other window if event is there, this makes overdraws disappear nicely */
@@ -2768,7 +2851,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
oevent.y = owin->eventstate->y = event.y;
oevent.type = MOUSEMOVE;
- update_tablet_data(owin, &oevent);
wm_event_add(owin, &oevent);
}
@@ -2780,6 +2862,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
switch (pd->subtype) {
case GHOST_kTrackpadEventMagnify:
event.type = MOUSEZOOM;
+ pd->deltaX = -pd->deltaX;
+ pd->deltaY = -pd->deltaY;
break;
case GHOST_kTrackpadEventRotate:
event.type = MOUSEROTATE;
@@ -2790,20 +2874,14 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
break;
}
- {
- int cx, cy;
- GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy);
- event.x = evt->x = cx;
- event.y = evt->y = (win->sizey - 1) - cy;
- }
-
+ event.x = evt->x = pd->x;
+ event.y = evt->y = pd->y;
event.val = 0;
/* Use prevx/prevy so we can calculate the delta later */
event.prevx = event.x - pd->deltaX;
event.prevy = event.y - (-pd->deltaY);
- update_tablet_data(win, &event);
wm_event_add(win, &event);
break;
}
@@ -2848,15 +2926,10 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
}
/* double click test */
- if (event.type == evt->prevtype && event.val == KM_PRESS) {
- if ((ABS(event.x - evt->prevclickx)) <= 2 &&
- (ABS(event.y - evt->prevclicky)) <= 2 &&
- ((PIL_check_seconds_timer() - evt->prevclicktime) * 1000 < U.dbl_click_time))
- {
- if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) )
- printf("%s Send double click\n", __func__);
- event.val = KM_DBL_CLICK;
- }
+ if (wm_event_is_double_click(&event, evt)) {
+ if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) )
+ printf("%s Send double click\n", __func__);
+ event.val = KM_DBL_CLICK;
}
if (event.val == KM_PRESS) {
evt->prevclicktime = PIL_check_seconds_timer();
@@ -2874,11 +2947,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
oevent.type = event.type;
oevent.val = event.val;
- update_tablet_data(owin, &oevent);
wm_event_add(owin, &oevent);
}
else {
- update_tablet_data(win, &event);
wm_event_add(win, &event);
}
@@ -2962,15 +3033,10 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
/* double click test */
/* if previous event was same type, and previous was release, and now it presses... */
- if (event.type == evt->prevtype && evt->prevval == KM_RELEASE && event.val == KM_PRESS) {
- if ((ABS(event.x - evt->prevclickx)) <= 2 &&
- (ABS(event.y - evt->prevclicky)) <= 2 &&
- ((PIL_check_seconds_timer() - evt->prevclicktime) * 1000 < U.dbl_click_time))
- {
- if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) )
- printf("%s Send double click\n", __func__);
- evt->val = event.val = KM_DBL_CLICK;
- }
+ if (wm_event_is_double_click(&event, evt)) {
+ if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) )
+ printf("%s Send double click\n", __func__);
+ evt->val = event.val = KM_DBL_CLICK;
}
/* this case happens on holding a key pressed, it should not generate
@@ -2979,7 +3045,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
event.keymodifier = 0;
/* this case happened with an external numpad, it's not really clear
- * why, but it's also impossible to map a key modifier to an unknwon
+ * why, but it's also impossible to map a key modifier to an unknown
* key, so it shouldn't harm */
if (event.keymodifier == UNKNOWNKEY)
event.keymodifier = 0;
@@ -3080,4 +3146,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
}
+#if 0
+ WM_event_print(&event);
+#endif
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 0e4af46d0fc..45cc48c254a 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -283,7 +283,9 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
/* in case UserDef was read, we re-initialize all, and do versioning */
static void wm_init_userdef(bContext *C)
{
+ /* versioning is here */
UI_init_userdef();
+
MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024);
sound_init(CTX_data_main(C));
@@ -300,6 +302,8 @@ static void wm_init_userdef(bContext *C)
/* update tempdir from user preferences */
BLI_init_temporary_dir(U.tempdir);
+
+ BKE_userdef_state();
}
@@ -388,6 +392,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* also exit screens and editors */
wm_window_match_init(C, &wmbase);
+ /* confusing this global... */
+ G.relbase_valid = 1;
retval = BKE_read_file(C, filepath, reports);
G.save_over = 1;
@@ -408,7 +414,6 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
}
if (retval != BKE_READ_FILE_FAIL) {
- G.relbase_valid = 1;
if (do_history) {
write_history();
}
@@ -485,11 +490,12 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* called on startup, (context entirely filled with NULLs) */
/* or called for 'New File' */
-/* op can be NULL */
-int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory)
+/* both startup.blend and userpref.blend are checked */
+int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory)
{
ListBase wmbase;
- char tstr[FILE_MAX];
+ char startstr[FILE_MAX];
+ char prefstr[FILE_MAX];
int success = 0;
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
@@ -498,10 +504,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
if (!from_memory) {
char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
- BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE);
+ BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE);
+ BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE);
}
else {
- tstr[0] = '\0';
+ startstr[0] = '\0';
+ prefstr[0] = '\0';
from_memory = 1;
}
}
@@ -512,14 +520,17 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
/* put aside screens to match with persistent windows later */
wm_window_match_init(C, &wmbase);
- if (!from_memory && BLI_exists(tstr)) {
- success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL);
-
+ if (!from_memory) {
+ if (BLI_exists(startstr)) {
+ success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL);
+ }
+
if (U.themes.first == NULL) {
- printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n");
+ printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr);
success = 0;
}
}
+
if (success == 0) {
success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL);
if (wmbase.first == NULL) wm_clear_default_size(C);
@@ -531,6 +542,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
#endif
}
+ /* check new prefs only after startup.blend was finished */
+ if (!from_memory && BLI_exists(prefstr)) {
+ int done = BKE_read_file_userdef(prefstr, NULL);
+ if (done) printf("Read new prefs: %s\n", prefstr);
+ }
+
/* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise
* can remove this eventually, only in a 2.53 and older, now its not written */
G.fileflags &= ~G_FILE_RELATIVE_REMAP;
@@ -584,13 +601,13 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
return TRUE;
}
-int WM_homefile_read_exec(bContext *C, wmOperator *op)
+int wm_homefile_read_exec(bContext *C, wmOperator *op)
{
int from_memory = strcmp(op->type->idname, "WM_OT_read_factory_settings") == 0;
- return WM_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return wm_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
-void WM_read_history(void)
+void wm_read_history(void)
{
char name[FILE_MAX];
LinkNode *l, *lines;
@@ -630,6 +647,10 @@ static void write_history(void)
FILE *fp;
int i;
+ /* no write history for recovered startup files */
+ if (G.main->name[0] == 0)
+ return;
+
/* will be NULL in background mode */
user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL);
if (!user_config_dir)
@@ -708,11 +729,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, err_out);
+ IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out);
}
else {
ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, FALSE, FALSE, err_out);
+ IB_rect, FALSE, R_ADDSKY, err_out);
}
if (ibuf) {
@@ -762,12 +783,11 @@ int write_crash_blend(void)
}
}
-int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *reports)
+int wm_file_write(bContext *C, const char *target, int fileflags, ReportList *reports)
{
Library *li;
int len;
char filepath[FILE_MAX];
-
int *thumb = NULL;
ImBuf *ibuf_thumb = NULL;
@@ -817,6 +837,14 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re
fileflags |= G_FILE_HISTORY; /* write file history */
+ /* first time saving */
+ /* XXX temp solution to solve bug, real fix coming (ton) */
+ if (G.main->name[0] == 0)
+ BLI_strncpy(G.main->name, filepath, sizeof(G.main->name));
+
+ /* XXX temp solution to solve bug, real fix coming (ton) */
+ G.main->recovered = 0;
+
if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) {
if (!(fileflags & G_FILE_SAVE_COPY)) {
G.relbase_valid = 1;
@@ -861,7 +889,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re
}
/* operator entry */
-int WM_homefile_write_exec(bContext *C, wmOperator *op)
+int wm_homefile_write_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
@@ -881,7 +909,7 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op)
/* force save as regular blend file */
fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
- if (BLO_write_file(CTX_data_main(C), filepath, fileflags, op->reports, NULL) == 0) {
+ if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) {
printf("fail\n");
return OPERATOR_CANCELLED;
}
@@ -893,6 +921,28 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+/* Only save the prefs block. operator entry */
+int wm_userpref_write_exec(bContext *C, wmOperator *op)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ char filepath[FILE_MAX];
+
+ /* 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);
+ printf("trying to save userpref at %s ", filepath);
+
+ if (BKE_write_file_userdef(filepath, op->reports) == 0) {
+ printf("fail\n");
+ return OPERATOR_CANCELLED;
+ }
+
+ printf("ok\n");
+
+ return OPERATOR_FINISHED;
+}
+
/************************ autosave ****************************/
void wm_autosave_location(char *filepath)
@@ -936,7 +986,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w
wmWindow *win;
wmEventHandler *handler;
char filepath[FILE_MAX];
- int fileflags;
+
Scene *scene = CTX_data_scene(C);
WM_event_remove_timer(wm, NULL, wm->autosavetimer);
@@ -960,12 +1010,17 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w
wm_autosave_location(filepath);
- /* force save as regular blend file */
- fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
-
- /* no error reporting to console */
- BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
+ if (U.uiflag & USER_GLOBALUNDO) {
+ /* fast save of last undobuffer, now with UI */
+ BKE_undo_save_file(filepath);
+ }
+ else {
+ /* save as regular blend file */
+ int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
+ /* no error reporting to console */
+ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
+ }
/* do timer after file write, just in case file write takes a long time */
wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0);
}
@@ -986,7 +1041,7 @@ void wm_autosave_delete(void)
if (BLI_exists(filename)) {
char str[FILE_MAX];
- BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend");
+ BLI_make_file_string("/", str, BLI_temporary_dir(), BLENDER_QUIT_FILE);
/* if global undo; remove tempsave, otherwise rename */
if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0);
@@ -1002,3 +1057,6 @@ void wm_autosave_read(bContext *C, ReportList *reports)
WM_file_read(C, filename, reports);
}
+
+
+
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index a80386e9860..302bf61756a 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -113,6 +113,9 @@ void WM_gesture_end(bContext *C, wmGesture *gesture)
win->tweak = NULL;
BLI_remlink(&win->gesture, gesture);
MEM_freeN(gesture->customdata);
+ if (gesture->userdata) {
+ MEM_freeN(gesture->userdata);
+ }
MEM_freeN(gesture);
}
@@ -255,7 +258,7 @@ static void draw_filled_lasso(wmGesture *gt)
if (sf_vert_first) {
const float zvec[3] = {0.0f, 0.0f, 1.0f};
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
- BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES, zvec);
+ BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_HOLES, zvec);
glEnable(GL_BLEND);
glColor4f(1.0, 1.0, 1.0, 0.05);
@@ -306,17 +309,19 @@ static void wm_gesture_draw_lasso(wmGesture *gt)
static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
{
rcti *rect = (rcti *)gt->customdata;
-
+ int winsizex = WM_window_pixels_x(win);
+ int winsizey = WM_window_pixels_y(win);
+
glEnable(GL_LINE_STIPPLE);
glColor3ub(96, 96, 96);
glLineStipple(1, 0xCCCC);
- sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin);
- sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey);
+ sdrawline(rect->xmin - winsizex, rect->ymin, rect->xmin + winsizex, rect->ymin);
+ sdrawline(rect->xmin, rect->ymin - winsizey, rect->xmin, rect->ymin + winsizey);
glColor3ub(255, 255, 255);
glLineStipple(1, 0x3333);
- sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin);
- sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey);
+ sdrawline(rect->xmin - winsizex, rect->ymin, rect->xmin + winsizex, rect->ymin);
+ sdrawline(rect->xmin, rect->ymin - winsizey, rect->xmin, rect->ymin + winsizey);
glDisable(GL_LINE_STIPPLE);
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index c9f0bbffc63..da0c6dd2a63 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -33,7 +33,7 @@
#include <string.h>
#ifdef WIN32
-# include <Windows.h>
+# include <windows.h>
#endif
#include "MEM_guardedalloc.h"
@@ -48,6 +48,7 @@
#include "DNA_windowmanager_types.h"
#include "BLI_listbase.h"
+#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -65,6 +66,7 @@
#include "BKE_node.h"
#include "BKE_report.h"
+#include "BKE_addon.h"
#include "BKE_packedFile.h"
#include "BKE_sequencer.h" /* free seq clipboard */
#include "BKE_material.h" /* clear_matcopybuf */
@@ -128,13 +130,18 @@ int wm_start_with_console = 0; /* used in creator.c */
/* only called once, for startup */
void WM_init(bContext *C, int argc, const char **argv)
{
+
if (!G.background) {
wm_ghost_init(C); /* note: it assigns C to ghost! */
wm_init_cursor_data();
}
GHOST_CreateSystemPaths();
+
+ BKE_addon_pref_type_init();
+
wm_operatortype_init();
WM_menutype_init();
+ WM_uilisttype_init();
set_free_windowmanager_cb(wm_close_and_free); /* library.c */
set_blender_test_break_cb(wm_window_testbreak); /* blender.c */
@@ -149,8 +156,8 @@ void WM_init(bContext *C, int argc, const char **argv)
BLF_lang_init();
/* get the default database, plus a wm */
- WM_homefile_read(C, NULL, G.factory_startup);
-
+ wm_homefile_read(C, NULL, G.factory_startup);
+
BLF_lang_set(NULL);
/* note: there is a bug where python needs initializing before loading the
@@ -158,7 +165,7 @@ void WM_init(bContext *C, int argc, const char **argv)
* initializing space types and other internal data.
*
* However cant redo this at the moment. Solution is to load python
- * before WM_homefile_read() or make py-drivers check if python is running.
+ * before wm_homefile_read() or make py-drivers check if python is running.
* Will try fix when the crash can be repeated. - campbell. */
#ifdef WITH_PYTHON
@@ -195,7 +202,7 @@ void WM_init(bContext *C, int argc, const char **argv)
ED_preview_init_dbase();
- WM_read_history();
+ wm_read_history();
/* allow a path of "", this is what happens when making a new file */
#if 0
@@ -211,6 +218,10 @@ void WM_init(bContext *C, int argc, const char **argv)
COM_linker_hack = COM_execute;
}
#endif
+
+ /* load last session, uses regular file reading so it has to be in end (after init py etc) */
+ if (U.uiflag2 & USER_KEEP_SESSION)
+ wm_recover_last_session(C, NULL);
}
void WM_init_splash(bContext *C)
@@ -372,6 +383,18 @@ void WM_exit_ext(bContext *C, const short do_python)
if (C && wm) {
wmWindow *win;
+ if (!G.background) {
+ if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) {
+ /* save the undo state as quit.blend */
+ char filename[FILE_MAX];
+
+ BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE);
+
+ if (BKE_undo_save_file(filename))
+ printf("Saved session recovery to '%s'\n", filename);
+ }
+ }
+
WM_jobs_kill_all(wm);
for (win = wm->windows.first; win; win = win->next) {
@@ -382,9 +405,12 @@ void WM_exit_ext(bContext *C, const short do_python)
ED_screen_exit(C, win, win->screen);
}
}
+
+ BKE_addon_pref_type_free();
wm_operatortype_free();
wm_dropbox_free();
WM_menutype_free();
+ WM_uilisttype_free();
/* all non-screen and non-space stuff editors did, like editmode */
if (C)
@@ -454,9 +480,6 @@ void WM_exit_ext(bContext *C, const short do_python)
GPU_free_unused_buffers();
GPU_extensions_exit();
- if (!G.background) {
- BKE_undo_save_quit(); /* saves quit.blend if global undo is on */
- }
BKE_reset_undo();
ED_file_exit(); /* for fsmenu */
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 3739462ac2c..92a310ac34e 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -126,10 +126,13 @@ static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
/* properties can be NULL, otherwise the arg passed is used and ownership is given to the kmi */
void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties)
{
- WM_operator_properties_free(kmi->ptr);
- MEM_freeN(kmi->ptr);
+ if (LIKELY(kmi->ptr)) {
+ WM_operator_properties_free(kmi->ptr);
+ MEM_freeN(kmi->ptr);
+
+ kmi->ptr = NULL;
+ }
- kmi->ptr = NULL;
kmi->properties = properties;
wm_keymap_item_properties_set(kmi);
@@ -734,6 +737,24 @@ wmKeyMapItem *WM_modalkeymap_add_item_str(wmKeyMap *km, int type, int val, int m
return kmi;
}
+wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue)
+{
+
+ if (km->flag & KEYMAP_MODAL) {
+ wmKeyMapItem *kmi;
+ for (kmi = km->items.first; kmi; kmi = kmi->next) {
+ if (kmi->propvalue == propvalue) {
+ return kmi;
+ }
+ }
+ }
+ else {
+ BLI_assert(!"called with non modal keymap");
+ }
+
+ return NULL;
+}
+
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
@@ -782,7 +803,7 @@ const char *WM_key_event_string(short type)
return "";
}
-char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len)
+int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len)
{
char buf[128];
@@ -815,9 +836,7 @@ char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len)
}
strcat(buf, WM_key_event_string(kmi->type));
- BLI_strncpy(str, buf, len);
-
- return str;
+ return BLI_snprintf(str, len, "%s", buf);
}
static wmKeyMapItem *wm_keymap_item_find_handlers(
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 8a0701b1063..79257479529 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -69,6 +69,7 @@
#include "BKE_library.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 */
@@ -103,6 +104,7 @@
#include "wm_draw.h"
#include "wm_event_system.h"
#include "wm_event_types.h"
+#include "wm_files.h"
#include "wm_subwindow.h"
#include "wm_window.h"
@@ -150,7 +152,7 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
opfunc(ot);
@@ -172,7 +174,7 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
opfunc(ot, userdata);
@@ -359,7 +361,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
}
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
ot->idname = idname;
ot->name = name;
@@ -389,7 +391,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *),
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
ot->flag = OPTYPE_MACRO;
ot->exec = wm_macro_exec;
@@ -559,6 +561,187 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i
return cstring;
}
+/* return NULL if no match is found */
+#if 0
+static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+
+ /* loop over all context items and do 2 checks
+ *
+ * - see if the pointer is in the context.
+ * - see if the pointers ID is in the context.
+ */
+
+ /* don't get from the context store since this is normally set only for the UI and not usable elsewhere */
+ ListBase lb = CTX_data_dir_get_ex(C, FALSE, TRUE, TRUE);
+ LinkData *link;
+
+ const char *member_found = NULL;
+ const char *member_id = NULL;
+
+ char *prop_str = NULL;
+ char *ret = NULL;
+
+
+ for (link = lb.first; link; link = link->next) {
+ const char *identifier = link->data;
+ PointerRNA ctx_item_ptr = {{0}} // CTX_data_pointer_get(C, identifier); // XXX, this isnt working
+
+ if (ctx_item_ptr.type == NULL) {
+ continue;
+ }
+
+ if (ptr->id.data == ctx_item_ptr.id.data) {
+ if ((ptr->data == ctx_item_ptr.data) &&
+ (ptr->type == ctx_item_ptr.type))
+ {
+ /* found! */
+ member_found = identifier;
+ break;
+ }
+ else if (RNA_struct_is_ID(ctx_item_ptr.type)) {
+ /* we found a reference to this ID,
+ * so fallback to it if there is no direct reference */
+ member_id = identifier;
+ }
+ }
+ }
+
+ if (member_found) {
+ prop_str = RNA_path_property_py(ptr, prop, index);
+ if (prop_str) {
+ ret = BLI_sprintfN("bpy.context.%s.%s", member_found, prop_str);
+ MEM_freeN(prop_str);
+ }
+ }
+ else if (member_id) {
+ prop_str = RNA_path_struct_property_py(ptr, prop, index);
+ if (prop_str) {
+ ret = BLI_sprintfN("bpy.context.%s.%s", member_id, prop_str);
+ MEM_freeN(prop_str);
+ }
+ }
+
+ BLI_freelistN(&lb);
+
+ return ret;
+}
+#else
+
+/* use hard coded checks for now */
+static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ const char *member_id = NULL;
+
+ char *prop_str = NULL;
+ char *ret = NULL;
+
+ if (ptr->id.data) {
+ ID *idptr = ptr->id.data;
+
+#define CTX_TEST_PTR_ID(C, member, idptr) \
+ { \
+ const char *ctx_member = member; \
+ PointerRNA ctx_item_ptr = CTX_data_pointer_get(C, ctx_member); \
+ if (ctx_item_ptr.id.data == idptr) { \
+ member_id = ctx_member; \
+ break; \
+ } \
+ } (void)0
+
+#define CTX_TEST_PTR_ID_CAST(C, member, member_full, cast, idptr) \
+ { \
+ const char *ctx_member = member; \
+ const char *ctx_member_full = member_full; \
+ PointerRNA ctx_item_ptr = CTX_data_pointer_get(C, ctx_member); \
+ if (ctx_item_ptr.id.data && cast(ctx_item_ptr.id.data) == idptr) { \
+ member_id = ctx_member_full; \
+ break; \
+ } \
+ } (void)0
+
+ switch (GS(idptr->name)) {
+ case ID_SCE:
+ {
+ CTX_TEST_PTR_ID(C, "scene", ptr->id.data);
+ break;
+ }
+ case ID_OB:
+ {
+ CTX_TEST_PTR_ID(C, "object", ptr->id.data);
+ break;
+ }
+ /* from rna_Main_objects_new */
+ case OB_DATA_SUPPORT_ID_CASE:
+ {
+#define ID_CAST_OBDATA(id_pt) (((Object *)(id_pt))->data)
+ CTX_TEST_PTR_ID_CAST(C, "object", "object.data", ID_CAST_OBDATA, ptr->id.data);
+ break;
+#undef ID_CAST_OBDATA
+ }
+ case ID_MA:
+ {
+#define ID_CAST_OBMATACT(id_pt) (give_current_material(((Object *)id_pt), ((Object *)id_pt)->actcol))
+ CTX_TEST_PTR_ID_CAST(C, "object", "object.active_material", ID_CAST_OBMATACT, ptr->id.data);
+ break;
+#undef ID_CAST_OBMATACT
+ }
+ case ID_WO:
+ {
+#define ID_CAST_SCENEWORLD(id_pt) (((Scene *)(id_pt))->world)
+ CTX_TEST_PTR_ID_CAST(C, "scene", "scene.world", ID_CAST_SCENEWORLD, ptr->id.data);
+ break;
+#undef ID_CAST_SCENEWORLD
+ }
+ case ID_SCR:
+ {
+ CTX_TEST_PTR_ID(C, "screen", ptr->id.data);
+ break;
+ }
+ }
+
+ if (member_id) {
+ prop_str = RNA_path_struct_property_py(ptr, prop, index);
+ if (prop_str) {
+ ret = BLI_sprintfN("bpy.context.%s.%s", member_id, prop_str);
+ MEM_freeN(prop_str);
+ }
+ }
+#undef CTX_TEST_PTR_ID
+#undef CTX_TEST_PTR_ID_CAST
+ }
+
+ return ret;
+}
+#endif
+
+char *WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ char *lhs, *rhs, *ret;
+
+ lhs = C ? wm_prop_pystring_from_context(C, ptr, prop, index) : NULL;
+
+ if (lhs == NULL) {
+ /* fallback to bpy.data.foo[id] if we dont find in the context */
+ lhs = RNA_path_full_property_py(ptr, prop, index);
+ }
+
+ if (!lhs) {
+ return NULL;
+ }
+
+ rhs = RNA_property_as_string(C, ptr, prop, index);
+ if (!rhs) {
+ MEM_freeN(lhs);
+ return NULL;
+ }
+
+ ret = BLI_sprintfN("%s = %s", lhs, rhs);
+ MEM_freeN(lhs);
+ MEM_freeN(rhs);
+ return ret;
+}
+
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
{
RNA_pointer_create(NULL, ot->srna, NULL, ptr);
@@ -883,14 +1066,14 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
}
}
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const char imtype)
+int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
{
PropertyRNA *prop;
char filepath[FILE_MAX];
/* 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, imtype)) {
+ if (BKE_add_image_extension(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. */
@@ -1021,8 +1204,13 @@ void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
RNA_def_int(ot->srna, "ystart", 0, INT_MIN, INT_MAX, "Y Start", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "yend", 0, INT_MIN, INT_MAX, "Y End", "", INT_MIN, INT_MAX);
- if (cursor)
- RNA_def_int(ot->srna, "cursor", cursor, 0, INT_MAX, "Cursor", "Mouse cursor style to use during the modal operator", 0, INT_MAX);
+ if (cursor) {
+ PropertyRNA *prop;
+
+ prop = RNA_def_int(ot->srna, "cursor", cursor, 0, INT_MAX,
+ "Cursor", "Mouse cursor style to use during the modal operator", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ }
}
@@ -1072,13 +1260,22 @@ static void wm_block_redo_cb(bContext *C, void *arg_op, int UNUSED(arg_event))
}
}
+static void wm_block_redo_cancel_cb(bContext *C, void *arg_op)
+{
+ wmOperator *op = arg_op;
+
+ /* if operator never got executed, free it */
+ if (op != WM_operator_last_redo(C))
+ WM_operator_free(op);
+}
+
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();
- int width = 300;
+ int width = 15 * UI_UNIT_X;
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
uiBlockClearFlag(block, UI_BLOCK_LOOP);
@@ -1158,7 +1355,7 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
uiBlockClearFlag(block, UI_BLOCK_LOOP);
- /* intentionally don't use 'UI_BLOCK_MOVEMOUSE_QUIT', some dialogs have many items
+ /* 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);
@@ -1214,7 +1411,7 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
return block;
}
-static void wm_operator_ui_popup_cancel(void *userData)
+static void wm_operator_ui_popup_cancel(struct bContext *UNUSED(C), void *userData)
{
wmOpPopUp *data = userData;
if (data->free_op && data->op) {
@@ -1262,9 +1459,9 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_
/* if we don't have global undo, we can't do undo push for automatic redo,
* so we require manual OK clicking in this popup */
if (!(U.uiflag & USER_GLOBALUNDO))
- return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y);
+ return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y);
- uiPupBlock(C, wm_block_create_redo, op);
+ uiPupBlockEx(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op);
if (do_call)
wm_block_redo_cb(C, op, 0);
@@ -1429,7 +1626,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
int i;
MenuType *mt = WM_menutype_find("USERPREF_MT_splash", TRUE);
char url[96];
- char file [FILE_MAX];
+ char file[FILE_MAX];
#ifndef WITH_HEADLESS
extern char datatoc_splash_png[];
@@ -1452,9 +1649,9 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
"%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev);
- BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.dpi);
- ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 5;
- rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 5;
+ BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi);
+ ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 0.5f * U.widget_unit;
+ rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 0.5f * U.widget_unit;
#endif /* WITH_BUILDINFO */
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
@@ -1464,16 +1661,17 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
* 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);
- but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 10, 501, 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
+ /* 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);
#ifdef WITH_BUILDINFO
- uiDefBut(block, LABEL, 0, version_buf, 494 - ver_width, 282 - 24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
- uiDefBut(block, LABEL, 0, revision_buf, 494 - rev_width, 282 - 36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, version_buf, U.pixelsize * 494 - ver_width, U.pixelsize * 258, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, revision_buf, U.pixelsize * 494 - rev_width, U.pixelsize * 246, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
#endif /* WITH_BUILDINFO */
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style);
+ layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, style);
uiBlockSetEmboss(block, UI_EMBOSS);
/* show the splash menu (containing interaction presets), using python */
@@ -1492,18 +1690,26 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
split = uiLayoutSplit(layout, 0.0f, FALSE);
col = uiLayoutColumn(split, FALSE);
- uiItemL(col, "Links", ICON_NONE);
- uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/blenderorg/blender-foundation/donation-payment");
- uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/credits");
- uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-265");
- uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.6/Manual");
+ uiItemL(col, IFACE_("Links"), ICON_NONE);
+ uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url",
+ "http://www.blender.org/blenderorg/blender-foundation/donation-payment");
+ uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url",
+ "http://www.blender.org/development/credits");
+ uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url",
+ "http://www.blender.org/development/release-logs/blender-266");
+ uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url",
+ "http://wiki.blender.org/index.php/Doc:2.6/Manual");
uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
- uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/community/user-community");
+ uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url",
+ "http://www.blender.org/community/user-community");
if (strcmp(STRINGIFY(BLENDER_VERSION_CYCLE), "release") == 0) {
- BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d" STRINGIFY(BLENDER_VERSION_CHAR) "_release", BLENDER_VERSION / 100, BLENDER_VERSION % 100);
+ BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d"
+ STRINGIFY(BLENDER_VERSION_CHAR) "_release",
+ BLENDER_VERSION / 100, BLENDER_VERSION % 100);
}
else {
- BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d_%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
+ BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d_%d",
+ BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
}
uiItemStringO(col, IFACE_("Python API Reference"), ICON_URL, "WM_OT_url_open", "url", url);
uiItemL(col, "", ICON_NONE);
@@ -1675,12 +1881,23 @@ static void WM_OT_window_duplicate(wmOperatorType *ot)
static void WM_OT_save_homefile(wmOperatorType *ot)
{
- ot->name = "Save User Settings";
+ ot->name = "Save Startup File";
ot->idname = "WM_OT_save_homefile";
- ot->description = "Make the current file the default .blend file";
+ ot->description = "Make the current file the default .blend file, includes preferences";
ot->invoke = WM_operator_confirm;
- ot->exec = WM_homefile_write_exec;
+ ot->exec = wm_homefile_write_exec;
+ ot->poll = WM_operator_winactive;
+}
+
+static void WM_OT_save_userpref(wmOperatorType *ot)
+{
+ ot->name = "Save User Settings";
+ ot->idname = "WM_OT_save_userpref";
+ ot->description = "Save user preferences separately, overrides startup file preferences";
+
+ ot->invoke = WM_operator_confirm;
+ ot->exec = wm_userpref_write_exec;
ot->poll = WM_operator_winactive;
}
@@ -1691,7 +1908,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot)
ot->description = "Open the default file (doesn't save the current file)";
ot->invoke = WM_operator_confirm;
- ot->exec = WM_homefile_read_exec;
+ ot->exec = wm_homefile_read_exec;
/* ommit poll to run in background mode */
}
@@ -1702,7 +1919,7 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot)
ot->description = "Load default file and user preferences";
ot->invoke = WM_operator_confirm;
- ot->exec = WM_homefile_read_exec;
+ ot->exec = wm_homefile_read_exec;
/* ommit poll to run in background mode */
}
@@ -1803,7 +2020,7 @@ static int wm_link_append_poll(bContext *C)
if (WM_operator_winactive(C)) {
/* linking changes active object which is pretty useful in general,
* but which totally confuses edit mode (i.e. it becoming not so obvious
- * to leave from edit mode and inwalid tools in toolbar might be displayed)
+ * to leave from edit mode and invalid tools in toolbar might be displayed)
* so disable link/append when in edit mode (sergey) */
if (CTX_data_edit_object(C))
return 0;
@@ -1957,8 +2174,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
/* recreate dependency graph to include new objects */
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_scene_relations_rebuild(bmain, scene);
BLO_blendhandle_close(bh);
@@ -2003,21 +2219,38 @@ static void WM_OT_link_append(wmOperatorType *ot)
/* *************** recover last session **************** */
-static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
+void wm_recover_last_session(bContext *C, ReportList *reports)
{
char filename[FILE_MAX];
+
+ BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE);
+ /* if reports==NULL, it's called directly without operator, we add a quick check here */
+ if (reports || BLI_exists(filename)) {
+ G.fileflags |= G_FILE_RECOVER;
+
+ /* XXX wm in context is not set correctly after WM_file_read -> crash */
+ /* do it before for now, but is this correct with multiple windows? */
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ /* load file */
+ WM_file_read(C, filename, reports);
+
+ G.fileflags &= ~G_FILE_RECOVER;
+
+ /* XXX bad global... fixme */
+ if (G.main->name[0])
+ G.file_loaded = 1; /* prevents splash to show */
+ else {
+ G.relbase_valid = 0;
+ G.save_over = 0; /* start with save preference untitled.blend */
+ }
- G.fileflags |= G_FILE_RECOVER;
-
- /* XXX wm in context is not set correctly after WM_file_read -> crash */
- /* do it before for now, but is this correct with multiple windows? */
- WM_event_add_notifier(C, NC_WINDOW, NULL);
-
- /* load file */
- BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend");
- WM_file_read(C, filename, op->reports);
+ }
+}
- G.fileflags &= ~G_FILE_RECOVER;
+static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
+{
+ wm_recover_last_session(C, op->reports);
return OPERATOR_FINISHED;
}
@@ -2025,7 +2258,7 @@ static void WM_OT_recover_last_session(wmOperatorType *ot)
{
ot->name = "Recover Last Session";
ot->idname = "WM_OT_recover_last_session";
- ot->description = "Open the last closed file (\"quit.blend\")";
+ ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")";
ot->exec = wm_recover_last_session_exec;
ot->poll = WM_operator_winactive;
@@ -2049,7 +2282,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
WM_file_read(C, path, op->reports);
G.fileflags &= ~G_FILE_RECOVER;
-
+
return OPERATOR_FINISHED;
}
@@ -2139,7 +2372,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
untitled(path);
}
- fileflags = G.fileflags;
+ fileflags = G.fileflags & ~G_FILE_USERPREFS;
/* set compression flag */
BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "compress"),
@@ -2158,7 +2391,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
G_FILE_MESH_COMPAT);
#endif
- if (WM_file_write(C, path, fileflags, op->reports) != 0)
+ if (wm_file_write(C, path, fileflags, op->reports) != 0)
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL);
@@ -2307,9 +2540,8 @@ static int wm_console_toggle_op(bContext *UNUSED(C), wmOperator *UNUSED(op))
static void WM_OT_console_toggle(wmOperatorType *ot)
{
- /* XXX Have to mark these for xgettext, as under linux they do not exists...
- * And even worth, have to give the context as text, as xgettext doesn't expand macros. :( */
- ot->name = CTX_N_("Operator" /* BLF_I18NCONTEXT_OPERATOR_DEFAULT */, "Toggle System Console");
+ /* XXX Have to mark these for xgettext, as under linux they do not exists... */
+ ot->name = CTX_N_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Toggle System Console");
ot->idname = "WM_OT_console_toggle";
ot->description = N_("Toggle System Console");
@@ -3045,6 +3277,7 @@ static void radial_control_set_initial_mouse(RadialControl *rc, wmEvent *event)
rc->initial_mouse[1] = event->y;
switch (rc->subtype) {
+ case PROP_NONE:
case PROP_DISTANCE:
d[0] = rc->initial_value;
break;
@@ -3144,6 +3377,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
float zoom[2], col[3] = {1, 1, 1};
switch (rc->subtype) {
+ case PROP_NONE:
case PROP_DISTANCE:
r1 = rc->current_value;
r2 = rc->initial_value;
@@ -3165,6 +3399,11 @@ 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;
@@ -3382,8 +3621,8 @@ static int radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* get subtype of property */
rc->subtype = RNA_property_subtype(rc->prop);
- if (!ELEM3(rc->subtype, PROP_DISTANCE, PROP_FACTOR, PROP_ANGLE)) {
- BKE_report(op->reports, RPT_ERROR, "Property must be a distance, a factor, or an angle");
+ if (!ELEM4(rc->subtype, PROP_NONE, PROP_DISTANCE, PROP_FACTOR, PROP_ANGLE)) {
+ BKE_report(op->reports, RPT_ERROR, "Property must be a none, distance, a factor, or an angle");
MEM_freeN(rc);
return OPERATOR_CANCELLED;
}
@@ -3467,6 +3706,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
/* calculate new value and apply snapping */
switch (rc->subtype) {
+ case PROP_NONE:
case PROP_DISTANCE:
new_value = dist;
if (snap) new_value = ((int)new_value + 5) / 10 * 10;
@@ -3743,7 +3983,7 @@ static int wm_ndof_sensitivity_exec(bContext *UNUSED(C), wmOperator *op)
static void WM_OT_ndof_sensitivity_change(wmOperatorType *ot)
{
- ot->name = "Change NDOF sensitivity";
+ ot->name = "Change NDOF Sensitivity";
ot->idname = "WM_OT_ndof_sensitivity_change";
ot->description = "Change NDOF sensitivity";
@@ -3787,6 +4027,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_read_homefile);
WM_operatortype_append(WM_OT_read_factory_settings);
WM_operatortype_append(WM_OT_save_homefile);
+ WM_operatortype_append(WM_OT_save_userpref);
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
WM_operatortype_append(WM_OT_quit_blender);
WM_operatortype_append(WM_OT_open_mainfile);
@@ -3891,6 +4132,7 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf)
/* assign map to operators */
WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line");
+ WM_modalkeymap_assign(keymap, "PAINT_OT_weight_gradient");
}
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 8b387196da7..fd44f4a7169 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -689,7 +689,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
break;
}
case GHOST_kEventWindowActivate:
- case GHOST_kEventWindowDeactivate: {
+ case GHOST_kEventWindowDeactivate:
+ {
g_WS.qual &= ~WS_QUAL_MOUSE;
break;
}
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 8533494ae96..20406ac463d 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -131,7 +131,7 @@ void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y)
}
}
-void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4])
+void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4])
{
wmSubWindow *swin = swin_from_swinid(win, swinid);
@@ -217,10 +217,10 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
* fixed it). - zr (2001!)
*/
- if (swin->winrct.xmax > win->sizex)
- swin->winrct.xmax = win->sizex;
- if (swin->winrct.ymax > win->sizey)
- swin->winrct.ymax = win->sizey;
+ if (swin->winrct.xmax > WM_window_pixels_x(win))
+ swin->winrct.xmax = WM_window_pixels_x(win);
+ if (swin->winrct.ymax > WM_window_pixels_y(win))
+ swin->winrct.ymax = WM_window_pixels_y(win);
/* extra service */
wmSubWindowSet(win, swinid);
@@ -255,10 +255,10 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
width = BLI_rcti_size_x(&_curswin->winrct) + 1;
height = BLI_rcti_size_y(&_curswin->winrct) + 1;
glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
-
+
if (srct) {
- width = BLI_rcti_size_x(srct) + 1;
- height = BLI_rcti_size_y(srct) + 1;
+ int width = BLI_rcti_size_x(srct) + 1; /* only here */
+ int height = BLI_rcti_size_y(srct) + 1;
glScissor(srct->xmin, srct->ymin, width, height);
}
else
@@ -266,11 +266,10 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
wmOrtho2(-GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS);
glLoadIdentity();
-
+
glFlush();
}
-
/* enable the WM versions of opengl calls */
void wmSubWindowSet(wmWindow *win, int swinid)
{
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 09f7e1692d9..a1ab0de49cf 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -43,6 +43,7 @@
#include "GHOST_C-api.h"
+#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -75,6 +76,11 @@
#include "UI_interface.h"
+/* for assert */
+#ifndef NDEBUG
+# include "BLI_threads.h"
+#endif
+
/* the global to talk to ghost */
static GHOST_SystemHandle g_system = NULL;
@@ -91,7 +97,9 @@ static struct WMInitStruct {
int windowstate;
WinOverrideFlag override_flag;
-} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0};
+
+ int native_pixels;
+} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0, 1};
/* ******** win open & close ************ */
@@ -107,6 +115,17 @@ void wm_get_screensize(int *width_r, int *height_r)
*height_r = uiheight;
}
+/* size of all screens, useful since the mouse is bound by this */
+void wm_get_screensize_all(int *width_r, int *height_r)
+{
+ unsigned int uiwidth;
+ unsigned int uiheight;
+
+ GHOST_GetAllDisplayDimensions(g_system, &uiwidth, &uiheight);
+ *width_r = uiwidth;
+ *height_r = uiheight;
+}
+
/* keeps offset and size within monitor bounds */
/* XXX solve dual screen... */
static void wm_window_check_position(rcti *rect)
@@ -241,7 +260,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
win->screen->do_refresh = TRUE;
win->screen->do_draw = TRUE;
- win->drawmethod = -1;
+ win->drawmethod = U.wmdrawmethod;
win->drawdata = NULL;
return win;
@@ -251,51 +270,50 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmWindow *tmpwin;
- bScreen *screen = win->screen;
+ int do_exit = 0;
+
+ /* first check if we have to quit (there are non-temp remaining windows) */
+ for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
+ if (tmpwin == win)
+ continue;
+ if (tmpwin->screen->temp == 0)
+ break;
+ }
+
+ if (tmpwin == NULL)
+ do_exit = 1;
- /* first check if we have any non-temp remaining windows */
if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) {
- if (wm->windows.first) {
- for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
- if (tmpwin == win)
- continue;
- if (tmpwin->screen->temp == 0)
- break;
- }
- if (tmpwin == NULL) {
- if (!GHOST_confirmQuit(win->ghostwin))
- return;
- }
+ if (do_exit) {
+ if (!GHOST_confirmQuit(win->ghostwin))
+ return;
}
}
- BLI_remlink(&wm->windows, win);
-
- wm_draw_window_clear(win);
- CTX_wm_window_set(C, win); /* needed by handlers */
- WM_event_remove_handlers(C, &win->handlers);
- WM_event_remove_handlers(C, &win->modalhandlers);
- ED_screen_exit(C, win, win->screen);
-
- wm_window_free(C, wm, win);
-
- /* if temp screen, delete it after window free (it stops jobs that can access it) */
- if (screen->temp) {
- Main *bmain = CTX_data_main(C);
- BKE_libblock_free(&bmain->screen, screen);
+ /* let WM_exit do all freeing, for correct quit.blend save */
+ if (do_exit) {
+ WM_exit(C);
}
+ else {
+ bScreen *screen = win->screen;
+
+ BLI_remlink(&wm->windows, win);
+
+ wm_draw_window_clear(win);
+
+ CTX_wm_window_set(C, win); /* needed by handlers */
+ WM_event_remove_handlers(C, &win->handlers);
+ WM_event_remove_handlers(C, &win->modalhandlers);
+ ED_screen_exit(C, win, win->screen);
+
+ wm_window_free(C, wm, win);
- /* check remaining windows */
- if (wm->windows.first) {
- for (win = wm->windows.first; win; win = win->next)
- if (win->screen->temp == 0)
- break;
- /* in this case we close all */
- if (win == NULL)
- WM_exit(C);
- }
- else
- WM_exit(C);
+ /* if temp screen, delete it after window free (it stops jobs that can access it) */
+ if (screen->temp) {
+ Main *bmain = CTX_data_main(C);
+ BKE_libblock_free(&bmain->screen, screen);
+ }
+ }
}
void wm_window_title(wmWindowManager *wm, wmWindow *win)
@@ -308,8 +326,9 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
/* this is set to 1 if you don't have startup.blend open */
if (G.save_over && G.main->name[0]) {
- char str[sizeof(G.main->name) + 12];
- BLI_snprintf(str, sizeof(str), "Blender%s [%s]", wm->file_saved ? "" : "*", G.main->name);
+ char str[sizeof(G.main->name) + 24];
+ BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name,
+ G.main->recovered ? " (Recovered)" : "");
GHOST_SetTitle(win->ghostwin, str);
}
else
@@ -344,8 +363,6 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
wm_get_screensize(&scr_w, &scr_h);
posy = (scr_h - win->posy - win->sizey);
- /* Disable AA for now, as GL_SELECT (used for border, lasso, ... select)
- * doesn't work well when AA is initialized, even if not used. */
ghostwin = GHOST_CreateWindow(g_system, title,
win->posx, posy, win->sizex, win->sizey,
(GHOST_TWindowState)win->windowstate,
@@ -354,6 +371,8 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
multisamples /* AA */);
if (ghostwin) {
+ GHOST_RectangleHandle bounds;
+
/* needed so we can detect the graphics card below */
GPU_extensions_init();
@@ -372,7 +391,19 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
glClear(GL_COLOR_BUFFER_BIT);
}
+
+ /* displays with larger native pixels, like Macbook. Used to scale dpi with */
+ /* needed here, because it's used before it reads userdef */
+ U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
+ BKE_userdef_state();
+
+ /* store actual window size in blender window */
+ bounds = GHOST_GetClientBounds(win->ghostwin);
+ win->sizex = GHOST_GetWidthRectangle(bounds);
+ win->sizey = GHOST_GetHeightRectangle(bounds);
+ GHOST_DisposeRectangle(bounds);
+
wm_window_swap_buffers(win);
//GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified);
@@ -406,10 +437,19 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
wm_set_apple_prefsize(wm_init_state.size_x, wm_init_state.size_y);
}
#else
+ /* note!, this isnt quite correct, active screen maybe offset 1000s if PX,
+ * we'd need a wm_get_screensize like function that gives offset,
+ * in practice the window manager will likely move to the correct monitor */
wm_init_state.start_x = 0;
wm_init_state.start_y = 0;
-
#endif
+
+#if !defined(__APPLE__) && !defined(WIN32) /* X11 */
+ /* X11, start maximized but use default same size */
+ wm_init_state.size_x = min_ii(wm_init_state.size_x, WM_WIN_INIT_SIZE_X);
+ wm_init_state.size_y = min_ii(wm_init_state.size_y, WM_WIN_INIT_SIZE_Y);
+#endif
+
}
for (win = wm->windows.first; win; win = win->next) {
@@ -420,8 +460,18 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
win->sizex = wm_init_state.size_x;
win->sizey = wm_init_state.size_y;
- /* we can't properly resize a maximized window */
+#if !defined(__APPLE__) && !defined(WIN32) /* X11 */
+ if (wm_init_state.override_flag & WIN_OVERRIDE_GEOM) {
+ /* we can't properly resize a maximized window */
+ win->windowstate = GHOST_kWindowStateNormal;
+ }
+ else {
+ /* loading without userpref, default to maximized */
+ win->windowstate = GHOST_kWindowStateMaximized;
+ }
+#else
win->windowstate = GHOST_kWindowStateNormal;
+#endif
wm_init_state.override_flag &= ~WIN_OVERRIDE_GEOM;
}
@@ -468,7 +518,7 @@ wmWindow *WM_window_open(bContext *C, rcti *rect)
win->sizex = BLI_rcti_size_x(rect);
win->sizey = BLI_rcti_size_y(rect);
- win->drawmethod = -1;
+ win->drawmethod = U.wmdrawmethod;
win->drawdata = NULL;
WM_check(C);
@@ -530,6 +580,7 @@ void WM_window_open_temp(bContext *C, rcti *position, int type)
}
ED_screen_set(C, win->screen);
+ ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */
if (sa->spacetype == SPACE_IMAGE)
GHOST_SetTitle(win->ghostwin, IFACE_("Blender Render"));
@@ -578,6 +629,24 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
/* ************ events *************** */
+static void wm_convert_cursor_position(wmWindow *win, int *x, int *y)
+{
+ float fac = GHOST_GetNativePixelSize(win->ghostwin);
+
+ GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
+ *x *= fac;
+
+ *y = (win->sizey - 1) - *y;
+ *y *= fac;
+}
+
+
+void wm_get_cursor_position(wmWindow *win, int *x, int *y)
+{
+ GHOST_GetCursorPosition(g_system, x, y);
+ wm_convert_cursor_position(win, x, y);
+}
+
typedef enum {
SHIFT = 's',
CONTROL = 'c',
@@ -629,10 +698,15 @@ void wm_window_make_drawable(bContext *C, wmWindow *win)
printf("%s: set drawable %d\n", __func__, win->winid);
}
GHOST_ActivateWindowDrawingContext(win->ghostwin);
+
+ /* this can change per window */
+ U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
+ BKE_userdef_state();
}
}
/* called by ghost, here we handle events for windows themselves or send to event system */
+/* mouse coordinate converversion happens here */
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
{
bContext *C = C_void_ptr;
@@ -668,12 +742,20 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
case GHOST_kEventWindowDeactivate:
wm_event_add_ghostevent(wm, win, type, time, data);
win->active = 0; /* XXX */
+
+ /* clear modifiers for inactive windows */
+ win->eventstate->alt = 0;
+ win->eventstate->ctrl = 0;
+ win->eventstate->shift = 0;
+ win->eventstate->oskey = 0;
+ win->eventstate->keymodifier = 0;
+
break;
case GHOST_kEventWindowActivate:
{
GHOST_TEventKeyData kdata;
wmEvent event;
- int cx, cy, wx, wy;
+ int wx, wy;
wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
@@ -681,6 +763,9 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
// window_handle(win, INPUTCHANGE, win->active);
/* bad ghost support for modifier keys... so on activate we set the modifiers again */
+
+ /* TODO: This is not correct since a modifier may be held when a window is activated...
+ * better solve this at ghost level. attempted fix r54450 but it caused bug [#34255] */
kdata.ascii = '\0';
kdata.utf8_buf[0] = '\0';
if (win->eventstate->shift && !query_qual(SHIFT)) {
@@ -703,11 +788,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
win->eventstate->keymodifier = 0;
/* entering window, update mouse pos. but no event */
- GHOST_GetCursorPosition(g_system, &wx, &wy);
-
- GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
- win->eventstate->x = cx;
- win->eventstate->y = (win->sizey - 1) - cy;
+ wm_get_cursor_position(win, &wx, &wy);
+
+ win->eventstate->x = wx;
+ win->eventstate->y = wy;
win->addmousemove = 1; /* enables highlighted buttons */
@@ -770,7 +854,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
GHOST_DisposeRectangle(client_rect);
- wm_get_screensize(&scr_w, &scr_h);
+ wm_get_screensize_all(&scr_w, &scr_h);
sizex = r - l;
sizey = b - t;
posx = l;
@@ -857,14 +941,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
{
wmEvent event;
GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
- int cx, cy, wx, wy;
+ int wx, wy;
/* entering window, update mouse pos */
- GHOST_GetCursorPosition(g_system, &wx, &wy);
-
- GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
- win->eventstate->x = cx;
- win->eventstate->y = (win->sizey - 1) - cy;
+ wm_get_cursor_position(win, &wx, &wy);
+ win->eventstate->x = wx;
+ win->eventstate->y = wy;
event = *(win->eventstate); /* copy last state, like mouse coords */
@@ -907,11 +989,33 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
}
}
+ break;
+ }
+ case GHOST_kEventNativeResolutionChange:
+ // printf("change, pixel size %f\n", GHOST_GetNativePixelSize(win->ghostwin));
+
+ U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
+ BKE_userdef_state();
+ WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
+
+ break;
+ case GHOST_kEventTrackpad:
+ {
+ GHOST_TEventTrackpadData *pd = data;
+ wm_convert_cursor_position(win, &pd->x, &pd->y);
+ wm_event_add_ghostevent(wm, win, type, time, data);
+ break;
+ }
+ case GHOST_kEventCursorMove:
+ {
+ GHOST_TEventCursorData *cd = data;
+ wm_convert_cursor_position(win, &cd->x, &cd->y);
+ wm_event_add_ghostevent(wm, win, type, time, data);
break;
}
-
default:
wm_event_add_ghostevent(wm, win, type, time, data);
break;
@@ -971,8 +1075,12 @@ static int wm_window_timer(const bContext *C)
void wm_window_process_events(const bContext *C)
{
- int hasevent = GHOST_ProcessEvents(g_system, 0); /* 0 is no wait */
-
+ int hasevent;
+
+ BLI_assert(BLI_thread_is_main());
+
+ hasevent = GHOST_ProcessEvents(g_system, 0); /* 0 is no wait */
+
if (hasevent)
GHOST_DispatchEvents(g_system);
@@ -994,7 +1102,9 @@ void wm_window_testbreak(void)
{
static double ltime = 0;
double curtime = PIL_check_seconds_timer();
-
+
+ BLI_assert(BLI_thread_is_main());
+
/* only check for breaks every 50 milliseconds
* if we get called more often.
*/
@@ -1017,6 +1127,10 @@ void wm_ghost_init(bContext *C)
g_system = GHOST_CreateSystem();
GHOST_AddEventConsumer(g_system, consumer);
+
+ if (wm_init_state.native_pixels) {
+ GHOST_UseNativePixels();
+ }
}
}
@@ -1068,6 +1182,8 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *
if (wt == timer)
break;
if (wt) {
+ wmWindow *win;
+
if (wm->reports.reporttimer == wt)
wm->reports.reporttimer = NULL;
@@ -1075,6 +1191,17 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *
if (wt->customdata)
MEM_freeN(wt->customdata);
MEM_freeN(wt);
+
+ /* there might be events in queue with this timer as customdata */
+ for (win = wm->windows.first; win; win = win->next) {
+ wmEvent *event;
+ for (event = win->queue.first; event; event = event->next) {
+ if (event->customdata == wt) {
+ event->customdata = NULL;
+ event->type = EVENT_NONE; /* timer users customdata, dont want NULL == NULL */
+ }
+ }
+ }
}
}
@@ -1158,23 +1285,6 @@ void wm_window_get_position(wmWindow *win, int *posx_r, int *posy_r)
*posy_r = win->posy;
}
-void wm_window_get_size(wmWindow *win, int *width_r, int *height_r)
-{
- *width_r = win->sizex;
- *height_r = win->sizey;
-}
-
-/* exceptional case: - splash is called before events are processed
- * this means we don't actually know the window size so get this from GHOST */
-void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r)
-{
- GHOST_RectangleHandle bounds = GHOST_GetClientBounds(win->ghostwin);
- *width_r = GHOST_GetWidthRectangle(bounds);
- *height_r = GHOST_GetHeightRectangle(bounds);
-
- GHOST_DisposeRectangle(bounds);
-}
-
void wm_window_set_size(wmWindow *win, int width, int height)
{
GHOST_SetClientSize(win->ghostwin, width, height);
@@ -1202,12 +1312,6 @@ void wm_window_swap_buffers(wmWindow *win)
#endif
}
-void wm_get_cursor_position(wmWindow *win, int *x, int *y)
-{
- GHOST_GetCursorPosition(g_system, x, y);
- GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
- *y = (win->sizey - 1) - *y;
-}
/* ******************* exported api ***************** */
@@ -1217,8 +1321,8 @@ void WM_init_state_size_set(int stax, int stay, int sizx, int sizy)
{
wm_init_state.start_x = stax; /* left hand pos */
wm_init_state.start_y = stay; /* bottom pos */
- wm_init_state.size_x = sizx;
- wm_init_state.size_y = sizy;
+ wm_init_state.size_x = sizx < 640 ? 640 : sizx;
+ wm_init_state.size_y = sizy < 480 ? 480 : sizy;
wm_init_state.override_flag |= WIN_OVERRIDE_GEOM;
}
@@ -1235,12 +1339,20 @@ void WM_init_state_normal_set(void)
wm_init_state.override_flag |= WIN_OVERRIDE_WINSTATE;
}
+void WM_init_native_pixels(int do_it)
+{
+ wm_init_state.native_pixels = do_it;
+}
+
/* This function requires access to the GHOST_SystemHandle (g_system) */
void WM_cursor_warp(wmWindow *win, int x, int y)
{
if (win && win->ghostwin) {
+ float f = GHOST_GetNativePixelSize(win->ghostwin);
int oldx = x, oldy = y;
+ x = x / f;
+ y = y / f;
y = win->sizey - y - 1;
GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y);
@@ -1251,3 +1363,34 @@ void WM_cursor_warp(wmWindow *win, int x, int y)
}
}
+/**
+ * Get the cursor pressure, in most cases you'll want to use wmTabletData from the event
+ */
+float WM_cursor_pressure(const struct wmWindow *win)
+{
+ const GHOST_TabletData *td = GHOST_GetTabletData(win->ghostwin);
+ /* if there's tablet data from an active tablet device then add it */
+ if ((td != NULL) && td->Active != GHOST_kTabletModeNone) {
+ return td->Pressure;
+ }
+ else {
+ return -1.0f;
+ }
+}
+
+/* support for native pixel size */
+/* mac retina opens window in size X, but it has up to 2 x more pixels */
+int WM_window_pixels_x(wmWindow *win)
+{
+ float f = GHOST_GetNativePixelSize(win->ghostwin);
+
+ return (int)(f * (float)win->sizex);
+}
+
+int WM_window_pixels_y(wmWindow *win)
+{
+ float f = GHOST_GetNativePixelSize(win->ghostwin);
+
+ return (int)(f * (float)win->sizey);
+
+}
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 2d0dd2ef911..d12e1d47fa0 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -45,7 +45,8 @@ struct ARegion;
typedef struct wmEventHandler {
struct wmEventHandler *next, *prev;
- int type, flag; /* type default=0, rest is custom */
+ int type; /* WM_HANDLER_DEFAULT, ... */
+ int flag; /* WM_HANDLER_BLOCKING, ... */
/* keymap handler */
wmKeyMap *keymap; /* pointer to builtin/custom keymaps */
@@ -72,21 +73,17 @@ typedef struct wmEventHandler {
} wmEventHandler;
-
-/* handler flag */
- /* after this handler all others are ignored */
-#define WM_HANDLER_BLOCKING 1
- /* handler tagged to be freed in wm_handlers_do() */
-#define WM_HANDLER_DO_FREE 2
-
-
-
/* custom types for handlers, for signalling, freeing */
enum {
WM_HANDLER_DEFAULT,
WM_HANDLER_FILESELECT
};
+/* handler flag */
+enum {
+ WM_HANDLER_BLOCKING = 1, /* after this handler all others are ignored */
+ WM_HANDLER_DO_FREE = 2 /* handler tagged to be freed in wm_handlers_do() */
+};
/* wm_event_system.c */
void wm_event_free_all (wmWindow *win);
@@ -107,5 +104,8 @@ void wm_dropbox_free(void);
void wm_drags_check_ops(bContext *C, wmEvent *event);
void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect);
+/* wm_operators.c */
+void wm_recover_last_session(bContext *C, ReportList *reports);
+
#endif /* __WM_EVENT_SYSTEM_H__ */
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 4d3d6ef89d9..bc7e7efdcfd 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -39,11 +39,10 @@
#define __WM_EVENT_TYPES_H__
/* customdata type */
-#define EVT_DATA_TABLET 1
-#define EVT_DATA_GESTURE 2
-#define EVT_DATA_TIMER 3
-#define EVT_DATA_LISTBASE 4
-#define EVT_DATA_NDOF_MOTION 5
+#define EVT_DATA_GESTURE 1
+#define EVT_DATA_TIMER 2
+#define EVT_DATA_LISTBASE 3
+#define EVT_DATA_NDOF_MOTION 4
/* tablet active, matches GHOST_TTabletMode */
#define EVT_TABLET_NONE 0
@@ -53,6 +52,11 @@
#define MOUSEX 4
#define MOUSEY 5
+
+/* *** wmEvent.type *** */
+
+/* non-event, for example disabled timer */
+#define EVENT_NONE 0
/* MOUSE : 0x00x */
#define LEFTMOUSE 1
#define MIDDLEMOUSE 2
@@ -148,11 +152,11 @@ enum {
#define TIMERJOBS 0x0114 /* timer event, jobs system */
#define TIMERAUTOSAVE 0x0115 /* timer event, autosave */
#define TIMERREPORT 0x0116 /* timer event, reports */
+#define TIMERREGION 0x0117 /* timer event, region slide in/out */
#define TIMERF 0x011F /* last timer */
/* test whether the event is timer event */
-#define ISTIMER(event) (event >= TIMER && event <= TIMERF)
-
+#define ISTIMER(event_type) (event_type >= TIMER && event_type <= TIMERF)
/* standard keyboard */
#define AKEY 'a'
@@ -286,29 +290,30 @@ enum {
/* for event checks */
/* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */
/* UNUSED - see wm_eventmatch - BUG [#30479] */
-// #define ISTEXTINPUT(event) (event >= ' ' && event <= 255)
+// #define ISTEXTINPUT(event_type) (event_type >= ' ' && event_type <= 255)
+/* note, an alternative could be to check 'event->utf8_buf' */
/* test whether the event is a key on the keyboard */
-#define ISKEYBOARD(event) (event >= ' ' && event <= 320)
+#define ISKEYBOARD(event_type) (event_type >= ' ' && event_type <= 320)
/* test whether the event is a modifier key */
-#define ISKEYMODIFIER(event) ((event >= LEFTCTRLKEY && event <= LEFTSHIFTKEY) || event == OSKEY)
+#define ISKEYMODIFIER(event_type) ((event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) || event_type == OSKEY)
/* test whether the event is a mouse button */
-#define ISMOUSE(event) (event >= LEFTMOUSE && event <= MOUSEROTATE)
+#define ISMOUSE(event_type) (event_type >= LEFTMOUSE && event_type <= MOUSEROTATE)
/* test whether the event is tweak event */
-#define ISTWEAK(event) (event >= EVT_TWEAK_L && event <= EVT_GESTURE)
+#define ISTWEAK(event_type) (event_type >= EVT_TWEAK_L && event_type <= EVT_GESTURE)
/* test whether the event is a NDOF event */
-#define ISNDOF(event) (event >= NDOF_MOTION && event < NDOF_LAST)
+#define ISNDOF(event_type) (event_type >= NDOF_MOTION && event_type < NDOF_LAST)
/* test whether event type is acceptable as hotkey, excluding modifiers */
-#define ISHOTKEY(event) \
- ((ISKEYBOARD(event) || ISMOUSE(event) || ISNDOF(event)) && \
- (event != ESCKEY) && \
- (event >= LEFTCTRLKEY && event <= LEFTSHIFTKEY) == FALSE && \
- (event >= UNKNOWNKEY && event <= GRLESSKEY) == FALSE)
+#define ISHOTKEY(event_type) \
+ ((ISKEYBOARD(event_type) || ISMOUSE(event_type) || ISNDOF(event_type)) && \
+ (event_type != ESCKEY) && \
+ (event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) == FALSE && \
+ (event_type >= UNKNOWNKEY && event_type <= GRLESSKEY) == FALSE)
/* **************** BLENDER GESTURE EVENTS (0x5000) **************** */
diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h
index f373530b5e6..fe007e7f52f 100644
--- a/source/blender/windowmanager/wm_files.h
+++ b/source/blender/windowmanager/wm_files.h
@@ -31,7 +31,13 @@
#ifndef __WM_FILES_H__
#define __WM_FILES_H__
-void WM_read_history(void);
+void wm_read_history(void);
+int wm_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports);
+int wm_homefile_read_exec(struct bContext *C, struct wmOperator *op);
+int wm_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory);
+int wm_homefile_write_exec(struct bContext *C, struct wmOperator *op);
+int wm_userpref_write_exec(struct bContext *C, struct wmOperator *op);
+
#endif /* __WM_FILES_H__ */
diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h
index 5017977952b..b584d0127a5 100644
--- a/source/blender/windowmanager/wm_subwindow.h
+++ b/source/blender/windowmanager/wm_subwindow.h
@@ -46,7 +46,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct);
void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y);
void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y);
-void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]);
+void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]);
unsigned int index_to_framebuffer(int index);
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 6360cfd4802..c4c64ed429f 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -40,6 +40,7 @@ void wm_ghost_init (bContext *C);
void wm_ghost_exit(void);
void wm_get_screensize(int *width_r, int *height_r);
+void wm_get_screensize_all(int *width_r, int *height_r);
wmWindow *wm_window_new (bContext *C);
void wm_window_free (bContext *C, wmWindowManager *wm, wmWindow *win);
@@ -55,8 +56,6 @@ void wm_window_make_drawable(bContext *C, wmWindow *win);
void wm_window_raise (wmWindow *win);
void wm_window_lower (wmWindow *win);
void wm_window_set_size (wmWindow *win, int width, int height);
-void wm_window_get_size (wmWindow *win, int *width_r, int *height_r);
-void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r);
void wm_window_get_position (wmWindow *win, int *posx_r, int *posy_r);
void wm_window_swap_buffers (wmWindow *win);
@@ -70,5 +69,11 @@ void wm_window_testbreak (void);
int wm_window_duplicate_exec(bContext *C, struct wmOperator *op);
int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
+/* Initial (unmaximized) size to start with for
+ * systems that can't find it for themselves (X11).
+ * Clamped by real desktop limits */
+#define WM_WIN_INIT_SIZE_X 1800
+#define WM_WIN_INIT_SIZE_Y 1000
+
#endif /* __WM_WINDOW_H__ */
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 85bb07d6e83..5e65324d893 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -95,6 +95,7 @@ endif()
bf_rna
bf_bmesh
bf_blenkernel
+ bf_intern_rigidbody
bf_blenloader
ge_blen_routines
bf_editor_datafiles
@@ -102,7 +103,6 @@ endif()
ge_logic_ketsji
ge_phys_bullet
ge_phys_dummy
- ge_phys_common
ge_logic
ge_rasterizer
ge_oglrasterizer
@@ -149,6 +149,7 @@ endif()
bf_intern_raskter
bf_intern_opencolorio
bf_intern_opennl
+ extern_rangetree
)
if(WITH_MOD_CLOTH_ELTOPO)
diff --git a/source/blenderplayer/bad_level_call_stubs/SConscript b/source/blenderplayer/bad_level_call_stubs/SConscript
index 5efe9aa5761..f26f4dfea6b 100644
--- a/source/blenderplayer/bad_level_call_stubs/SConscript
+++ b/source/blenderplayer/bad_level_call_stubs/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'stubs.c'
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 5e38dad74ed..3bc1cb9bc94 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -114,6 +114,7 @@ struct wmEvent;
struct wmKeyConfig;
struct wmKeyMap;
struct wmOperator;
+struct wmOperatorType;
struct wmWindow;
struct wmWindowManager;
@@ -176,7 +177,7 @@ int RE_RenderInProgress(struct Render *re) {return 0;}
struct Scene *RE_GetScene(struct Render *re) {return (struct Scene *) NULL;}
void RE_Database_Free(struct Render *re) {}
void RE_FreeRender(struct Render *re) {}
-void RE_DataBase_GetView(struct Render *re, float mat[][4]) {}
+void RE_DataBase_GetView(struct Render *re, float mat[4][4]) {}
int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta) {return 0;}
float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip) {return 0.0f;}
void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype) {}
@@ -196,13 +197,20 @@ int WM_operator_props_dialog_popup(struct bContext *C, struct wmOperator *op, in
int WM_operator_confirm(struct bContext *C, struct wmOperator *op, struct wmEvent *event) {return 0;}
struct MenuType *WM_menutype_find(const char *idname, int quiet) {return (struct MenuType *) NULL;}
void WM_operator_stack_clear(struct bContext *C) {}
+void WM_operator_handlers_clear(struct bContext *C, struct wmOperatorType *ot) {}
void WM_autosave_init(struct bContext *C) {}
void WM_jobs_kill_all_except(struct wmWindowManager *wm) {}
-char *WM_clipboard_text_get(int selection) {return (char*)0;}
+char *WM_clipboard_text_get(int selection) {return (char *)0;}
void WM_clipboard_text_set(char *buf, int selection) {}
+void WM_uilisttype_init(void) {}
+struct uiListType *WM_uilisttype_find(const char *idname, int quiet) {return (struct uiListType *)NULL;}
+int WM_uilisttype_add(struct uiListType *ult) {return 0;}
+void WM_uilisttype_freelink(struct uiListType *ult) {}
+void WM_uilisttype_free(void) {}
+
struct wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id) {return (struct wmKeyMapItem *) NULL;}
int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event) {return 0;}
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference) {}
@@ -299,13 +307,13 @@ void ED_node_tree_update(struct SpaceNode *snode, struct Scene *scene) {}
void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene) {}
int ED_view3d_scene_layer_set(int lay, const int *values) {return 0;}
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar) {}
-void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) {}
+void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) {}
struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) {return (struct BGpic *) NULL;}
void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) {}
void ED_view3D_background_image_clear(struct View3D *v3d) {}
-void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]) {}
+void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]) {}
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) {return 0.0f;}
-void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist) {}
+void view3d_apply_mat4(float mat[4][4], float *ofs, float *quat, float *dist) {}
int text_file_modified(struct Text *text) {return 0;}
void ED_node_shader_default(struct Material *ma) {}
void ED_screen_animation_timer_update(struct bContext *C, int redraws) {}
@@ -313,7 +321,7 @@ void ED_screen_animation_playing(struct wmWindowManager *wm) {}
void ED_base_object_select(struct Base *base, short mode) {}
int ED_object_modifier_remove(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct ModifierData *md) {return 0;}
int ED_object_modifier_add(struct ReportList *reports, struct Scene *scene, struct Object *ob, char *name, int type) {return 0;}
-void ED_object_modifier_clear(struct Scene *scene, struct Object *ob) {}
+void ED_object_modifier_clear(struct Main *bmain, struct Object *ob) {}
void ED_object_enter_editmode(struct bContext *C, int flag) {}
void ED_object_exit_editmode(struct bContext *C, int flag) {}
int uiLayoutGetActive(struct uiLayout *layout) {return 0;}
@@ -328,6 +336,7 @@ void uiLayoutSetEnabled(struct uiLayout *layout, int enabled) {}
void uiLayoutSetAlignment(struct uiLayout *layout, int alignment) {}
void uiLayoutSetScaleX(struct uiLayout *layout, float scale) {}
void uiLayoutSetScaleY(struct uiLayout *layout, float scale) {}
+void uiTemplateIconView(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname) {}
void ED_base_object_free_and_unlink(struct Scene *scene, struct Base *base) {}
void ED_mesh_calc_normals(struct Mesh *me) {}
void ED_mesh_geometry_add(struct Mesh *mesh, struct ReportList *reports, int verts, int edges, int faces) {}
@@ -364,6 +373,8 @@ int ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *s
void ED_nurb_set_spline_type(struct Nurb *nu, int type) {}
+void ED_mball_transform(struct MetaBall *mb, float *mat) {}
+
void make_editLatt(struct Object *obedit) {}
void load_editLatt(struct Object *obedit) {}
@@ -374,6 +385,7 @@ void make_editNurb(struct Object *obedit) {}
void uiItemR(struct uiLayout *layout, struct PointerRNA *ptr, char *propname, int flag, char *name, int icon) {}
struct PointerRNA uiItemFullO(struct uiLayout *layout, char *idname, char *name, int icon, struct IDProperty *properties, int context, int flag) {struct PointerRNA a = {{0}}; return a;}
+PointerRNA uiItemFullO_ptr(struct uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, struct IDProperty *properties, int context, int flag) {struct PointerRNA a = {{0}}; return a;}
struct uiLayout *uiLayoutRow(struct uiLayout *layout, int align) {return (struct uiLayout *) NULL;}
struct uiLayout *uiLayoutColumn(struct uiLayout *layout, int align) {return (struct uiLayout *) NULL;}
struct uiLayout *uiLayoutColumnFlow(struct uiLayout *layout, int number, int align) {return (struct uiLayout *) NULL;}
@@ -400,6 +412,7 @@ void uiItemFullR(struct uiLayout *layout, struct PointerRNA *ptr, struct Propert
void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct PointerRNA *ptr) {}
char *uiLayoutIntrospect(struct uiLayout *layout) {return (char *)NULL;}
void UI_reinit_font(void) {}
+int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, int big) {return 0;}
/* rna template */
void uiTemplateAnyID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *text) {}
@@ -414,7 +427,9 @@ void uiTemplateCurveMapping(struct uiLayout *layout, struct CurveMapping *cumap,
void uiTemplateColorRamp(struct uiLayout *layout, struct ColorBand *coba, int expand) {}
void uiTemplateLayers(struct uiLayout *layout, struct PointerRNA *ptr, char *propname) {}
void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser) {}
-ListBase uiTemplateList(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activepropname, int rows, int listtype) {struct ListBase b = {0,0}; return b;}
+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) {}
void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C) {}
void uiTemplateOperatorSearch(struct uiLayout *layout) {}
void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C) {}
@@ -502,6 +517,7 @@ float sculpt_get_brush_alpha(struct Brush *brush) {return 0.0f;}
void sculpt_set_brush_alpha(struct Brush *brush, float alpha) {}
void ED_sculpt_modifiers_changed(struct Object *ob) {}
void ED_mesh_calc_tessface(struct Mesh *mesh) {}
+void BKE_brush_gen_texture_cache(struct Brush *br, int half_side) {}
/* bpy/python internal api */
void operator_wrapper(struct wmOperatorType *ot, void *userdata) {}
@@ -516,6 +532,7 @@ void macro_wrapper(struct wmOperatorType *ot, void *userdata) {}
int pyrna_id_FromPyObject(struct PyObject *obj, struct ID **id) { return 0; }
struct PyObject *pyrna_id_CreatePyObject(struct ID *id) {return NULL; }
void BPY_context_update(struct bContext *C) {};
+const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *msgid) { return msgid; }
/* intern/dualcon */
struct DualConMesh;
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index b66c000ac89..7409e23a1f4 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -689,7 +689,7 @@ elseif(APPLE)
)
# python
- if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE)
+ if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
# the python zip is first extract as part of the build process,
# and then later installed as part of make install. this is much
# quicker, and means we can easily exclude files on copy
@@ -742,7 +742,7 @@ elseif(APPLE)
)
# python
- if(WITH_PYTHON)
+ if(WITH_PYTHON AND NOT WITH_PYTHON_FRAMEWORK)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/python
COMMAND rm -rf ${CMAKE_CURRENT_BINARY_DIR}/python/
@@ -779,8 +779,7 @@ add_dependencies(blender makesdna)
get_property(BLENDER_LINK_LIBS GLOBAL PROPERTY BLENDER_LINK_LIBS)
-set(BLENDER_LINK_LIBS
- ${BLENDER_LINK_LIBS}
+list(APPEND BLENDER_LINK_LIBS
bf_windowmanager
bf_render
)
@@ -885,7 +884,6 @@ endif()
extern_colamd
ge_logic_ketsji
extern_recastnavigation
- ge_phys_common
ge_logic
ge_rasterizer
ge_oglrasterizer
@@ -893,7 +891,6 @@ endif()
ge_scenegraph
ge_logic_network
ge_logic_ngnetwork
- extern_bullet
ge_logic_loopbacknetwork
bf_intern_moto
extern_openjpeg
@@ -914,12 +911,13 @@ endif()
cycles_subd
bf_intern_raskter
bf_intern_opencolorio
+ extern_rangetree
)
if(WITH_COMPOSITOR)
# added for opencl compositor
list_insert_before(BLENDER_SORTED_LIBS "bf_blenkernel" "bf_compositor")
- list_insert_after(BLENDER_SORTED_LIBS "bf_compositor" "bf_opencl")
+ list_insert_after(BLENDER_SORTED_LIBS "bf_compositor" "bf_intern_opencl")
endif()
if(WITH_LIBMV)
@@ -971,6 +969,14 @@ endif()
list(APPEND BLENDER_SORTED_LIBS bf_intern_locale)
endif()
+ if(WITH_BULLET)
+ list_insert_after(BLENDER_SORTED_LIBS "bf_blenkernel" "bf_intern_rigidbody")
+ endif()
+
+ if(WITH_BULLET AND NOT WITH_BULLET_SYSTEM)
+ list_insert_after(BLENDER_SORTED_LIBS "ge_logic_ngnetwork" "extern_bullet")
+ endif()
+
foreach(SORTLIB ${BLENDER_SORTED_LIBS})
set(REMLIB ${SORTLIB})
foreach(SEARCHLIB ${BLENDER_LINK_LIBS})
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 0f1207a9a88..d7b2d87ffe8 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -40,14 +40,29 @@
# include <xmmintrin.h>
#endif
+/* crash handler */
#ifdef WIN32
-# include <Windows.h>
+# include <process.h> /* getpid */
+#else
+# include <unistd.h> /* getpid */
+#endif
+
+#ifdef WIN32
+# include <windows.h>
# 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>
+#include <errno.h>
/* This little block needed for linking to Blender... */
@@ -73,6 +88,7 @@
#include "BKE_depsgraph.h" /* for DAG_on_visible_update */
#include "BKE_font.h"
#include "BKE_global.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_packedFile.h"
@@ -143,22 +159,28 @@ extern char build_system[];
#endif
/* Local Function prototypes */
-#ifndef WITH_PYTHON_MODULE
+#ifdef WITH_PYTHON_MODULE
+int main_python_enter(int argc, const char **argv);
+void main_python_exit(void);
+#else
static int print_help(int argc, const char **argv, void *data);
static int print_version(int argc, const char **argv, void *data);
#endif
/* for the callbacks: */
-#define BLEND_VERSION_STRING_FMT \
- "Blender %d.%02d (sub %d)\n", \
- BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION \
+#define BLEND_VERSION_FMT "Blender %d.%02d (sub %d)"
+#define BLEND_VERSION_ARG BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION
+/* pass directly to printf */
+#define BLEND_VERSION_STRING_FMT BLEND_VERSION_FMT "\n", BLEND_VERSION_ARG
/* Initialize callbacks for the modules that need them */
static void setCallbacks(void);
#ifndef WITH_PYTHON_MODULE
+static bool use_crash_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))
@@ -246,6 +268,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
printf("Misc Options:\n");
BLI_argsPrintArgDoc(ba, "--debug");
BLI_argsPrintArgDoc(ba, "--debug-fpe");
+ BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
#ifdef WITH_FFMPEG
BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
@@ -280,6 +303,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
printf("\n");
BLI_argsPrintArgDoc(ba, "--python");
+ BLI_argsPrintArgDoc(ba, "--python-text");
BLI_argsPrintArgDoc(ba, "--python-console");
BLI_argsPrintArgDoc(ba, "--addons");
@@ -350,6 +374,12 @@ static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNU
return 0;
}
+static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+ use_crash_handler = false;
+ return 0;
+}
+
static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
G.background = 1;
@@ -423,6 +453,148 @@ 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(_MSV_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;
+}
+
+#endif
+
+static void blender_crash_handler(int signum)
+{
+
+#if 0
+ {
+ char fname[FILE_MAX];
+
+ if (!G.main->name[0]) {
+ BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend");
+ }
+ else {
+ BLI_strncpy(fname, G.main->name, sizeof(fname));
+ BLI_replace_extension(fname, sizeof(fname), ".crash.blend");
+ }
+
+ printf("Writing: %s\n", fname);
+ fflush(stdout);
+
+ BKE_undo_save_file(fname);
+ }
+#endif
+
+ FILE *fp;
+ char header[512];
+ wmWindowManager *wm = G.main->wm.first;
+
+ char fname[FILE_MAX];
+
+ if (!G.main->name[0]) {
+ BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), "blender.crash.txt");
+ }
+ else {
+ BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), BLI_path_basename(G.main->name));
+ BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
+ }
+
+ printf("Writing: %s\n", fname);
+ fflush(stdout);
+
+ BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Revision: %s\n", BLEND_VERSION_ARG,
+#ifdef BUILD_DATE
+ build_rev
+#else
+ "Unknown"
+#endif
+ );
+
+ /* open the crash log */
+ errno = 0;
+ fp = BLI_fopen(fname, "wb");
+ if (fp == NULL) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ fname, errno ? strerror(errno) : "Unknown error opening file");
+ }
+ else {
+ if (wm) {
+ BKE_report_write_file_fp(fp, &wm->reports, header);
+ }
+
+ blender_crash_handler_backtrace(fp);
+
+ fclose(fp);
+ }
+
+
+ /* really crash */
+ signal(signum, SIG_DFL);
+#ifndef WIN32
+ kill(getpid(), signum);
+#else
+ TerminateProcess(GetCurrentProcess(), signum);
+#endif
+}
+
+
static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
G.factory_startup = 1;
@@ -481,6 +653,12 @@ static int prefsize(int argc, const char **argv, void *UNUSED(data))
return 4;
}
+static int native_pixels(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+ WM_init_native_pixels(0);
+ return 0;
+}
+
static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
WM_init_state_normal_set();
@@ -747,7 +925,7 @@ static int set_ge_parameters(int argc, const char **argv, void *data)
}
- } /* if (*(argv[a+1]) == '=') */
+ } /* if (*(argv[a + 1]) == '=') */
}
return a;
@@ -913,11 +1091,11 @@ static int set_skip_frame(int argc, const char **argv, void *data)
_cmd; \
} \
CTX_data_scene_set(C, prevscene); \
- } \
+ } (void)0 \
#endif /* WITH_PYTHON */
-static int run_python(int argc, const char **argv, void *data)
+static int run_python_file(int argc, const char **argv, void *data)
{
#ifdef WITH_PYTHON
bContext *C = data;
@@ -929,12 +1107,42 @@ static int run_python(int argc, const char **argv, void *data)
BLI_strncpy(filename, argv[1], sizeof(filename));
BLI_path_cwd(filename);
- BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
+ BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL));
return 1;
}
else {
- printf("\nError: you must specify a Python script after '-P / --python'.\n");
+ printf("\nError: you must specify a filepath after '%s'.\n", argv[0]);
+ return 0;
+ }
+#else
+ (void)argc; (void)argv; (void)data; /* unused */
+ printf("This blender was built without python support\n");
+ return 0;
+#endif /* WITH_PYTHON */
+}
+
+static int run_python_text(int argc, const char **argv, void *data)
+{
+#ifdef WITH_PYTHON
+ bContext *C = data;
+
+ /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
+ if (argc > 1) {
+ /* Make the path absolute because its needed for relative linked blends to be found */
+ struct Text *text = (struct Text *)BKE_libblock_find_name(ID_TXT, argv[1]);
+
+ if (text) {
+ BPY_CTX_SETUP(BPY_text_exec(C, text, NULL, false));
+ return 1;
+ }
+ else {
+ printf("\nError: text block not found %s.\n", argv[1]);
+ return 1;
+ }
+ }
+ else {
+ printf("\nError: you must specify a text block after '%s'.\n", argv[0]);
return 0;
}
#else
@@ -949,7 +1157,7 @@ static int run_python_console(int UNUSED(argc), const char **argv, void *data)
#ifdef WITH_PYTHON
bContext *C = data;
- BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
+ BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"));
return 0;
#else
@@ -1116,6 +1324,8 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
+ BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
+
#undef PY_ENABLE_AUTO
#undef PY_DISABLE_AUTO
@@ -1156,9 +1366,10 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 2, "-p", "--window-geometry", "<sx> <sy> <w> <h>\n\tOpen with lower left corner at <sx>, <sy> and width and height as <w>, <h>", prefsize, NULL);
BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
- BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
+ BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set), (Windows only)", start_with_console, NULL);
BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
+ BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba);
/* third pass: disabling things and forcing settings */
BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
@@ -1174,7 +1385,8 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
- BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
+ BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script file", run_python_file, C);
+ BLI_argsAdd(ba, 4, NULL, "--python-text", "<name>\n\tRun the given Python script text block", run_python_text, C);
BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
@@ -1292,8 +1504,15 @@ int main(int argc, const char **argv)
setupArguments(C, ba, &syshandle);
BLI_argsParse(ba, 1, NULL, NULL);
-#endif
+ if (use_crash_handler) {
+ /* after parsing args */
+ signal(SIGSEGV, blender_crash_handler);
+ }
+#else
+ G.factory_startup = true; /* using preferences or user startup makes no sense for py-as-module */
+ (void)syshandle;
+#endif
/* after level 1 args, this is so playanim skips RNA init */
RNA_init();
@@ -1304,10 +1523,12 @@ int main(int argc, const char **argv)
#if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
- G.background = 1; /* python module mode ALWAYS runs in background mode (for now) */
+ G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
#else
/* for all platforms, even windos has it! */
- if (G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
+ if (G.background) {
+ signal(SIGINT, blender_esc); /* ctrl c out bg render */
+ }
#endif
/* background render uses this font too */
@@ -1398,7 +1619,7 @@ int main(int argc, const char **argv)
WM_main(C);
return 0;
-} /* end of int main(argc,argv) */
+} /* end of int main(argc, argv) */
#ifdef WITH_PYTHON_MODULE
void main_python_exit(void)
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 6807f531f0a..e78b996391e 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -58,7 +58,6 @@
#include "RAS_GLExtensionManager.h"
#include "RAS_OpenGLRasterizer.h"
-#include "RAS_VAOpenGLRasterizer.h"
#include "RAS_ListRasterizer.h"
#include "NG_LoopBackNetworkDeviceInterface.h"
@@ -270,7 +269,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
#ifdef WITH_PYTHON
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
#endif
- bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
+ // 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;
@@ -287,16 +286,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
RAS_IRasterizer* rasterizer = NULL;
- if (displaylists) {
- if (GLEW_VERSION_1_1 && !novertexarrays)
- rasterizer = new RAS_ListRasterizer(canvas, true, true);
- else
- rasterizer = new RAS_ListRasterizer(canvas);
- }
- else if (GLEW_VERSION_1_1 && !novertexarrays)
- rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
+ //Don't use displaylists with VBOs
+ //If auto starts using VBOs, make sure to check for that here
+ if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO)
+ rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage);
else
- rasterizer = new RAS_OpenGLRasterizer(canvas);
+ rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage);
// create the inputdevices
KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
@@ -443,7 +438,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat));
if (rv3d->persp == RV3D_ORTHO)
{
- ketsjiengine->SetCameraOverrideClipping(-v3d->far, v3d->far);
+ ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
}
else
{
@@ -473,6 +468,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
sceneconverter->SetMaterials(true);
if (useglslmat && (gs.matmode == GAME_MAT_GLSL))
sceneconverter->SetGLSLMaterials(true);
+ if (scene->gm.flag & GAME_NO_MATERIAL_CACHING)
+ sceneconverter->SetCacheMaterials(false);
KX_Scene* startscene = new KX_Scene(keyboarddevice,
mousedevice,
diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt
index 9a47d223f76..32efc5bde21 100644
--- a/source/gameengine/BlenderRoutines/CMakeLists.txt
+++ b/source/gameengine/BlenderRoutines/CMakeLists.txt
@@ -30,7 +30,6 @@ set(INC
)
set(INC_SYS
- ../../../extern/bullet2/src
${PTHREADS_INCLUDE_DIRS}
${GLEW_INCLUDE_PATH}
${BOOST_INCLUDE_DIR}
@@ -70,4 +69,12 @@ if(WITH_CODEC_FFMPEG)
add_definitions(-DWITH_FFMPEG)
endif()
+if(WITH_BULLET)
+ list(APPEND INC_SYS
+ ${BULLET_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_BULLET)
+endif()
+
+
blender_add_lib(ge_blen_routines "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
index 346d2017ef0..6ab1d032bf2 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
@@ -154,11 +154,11 @@ SetViewPort(
int x1, int y1,
int x2, int y2
) {
- /* x1 and y1 are the min pixel coordinate (e.g. 0)
- x2 and y2 are the max pixel coordinate
- the width,height is calculated including both pixels
- therefore: max - min + 1
- */
+ /* x1 and y1 are the min pixel coordinate (e.g. 0)
+ * x2 and y2 are the max pixel coordinate
+ * the width,height is calculated including both pixels
+ * therefore: max - min + 1
+ */
int vp_width = (x2 - x1) + 1;
int vp_height = (y2 - y1) + 1;
int minx = m_frame_rect.GetLeft();
@@ -178,6 +178,18 @@ SetViewPort(
glScissor(minx + x1, miny + y1, vp_width, vp_height);
}
+ void
+KX_BlenderCanvas::
+UpdateViewPort(
+ int x1, int y1,
+ int x2, int y2
+) {
+ m_viewport[0] = x1;
+ m_viewport[1] = y1;
+ m_viewport[2] = x2;
+ m_viewport[3] = y2;
+}
+
const int*
KX_BlenderCanvas::
GetViewPort() {
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
index 244394a115d..430f956bc7f 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
@@ -58,8 +58,9 @@ struct wmWindow;
class KX_BlenderCanvas : public RAS_ICanvas
{
private:
- /** Rect that defines the area used for rendering,
- relative to the context */
+ /**
+ * Rect that defines the area used for rendering,
+ * relative to the context */
RAS_Rect m_displayarea;
int m_viewport[4];
@@ -151,6 +152,13 @@ public:
int x1, int y1,
int x2, int y2
);
+
+ void
+ UpdateViewPort(
+ int x1, int y1,
+ int x2, int y2
+ );
+
const int*
GetViewPort();
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index 00836fa8ecb..3a9a10dd0cc 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -121,6 +121,50 @@ static void DisableForText()
}
}
+void BL_draw_gamedebug_box(int xco, int yco, int width, int height, float percentage)
+{
+ /* This is a rather important line :( The gl-mode hasn't been left
+ * behind quite as neatly as we'd have wanted to. I don't know
+ * what cause it, though :/ .*/
+ glDisable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glOrtho(0, width, 0, height, -100, 100);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ yco = height - yco;
+ int barsize = 50;
+
+ /* draw in black first*/
+ glColor3ub(0, 0, 0);
+ glBegin(GL_QUADS);
+ glVertex2f(xco + 1 + 1 + barsize * percentage, yco - 1 + 10);
+ glVertex2f(xco + 1, yco - 1 + 10);
+ glVertex2f(xco + 1, yco - 1);
+ glVertex2f(xco + 1 + 1 + barsize * percentage, yco - 1);
+ glEnd();
+
+ glColor3ub(255, 255, 255);
+ glBegin(GL_QUADS);
+ glVertex2f(xco + 1 + barsize * percentage, yco + 10);
+ glVertex2f(xco, yco + 10);
+ glVertex2f(xco, yco);
+ glVertex2f(xco + 1 + barsize * percentage, yco);
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glEnable(GL_DEPTH_TEST);
+}
+
/* Print 3D text */
void BL_print_game_line(int fontid, const char* text, int size, int dpi, float* color, double* mat, float aspect)
{
@@ -164,7 +208,9 @@ void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int
/* the actual drawing */
glColor3ub(255, 255, 255);
- BLF_draw_default((float)xco, (float)(height-yco), 0.0f, (char *)text, 65535); /* XXX, use real len */
+ BLF_size(blf_mono_font, 11, 72);
+ BLF_position(blf_mono_font, (float)xco, (float)(height-yco), 0.0f);
+ BLF_draw(blf_mono_font, (char *)text, 65535); /* XXX, use real len */
glMatrixMode(GL_PROJECTION);
glPopMatrix();
@@ -193,9 +239,13 @@ void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int widt
/* draw in black first*/
glColor3ub(0, 0, 0);
- BLF_draw_default((float)(xco+2), (float)(height-yco-2), 0.0f, text, 65535); /* XXX, use real len */
+ BLF_size(blf_mono_font, 11, 72);
+ BLF_position(blf_mono_font, (float)xco+1, (float)(height-yco-1), 0.0f);
+ BLF_draw(blf_mono_font, (char *)text, 65535);/* XXX, use real len */
+
glColor3ub(255, 255, 255);
- BLF_draw_default((float)xco, (float)(height-yco), 0.0f, text, 65535); /* XXX, use real len */
+ BLF_position(blf_mono_font, (float)xco, (float)(height-yco), 0.0f);
+ BLF_draw(blf_mono_font, (char *)text, 65535);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
@@ -259,7 +309,7 @@ void BL_MakeScreenShot(ScrArea *curarea, const char* filename)
ImBuf *ibuf;
BLI_path_abs(path, G.main->name);
/* BKE_add_image_extension() checks for if extension was already set */
- BKE_add_image_extension(path, R_IMF_IMTYPE_PNG); /* scene->r.im_format.imtype */
+ BKE_add_image_extension_from_type(path, R_IMF_IMTYPE_PNG); /* scene->r.im_format.imtype */
ibuf= IMB_allocImBuf(dumpsx, dumpsy, 24, 0);
ibuf->rect= dumprect;
ibuf->ftype= PNG;
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h
index 7ba612b19cf..5c3f0684764 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h
@@ -50,6 +50,7 @@ void BL_HideMouse(struct wmWindow *win);
void BL_NormalMouse(struct wmWindow *win);
void BL_WaitMouse(struct wmWindow *win);
+void BL_draw_gamedebug_box(int xco, int yco, int width, int height, float percentage);
void BL_print_game_line(int fontid, const char* text, int size, int dpi, float* color, double* mat, float aspect);
void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int height);
void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int width, int height);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
index 19ba46ed6d7..5917ce40440 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
@@ -49,8 +49,8 @@ KX_BlenderKeyboardDevice::~KX_BlenderKeyboardDevice()
}
/**
- IsPressed gives boolean information about keyboard status, true if pressed, false if not
-*/
+ * IsPressed gives boolean information about keyboard status, true if pressed, false if not
+ */
bool KX_BlenderKeyboardDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
@@ -64,11 +64,11 @@ bool KX_BlenderKeyboardDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputco
return m_eventStatusTables[m_currentTable][inputcode];
}
*/
-/**
- NextFrame toggles currentTable with previousTable,
- and copy relevant event information from previous to current
- (pressed keys need to be remembered)
-*/
+/**
+ * NextFrame toggles currentTable with previousTable,
+ * and copy relevant event information from previous to current
+ * (pressed keys need to be remembered)
+ */
void KX_BlenderKeyboardDevice::NextFrame()
{
SCA_IInputDevice::NextFrame();
@@ -87,13 +87,11 @@ void KX_BlenderKeyboardDevice::NextFrame()
}
}
-/**
- ConvertBlenderEvent translates blender keyboard events into ketsji kbd events
- extra event information is stored, like ramp-mode (just released/pressed)
+/**
+ * ConvertBlenderEvent translates blender keyboard events into ketsji kbd events
+ * extra event information is stored, like ramp-mode (just released/pressed)
*/
-
-
-bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode,short val)
+bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode, short val)
{
bool result = false;
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
index 8d90eacd27f..0cdc10264a5 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
@@ -46,8 +46,8 @@ KX_BlenderMouseDevice::~KX_BlenderMouseDevice()
}
/**
- IsPressed gives boolean information about mouse status, true if pressed, false if not
-*/
+ * IsPressed gives boolean information about mouse status, true if pressed, false if not
+ */
bool KX_BlenderMouseDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
@@ -62,11 +62,11 @@ bool KX_BlenderMouseDevice::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
}
*/
-/**
- NextFrame toggles currentTable with previousTable,
- and copy relevant event information from previous to current
- (pressed keys need to be remembered)
-*/
+/**
+ * NextFrame toggles currentTable with previousTable,
+ * and copy relevant event information from previous to current
+ * (pressed keys need to be remembered)
+ */
void KX_BlenderMouseDevice::NextFrame()
{
SCA_IInputDevice::NextFrame();
@@ -104,13 +104,11 @@ void KX_BlenderMouseDevice::NextFrame()
}
-/**
- ConvertBlenderEvent translates blender mouse events into ketsji kbd events
- extra event information is stored, like ramp-mode (just released/pressed)
-*/
-
-
-bool KX_BlenderMouseDevice::ConvertBlenderEvent(unsigned short incode,short val)
+/**
+ * ConvertBlenderEvent translates blender mouse events into ketsji kbd events
+ * extra event information is stored, like ramp-mode (just released/pressed)
+ */
+bool KX_BlenderMouseDevice::ConvertBlenderEvent(unsigned short incode, short val)
{
bool result = false;
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index e32239b148d..64ed384e961 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -280,6 +280,16 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
}
}
}
+
+void KX_BlenderRenderTools::RenderBox2D(int xco,
+ int yco,
+ int width,
+ int height,
+ float percentage)
+{
+ BL_draw_gamedebug_box(xco, yco, width, height, percentage);
+}
+
void KX_BlenderRenderTools::RenderText3D(int fontid,
const char* text,
int size,
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
index 7195524ceae..228763e7d2d 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -71,6 +71,13 @@ public:
void DisableOpenGLLights();
void ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat);
+ void RenderBox2D(int xco,
+ int yco,
+ int width,
+ int height,
+ float percentage);
+
+
void RenderText3D(int fontid,
const char* text,
int size,
diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript
index 04dbe27337f..e2417d70b58 100644
--- a/source/gameengine/BlenderRoutines/SConscript
+++ b/source/gameengine/BlenderRoutines/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt
index aae7e93cc91..cf7895e98ea 100644
--- a/source/gameengine/CMakeLists.txt
+++ b/source/gameengine/CMakeLists.txt
@@ -37,7 +37,6 @@ add_subdirectory(Ketsji)
add_subdirectory(Ketsji/KXNetwork)
add_subdirectory(Network)
add_subdirectory(Network/LoopBackNetwork)
-add_subdirectory(Physics/common)
add_subdirectory(Physics/Dummy)
add_subdirectory(Rasterizer)
add_subdirectory(Rasterizer/RAS_OpenGLRasterizer)
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index 1f1c404efcb..395a57d753c 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -112,7 +112,8 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
if (copy_constraint) {
ListBase listb;
// copy all constraint for backward compatibility
- copy_constraints(&listb, &pchan->constraints, FALSE); // copy_constraints NULLs listb, no need to make extern for this operation.
+ // BKE_copy_constraints NULLs listb, no need to make extern for this operation.
+ BKE_copy_constraints(&listb, &pchan->constraints, FALSE);
pchan->constraints= listb;
} else {
pchan->constraints.first = NULL;
@@ -304,7 +305,7 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter)
case CONSTRAINT_TYPE_TRANSFORM:
case CONSTRAINT_TYPE_DISTLIMIT:
case CONSTRAINT_TYPE_TRANSLIKE:
- cti = constraint_get_typeinfo(pcon);
+ cti = BKE_constraint_get_typeinfo(pcon);
gametarget = gamesubtarget = NULL;
if (cti && cti->get_constraint_targets) {
ListBase listb = { NULL, NULL };
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index eb695e624e4..f861b105ba3 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -164,7 +164,7 @@ extern Material defmaterial; /* material.c */
#include "SG_Tree.h"
#include "KX_ConvertPhysicsObject.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "CcdPhysicsEnvironment.h"
#include "CcdGraphicController.h"
#endif
@@ -192,6 +192,8 @@ extern "C" {
}
#endif
+#include "BLI_threads.h"
+
static bool default_light_mode = 0;
static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table()
@@ -423,55 +425,61 @@ static void SetDefaultLightMode(Scene* scene)
// --
-static void GetRGB(
- const bool use_mcol,
- MFace *mface,
- MCol *mmcol,
- Material *mat,
- unsigned int &c0,
- unsigned int &c1,
- unsigned int &c2,
- unsigned int &c3)
+static void GetRGB(short type,
+ MFace* mface,
+ MCol* mmcol,
+ Material *mat,
+ unsigned int c[4])
{
unsigned int color = 0xFFFFFFFFL;
- if (use_mcol) {
- // vertex colors
-
- if (mmcol) {
- c0 = KX_Mcol2uint_new(mmcol[0]);
- c1 = KX_Mcol2uint_new(mmcol[1]);
- c2 = KX_Mcol2uint_new(mmcol[2]);
+ switch (type) {
+ case 0: // vertex colors
+ {
+ if (mmcol) {
+ c[0] = KX_Mcol2uint_new(mmcol[0]);
+ c[1] = KX_Mcol2uint_new(mmcol[1]);
+ c[2] = KX_Mcol2uint_new(mmcol[2]);
+ if (mface->v4)
+ c[3] = KX_Mcol2uint_new(mmcol[3]);
+ }
+ else { // backup white
+ c[0] = KX_rgbaint2uint_new(color);
+ c[1] = KX_rgbaint2uint_new(color);
+ c[2] = KX_rgbaint2uint_new(color);
+ if (mface->v4)
+ c[3] = KX_rgbaint2uint_new( color );
+ }
+ } break;
+
+
+ case 1: // material rgba
+ {
+ if (mat) {
+ union {
+ unsigned char cp[4];
+ unsigned int integer;
+ } col_converter;
+ col_converter.cp[3] = (unsigned char) (mat->r * 255.0f);
+ col_converter.cp[2] = (unsigned char) (mat->g * 255.0f);
+ col_converter.cp[1] = (unsigned char) (mat->b * 255.0f);
+ col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
+ color = col_converter.integer;
+ }
+ c[0] = KX_rgbaint2uint_new(color);
+ c[1] = KX_rgbaint2uint_new(color);
+ c[2] = KX_rgbaint2uint_new(color);
if (mface->v4)
- c3 = KX_Mcol2uint_new(mmcol[3]);
- }
- else { // backup white
- c0 = KX_rgbaint2uint_new(color);
- c1 = KX_rgbaint2uint_new(color);
- c2 = KX_rgbaint2uint_new(color);
+ c[3] = KX_rgbaint2uint_new(color);
+ } break;
+
+ default: // white
+ {
+ c[0] = KX_rgbaint2uint_new(color);
+ c[1] = KX_rgbaint2uint_new(color);
+ c[2] = KX_rgbaint2uint_new(color);
if (mface->v4)
- c3 = KX_rgbaint2uint_new( color );
- }
- }
- else {
- // material rgba
- if (mat) {
- union {
- unsigned char cp[4];
- unsigned int integer;
- } col_converter;
- col_converter.cp[3] = (unsigned char) (mat->r * 255.0f);
- col_converter.cp[2] = (unsigned char) (mat->g * 255.0f);
- col_converter.cp[1] = (unsigned char) (mat->b * 255.0f);
- col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
- color = col_converter.integer;
- }
- // backup white is fallback
-
- c0 = KX_rgbaint2uint_new(color);
- c1 = KX_rgbaint2uint_new(color);
- c2 = KX_rgbaint2uint_new(color);
- if (mface->v4)
- c3 = KX_rgbaint2uint_new(color);
+ c[3] = KX_rgbaint2uint_new(color);
+ } break;
}
}
@@ -480,42 +488,65 @@ typedef struct MTF_localLayer {
const char *name;
} MTF_localLayer;
-static void tface_to_uv_bge(const MFace *mface, const MTFace *tface, MT_Point2 uv[4])
+static void GetUVs(BL_Material *material, MTF_localLayer *layers, MFace *mface, MTFace *tface, MT_Point2 uvs[4][MAXTEX])
{
- uv[0].setValue(tface->uv[0]);
- uv[1].setValue(tface->uv[1]);
- uv[2].setValue(tface->uv[2]);
- if (mface->v4) {
- uv[3].setValue(tface->uv[3]);
+ int unit = 0;
+ if (tface)
+ {
+
+ uvs[0][0].setValue(tface->uv[0]);
+ uvs[1][0].setValue(tface->uv[1]);
+ uvs[2][0].setValue(tface->uv[2]);
+
+ if (mface->v4)
+ uvs[3][0].setValue(tface->uv[3]);
}
-}
+ else
+ {
+ uvs[0][0] = uvs[1][0] = uvs[2][0] = uvs[3][0] = MT_Point2(0.f, 0.f);
+ }
+
+ for (int vind = 0; vind<MAXTEX; vind++)
+ {
+ BL_Mapping &map = material->mapping[vind];
-static void GetUV(
- MFace *mface,
- MTFace *tface,
- MTF_localLayer *layers,
- const int layer_uv[2],
- MT_Point2 uv[4],
- MT_Point2 uv2[4])
-{
- bool validface = (tface != NULL);
+ if (!(map.mapping & USEUV)) continue;
- uv2[0] = uv2[1] = uv2[2] = uv2[3] = MT_Point2(0.0f, 0.0f);
+ //If no UVSet is specified, try grabbing one from the UV/Image editor
+ if (map.uvCoName.IsEmpty() && tface)
+ {
+ uvs[0][unit].setValue(tface->uv[0]);
+ uvs[1][unit].setValue(tface->uv[1]);
+ uvs[2][unit].setValue(tface->uv[2]);
- /* No material, what to do? let's see what is in the UV and set the material accordingly
- * light and visible is always on */
- if (layer_uv[0] != -1) {
- tface_to_uv_bge(mface, layers[layer_uv[0]].face, uv);
- if (layer_uv[1] != -1) {
- tface_to_uv_bge(mface, layers[layer_uv[1]].face, uv2);
+ if (mface->v4)
+ uvs[3][unit].setValue(tface->uv[3]);
+
+ ++unit;
+ continue;
+ }
+
+
+ for (int lay=0; lay<MAX_MTFACE; lay++)
+ {
+ MTF_localLayer& layer = layers[lay];
+ if (layer.face == 0) break;
+
+ if (map.uvCoName.IsEmpty() || strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
+ {
+ uvs[0][unit].setValue(layer.face->uv[0]);
+ uvs[1][unit].setValue(layer.face->uv[1]);
+ uvs[2][unit].setValue(layer.face->uv[2]);
+
+ if (mface->v4)
+ uvs[3][unit].setValue(layer.face->uv[3]);
+ else
+ uvs[3][unit].setValue(0.0f, 0.0f);
+
+ ++unit;
+ break;
+ }
}
- }
- else if (validface) {
- tface_to_uv_bge(mface, tface, uv);
- }
- else {
- // nothing at all
- uv[0] = uv[1] = uv[2] = uv[3] = MT_Point2(0.0f, 0.0f);
}
}
@@ -526,25 +557,29 @@ static bool ConvertMaterial(
MTFace* tface,
const char *tfaceName,
MFace* mface,
- MCol* mmcol, /* only for text, use first mcol, weak */
- MTF_localLayer *layers,
- int layer_uv[2],
- const bool glslmat)
+ MCol* mmcol,
+ bool glslmat)
{
material->Initialize();
- int numchan = -1, texalpha = 0;
+ int texalpha = 0;
bool validmat = (mat!=0);
bool validface = (tface!=0);
+ short type = 0;
+ if ( validmat )
+ type = 1; // material color
+
material->IdMode = DEFAULT_BLENDER;
material->glslmat = (validmat)? glslmat: false;
material->materialindex = mface->mat_nr;
- /* default value for being unset */
- layer_uv[0] = layer_uv[1] = -1;
-
// --------------------------------
if (validmat) {
+
+ // use vertex colors by explicitly setting
+ if (mat->mode &MA_VERTEXCOLP || glslmat)
+ type = 0;
+
// use lighting?
material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED;
@@ -552,7 +587,6 @@ static bool ConvertMaterial(
// cast shadows?
material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0;
MTex *mttmp = 0;
- numchan = getNumTexChannels(mat);
int valid_index = 0;
/* In Multitexture use the face texture if and only if
@@ -561,12 +595,9 @@ static bool ConvertMaterial(
bool facetex = false;
if (validface && mat->mode &MA_FACETEXTURE)
facetex = true;
-
- numchan = numchan>MAXTEX?MAXTEX:numchan;
- if (facetex && numchan == 0) numchan = 1;
// foreach MTex
- for (int i=0; i<numchan; i++) {
+ for (int i=0; i<MAXTEX; i++) {
// use face tex
if (i==0 && facetex ) {
@@ -582,19 +613,14 @@ static bool ConvertMaterial(
material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ALPHA )?USEALPHA:0;
material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ADD )?CALCALPHA:0;
- if (material->img[i]->flag & IMA_REFLECT)
+ if (material->img[i]->flag & IMA_REFLECT) {
material->mapping[i].mapping |= USEREFL;
- else
- {
- mttmp = getImageFromMaterial( mat, i );
- if (mttmp && mttmp->texco &TEXCO_UV)
- {
- STR_String uvName = mttmp->uvname;
-
- if (!uvName.IsEmpty())
- material->mapping[i].uvCoName = mttmp->uvname;
- else
- material->mapping[i].uvCoName = "";
+ }
+ else {
+ mttmp = getMTexFromMaterial(mat, i);
+ if (mttmp && (mttmp->texco & TEXCO_UV)) {
+ /* string may be "" but thats detected as empty after */
+ material->mapping[i].uvCoName = mttmp->uvname;
}
material->mapping[i].mapping |= USEUV;
}
@@ -608,9 +634,9 @@ static bool ConvertMaterial(
continue;
}
- mttmp = getImageFromMaterial( mat, i );
- if ( mttmp ) {
- if ( mttmp->tex ) {
+ mttmp = getMTexFromMaterial(mat, i);
+ if (mttmp) {
+ if (mttmp->tex) {
if ( mttmp->tex->type == TEX_IMAGE ) {
material->mtexname[i] = mttmp->tex->id.name;
material->img[i] = mttmp->tex->ima;
@@ -619,11 +645,10 @@ static bool ConvertMaterial(
material->texname[i] = material->img[i]->id.name;
material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
// -----------------------
- if ( mttmp->tex->imaflag &TEX_USEALPHA ) {
+ if (material->img[i] && (material->img[i]->flag & IMA_IGNORE_ALPHA) == 0)
material->flag[i] |= USEALPHA;
- }
// -----------------------
- else if ( mttmp->tex->imaflag &TEX_CALCALPHA ) {
+ if ( mttmp->tex->imaflag &TEX_CALCALPHA ) {
material->flag[i] |= CALCALPHA;
}
else if (mttmp->tex->flag &TEX_NEGALPHA) {
@@ -661,44 +686,44 @@ static bool ConvertMaterial(
#endif
/// --------------------------------
// mapping methods
- material->mapping[i].mapping |= ( mttmp->texco & TEXCO_REFL )?USEREFL:0;
-
- if (mttmp->texco & TEXCO_OBJECT) {
- material->mapping[i].mapping |= USEOBJ;
- if (mttmp->object)
- material->mapping[i].objconame = mttmp->object->id.name;
- }
- else if (mttmp->texco &TEXCO_REFL)
- material->mapping[i].mapping |= USEREFL;
- else if (mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB))
- material->mapping[i].mapping |= USEORCO;
- else if (mttmp->texco &TEXCO_UV)
- {
- STR_String uvName = mttmp->uvname;
-
- if (!uvName.IsEmpty())
+ if (mat->septex & (1 << i)) {
+ // If this texture slot isn't in use, set it to disabled to prevent multi-uv problems
+ material->mapping[i].mapping = DISABLE;
+ } else {
+ material->mapping[i].mapping |= ( mttmp->texco & TEXCO_REFL )?USEREFL:0;
+
+ if (mttmp->texco & TEXCO_OBJECT) {
+ material->mapping[i].mapping |= USEOBJ;
+ if (mttmp->object)
+ material->mapping[i].objconame = mttmp->object->id.name;
+ }
+ else if (mttmp->texco &TEXCO_REFL)
+ material->mapping[i].mapping |= USEREFL;
+ else if (mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB))
+ material->mapping[i].mapping |= USEORCO;
+ else if (mttmp->texco & TEXCO_UV) {
+ /* string may be "" but thats detected as empty after */
material->mapping[i].uvCoName = mttmp->uvname;
+ material->mapping[i].mapping |= USEUV;
+ }
+ else if (mttmp->texco &TEXCO_NORM)
+ material->mapping[i].mapping |= USENORM;
+ else if (mttmp->texco &TEXCO_TANGENT)
+ material->mapping[i].mapping |= USETANG;
else
- material->mapping[i].uvCoName = "";
- material->mapping[i].mapping |= USEUV;
+ material->mapping[i].mapping |= DISABLE;
+
+ material->mapping[i].scale[0] = mttmp->size[0];
+ material->mapping[i].scale[1] = mttmp->size[1];
+ material->mapping[i].scale[2] = mttmp->size[2];
+ material->mapping[i].offsets[0] = mttmp->ofs[0];
+ material->mapping[i].offsets[1] = mttmp->ofs[1];
+ material->mapping[i].offsets[2] = mttmp->ofs[2];
+
+ material->mapping[i].projplane[0] = mttmp->projx;
+ material->mapping[i].projplane[1] = mttmp->projy;
+ material->mapping[i].projplane[2] = mttmp->projz;
}
- else if (mttmp->texco &TEXCO_NORM)
- material->mapping[i].mapping |= USENORM;
- else if (mttmp->texco &TEXCO_TANGENT)
- material->mapping[i].mapping |= USETANG;
- else
- material->mapping[i].mapping |= DISABLE;
-
- material->mapping[i].scale[0] = mttmp->size[0];
- material->mapping[i].scale[1] = mttmp->size[1];
- material->mapping[i].scale[2] = mttmp->size[2];
- material->mapping[i].offsets[0] = mttmp->ofs[0];
- material->mapping[i].offsets[1] = mttmp->ofs[1];
- material->mapping[i].offsets[2] = mttmp->ofs[2];
-
- material->mapping[i].projplane[0] = mttmp->projx;
- material->mapping[i].projplane[1] = mttmp->projy;
- material->mapping[i].projplane[2] = mttmp->projz;
/// --------------------------------
switch (mttmp->blendtype) {
@@ -798,14 +823,11 @@ static bool ConvertMaterial(
material->ras_mode |= USE_LIGHT;
}
- const char *uvName = "", *uv2Name = "";
-
/* No material, what to do? let's see what is in the UV and set the material accordingly
* light and visible is always on */
if ( validface ) {
material->tile = tface->tile;
- uvName = tfaceName;
- }
+ }
else {
// nothing at all
material->alphablend = GEMAT_SOLID;
@@ -826,45 +848,19 @@ static bool ConvertMaterial(
material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0;
}
- // get uv sets
- if (validmat) {
- bool isFirstSet = true;
-
- // only two sets implemented, but any of the eight
- // sets can make up the two layers
- for (int vind = 0; vind<material->num_enabled; vind++) {
- BL_Mapping &map = material->mapping[vind];
+ // XXX The RGB values here were meant to be temporary storage for the conversion process,
+ // but fonts now make use of them too, so we leave them in for now.
+ unsigned int rgb[4];
+ GetRGB(type,mface,mmcol,mat,rgb);
- if (map.uvCoName.IsEmpty()) {
- isFirstSet = false;
- }
- else {
- for (int lay=0; lay<MAX_MTFACE; lay++) {
- MTF_localLayer& layer = layers[lay];
- if (layer.face == 0) break;
-
- if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) {
- if (isFirstSet) {
- layer_uv[0] = lay;
- isFirstSet = false;
- uvName = layer.name;
- }
- else if (strcmp(layer.name, uvName) != 0) {
- layer_uv[1] = lay;
- map.mapping |= USECUSTOMUV;
- uv2Name = layer.name;
- }
- }
- }
- }
- }
- }
-
- if (validmat && mmcol) { /* color is only for text */
- material->m_mcol = *(unsigned int *)mmcol;
+ // swap the material color, so MCol on bitmap font works
+ if (validmat && type==1 && (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->SetUVLayerName(uvName);
- material->SetUVLayerName2(uv2Name);
if (validmat)
material->matname =(mat->id.name);
@@ -879,8 +875,189 @@ static bool ConvertMaterial(
return true;
}
+static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace *tface, MCol *mcol, MTF_localLayer *layers, int lightlayer, unsigned int *rgb, MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT], const char *tfaceName, KX_Scene* scene, KX_BlenderSceneConverter *converter)
+{
+ RAS_IPolyMaterial* polymat = converter->FindCachedPolyMaterial(ma);
+ BL_Material* bl_mat = converter->FindCachedBlenderMaterial(ma);
+ KX_BlenderMaterial* kx_blmat = NULL;
+ KX_PolygonMaterial* kx_polymat = NULL;
+
+ if (converter->GetMaterials()) {
+ /* do Blender Multitexture and Blender GLSL materials */
+
+ /* first is the BL_Material */
+ if (!bl_mat)
+ {
+ bl_mat = new BL_Material();
+
+ ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
+ converter->GetGLSLMaterials());
+
+ converter->CacheBlenderMaterial(ma, bl_mat);
+ }
+
+
+ short type = (ma) ? ((ma->mode & MA_VERTEXCOLP || bl_mat->glslmat) ? 0 : 1) : 0;
+ GetRGB(type,mface,mcol,ma,rgb);
+
+ GetUVs(bl_mat, layers, mface, tface, uvs);
+
+ /* then the KX_BlenderMaterial */
+ if (polymat == NULL)
+ {
+ kx_blmat = new KX_BlenderMaterial();
+
+ kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer);
+ polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
+ converter->CachePolyMaterial(ma, polymat);
+ }
+ }
+ else {
+ /* do Texture Face materials */
+ Image* bima = (tface)? (Image*)tface->tpage: NULL;
+ STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
+
+ char alpha_blend=0;
+ short tile=0;
+ int tilexrep=4,tileyrep = 4;
+
+ /* set material properties - old TexFace */
+ if (ma) {
+ alpha_blend = ma->game.alpha_blend;
+ /* Commented out for now. If we ever get rid of
+ * "Texture Face/Singletexture" we can then think about it */
+
+ /* Texture Face mode ignores texture but requires "Face Textures to be True "*/
+ #if 0
+ if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
+ bima = NULL;
+ imastr = "";
+ alpha_blend = GEMAT_SOLID;
+ }
+ else {
+ alpha_blend = ma->game.alpha_blend;
+ }
+ #endif
+ }
+ /* check for tface tex to fallback on */
+ else {
+ if (bima) {
+ /* see if depth of the image is 32 */
+ if (BKE_image_has_alpha(bima))
+ alpha_blend = GEMAT_ALPHA;
+ else
+ alpha_blend = GEMAT_SOLID;
+ }
+ else {
+ alpha_blend = GEMAT_SOLID;
+ }
+ }
+
+ if (bima) {
+ tilexrep = bima->xrep;
+ tileyrep = bima->yrep;
+ }
+
+ /* set UV properties */
+ if (tface) {
+ uvs[0][0].setValue(tface->uv[0]);
+ uvs[1][0].setValue(tface->uv[1]);
+ uvs[2][0].setValue(tface->uv[2]);
+
+ if (mface->v4)
+ uvs[3][0].setValue(tface->uv[3]);
+
+ tile = tface->tile;
+ }
+ else {
+ /* no texfaces */
+ tile = 0;
+ }
+
+ /* get vertex colors */
+ if (mcol) {
+ /* we have vertex colors */
+ rgb[0] = KX_Mcol2uint_new(mcol[0]);
+ rgb[1] = KX_Mcol2uint_new(mcol[1]);
+ rgb[2] = KX_Mcol2uint_new(mcol[2]);
+
+ if (mface->v4)
+ rgb[3] = KX_Mcol2uint_new(mcol[3]);
+ }
+ else {
+ /* no vertex colors, take from material, otherwise white */
+ unsigned int color = 0xFFFFFFFFL;
+
+ if (ma)
+ {
+ union
+ {
+ unsigned char cp[4];
+ unsigned int integer;
+ } col_converter;
+
+ col_converter.cp[3] = (unsigned char) (ma->r*255.0);
+ col_converter.cp[2] = (unsigned char) (ma->g*255.0);
+ col_converter.cp[1] = (unsigned char) (ma->b*255.0);
+ col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
+
+ color = col_converter.integer;
+ }
+
+ rgb[0] = KX_rgbaint2uint_new(color);
+ rgb[1] = KX_rgbaint2uint_new(color);
+ rgb[2] = KX_rgbaint2uint_new(color);
+
+ if (mface->v4)
+ rgb[3] = KX_rgbaint2uint_new(color);
+ }
+
+ // only zsort alpha + add
+ bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
+ bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
+ bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
+
+ // don't need zort anymore, deal as if it it's alpha blend
+ if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
+
+ if (polymat == NULL)
+ {
+ kx_polymat = new KX_PolygonMaterial();
+ kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
+ tile, tilexrep, tileyrep,
+ alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
+ polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
+
+ if (ma) {
+ polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
+ polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
+ polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
+ }
+ else {
+ polymat->m_specular.setValue(0.0f,0.0f,0.0f);
+ polymat->m_shininess = 35.0;
+ }
+
+ converter->CachePolyMaterial(ma, polymat);
+ }
+ }
+
+ // see if a bucket was reused or a new one was created
+ // this way only one KX_BlenderMaterial object has to exist per bucket
+ bool bucketCreated;
+ RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
+ if (bucketCreated) {
+ // this is needed to free up memory afterwards
+ converter->RegisterPolyMaterial(polymat);
+ if (converter->GetMaterials())
+ converter->RegisterBlenderMaterial(bl_mat);
+ }
+
+ return bucket;
+}
+
/* blenderobj can be NULL, make sure its checked for */
-RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter)
+RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter, bool libloading)
{
RAS_MeshObject *meshobj;
int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object.
@@ -910,7 +1087,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
// Extract avaiable layers
MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
- int layer_uv[2]; /* store uv1, uv2 layers */
for (int lay=0; lay<MAX_MTFACE; lay++) {
layers[lay].face = 0;
layers[lay].name = "";
@@ -933,31 +1109,33 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
meshobj->SetName(mesh->id.name + 2);
meshobj->m_sharedvertex_map.resize(totvert);
- RAS_IPolyMaterial* polymat = NULL;
- STR_String imastr;
- // These pointers will hold persistent material structure during the conversion
- // to avoid countless allocation/deallocation of memory.
- BL_Material* bl_mat = NULL;
- KX_BlenderMaterial* kx_blmat = NULL;
- KX_PolygonMaterial* kx_polymat = NULL;
- for (int f=0;f<totface;f++,mface++)
- {
- Material* ma = 0;
- bool collider = true;
- MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
- MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
- unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
+ Material* ma = 0;
+ bool collider = true;
+ MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT];
+ unsigned int rgb[4] = {0};
- MT_Point3 pt0, pt1, pt2, pt3;
- MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
- MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
+ MT_Point3 pt[4];
+ MT_Vector3 no[4];
+ MT_Vector4 tan[4];
+ /* ugh, if there is a less annoying way to do this please use that.
+ * since these are converted from floats to floats, theres no real
+ * advantage to use MT_ types - campbell */
+ for (unsigned int i = 0; i < 4; i++) {
+ const float zero_vec[4] = {0.0f};
+ pt[i].setValue(zero_vec);
+ no[i].setValue(zero_vec);
+ tan[i].setValue(zero_vec);
+ }
+
+ for (int f=0;f<totface;f++,mface++)
+ {
/* get coordinates, normals and tangents */
- pt0.setValue(mvert[mface->v1].co);
- pt1.setValue(mvert[mface->v2].co);
- pt2.setValue(mvert[mface->v3].co);
- if (mface->v4) pt3.setValue(mvert[mface->v4].co);
+ pt[0].setValue(mvert[mface->v1].co);
+ pt[1].setValue(mvert[mface->v2].co);
+ pt[2].setValue(mvert[mface->v3].co);
+ if (mface->v4) pt[3].setValue(mvert[mface->v4].co);
if (mface->flag & ME_SMOOTH) {
float n0[3], n1[3], n2[3], n3[3];
@@ -965,13 +1143,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
normal_short_to_float_v3(n0, mvert[mface->v1].no);
normal_short_to_float_v3(n1, mvert[mface->v2].no);
normal_short_to_float_v3(n2, mvert[mface->v3].no);
- no0 = n0;
- no1 = n1;
- no2 = n2;
+ no[0] = n0;
+ no[1] = n1;
+ no[2] = n2;
if (mface->v4) {
normal_short_to_float_v3(n3, mvert[mface->v4].no);
- no3 = n3;
+ no[3] = n3;
}
}
else {
@@ -982,16 +1160,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
else
normal_tri_v3(fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
- no0 = no1 = no2 = no3 = MT_Vector3(fno);
+ no[0] = no[1] = no[2] = no[3] = MT_Vector3(fno);
}
if (tangent) {
- tan0 = tangent[f*4 + 0];
- tan1 = tangent[f*4 + 1];
- tan2 = tangent[f*4 + 2];
+ tan[0] = tangent[f*4 + 0];
+ tan[1] = tangent[f*4 + 1];
+ tan[2] = tangent[f*4 + 2];
if (mface->v4)
- tan3 = tangent[f*4 + 3];
+ tan[3] = tangent[f*4 + 3];
}
if (blenderobj)
ma = give_current_material(blenderobj, mface->mat_nr+1);
@@ -1007,171 +1185,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
bool visible = true;
bool twoside = false;
- if (converter->GetMaterials()) {
- const bool is_bl_mat_new = (bl_mat == NULL);
- //const bool is_kx_blmat_new = (kx_blmat == NULL);
- const bool glslmat = converter->GetGLSLMaterials();
- const bool use_mcol = ma ? (ma->mode & MA_VERTEXCOLP || glslmat) : true;
- /* do Blender Multitexture and Blender GLSL materials */
- MT_Point2 uv_1[4];
- MT_Point2 uv_2[4];
-
- /* first is the BL_Material */
- if (!bl_mat) {
- bl_mat = new BL_Material();
- }
-
- /* only */
- if (is_bl_mat_new || (bl_mat->material != ma)) {
- ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
- layers, layer_uv, glslmat);
- }
-
- /* vertex colors and uv's from the faces */
- GetRGB(use_mcol, mface, mcol, ma, rgb0, rgb1, rgb2, rgb3);
- GetUV(mface, tface, layers, layer_uv, uv_1, uv_2);
-
- uv0 = uv_1[0]; uv1 = uv_1[1];
- uv2 = uv_1[2]; uv3 = uv_1[3];
-
- uv20 = uv_2[0]; uv21 = uv_2[1];
- uv22 = uv_2[2]; uv23 = uv_2[3];
-
- /* then the KX_BlenderMaterial */
- if (kx_blmat == NULL)
- kx_blmat = new KX_BlenderMaterial();
-
- //if (is_kx_blmat_new || !kx_blmat->IsMaterial(bl_mat)) {
- kx_blmat->Initialize(scene, bl_mat, (ma ? &ma->game : NULL));
- //}
-
- polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
- }
- else {
- /* do Texture Face materials */
- Image* bima = (tface)? (Image*)tface->tpage: NULL;
- imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
-
- char alpha_blend=0;
- short tile=0;
- int tilexrep=4,tileyrep = 4;
-
- /* set material properties - old TexFace */
- if (ma) {
- alpha_blend = ma->game.alpha_blend;
- /* Commented out for now. If we ever get rid of
- * "Texture Face/Singletexture" we can then think about it */
-
- /* Texture Face mode ignores texture but requires "Face Textures to be True "*/
-#if 0
- if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
- bima = NULL;
- imastr = "";
- alpha_blend = GEMAT_SOLID;
- }
- else {
- alpha_blend = ma->game.alpha_blend;
- }
-#endif
- }
- /* check for tface tex to fallback on */
- else {
- if (bima) {
- /* see if depth of the image is 32 */
- if (BKE_image_has_alpha(bima))
- alpha_blend = GEMAT_ALPHA;
- else
- alpha_blend = GEMAT_SOLID;
- }
- else {
- alpha_blend = GEMAT_SOLID;
- }
- }
-
- if (bima) {
- tilexrep = bima->xrep;
- tileyrep = bima->yrep;
- }
-
- /* set UV properties */
- if (tface) {
- uv0.setValue(tface->uv[0]);
- uv1.setValue(tface->uv[1]);
- uv2.setValue(tface->uv[2]);
-
- if (mface->v4)
- uv3.setValue(tface->uv[3]);
-
- tile = tface->tile;
- }
- else {
- /* no texfaces */
- tile = 0;
- }
-
- /* get vertex colors */
- if (mcol) {
- /* we have vertex colors */
- rgb0 = KX_Mcol2uint_new(mcol[0]);
- rgb1 = KX_Mcol2uint_new(mcol[1]);
- rgb2 = KX_Mcol2uint_new(mcol[2]);
-
- if (mface->v4)
- rgb3 = KX_Mcol2uint_new(mcol[3]);
- }
- else {
- /* no vertex colors, take from material, otherwise white */
- unsigned int color = 0xFFFFFFFFL;
-
- if (ma)
- {
- union
- {
- unsigned char cp[4];
- unsigned int integer;
- } col_converter;
-
- col_converter.cp[3] = (unsigned char) (ma->r * 255.0f);
- col_converter.cp[2] = (unsigned char) (ma->g * 255.0f);
- col_converter.cp[1] = (unsigned char) (ma->b * 255.0f);
- col_converter.cp[0] = (unsigned char) (ma->alpha * 255.0f);
-
- color = col_converter.integer;
- }
-
- rgb0 = KX_rgbaint2uint_new(color);
- rgb1 = KX_rgbaint2uint_new(color);
- rgb2 = KX_rgbaint2uint_new(color);
-
- if (mface->v4)
- rgb3 = KX_rgbaint2uint_new(color);
- }
-
- // only zsort alpha + add
- bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
- bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
- bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
-
- // don't need zort anymore, deal as if it it's alpha blend
- if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
-
- if (kx_polymat == NULL)
- kx_polymat = new KX_PolygonMaterial();
- kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
- tile, tilexrep, tileyrep,
- alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
- polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
-
- if (ma) {
- polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
- polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
- polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
- }
- else {
- polymat->m_specular.setValue(0.0f,0.0f,0.0f);
- polymat->m_shininess = 35.0;
- }
- }
+ RAS_MaterialBucket* bucket = material_from_mesh(ma, mface, tface, mcol, layers, lightlayer, rgb, uvs, tfaceName, scene, converter);
// set render flags
if (ma)
@@ -1188,30 +1202,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
/* mark face as flat, so vertices are split */
bool flat = (mface->flag & ME_SMOOTH) == 0;
-
- // see if a bucket was reused or a new one was created
- // this way only one KX_BlenderMaterial object has to exist per bucket
- bool bucketCreated;
- RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
- if (bucketCreated) {
- // this is needed to free up memory afterwards
- converter->RegisterPolyMaterial(polymat);
- if (converter->GetMaterials()) {
- converter->RegisterBlenderMaterial(bl_mat);
- // the poly material has been stored in the bucket, next time we must create a new one
- bl_mat = NULL;
- kx_blmat = NULL;
- } else {
- // the poly material has been stored in the bucket, next time we must create a new one
- kx_polymat = NULL;
- }
- } else {
- // from now on, use the polygon material from the material bucket
- polymat = bucket->GetPolyMaterial();
- // keep the material pointers, they will be reused for next face
- }
-
+
int nverts = (mface->v4)? 4: 3;
+
RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
poly->SetVisible(visible);
@@ -1219,12 +1212,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
poly->SetTwoside(twoside);
//poly->SetEdgeCode(mface->edcode);
- meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
- meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
- meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
+ meshobj->AddVertex(poly,0,pt[0],uvs[0],tan[0],rgb[0],no[0],flat,mface->v1);
+ meshobj->AddVertex(poly,1,pt[1],uvs[1],tan[1],rgb[1],no[1],flat,mface->v2);
+ meshobj->AddVertex(poly,2,pt[2],uvs[2],tan[2],rgb[2],no[2],flat,mface->v3);
if (nverts==4)
- meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
+ meshobj->AddVertex(poly,3,pt[3],uvs[3],tan[3],rgb[3],no[3],flat,mface->v4);
}
if (tface)
@@ -1246,22 +1239,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
meshobj->EndConversion();
// pre calculate texture generation
- for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
- mit != meshobj->GetLastMaterial(); ++ mit) {
- mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer);
+ // However, we want to delay this if we're libloading so we can make sure we have the right scene.
+ if (!libloading) {
+ for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
+ mit != meshobj->GetLastMaterial(); ++ mit) {
+ mit->m_bucket->GetPolyMaterial()->OnConstruction();
+ }
}
if (layers)
delete []layers;
dm->release(dm);
- // cleanup material
- if (bl_mat)
- delete bl_mat;
- if (kx_blmat)
- delete kx_blmat;
- if (kx_polymat)
- delete kx_polymat;
+
converter->RegisterGameMesh(meshobj, mesh);
return meshobj;
}
@@ -1274,7 +1264,7 @@ static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blender
MT_assert(materialProps && "Create physics material properties failed");
- Material* blendermat = give_current_material(blenderobject, 0);
+ Material* blendermat = give_current_material(blenderobject, 1);
if (blendermat)
{
@@ -1358,7 +1348,9 @@ static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
float radius=0.0f, vert_radius, *co;
int a;
- if (me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
+ if (me->bb==0) {
+ me->bb = BKE_boundbox_alloc_unit();
+ }
bb= me->bb;
INIT_MINMAX(min, max);
@@ -1535,7 +1527,7 @@ static void BL_CreateGraphicObjectNew(KX_GameObject* gameobj,
{
switch (physics_engine)
{
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
case UseBullet:
{
CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
@@ -1838,7 +1830,7 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
switch (physics_engine)
{
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
case UseBullet:
KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, &objprop);
break;
@@ -1921,7 +1913,8 @@ static KX_GameObject *gameobject_from_blenderobject(
Object *ob,
KX_Scene *kxscene,
RAS_IRenderTools *rendertools,
- KX_BlenderSceneConverter *converter)
+ KX_BlenderSceneConverter *converter,
+ bool libloading)
{
KX_GameObject *gameobj = NULL;
Scene *blenderscene = kxscene->GetBlenderScene();
@@ -1958,7 +1951,7 @@ static KX_GameObject *gameobject_from_blenderobject(
Mesh* mesh = static_cast<Mesh*>(ob->data);
float center[3], extents[3];
float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
- RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter);
+ RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter, libloading);
// needed for python scripting
kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
@@ -1981,6 +1974,22 @@ static KX_GameObject *gameobject_from_blenderobject(
((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
gameobj->SetOccluder((ob->gameflag & OB_OCCLUDER) != 0, false);
+
+ // we only want obcolor used if there is a material in the mesh
+ // that requires it
+ Material *mat= NULL;
+ bool bUseObjectColor=false;
+
+ for (int i=0;i<mesh->totcol;i++) {
+ mat=mesh->mat[i];
+ if (!mat) break;
+ if ((mat->shade_flag & MA_OBCOLOR)) {
+ bUseObjectColor = true;
+ break;
+ }
+ }
+ if (bUseObjectColor)
+ gameobj->SetObjectColor(ob->col);
// two options exists for deform: shape keys and armature
// only support relative shape key
@@ -1988,7 +1997,7 @@ static KX_GameObject *gameobject_from_blenderobject(
bool bHasDvert = mesh->dvert != NULL && ob->defbase.first;
bool bHasArmature = (BL_ModifierDeformer::HasArmatureDeformer(ob) && ob->parent && ob->parent->type == OB_ARMATURE && bHasDvert);
bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(ob);
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
bool bHasSoftBody = (!ob->parent && (ob->gameflag & OB_SOFT_BODY));
#endif
if (bHasModifier) {
@@ -2015,7 +2024,7 @@ static KX_GameObject *gameobject_from_blenderobject(
BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
ob, meshobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
} else if (bHasSoftBody) {
KX_SoftBodyDeformer *dcont = new KX_SoftBodyDeformer(meshobj, (BL_DeformableGameObject*)gameobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
@@ -2187,26 +2196,37 @@ static void bl_ConvertBlenderObject_Single(
blenderobject->loc[1]+blenderobject->dloc[1],
blenderobject->loc[2]+blenderobject->dloc[2]
);
- MT_Vector3 eulxyz(blenderobject->rot);
+
+ MT_Matrix3x3 rotation;
+ float rotmat[3][3];
+ BKE_object_rot_to_mat3(blenderobject, rotmat, FALSE);
+ rotation.setValue3x3((float*)rotmat);
+
MT_Vector3 scale(blenderobject->size);
+
if (converter->addInitFromFrame) {//rcruiz
- float eulxyzPrev[3];
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]
);
- eulxyzPrev[0]=blenderobject->rot[0];
- eulxyzPrev[1]=blenderobject->rot[1];
- eulxyzPrev[2]=blenderobject->rot[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=eulxyz-eulxyzPrev;
+ 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;
@@ -2214,12 +2234,10 @@ static void bl_ConvertBlenderObject_Single(
}
gameobj->NodeSetLocalPosition(pos);
- gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
+ gameobj->NodeSetLocalOrientation(rotation);
gameobj->NodeSetLocalScale(scale);
gameobj->NodeUpdateGS(0);
- BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
-
sumolist->Add(gameobj->AddRef());
BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
@@ -2321,7 +2339,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
RAS_IRenderTools* rendertools,
RAS_ICanvas* canvas,
KX_BlenderSceneConverter* converter,
- bool alwaysUseExpandFraming
+ bool alwaysUseExpandFraming,
+ bool libloading
)
{
@@ -2355,6 +2374,10 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
set<Object*> allblobj; // all objects converted
set<Object*> groupobj; // objects from groups (never in active layer)
+ // This is bad, but we use this to make sure the first time this is called
+ // is not in a separate thread.
+ BL_Texture::GetMaxUnits();
+
if (alwaysUseExpandFraming) {
frame_type = RAS_FrameSettings::e_frame_extend;
aspect_width = canvas->GetWidth();
@@ -2431,7 +2454,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
base->object,
kxscene,
rendertools,
- converter);
+ converter,
+ libloading);
bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
bool addobj=true;
@@ -2490,7 +2514,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
blenderobject,
kxscene,
rendertools,
- converter);
+ converter,
+ libloading);
// this code is copied from above except that
// object from groups are never in active layer
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h
index 2a7efaac898..f3a680929fb 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.h
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.h
@@ -38,7 +38,7 @@
#include "KX_PhysicsEngineEnums.h"
#include "SCA_IInputDevice.h"
-class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
+class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter, bool libloading);
void BL_ConvertBlenderObjects(struct Main* maggie,
class KX_Scene* kxscene,
@@ -47,7 +47,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas,
class KX_BlenderSceneConverter* sceneconverter,
- bool alwaysUseExpandFraming
+ bool alwaysUseExpandFraming,
+ bool libloading=false
);
SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code);
diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt
index e9dd97f3821..f18646c1de0 100644
--- a/source/gameengine/Converter/CMakeLists.txt
+++ b/source/gameengine/Converter/CMakeLists.txt
@@ -82,7 +82,7 @@ set(SRC
KX_ConvertControllers.cpp
KX_ConvertProperties.cpp
KX_ConvertSensors.cpp
- KX_IpoConvert.cpp
+ KX_LibLoadStatus.cpp
KX_SoftBodyDeformer.cpp
BL_ActionActuator.h
@@ -104,15 +104,15 @@ set(SRC
KX_ConvertControllers.h
KX_ConvertProperties.h
KX_ConvertSensors.h
- KX_IpoConvert.h
+ KX_LibLoadStatus.h
KX_SoftBodyDeformer.h
)
if(WITH_BULLET)
list(APPEND INC_SYS
- ../../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
)
- add_definitions(-DUSE_BULLET)
+ add_definitions(-DWITH_BULLET)
endif()
if(WITH_AUDASPACE)
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index d1684db0f5a..cd5dec4669d 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -55,11 +55,12 @@
#include "KX_ConvertPhysicsObject.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "CcdPhysicsEnvironment.h"
#endif
#include "KX_BlenderSceneConverter.h"
+#include "KX_LibLoadStatus.h"
#include "KX_BlenderScalarInterpolator.h"
#include "BL_BlenderDataConversion.h"
#include "BlenderWorldInfo.h"
@@ -113,6 +114,14 @@ extern "C" {
#include "../../blender/blenlib/BLI_linklist.h"
}
+#include <pthread.h>
+
+/* This is used to avoid including pthread.h in KX_BlenderSceneConverter.h */
+typedef struct ThreadInfo {
+ vector<pthread_t> threads;
+ pthread_mutex_t merge_lock;
+} ThreadInfo;
+
KX_BlenderSceneConverter::KX_BlenderSceneConverter(
struct Main* maggie,
class KX_KetsjiEngine* engine
@@ -122,10 +131,13 @@ KX_BlenderSceneConverter::KX_BlenderSceneConverter(
m_ketsjiEngine(engine),
m_alwaysUseExpandFraming(false),
m_usemat(false),
- m_useglslmat(false)
+ m_useglslmat(false),
+ m_use_mat_cache(true)
{
tag_main(maggie, 0); /* avoid re-tagging later on */
m_newfilename = "";
+ m_threadinfo = new ThreadInfo();
+ pthread_mutex_init(&m_threadinfo->merge_lock, NULL);
}
@@ -135,6 +147,16 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
int i;
// delete sumoshapes
+ if (m_threadinfo) {
+ vector<pthread_t>::iterator pit = m_threadinfo->threads.begin();
+ while (pit != m_threadinfo->threads.end()) {
+ pthread_join((*pit), NULL);
+ pit++;
+ }
+
+ pthread_mutex_destroy(&m_threadinfo->merge_lock);
+ delete m_threadinfo;
+ }
int numAdtLists = m_map_blender_to_gameAdtList.size();
for (i=0; i<numAdtLists; i++) {
@@ -151,6 +173,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
while (itp != m_polymaterials.end()) {
+ m_polymat_cache.erase((*itp).second->GetBlenderMaterial());
delete (*itp).second;
itp++;
}
@@ -158,6 +181,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
// delete after RAS_IPolyMaterial
vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
while (itmat != m_materials.end()) {
+ m_mat_cache.erase((*itmat).second->material);
delete (*itmat).second;
itmat++;
}
@@ -169,7 +193,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
itm++;
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
KX_ClearBulletSharedShapes();
#endif
@@ -230,7 +254,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
}
#include "KX_PythonInit.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "LinearMath/btIDebugDraw.h"
@@ -286,7 +310,8 @@ struct BlenderDebugDraw : public btIDebugDraw
void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
class RAS_IRenderTools* rendertools,
- class RAS_ICanvas* canvas)
+ class RAS_ICanvas* canvas,
+ bool libloading)
{
//find out which physics engine
Scene *blenderscene = destinationscene->GetBlenderScene();
@@ -296,7 +321,10 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
// hook for registration function during conversion.
m_currentScene = destinationscene;
destinationscene->SetSceneConverter(this);
- SG_SetActiveStage(SG_STAGE_CONVERTER);
+
+ // This doesn't really seem to do anything except cause potential issues
+ // when doing threaded conversion, so it's disabled for now.
+ // SG_SetActiveStage(SG_STAGE_CONVERTER);
if (blenderscene)
{
@@ -320,7 +348,7 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
switch (physics_engine)
{
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
case UseBullet:
{
CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
@@ -355,7 +383,8 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
rendertools,
canvas,
this,
- m_alwaysUseExpandFraming
+ m_alwaysUseExpandFraming,
+ libloading
);
//These lookup are not needed during game
@@ -369,7 +398,7 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
//that would result from this is fixed in RemoveScene()
m_map_mesh_to_gamemesh.clear();
-#ifndef USE_BULLET
+#ifndef WITH_BULLET
/* quiet compiler warning */
(void)useDbvtCulling;
#endif
@@ -406,6 +435,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
size = m_polymaterials.size();
for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
if ((*polymit).first == scene) {
+ m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
delete (*polymit).second;
*polymit = m_polymaterials.back();
m_polymaterials.pop_back();
@@ -420,6 +450,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
size = m_materials.size();
for (i=0, matit=m_materials.begin(); i<size; ) {
if ((*matit).first == scene) {
+ m_mat_cache.erase((*matit).second->material);
delete (*matit).second;
*matit = m_materials.back();
m_materials.pop_back();
@@ -458,6 +489,11 @@ void KX_BlenderSceneConverter::SetGLSLMaterials(bool val)
m_useglslmat = val;
}
+void KX_BlenderSceneConverter::SetCacheMaterials(bool val)
+{
+ m_use_mat_cache = val;
+}
+
bool KX_BlenderSceneConverter::GetMaterials()
{
return m_usemat;
@@ -468,8 +504,19 @@ bool KX_BlenderSceneConverter::GetGLSLMaterials()
return m_useglslmat;
}
+bool KX_BlenderSceneConverter::GetCacheMaterials()
+{
+ return m_use_mat_cache;
+}
+
void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
{
+ // First make sure we don't register the material twice
+ vector<pair<KX_Scene*,BL_Material*> >::iterator it;
+ for (it = m_materials.begin(); it != m_materials.end(); ++it)
+ if (it->second == mat)
+ return;
+
m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
}
@@ -540,19 +587,39 @@ RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
} else {
return NULL;
}
-}
-
-
-
-
-
+}
void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
{
+ // First make sure we don't register the material twice
+ vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator it;
+ for (it = m_polymaterials.begin(); it != m_polymaterials.end(); ++it)
+ if (it->second == polymat)
+ return;
m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
}
+void KX_BlenderSceneConverter::CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat)
+{
+ if (m_use_mat_cache)
+ m_polymat_cache[mat] = polymat;
+}
+
+RAS_IPolyMaterial *KX_BlenderSceneConverter::FindCachedPolyMaterial(struct Material *mat)
+{
+ return (m_use_mat_cache) ? m_polymat_cache[mat] : NULL;
+}
+void KX_BlenderSceneConverter::CacheBlenderMaterial(struct Material *mat, BL_Material *blmat)
+{
+ if (m_use_mat_cache)
+ m_mat_cache[mat] = blmat;
+}
+
+BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(struct Material *mat)
+{
+ return (m_use_mat_cache) ? m_mat_cache[mat] : NULL;
+}
void KX_BlenderSceneConverter::RegisterInterpolatorList(
BL_InterpolatorList *actList,
@@ -915,7 +982,67 @@ Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
return NULL;
}
-bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
+void KX_BlenderSceneConverter::MergeAsyncLoads()
+{
+ vector<KX_Scene*> *merge_scenes;
+
+ vector<KX_LibLoadStatus*>::iterator mit;
+ vector<KX_Scene*>::iterator sit;
+
+ pthread_mutex_lock(&m_threadinfo->merge_lock);
+
+ for (mit=m_mergequeue.begin(); mit!=m_mergequeue.end(); ++mit) {
+ merge_scenes = (vector<KX_Scene*>*)(*mit)->GetData();
+
+ for (sit=merge_scenes->begin(); sit!=merge_scenes->end(); ++sit) {
+ (*mit)->GetMergeScene()->MergeScene(*sit);
+ delete (*sit);
+ }
+
+
+ delete merge_scenes;
+ (*mit)->SetData(NULL);
+
+ (*mit)->Finish();
+ }
+
+ m_mergequeue.clear();
+
+ pthread_mutex_unlock(&m_threadinfo->merge_lock);
+}
+
+void KX_BlenderSceneConverter::AddScenesToMergeQueue(KX_LibLoadStatus *status)
+{
+ pthread_mutex_lock(&m_threadinfo->merge_lock);
+ m_mergequeue.push_back(status);
+ pthread_mutex_unlock(&m_threadinfo->merge_lock);
+}
+
+static void *async_convert(void *ptr)
+{
+ KX_Scene *new_scene = NULL;
+ KX_LibLoadStatus *status = (KX_LibLoadStatus*)ptr;
+ vector<Scene*> *scenes = (vector<Scene*>*)status->GetData();
+ vector<KX_Scene*> *merge_scenes = new vector<KX_Scene*>(); // Deleted in MergeAsyncLoads
+
+ for (unsigned int i=0; i<scenes->size(); ++i) {
+ new_scene = status->GetEngine()->CreateScene((*scenes)[i], true);
+
+ if (new_scene)
+ merge_scenes->push_back(new_scene);
+
+ status->AddProgress((1.f/scenes->size())*0.9f); // We'll call conversion 90% and merging 10% for now
+ }
+
+ delete scenes;
+ status->SetData(merge_scenes);
+
+ status->GetConverter()->AddScenesToMergeQueue(status);
+
+ return NULL;
+}
+
+KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
BlendHandle *bpy_openlib = BLO_blendhandle_from_memory(data, length);
@@ -923,7 +1050,7 @@ bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const
return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options);
}
-bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
+KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
BlendHandle *bpy_openlib = BLO_blendhandle_from_file((char *)path, NULL);
@@ -955,7 +1082,7 @@ static void load_datablocks(Main *main_newlib, BlendHandle *bpy_openlib, const c
BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag);
}
-bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
+KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
Main *main_newlib; /* stored as a dynamic 'main' until we free it */
const int idcode = BKE_idcode_from_name(group);
@@ -964,25 +1091,27 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
// TIMEIT_START(bge_link_blend_file);
+ KX_LibLoadStatus *status;
+
/* only scene and mesh supported right now */
if (idcode!=ID_SCE && idcode!=ID_ME &&idcode!=ID_AC) {
snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group);
*err_str= err_local;
BLO_blendhandle_close(bpy_openlib);
- return false;
+ return NULL;
}
if (GetMainDynamicPath(path)) {
snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path);
*err_str= err_local;
BLO_blendhandle_close(bpy_openlib);
- return false;
+ return NULL;
}
if (bpy_openlib==NULL) {
snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path);
*err_str= err_local;
- return false;
+ return NULL;
}
main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
@@ -1009,6 +1138,8 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
strncpy(main_newlib->name, path, sizeof(main_newlib->name));
+ status = new KX_LibLoadStatus(this, m_ketsjiEngine, scene_merge, path);
+
if (idcode==ID_ME) {
/* Convert all new meshes into BGE meshes */
ID* mesh;
@@ -1016,7 +1147,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) {
if (options & LIB_LOAD_VERBOSE)
printf("MeshName: %s\n", mesh->name+2);
- RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this);
+ RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this, false); // For now only use the libloading option for scenes, which need to handle materials/shaders
scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
}
}
@@ -1033,16 +1164,30 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
else if (idcode==ID_SCE) {
/* Merge all new linked in scene into the existing one */
ID *scene;
+ // scenes gets deleted by the thread when it's done using it (look in async_convert())
+ vector<Scene*> *scenes = (options & LIB_LOAD_ASYNC) ? new vector<Scene*>() : NULL;
+
for (scene= (ID *)main_newlib->scene.first; scene; scene= (ID *)scene->next ) {
if (options & LIB_LOAD_VERBOSE)
printf("SceneName: %s\n", scene->name+2);
- /* merge into the base scene */
- KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene);
- scene_merge->MergeScene(other);
+ if (options & LIB_LOAD_ASYNC) {
+ scenes->push_back((Scene*)scene);
+ } else {
+ /* merge into the base scene */
+ KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene, true);
+ scene_merge->MergeScene(other);
- // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
- delete other;
+ // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
+ delete other;
+ }
+ }
+
+ if (options & LIB_LOAD_ASYNC) {
+ pthread_t id;
+ status->SetData(scenes);
+ pthread_create(&id, NULL, &async_convert, (void*)status);
+ m_threadinfo->threads.push_back(id);
}
#ifdef WITH_PYTHON
@@ -1063,9 +1208,14 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
}
}
+ if (!(options & LIB_LOAD_ASYNC))
+ status->Finish();
+
+
// TIMEIT_END(bge_link_blend_file);
- return true;
+ m_status_map[main_newlib->name] = status;
+ return status;
}
/* Note m_map_*** are all ok and don't need to be freed
@@ -1302,7 +1452,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
}
if (IS_TAGGED(bmat)) {
-
+ m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
delete (*polymit).second;
*polymit = m_polymaterials.back();
m_polymaterials.pop_back();
@@ -1320,6 +1470,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
for (i=0, matit=m_materials.begin(); i<size; ) {
BL_Material *mat= (*matit).second;
if (IS_TAGGED(mat->material)) {
+ m_mat_cache.erase((*matit).second->material);
delete (*matit).second;
*matit = m_materials.back();
m_materials.pop_back();
@@ -1351,6 +1502,9 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
removeImportMain(maggie);
#endif
+ delete m_status_map[maggie->name];
+ m_status_map.erase(maggie->name);
+
free_main(maggie);
return true;
@@ -1469,7 +1623,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
}
}
- RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this);
+ RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false);
kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
return meshobj;
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
index 34a1117a0eb..06dac1707c5 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.h
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -39,6 +39,8 @@
#include "KX_ISceneConverter.h"
#include "KX_IpoConvert.h"
+#include <map>
+
using namespace std;
class KX_WorldInfo;
@@ -50,6 +52,7 @@ class BL_InterpolatorList;
class BL_Material;
struct Main;
struct Scene;
+struct ThreadInfo;
class KX_BlenderSceneConverter : public KX_ISceneConverter
{
@@ -58,6 +61,17 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
vector<pair<KX_Scene*,RAS_IPolyMaterial*> > m_polymaterials;
vector<pair<KX_Scene*,RAS_MeshObject*> > m_meshobjects;
vector<pair<KX_Scene*,BL_Material *> > m_materials;
+
+ vector<class KX_LibLoadStatus*> m_mergequeue;
+ ThreadInfo *m_threadinfo;
+
+ // Cached material conversions
+ map<struct Material*, BL_Material*> m_mat_cache;
+ map<struct Material*, RAS_IPolyMaterial*> m_polymat_cache;
+
+ // Saved KX_LibLoadStatus objects
+ map<char *, class KX_LibLoadStatus*> m_status_map;
+
// Should also have a list of collision shapes.
// For the time being this is held in KX_Scene::m_shapes
@@ -77,6 +91,7 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
bool m_alwaysUseExpandFraming;
bool m_usemat;
bool m_useglslmat;
+ bool m_use_mat_cache;
public:
KX_BlenderSceneConverter(
@@ -93,7 +108,8 @@ public:
virtual void ConvertScene(
class KX_Scene* destinationscene,
class RAS_IRenderTools* rendertools,
- class RAS_ICanvas* canvas
+ class RAS_ICanvas* canvas,
+ bool libloading=false
);
virtual void RemoveScene(class KX_Scene *scene);
@@ -110,8 +126,12 @@ public:
RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/);
void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
+ void CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat);
+ RAS_IPolyMaterial *FindCachedPolyMaterial(struct Material *mat);
void RegisterBlenderMaterial(BL_Material *mat);
+ void CacheBlenderMaterial(struct Material *mat, BL_Material *blmat);
+ BL_Material *FindCachedBlenderMaterial(struct Material *mat);
void RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act);
BL_InterpolatorList *FindInterpolatorList(struct bAction *for_act);
@@ -141,19 +161,26 @@ public:
virtual void SetGLSLMaterials(bool val);
virtual bool GetGLSLMaterials();
+ // cache materials during conversion
+ virtual void SetCacheMaterials(bool val);
+ virtual bool GetCacheMaterials();
+
struct Scene* GetBlenderSceneForName(const STR_String& name);
// struct Main* GetMain() { return m_maggie; }
struct Main* GetMainDynamicPath(const char *path);
vector<struct Main*> &GetMainDynamic();
- bool LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
- bool LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
- bool LinkBlendFile(struct BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
+ class KX_LibLoadStatus *LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
+ class KX_LibLoadStatus *LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
+ class KX_LibLoadStatus *LinkBlendFile(struct BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
bool MergeScene(KX_Scene *to, KX_Scene *from);
RAS_MeshObject *ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name);
bool FreeBlendFile(struct Main *maggie);
bool FreeBlendFile(const char *path);
+
+ virtual void MergeAsyncLoads();
+ void AddScenesToMergeQueue(class KX_LibLoadStatus *status);
void PrintStats() {
printf("BGE STATS!\n");
@@ -183,6 +210,7 @@ public:
LIB_LOAD_LOAD_ACTIONS = 1,
LIB_LOAD_VERBOSE = 2,
LIB_LOAD_LOAD_SCRIPTS = 4,
+ LIB_LOAD_ASYNC = 8,
};
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 06399642edd..05da38dd1af 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -180,7 +180,10 @@ void BL_ConvertActuators(const char* maggiename,
bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
bitLocalFlag.ServoControl = bool(obact->type == ACT_OBJECT_SERVO);
+ bitLocalFlag.CharacterMotion = bool(obact->type == ACT_OBJECT_CHARACTER);
+ bitLocalFlag.CharacterJump = bool((obact->flag & ACT_CHAR_JUMP)!=0);
bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
+ bitLocalFlag.AddOrSetCharLoc = bool((obact->flag & ACT_ADD_CHAR_LOC)!=0);
if (obact->reference && bitLocalFlag.ServoControl)
{
obref = converter->FindGameObject(obact->reference);
@@ -523,7 +526,8 @@ void BL_ConvertActuators(const char* maggiename,
editobact->me,
blenderobject,
scene,
- converter
+ converter,
+ false
);
KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator(
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index 769abd01ce0..5d3d0f33bec 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -157,7 +157,7 @@ void BL_ConvertControllers(
SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
gamecontroller = pyctrl;
#ifdef WITH_PYTHON
-
+ PyGILState_STATE gstate = PyGILState_Ensure();
pyctrl->SetNamespace(converter->GetPyNamespace());
if (pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
@@ -186,6 +186,7 @@ void BL_ConvertControllers(
}
}
+ PyGILState_Release(gstate);
#endif // WITH_PYTHON
break;
@@ -218,6 +219,7 @@ void BL_ConvertControllers(
converter->RegisterGameController(gamecontroller, bcontr);
#ifdef WITH_PYTHON
+ PyGILState_STATE gstate = PyGILState_Ensure();
if (bcontr->type==CONT_PYTHON) {
SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
/* not strictly needed but gives syntax errors early on and
@@ -232,6 +234,8 @@ void BL_ConvertControllers(
// pyctrl->Import();
}
}
+
+ PyGILState_Release(gstate);
#endif // WITH_PYTHON
//done with gamecontroller
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 538f9e2c833..acaf911c26e 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -260,14 +260,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
// this sumoObject is not deleted by a gameobj, so delete it ourself
// later (memleaks)!
float radius = blendernearsensor->dist;
- PHY__Vector3 pos;
const MT_Vector3& wpos = gameobj->NodeGetWorldPosition();
- pos[0] = (float)wpos[0];
- pos[1] = (float)wpos[1];
- pos[2] = (float)wpos[2];
- pos[3] = 0.f;
bool bFindMaterial = false;
- PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos);
+ PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,wpos);
//will be done in KX_TouchEventManager::RegisterSensor()
//if (isInActiveLayer)
diff --git a/source/gameengine/Converter/KX_LibLoadStatus.cpp b/source/gameengine/Converter/KX_LibLoadStatus.cpp
new file mode 100644
index 00000000000..2a38e062f89
--- /dev/null
+++ b/source/gameengine/Converter/KX_LibLoadStatus.cpp
@@ -0,0 +1,252 @@
+/*
+ * ***** 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): Mitchell Stokes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file KX_LibLoadStatus.cpp
+ * \ingroup bgeconv
+ */
+
+#include "KX_LibLoadStatus.h"
+#include "PIL_time.h"
+
+KX_LibLoadStatus::KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter,
+ class KX_KetsjiEngine* kx_engine,
+ class KX_Scene* merge_scene,
+ const char *path) :
+ m_converter(kx_converter),
+ m_engine(kx_engine),
+ m_mergescene(merge_scene),
+ m_data(NULL),
+ m_libname(path),
+ m_progress(0.f)
+#ifdef WITH_PYTHON
+ ,
+ m_finish_cb(NULL),
+ m_progress_cb(NULL)
+#endif
+{
+ m_endtime = m_starttime = PIL_check_seconds_timer();
+}
+
+void KX_LibLoadStatus::Finish()
+{
+ m_progress = 1.f;
+ m_endtime = PIL_check_seconds_timer();
+
+ RunFinishCallback();
+ RunProgressCallback();
+}
+
+void KX_LibLoadStatus::RunFinishCallback()
+{
+#ifdef WITH_PYTHON
+ if (m_finish_cb) {
+ PyObject* args = Py_BuildValue("(O)", GetProxy());
+
+ if (!PyObject_Call(m_finish_cb, args, NULL)) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ Py_DECREF(args);
+ }
+#endif
+}
+
+void KX_LibLoadStatus::RunProgressCallback()
+{
+// Progess callbacks are causing threading problems with Python, so they're disabled for now
+#if 0
+#ifdef WITH_PYTHON
+ if (m_progress_cb) {
+ //PyGILState_STATE gstate = PyGILState_Ensure();
+ PyObject* args = Py_BuildValue("(O)", GetProxy());
+
+ if (!PyObject_Call(m_progress_cb, args, NULL)) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ Py_DECREF(args);
+ //PyGILState_Release(gstate);
+ }
+#endif
+#endif
+}
+
+class KX_BlenderSceneConverter *KX_LibLoadStatus::GetConverter()
+{
+ return m_converter;
+}
+
+class KX_KetsjiEngine *KX_LibLoadStatus::GetEngine()
+{
+ return m_engine;
+}
+
+class KX_Scene *KX_LibLoadStatus::GetMergeScene()
+{
+ return m_mergescene;
+}
+
+void KX_LibLoadStatus::SetLibName(const char *name)
+{
+ m_libname = name;
+}
+
+const char *KX_LibLoadStatus::GetLibName()
+{
+ return m_libname;
+}
+
+void KX_LibLoadStatus::SetData(void *data)
+{
+ m_data = data;
+}
+
+void *KX_LibLoadStatus::GetData()
+{
+ return m_data;
+}
+
+void KX_LibLoadStatus::SetProgress(float progress)
+{
+ m_progress = progress;
+ RunProgressCallback();
+}
+
+float KX_LibLoadStatus::GetProgress()
+{
+ return m_progress;
+}
+
+void KX_LibLoadStatus::AddProgress(float progress)
+{
+ m_progress += progress;
+ RunProgressCallback();
+}
+
+#ifdef WITH_PYTHON
+
+PyMethodDef KX_LibLoadStatus::Methods[] =
+{
+ {NULL} //Sentinel
+};
+
+PyAttributeDef KX_LibLoadStatus::Attributes[] = {
+ KX_PYATTRIBUTE_RW_FUNCTION("onFinish", KX_LibLoadStatus, pyattr_get_onfinish, pyattr_set_onfinish),
+ // KX_PYATTRIBUTE_RW_FUNCTION("onProgress", KX_LibLoadStatus, pyattr_get_onprogress, pyattr_set_onprogress),
+ KX_PYATTRIBUTE_FLOAT_RO("progress", KX_LibLoadStatus, m_progress),
+ KX_PYATTRIBUTE_STRING_RO("libraryName", KX_LibLoadStatus, m_libname),
+ KX_PYATTRIBUTE_RO_FUNCTION("timeTaken", KX_LibLoadStatus, pyattr_get_timetaken),
+ { NULL } //Sentinel
+};
+
+PyTypeObject KX_LibLoadStatus::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "KX_LibLoadStatus",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,0,0,0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &PyObjectPlus::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+
+PyObject* KX_LibLoadStatus::pyattr_get_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (self->m_finish_cb) {
+ Py_INCREF(self->m_finish_cb);
+ return self->m_finish_cb;
+ }
+
+ Py_RETURN_NONE;
+}
+
+int KX_LibLoadStatus::pyattr_set_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (!PyCallable_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "KX_LibLoadStatus.onFinished requires a callable object");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (self->m_finish_cb)
+ Py_DECREF(self->m_finish_cb);
+
+ Py_INCREF(value);
+ self->m_finish_cb = value;
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject* KX_LibLoadStatus::pyattr_get_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (self->m_progress_cb) {
+ Py_INCREF(self->m_progress_cb);
+ return self->m_progress_cb;
+ }
+
+ Py_RETURN_NONE;
+}
+
+int KX_LibLoadStatus::pyattr_set_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (!PyCallable_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "KX_LibLoadStatus.onProgress requires a callable object");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (self->m_progress_cb)
+ Py_DECREF(self->m_progress_cb);
+
+ Py_INCREF(value);
+ self->m_progress_cb = value;
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject* KX_LibLoadStatus::pyattr_get_timetaken(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ return PyFloat_FromDouble(self->m_endtime - self->m_starttime);
+}
+#endif // WITH_PYTHON
diff --git a/source/gameengine/Converter/KX_LibLoadStatus.h b/source/gameengine/Converter/KX_LibLoadStatus.h
new file mode 100644
index 00000000000..3da7329213b
--- /dev/null
+++ b/source/gameengine/Converter/KX_LibLoadStatus.h
@@ -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.
+ *
+ * Contributor(s): Mitchell Stokes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file KX_LibLoadStatus.h
+ * \ingroup bgeconv
+ */
+
+#ifndef __KX_LIBLOADSTATUS_H__
+#define __KX_LIBLOADSTATUS_H__
+
+#include "PyObjectPlus.h"
+
+class KX_LibLoadStatus : public PyObjectPlus
+{
+ Py_Header
+private:
+ class KX_BlenderSceneConverter* m_converter;
+ class KX_KetsjiEngine* m_engine;
+ class KX_Scene* m_mergescene;
+ void* m_data;
+ STR_String m_libname;
+
+ float m_progress;
+ double m_starttime;
+ double m_endtime;
+
+#ifdef WITH_PYTHON
+ PyObject* m_finish_cb;
+ PyObject* m_progress_cb;
+#endif
+
+public:
+ KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter,
+ class KX_KetsjiEngine* kx_engine,
+ class KX_Scene* merge_scene,
+ const char *path);
+
+ void Finish(); // Called when the libload is done
+ void RunFinishCallback();
+ void RunProgressCallback();
+
+ class KX_BlenderSceneConverter *GetConverter();
+ class KX_KetsjiEngine *GetEngine();
+ class KX_Scene *GetMergeScene();
+
+ void SetLibName(const char *name);
+ const char *GetLibName();
+
+ void SetData(void *data);
+ void *GetData();
+
+ void SetProgress(float progress);
+ float GetProgress();
+ void AddProgress(float progress);
+
+#ifdef WITH_PYTHON
+ static PyObject* pyattr_get_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
+ static PyObject* pyattr_get_timetaken(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif
+};
+
+#endif // __KX_LIBLOADSTATUS_H__
diff --git a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp
index 72d0c8733f2..d860b2ee694 100644
--- a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp
+++ b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp
@@ -42,7 +42,7 @@
#include "CTR_Map.h"
#include "CTR_HashedPtr.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "CcdPhysicsEnvironment.h"
#include "CcdPhysicsController.h"
diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript
index b9c70910283..ef546ce1b19 100644
--- a/source/gameengine/Converter/SConscript
+++ b/source/gameengine/Converter/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
@@ -38,7 +64,7 @@ if env['WITH_BF_CXX_GUARDEDALLOC']:
defs.append('WITH_CXX_GUARDEDALLOC')
if env['WITH_BF_BULLET']:
- defs.append('USE_BULLET')
+ defs.append('WITH_BULLET')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/gameengine/Expressions/EmptyValue.cpp b/source/gameengine/Expressions/EmptyValue.cpp
index 2bb8f69ac51..8170c588a28 100644
--- a/source/gameengine/Expressions/EmptyValue.cpp
+++ b/source/gameengine/Expressions/EmptyValue.cpp
@@ -30,9 +30,9 @@
CEmptyValue::CEmptyValue()
/*
-pre:
-effect: constructs a new CEmptyValue
-*/
+ * pre:
+ * effect: constructs a new CEmptyValue
+ */
{
SetModified(false);
}
@@ -41,9 +41,9 @@ effect: constructs a new CEmptyValue
CEmptyValue::~CEmptyValue()
/*
-pre:
-effect: deletes the object
-*/
+ * pre:
+ * effect: deletes the object
+ */
{
}
@@ -52,10 +52,10 @@ effect: deletes the object
CValue * CEmptyValue::Calc(VALUE_OPERATOR op, CValue * val)
/*
-pre:
-ret: a new object containing the result of applying operator op to this
-object and val
-*/
+ * pre:
+ * ret: a new object containing the result of applying operator op to this
+ * object and val
+ */
{
return val->CalcFinal(VALUE_EMPTY_TYPE, op, this);
@@ -65,10 +65,10 @@ object and val
CValue * CEmptyValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue * val)
/*
-pre: the type of val is dtype
-ret: a new object containing the result of applying operator op to val and
-this object
-*/
+ * pre: the type of val is dtype
+ * ret: a new object containing the result of applying operator op to val and
+ * this object
+ */
{
return val->AddRef();
}
diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp
index 0a5af4a18ea..ed89fb13337 100644
--- a/source/gameengine/Expressions/InputParser.cpp
+++ b/source/gameengine/Expressions/InputParser.cpp
@@ -260,7 +260,8 @@ void CParser::NextSym()
opkind = OPless;
}
break;
- case '\"' : {
+ case '\"' :
+ {
int start;
sym = constsym;
constkind = stringtype;
@@ -354,7 +355,7 @@ int CParser::MakeInt()
}
#endif
-STR_String CParser::Symbol2Str(int s)
+const char *CParser::Symbol2Str(int s)
{
// returns a string representation of of symbol s,
// for use in Term when generating an error
@@ -370,18 +371,20 @@ STR_String CParser::Symbol2Str(int s)
case whocodedsym: return "WHOMADE";
case eolsym: return "end of line";
case idsym: return "identifier";
- default: return "unknown"; // should not happen
}
+ return "unknown"; // should not happen
}
void CParser::Term(int s)
{
// generates an error if the next symbol isn't the specified symbol s
// otherwise, skip the symbol
- if (s == sym) NextSym();
+ if (s == sym) {
+ NextSym();
+ }
else {
STR_String msg;
- msg.Format("Warning: " + Symbol2Str(s) + " expected\ncontinuing without it");
+ msg.Format("Warning: %s expected\ncontinuing without it", Symbol2Str(s));
// AfxMessageBox(msg,MB_ICONERROR);
@@ -462,7 +465,8 @@ CExpression *CParser::Ex(int i)
}
else {
switch (sym) {
- case constsym: {
+ case constsym:
+ {
switch (constkind) {
case booltype:
e1 = new CConstExpr(new CBoolValue(boolvalue));
diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h
index 6dfeff55105..50bb1ae2f6e 100644
--- a/source/gameengine/Expressions/InputParser.h
+++ b/source/gameengine/Expressions/InputParser.h
@@ -102,7 +102,7 @@ private:
#if 0 /* not used yet */
int MakeInt();
#endif
- STR_String Symbol2Str(int s);
+ const char *Symbol2Str(int s);
void Term(int s);
int Priority(int optor);
CExpression *Ex(int i);
diff --git a/source/gameengine/Expressions/Operator2Expr.cpp b/source/gameengine/Expressions/Operator2Expr.cpp
index d0240b5ec75..b03d00e7f77 100644
--- a/source/gameengine/Expressions/Operator2Expr.cpp
+++ b/source/gameengine/Expressions/Operator2Expr.cpp
@@ -113,61 +113,61 @@ and m_rhs
}
-/*
+#if 0
bool COperator2Expr::IsInside(float x, float y, float z,bool bBorderInclude)
{
bool inside;
inside = false;
- switch (m_op)
- {
- case VALUE_ADD_OPERATOR: {
- // inside = first || second; // optimized with early out if first is inside
- // todo: calculate smallest leaf first ! is much faster...
-
- bool second;//first ;//,second;
-
- //first = m_lhs->IsInside(x,y,z);
- second = m_rhs->IsInside(x,y,z,bBorderInclude);
- if (second)
- return true; //early out
-
- // second = m_rhs->IsInside(x,y,z);
+ switch (m_op) {
+ case VALUE_ADD_OPERATOR:
+ {
+ // inside = first || second; // optimized with early out if first is inside
+ // todo: calculate smallest leaf first ! is much faster...
- return m_lhs->IsInside(x,y,z,bBorderInclude);
-
- break;
- }
-
- case VALUE_SUB_OPERATOR: {
- //inside = first && !second; // optimized with early out
- // todo: same as with add_operator: calc smallest leaf first
+ bool second;//first ;//,second;
- bool second;//first ;//,second;
- //first = m_lhs->IsInside(x,y,z);
- second = m_rhs->IsInside(x,y,z,bBorderInclude);
- if (second)
- return false;
+ //first = m_lhs->IsInside(x,y,z);
+ second = m_rhs->IsInside(x,y,z,bBorderInclude);
+ if (second)
+ return true; //early out
- // second space get subtracted -> negate!
- //second = m_rhs->IsInside(x,y,z);
+ // second = m_rhs->IsInside(x,y,z);
- return (m_lhs->IsInside(x,y,z,bBorderInclude));
+ return m_lhs->IsInside(x,y,z,bBorderInclude);
-
- break;
- }
- default:{
- assert(false);
- // not yet implemented, only add or sub csg operations
- }
+ break;
+ }
+
+ case VALUE_SUB_OPERATOR:
+ {
+ //inside = first && !second; // optimized with early out
+ // todo: same as with add_operator: calc smallest leaf first
+
+ bool second;//first ;//,second;
+ //first = m_lhs->IsInside(x,y,z);
+ second = m_rhs->IsInside(x,y,z,bBorderInclude);
+ if (second)
+ return false;
+
+ // second space get subtracted -> negate!
+ //second = m_rhs->IsInside(x,y,z);
+
+ return (m_lhs->IsInside(x,y,z,bBorderInclude));
+
+
+ break;
+ }
+ default:
+ {
+ assert(false);
+ // not yet implemented, only add or sub csg operations
+ }
}
return inside;
}
-
-
bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude)
{
return m_rhs->IsInside(x,y,z,bBorderInclude);
@@ -177,7 +177,8 @@ bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude)
{
return m_lhs->IsInside(x,y,z,bBorderInclude);
}
-*/
+#endif
+
bool COperator2Expr::NeedsRecalculated()
{
// added some lines, just for debugging purposes, it could be a one-liner :)
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 11b00b7bbf5..52ad95c71b6 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -43,7 +43,7 @@
* Center for the Neural Basis of Cognition (CNBC)
* http://www.python.org/doc/PyCPP.html
*
-------------------------------*/
+ * ----------------------------- */
#include <stdlib.h>
#include <stddef.h>
@@ -103,7 +103,7 @@ void PyObjectPlus::InvalidateProxy() // check typename of each parent
/*------------------------------
* PyObjectPlus Type -- Every class, even the abstract one should have a Type
-------------------------------*/
+ * ----------------------------- */
PyTypeObject PyObjectPlus::Type = {
@@ -118,16 +118,16 @@ PyTypeObject PyObjectPlus::Type = {
0, /* setattrfunc tp_setattr; */
0, /* tp_compare */ /* DEPRECATED in python 3.0! */
py_base_repr, /* tp_repr */
- 0,0,0,0,0,0,0,0,0, /* Method suites for standard classes */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* long tp_flags; */
- 0,0,0,0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Method suites for standard classes */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
+ 0, 0, 0, 0,
/* weak reference enabler */
#ifdef USE_WEAKREFS
offsetof(PyObjectPlus_Proxy, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
- 0,0,
+ 0, 0,
Methods,
0,
0,
@@ -217,8 +217,8 @@ PyObject *PyObjectPlus::py_base_new(PyTypeObject *type, PyObject *args, PyObject
}
/**
- * \param self A PyObjectPlus_Proxy
- */
+ * \param self A PyObjectPlus_Proxy
+ */
void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper
{
#ifdef USE_WEAKREFS
@@ -311,14 +311,14 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
{
bool *val = reinterpret_cast<bool*>(ptr);
ptr += sizeof(bool);
- PyList_SET_ITEM(resultlist,i,PyBool_FromLong(*val));
+ PyList_SET_ITEM(resultlist, i, PyBool_FromLong(*val));
break;
}
case KX_PYATTRIBUTE_TYPE_SHORT:
{
short int *val = reinterpret_cast<short int*>(ptr);
ptr += sizeof(short int);
- PyList_SET_ITEM(resultlist,i,PyLong_FromLong(*val));
+ PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
break;
}
case KX_PYATTRIBUTE_TYPE_ENUM:
@@ -333,14 +333,14 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
{
int *val = reinterpret_cast<int*>(ptr);
ptr += sizeof(int);
- PyList_SET_ITEM(resultlist,i,PyLong_FromLong(*val));
+ PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
break;
}
case KX_PYATTRIBUTE_TYPE_FLOAT:
{
float *val = reinterpret_cast<float*>(ptr);
ptr += sizeof(float);
- PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble(*val));
+ PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(*val));
break;
}
default:
@@ -423,7 +423,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
PyObject *resultlist = PyList_New(attrdef->m_imax);
for (unsigned int i=0; i<attrdef->m_imax; i++)
{
- PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble(val[i]));
+ PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(val[i]));
}
return resultlist;
#endif
@@ -443,9 +443,9 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
PyObject *col = PyList_New(attrdef->m_imax);
for (unsigned int j=0; j<attrdef->m_imax; j++)
{
- PyList_SET_ITEM(col,j,PyFloat_FromDouble(val[j]));
+ PyList_SET_ITEM(col, j, PyFloat_FromDouble(val[j]));
}
- PyList_SET_ITEM(collist,i,col);
+ PyList_SET_ITEM(collist, i, col);
val += attrdef->m_imax;
}
return collist;
@@ -463,7 +463,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
PyObject *resultlist = PyList_New(3);
for (unsigned int i=0; i<3; i++)
{
- PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble((*val)[i]));
+ PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble((*val)[i]));
}
return resultlist;
#endif
@@ -1110,7 +1110,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
------------------------------*/
PyObject *PyObjectPlus::py_repr(void)
{
- PyErr_SetString(PyExc_SystemError, "Representation not overridden by object.");
+ PyErr_SetString(PyExc_SystemError, "Representation not overridden by object.");
return NULL;
}
@@ -1187,7 +1187,7 @@ void PyObjectPlus::SetDeprecationWarnings(bool ignoreDeprecationWarnings)
m_ignore_deprecation_warnings = ignoreDeprecationWarnings;
}
-void PyObjectPlus::ShowDeprecationWarning_func(const char* old_way,const char* new_way)
+void PyObjectPlus::ShowDeprecationWarning_func(const char *old_way, const char *new_way)
{
printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way);
PyC_LineSpit();
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 37e26e88750..e2e7c248795 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -389,139 +389,139 @@ typedef struct KX_PYATTRIBUTE_DEF {
} m_typeCheck;
} PyAttributeDef;
-#define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_BOOL_RW(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_BOOL_RW_CHECK(name, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_BOOL_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
/* attribute points to a single bit of an integer field, attribute=true if bit is set */
-#define KX_PYATTRIBUTE_FLAG_RW(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_RW_CHECK(name,object,field,bit,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_RO(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_RW(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_RW_CHECK(name, object, field, bit, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_RO(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
/* attribute points to a single bit of an integer field, attribute=true if bit is set*/
-#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW_CHECK(name,object,field,bit,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RO(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW_CHECK(name, object, field, bit, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RO(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 1, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
// enum field cannot be mapped to pointer (because we would need a pointer for each enum)
// use field size to verify mapping at runtime only, assuming enum size is equal to int size.
-#define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-
-#define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ENUM_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ENUM_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ENUM_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+
+#define KX_PYATTRIBUTE_SHORT_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
// SHORT_LIST
-#define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-
-#define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+
+#define KX_PYATTRIBUTE_INT_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_ARRAY_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_ARRAY_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
// INT_LIST
-#define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
// always clamp for float
-#define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_RW(name, min, max, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name, min, max, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
// field must be float[n], returns a sequence
-#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name, min, max, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name, min, max, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
// field must be float[n], returns a vector
-#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW(name,min,max,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW_CHECK(name,min,max,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_VECTOR_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW(name, min, max, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW_CHECK(name, min, max, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_VECTOR_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, length, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
// field must be float[n][n], returns a matrix
-#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW(name,min,max,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW_CHECK(name,min,max,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_MATRIX_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, length, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW(name, min, max, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW_CHECK(name, min, max, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_MATRIX_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, length, length, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
// only for STR_String member
-#define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
-#define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
-#define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_STRING_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_STRING_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_STRING_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
// only for char [] array
-#define KX_PYATTRIBUTE_CHAR_RW(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
-#define KX_PYATTRIBUTE_CHAR_RW_CHECK(name,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
-#define KX_PYATTRIBUTE_CHAR_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
+#define KX_PYATTRIBUTE_CHAR_RW(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
+#define KX_PYATTRIBUTE_CHAR_RW_CHECK(name, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
+#define KX_PYATTRIBUTE_CHAR_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
// for MT_Vector3 member
-#define KX_PYATTRIBUTE_VECTOR_RW(name,min,max,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
-#define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
-#define KX_PYATTRIBUTE_VECTOR_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
-
-#define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \
+#define KX_PYATTRIBUTE_VECTOR_RW(name, min, max, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+#define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+#define KX_PYATTRIBUTE_VECTOR_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+
+#define KX_PYATTRIBUTE_RW_FUNCTION(name, object, getfunction, setfunction) \
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \
+#define KX_PYATTRIBUTE_RO_FUNCTION(name, object, getfunction) \
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \
- { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \
- { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name, object, length, getfunction, setfunction) \
+ { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0, f, false, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name, object, length, getfunction) \
+ { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0, f, false, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
/*------------------------------
@@ -614,7 +614,7 @@ public:
/** enable/disable display of deprecation warnings */
static void SetDeprecationWarnings(bool ignoreDeprecationWarnings);
/** Shows a deprecation warning */
- static void ShowDeprecationWarning_func(const char* method,const char* prop);
+ static void ShowDeprecationWarning_func(const char *method, const char *prop);
static void ClearDeprecationWarning();
#endif
diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript
index 4dc165a7696..a6d82a4f2da 100644
--- a/source/gameengine/Expressions/SConscript
+++ b/source/gameengine/Expressions/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index e511704c7f4..ad357bd015b 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -71,6 +71,7 @@ set(SRC
SCA_PropertyEventManager.cpp
SCA_PropertySensor.cpp
SCA_PythonController.cpp
+ SCA_PythonJoystick.cpp
SCA_PythonKeyboard.cpp
SCA_PythonMouse.cpp
SCA_RandomActuator.cpp
@@ -114,6 +115,7 @@ set(SRC
SCA_PropertyEventManager.h
SCA_PropertySensor.h
SCA_PythonController.h
+ SCA_PythonJoystick.h
SCA_PythonKeyboard.h
SCA_PythonMouse.h
SCA_RandomActuator.h
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index 8b343be8226..dce62ad189a 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -307,8 +307,11 @@ int SCA_Joystick::pGetAxis(int axisnum, int udlr)
int SCA_Joystick::pAxisTest(int axisnum)
{
#ifdef WITH_SDL
- short i1 = m_axis_array[(axisnum * 2)];
- short i2 = m_axis_array[(axisnum * 2) + 1];
+ /* Use ints instead of shorts here to avoid problems when we get -32768.
+ * When we take the negative of that later, we should get 32768, which is greater
+ * than what a short can hold. In other words, abs(MIN_SHORT) > MAX_SHRT. */
+ int i1 = m_axis_array[(axisnum * 2)];
+ int i2 = m_axis_array[(axisnum * 2) + 1];
/* long winded way to do:
* return max_ff(absf(i1), absf(i2))
@@ -321,3 +324,12 @@ int SCA_Joystick::pAxisTest(int axisnum)
return 0;
#endif /* WITH_SDL */
}
+
+const char *SCA_Joystick::GetName()
+{
+#ifdef WITH_SDL
+ return SDL_JoystickName(m_joyindex);
+#else /* WITH_SDL */
+ return "";
+#endif /* WITH_SDL */
+}
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
index 912484a2fe5..dd9fbefa545 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
@@ -192,6 +192,11 @@ public:
* Test if the joystick is connected
*/
int Connected(void);
+
+ /**
+ * Name of the joytsick
+ */
+ const char *GetName();
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index 5ad5aedbd39..6a87d3ccb98 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -97,6 +97,11 @@ bool SCA_2DFilterActuator::Update()
}
+void SCA_2DFilterActuator::SetScene(SCA_IScene *scene)
+{
+ m_scene = scene;
+}
+
void SCA_2DFilterActuator::SetShaderText(const char *text)
{
m_shaderText = text;
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index a754d950859..4635a8ad9f8 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -64,6 +64,8 @@ public:
virtual ~SCA_2DFilterActuator();
virtual bool Update();
+ void SetScene(SCA_IScene *scene);
+
virtual CValue* GetReplica();
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h
index 1a403f40955..ceb9c1e1d4f 100644
--- a/source/gameengine/GameLogic/SCA_IInputDevice.h
+++ b/source/gameengine/GameLogic/SCA_IInputDevice.h
@@ -269,7 +269,7 @@ public:
KX_MAX_KEYS
- } ; // enum
+ }; // enum
protected:
@@ -301,17 +301,18 @@ public:
virtual void HookEscape();
- /* Next frame: we calculate the new key states. This goes as follows:
- *
- * KX_NO_INPUTSTATUS -> KX_NO_INPUTSTATUS
- * KX_JUSTACTIVATED -> KX_ACTIVE
- * KX_ACTIVE -> KX_ACTIVE
- * KX_JUSTRELEASED -> KX_NO_INPUTSTATUS
- *
- * Getting new events provides the
- * KX_NO_INPUTSTATUS->KX_JUSTACTIVATED and
- * KX_ACTIVE->KX_JUSTRELEASED transitions.
- */
+ /**
+ * Next frame: we calculate the new key states. This goes as follows:
+ *
+ * KX_NO_INPUTSTATUS -> KX_NO_INPUTSTATUS
+ * KX_JUSTACTIVATED -> KX_ACTIVE
+ * KX_ACTIVE -> KX_ACTIVE
+ * KX_JUSTRELEASED -> KX_NO_INPUTSTATUS
+ *
+ * Getting new events provides the
+ * KX_NO_INPUTSTATUS->KX_JUSTACTIVATED and
+ * KX_ACTIVE->KX_JUSTRELEASED transitions.
+ */
virtual void NextFrame();
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 0189af00322..365e2b0c853 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -221,7 +221,7 @@ public:
OBJ_ARMATURE=0,
OBJ_CAMERA=1,
OBJ_LIGHT=2,
- }ObjectTypes;
+ } ObjectTypes;
};
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
index c21db794e42..780e4e9ce88 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
@@ -60,14 +60,16 @@ SCA_JoystickManager::~SCA_JoystickManager()
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
+ // We should always handle events in case we want to grab them with Python
+#ifdef WITH_SDL
+ SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
+#endif
+
if (m_sensors.Empty()) {
return;
}
else {
;
-#ifdef WITH_SDL
- SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
-#endif
SG_DList::iterator<SCA_JoystickSensor> it(m_sensors);
for (it.begin();!it.end();++it)
{
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
index 690930196b3..4d8c20065b5 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.h
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -52,7 +52,7 @@ using namespace std;
typedef std::list<class SCA_IController*> controllerlist;
typedef std::map<class SCA_ISensor*,controllerlist > sensormap_t;
-/**
+/**
* This manager handles sensor, controllers and actuators.
* logic executes each frame the following way:
* find triggering sensors
@@ -63,7 +63,7 @@ typedef std::map<class SCA_ISensor*,controllerlist > sensormap_t;
* clear triggering sensors
* clear triggered controllers
* (actuators may be active during a longer timeframe)
-*/
+ */
#include "SCA_ILogicBrick.h"
#include "SCA_IActuator.h"
@@ -117,8 +117,8 @@ public:
void RemoveGameObject(const STR_String& gameobjname);
/**
- * remove Logic Bricks from the running logicmanager
- */
+ * remove Logic Bricks from the running logicmanager
+ */
void RemoveSensor(SCA_ISensor* sensor);
void RemoveController(SCA_IController* controller);
void RemoveActuator(SCA_IActuator* actuator);
diff --git a/source/gameengine/GameLogic/SCA_PythonJoystick.cpp b/source/gameengine/GameLogic/SCA_PythonJoystick.cpp
new file mode 100644
index 00000000000..9b24ad7bcf2
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonJoystick.cpp
@@ -0,0 +1,188 @@
+/*
+ * ***** 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): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gameengine/GameLogic/SCA_PythonJoystick.cpp
+ * \ingroup gamelogic
+ */
+
+
+#include "SCA_PythonJoystick.h"
+#include "./Joystick/SCA_Joystick.h"
+#include "SCA_IInputDevice.h"
+
+//#include "GHOST_C-api.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_PythonJoystick::SCA_PythonJoystick(SCA_Joystick* joystick)
+: PyObjectPlus(),
+m_joystick(joystick)
+{
+#ifdef WITH_PYTHON
+ m_event_dict = PyDict_New();
+#endif
+}
+
+SCA_PythonJoystick::~SCA_PythonJoystick()
+{
+ // The joystick reference we got in the constructor was a new instance,
+ // so we release it here
+ m_joystick->ReleaseInstance();
+
+#ifdef WITH_PYTHON
+ PyDict_Clear(m_event_dict);
+ Py_DECREF(m_event_dict);
+#endif
+}
+
+#ifdef WITH_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+PyObject* SCA_PythonJoystick::py_repr(void)
+{
+ return PyUnicode_FromString(m_joystick->GetName());
+}
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PythonJoystick::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "SCA_PythonJoystick",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,0,0,0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &PyObjectPlus::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyMethodDef SCA_PythonJoystick::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef SCA_PythonJoystick::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("numButtons", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("numHats", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("numAxis", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("activeButtons", SCA_PythonJoystick, pyattr_get_active_buttons),
+ KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_PythonJoystick, pyattr_get_hat_values),
+ KX_PYATTRIBUTE_RO_FUNCTION("axisValues", SCA_PythonJoystick, pyattr_get_axis_values),
+ KX_PYATTRIBUTE_RO_FUNCTION("name", SCA_PythonJoystick, pyattr_get_name),
+ { NULL } //Sentinel
+};
+
+// Use one function for numAxis, numButtons, and numHats
+PyObject* SCA_PythonJoystick::pyattr_get_num_x(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ if (strcmp(attrdef->m_name, "numButtons") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfButtons());
+ else if (strcmp(attrdef->m_name, "numAxis") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfAxes());
+ else if (strcmp(attrdef->m_name, "numHats") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfHats());
+
+ // If we got here, we have a problem...
+ PyErr_SetString(PyExc_AttributeError, "invalid attribute");
+ return NULL;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_active_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ const int button_number = self->m_joystick->GetNumberOfButtons();
+
+ PyObject *list = PyList_New(0);
+ PyObject *value;
+
+ for (int i=0; i < button_number; i++) {
+ if (self->m_joystick->aButtonPressIsPositive(i)) {
+ value = PyLong_FromLong(i);
+ PyList_Append(list, value);
+ Py_DECREF(value);
+ }
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ int hat_index = self->m_joystick->GetNumberOfHats();
+ PyObject *list = PyList_New(hat_index);
+
+ while (hat_index--) {
+ PyList_SET_ITEM(list, hat_index, PyLong_FromLong(self->m_joystick->GetHat(hat_index)));
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ int axis_index = self->m_joystick->GetNumberOfAxes();
+ PyObject *list = PyList_New(axis_index);
+ int position;
+
+ while (axis_index--) {
+ position = self->m_joystick->GetAxisPosition(axis_index);
+
+ // We get back a range from -32768 to 32767, so we use an if here to
+ // get a perfect -1.0 to 1.0 mapping. Some oddball system might have an
+ // actual min of -32767 for shorts, so we use SHRT_MIN/MAX to be safe.
+ if (position < 0)
+ PyList_SET_ITEM(list, axis_index, PyFloat_FromDouble(position/((double)-SHRT_MIN)));
+ else
+ PyList_SET_ITEM(list, axis_index, PyFloat_FromDouble(position/(double)SHRT_MAX));
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ return PyUnicode_FromString(self->m_joystick->GetName());
+}
+#endif
diff --git a/source/gameengine/GameLogic/SCA_PythonJoystick.h b/source/gameengine/GameLogic/SCA_PythonJoystick.h
new file mode 100644
index 00000000000..15c6285aed5
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonJoystick.h
@@ -0,0 +1,56 @@
+/*
+ * ***** 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): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file SCA_PythonJoystick.h
+ * \ingroup gamelogic
+ */
+
+#ifndef __SCA_PYTHONJOYSTICK_H__
+#define __SCA_PYTHONJOYSTICK_H__
+
+#include "PyObjectPlus.h"
+
+class SCA_PythonJoystick : public PyObjectPlus
+{
+ Py_Header
+private:
+ class SCA_Joystick *m_joystick;
+#ifdef WITH_PYTHON
+ PyObject* m_event_dict;
+#endif
+public:
+ SCA_PythonJoystick(class SCA_Joystick* joystick);
+ virtual ~SCA_PythonJoystick();
+
+#ifdef WITH_PYTHON
+ virtual PyObject* py_repr(void);
+
+ static PyObject* pyattr_get_num_x(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_active_buttons(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hat_values(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_axis_values(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif
+};
+
+#endif //__SCA_PYTHONJOYSTICK_H__
+
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
index 5568072abcf..db6b4a63423 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -178,23 +178,15 @@ bool SCA_RandomActuator::Update()
case KX_RANDOMACT_FLOAT_NORMAL: {
/* normal (big numbers): para1 = mean, para2 = std dev */
- /*
-
- 070301 - nzc - Changed the termination condition. I think I
- made a small mistake here, but it only affects distro's where
- the seed equals 0. In that case, the algorithm locks. Let's
- just guard that case separately.
-
- */
+ /* 070301 - nzc: Changed the termination condition. I think I
+ * made a small mistake here, but it only affects distro's where
+ * the seed equals 0. In that case, the algorithm locks. Let's
+ * just guard that case separately.
+ */
float x = 0.0, y = 0.0, s = 0.0, t = 0.0;
if (m_base->GetSeed() == 0) {
- /*
-
- 070301 - nzc
- Just taking the mean here seems reasonable.
-
- */
+ /* 070301 - nzc: Just taking the mean here seems reasonable. */
tmpval = new CFloatValue(m_parameter1);
}
else {
diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript
index da3c0fadb51..b274e518015 100644
--- a/source/gameengine/GameLogic/SConscript
+++ b/source/gameengine/GameLogic/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp')
diff --git a/source/gameengine/GamePlayer/SConscript b/source/gameengine/GamePlayer/SConscript
index 0b140bba8e7..d1930aca26d 100644
--- a/source/gameengine/GamePlayer/SConscript
+++ b/source/gameengine/GamePlayer/SConscript
@@ -1,3 +1,29 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
SConscript(['common/SConscript',
'ghost/SConscript'])
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
index b5c1c29238a..058454ca352 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
@@ -131,7 +131,15 @@ void GPC_Canvas::SetViewPort(int x1, int y1, int x2, int y2)
glViewport(x1,y1,x2-x1 + 1,y2-y1 + 1);
glScissor(x1,y1,x2-x1 + 1,y2-y1 + 1);
-};
+}
+
+void GPC_Canvas::UpdateViewPort(int x1, int y1, int x2, int y2)
+{
+ m_viewport[0] = x1;
+ m_viewport[1] = y1;
+ m_viewport[2] = x2;
+ m_viewport[3] = y2;
+}
const int *GPC_Canvas::GetViewPort()
{
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h
index ec5375c0e13..00c5911a8b4 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.h
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h
@@ -155,6 +155,7 @@ public:
);
void SetViewPort(int x1, int y1, int x2, int y2);
+ void UpdateViewPort(int x1, int y1, int x2, int y2);
const int *GetViewPort();
void ClearColor(float r, float g, float b, float a);
diff --git a/source/gameengine/GamePlayer/common/GPC_RawImage.cpp b/source/gameengine/GamePlayer/common/GPC_RawImage.cpp
index c0d66541800..0e2585b0baa 100644
--- a/source/gameengine/GamePlayer/common/GPC_RawImage.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RawImage.cpp
@@ -29,7 +29,6 @@
* \ingroup player
*/
-
#include <iostream>
#include <string.h>
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index dfc866526eb..bab4aa14bbd 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -283,6 +283,78 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
}
}
+void GPC_RenderTools::RenderBox2D(int xco,
+ int yco,
+ int width,
+ int height,
+ float percentage)
+{
+ // Save and change OpenGL settings
+ int texture2D;
+ glGetIntegerv(GL_TEXTURE_2D, (GLint*)&texture2D);
+ glDisable(GL_TEXTURE_2D);
+ int fog;
+ glGetIntegerv(GL_FOG, (GLint*)&fog);
+ glDisable(GL_FOG);
+
+ int light;
+ glGetIntegerv(GL_LIGHTING, (GLint*)&light);
+ glDisable(GL_LIGHTING);
+
+ glDisable(GL_DEPTH_TEST);
+
+ // Set up viewing settings
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ yco = height - yco;
+ int barsize = 50;
+
+ // draw in black first
+ glColor3ub(0, 0, 0);
+ glBegin(GL_QUADS);
+ glVertex2f(xco + 1 + 1 + barsize * percentage, yco - 1 + 10);
+ glVertex2f(xco + 1, yco - 1 + 10);
+ glVertex2f(xco + 1, yco - 1);
+ glVertex2f(xco + 1 + 1 + barsize * percentage, yco - 1);
+ glEnd();
+
+ glColor3ub(255, 255, 255);
+ glBegin(GL_QUADS);
+ glVertex2f(xco + 1 + barsize * percentage, yco + 10);
+ glVertex2f(xco, yco + 10);
+ glVertex2f(xco, yco);
+ glVertex2f(xco + 1 + barsize * percentage, yco);
+ glEnd();
+
+ // Restore view settings
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ // Restore OpenGL Settings
+ if (fog)
+ glEnable(GL_FOG);
+ else
+ glDisable(GL_FOG);
+
+ if (texture2D)
+ glEnable(GL_TEXTURE_2D);
+ else
+ glDisable(GL_TEXTURE_2D);
+ if (light)
+ glEnable(GL_LIGHTING);
+ else
+ glDisable(GL_LIGHTING);
+}
+
+
void GPC_RenderTools::RenderText3D( int fontid,
const char* text,
int size,
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
index 1030c09548a..f4dcddd3250 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -70,6 +70,12 @@ public:
void DisableOpenGLLights();
void ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat);
+ void RenderBox2D(int xco,
+ int yco,
+ int width,
+ int height,
+ float percentage);
+
void RenderText3D(int fontid,
const char* text,
int size,
diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript
index 6a1f47c51af..1648d8af78c 100644
--- a/source/gameengine/GamePlayer/common/SConscript
+++ b/source/gameengine/GamePlayer/common/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 92db1fe790e..58710120afa 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -76,7 +76,6 @@ extern "C"
#include "SCA_IActuator.h"
#include "RAS_MeshObject.h"
#include "RAS_OpenGLRasterizer.h"
-#include "RAS_VAOpenGLRasterizer.h"
#include "RAS_ListRasterizer.h"
#include "RAS_GLExtensionManager.h"
#include "KX_PythonInit.h"
@@ -309,20 +308,21 @@ bool GPG_Application::startScreenSaverFullScreen(
#endif
-bool GPG_Application::startWindow(STR_String& title,
- int windowLeft,
- int windowTop,
- int windowWidth,
- int windowHeight,
- const bool stereoVisual,
- const int stereoMode,
- const GHOST_TUns16 samples)
+bool GPG_Application::startWindow(
+ STR_String& title,
+ int windowLeft,
+ int windowTop,
+ int windowWidth,
+ int windowHeight,
+ const bool stereoVisual,
+ const int stereoMode,
+ const GHOST_TUns16 samples)
{
bool success;
// Create the main window
//STR_String title ("Blender Player - GHOST");
m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples);
+ GHOST_kDrawingContextTypeOpenGL, stereoVisual, false, samples);
if (!m_mainWindow) {
printf("error: could not create main window\n");
exit(-1);
@@ -341,16 +341,18 @@ bool GPG_Application::startWindow(STR_String& title,
return success;
}
-bool GPG_Application::startEmbeddedWindow(STR_String& title,
- const GHOST_TEmbedderWindowID parentWindow,
- const bool stereoVisual,
- const int stereoMode,
- const GHOST_TUns16 samples) {
+bool GPG_Application::startEmbeddedWindow(
+ STR_String& title,
+ const GHOST_TEmbedderWindowID parentWindow,
+ const bool stereoVisual,
+ const int stereoMode,
+ const GHOST_TUns16 samples)
+{
GHOST_TWindowState state = GHOST_kWindowStateNormal;
if (parentWindow != 0)
state = GHOST_kWindowStateEmbedded;
m_mainWindow = fSystem->createWindow(title, 0, 0, 0, 0, state,
- GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples, parentWindow);
+ GHOST_kDrawingContextTypeOpenGL, stereoVisual, false, samples, parentWindow);
if (!m_mainWindow) {
printf("error: could not create main window\n");
@@ -367,13 +369,13 @@ bool GPG_Application::startEmbeddedWindow(STR_String& title,
bool GPG_Application::startFullScreen(
- int width,
- int height,
- int bpp,int frequency,
- const bool stereoVisual,
- const int stereoMode,
- const GHOST_TUns16 samples,
- bool useDesktop)
+ int width,
+ int height,
+ int bpp,int frequency,
+ const bool stereoVisual,
+ const int stereoMode,
+ const GHOST_TUns16 samples,
+ bool useDesktop)
{
bool success;
GHOST_TUns32 sysWidth=0, sysHeight=0;
@@ -387,6 +389,7 @@ bool GPG_Application::startFullScreen(
fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual, samples);
m_mainWindow->setCursorVisibility(false);
+ /* note that X11 ignores this (it uses a window internally for fullscreen) */
m_mainWindow->setState(GHOST_kWindowStateFullScreen);
success = initEngine(m_mainWindow, stereoMode);
@@ -582,16 +585,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
if (!m_rendertools)
goto initFailed;
- if (useLists) {
- if (GLEW_VERSION_1_1)
- m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
- else
- m_rasterizer = new RAS_ListRasterizer(m_canvas);
- }
- else if (GLEW_VERSION_1_1)
- m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
+ //Don't use displaylists with VBOs
+ //If auto starts using VBOs, make sure to check for that here
+ if (useLists && gm->raster_storage != RAS_STORE_VBO)
+ m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage);
else
- m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
+ m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage);
/* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
@@ -708,6 +707,8 @@ bool GPG_Application::startEngine(void)
m_sceneconverter->SetMaterials(true);
if (m_blenderglslmat && (m_globalSettings->matmode == GAME_MAT_GLSL))
m_sceneconverter->SetGLSLMaterials(true);
+ if (m_startScene->gm.flag & GAME_NO_MATERIAL_CACHING)
+ m_sceneconverter->SetCacheMaterials(false);
KX_Scene* startscene = new KX_Scene(m_keyboard,
m_mouse,
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h
index e04fcc2a555..f141443e738 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.h
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h
@@ -61,23 +61,32 @@ public:
GPG_Application(GHOST_ISystem* system);
~GPG_Application(void);
- bool SetGameEngineData(struct Main* maggie, struct Scene* scene, GlobalSettings* gs, int argc, char** argv);
- bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight,
- const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
- bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0, bool useDesktop=false);
- bool startEmbeddedWindow(STR_String& title, const GHOST_TEmbedderWindowID parent_window, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
+ bool SetGameEngineData(struct Main* maggie, struct Scene* scene, GlobalSettings* gs, int argc, char** argv);
+ bool startWindow(STR_String& title,
+ int windowLeft, int windowTop,
+ int windowWidth, int windowHeight,
+ const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
+ bool startFullScreen(int width, int height,
+ int bpp, int frequency,
+ const bool stereoVisual, const int stereoMode,
+ const GHOST_TUns16 samples=0, bool useDesktop=false);
+ bool startEmbeddedWindow(STR_String& title, const GHOST_TEmbedderWindowID parent_window,
+ const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
#ifdef WIN32
- bool startScreenSaverFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
- bool startScreenSaverPreview(HWND parentWindow, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
+ bool startScreenSaverFullScreen(int width, int height,
+ int bpp, int frequency,
+ const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
+ bool startScreenSaverPreview(HWND parentWindow,
+ const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
#endif
virtual bool processEvent(GHOST_IEvent* event);
- int getExitRequested(void);
- const STR_String& getExitString(void);
- GlobalSettings* getGlobalSettings(void);
- bool StartGameEngine(int stereoMode);
- void StopGameEngine();
- void EngineNextFrame();
+ int getExitRequested(void);
+ const STR_String& getExitString(void);
+ GlobalSettings* getGlobalSettings(void);
+ bool StartGameEngine(int stereoMode);
+ void StopGameEngine();
+ void EngineNextFrame();
protected:
bool handleWheel(GHOST_IEvent* event);
@@ -165,4 +174,3 @@ protected:
int m_argc;
char** m_argv;
};
-
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index a82f9ce1779..c1f43306eba 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -258,10 +258,10 @@ static void usage(const char* program, bool isBlenderPlayer)
static void get_filename(int argc, char **argv, char *filename)
{
#ifdef __APPLE__
-/* On Mac we park the game file (called game.blend) in the application bundle.
-* The executable is located in the bundle as well.
-* Therefore, we can locate the game relative to the executable.
- */
+ /* On Mac we park the game file (called game.blend) in the application bundle.
+ * The executable is located in the bundle as well.
+ * Therefore, we can locate the game relative to the executable.
+ */
int srclen = ::strlen(argv[0]);
int len = 0;
char *gamefile = NULL;
@@ -449,6 +449,10 @@ int main(int argc, char** argv)
IMB_init();
BKE_images_init();
+#ifdef WITH_FFMPEG
+ IMB_ffmpeg_init();
+#endif
+
// Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
BLF_init(11, U.dpi);
BLF_lang_init();
@@ -471,7 +475,7 @@ int main(int argc, char** argv)
break;
case SCREEN_SAVER_MODE_PASSWORD:
/* This is W95 only, which we currently do not support.
- Fall-back to normal screen saver behavior in that case... */
+ * Fall-back to normal screen saver behavior in that case... */
case SCREEN_SAVER_MODE_SAVER:
fullScreen = true;
fullScreenParFound = true;
@@ -492,6 +496,8 @@ int main(int argc, char** argv)
// XXX this one too
U.anisotropic_filter = 2;
+ // enable fast mipmap generation
+ U.use_gpu_mipmap = 1;
sound_init_once();
@@ -606,7 +612,7 @@ int main(int argc, char** argv)
case 'i':
i++;
if ( (i + 1) <= validArguments )
- parentWindow = atoi(argv[i++]);
+ parentWindow = atoi(argv[i++]);
else {
error = true;
printf("error: too few options for parent window argument.\n");
@@ -639,10 +645,10 @@ int main(int argc, char** argv)
stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
-
+
if (!strcmp(argv[i], "nostereo")) // ok, redundant but clear
stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
-
+
// only the hardware pageflip method needs a stereo window
else if (!strcmp(argv[i], "hwpageflip")) {
stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
@@ -650,22 +656,22 @@ int main(int argc, char** argv)
}
else if (!strcmp(argv[i], "syncdoubling"))
stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;
-
+
else if (!strcmp(argv[i], "anaglyph"))
stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;
-
+
else if (!strcmp(argv[i], "sidebyside"))
stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
-
+
else if (!strcmp(argv[i], "vinterlace"))
stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
-
+
#if 0
- // future stuff
- else if (!strcmp(argv[i], "stencil")
- stereomode = RAS_STEREO_STENCIL;
+// // future stuff
+// else if (!strcmp(argv[i], "stencil")
+// stereomode = RAS_STEREO_STENCIL;
#endif
-
+
i++;
stereoParFound = true;
stereoFlag = STEREO_ENABLED;
@@ -727,7 +733,7 @@ int main(int argc, char** argv)
i++;
}
}
-
+
if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
{
error = true;
@@ -750,8 +756,7 @@ int main(int argc, char** argv)
//fullScreen = false; // Can't use full screen
#endif
- if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
- {
+ if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0)) {
GPU_set_mipmap(0);
}
@@ -759,15 +764,14 @@ int main(int argc, char** argv)
GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
// Create the system
- if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
- {
+ if (GHOST_ISystem::createSystem() == GHOST_kSuccess) {
GHOST_ISystem* system = GHOST_ISystem::getSystem();
assertd(system);
if (!fullScreenWidth || !fullScreenHeight)
system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
// process first batch of events. If the user
- // drops a file on top off the blenderplayer icon, we
+ // drops a file on top off the blenderplayer icon, we
// receive an event with the filename
system->processEvents(0);
@@ -792,8 +796,7 @@ int main(int argc, char** argv)
// those may change during the game and persist after using Game Actuator
GlobalSettings gs;
- do
- {
+ do {
// Read the Blender file
BlendFileData *bfd;
@@ -808,19 +811,17 @@ int main(int argc, char** argv)
bfd = load_game_data(basedpath);
- if (!bfd)
- {
+ if (!bfd) {
// just add "//" in front of it
char temppath[242];
strcpy(temppath, "//");
strcat(temppath, basedpath);
-
+
BLI_path_abs(temppath, pathname);
bfd = load_game_data(temppath);
}
}
- else
- {
+ else {
bfd = load_game_data(BLI_program_path(), filename[0]? filename: NULL);
}
@@ -830,13 +831,11 @@ int main(int argc, char** argv)
usage(argv[0], isBlenderPlayer);
error = true;
exitcode = KX_EXIT_REQUEST_QUIT_GAME;
- }
- else
- {
+ }
+ else {
#ifdef WIN32
#if !defined(DEBUG)
- if (closeConsole)
- {
+ if (closeConsole) {
system->toggleConsole(0); // Close a console window
}
#endif // !defined(DEBUG)
@@ -858,8 +857,7 @@ int main(int argc, char** argv)
titlename = maggie->name;
// Check whether the game should be displayed full-screen
- if ((!fullScreenParFound) && (!windowParFound))
- {
+ if ((!fullScreenParFound) && (!windowParFound)) {
// Only use file settings when command line did not override
if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) {
//printf("fullscreen option found in Blender file\n");
@@ -879,16 +877,16 @@ int main(int argc, char** argv)
// Check whether the game should be displayed in stereo
- if (!stereoParFound)
- {
+ if (!stereoParFound) {
if (scene->gm.stereoflag == STEREO_ENABLED) {
stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
if (stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
stereoWindow = true;
}
}
- else
+ else {
scene->gm.stereoflag = STEREO_ENABLED;
+ }
if (!samplesParFound)
aasamples = scene->gm.aasamples;
@@ -902,10 +900,9 @@ int main(int argc, char** argv)
scene->gm.dome.tilt = domeTilt;
if (domeMode > 0)
scene->gm.dome.mode = domeMode;
- if (domeWarp)
- {
+ if (domeWarp) {
//XXX to do: convert relative to absolute path
- domeText= BKE_text_load(domeWarp, "");
+ domeText= BKE_text_load(G.main, domeWarp, "");
if (!domeText)
printf("error: invalid warpdata text file - %s\n", domeWarp);
else
@@ -922,23 +919,21 @@ int main(int argc, char** argv)
#ifdef WITH_PYTHON
setGamePythonPath(G.main->name);
#endif
- if (firstTimeRunning)
- {
+ if (firstTimeRunning) {
firstTimeRunning = false;
- if (fullScreen)
- {
+ if (fullScreen) {
#ifdef WIN32
if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
{
app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
- stereoWindow, stereomode, aasamples);
+ stereoWindow, stereomode, aasamples);
}
else
#endif
{
app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
- stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
+ stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
}
}
else
@@ -962,8 +957,7 @@ int main(int argc, char** argv)
vector<STR_String> parts = path.Explode('\\');
#endif // WIN32
STR_String title;
- if (parts.size())
- {
+ if (parts.size()) {
title = parts[parts.size()-1];
parts = title.Explode('.');
if (parts.size() > 1)
@@ -971,8 +965,7 @@ int main(int argc, char** argv)
title = parts[0];
}
}
- else
- {
+ else {
title = "blenderplayer";
}
#ifdef WIN32
@@ -983,16 +976,15 @@ int main(int argc, char** argv)
else
#endif
{
- if (parentWindow != 0)
+ if (parentWindow != 0)
app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
else
app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
- stereoWindow, stereomode, aasamples);
+ stereoWindow, stereomode, aasamples);
}
}
}
- else
- {
+ else {
app.StartGameEngine(stereomode);
exitcode = KX_EXIT_REQUEST_NO_REQUEST;
}
@@ -1002,44 +994,40 @@ int main(int argc, char** argv)
// Enter main loop
bool run = true;
- char *python_main = NULL;
+ char *python_main = NULL;
pynextframestate.state = NULL;
pynextframestate.func = NULL;
#ifdef WITH_PYTHON
python_main = KX_GetPythonMain(scene);
#endif // WITH_PYTHON
- if (python_main)
- {
+ if (python_main) {
char *python_code = KX_GetPythonCode(maggie, python_main);
- if (python_code)
- {
-#ifdef WITH_PYTHON
+ if (python_code) {
+#ifdef WITH_PYTHON
gpg_nextframestate.system = system;
gpg_nextframestate.app = &app;
gpg_nextframestate.gs = &gs;
pynextframestate.state = &gpg_nextframestate;
pynextframestate.func = &GPG_PyNextFrame;
- printf("Yielding control to Python script '%s'...\n", python_main);
- PyRun_SimpleString(python_code);
- printf("Exit Python script '%s'\n", python_main);
+ printf("Yielding control to Python script '%s'...\n", python_main);
+ PyRun_SimpleString(python_code);
+ printf("Exit Python script '%s'\n", python_main);
#endif // WITH_PYTHON
- MEM_freeN(python_code);
- }
- else {
- fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main);
- }
- }
- else
- {
- while (run)
- {
+ MEM_freeN(python_code);
+ }
+ else {
+ fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main);
+ }
+ }
+ else {
+ while (run) {
run = GPG_NextFrame(system, &app, exitcode, exitstring, &gs);
}
}
app.StopGameEngine();
- /* 'app' is freed automatic when out of scope.
+ /* 'app' is freed automatic when out of scope.
* removal is needed else the system will free an already freed value */
system->removeEventConsumer(&app);
@@ -1054,7 +1042,8 @@ int main(int argc, char** argv)
// Dispose the system
GHOST_ISystem::disposeSystem();
- } else {
+ }
+ else {
error = true;
printf("error: couldn't create a system.\n");
}
@@ -1084,5 +1073,3 @@ int main(int argc, char** argv)
return error ? -1 : 0;
}
-
-
diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript
index fb046d0fdf8..64bd58aa784 100644
--- a/source/gameengine/GamePlayer/ghost/SConscript
+++ b/source/gameengine/GamePlayer/ghost/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
index 5b7a2313f43..1a49f76e71a 100644
--- a/source/gameengine/Ketsji/BL_Action.cpp
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -36,7 +36,6 @@
// These three are for getting the action from the logic manager
#include "KX_Scene.h"
-#include "KX_PythonInit.h"
#include "SCA_LogicManager.h"
extern "C" {
@@ -44,6 +43,10 @@ extern "C" {
#include "BKE_action.h"
#include "RNA_access.h"
#include "RNA_define.h"
+
+// Needed for material IPOs
+#include "BKE_material.h"
+#include "DNA_material_types.h"
}
BL_Action::BL_Action(class KX_GameObject* gameobj)
@@ -132,8 +135,10 @@ bool BL_Action::Play(const char* name,
m_priority = priority;
bAction* prev_action = m_action;
+ KX_Scene* kxscene = m_obj->GetScene();
+
// First try to load the action
- m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name);
+ m_action = (bAction*)kxscene->GetLogicManager()->GetActionByName(name);
if (!m_action)
{
printf("Failed to load action: %s\n", name);
@@ -151,33 +156,67 @@ bool BL_Action::Play(const char* name,
&& m_priority == priority && m_speed == playback_speed)
return false;
- if (prev_action != m_action)
- {
- // First get rid of any old controllers
- ClearControllerList();
+ // First get rid of any old controllers
+ ClearControllerList();
+
+ // Create an SG_Controller
+ SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, kxscene->GetSceneConverter());
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
- // Create an SG_Controller
- SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
+ // Try obcolor
+ sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter());
+ if (sg_contr) {
m_sg_contr_list.push_back(sg_contr);
m_obj->GetSGNode()->AddSGController(sg_contr);
sg_contr->SetObject(m_obj->GetSGNode());
+ }
- // Extra controllers
- if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
- {
- sg_contr = BL_CreateLampIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
- m_sg_contr_list.push_back(sg_contr);
- m_obj->GetSGNode()->AddSGController(sg_contr);
- sg_contr->SetObject(m_obj->GetSGNode());
+ // Now try materials
+ if (m_obj->GetBlenderObject()->totcol==1) {
+ Material *mat = give_current_material(m_obj->GetBlenderObject(), 1);
+ if (mat) {
+ sg_contr = BL_CreateMaterialIpo(m_action, mat, 0, m_obj, kxscene->GetSceneConverter());
+ if (sg_contr) {
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+ }
}
- else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
- {
- sg_contr = BL_CreateCameraIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
- m_sg_contr_list.push_back(sg_contr);
- m_obj->GetSGNode()->AddSGController(sg_contr);
- sg_contr->SetObject(m_obj->GetSGNode());
+ } else {
+ Material *mat;
+ STR_HashedString matname;
+
+ for (int matidx = 1; matidx <= m_obj->GetBlenderObject()->totcol; ++matidx) {
+ mat = give_current_material(m_obj->GetBlenderObject(), matidx);
+ if (mat) {
+ matname = mat->id.name;
+ sg_contr = BL_CreateMaterialIpo(m_action, mat, matname.hash(), m_obj, kxscene->GetSceneConverter());
+ if (sg_contr) {
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+ }
+ }
}
}
+
+ // Extra controllers
+ if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
+ {
+ sg_contr = BL_CreateLampIPO(m_action, m_obj, kxscene->GetSceneConverter());
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+ }
+ else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
+ {
+ sg_contr = BL_CreateCameraIPO(m_action, m_obj, kxscene->GetSceneConverter());
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+ }
m_ipo_flags = ipo_flags;
InitIPO();
@@ -458,4 +497,7 @@ void BL_Action::Update(float curtime)
m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
}
+
+ if (m_done)
+ ClearControllerList();
}
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 23bfd7a111b..64e191fe960 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -95,21 +95,15 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
ras->SetTexCoordNum(0);
ras->SetAttribNum(attrib_num);
- for (i=0; i<attrib_num; i++)
+ for (i = 0; i < attrib_num; i++)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
for (i = 0; i < attribs.totlayer; i++) {
if (attribs.layer[i].glindex > attrib_num)
continue;
- if (attribs.layer[i].type == CD_MTFACE) {
- if (!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
- else if (!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
- else
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
- }
+ if (attribs.layer[i].type == CD_MTFACE)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV, attribs.layer[i].glindex);
else if (attribs.layer[i].type == CD_TANGENT)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
else if (attribs.layer[i].type == CD_ORCO)
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 0954aa0f7ab..393d00223e0 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -10,23 +10,14 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-MTex* getImageFromMaterial(Material *mat, int index)
+MTex* getMTexFromMaterial(Material *mat, int index)
{
- if (!mat) return 0;
-
- if (!(index >=0 && index < MAX_MTEX) ) return 0;
-
- MTex *m = mat->mtex[index];
- return m?m:0;
-}
-
-int getNumTexChannels( Material *mat )
-{
- int count = -1;
- if (!mat) return -1;
-
- for (count =0; (count < 10) && mat->mtex[count] != 0; count++) {}
- return count;
+ if (mat && (index >= 0) && (index < MAX_MTEX)) {
+ return mat->mtex[index];
+ }
+ else {
+ return NULL;
+ }
}
BL_Material::BL_Material()
@@ -36,7 +27,10 @@ BL_Material::BL_Material()
void BL_Material::Initialize()
{
- m_mcol = 0xFFFFFFFFL;
+ rgb[0] = 0;
+ rgb[1] = 0;
+ rgb[2] = 0;
+ rgb[3] = 0;
IdMode = 0;
ras_mode = 0;
glslmat = 0;
@@ -64,7 +58,7 @@ void BL_Material::Initialize()
int i;
- for (i=0; i<MAXTEX; i++) // :(
+ for (i = 0; i < MAXTEX; i++) // :(
{
mapping[i].mapping = 0;
mapping[i].offsets[0] = 0.f;
@@ -90,15 +84,6 @@ void BL_Material::Initialize()
}
}
-void BL_Material::SetUVLayerName(const STR_String& name)
-{
- uvName = name;
-}
-void BL_Material::SetUVLayerName2(const STR_String& name)
-{
- uv2Name = name;
-}
-
void BL_Material::SetSharedMaterial(bool v)
{
if ((v && num_users == -1) || num_users > 1 )
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index ef180ed2126..be66e2ec84d 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -87,13 +87,8 @@ public:
MTFace tface; /* copy of the derived meshes tface */
Image* img[MAXTEX];
EnvMap* cubemap[MAXTEX];
- unsigned int m_mcol; /* for text color (only) */
- STR_String uvName;
- STR_String uv2Name;
-
- void SetUVLayerName(const STR_String &name);
- void SetUVLayerName2(const STR_String &name);
+ unsigned int rgb[4];
void SetSharedMaterial(bool v);
bool IsShared();
@@ -179,8 +174,7 @@ enum BL_MappingProj
// ------------------------------------
//extern void initBL_Material(BL_Material* mat);
-extern MTex* getImageFromMaterial(Material *mat, int index);
-extern int getNumTexChannels( Material *mat );
+extern MTex* getMTexFromMaterial(Material *mat, int index);
// ------------------------------------
#endif
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 66423ed820e..98fff5c8b65 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -60,6 +60,7 @@ public:
typedef std::map<char*, BL_TextureObject> BL_TextureMap;
static BL_TextureMap g_textureManager;
+static GLint g_max_units = -1;
BL_Texture::BL_Texture()
@@ -379,14 +380,17 @@ unsigned int BL_Texture::GetTextureType() const
int BL_Texture::GetMaxUnits()
{
- GLint unit=0;
-
- if (GLEW_ARB_multitexture) {
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
- return (MAXTEX>=unit?unit:MAXTEX);
+ if (g_max_units < 0) {
+ GLint unit;
+ if (GLEW_ARB_multitexture) {
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
+ g_max_units = (MAXTEX>=unit)?unit:MAXTEX;
+ } else {
+ g_max_units = 0;
+ }
}
- return 0;
+ return g_max_units;
}
void BL_Texture::ActivateFirst()
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 524a38a4c26..7f748013648 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -84,6 +84,7 @@ set(SRC
KX_FontObject.cpp
KX_GameActuator.cpp
KX_GameObject.cpp
+ KX_IpoConvert.cpp
KX_IPO_SGController.cpp
KX_IPhysicsController.cpp
KX_IpoActuator.cpp
@@ -161,6 +162,7 @@ set(SRC
KX_GameActuator.h
KX_GameObject.h
KX_IInterpolator.h
+ KX_IpoConvert.h
KX_IPOTransform.h
KX_IPO_SGController.h
KX_IPhysicsController.h
@@ -252,9 +254,9 @@ if(WITH_BULLET)
../Physics/Bullet
)
list(APPEND INC
- ../../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
)
- add_definitions(-DUSE_BULLET)
+ add_definitions(-DWITH_BULLET)
endif()
blender_add_lib(ge_logic_ketsji "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript
index 3d696501203..40a1ec10df3 100644
--- a/source/gameengine/Ketsji/KXNetwork/SConscript
+++ b/source/gameengine/Ketsji/KXNetwork/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 20c36c2cc44..231ec27030d 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -60,7 +60,8 @@ KX_BlenderMaterial::KX_BlenderMaterial()
void KX_BlenderMaterial::Initialize(
KX_Scene *scene,
BL_Material *data,
- GameSettings *game)
+ GameSettings *game,
+ int lightlayer)
{
RAS_IPolyMaterial::Initialize(
data->texname[0],
@@ -84,6 +85,7 @@ void KX_BlenderMaterial::Initialize(
mModified = 0;
mConstructed = false;
mPass = 0;
+ mLightLayer = lightlayer;
// --------------------------------
// RAS_IPolyMaterial variables...
m_flag |= RAS_BLENDERMAT;
@@ -92,16 +94,11 @@ void KX_BlenderMaterial::Initialize(
m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0;
m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0;
- // figure max
- int enabled = mMaterial->num_enabled;
- int max = BL_Texture::GetMaxUnits();
- mMaterial->num_enabled = enabled>=max?max:enabled;
-
// test the sum of the various modes for equality
// so we can ether accept or reject this material
// as being equal, this is rather important to
// prevent material bleeding
- for (int i=0; i<mMaterial->num_enabled; i++) {
+ for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
m_multimode += (mMaterial->flag[i] + mMaterial->blend_mode[i]);
}
m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT));
@@ -124,7 +121,7 @@ MTFace* KX_BlenderMaterial::GetMTFace(void) const
unsigned int* KX_BlenderMaterial::GetMCol(void) const
{
// fonts on polys
- return &mMaterial->m_mcol;
+ return mMaterial->rgb;
}
void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
@@ -138,11 +135,6 @@ void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
}
-bool KX_BlenderMaterial::IsMaterial(const BL_Material *bl_mat) const
-{
- return (mMaterial == bl_mat);
-}
-
Material *KX_BlenderMaterial::GetBlenderMaterial() const
{
return mMaterial->material;
@@ -163,7 +155,7 @@ void KX_BlenderMaterial::InitTextures()
{
// for each unique material...
int i;
- for (i=0; i<mMaterial->num_enabled; i++) {
+ for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
if ( mMaterial->mapping[i].mapping & USEENV ) {
if (!GLEW_ARB_texture_cube_map) {
spit("CubeMap textures not supported");
@@ -185,14 +177,14 @@ void KX_BlenderMaterial::InitTextures()
}
}
-void KX_BlenderMaterial::OnConstruction(int layer)
+void KX_BlenderMaterial::OnConstruction()
{
if (mConstructed)
// when material are reused between objects
return;
if (mMaterial->glslmat)
- SetBlenderGLSLShader(layer);
+ SetBlenderGLSLShader();
InitTextures();
@@ -239,7 +231,8 @@ void KX_BlenderMaterial::OnExit()
}
BL_Texture::ActivateFirst();
- for (int i=0; i<mMaterial->num_enabled; i++) {
+ for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
+ if (!mTextures[i].Ok()) continue;
BL_Texture::ActivateUnit(i);
mTextures[i].DeleteTex();
mTextures[i].DisableUnit();
@@ -278,7 +271,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
mShader->ApplyShader();
// for each enabled unit
- for (i=0; i<mMaterial->num_enabled; i++) {
+ for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
if (!mTextures[i].Ok()) continue;
mTextures[i].ActivateTexture();
mTextures[0].SetMapping(mMaterial->mapping[i].mapping);
@@ -354,7 +347,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
}
int mode = 0,i=0;
- for (i=0; (i<mMaterial->num_enabled && i<MAXTEX); i++) {
+ for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
if ( !mTextures[i].Ok() ) continue;
mTextures[i].ActivateTexture();
@@ -407,6 +400,8 @@ KX_BlenderMaterial::ActivatShaders(
if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
tmp->setShaderData(true, rasty);
+ else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && IsAlpha() && !rasty->GetUsingOverrideShader())
+ tmp->setShaderData(true, rasty);
else
tmp->setShaderData(false, rasty);
@@ -452,6 +447,8 @@ KX_BlenderMaterial::ActivateBlenderShaders(
if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
tmp->setBlenderShaderData(true, rasty);
+ else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && IsAlpha() && !rasty->GetUsingOverrideShader())
+ tmp->setBlenderShaderData(true, rasty);
else
tmp->setBlenderShaderData(false, rasty);
@@ -501,6 +498,8 @@ KX_BlenderMaterial::ActivateMat(
if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
tmp->setTexData( true,rasty );
+ else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && IsAlpha() && !rasty->GetUsingOverrideShader())
+ tmp->setTexData(true, rasty);
else
tmp->setTexData( false,rasty);
@@ -635,7 +634,8 @@ void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const
void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
{
- if (ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
+ if (ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED ||
+ (ras->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && IsAlpha() && !ras->GetUsingOverrideShader())) {
ras->SetAttribNum(0);
if (mShader && GLEW_ARB_shader_objects) {
if (mShader->GetAttribute() == BL_Shader::SHD_TANGENT) {
@@ -647,16 +647,9 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
ras->SetTexCoordNum(mMaterial->num_enabled);
- for (int i=0; i<mMaterial->num_enabled; i++) {
+ for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
int mode = mMaterial->mapping[i].mapping;
- if (mode &USECUSTOMUV)
- {
- if (!mMaterial->mapping[i].uvCoName.IsEmpty())
- ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i);
- continue;
- }
-
if ( mode &(USEREFL|USEOBJ))
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i);
else if (mode &USEORCO)
@@ -664,7 +657,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
else if (mode &USENORM)
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i);
else if (mode &USEUV)
- ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i);
+ ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV, i);
else if (mode &USETANG)
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i);
else
@@ -790,10 +783,19 @@ void KX_BlenderMaterial::UpdateIPO(
mMaterial->ref = (float)(ref);
}
-void KX_BlenderMaterial::SetBlenderGLSLShader(int layer)
+void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val)
+{
+ mScene= static_cast<KX_Scene *>(val);
+ if (mBlenderShader)
+ mBlenderShader->SetScene(mScene);
+
+ OnConstruction();
+}
+
+void KX_BlenderMaterial::SetBlenderGLSLShader()
{
if (!mBlenderShader)
- mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer);
+ mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, mLightLayer);
if (!mBlenderShader->Ok()) {
delete mBlenderShader;
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 7bc9c7c3863..c34a49e1bde 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -39,7 +39,8 @@ public:
void Initialize(
class KX_Scene* scene,
BL_Material* mat,
- GameSettings* game
+ GameSettings* game,
+ int lightlayer
);
virtual ~KX_BlenderMaterial();
@@ -76,8 +77,6 @@ public:
TCachingInfo& cachingInfo
)const;
- /* mMaterial is private, but need this for conversion */
- bool IsMaterial(const BL_Material *bl_mat) const;
Material* GetBlenderMaterial() const;
MTFace* GetMTFace(void) const;
unsigned int* GetMCol(void) const;
@@ -97,14 +96,7 @@ public:
MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha
);
- virtual void Replace_IScene(SCA_IScene *val)
- {
- mScene= static_cast<KX_Scene *>(val);
- if (mBlenderShader)
- {
- mBlenderShader->SetScene(mScene);
- }
- };
+ virtual void Replace_IScene(SCA_IScene *val);
#ifdef WITH_PYTHON
// --------------------------------
@@ -125,7 +117,7 @@ public:
// --------------------------------
// pre calculate to avoid pops/lag at startup
- virtual void OnConstruction(int layer);
+ virtual void OnConstruction();
static void EndFrame();
@@ -139,10 +131,11 @@ private:
unsigned int mBlendFunc[2];
bool mModified;
bool mConstructed; // if false, don't clean on exit
+ int mLightLayer;
void InitTextures();
- void SetBlenderGLSLShader(int layer);
+ void SetBlenderGLSLShader();
void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
void ActivateTexGen( RAS_IRasterizer *ras ) const;
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 20c41b95dd3..262ec541cf9 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -4,7 +4,7 @@
//under visual studio the #define in KX_ConvertPhysicsObject.h is quicker for recompilation
#include "KX_ConvertPhysicsObject.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "KX_BulletPhysicsController.h"
@@ -75,6 +75,11 @@ void KX_BulletPhysicsController::SetLinVelocityMin(float val)
CcdPhysicsController::SetLinVelocityMin(val);
}
+void KX_BulletPhysicsController::Jump()
+{
+ CcdPhysicsController::Jump();
+}
+
float KX_BulletPhysicsController::GetLinVelocityMax()
{
return (float)CcdPhysicsController::GetLinVelocityMax();
@@ -119,6 +124,11 @@ void KX_BulletPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool l
}
+void KX_BulletPhysicsController::SetWalkDirection(const MT_Vector3& dloc,bool local)
+{
+ CcdPhysicsController::SetWalkDirection(dloc[0],dloc[1],dloc[2],local);
+}
+
void KX_BulletPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local)
{
float rotval[9];
@@ -155,6 +165,13 @@ MT_Vector3 KX_BulletPhysicsController::GetVelocity(const MT_Point3& pos)
return MT_Vector3(linVel[0],linVel[1],linVel[2]);
}
+MT_Vector3 KX_BulletPhysicsController::GetWalkDirection()
+{
+ float dir[3];
+ CcdPhysicsController::GetWalkDirection(dir[0], dir[1], dir[2]);
+ return MT_Vector3(dir[0], dir[1], dir[2]);
+}
+
void KX_BulletPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local)
{
CcdPhysicsController::SetAngularVelocity(ang_vel.x(),ang_vel.y(),ang_vel.z(),local);
@@ -536,4 +553,4 @@ const char* KX_BulletPhysicsController::getName()
return 0;
}
-#endif // USE_BULLET
+#endif // WITH_BULLET
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
index 4813b39a34e..3d13744567b 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
@@ -8,7 +8,7 @@
#include "KX_IPhysicsController.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "CcdPhysicsController.h"
#endif
@@ -25,7 +25,7 @@ private:
btCollisionShape* m_bulletChildShape;
public:
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool character, bool compound);
virtual ~KX_BulletPhysicsController ();
#endif
@@ -40,11 +40,14 @@ public:
virtual void RelativeRotate(const MT_Matrix3x3& drot,bool local);
virtual void ApplyTorque(const MT_Vector3& torque,bool local);
virtual void ApplyForce(const MT_Vector3& force,bool local);
+ virtual void SetWalkDirection(const MT_Vector3& dir,bool local);
virtual MT_Vector3 GetLinearVelocity();
virtual MT_Vector3 GetAngularVelocity();
virtual MT_Vector3 GetVelocity(const MT_Point3& pos);
+ virtual MT_Vector3 GetWalkDirection();
virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local);
virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local);
+ virtual void Jump();
virtual void getOrientation(MT_Quaternion& orn);
virtual void setOrientation(const MT_Matrix3x3& orn);
virtual void setPosition(const MT_Point3& pos);
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index 59ca0d8d326..792a0759b59 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -115,7 +115,7 @@ void KX_CameraActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
/* copied from blender BLI_math ... don't know if there's an equivalent */
-static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis)
+static void Kx_VecUpMat3(float vec[3], float mat[3][3], short axis)
{
// Construct a camera matrix s.t. the specified axis
diff --git a/source/gameengine/Ketsji/KX_CharacterWrapper.cpp b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
index ce208f3a75f..3fbddef89be 100644
--- a/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
@@ -5,6 +5,7 @@
#include "KX_CharacterWrapper.h"
#include "PHY_ICharacter.h"
+#include "KX_PyMath.h"
KX_CharacterWrapper::KX_CharacterWrapper(PHY_ICharacter* character) :
PyObjectPlus(),
@@ -45,6 +46,9 @@ PyTypeObject KX_CharacterWrapper::Type = {
PyAttributeDef KX_CharacterWrapper::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("onGround", KX_CharacterWrapper, pyattr_get_onground),
KX_PYATTRIBUTE_RW_FUNCTION("gravity", KX_CharacterWrapper, pyattr_get_gravity, pyattr_set_gravity),
+ KX_PYATTRIBUTE_RW_FUNCTION("maxJumps", KX_CharacterWrapper, pyattr_get_max_jumps, pyattr_set_max_jumps),
+ KX_PYATTRIBUTE_RO_FUNCTION("jumpCount", KX_CharacterWrapper, pyattr_get_jump_count),
+ KX_PYATTRIBUTE_RW_FUNCTION("walkDirection", KX_CharacterWrapper, pyattr_get_walk_dir, pyattr_set_walk_dir),
{ NULL } //Sentinel
};
@@ -77,6 +81,55 @@ int KX_CharacterWrapper::pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_D
return PY_SET_ATTR_SUCCESS;
}
+PyObject *KX_CharacterWrapper::pyattr_get_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+
+ return PyLong_FromLong(self->m_character->GetMaxJumps());
+}
+
+int KX_CharacterWrapper::pyattr_set_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+ long param = PyLong_AsLong(value);
+
+ if (param == -1)
+ {
+ PyErr_SetString(PyExc_ValueError, "KX_CharacterWrapper.maxJumps: expected an integer");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ self->m_character->SetMaxJumps((int)param);
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject *KX_CharacterWrapper::pyattr_get_jump_count(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+
+ return PyLong_FromLong(self->m_character->GetJumpCount());
+}
+
+PyObject *KX_CharacterWrapper::pyattr_get_walk_dir(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+
+ return PyObjectFrom(self->m_character->GetWalkDirection());
+}
+
+int KX_CharacterWrapper::pyattr_set_walk_dir(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+ MT_Vector3 dir;
+ if (!PyVecTo(value, dir)) {
+ PyErr_SetString(PyExc_TypeError, "KX_CharacterWrapper.walkDirection: expected a vector");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ self->m_character->SetWalkDirection(dir);
+ return PY_SET_ATTR_SUCCESS;
+}
+
PyMethodDef KX_CharacterWrapper::Methods[] = {
KX_PYMETHODTABLE_NOARGS(KX_CharacterWrapper, jump),
{NULL,NULL} //Sentinel
diff --git a/source/gameengine/Ketsji/KX_CharacterWrapper.h b/source/gameengine/Ketsji/KX_CharacterWrapper.h
index 3b0058aca6f..d4d8f195102 100644
--- a/source/gameengine/Ketsji/KX_CharacterWrapper.h
+++ b/source/gameengine/Ketsji/KX_CharacterWrapper.h
@@ -26,6 +26,11 @@ public:
static PyObject* pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_jump_count(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_walk_dir(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_walk_dir(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
#endif // WITH_PYTHON
private:
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
index e71037d08a0..903966b79be 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
@@ -145,7 +145,7 @@ void KX_ConvertDynamoObject(KX_GameObject* gameobj,
struct KX_ObjectProperties* objprop);
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
void KX_ConvertBulletObject( class KX_GameObject* gameobj,
class RAS_MeshObject* meshobj,
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index ff3c46cb8ab..4a5a1704979 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -58,7 +58,7 @@ extern "C"{
#include "BKE_DerivedMesh.h"
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "BulletSoftBody/btSoftBody.h"
#include "CcdPhysicsEnvironment.h"
@@ -574,4 +574,4 @@ bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *fro
spc->ReplaceControllerShape(bm);
return true;
}
-#endif // USE_BULLET
+#endif // WITH_BULLET
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index c7f6954fd6c..3a60ccc85e9 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -42,7 +42,6 @@ typedef unsigned __int64 uint_ptr;
typedef unsigned long uint_ptr;
#endif
-#define KX_INERTIA_INFINITE 10000
#include "RAS_IPolygonMaterial.h"
#include "KX_BlenderMaterial.h"
#include "KX_GameObject.h"
@@ -1401,6 +1400,14 @@ CListValue* KX_GameObject::GetChildrenRecursive()
return list;
}
+KX_Scene* KX_GameObject::GetScene()
+{
+ SG_Node* node = this->GetSGNode();
+ KX_Scene* scene = static_cast<KX_Scene*>(node->GetSGClientInfo());
+
+ return scene;
+}
+
/* ---------------------------------------------------------------------
* Some stuff taken from the header
* --------------------------------------------------------------------- */
@@ -1755,8 +1762,7 @@ PyObject *KX_GameObject::PyReplaceMesh(PyObject *args)
PyObject *KX_GameObject::PyEndObject()
{
- SG_Node* node = this->GetSGNode();
- KX_Scene* scene = static_cast<KX_Scene*>(node->GetSGClientInfo());
+ KX_Scene* scene = GetScene();
scene->DelayedRemoveObject(this);
@@ -1778,7 +1784,7 @@ PyObject *KX_GameObject::PyReinstancePhysicsMesh(PyObject *args)
) {
return NULL;
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
/* gameobj and mesh can be NULL */
if (KX_ReInstanceBulletShapeFromMesh(this, gameobj, mesh))
Py_RETURN_TRUE;
@@ -2004,8 +2010,7 @@ PyObject *KX_GameObject::pyattr_get_group_members(void *self_v, const KX_PYATTRI
PyObject* KX_GameObject::pyattr_get_scene(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject *self = static_cast<KX_GameObject*>(self_v);
- SG_Node *node = self->GetSGNode();
- KX_Scene *scene = static_cast<KX_Scene *>(node->GetSGClientInfo());
+ KX_Scene *scene = self->GetScene();
if (scene) {
return scene->GetProxy();
}
@@ -3057,7 +3062,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
if (dist != 0.0f)
toPoint = fromPoint + dist * (toPoint-fromPoint).safe_normalized();
- PHY_IPhysicsEnvironment* pe = KX_GetActiveScene()->GetPhysicsEnvironment();
+ PHY_IPhysicsEnvironment* pe = GetScene()->GetPhysicsEnvironment();
KX_IPhysicsController *spc = GetPhysicsController();
KX_GameObject *parent = GetParent();
if (!spc && parent)
@@ -3203,7 +3208,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
return none_tuple_3();
}
- PHY_IPhysicsEnvironment* pe = KX_GetActiveScene()->GetPhysicsEnvironment();
+ PHY_IPhysicsEnvironment* pe = GetScene()->GetPhysicsEnvironment();
KX_IPhysicsController *spc = GetPhysicsController();
KX_GameObject *parent = GetParent();
if (!spc && parent)
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index e71af674a79..86c712ea017 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -501,8 +501,8 @@ public:
void SetUserCollisionGroup(short filter);
void SetUserCollisionMask(short mask);
/**
- * Extra broadphase check for user controllable collisions
- */
+ * Extra broadphase check for user controllable collisions
+ */
bool CheckCollision(KX_GameObject *other);
/**
@@ -923,6 +923,8 @@ public:
CListValue* GetChildren();
CListValue* GetChildrenRecursive();
+ KX_Scene* GetScene();
+
#ifdef WITH_PYTHON
/**
* \section Python interface functions.
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h
index 280b1816a1e..2019be57679 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.h
@@ -70,11 +70,14 @@ public:
virtual void RelativeRotate(const MT_Matrix3x3& drot,bool local)=0;
virtual void ApplyTorque(const MT_Vector3& torque,bool local)=0;
virtual void ApplyForce(const MT_Vector3& force,bool local)=0;
+ virtual void SetWalkDirection(const MT_Vector3& dir,bool local)=0;
virtual MT_Vector3 GetLinearVelocity()=0;
virtual MT_Vector3 GetAngularVelocity()=0;
virtual MT_Vector3 GetVelocity(const MT_Point3& pos)=0;
+ virtual MT_Vector3 GetWalkDirection()=0;
virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0;
virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0;
+ virtual void Jump()=0;
virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) = 0;
virtual void getOrientation(MT_Quaternion& orn)=0;
diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h
index 18fb336dbe0..616895a8269 100644
--- a/source/gameengine/Ketsji/KX_ISceneConverter.h
+++ b/source/gameengine/Ketsji/KX_ISceneConverter.h
@@ -57,10 +57,14 @@ public:
virtual void ConvertScene(
class KX_Scene* destinationscene,
class RAS_IRenderTools* rendertools,
- class RAS_ICanvas* canvas)=0;
+ class RAS_ICanvas* canvas,
+ bool libloading=false)=0;
virtual void RemoveScene(class KX_Scene *scene)=0;
+ // handle any pending merges from asynchronous loads
+ virtual void MergeAsyncLoads()=0;
+
virtual void SetAlwaysUseExpandFraming(bool to_what) = 0;
virtual void SetNewFileName(const STR_String& filename) = 0;
@@ -85,6 +89,10 @@ public:
virtual void SetGLSLMaterials(bool val) =0;
virtual bool GetGLSLMaterials()=0;
+ // cache materials during conversion
+ virtual void SetCacheMaterials(bool val) =0;
+ virtual bool GetCacheMaterials()=0;
+
virtual struct Scene* GetBlenderSceneForName(const STR_String& name)=0;
diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Ketsji/KX_IpoConvert.cpp
index a81d52f6698..9ec354ec840 100644
--- a/source/gameengine/Converter/KX_IpoConvert.cpp
+++ b/source/gameengine/Ketsji/KX_IpoConvert.cpp
@@ -162,32 +162,29 @@ SG_Controller *BL_CreateIPO(struct bAction *action, KX_GameObject* gameobj, KX_B
}
}
- {
- KX_ObColorIpoSGController* ipocontr_obcol=NULL;
-
- for (int i=0; i<4; i++) {
- if ((interp = adtList->GetScalarInterpolator("color", i))) {
- if (!ipocontr_obcol) {
- ipocontr_obcol = new KX_ObColorIpoSGController();
- gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
- ipocontr_obcol->SetObject(gameobj->GetSGNode());
- }
- interpolator= new KX_ScalarInterpolator(&ipocontr_obcol->m_rgba[i], interp);
- ipocontr_obcol->AddInterpolator(interpolator);
- }
- }
- }
return ipocontr;
}
-void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_BlenderSceneConverter *converter)
+
+SG_Controller *BL_CreateObColorIPO(struct bAction *action, KX_GameObject* gameobj, KX_BlenderSceneConverter *converter)
{
- if (blenderobject->adt) {
- SG_Controller *ipocontr = BL_CreateIPO(blenderobject->adt->action, gameobj, converter);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
+ KX_ObColorIpoSGController* ipocontr_obcol=NULL;
+ KX_IInterpolator *interpolator;
+ KX_IScalarInterpolator *interp;
+ BL_InterpolatorList *adtList= GetAdtList(action, converter);
+
+ for (int i=0; i<4; i++) {
+ if ((interp = adtList->GetScalarInterpolator("color", i))) {
+ if (!ipocontr_obcol) {
+ ipocontr_obcol = new KX_ObColorIpoSGController();
+ }
+ interpolator= new KX_ScalarInterpolator(&ipocontr_obcol->m_rgba[i], interp);
+ ipocontr_obcol->AddInterpolator(interpolator);
+ }
}
+
+ return ipocontr_obcol;
}
SG_Controller *BL_CreateLampIPO(struct bAction *action, KX_GameObject* lightobj, KX_BlenderSceneConverter *converter)
@@ -233,19 +230,6 @@ SG_Controller *BL_CreateLampIPO(struct bAction *action, KX_GameObject* lightobj
return ipocontr;
}
-void BL_ConvertLampIpos(struct Lamp* blenderlamp, KX_GameObject *lightobj,KX_BlenderSceneConverter *converter)
-{
-
- if (blenderlamp->adt) {
-
- SG_Controller* ipocontr = BL_CreateLampIPO(blenderlamp->adt->action, lightobj, converter);
- lightobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(lightobj->GetSGNode());
-
-
- }
-}
-
SG_Controller *BL_CreateCameraIPO(struct bAction *action, KX_GameObject* cameraobj, KX_BlenderSceneConverter *converter)
{
KX_CameraIpoSGController* ipocontr = new KX_CameraIpoSGController();
@@ -285,17 +269,6 @@ SG_Controller *BL_CreateCameraIPO(struct bAction *action, KX_GameObject* camera
return ipocontr;
}
-void BL_ConvertCameraIpos(struct Camera* blendercamera, KX_GameObject *cameraobj,KX_BlenderSceneConverter *converter)
-{
-
- if (blendercamera->adt) {
- SG_Controller* ipocontr = BL_CreateCameraIPO(blendercamera->adt->action, cameraobj, converter);
- cameraobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(cameraobj->GetSGNode());
- }
-}
-
-
void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *converter)
{
@@ -344,141 +317,97 @@ void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *co
}
}
-static void ConvertMaterialIpos(
+SG_Controller *BL_CreateMaterialIpo(
+ struct bAction *action,
Material* blendermaterial,
dword matname_hash,
KX_GameObject* gameobj,
KX_BlenderSceneConverter *converter
)
{
- if (blendermaterial->adt) {
- KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
-
- BL_InterpolatorList *adtList= GetAdtList(blendermaterial->adt->action, converter);
+ KX_MaterialIpoController* ipocontr = NULL;
+ BL_InterpolatorList *adtList= GetAdtList(action, converter);
+ KX_IInterpolator *interpolator;
+ KX_IScalarInterpolator *sinterp;
- ipocontr->m_rgba[0] = blendermaterial->r;
- ipocontr->m_rgba[1] = blendermaterial->g;
- ipocontr->m_rgba[2] = blendermaterial->b;
- ipocontr->m_rgba[3] = blendermaterial->alpha;
-
- ipocontr->m_specrgb[0] = blendermaterial->specr;
- ipocontr->m_specrgb[1] = blendermaterial->specg;
- ipocontr->m_specrgb[2] = blendermaterial->specb;
-
- ipocontr->m_hard = blendermaterial->har;
- ipocontr->m_spec = blendermaterial->spec;
- ipocontr->m_ref = blendermaterial->ref;
- ipocontr->m_emit = blendermaterial->emit;
- ipocontr->m_alpha = blendermaterial->alpha;
-
- KX_IInterpolator *interpolator;
- KX_IScalarInterpolator *sinterp;
-
- // --
- for (int i=0; i<3; i++) {
- if ((sinterp = adtList->GetScalarInterpolator("diffuse_color", i))) {
- if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
- }
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[i], sinterp);
- ipocontr->AddInterpolator(interpolator);
- }
- }
-
- if ((sinterp = adtList->GetScalarInterpolator("alpha", 0))) {
+ // --
+ for (int i=0; i<3; i++) {
+ if ((sinterp = adtList->GetScalarInterpolator("diffuse_color", i))) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
}
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[3], sinterp);
+ interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[i], sinterp);
ipocontr->AddInterpolator(interpolator);
}
+ }
- for (int i=0; i<3; i++) {
- if ((sinterp = adtList->GetScalarInterpolator("specular_color", i))) {
- if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
- }
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_specrgb[i], sinterp);
- ipocontr->AddInterpolator(interpolator);
- }
- }
-
- if ((sinterp = adtList->GetScalarInterpolator("specular_hardness", 0))) {
- if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
- }
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_hard, sinterp);
- ipocontr->AddInterpolator(interpolator);
+ if ((sinterp = adtList->GetScalarInterpolator("alpha", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_MaterialIpoController(matname_hash);
}
+ interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[3], sinterp);
+ ipocontr->AddInterpolator(interpolator);
+ }
- if ((sinterp = adtList->GetScalarInterpolator("specularity", 0))) {
+ for (int i=0; i<3; i++) {
+ if ((sinterp = adtList->GetScalarInterpolator("specular_color", i))) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
}
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_spec, sinterp);
+ interpolator= new KX_ScalarInterpolator(&ipocontr->m_specrgb[i], sinterp);
ipocontr->AddInterpolator(interpolator);
}
-
- if ((sinterp = adtList->GetScalarInterpolator("diffuse_reflection", 0))) {
- if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
- }
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_ref, sinterp);
- ipocontr->AddInterpolator(interpolator);
+ }
+
+ if ((sinterp = adtList->GetScalarInterpolator("specular_hardness", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_MaterialIpoController(matname_hash);
}
-
- if ((sinterp = adtList->GetScalarInterpolator("emit", 0))) {
- if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController(matname_hash);
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
- }
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_emit, sinterp);
- ipocontr->AddInterpolator(interpolator);
+ interpolator= new KX_ScalarInterpolator(&ipocontr->m_hard, sinterp);
+ ipocontr->AddInterpolator(interpolator);
+ }
+
+ if ((sinterp = adtList->GetScalarInterpolator("specularity", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_MaterialIpoController(matname_hash);
}
+ interpolator= new KX_ScalarInterpolator(&ipocontr->m_spec, sinterp);
+ ipocontr->AddInterpolator(interpolator);
}
-}
-void BL_ConvertMaterialIpos(
- struct Object* blenderobject,
- KX_GameObject* gameobj,
- KX_BlenderSceneConverter *converter
- )
-{
- if (blenderobject->totcol==1)
- {
- Material *mat = give_current_material(blenderobject, 1);
- // if there is only one material attached to the mesh then set material_index in BL_ConvertMaterialIpos to NULL
- // --> this makes the UpdateMaterialData function in KX_GameObject.cpp use the old hack of using SetObjectColor
- // because this yields a better performance as not all the vertex colors need to be edited
- if (mat) ConvertMaterialIpos(mat, 0, gameobj, converter);
+ if ((sinterp = adtList->GetScalarInterpolator("diffuse_reflection", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_MaterialIpoController(matname_hash);
+ }
+ interpolator= new KX_ScalarInterpolator(&ipocontr->m_ref, sinterp);
+ ipocontr->AddInterpolator(interpolator);
}
- else
- {
- for (int material_index=1; material_index <= blenderobject->totcol; material_index++)
- {
- Material *mat = give_current_material(blenderobject, material_index);
- STR_HashedString matname;
- if (mat) {
- matname= mat->id.name; // who is using this name? can we remove the MA here?
- ConvertMaterialIpos(mat, matname.hash(), gameobj, converter);
- }
+
+ if ((sinterp = adtList->GetScalarInterpolator("emit", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_MaterialIpoController(matname_hash);
}
+ interpolator= new KX_ScalarInterpolator(&ipocontr->m_emit, sinterp);
+ ipocontr->AddInterpolator(interpolator);
}
-}
+ if (ipocontr) {
+ ipocontr->m_rgba[0] = blendermaterial->r;
+ ipocontr->m_rgba[1] = blendermaterial->g;
+ ipocontr->m_rgba[2] = blendermaterial->b;
+ ipocontr->m_rgba[3] = blendermaterial->alpha;
+
+ ipocontr->m_specrgb[0] = blendermaterial->specr;
+ ipocontr->m_specrgb[1] = blendermaterial->specg;
+ ipocontr->m_specrgb[2] = blendermaterial->specb;
+
+ ipocontr->m_hard = blendermaterial->har;
+ ipocontr->m_spec = blendermaterial->spec;
+ ipocontr->m_ref = blendermaterial->ref;
+ ipocontr->m_emit = blendermaterial->emit;
+ ipocontr->m_alpha = blendermaterial->alpha;
+ }
+
+ return ipocontr;
+}
diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Ketsji/KX_IpoConvert.h
index 861a2ba66f2..1f4e1bea96d 100644
--- a/source/gameengine/Converter/KX_IpoConvert.h
+++ b/source/gameengine/Ketsji/KX_IpoConvert.h
@@ -33,37 +33,36 @@
#define __KX_IPOCONVERT_H__
struct Object;
+struct bAction;
+class SG_Controller;
+class KX_GameObject;
+class KX_BlenderSceneConverter;
-class SG_Controller *BL_CreateIPO(struct bAction *action,
- class KX_GameObject* gameobj,
- class KX_BlenderSceneConverter *converter);
+SG_Controller *BL_CreateIPO(bAction *action,
+ KX_GameObject* gameobj,
+ KX_BlenderSceneConverter *converter);
-void BL_ConvertIpos(struct Object* blenderobject,
- class KX_GameObject* gameobj,
- class KX_BlenderSceneConverter *converter);
+SG_Controller *BL_CreateObColorIPO(bAction *action,
+ KX_GameObject* gameobj,
+ KX_BlenderSceneConverter *converter);
-class SG_Controller *BL_CreateLampIPO(struct bAction *action,
- class KX_GameObject* lightobj,
- class KX_BlenderSceneConverter *converter);
-
-void BL_ConvertLampIpos(struct Lamp* blenderlight,
- class KX_GameObject* lightobj,
- class KX_BlenderSceneConverter *converter);
+SG_Controller *BL_CreateLampIPO(bAction *action,
+ KX_GameObject* lightobj,
+ KX_BlenderSceneConverter *converter);
void BL_ConvertWorldIpos(struct World* blenderworld,
- class KX_BlenderSceneConverter *converter);
-
-class SG_Controller *BL_CreateCameraIPO(struct bAction *action,
- class KX_GameObject* cameraobj,
- class KX_BlenderSceneConverter *converter);
+ KX_BlenderSceneConverter *converter);
-void BL_ConvertCameraIpos(struct Camera* blendercamera,
- class KX_GameObject* cameraobj,
- class KX_BlenderSceneConverter *converter);
+SG_Controller *BL_CreateCameraIPO(bAction *action,
+ KX_GameObject* cameraobj,
+ KX_BlenderSceneConverter *converter);
-void BL_ConvertMaterialIpos(struct Object* blenderobject,
- class KX_GameObject* materialobj,
- class KX_BlenderSceneConverter *converter);
+SG_Controller *BL_CreateMaterialIpo(
+ bAction *action,
+ class Material* blendermaterial,
+ dword matname_hash,
+ KX_GameObject* gameobj,
+ KX_BlenderSceneConverter *converter);
#endif /* __KX_IPOCONVERT_H__ */
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index a12e12ccef2..23419f11cd5 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -83,7 +83,7 @@
// not valid, skip rendering this frame.
//#define NZC_GUARDED_OUTPUT
#define DEFAULT_LOGIC_TIC_RATE 60.0
-#define DEFAULT_PHYSICS_TIC_RATE 60.0
+//#define DEFAULT_PHYSICS_TIC_RATE 60.0
#ifdef FREE_WINDOWS /* XXX mingw64 (gcc 4.7.0) defines a macro for DrawText that translates to DrawTextA. Not good */
#ifdef DrawText
@@ -592,6 +592,8 @@ bool KX_KetsjiEngine::NextFrame()
m_frameTime += framestep;
+ m_sceneconverter->MergeAsyncLoads();
+
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
// for each scene, call the proceed functions
{
@@ -1165,7 +1167,7 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW);
/* binds framebuffer object, sets up camera .. */
- light->BindShadowBuffer(m_rasterizer, cam, camtrans);
+ light->BindShadowBuffer(m_rasterizer, m_canvas, cam, camtrans);
/* update scene */
scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
@@ -1444,7 +1446,7 @@ void KX_KetsjiEngine::RenderDebugProperties()
int xcoord = 12; // mmmm, these constants were taken from blender source
int ycoord = 17; // to 'mimic' behavior
- int profile_indent = 64;
+ int profile_indent = 72;
float tottime = m_logger->GetAverage();
if (tottime < 1e-6f) {
@@ -1455,15 +1457,14 @@ void KX_KetsjiEngine::RenderDebugProperties()
RAS_Rect viewport;
m_canvas->SetViewPort(0, 0, int(m_canvas->GetWidth()), int(m_canvas->GetHeight()));
- if (m_show_framerate || m_show_profile) {
+ if (m_show_framerate || m_show_profile) {
/* Title for profiling("Profile") */
- debugtxt.Format("Profile");
m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
- xcoord + const_xindent + title_xmargin, // Adds the constant x indent (0 for now) to the title x margin
- ycoord,
- m_canvas->GetWidth() /* RdV, TODO ?? */,
- m_canvas->GetHeight() /* RdV, TODO ?? */);
+ "Profile",
+ xcoord + const_xindent + title_xmargin, // Adds the constant x indent (0 for now) to the title x margin
+ ycoord,
+ m_canvas->GetWidth() /* RdV, TODO ?? */,
+ m_canvas->GetHeight() /* RdV, TODO ?? */);
// Increase the indent by default increase
ycoord += const_ysize;
@@ -1473,46 +1474,44 @@ void KX_KetsjiEngine::RenderDebugProperties()
/* Framerate display */
if (m_show_framerate) {
- debugtxt.Format("Frametime :");
- m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
- xcoord + const_xindent,
- ycoord,
- m_canvas->GetWidth() /* RdV, TODO ?? */,
- m_canvas->GetHeight() /* RdV, TODO ?? */);
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ "Frametime :",
+ xcoord + const_xindent,
+ ycoord,
+ m_canvas->GetWidth() /* RdV, TODO ?? */,
+ m_canvas->GetHeight() /* RdV, TODO ?? */);
- debugtxt.Format("%5.1fms (%5.1f fps)", tottime * 1000.f, 1.0/tottime);
- m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
- xcoord + const_xindent + profile_indent,
- ycoord,
- m_canvas->GetWidth() /* RdV, TODO ?? */,
- m_canvas->GetHeight() /* RdV, TODO ?? */);
+ debugtxt.Format("%5.1fms (%.1ffps)", tottime * 1000.f, 1.0/tottime);
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ debugtxt.ReadPtr(),
+ xcoord + const_xindent + profile_indent,
+ ycoord,
+ m_canvas->GetWidth() /* RdV, TODO ?? */,
+ m_canvas->GetHeight() /* RdV, TODO ?? */);
// Increase the indent by default increase
ycoord += const_ysize;
}
/* Profile display */
- if (m_show_profile)
- {
- for (int j = tc_first; j < tc_numCategories; j++)
- {
- debugtxt.Format(m_profileLabels[j]);
+ if (m_show_profile) {
+ for (int j = tc_first; j < tc_numCategories; j++) {
m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
+ m_profileLabels[j],
xcoord + const_xindent,
- ycoord,
+ ycoord,
m_canvas->GetWidth(),
m_canvas->GetHeight());
double time = m_logger->GetAverage((KX_TimeCategory)j);
- debugtxt.Format("%5.2fms (%2d%%)", time*1000.f, (int)(time/tottime * 100.f));
+ debugtxt.Format("%5.2fms | %d%%", time*1000.f, (int)(time/tottime * 100.f));
m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
+ debugtxt.ReadPtr(),
xcoord + const_xindent + profile_indent, ycoord,
m_canvas->GetWidth(),
m_canvas->GetHeight());
+
+ m_rendertools->RenderBox2D(xcoord + (int)(2.2 * profile_indent), ycoord, m_canvas->GetWidth(), m_canvas->GetHeight(), time/tottime);
ycoord += const_ysize;
}
}
@@ -1520,17 +1519,15 @@ void KX_KetsjiEngine::RenderDebugProperties()
ycoord += title_y_top_margin;
/* Property display*/
- if (m_show_debug_properties && m_propertiesPresent)
- {
+ if (m_show_debug_properties && m_propertiesPresent) {
/* Title for debugging("Debug properties") */
- debugtxt.Format("Debug Properties");
- m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
- xcoord + const_xindent + title_xmargin, // Adds the constant x indent (0 for now) to the title x margin
- ycoord,
- m_canvas->GetWidth() /* RdV, TODO ?? */,
- m_canvas->GetHeight() /* RdV, TODO ?? */);
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ "Debug Properties",
+ xcoord + const_xindent + title_xmargin, // Adds the constant x indent (0 for now) to the title x margin
+ ycoord,
+ m_canvas->GetWidth() /* RdV, TODO ?? */,
+ m_canvas->GetHeight() /* RdV, TODO ?? */);
// Increase the indent by default increase
ycoord += const_ysize;
@@ -1538,20 +1535,18 @@ void KX_KetsjiEngine::RenderDebugProperties()
ycoord += title_y_bottom_margin;
KX_SceneList::iterator sceneit;
- for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
- {
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) {
KX_Scene* scene = *sceneit;
/* the 'normal' debug props */
vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
for (vector<SCA_DebugProp*>::iterator it = debugproplist.begin();
- !(it==debugproplist.end());it++)
+ !(it==debugproplist.end());it++)
{
- CValue* propobj = (*it)->m_obj;
+ CValue *propobj = (*it)->m_obj;
STR_String objname = propobj->GetName();
STR_String propname = (*it)->m_name;
- if (propname == "__state__")
- {
+ if (propname == "__state__") {
// reserve name for object state
KX_GameObject* gameobj = static_cast<KX_GameObject*>(propobj);
unsigned int state = gameobj->GetState();
@@ -1569,27 +1564,25 @@ void KX_KetsjiEngine::RenderDebugProperties()
first = false;
}
}
- m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
- xcoord + const_xindent,
- ycoord,
- m_canvas->GetWidth(),
- m_canvas->GetHeight());
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ debugtxt.ReadPtr(),
+ xcoord + const_xindent,
+ ycoord,
+ m_canvas->GetWidth(),
+ m_canvas->GetHeight());
ycoord += const_ysize;
}
- else
- {
- CValue* propval = propobj->GetProperty(propname);
- if (propval)
- {
+ else {
+ CValue *propval = propobj->GetProperty(propname);
+ if (propval) {
STR_String text = propval->GetText();
debugtxt = objname + ": '" + propname + "' = " + text;
- m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
- debugtxt.Ptr(),
- xcoord + const_xindent,
- ycoord,
- m_canvas->GetWidth(),
- m_canvas->GetHeight());
+ m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
+ debugtxt.ReadPtr(),
+ xcoord + const_xindent,
+ ycoord,
+ m_canvas->GetWidth(),
+ m_canvas->GetHeight());
ycoord += const_ysize;
}
}
@@ -1625,19 +1618,14 @@ KX_Scene* KX_KetsjiEngine::FindScene(const STR_String& scenename)
void KX_KetsjiEngine::ConvertAndAddScene(const STR_String& scenename,bool overlay)
{
// only add scene when it doesn't exist!
- if (FindScene(scenename))
- {
- STR_String tmpname = scenename;
- printf("warning: scene %s already exists, not added!\n",tmpname.Ptr());
+ if (FindScene(scenename)) {
+ printf("warning: scene %s already exists, not added!\n",scenename.ReadPtr());
}
- else
- {
- if (overlay)
- {
+ else {
+ if (overlay) {
m_addingOverlayScenes.insert(scenename);
}
- else
- {
+ else {
m_addingBackgroundScenes.insert(scenename);
}
}
@@ -1686,7 +1674,7 @@ void KX_KetsjiEngine::RemoveScheduledScenes()
}
}
-KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
+KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading)
{
KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
m_mousedevice,
@@ -1697,7 +1685,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
m_sceneconverter->ConvertScene(tmpscene,
m_rendertools,
- m_canvas);
+ m_canvas,
+ libloading);
return tmpscene;
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 972594bd90f..92ffaf47aa4 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -413,7 +413,7 @@ public:
void GetOverrideFrameColor(float& r, float& g, float& b) const;
KX_Scene* CreateScene(const STR_String& scenename);
- KX_Scene* CreateScene(Scene *scene);
+ KX_Scene* CreateScene(Scene *scene, bool libloading=false);
GlobalSettings* GetGlobalSettings(void);
void SetGlobalSettings(GlobalSettings* gs);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index cf58d18838a..a8f309cc592 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -236,7 +236,7 @@ int KX_LightObject::GetShadowLayer()
return 0;
}
-void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_Transform& camtrans)
+void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans)
{
GPULamp *lamp;
float viewmat[4][4], winmat[4][4];
@@ -246,6 +246,12 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T
lamp = GetGPULamp();
GPU_lamp_shadow_buffer_bind(lamp, viewmat, &winsize, winmat);
+ if (GPU_lamp_shadow_buffer_type(lamp) == LA_SHADMAP_VARIANCE)
+ ras->SetUsingOverrideShader(true);
+
+ /* GPU_lamp_shadow_buffer_bind() changes the viewport, so update the canvas */
+ canvas->UpdateViewPort(0, 0, winsize, winsize);
+
/* setup camera transformation */
MT_Matrix4x4 modelviewmat((float*)viewmat);
MT_Matrix4x4 projectionmat((float*)winmat);
@@ -273,6 +279,9 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
{
GPULamp *lamp = GetGPULamp();
GPU_lamp_shadow_buffer_unbind(lamp);
+
+ if (GPU_lamp_shadow_buffer_type(lamp) == LA_SHADMAP_VARIANCE)
+ ras->SetUsingOverrideShader(false);
}
struct Image *KX_LightObject::GetTextureImage(short texslot)
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 52f076c772a..f88fc7f6a1b 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -64,7 +64,7 @@ public:
struct GPULamp *GetGPULamp();
bool HasShadowBuffer();
int GetShadowLayer();
- void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans);
+ void BindShadowBuffer(class RAS_IRasterizer *ras, class RAS_ICanvas *canvas, class KX_Camera *cam, class MT_Transform& camtrans);
void UnbindShadowBuffer(class RAS_IRasterizer *ras);
struct Image *GetTextureImage(short texslot);
void Update();
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index d83e98d4712..57695df2782 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -338,20 +338,20 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds)
for (i = it.startvertex; i < it.endvertex; i++) {
RAS_TexVert *vert = &it.vertex[i];
if (uvindex_from != -1) {
- if (uvindex_from == 0) vert->SetUV2(vert->getUV1());
- else vert->SetUV1(vert->getUV2());
+ if (uvindex_from == 0) vert->SetUV(1, vert->getUV(0));
+ else vert->SetUV(0, vert->getUV(1));
}
switch (uvindex) {
case 0:
- vert->TransformUV1(transform);
+ vert->TransformUV(0, transform);
break;
case 1:
- vert->TransformUV2(transform);
+ vert->TransformUV(1, transform);
break;
case -1:
- vert->TransformUV1(transform);
- vert->TransformUV2(transform);
+ vert->TransformUV(0, transform);
+ vert->TransformUV(1, transform);
break;
}
}
diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp b/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp
index f7e3194ee78..7f81f221c07 100644
--- a/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp
+++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp
@@ -45,10 +45,10 @@ bool KX_ObColorIpoSGController::Update(double currentTime)
{
if (m_modified)
{
- m_rgba[0]=0;
- m_rgba[1]=0;
- m_rgba[2]=0;
- m_rgba[3]=0;
+ SG_Spatial* ob = (SG_Spatial*)m_pObject;
+ KX_GameObject* kxgameobj= (KX_GameObject*) ob->GetSGClientObject();
+
+ m_rgba = kxgameobj->GetObjectColor();
T_InterpolatorList::iterator i;
for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
@@ -56,9 +56,6 @@ bool KX_ObColorIpoSGController::Update(double currentTime)
}
- SG_Spatial* ob = (SG_Spatial*)m_pObject;
- KX_GameObject* kxgameobj= (KX_GameObject*) ob->GetSGClientObject();
-
kxgameobj->SetObjectColor(m_rgba);
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
index 931039bc54c..b4ee339568c 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -81,6 +81,16 @@ KX_ObjectActuator(
m_pid = m_torque;
}
+ if (m_bitLocalFlag.CharacterMotion)
+ {
+ KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent());
+
+ if (!parent->GetPhysicsController() || !parent->GetPhysicsController()->IsCharacter())
+ {
+ printf("Character motion enabled on non-character object (%s), falling back to simple motion.\n", parent->GetName().Ptr());
+ m_bitLocalFlag.CharacterMotion = false;
+ }
+ }
if (m_reference)
m_reference->RegisterActuator(this);
UpdateFuzzyFlags();
@@ -116,10 +126,10 @@ bool KX_ObjectActuator::Update()
m_active_combined_velocity = false;
}
- // Explicitly stop the movement if we're using a character (apply movement is a little different for characters)
- if (parent->GetPhysicsController() && parent->GetPhysicsController()->IsCharacter()) {
+ // Explicitly stop the movement if we're using character motion
+ if (m_bitLocalFlag.CharacterMotion) {
MT_Vector3 vec(0.0, 0.0, 0.0);
- parent->ApplyMovement(vec, true);
+ parent->GetPhysicsController()->SetWalkDirection(vec, true);
}
m_linear_damping_active = false;
@@ -205,8 +215,35 @@ bool KX_ObjectActuator::Update()
m_previous_error = e;
m_error_accumulator = I;
parent->ApplyForce(m_force,(m_bitLocalFlag.LinearVelocity) != 0);
- } else
+ } else if(m_bitLocalFlag.CharacterMotion)
{
+ MT_Vector3 dir = m_dloc;
+
+ if (m_bitLocalFlag.AddOrSetCharLoc) {
+ MT_Vector3 old_dir = parent->GetPhysicsController()->GetWalkDirection();
+
+ if (!old_dir.fuzzyZero()) {
+ MT_Scalar mag = old_dir.length();
+
+ dir = dir + old_dir;
+ if (!dir.fuzzyZero())
+ dir = dir.normalized() * mag;
+ }
+ }
+
+ // We always want to set the walk direction since a walk direction of (0, 0, 0) should stop the character
+ parent->GetPhysicsController()->SetWalkDirection(dir, (m_bitLocalFlag.DLoc) != 0);
+
+ if (!m_bitLocalFlag.ZeroDRot)
+ {
+ parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
+ }
+ if (m_bitLocalFlag.CharacterJump)
+ {
+ parent->GetPhysicsController()->Jump();
+ }
+ }
+ else {
if (!m_bitLocalFlag.ZeroForce)
{
parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index b0efee550af..1f2453e3700 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -54,7 +54,12 @@ struct KX_LocalFlags {
LinearVelocity(false),
AngularVelocity(false),
AddOrSetLinV(false),
+ AddOrSetCharLoc(false),
+ ServoControl(false),
+ CharacterMotion(false),
+ CharacterJump(false),
ZeroForce(false),
+ ZeroTorque(false),
ZeroDRot(false),
ZeroDLoc(false),
ZeroLinearVelocity(false),
@@ -69,7 +74,10 @@ struct KX_LocalFlags {
bool LinearVelocity;
bool AngularVelocity;
bool AddOrSetLinV;
+ bool AddOrSetCharLoc;
bool ServoControl;
+ bool CharacterMotion;
+ bool CharacterJump;
bool ZeroForce;
bool ZeroTorque;
bool ZeroDRot;
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index f157d9ed20a..5ce370ccdfe 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -109,7 +109,7 @@ void KX_PolygonMaterial::Initialize(
m_mcol = *mcol;
}
else {
- m_mcol = 0;
+ memset(&m_mcol, 0, sizeof(m_mcol));
}
m_material = ma;
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index 2ce8f480c1c..89bfb4ff9fb 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -60,7 +60,7 @@ class KX_PolygonMaterial : public PyObjectPlus, public RAS_IPolyMaterial
private:
/** Blender texture face structure. */
mutable MTFace m_tface;
- mutable unsigned int m_mcol; /* for text color (only) */
+ mutable unsigned int m_mcol;
Material* m_material;
#ifdef WITH_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index 9bb09d56de6..2e9b988dff1 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -43,7 +43,7 @@
#include "PyObjectPlus.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
# include "LinearMath/btIDebugDraw.h"
#endif
@@ -716,7 +716,7 @@ PyObject *initPythonConstraintBinding()
PyDict_SetItemString(d, "error", ErrorObject);
Py_DECREF(ErrorObject);
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
//Debug Modes constants to be used with setDebugMode() python function
KX_MACRO_addTypesToDict(d, DBG_NODEBUG, btIDebugDraw::DBG_NoDebug);
KX_MACRO_addTypesToDict(d, DBG_DRAWWIREFRAME, btIDebugDraw::DBG_DrawWireframe);
@@ -732,7 +732,7 @@ PyObject *initPythonConstraintBinding()
KX_MACRO_addTypesToDict(d, DBG_DRAWCONSTRAINTS, btIDebugDraw::DBG_DrawConstraints);
KX_MACRO_addTypesToDict(d, DBG_DRAWCONSTRAINTLIMITS, btIDebugDraw::DBG_DrawConstraintLimits);
KX_MACRO_addTypesToDict(d, DBG_FASTWIREFRAME, btIDebugDraw::DBG_FastWireframe);
-#endif // USE_BULLET
+#endif // WITH_BULLET
//Constraint types to be used with createConstraint() python function
KX_MACRO_addTypesToDict(d, POINTTOPOINT_CONSTRAINT, PHY_POINT2POINT_CONSTRAINT);
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 996be97c474..a54d4909db9 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -92,6 +92,8 @@ extern "C" {
#include "SCA_PropertySensor.h"
#include "SCA_RandomActuator.h"
#include "SCA_KeyboardSensor.h" /* IsPrintable, ToCharacter */
+#include "SCA_JoystickManager.h" /* JOYINDEX_MAX */
+#include "SCA_PythonJoystick.h"
#include "SCA_PythonKeyboard.h"
#include "SCA_PythonMouse.h"
#include "KX_ConstraintActuator.h"
@@ -134,6 +136,7 @@ extern "C" {
/* for converting new scenes */
#include "KX_BlenderSceneConverter.h"
+#include "KX_LibLoadStatus.h"
#include "KX_MeshProxy.h" /* for creating a new library of mesh objects */
extern "C" {
#include "BKE_idcode.h"
@@ -151,6 +154,7 @@ static char gp_GamePythonPathOrig[FILE_MAX] = ""; // not super happy about this,
static SCA_PythonKeyboard* gp_PythonKeyboard = NULL;
static SCA_PythonMouse* gp_PythonMouse = NULL;
+static SCA_PythonJoystick* gp_PythonJoysticks[JOYINDEX_MAX] = {NULL};
#endif // WITH_PYTHON
static KX_Scene* gp_KetsjiScene = NULL;
@@ -194,7 +198,7 @@ static PyObject *gp_OrigPythonSysModules= NULL;
/* Macro for building the keyboard translation */
//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromLong(SCA_IInputDevice::KX_##name))
-#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item)
+//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item)
/* For the defines for types from logic bricks, we do stuff explicitly... */
#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name2)); Py_DECREF(item)
@@ -667,14 +671,15 @@ static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
Py_buffer py_buffer;
py_buffer.buf = NULL;
char *err_str= NULL;
+ KX_LibLoadStatus *status = NULL;
short options=0;
- int load_actions=0, verbose=0, load_scripts=1;
+ int load_actions=0, verbose=0, load_scripts=1, async=0;
- static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", "load_scripts", NULL};
+ static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", "load_scripts", "async", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*iii:LibLoad", const_cast<char**>(kwlist),
- &path, &group, &py_buffer, &load_actions, &verbose, &load_scripts))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*iiIi:LibLoad", const_cast<char**>(kwlist),
+ &path, &group, &py_buffer, &load_actions, &verbose, &load_scripts, &async))
return NULL;
/* setup options */
@@ -684,6 +689,8 @@ static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
options |= KX_BlenderSceneConverter::LIB_LOAD_VERBOSE;
if (load_scripts != 0)
options |= KX_BlenderSceneConverter::LIB_LOAD_LOAD_SCRIPTS;
+ if (async != 0)
+ options |= KX_BlenderSceneConverter::LIB_LOAD_ASYNC;
if (!py_buffer.buf)
{
@@ -692,16 +699,16 @@ static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
BLI_strncpy(abs_path, path, sizeof(abs_path));
BLI_path_abs(abs_path, gp_GamePythonPath);
- if (kx_scene->GetSceneConverter()->LinkBlendFilePath(abs_path, group, kx_scene, &err_str, options)) {
- Py_RETURN_TRUE;
+ if ((status=kx_scene->GetSceneConverter()->LinkBlendFilePath(abs_path, group, kx_scene, &err_str, options))) {
+ return status->GetProxy();
}
}
else
{
- if (kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str, options)) {
+ if ((status=kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str, options))) {
PyBuffer_Release(&py_buffer);
- Py_RETURN_TRUE;
+ return status->GetProxy();
}
PyBuffer_Release(&py_buffer);
@@ -1420,6 +1427,22 @@ PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
gp_PythonMouse = new SCA_PythonMouse(gp_KetsjiEngine->GetMouseDevice(), gp_Canvas);
PyDict_SetItemString(d, "mouse", gp_PythonMouse->NewProxy(true));
+ PyObject* joylist = PyList_New(JOYINDEX_MAX);
+ for (int i=0; i<JOYINDEX_MAX; ++i) {
+ SCA_Joystick* joy = SCA_Joystick::GetInstance(i);
+ 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);
+ }
+ }
+ PyDict_SetItemString(d, "joysticks", joylist);
+
ErrorObject = PyUnicode_FromString("GameLogic.error");
PyDict_SetItemString(d, "error", ErrorObject);
Py_DECREF(ErrorObject);
@@ -1898,6 +1921,9 @@ 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());
@@ -1937,6 +1963,13 @@ void exitGamePlayerPythonScripting()
delete gp_PythonMouse;
gp_PythonMouse = NULL;
+ for (int i=0; i<JOYINDEX_MAX; ++i) {
+ if (gp_PythonJoysticks[i]) {
+ delete gp_PythonJoysticks[i];
+ gp_PythonJoysticks[i] = NULL;
+ }
+ }
+
/* since python restarts we cant let the python backup of the sys.path hang around in a global pointer */
restorePySysObjects(); /* get back the original sys.path and clear the backup */
@@ -1985,6 +2018,13 @@ void exitGamePythonScripting()
delete gp_PythonMouse;
gp_PythonMouse = NULL;
+ for (int i=0; i<JOYINDEX_MAX; ++i) {
+ if (gp_PythonJoysticks[i]) {
+ delete gp_PythonJoysticks[i];
+ gp_PythonJoysticks[i] = NULL;
+ }
+ }
+
restorePySysObjects(); /* get back the original sys.path and clear the backup */
bpy_import_main_set(NULL);
PyObjectPlus::ClearDeprecationWarning();
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
index 971730672db..c6aa436537a 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -47,6 +47,7 @@
#include "KX_ConstraintActuator.h"
#include "KX_ConstraintWrapper.h"
#include "KX_GameActuator.h"
+#include "KX_LibLoadStatus.h"
#include "KX_Light.h"
#include "KX_FontObject.h"
#include "KX_MeshProxy.h"
@@ -81,6 +82,7 @@
#include "SCA_RandomSensor.h"
#include "SCA_XNORController.h"
#include "SCA_XORController.h"
+#include "SCA_PythonJoystick.h"
#include "SCA_PythonKeyboard.h"
#include "SCA_PythonMouse.h"
#include "KX_IpoActuator.h"
@@ -198,6 +200,7 @@ void initPyTypes(void)
PyType_Ready_Attr(dict, KX_GameActuator, init_getset);
PyType_Ready_Attr(dict, KX_GameObject, init_getset);
PyType_Ready_Attr(dict, KX_IpoActuator, init_getset);
+ PyType_Ready_Attr(dict, KX_LibLoadStatus, init_getset);
PyType_Ready_Attr(dict, KX_LightObject, init_getset);
PyType_Ready_Attr(dict, KX_FontObject, init_getset);
PyType_Ready_Attr(dict, KX_MeshProxy, init_getset);
@@ -250,6 +253,7 @@ void initPyTypes(void)
PyType_Ready_Attr(dict, SCA_XNORController, init_getset);
PyType_Ready_Attr(dict, SCA_XORController, init_getset);
PyType_Ready_Attr(dict, SCA_IController, init_getset);
+ PyType_Ready_Attr(dict, SCA_PythonJoystick, init_getset);
PyType_Ready_Attr(dict, SCA_PythonKeyboard, init_getset);
PyType_Ready_Attr(dict, SCA_PythonMouse, init_getset);
}
diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp
index 2a6b7d122b5..878f9d267dc 100644
--- a/source/gameengine/Ketsji/KX_RayCast.cpp
+++ b/source/gameengine/Ketsji/KX_RayCast.cpp
@@ -51,10 +51,10 @@ KX_RayCast::KX_RayCast(KX_IPhysicsController* ignoreController, bool faceNormal,
void KX_RayCast::reportHit(PHY_RayCastResult* result)
{
m_hitFound = true;
- m_hitPoint.setValue((const float*)result->m_hitPoint);
- m_hitNormal.setValue((const float*)result->m_hitNormal);
+ m_hitPoint = MT_Vector3(result->m_hitPoint);
+ m_hitNormal = MT_Vector3(result->m_hitNormal);
m_hitUVOK = result->m_hitUVOK;
- m_hitUV.setValue((const float*)result->m_hitUV);
+ m_hitUV = MT_Vector2(result->m_hitUV);
m_hitMesh = result->m_meshObject;
m_hitPolygon = result->m_polygon;
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 72be5f57b95..fec275322e9 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -47,6 +47,7 @@
//#include "SCA_AlwaysEventManager.h"
//#include "SCA_RandomEventManager.h"
//#include "KX_RayEventManager.h"
+#include "SCA_2DFilterActuator.h"
#include "KX_TouchEventManager.h"
#include "SCA_KeyboardManager.h"
#include "SCA_MouseManager.h"
@@ -87,7 +88,7 @@
#include "BL_DeformableGameObject.h"
#include "KX_ObstacleSimulation.h"
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "KX_SoftBodyDeformer.h"
#include "KX_ConvertPhysicsObject.h"
#include "CcdPhysicsEnvironment.h"
@@ -227,7 +228,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
}
#ifdef WITH_PYTHON
- m_attr_dict = PyDict_New(); /* new ref */
+ m_attr_dict = NULL;
m_draw_call_pre = NULL;
m_draw_call_post = NULL;
#endif
@@ -287,9 +288,11 @@ KX_Scene::~KX_Scene()
}
#ifdef WITH_PYTHON
- PyDict_Clear(m_attr_dict);
- /* Py_CLEAR: Py_DECREF's and NULL's */
- Py_CLEAR(m_attr_dict);
+ if (m_attr_dict) {
+ PyDict_Clear(m_attr_dict);
+ /* Py_CLEAR: Py_DECREF's and NULL's */
+ Py_CLEAR(m_attr_dict);
+ }
/* these may be NULL but the macro checks */
Py_CLEAR(m_draw_call_pre);
@@ -1128,7 +1131,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
blendobj->parent && // original object had armature (not sure this test is needed)
blendobj->parent->type == OB_ARMATURE &&
blendmesh->dvert!=NULL; // mesh has vertex group
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
bool bHasSoftBody = (!parentobj && (blendobj->gameflag & OB_SOFT_BODY));
#endif
bool releaseParent = true;
@@ -1219,7 +1222,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
);
newobj->SetDeformer(meshdeformer);
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
else if (bHasSoftBody)
{
KX_SoftBodyDeformer *softdeformer = new KX_SoftBodyDeformer(mesh, newobj);
@@ -1236,7 +1239,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
gameobj->AddMeshUser();
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
if (use_phys) { /* update the new assigned mesh with the physics mesh */
KX_ReInstanceBulletShapeFromMesh(gameobj, NULL, use_gfx?NULL:mesh);
}
@@ -1487,7 +1490,7 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int
if (m_dbvt_culling)
{
// test culling through Bullet
- PHY__Vector4 planes[6];
+ MT_Vector4 planes[6];
// get the clip planes
MT_Vector4* cplanes = cam->GetNormalizedClipPlanes();
// and convert
@@ -1708,13 +1711,11 @@ void KX_Scene::SetGravity(const MT_Vector3& gravity)
MT_Vector3 KX_Scene::GetGravity()
{
- PHY__Vector3 gravity;
- MT_Vector3 vec;
+ MT_Vector3 gravity;
GetPhysicsEnvironment()->getGravity(gravity);
- vec = gravity.m_vec;
- return vec;
+ return gravity;
}
void KX_Scene::SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter)
@@ -1753,7 +1754,7 @@ short KX_Scene::GetAnimationFPS()
return m_blenderScene->r.frs_sec;
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "KX_BulletPhysicsController.h"
#endif
@@ -1765,7 +1766,7 @@ static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
brick->Replace_NetworkScene(to->GetNetworkScene());
/* near sensors have physics controllers */
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
KX_TouchSensor *touch_sensor = dynamic_cast<class KX_TouchSensor *>(brick);
if (touch_sensor) {
touch_sensor->GetPhysicsController()->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
@@ -1779,9 +1780,14 @@ static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
if (sensor) {
sensor->Replace_EventManager(logicmgr);
}
+
+ SCA_2DFilterActuator *filter_actuator = dynamic_cast<class SCA_2DFilterActuator*>(brick);
+ if (filter_actuator) {
+ filter_actuator->SetScene(to);
+ }
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
#include "CcdGraphicController.h" // XXX ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
#include "CcdPhysicsEnvironment.h" // XXX ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
#include "KX_BulletPhysicsController.h"
@@ -1850,7 +1856,7 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
for (int i=0; i<children.size(); i++)
children[i]->SetSGClientInfo(to);
}
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
SGControllerList::iterator contit;
SGControllerList& controllers = sg->GetSGControllerList();
for (contit = controllers.begin();contit!=controllers.end();++contit)
@@ -1859,7 +1865,7 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
if (phys_ctrl)
phys_ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
}
-#endif // USE_BULLET
+#endif // WITH_BULLET
}
/* If the object is a light, update it's scene */
if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
@@ -1878,7 +1884,7 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
bool KX_Scene::MergeScene(KX_Scene *other)
{
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
CcdPhysicsEnvironment *env= dynamic_cast<CcdPhysicsEnvironment *>(this->GetPhysicsEnvironment());
CcdPhysicsEnvironment *env_other= dynamic_cast<CcdPhysicsEnvironment *>(other->GetPhysicsEnvironment());
@@ -1888,7 +1894,7 @@ bool KX_Scene::MergeScene(KX_Scene *other)
printf("\tsource %d, terget %d\n", (int)(env!=NULL), (int)(env_other!=NULL));
return false;
}
-#endif // USE_BULLET
+#endif // WITH_BULLET
if (GetSceneConverter() != other->GetSceneConverter()) {
printf("KX_Scene::MergeScene: converters differ, aborting\n");
@@ -1931,7 +1937,7 @@ bool KX_Scene::MergeScene(KX_Scene *other)
GetLightList()->MergeList(other->GetLightList());
other->GetLightList()->ReleaseAndRemoveAll();
-#ifdef USE_BULLET
+#ifdef WITH_BULLET
if (env) /* bullet scene? - dummy scenes don't need touching */
env->MergeEnvironment(env_other);
#endif
@@ -2062,6 +2068,9 @@ static PyObject *Map_GetItem(PyObject *self_v, PyObject *item)
PyErr_SetString(PyExc_SystemError, "val = scene[key]: KX_Scene, "BGE_PROXY_ERROR_MSG);
return NULL;
}
+
+ if (!self->m_attr_dict)
+ self->m_attr_dict = PyDict_New();
if (self->m_attr_dict && (pyconvert=PyDict_GetItem(self->m_attr_dict, item))) {
@@ -2089,7 +2098,10 @@ static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
PyErr_SetString(PyExc_SystemError, "scene[key] = value: KX_Scene, "BGE_PROXY_ERROR_MSG);
return -1;
}
-
+
+ if (!self->m_attr_dict)
+ self->m_attr_dict = PyDict_New();
+
if (val==NULL) { /* del ob["key"] */
int del= 0;
@@ -2133,7 +2145,10 @@ static int Seq_Contains(PyObject *self_v, PyObject *value)
PyErr_SetString(PyExc_SystemError, "val in scene: KX_Scene, "BGE_PROXY_ERROR_MSG);
return -1;
}
-
+
+ if (!self->m_attr_dict)
+ self->m_attr_dict = PyDict_New();
+
if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value))
return 1;
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index 2a4f2b3e7d9..5438ae5a97c 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -132,10 +132,13 @@ void KX_SoundActuator::play()
handle3d->setConeVolumeOuter(m_3d.cone_outer_gain);
}
- if (loop)
- m_handle->setLoopCount(-1);
- m_handle->setPitch(m_pitch);
- m_handle->setVolume(m_volume);
+ if (m_handle.get()) {
+ if (loop)
+ m_handle->setLoopCount(-1);
+ m_handle->setPitch(m_pitch);
+ m_handle->setVolume(m_volume);
+ }
+
m_isplaying = true;
}
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index 1597948bafe..44a6e2fd7ee 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -294,7 +294,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
{
// (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
left = dir.safe_normalized();
- dir = (left.cross(up)).safe_normalized();
+ dir = up.cross(left).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
@@ -334,7 +334,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
{
// (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
left = -dir.safe_normalized();
- dir = -(left.cross(up)).safe_normalized();
+ dir = up.cross(left).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
@@ -373,7 +373,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
{
// (1.0 , 0.0 , 0.0 ) -x direction is forward, z (0.0 , 0.0 , 1.0 ) up
left = -dir.safe_normalized();
- dir = -(left.cross(up)).safe_normalized();
+ dir = up.cross(left).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index 9cc91a33886..f189891bf02 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -59,19 +59,12 @@ PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args)
PyVecTo(pylistPos,attachPos);
PyVecTo(pylistDir,attachDir);
PyVecTo(pylistAxleDir,attachAxle);
- PHY__Vector3 aPos,aDir,aAxle;
- aPos[0] = attachPos[0];
- aPos[1] = attachPos[1];
- aPos[2] = attachPos[2];
- aDir[0] = attachDir[0];
- aDir[1] = attachDir[1];
- aDir[2] = attachDir[2];
- aAxle[0] = -attachAxle[0];//someone reverse some conventions inside Bullet (axle winding)
- aAxle[1] = -attachAxle[1];
- aAxle[2] = -attachAxle[2];
+
+ //someone reverse some conventions inside Bullet (axle winding)
+ attachAxle = -attachAxle;
printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering);
- m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering);
+ m_vehicle->AddWheel(motionState,attachPos,attachDir,attachAxle,suspensionRestLength,wheelRadius,hasSteering);
}
} else {
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h
index ccd666e84f3..c38f57d8b9f 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.h
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h
@@ -7,7 +7,6 @@
#define __KX_VEHICLEWRAPPER_H__
#include "Value.h"
-#include "PHY_DynamicTypes.h"
class PHY_IVehicle;
class PHY_IMotionState;
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
index 2354359af18..ab73ba1902a 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.cpp
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -94,6 +94,7 @@ PyAttributeDef KX_VertexProxy::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("XYZ", KX_VertexProxy, pyattr_get_XYZ, pyattr_set_XYZ),
KX_PYATTRIBUTE_RW_FUNCTION("UV", KX_VertexProxy, pyattr_get_UV, pyattr_set_UV),
+ KX_PYATTRIBUTE_RW_FUNCTION("uvs", KX_VertexProxy, pyattr_get_uvs, pyattr_set_uvs),
KX_PYATTRIBUTE_RW_FUNCTION("color", KX_VertexProxy, pyattr_get_color, pyattr_set_color),
KX_PYATTRIBUTE_RW_FUNCTION("normal", KX_VertexProxy, pyattr_get_normal, pyattr_set_normal),
@@ -146,25 +147,25 @@ PyObject *KX_VertexProxy::pyattr_get_a(void *self_v, const KX_PYATTRIBUTE_DEF *a
PyObject *KX_VertexProxy::pyattr_get_u(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV1()[0]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(0)[0]);
}
PyObject *KX_VertexProxy::pyattr_get_v(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV1()[1]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(0)[1]);
}
PyObject *KX_VertexProxy::pyattr_get_u2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV2()[0]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(1)[0]);
}
PyObject *KX_VertexProxy::pyattr_get_v2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV2()[1]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(1)[1]);
}
PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -176,7 +177,20 @@ PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF
PyObject *KX_VertexProxy::pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyObjectFrom(MT_Point2(self->m_vertex->getUV1()));
+ return PyObjectFrom(MT_Point2(self->m_vertex->getUV(0)));
+}
+
+PyObject *KX_VertexProxy::pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
+
+ PyObject* uvlist = PyList_New(RAS_TexVert::MAX_UNIT);
+ for (int i=0; i<RAS_TexVert::MAX_UNIT; ++i)
+ {
+ PyList_SET_ITEM(uvlist, i, PyObjectFrom(MT_Point2(self->m_vertex->getUV(i))));
+ }
+
+ return uvlist;
}
PyObject *KX_VertexProxy::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -245,9 +259,9 @@ int KX_VertexProxy::pyattr_set_u(void *self_v, const struct KX_PYATTRIBUTE_DEF *
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV1();
+ MT_Point2 uv = self->m_vertex->getUV(0);
uv[0] = val;
- self->m_vertex->SetUV1(uv);
+ self->m_vertex->SetUV(0, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -260,9 +274,9 @@ int KX_VertexProxy::pyattr_set_v(void *self_v, const struct KX_PYATTRIBUTE_DEF *
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV1();
+ MT_Point2 uv = self->m_vertex->getUV(0);
uv[1] = val;
- self->m_vertex->SetUV1(uv);
+ self->m_vertex->SetUV(0, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -275,9 +289,9 @@ int KX_VertexProxy::pyattr_set_u2(void *self_v, const struct KX_PYATTRIBUTE_DEF
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV2();
+ MT_Point2 uv = self->m_vertex->getUV(1);
uv[0] = val;
- self->m_vertex->SetUV2(uv);
+ self->m_vertex->SetUV(1, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -290,9 +304,9 @@ int KX_VertexProxy::pyattr_set_v2(void *self_v, const struct KX_PYATTRIBUTE_DEF
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV2();
+ MT_Point2 uv = self->m_vertex->getUV(1);
uv[1] = val;
- self->m_vertex->SetUV2(uv);
+ self->m_vertex->SetUV(1, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -390,7 +404,7 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
{
MT_Point2 vec;
if (PyVecTo(value, vec)) {
- self->m_vertex->SetUV1(vec);
+ self->m_vertex->SetUV(0, vec);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -398,6 +412,32 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
return PY_SET_ATTR_FAIL;
}
+int KX_VertexProxy::pyattr_set_uvs(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
+ if (PySequence_Check(value))
+ {
+ MT_Point2 vec;
+ for (int i=0; i<PySequence_Size(value) && i<RAS_TexVert::MAX_UNIT; ++i)
+ {
+ if (PyVecTo(PySequence_GetItem(value, i), vec))
+ {
+ self->m_vertex->SetUV(i, vec);
+ self->m_mesh->SetMeshModified(true);
+ }
+ else
+ {
+ PyErr_SetString(PyExc_AttributeError, STR_String().Format("list[%d] was not a vector", i).ReadPtr());
+ return PY_SET_ATTR_FAIL;
+ }
+ }
+
+ self->m_mesh->SetMeshModified(true);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ return PY_SET_ATTR_FAIL;
+}
+
int KX_VertexProxy::pyattr_set_color(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
@@ -522,7 +562,7 @@ PyObject *KX_VertexProxy::PySetRGBA(PyObject *value)
PyObject *KX_VertexProxy::PyGetUV1()
{
- return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
+ return PyObjectFrom(MT_Vector2(m_vertex->getUV(0)));
}
PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
@@ -531,31 +571,23 @@ PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
if (!PyVecTo(value, vec))
return NULL;
- m_vertex->SetUV1(vec);
+ m_vertex->SetUV(0, vec);
m_mesh->SetMeshModified(true);
Py_RETURN_NONE;
}
PyObject *KX_VertexProxy::PyGetUV2()
{
- return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
+ return PyObjectFrom(MT_Vector2(m_vertex->getUV(1)));
}
PyObject *KX_VertexProxy::PySetUV2(PyObject *args)
{
MT_Point2 vec;
- unsigned int unit= RAS_TexVert::SECOND_UV;
-
- PyObject *list = NULL;
- if (!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit))
- return NULL;
-
- if (!PyVecTo(list, vec))
+ if (!PyVecTo(args, vec))
return NULL;
- m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
- m_vertex->SetUnit(unit);
- m_vertex->SetUV2(vec);
+ m_vertex->SetUV(1, vec);
m_mesh->SetMeshModified(true);
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
index 4247d138a66..8070825ad11 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.h
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -74,6 +74,7 @@ public:
static PyObject *pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject *pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject *pyattr_get_normal(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject *pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_x(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_y(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_z(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
@@ -89,6 +90,7 @@ public:
static int pyattr_set_UV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_color(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_normal(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_uvs(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ);
KX_PYMETHOD_O(KX_VertexProxy,SetXYZ);
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 88689a5a736..0690bdd6538 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
@@ -45,7 +71,7 @@ if env['WITH_BF_CXX_GUARDEDALLOC']:
defs.append('WITH_CXX_GUARDEDALLOC')
if env['WITH_BF_BULLET']:
- defs.append('USE_BULLET')
+ defs.append('WITH_BULLET')
incs += ' #source/gameengine/Physics/Bullet'
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
diff --git a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h
index 7581486c80a..8bbb1e91e35 100644
--- a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h
+++ b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h
@@ -45,8 +45,8 @@ public:
virtual ~NG_LoopBackNetworkDeviceInterface();
/**
- * Clear message buffer
- */
+ * Clear message buffer
+ */
virtual void NextFrame();
bool Connect(char *address, unsigned int port, char *password,
diff --git a/source/gameengine/Network/LoopBackNetwork/SConscript b/source/gameengine/Network/LoopBackNetwork/SConscript
index 7ca0a64f774..b183634d224 100644
--- a/source/gameengine/Network/LoopBackNetwork/SConscript
+++ b/source/gameengine/Network/LoopBackNetwork/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'NG_LoopBackNetworkDeviceInterface.cpp'
diff --git a/source/gameengine/Network/NG_NetworkDeviceInterface.h b/source/gameengine/Network/NG_NetworkDeviceInterface.h
index 6da478ecda5..7fcf799db31 100644
--- a/source/gameengine/Network/NG_NetworkDeviceInterface.h
+++ b/source/gameengine/Network/NG_NetworkDeviceInterface.h
@@ -49,16 +49,16 @@ public:
virtual void NextFrame()=0;
/**
- * Mark network connection online
- */
+ * Mark network connection online
+ */
void Online(void) { m_online = true; }
/**
- * Mark network connection offline
- */
+ * Mark network connection offline
+ */
void Offline(void) { m_online = false; }
/**
- * Is the network connection established ?
- */
+ * Is the network connection established ?
+ */
bool IsOnline(void) { return m_online; }
virtual bool Connect(char *address, unsigned int port, char *password,
@@ -67,9 +67,9 @@ public:
virtual void SendNetworkMessage(NG_NetworkMessage* msg)=0;
/**
- * read NG_NetworkMessage from library buffer, may be
- * irrelevant for loopbackdevices
- */
+ * read NG_NetworkMessage from library buffer, may be
+ * irrelevant for loopbackdevices
+ */
virtual std::vector<NG_NetworkMessage*> RetrieveNetworkMessages()=0;
diff --git a/source/gameengine/Network/NG_NetworkMessage.h b/source/gameengine/Network/NG_NetworkMessage.h
index 5185849f8d7..6ed266557fc 100644
--- a/source/gameengine/Network/NG_NetworkMessage.h
+++ b/source/gameengine/Network/NG_NetworkMessage.h
@@ -123,8 +123,8 @@ public:
}
/**
- * get the unique Network Message ID
- */
+ * get the unique Network Message ID
+ */
int GetMessageID() {
return m_uniqueMessageID;
}
diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript
index bbf714383b7..7365db5ba99 100644
--- a/source/gameengine/Network/SConscript
+++ b/source/gameengine/Network/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_NetworkScene.cpp'
diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt
index 43b1bfe7468..c5b601361d9 100644
--- a/source/gameengine/Physics/Bullet/CMakeLists.txt
+++ b/source/gameengine/Physics/Bullet/CMakeLists.txt
@@ -44,7 +44,6 @@ set(INC
)
set(INC_SYS
- ../../../../extern/bullet2/src
${GLEW_INCLUDE_PATH}
${PYTHON_INCLUDE_DIRS}
)
@@ -60,7 +59,10 @@ set(SRC
)
if(WITH_BULLET)
- add_definitions(-DUSE_BULLET)
+ list(APPEND INC
+ ${BULLET_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_BULLET)
endif()
blender_add_lib(ge_phys_bullet "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
index 36e7b0d482f..3cb80e53e12 100644
--- a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
@@ -55,7 +55,7 @@ void CcdGraphicController::setLocalAabb(const MT_Point3& aabbMin,const MT_Point3
SetGraphicTransform();
}
-void CcdGraphicController::setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax)
+void CcdGraphicController::setLocalAabb(const MT_Vector3& aabbMin,const MT_Vector3& aabbMax)
{
m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]);
m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]);
diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h
index 72eb699ce5b..064f86040f6 100644
--- a/source/gameengine/Physics/Bullet/CcdGraphicController.h
+++ b/source/gameengine/Physics/Bullet/CcdGraphicController.h
@@ -42,7 +42,7 @@ public:
void setLocalAabb(const btVector3& aabbMin,const btVector3& aabbMax);
void setLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax);
- virtual void setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax);
+ virtual void setLocalAabb(const MT_Vector3& aabbMin,const MT_Vector3& aabbMax);
virtual void setLocalAabb(const float aabbMin[3],const float aabbMax[3]);
PHY_IMotionState* GetMotionState() { return m_motionState; }
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 6c6ce94d8d5..08ea9706eba 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -24,7 +24,6 @@ subject to the following restrictions:
#include "btBulletDynamicsCommon.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
-
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
#include "PHY_IMotionState.h"
@@ -33,11 +32,10 @@ subject to the following restrictions:
#include "KX_GameObject.h"
#include "BulletSoftBody/btSoftBody.h"
-#include "BulletSoftBody//btSoftBodyInternals.h"
+#include "BulletSoftBody/btSoftBodyInternals.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "LinearMath/btConvexHull.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
-#include "BulletCollision/Gimpact/btGImpactShape.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
@@ -68,6 +66,58 @@ float gAngularSleepingTreshold;
btVector3 startVel(0,0,0);//-10000);
+BlenderBulletCharacterController::BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
+ : btKinematicCharacterController(ghost,shape,stepHeight,2),
+ m_motionState(motionState),
+ m_jumps(0),
+ m_maxJumps(1)
+{
+}
+
+void BlenderBulletCharacterController::updateAction(btCollisionWorld *collisionWorld, btScalar dt)
+{
+ if (onGround())
+ m_jumps = 0;
+
+ btKinematicCharacterController::updateAction(collisionWorld,dt);
+ m_motionState->setWorldTransform(getGhostObject()->getWorldTransform());
+}
+
+int BlenderBulletCharacterController::getMaxJumps() const
+{
+ return m_maxJumps;
+}
+
+void BlenderBulletCharacterController::setMaxJumps(int maxJumps)
+{
+ m_maxJumps = maxJumps;
+}
+
+int BlenderBulletCharacterController::getJumpCount() const
+{
+ return m_jumps;
+}
+
+bool BlenderBulletCharacterController::canJump() const
+{
+ return onGround() || m_jumps < m_maxJumps;
+}
+
+void BlenderBulletCharacterController::jump()
+{
+ if (!canJump())
+ return;
+
+ m_verticalVelocity = m_jumpSpeed;
+ m_wasJumping = true;
+ m_jumps++;
+}
+
+const btVector3& BlenderBulletCharacterController::getWalkDirection()
+{
+ return m_walkDirection;
+}
+
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
@@ -154,25 +204,6 @@ public:
};
-class BlenderBulletCharacterController : public btKinematicCharacterController
-{
-private:
- btMotionState* m_motionState;
-
-public:
- BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
- : btKinematicCharacterController(ghost,shape,stepHeight,2),
- m_motionState(motionState)
- {
- }
-
- virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt)
- {
- btKinematicCharacterController::updateAction(collisionWorld,dt);
- m_motionState->setWorldTransform(getGhostObject()->getWorldTransform());
- }
-};
-
btRigidBody* CcdPhysicsController::GetRigidBody()
{
return btRigidBody::upcast(m_object);
@@ -463,9 +494,6 @@ bool CcdPhysicsController::CreateCharacterController()
m_characterController = new BlenderBulletCharacterController(m_bulletMotionState,(btPairCachingGhostObject*)m_object,(btConvexShape*)m_collisionShape,m_cci.m_stepHeight);
- PHY__Vector3 gravity;
- m_cci.m_physicsEnv->getGravity(gravity);
- m_characterController->setGravity(-gravity.m_vec[2]); // need positive gravity
m_characterController->setJumpSpeed(m_cci.m_jumpSpeed);
m_characterController->setFallSpeed(m_cci.m_fallSpeed);
@@ -645,9 +673,9 @@ CcdPhysicsController::~CcdPhysicsController()
}
- /**
- SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
- */
+/**
+ * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
bool CcdPhysicsController::SynchronizeMotionStates(float time)
{
//sync non-static to motionstate, and static from motionstate (todo: add kinematic etc.)
@@ -730,8 +758,8 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time)
}
/**
- WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding')
- */
+ * WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
void CcdPhysicsController::WriteMotionStateToDynamics(bool nondynaonly)
{
@@ -901,20 +929,27 @@ void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dloc
if (local)
dloc = xform.getBasis()*dloc;
- if (m_characterController)
- {
- m_characterController->setWalkDirection(dloc/GetPhysicsEnvironment()->getNumTimeSubSteps());
- }
- else
- {
-
- xform.setOrigin(xform.getOrigin() + dloc);
- SetCenterOfMassTransform(xform);
- }
+ xform.setOrigin(xform.getOrigin() + dloc);
+ SetCenterOfMassTransform(xform);
}
}
+void CcdPhysicsController::SetWalkDirection(float dirX,float dirY,float dirZ,bool local)
+{
+
+ if (m_object && m_characterController)
+ {
+ btVector3 dir(dirX,dirY,dirZ);
+ btTransform xform = m_object->getWorldTransform();
+
+ if (local)
+ dir = xform.getBasis()*dir;
+
+ m_characterController->setWalkDirection(dir/GetPhysicsEnvironment()->getNumTimeSubSteps());
+ }
+}
+
void CcdPhysicsController::RelativeRotate(const float rotval[9],bool local)
{
if (m_object)
@@ -1055,7 +1090,7 @@ void CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvel
{
}
-void CcdPhysicsController::getPosition(PHY__Vector3& pos) const
+void CcdPhysicsController::getPosition(MT_Vector3& pos) const
{
const btTransform& xform = m_object->getWorldTransform();
pos[0] = xform.getOrigin().x();
@@ -1242,6 +1277,13 @@ void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attac
}
}
+
+void CcdPhysicsController::Jump()
+{
+ if (m_object && m_characterController)
+ m_characterController->jump();
+}
+
void CcdPhysicsController::SetActive(bool active)
{
}
@@ -1298,6 +1340,24 @@ void CcdPhysicsController::GetVelocity(const float posX,const float posY,const
linvZ = 0.f;
}
}
+
+void CcdPhysicsController::GetWalkDirection(float& dirX,float& dirY,float& dirZ)
+{
+ if (m_object && m_characterController)
+ {
+ const btVector3 dir = m_characterController->getWalkDirection();
+ dirX = dir.x();
+ dirY = dir.y();
+ dirZ = dir.z();
+ }
+ else
+ {
+ dirX = 0.f;
+ dirY = 0.f;
+ dirZ = 0.f;
+ }
+}
+
void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ)
{
}
@@ -2169,8 +2229,9 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, b
);
btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays);
gimpactShape->setMargin(margin);
- collisionShape = gimpactShape;
gimpactShape->updateBound();
+ collisionShape = gimpactShape;
+
} else
{
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 6df5c85f5c0..f1f0ca31419 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -391,17 +391,42 @@ struct CcdConstructionInfo
};
-
class btRigidBody;
class btCollisionObject;
class btSoftBody;
+class btPairCachingGhostObject;
+
+class BlenderBulletCharacterController : public btKinematicCharacterController
+{
+private:
+ btMotionState* m_motionState;
+ int m_jumps;
+ int m_maxJumps;
+
+public:
+ BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight);
+
+ virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt);
+
+ int getMaxJumps() const;
+
+ void setMaxJumps(int maxJumps);
+
+ int getJumpCount() const;
+
+ virtual bool canJump() const;
+
+ virtual void jump();
+
+ const btVector3& getWalkDirection();
+};
///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
class CcdPhysicsController : public PHY_IPhysicsController
{
protected:
btCollisionObject* m_object;
- btKinematicCharacterController* m_characterController;
+ BlenderBulletCharacterController* m_characterController;
class PHY_IMotionState* m_MotionState;
@@ -478,12 +503,12 @@ protected:
/**
- SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
- */
+ * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
virtual bool SynchronizeMotionStates(float time);
/**
- WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
- */
+ * WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
virtual void WriteMotionStateToDynamics(bool nondynaonly);
virtual void WriteDynamicsToMotionState();
@@ -494,11 +519,12 @@ protected:
// kinematic methods
virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local);
+ virtual void SetWalkDirection(float dirX,float dirY,float dirZ,bool local);
virtual void RelativeRotate(const float drot[9],bool local);
virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal);
virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal);
virtual void setPosition(float posX,float posY,float posZ);
- virtual void getPosition(PHY__Vector3& pos) const;
+ virtual void getPosition(MT_Vector3& pos) const;
virtual void setScaling(float scaleX,float scaleY,float scaleZ);
@@ -508,6 +534,7 @@ protected:
virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local);
virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local);
virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ);
+ virtual void Jump();
virtual void SetActive(bool active);
// reading out information from physics
@@ -515,6 +542,7 @@ protected:
virtual void GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ);
virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ);
virtual void getReactionForce(float& forceX,float& forceY,float& forceZ);
+ virtual void GetWalkDirection(float& dirX,float& dirY,float& dirZ);
// dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
virtual void setRigidBody(bool rigid);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 486411d7e35..702452bc77e 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -97,9 +97,9 @@ public:
virtual void AddWheel(
PHY_IMotionState* motionState,
- PHY__Vector3 connectionPoint,
- PHY__Vector3 downDirection,
- PHY__Vector3 axleDirection,
+ MT_Vector3 connectionPoint,
+ MT_Vector3 downDirection,
+ MT_Vector3 axleDirection,
float suspensionRestLength,
float wheelRadius,
bool hasSteering
@@ -270,10 +270,10 @@ public:
class CharacterWrapper : public PHY_ICharacter
{
private:
- btKinematicCharacterController* m_controller;
+ BlenderBulletCharacterController* m_controller;
public:
- CharacterWrapper(btKinematicCharacterController* cont)
+ CharacterWrapper(BlenderBulletCharacterController* cont)
: m_controller(cont)
{}
@@ -295,6 +295,33 @@ public:
{
m_controller->setGravity(gravity);
}
+
+ virtual int GetMaxJumps()
+ {
+ return m_controller->getMaxJumps();
+ }
+
+ virtual void SetMaxJumps(int maxJumps)
+ {
+ m_controller->setMaxJumps(maxJumps);
+ }
+
+ virtual int GetJumpCount()
+ {
+ return m_controller->getJumpCount();
+ }
+
+ virtual void SetWalkDirection(const MT_Vector3& dir)
+ {
+ btVector3 vec = btVector3(dir[0], dir[1], dir[2]);
+ m_controller->setWalkDirection(vec);
+ }
+
+ virtual MT_Vector3 GetWalkDirection()
+ {
+ btVector3 vec = m_controller->getWalkDirection();
+ return MT_Vector3(vec[0], vec[1], vec[2]);
+ }
};
class CcdOverlapFilterCallBack : public btOverlapFilterCallback
@@ -920,7 +947,7 @@ void CcdPhysicsEnvironment::setSolverType(int solverType)
-void CcdPhysicsEnvironment::getGravity(PHY__Vector3& grav)
+void CcdPhysicsEnvironment::getGravity(MT_Vector3& grav)
{
const btVector3& gravity = m_dynamicsWorld->getGravity();
grav[0] = gravity.getX();
@@ -1820,7 +1847,7 @@ struct DbvtCullingCallback : btDbvt::ICollide
};
static OcclusionBuffer gOcb;
-bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16])
+bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, MT_Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16])
{
if (!m_cullingTree)
return false;
@@ -2320,7 +2347,7 @@ PHY_ICharacter* CcdPhysicsEnvironment::getCharacterController(KX_GameObject *ob)
{
CcdPhysicsController* controller = (CcdPhysicsController*)ob->GetPhysicsController()->GetUserData();
if (controller->GetCharacterController())
- return new CharacterWrapper(controller->GetCharacterController());
+ return new CharacterWrapper((BlenderBulletCharacterController*)controller->GetCharacterController());
return NULL;
}
@@ -2331,7 +2358,7 @@ int numController = 0;
-PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
+PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radius,const MT_Vector3& position)
{
CcdConstructionInfo cinfo;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 18ce0550498..8cf88526969 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -140,7 +140,7 @@ protected:
virtual void setDebugMode(int debugMode);
virtual void setGravity(float x,float y,float z);
- virtual void getGravity(PHY__Vector3& grav);
+ virtual void getGravity(MT_Vector3& grav);
virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
@@ -190,7 +190,7 @@ protected:
btTypedConstraint* getConstraintById(int constraintId);
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
- virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]);
+ virtual bool cullingTest(PHY_CullingCallback callback, void* userData, MT_Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]);
//Methods for gamelogic collision/physics callbacks
@@ -200,7 +200,7 @@ protected:
virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl);
virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl);
//These two methods are used *solely* to create controllers for Near/Radar sensor! Don't use for anything else
- virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position);
+ virtual PHY_IPhysicsController* CreateSphereController(float radius,const MT_Vector3& position);
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight);
diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript
index ba4db001533..6ef2750e8d6 100644
--- a/source/gameengine/Physics/Bullet/SConscript
+++ b/source/gameengine/Physics/Bullet/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp CcdGraphicController.cpp'
@@ -30,6 +56,6 @@ if env['WITH_BF_CXX_GUARDEDALLOC']:
defs.append('WITH_CXX_GUARDEDALLOC')
if env['WITH_BF_BULLET']:
- defs.append('USE_BULLET')
+ defs.append('WITH_BULLET')
env.BlenderLib ( 'ge_phys_bullet', Split(sources), Split(incs), defs, libtype=['core','player'], priority=[350,50], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/Physics/Dummy/CMakeLists.txt b/source/gameengine/Physics/Dummy/CMakeLists.txt
index 6a21fc6fcb7..529a75b2a62 100644
--- a/source/gameengine/Physics/Dummy/CMakeLists.txt
+++ b/source/gameengine/Physics/Dummy/CMakeLists.txt
@@ -26,6 +26,7 @@
set(INC
.
../common
+ ../../../../intern/moto/include
)
set(INC_SYS
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
index d1fabba18f9..72450e4307c 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
@@ -85,7 +85,7 @@ void DummyPhysicsEnvironment::setGravity(float x,float y,float z)
{
}
-void DummyPhysicsEnvironment::getGravity(PHY__Vector3& grav)
+void DummyPhysicsEnvironment::getGravity(class MT_Vector3& grav)
{
}
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
index 5ce34bdf7cf..9f6bc85fced 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
@@ -56,7 +56,7 @@ public:
virtual float getFixedTimeStep();
virtual void setGravity(float x,float y,float z);
- virtual void getGravity(PHY__Vector3& grav);
+ virtual void getGravity(class MT_Vector3& grav);
virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
float pivotX,float pivotY,float pivotZ,
@@ -80,7 +80,7 @@ public:
}
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
- virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) { return false; }
+ virtual bool cullingTest(PHY_CullingCallback callback, void* userData, class MT_Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) { return false; }
//gamelogic callbacks
@@ -91,7 +91,7 @@ public:
}
virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl) { return false; }
virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl) { return false;}
- virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;}
+ virtual PHY_IPhysicsController* CreateSphereController(float radius,const class MT_Vector3& position) {return 0;}
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;}
virtual void setConstraintParam(int constraintId,int param,float value,float value1)
diff --git a/source/gameengine/Physics/Dummy/SConscript b/source/gameengine/Physics/Dummy/SConscript
index 13d1a893823..15a68ad4e85 100644
--- a/source/gameengine/Physics/Dummy/SConscript
+++ b/source/gameengine/Physics/Dummy/SConscript
@@ -1,9 +1,35 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'DummyPhysicsEnvironment.cpp'
-incs = '. ../common'
+incs = '. ../common ../../../../intern/moto/include'
defs = []
diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h
index 0fe2533cf93..d10f48ad7a4 100644
--- a/source/gameengine/Physics/common/PHY_DynamicTypes.h
+++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h
@@ -20,69 +20,9 @@ subject to the following restrictions:
#ifndef __PHY_DYNAMICTYPES_H__
#define __PHY_DYNAMICTYPES_H__
-
+#include "MT_Vector3.h"
struct KX_ClientObjectInfo;
-class PHY_Shape;
-
-struct PHY__Vector2
-{
- float m_vec[2];
-
- operator const float* () const
- {
- return &m_vec[0];
- }
- operator float* ()
- {
- return &m_vec[0];
- }
-};
-
-struct PHY__Vector3
-{
- float m_vec[4];
-
- operator const float* () const
- {
- return &m_vec[0];
- }
- operator float* ()
- {
- return &m_vec[0];
- }
-};
-
-struct PHY__Vector4
-{
- float m_vec[4];
- PHY__Vector4() {}
- void setValue(const float *value)
- {
- m_vec[0] = *value++;
- m_vec[1] = *value++;
- m_vec[2] = *value++;
- m_vec[3] = *value++;
- }
- void setValue(const double *value)
- {
- m_vec[0] = (float)(*value++);
- m_vec[1] = (float)(*value++);
- m_vec[2] = (float)(*value++);
- m_vec[3] = (float)(*value++);
- }
-
- operator const float* () const
- {
- return &m_vec[0];
- }
- operator float* ()
- {
- return &m_vec[0];
- }
-};
-
-//typedef float PHY__Vector3[4];
enum
{
@@ -97,9 +37,9 @@ enum
};
typedef struct PHY_CollData {
- PHY__Vector3 m_point1; /* Point in object1 in world coordinates */
- PHY__Vector3 m_point2; /* Point in object2 in world coordinates */
- PHY__Vector3 m_normal; /* point2 - point1 */
+ MT_Vector3 m_point1; /* Point in object1 in world coordinates */
+ MT_Vector3 m_point2; /* Point in object2 in world coordinates */
+ MT_Vector3 m_normal; /* point2 - point1 */
} PHY_CollData;
@@ -148,7 +88,4 @@ typedef enum PHY_ShapeType {
PHY_SHAPE_PROXY
} PHY_ShapeType;
-
-typedef float PHY_Vector3[3];
-
#endif /* __PHY_DYNAMICTYPES_H__ */
diff --git a/source/gameengine/Physics/common/PHY_ICharacter.h b/source/gameengine/Physics/common/PHY_ICharacter.h
index e2fc5e45125..a3d3000a143 100644
--- a/source/gameengine/Physics/common/PHY_ICharacter.h
+++ b/source/gameengine/Physics/common/PHY_ICharacter.h
@@ -15,12 +15,21 @@
class PHY_ICharacter
{
public:
+ virtual ~PHY_ICharacter(){};
virtual void Jump()= 0;
virtual bool OnGround()= 0;
virtual float GetGravity()= 0;
virtual void SetGravity(float gravity)= 0;
+
+ virtual int GetMaxJumps()= 0;
+ virtual void SetMaxJumps(int maxJumps)= 0;
+
+ virtual int GetJumpCount()= 0;
+
+ virtual void SetWalkDirection(const class MT_Vector3& dir)=0;
+ virtual MT_Vector3 GetWalkDirection()=0;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_ICharacter")
diff --git a/source/gameengine/Physics/common/PHY_IController.h b/source/gameengine/Physics/common/PHY_IController.h
index 003c4edf598..ae1b2d9ad53 100644
--- a/source/gameengine/Physics/common/PHY_IController.h
+++ b/source/gameengine/Physics/common/PHY_IController.h
@@ -41,14 +41,14 @@ class PHY_IPhysicsEnvironment;
#endif
/**
- PHY_IController is the abstract simplified Interface to objects
- controlled by the physics engine. This includes the physics objects
- and the graphics object for view frustrum and occlusion culling.
-*/
+ * PHY_IController is the abstract simplified Interface to objects
+ * controlled by the physics engine. This includes the physics objects
+ * and the graphics object for view frustrum and occlusion culling.
+ */
class PHY_IController
{
public:
- virtual ~PHY_IController();
+ virtual ~PHY_IController(){};
// clientinfo for raycasts for example
virtual void* getNewClientInfo()=0;
virtual void setNewClientInfo(void* clientinfo)=0;
diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h
index cb13eda4f18..5f64e7ccc80 100644
--- a/source/gameengine/Physics/common/PHY_IGraphicController.h
+++ b/source/gameengine/Physics/common/PHY_IGraphicController.h
@@ -36,19 +36,18 @@
/**
- PHY_IPhysicsController is the abstract simplified Interface to a physical object.
- It contains the IMotionState and IDeformableMesh Interfaces.
-*/
+ * PHY_IPhysicsController is the abstract simplified Interface to a physical object.
+ * It contains the IMotionState and IDeformableMesh Interfaces.
+ */
class PHY_IGraphicController : public PHY_IController
{
public:
- virtual ~PHY_IGraphicController();
/**
- SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
- */
+ * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
virtual bool SetGraphicTransform()=0;
virtual void Activate(bool active=true)=0;
- virtual void setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax)=0;
+ virtual void setLocalAabb(const class MT_Vector3& aabbMin,const class MT_Vector3& aabbMax)=0;
virtual void setLocalAabb(const float* aabbMin,const float* aabbMax)=0;
virtual PHY_IGraphicController* GetReplica(class PHY_IMotionState* motionstate) {return 0;}
diff --git a/source/gameengine/Physics/common/PHY_IMotionState.h b/source/gameengine/Physics/common/PHY_IMotionState.h
index ccf7cf74724..be5b2b54907 100644
--- a/source/gameengine/Physics/common/PHY_IMotionState.h
+++ b/source/gameengine/Physics/common/PHY_IMotionState.h
@@ -37,14 +37,14 @@
#endif
/**
- PHY_IMotionState is the Interface to explicitly synchronize the world transformation.
- Default implementations for mayor graphics libraries like OpenGL and DirectX can be provided.
-*/
+ * PHY_IMotionState is the Interface to explicitly synchronize the world transformation.
+ * Default implementations for mayor graphics libraries like OpenGL and DirectX can be provided.
+ */
class PHY_IMotionState
{
public:
- virtual ~PHY_IMotionState();
+ virtual ~PHY_IMotionState(){};
virtual void getWorldPosition(float& posX,float& posY,float& posZ)=0;
virtual void getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)=0;
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index bc7671abe80..18af42adc15 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -38,21 +38,21 @@ class PHY_IMotionState;
class PHY_IPhysicsEnvironment;
/**
- PHY_IPhysicsController is the abstract simplified Interface to a physical object.
- It contains the IMotionState and IDeformableMesh Interfaces.
-*/
+ * PHY_IPhysicsController is the abstract simplified Interface to a physical object.
+ * It contains the IMotionState and IDeformableMesh Interfaces.
+ */
class PHY_IPhysicsController : public PHY_IController
{
public:
- virtual ~PHY_IPhysicsController();
+ virtual ~PHY_IPhysicsController(){};
/**
- SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
- */
+ * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
virtual bool SynchronizeMotionStates(float time)=0;
/**
- WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
- */
+ * WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
virtual void WriteMotionStateToDynamics(bool nondynaonly)=0;
virtual void WriteDynamicsToMotionState()=0;
@@ -66,7 +66,7 @@ class PHY_IPhysicsController : public PHY_IController
virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)=0;
virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)=0;
virtual void setPosition(float posX,float posY,float posZ)=0;
- virtual void getPosition(PHY__Vector3& pos) const=0;
+ virtual void getPosition(class MT_Vector3& pos) const=0;
virtual void setScaling(float scaleX,float scaleY,float scaleZ)=0;
// physics methods
@@ -100,7 +100,7 @@ class PHY_IPhysicsController : public PHY_IController
virtual float GetLinVelocityMax() const=0;
virtual void SetLinVelocityMax(float val) = 0;
- PHY__Vector3 GetWorldPosition(PHY__Vector3& localpos);
+ class MT_Vector3 GetWorldPosition(class MT_Vector3& localpos);
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index bfbe570ad0c..14904a70553 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -32,8 +32,10 @@
#ifndef __PHY_IPHYSICSENVIRONMENT_H__
#define __PHY_IPHYSICSENVIRONMENT_H__
-#include <vector>
#include "PHY_DynamicTypes.h"
+#include "MT_Vector2.h"
+#include "MT_Vector3.h"
+#include "MT_Vector4.h"
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
@@ -50,13 +52,13 @@ class PHY_IPhysicsController;
struct PHY_RayCastResult
{
PHY_IPhysicsController* m_controller;
- PHY__Vector3 m_hitPoint;
- PHY__Vector3 m_hitNormal;
+ MT_Vector3 m_hitPoint;
+ MT_Vector3 m_hitNormal;
const RAS_MeshObject* m_meshObject; // !=NULL for mesh object (only for Bullet controllers)
int m_polygon; // index of the polygon hit by the ray,
// only if m_meshObject != NULL
int m_hitUVOK; // !=0 if UV coordinate in m_hitUV is valid
- PHY__Vector2 m_hitUV; // UV coordinates of hit point
+ MT_Vector2 m_hitUV; // UV coordinates of hit point
};
/**
@@ -96,13 +98,14 @@ public:
};
/**
-* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
-* A derived class may be able to 'construct' entities by loading and/or converting
-*/
+ * Physics Environment takes care of stepping the simulation and is a container for physics entities
+ * (rigidbodies,constraints, materials etc.)
+ * A derived class may be able to 'construct' entities by loading and/or converting
+ */
class PHY_IPhysicsEnvironment
{
public:
- virtual ~PHY_IPhysicsEnvironment();
+ virtual ~PHY_IPhysicsEnvironment(){};
virtual void beginFrame() = 0;
virtual void endFrame() = 0;
/// Perform an integration step of duration 'timeStep'.
@@ -143,7 +146,7 @@ class PHY_IPhysicsEnvironment
virtual void setUseEpa(bool epa) {}
virtual void setGravity(float x,float y,float z)=0;
- virtual void getGravity(PHY__Vector3& grav) = 0;
+ virtual void getGravity(MT_Vector3& grav) = 0;
virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type,
float pivotX,float pivotY,float pivotZ,
@@ -166,7 +169,7 @@ class PHY_IPhysicsEnvironment
//culling based on physical broad phase
// the plane number must be set as follow: near, far, left, right, top, botton
// the near plane must be the first one and must always be present, it is used to get the direction of the view
- virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) = 0;
+ virtual bool cullingTest(PHY_CullingCallback callback, void *userData, MT_Vector4* planeNormals, int planeNumber, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) = 0;
//Methods for gamelogic collision/physics callbacks
//todo:
@@ -176,7 +179,7 @@ class PHY_IPhysicsEnvironment
virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl)=0;
virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl)=0;
//These two methods are *solely* used to create controllers for sensor! Don't use for anything else
- virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0;
+ virtual PHY_IPhysicsController* CreateSphereController(float radius,const MT_Vector3& position) =0;
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0;
virtual void setConstraintParam(int constraintId,int param,float value,float value1) = 0;
diff --git a/source/gameengine/Physics/common/PHY_IVehicle.cpp b/source/gameengine/Physics/common/PHY_IVehicle.cpp
deleted file mode 100644
index a60bb3e596d..00000000000
--- a/source/gameengine/Physics/common/PHY_IVehicle.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/** \file gameengine/Physics/common/PHY_IVehicle.cpp
- * \ingroup phys
- */
-
-#include "PHY_IVehicle.h"
-
-PHY_IVehicle::~PHY_IVehicle()
-{
-
-}
diff --git a/source/gameengine/Physics/common/PHY_IVehicle.h b/source/gameengine/Physics/common/PHY_IVehicle.h
index ecf7a87c40f..1dcec69a335 100644
--- a/source/gameengine/Physics/common/PHY_IVehicle.h
+++ b/source/gameengine/Physics/common/PHY_IVehicle.h
@@ -18,13 +18,13 @@ class PHY_IMotionState;
class PHY_IVehicle
{
public:
- virtual ~PHY_IVehicle();
+ virtual ~PHY_IVehicle(){};
virtual void AddWheel(
PHY_IMotionState* motionState,
- PHY__Vector3 connectionPoint,
- PHY__Vector3 downDirection,
- PHY__Vector3 axleDirection,
+ MT_Vector3 connectionPoint,
+ MT_Vector3 downDirection,
+ MT_Vector3 axleDirection,
float suspensionRestLength,
float wheelRadius,
bool hasSteering
diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript
deleted file mode 100644
index abff3e33121..00000000000
--- a/source/gameengine/Physics/common/SConscript
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/python
-Import ('env')
-
-sources = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp PHY_IGraphicController.cpp PHY_IPhysicsEnvironment.cpp PHY_IVehicle.cpp'
-
-incs = '. ../Dummy #intern/moto/include'
-
-defs = []
-
-if env['WITH_BF_CXX_GUARDEDALLOC']:
- defs.append('WITH_CXX_GUARDEDALLOC')
- incs += ' #intern/guardedalloc'
-
-env.BlenderLib ( 'ge_phys_common', Split(sources), Split(incs), defs, libtype=['core','player'], priority=[360,55], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt
index ddc72c08ea1..3ea26c3be9d 100644
--- a/source/gameengine/Rasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../Ketsji
../SceneGraph
../../blender/makesdna
+ ../../blender/blenlib
../../blender/blenkernel
../../../intern/container
../../../intern/guardedalloc
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index cf869e71945..ab0f62c84c7 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -428,8 +428,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
// reverting to texunit 0, without this we get bug [#28462]
glActiveTextureARB(GL_TEXTURE0);
-
- glViewport(rect.GetLeft(), rect.GetBottom(), rect_width, rect_height);
+ canvas->SetViewPort(0, 0, rect_width-1, rect_height-1);
glDisable(GL_DEPTH_TEST);
// in case the previous material was wire
@@ -466,7 +465,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
glEnable(GL_DEPTH_TEST);
- glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
+ canvas->SetViewPort(viewport[0],viewport[1],viewport[2],viewport[3]);
EndShaderProgram();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index f24e3397801..b2b766b65e8 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -148,7 +148,8 @@ void RAS_BucketManager::RenderAlphaBuckets(
// Having depth masks disabled/enabled gives different artifacts in
// case no sorting is done or is done inexact. For compatibility, we
// disable it.
- rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED);
+ if (rasty->GetDrawingMode() != RAS_IRasterizer::KX_SHADOW)
+ rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED);
OrderBuckets(cameratrans, m_AlphaBuckets, slots, true);
@@ -232,6 +233,24 @@ void RAS_BucketManager::Renderbuckets(
RenderSolidBuckets(cameratrans, rasty, rendertools);
RenderAlphaBuckets(cameratrans, rasty, rendertools);
+ /* All meshes should be up to date now */
+ /* Don't do this while processing buckets because some meshes are split between buckets */
+ BucketList::iterator bit;
+ list<RAS_MeshSlot>::iterator mit;
+ for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) {
+ // RAS_MaterialBucket *bucket = *bit; /* UNUSED */
+ for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+ mit->m_mesh->SetMeshModified(false);
+ }
+ }
+ for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
+ // RAS_MaterialBucket* bucket = *bit; /* UNUSED */
+ for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+ mit->m_mesh->SetMeshModified(false);
+ }
+ }
+
+
rendertools->SetClientObject(rasty, NULL);
}
diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h
index 60b9f052075..63ad7892aa5 100644
--- a/source/gameengine/Rasterizer/RAS_ICanvas.h
+++ b/source/gameengine/Rasterizer/RAS_ICanvas.h
@@ -178,7 +178,19 @@ public:
SetViewPort(
int x1, int y1,
int x2, int y2
- ) = 0;
+ ) = 0;
+
+ /**
+ * Update the Canvas' viewport (used when the viewport changes without using SetViewPort()
+ * eg: Shadow buffers and FBOs
+ */
+
+ virtual
+ void
+ UpdateViewPort(
+ int x1, int y1,
+ int x2, int y2
+ ) = 0;
/**
* Get the visible viewport
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 9fffc8bebc9..7aeeb364b47 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -177,14 +177,14 @@ public:
virtual void Replace_IScene(SCA_IScene *val) {} /* overridden by KX_BlenderMaterial */
/**
- * \return the equivalent drawing mode for the material settings (equivalent to old TexFace tface->mode).
- */
+ * \return the equivalent drawing mode for the material settings (equivalent to old TexFace tface->mode).
+ */
int ConvertFaceMode(struct GameSettings *game, bool image) const;
/*
* PreCalculate texture gen
*/
- virtual void OnConstruction(int layer) {}
+ virtual void OnConstruction() {}
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index e6948025999..99026fa259a 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -52,6 +52,7 @@ using namespace std;
class RAS_ICanvas;
class RAS_IPolyMaterial;
+class RAS_MeshSlot;
typedef vector<unsigned short> KX_IndexArray;
typedef vector<RAS_TexVert> KX_VertexArray;
@@ -129,7 +130,7 @@ public:
RAS_TEXCO_GEN, //< GPU will generate texture coordinates
RAS_TEXCO_ORCO, //< Vertex coordinates (object space)
RAS_TEXCO_GLOB, //< Vertex coordinates (world space)
- RAS_TEXCO_UV1, //< UV coordinates
+ RAS_TEXCO_UV, //< UV coordinates
RAS_TEXCO_OBJECT, //< Use another object's position as coordinates
RAS_TEXCO_LAVECTOR, //< Light vector as coordinates
RAS_TEXCO_VIEW, //< View vector as coordinates
@@ -137,7 +138,6 @@ public:
RAS_TEXCO_WINDOW, //< Window coordinates
RAS_TEXCO_NORM, //< Normal coordinates
RAS_TEXTANGENT, //<
- RAS_TEXCO_UV2, //<
RAS_TEXCO_VCOL, //< Vertex Color
RAS_TEXCO_DISABLE //< Disable this texture unit (cached)
};
@@ -417,6 +417,8 @@ public:
virtual void SetAnisotropicFiltering(short level)=0;
virtual short GetAnisotropicFiltering()=0;
+ virtual void SetUsingOverrideShader(bool val)=0;
+ virtual bool GetUsingOverrideShader()=0;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_IRasterizer")
diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h
index bccda634222..6131abc0650 100644
--- a/source/gameengine/Rasterizer/RAS_IRenderTools.h
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h
@@ -100,6 +100,22 @@ public:
double* oglmatrix,
int drawingmode
)=0;
+
+ /**
+ * Renders 2D boxes.
+ * \param xco Position on the screen (origin in lower left corner).
+ * \param yco Position on the screen (origin in lower left corner).
+ * \param width Width of the canvas to draw to.
+ * \param height Height of the canvas to draw to.
+ * \param percentage Percentage of bar.
+ */
+ virtual
+ void
+ RenderBox2D(int xco,
+ int yco,
+ int width,
+ int height,
+ float percentage) = 0;
/**
* Renders 3D text string using BFL.
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index 9fb47117f1d..8ea09029a35 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -605,7 +605,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
if (ms.m_pDeformer)
{
- ms.m_pDeformer->Apply(m_material);
+ if (ms.m_pDeformer->Apply(m_material))
+ ms.m_mesh->SetMeshModified(true);
// KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_)
}
@@ -648,10 +649,6 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
else
rasty->IndexPrimitives(ms);
- if (rasty->QueryLists())
- if (ms.m_DisplayList)
- ms.m_mesh->SetMeshModified(false);
-
rendertools->PopMatrix();
}
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 2ccb9453b3d..49b74895302 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -324,15 +324,14 @@ void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i,
const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
+ const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
bool flat,
int origindex)
{
- RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex);
+ RAS_TexVert texvert(xyz, uvs, tangent, rgba, normal, flat, origindex);
RAS_MeshMaterial *mmat;
RAS_DisplayArray *darray;
RAS_MeshSlot *slot;
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 281eae8734a..d77d0483024 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -116,8 +116,7 @@ public:
virtual RAS_Polygon* AddPolygon(RAS_MaterialBucket *bucket, int numverts);
virtual void AddVertex(RAS_Polygon *poly, int i,
const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
+ const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgbacolor,
const MT_Vector3& normal,
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
index 189c4f78f77..11cb4b1d9f9 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
@@ -46,12 +46,17 @@ set(SRC
RAS_GLExtensionManager.cpp
RAS_ListRasterizer.cpp
RAS_OpenGLRasterizer.cpp
- RAS_VAOpenGLRasterizer.cpp
+ RAS_StorageIM.cpp
+ RAS_StorageVA.cpp
+ RAS_StorageVBO.cpp
RAS_GLExtensionManager.h
+ RAS_IStorage.h
RAS_ListRasterizer.h
RAS_OpenGLRasterizer.h
- RAS_VAOpenGLRasterizer.h
+ RAS_StorageIM.h
+ RAS_StorageVA.h
+ RAS_StorageVBO.h
)
add_definitions(-DGLEW_STATIC)
diff --git a/source/blender/blenloader/BLO_soundfile.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h
index d2f87139b74..f5c16bc8cd8 100644
--- a/source/blender/blenloader/BLO_soundfile.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h
@@ -24,18 +24,39 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLO_SOUNDFILE_H__
-#define __BLO_SOUNDFILE_H__
-/** \file BLO_soundfile.h
- * \ingroup blenloader
- */
+#ifndef __KX_STORAGE
+#define __KX_STORAGE
+
+#include "RAS_MaterialBucket.h"
+
+enum RAS_STORAGE_TYPE {
+ RAS_AUTO_STORAGE,
+ RAS_IMMEDIATE,
+ RAS_VA,
+ RAS_VBO
+};
+
+class RAS_IStorage
+{
+
+public:
+ virtual ~RAS_IStorage() {};
+
+ virtual bool Init()=0;
+ virtual void Exit()=0;
+
+ virtual void IndexPrimitives(RAS_MeshSlot& ms)=0;
+ virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms)=0;
-#include "DNA_sound_types.h"
-#include "DNA_packedFile_types.h"
+ virtual void SetDrawingMode(int drawingmode)=0;
-struct bSound;
-struct PackedFile;
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_IStorage"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
+};
+#endif //__KX_STORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
index d74aa134779..3a60643e9e7 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
@@ -106,9 +106,8 @@ bool RAS_ListSlot::End()
-RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock)
-: RAS_VAOpenGLRasterizer(canvas, lock),
- mUseVertexArrays(useVertexArrays),
+RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock, int storage)
+: RAS_OpenGLRasterizer(canvas, storage),
mATI(false)
{
if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc."))
@@ -238,11 +237,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
return;
}
}
- // derived mesh cannot use vertex array
- if (mUseVertexArrays && !ms.m_pDerivedMesh)
- RAS_VAOpenGLRasterizer::IndexPrimitives(ms);
- else
- RAS_OpenGLRasterizer::IndexPrimitives(ms);
+
+ RAS_OpenGLRasterizer::IndexPrimitives(ms);
if (ms.m_bDisplayList) {
localSlot->EndList();
@@ -267,13 +263,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
}
}
- // workaround: note how we do not use vertex arrays for making display
- // lists, since glVertexAttribPointerARB doesn't seem to work correct
- // in display lists on ATI? either a bug in the driver or in Blender ..
- if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh)
- RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms);
- else
- RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
+ RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
if (ms.m_bDisplayList) {
localSlot->EndList();
@@ -283,29 +273,17 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
bool RAS_ListRasterizer::Init(void)
{
- if (mUseVertexArrays) {
- return RAS_VAOpenGLRasterizer::Init();
- } else {
- return RAS_OpenGLRasterizer::Init();
- }
+ return RAS_OpenGLRasterizer::Init();
}
void RAS_ListRasterizer::SetDrawingMode(int drawingmode)
{
- if (mUseVertexArrays) {
- RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode);
- } else {
- RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
- }
+ RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
}
void RAS_ListRasterizer::Exit()
{
- if (mUseVertexArrays) {
- RAS_VAOpenGLRasterizer::Exit();
- } else {
- RAS_OpenGLRasterizer::Exit();
- }
+ RAS_OpenGLRasterizer::Exit();
}
// eof
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
index a8eb2d5ffdf..558850a9173 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
@@ -7,7 +7,7 @@
#define __RAS_LISTRASTERIZER_H__
#include "RAS_MaterialBucket.h"
-#include "RAS_VAOpenGLRasterizer.h"
+#include "RAS_OpenGLRasterizer.h"
#include <vector>
#include <map>
@@ -49,9 +49,8 @@ typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
typedef std::vector<RAS_ListSlot*> RAS_ListSlots; // indexed by material slot number
typedef std::map<DerivedMesh*, RAS_ListSlots*> RAS_DerivedMeshLists;
-class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
+class RAS_ListRasterizer : public RAS_OpenGLRasterizer
{
- bool mUseVertexArrays;
bool mATI;
RAS_ArrayLists mArrayLists;
RAS_DerivedMeshLists mDerivedMeshLists;
@@ -61,7 +60,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
public:
void RemoveListSlot(RAS_ListSlot* list);
- RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false);
+ RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock=false, int storage=RAS_AUTO_STORAGE);
virtual ~RAS_ListRasterizer();
virtual void IndexPrimitives(class RAS_MeshSlot& ms);
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 22a700c7d2b..0186e99f78a 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -43,6 +43,10 @@
#include "MT_CmMatrix4x4.h"
#include "RAS_IRenderTools.h" // rendering text
+#include "RAS_StorageIM.h"
+#include "RAS_StorageVA.h"
+#include "RAS_StorageVBO.h"
+
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
@@ -74,7 +78,7 @@ static GLuint right_eye_vinterlace_mask[32];
*/
static GLuint hinterlace_mask[33];
-RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
+RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
:RAS_IRasterizer(canvas),
m_2DCanvas(canvas),
m_fogenabled(false),
@@ -89,11 +93,13 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_noOfScanlines(32),
m_motionblur(0),
m_motionblurvalue(-1.0),
+ m_usingoverrideshader(false),
m_texco_num(0),
m_attrib_num(0),
//m_last_alphablend(GPU_BLEND_SOLID),
m_last_frontface(true),
- m_materialCachingInfo(0)
+ m_materialCachingInfo(0),
+ m_storage_type(storage)
{
m_viewmatrix.setIdentity();
m_viewinvmatrix.setIdentity();
@@ -107,6 +113,24 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
hinterlace_mask[32] = 0;
m_prevafvalue = GPU_get_anisotropic();
+
+ if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/)
+ {
+ m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_storage_type = RAS_VBO;
+ }
+ else if ((m_storage_type == RAS_VA) || (m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1))
+ {
+ m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_storage_type = RAS_VA;
+ }
+ else
+ {
+ m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_storage_type = RAS_IMMEDIATE;
+ }
}
@@ -115,10 +139,16 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
{
// Restore the previous AF value
GPU_set_anisotropic(m_prevafvalue);
+ if (m_failsafe_storage && m_failsafe_storage != m_storage)
+ delete m_failsafe_storage;
+
+ if (m_storage)
+ delete m_storage;
}
bool RAS_OpenGLRasterizer::Init()
{
+ bool storage_init;
GPU_state_init();
@@ -146,7 +176,9 @@ bool RAS_OpenGLRasterizer::Init()
glShadeModel(GL_SMOOTH);
- return true;
+ storage_init = m_storage->Init();
+
+ return true && storage_init;
}
@@ -267,6 +299,8 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
void RAS_OpenGLRasterizer::Exit()
{
+ m_storage->Exit();
+
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0);
@@ -289,7 +323,7 @@ void RAS_OpenGLRasterizer::Exit()
bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
{
m_time = time;
- m_drawingmode = drawingmode;
+ SetDrawingMode(drawingmode);
// Blender camera routine destroys the settings
if (m_drawingmode < KX_SOLID)
@@ -328,6 +362,11 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
if (m_drawingmode == KX_WIREFRAME)
glDisable(GL_CULL_FACE);
+
+ m_storage->SetDrawingMode(drawingmode);
+ if (m_failsafe_storage && m_failsafe_storage != m_storage) {
+ m_failsafe_storage->SetDrawingMode(drawingmode);
+ }
}
int RAS_OpenGLRasterizer::GetDrawingMode()
@@ -666,7 +705,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
glattrib = -1;
if (GLEW_ARB_vertex_program)
for (unit=0; unit<m_attrib_num; unit++)
- if (m_attrib[unit] == RAS_TEXCO_UV1)
+ if (m_attrib[unit] == RAS_TEXCO_UV)
glattrib = unit;
rendertools->RenderText(polymat->GetDrawingMode(), polymat,
@@ -708,257 +747,20 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
m_attrib[unit] = coords;
}
-void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
-{
- int unit;
-
- if (GLEW_ARB_multitexture) {
- for (unit=0; unit<m_texco_num; unit++) {
- if (tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
- continue;
- }
- switch (m_texco[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
- break;
- case RAS_TEXCO_NORM:
- glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
- break;
- case RAS_TEXTANGENT:
- glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
- break;
- case RAS_TEXCO_UV2:
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
- break;
- default:
- break;
- }
- }
- }
-
- if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<m_attrib_num; unit++) {
- switch (m_attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glVertexAttrib3fvARB(unit, tv.getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glVertexAttrib2fvARB(unit, tv.getUV1());
- break;
- case RAS_TEXCO_NORM:
- glVertexAttrib3fvARB(unit, tv.getNormal());
- break;
- case RAS_TEXTANGENT:
- glVertexAttrib4fvARB(unit, tv.getTangent());
- break;
- case RAS_TEXCO_UV2:
- glVertexAttrib2fvARB(unit, tv.getUV2());
- break;
- case RAS_TEXCO_VCOL:
- glVertexAttrib4ubvARB(unit, tv.getRGBA());
- break;
- default:
- break;
- }
- }
- }
-
-}
-
void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
{
- IndexPrimitivesInternal(ms, false);
+ if (ms.m_pDerivedMesh)
+ m_failsafe_storage->IndexPrimitives(ms);
+ else
+ m_storage->IndexPrimitives(ms);
}
void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
{
- IndexPrimitivesInternal(ms, true);
-}
-
-static bool current_wireframe;
-static RAS_MaterialBucket *current_bucket;
-static RAS_IPolyMaterial *current_polymat;
-static RAS_MeshSlot *current_ms;
-static RAS_MeshObject *current_mesh;
-static int current_blmat_nr;
-static GPUVertexAttribs current_gpu_attribs;
-static Image *current_image;
-static int CheckMaterialDM(int matnr, void *attribs)
-{
- // only draw the current material
- if (matnr != current_blmat_nr)
- return 0;
- GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
- if (gattribs)
- memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
- return 1;
-}
-
-/*
-static int CheckTexfaceDM(void *mcol, int index)
-{
-
- // index is the original face index, retrieve the polygon
- RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
- current_mesh->GetPolygon(index) : NULL;
- if (polygon && polygon->GetMaterial() == current_bucket) {
- // must handle color.
- if (current_wireframe)
- return 2;
- if (current_ms->m_bObjectColor) {
- MT_Vector4& rgba = current_ms->m_RGBAcolor;
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- // don't use mcol
- return 2;
- }
- if (!mcol) {
- // we have to set the color from the material
- unsigned char rgba[4];
- current_polymat->GetMaterialRGBAColor(rgba);
- glColor4ubv((const GLubyte *)rgba);
- return 2;
- }
- return 1;
- }
- return 0;
-}
-*/
-
-static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
-{
-
- // index is the original face index, retrieve the polygon
- if (matnr == current_blmat_nr &&
- (tface == NULL || tface->tpage == current_image)) {
- // must handle color.
- if (current_wireframe)
- return DM_DRAW_OPTION_NO_MCOL;
- if (current_ms->m_bObjectColor) {
- MT_Vector4& rgba = current_ms->m_RGBAcolor;
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- // don't use mcol
- return DM_DRAW_OPTION_NO_MCOL;
- }
- if (!has_mcol) {
- // we have to set the color from the material
- unsigned char rgba[4];
- current_polymat->GetMaterialRGBAColor(rgba);
- glColor4ubv((const GLubyte *)rgba);
- return DM_DRAW_OPTION_NO_MCOL;
- }
- return DM_DRAW_OPTION_NORMAL;
- }
- return DM_DRAW_OPTION_SKIP;
-}
-
-void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
-{
- bool obcolor = ms.m_bObjectColor;
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
- MT_Vector4& rgba = ms.m_RGBAcolor;
- RAS_MeshSlot::iterator it;
-
- if (ms.m_pDerivedMesh) {
- // mesh data is in derived mesh,
- current_bucket = ms.m_bucket;
- current_polymat = current_bucket->GetPolyMaterial();
- current_ms = &ms;
- current_mesh = ms.m_mesh;
- current_wireframe = wireframe;
- // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
-
- // handle two-side
- if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
- this->SetCullFace(true);
- else
- this->SetCullFace(false);
-
- if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
- // GetMaterialIndex return the original mface material index,
- // increment by 1 to match what derived mesh is doing
- current_blmat_nr = current_polymat->GetMaterialIndex()+1;
- // For GLSL we need to retrieve the GPU material attribute
- Material* blmat = current_polymat->GetBlenderMaterial();
- Scene* blscene = current_polymat->GetBlenderScene();
- if (!wireframe && blscene && blmat)
- GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
- else
- memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
- // DM draw can mess up blending mode, restore at the end
- int current_blend_mode = GPU_get_material_alpha_blend();
- ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
- GPU_set_material_alpha_blend(current_blend_mode);
- }
- else {
- //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
- current_blmat_nr = current_polymat->GetMaterialIndex();
- current_image = current_polymat->GetBlenderImage();
- ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
- }
- return;
- }
- // iterate over display arrays, each containing an index + vertex array
- for (ms.begin(it); !ms.end(it); ms.next(it)) {
- RAS_TexVert *vertex;
- size_t i, j, numvert;
-
- numvert = it.array->m_type;
-
- if (it.array->m_type == RAS_DisplayArray::LINE) {
- // line drawing
- glBegin(GL_LINES);
-
- for (i=0; i<it.totindex; i+=2)
- {
- vertex = &it.vertex[it.index[i]];
- glVertex3fv(vertex->getXYZ());
-
- vertex = &it.vertex[it.index[i+1]];
- glVertex3fv(vertex->getXYZ());
- }
-
- glEnd();
- }
- else {
- // triangle and quad drawing
- if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
- glBegin(GL_TRIANGLES);
- else
- glBegin(GL_QUADS);
-
- for (i=0; i<it.totindex; i+=numvert)
- {
- if (obcolor)
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
-
- for (j=0; j<numvert; j++) {
- vertex = &it.vertex[it.index[i+j]];
-
- if (!wireframe) {
- if (!obcolor)
- glColor4ubv((const GLubyte *)(vertex->getRGBA()));
-
- glNormal3fv(vertex->getNormal());
-
- if (multi)
- TexCoord(*vertex);
- else
- glTexCoord2fv(vertex->getUV1());
- }
-
- glVertex3fv(vertex->getXYZ());
- }
- }
-
- glEnd();
- }
- }
+ if (ms.m_pDerivedMesh)
+ m_failsafe_storage->IndexPrimitivesMulti(ms);
+ else
+ m_storage->IndexPrimitivesMulti(ms);
}
void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
@@ -1259,3 +1061,14 @@ short RAS_OpenGLRasterizer::GetAnisotropicFiltering()
{
return (short)GPU_get_anisotropic();
}
+
+void RAS_OpenGLRasterizer::SetUsingOverrideShader(bool val)
+{
+ m_usingoverrideshader = val;
+}
+
+bool RAS_OpenGLRasterizer::GetUsingOverrideShader()
+{
+ return m_usingoverrideshader;
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 88bb0be531b..64c07358d95 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -41,6 +41,7 @@
using namespace std;
#include "RAS_IRasterizer.h"
+#include "RAS_IStorage.h"
#include "RAS_MaterialBucket.h"
#include "RAS_ICanvas.h"
@@ -83,7 +84,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
float m_ambr;
float m_ambg;
float m_ambb;
-
double m_time;
MT_Matrix4x4 m_viewmatrix;
MT_Matrix4x4 m_viewinvmatrix;
@@ -103,6 +103,8 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
int m_motionblur;
float m_motionblurvalue;
+ bool m_usingoverrideshader;
+
protected:
int m_drawingmode;
TexCoGen m_texco[RAS_MAX_TEXCO];
@@ -115,9 +117,16 @@ protected:
/** Stores the caching information for the last material activated. */
RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
+ /**
+ * Making use of a Strategy desing pattern for storage behavior.
+ * Examples of concrete strategies: Vertex Arrays, VBOs, Immediate Mode*/
+ int m_storage_type;
+ RAS_IStorage* m_storage;
+ RAS_IStorage* m_failsafe_storage; //So derived mesh can use immediate mode
+
public:
double GetTime();
- RAS_OpenGLRasterizer(RAS_ICanvas* canv);
+ RAS_OpenGLRasterizer(RAS_ICanvas* canv, int storage=RAS_AUTO_STORAGE);
virtual ~RAS_OpenGLRasterizer();
/*enum DrawType
@@ -166,8 +175,6 @@ public:
class RAS_IPolyMaterial* polymat,
class RAS_IRenderTools* rendertools);
- void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
-
virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat);
virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat);
virtual void SetViewMatrix(
@@ -316,6 +323,8 @@ public:
virtual void SetAnisotropicFiltering(short level);
virtual short GetAnisotropicFiltering();
+ virtual void SetUsingOverrideShader(bool val);
+ virtual bool GetUsingOverrideShader();
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_OpenGLRasterizer")
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
new file mode 100644
index 00000000000..7bcc8dc9034
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
@@ -0,0 +1,310 @@
+/*
+ * ***** 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 *****
+ */
+
+#include "RAS_StorageIM.h"
+
+#include "GL/glew.h"
+#include "GPU_draw.h"
+#include "GPU_extensions.h"
+#include "GPU_material.h"
+
+#include "DNA_meshdata_types.h"
+
+extern "C"{
+ #include "BLI_utildefines.h"
+ #include "BKE_DerivedMesh.h"
+}
+
+RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
+ m_texco_num(texco_num),
+ m_attrib_num(attrib_num),
+ m_texco(texco),
+ m_attrib(attrib)
+{
+}
+RAS_StorageIM::~RAS_StorageIM()
+{
+}
+
+bool RAS_StorageIM::Init()
+{
+ return true;
+}
+void RAS_StorageIM::Exit()
+{
+}
+
+void RAS_StorageIM::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, false);
+}
+
+void RAS_StorageIM::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, true);
+}
+
+void RAS_StorageIM::TexCoord(const RAS_TexVert &tv)
+{
+ int unit;
+
+ if (GLEW_ARB_multitexture) {
+ for (unit = 0; unit < *m_texco_num; unit++) {
+ switch (m_texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, tv.getUV(unit));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, tv.getTangent());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (GLEW_ARB_vertex_program) {
+ int uv = 0;
+ for (unit = 0; unit < *m_attrib_num; unit++) {
+ switch (m_attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glVertexAttrib3fvARB(unit, tv.getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glVertexAttrib2fvARB(unit, tv.getUV(uv++));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glVertexAttrib3fvARB(unit, tv.getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glVertexAttrib4fvARB(unit, tv.getTangent());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ glVertexAttrib4ubvARB(unit, tv.getRGBA());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+}
+
+void RAS_StorageIM::SetCullFace(bool enable)
+{
+ if (enable)
+ glEnable(GL_CULL_FACE);
+ else
+ glDisable(GL_CULL_FACE);
+}
+
+static bool current_wireframe;
+static RAS_MaterialBucket *current_bucket;
+static RAS_IPolyMaterial *current_polymat;
+static RAS_MeshSlot *current_ms;
+static RAS_MeshObject *current_mesh;
+static int current_blmat_nr;
+static GPUVertexAttribs current_gpu_attribs;
+static Image *current_image;
+static int CheckMaterialDM(int matnr, void *attribs)
+{
+ // only draw the current material
+ if (matnr != current_blmat_nr)
+ return 0;
+ GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
+ if (gattribs)
+ memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
+ return 1;
+}
+
+/*
+static int CheckTexfaceDM(void *mcol, int index)
+{
+
+ // index is the original face index, retrieve the polygon
+ RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
+ current_mesh->GetPolygon(index) : NULL;
+ if (polygon && polygon->GetMaterial() == current_bucket) {
+ // must handle color.
+ if (current_wireframe)
+ return 2;
+ if (current_ms->m_bObjectColor) {
+ MT_Vector4& rgba = current_ms->m_RGBAcolor;
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ // don't use mcol
+ return 2;
+ }
+ if (!mcol) {
+ // we have to set the color from the material
+ unsigned char rgba[4];
+ current_polymat->GetMaterialRGBAColor(rgba);
+ glColor4ubv((const GLubyte *)rgba);
+ return 2;
+ }
+ return 1;
+ }
+ return 0;
+}
+*/
+
+static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
+{
+
+ // index is the original face index, retrieve the polygon
+ if (matnr == current_blmat_nr &&
+ (tface == NULL || tface->tpage == current_image)) {
+ // must handle color.
+ if (current_wireframe)
+ return DM_DRAW_OPTION_NO_MCOL;
+ if (current_ms->m_bObjectColor) {
+ MT_Vector4& rgba = current_ms->m_RGBAcolor;
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ // don't use mcol
+ return DM_DRAW_OPTION_NO_MCOL;
+ }
+ if (!has_mcol) {
+ // we have to set the color from the material
+ unsigned char rgba[4];
+ current_polymat->GetMaterialRGBAColor(rgba);
+ glColor4ubv((const GLubyte *)rgba);
+ return DM_DRAW_OPTION_NO_MCOL;
+ }
+ return DM_DRAW_OPTION_NORMAL;
+ }
+ return DM_DRAW_OPTION_SKIP;
+}
+
+void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
+{
+ bool obcolor = ms.m_bObjectColor;
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
+ MT_Vector4& rgba = ms.m_RGBAcolor;
+ RAS_MeshSlot::iterator it;
+
+ if (ms.m_pDerivedMesh) {
+ // mesh data is in derived mesh,
+ current_bucket = ms.m_bucket;
+ current_polymat = current_bucket->GetPolyMaterial();
+ current_ms = &ms;
+ current_mesh = ms.m_mesh;
+ current_wireframe = wireframe;
+ // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
+
+ // handle two-side
+ if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
+ this->SetCullFace(true);
+ else
+ this->SetCullFace(false);
+
+ if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
+ // GetMaterialIndex return the original mface material index,
+ // increment by 1 to match what derived mesh is doing
+ current_blmat_nr = current_polymat->GetMaterialIndex()+1;
+ // For GLSL we need to retrieve the GPU material attribute
+ Material* blmat = current_polymat->GetBlenderMaterial();
+ Scene* blscene = current_polymat->GetBlenderScene();
+ if (!wireframe && blscene && blmat)
+ GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
+ else
+ memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
+ // DM draw can mess up blending mode, restore at the end
+ int current_blend_mode = GPU_get_material_alpha_blend();
+ ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
+ GPU_set_material_alpha_blend(current_blend_mode);
+ } else {
+ //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
+ current_blmat_nr = current_polymat->GetMaterialIndex();
+ current_image = current_polymat->GetBlenderImage();
+ ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
+ }
+ return;
+ }
+ // iterate over display arrays, each containing an index + vertex array
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ RAS_TexVert *vertex;
+ size_t i, j, numvert;
+
+ numvert = it.array->m_type;
+
+ if (it.array->m_type == RAS_DisplayArray::LINE) {
+ // line drawing
+ glBegin(GL_LINES);
+
+ for (i = 0; i < it.totindex; i += 2)
+ {
+ vertex = &it.vertex[it.index[i]];
+ glVertex3fv(vertex->getXYZ());
+
+ vertex = &it.vertex[it.index[i+1]];
+ glVertex3fv(vertex->getXYZ());
+ }
+
+ glEnd();
+ }
+ else {
+ // triangle and quad drawing
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ glBegin(GL_TRIANGLES);
+ else
+ glBegin(GL_QUADS);
+
+ for (i = 0; i < it.totindex; i += numvert)
+ {
+ if (obcolor)
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+
+ for (j = 0; j < numvert; j++) {
+ vertex = &it.vertex[it.index[i+j]];
+
+ if (!wireframe) {
+ if (!obcolor)
+ glColor4ubv((const GLubyte *)(vertex->getRGBA()));
+
+ glNormal3fv(vertex->getNormal());
+
+ if (multi)
+ TexCoord(*vertex);
+ else
+ glTexCoord2fv(vertex->getUV(0));
+ }
+
+ glVertex3fv(vertex->getXYZ());
+ }
+ }
+
+ glEnd();
+ }
+ }
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h
new file mode 100644
index 00000000000..de4ff30d394
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h
@@ -0,0 +1,68 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef __KX_IMMEDIATEMODESTORAGE
+#define __KX_IMMEDIATEMODESTORAGE
+
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
+
+class RAS_StorageIM : public RAS_IStorage
+{
+public:
+ RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+ virtual ~RAS_StorageIM();
+
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual void IndexPrimitives(RAS_MeshSlot& ms);
+ virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
+
+ virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+ int m_drawingmode;
+ int* m_texco_num;
+ int* m_attrib_num;
+ RAS_IRasterizer::TexCoGen* m_texco;
+ RAS_IRasterizer::TexCoGen* m_attrib;
+
+ void TexCoord(const RAS_TexVert &tv);
+ void SetCullFace(bool enable);
+
+ void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageIM"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_IMMEDIATEMODESTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
new file mode 100644
index 00000000000..7182525ea71
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
@@ -0,0 +1,320 @@
+/*
+ * ***** 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 *****
+ */
+
+#include "RAS_StorageVA.h"
+
+#include "GL/glew.h"
+
+RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
+ m_texco_num(texco_num),
+ m_attrib_num(attrib_num),
+ m_last_texco_num(0),
+ m_last_attrib_num(0),
+ m_texco(texco),
+ m_attrib(attrib)
+{
+}
+
+RAS_StorageVA::~RAS_StorageVA()
+{
+}
+
+bool RAS_StorageVA::Init()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ return true;
+}
+
+void RAS_StorageVA::Exit()
+{
+}
+
+void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ static const GLsizei stride = sizeof(RAS_TexVert);
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ if (!wireframe)
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // use glDrawElements to draw each vertexarray
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ if (it.totindex == 0)
+ continue;
+
+ // drawing mode
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ drawmode = GL_TRIANGLES;
+ else if (it.array->m_type == RAS_DisplayArray::QUAD)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
+ // colors
+ if (drawmode != GL_LINES && !wireframe) {
+ if (ms.m_bObjectColor) {
+ const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ }
+ else {
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+ }
+ else
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+
+ glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+ glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+ if (!wireframe) {
+ glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
+ if (glIsEnabled(GL_COLOR_ARRAY))
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+ }
+
+ // here the actual drawing takes places
+ glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ if (!wireframe) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+}
+
+void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
+{
+ static const GLsizei stride = sizeof(RAS_TexVert);
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME, use_color_array;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ if (!wireframe)
+ EnableTextures(true);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // use glDrawElements to draw each vertexarray
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ if (it.totindex == 0)
+ continue;
+
+ // drawing mode
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ drawmode = GL_TRIANGLES;
+ else if (it.array->m_type == RAS_DisplayArray::QUAD)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
+ // colors
+ if (drawmode != GL_LINES && !wireframe) {
+ if (ms.m_bObjectColor) {
+ const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ use_color_array = false;
+ }
+ else {
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glEnableClientState(GL_COLOR_ARRAY);
+ use_color_array = true;
+ }
+ }
+ else
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+
+ glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+ glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+
+ if (!wireframe) {
+ TexCoordPtr(it.vertex);
+ if (use_color_array)
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+ }
+
+ // here the actual drawing takes places
+ glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ if (!wireframe) {
+ glDisableClientState(GL_COLOR_ARRAY);
+ EnableTextures(false);
+ }
+}
+
+void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv)
+{
+ /* note: this function must closely match EnableTextures to enable/disable
+ * the right arrays, otherwise coordinate and attribute pointers from other
+ * materials can still be used and cause crashes */
+ int unit;
+
+ if (GLEW_ARB_multitexture)
+ {
+ for (unit = 0; unit < *m_texco_num; unit++)
+ {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
+ switch (m_texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
+ break;
+ default:
+ break;
+ }
+ }
+
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+
+ if (GLEW_ARB_vertex_program) {
+ int uv = 0;
+ for (unit = 0; unit < *m_attrib_num; unit++) {
+ switch (m_attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void RAS_StorageVA::EnableTextures(bool enable)
+{
+ RAS_IRasterizer::TexCoGen *texco, *attrib;
+ int unit, texco_num, attrib_num;
+
+ /* we cache last texcoords and attribs to ensure we disable the ones that
+ * were actually last set */
+ if (enable) {
+ texco = m_texco;
+ texco_num = *m_texco_num;
+ attrib = m_attrib;
+ attrib_num = *m_attrib_num;
+
+ memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num));
+ m_last_texco_num = *m_texco_num;
+ memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num));
+ m_last_attrib_num = *m_attrib_num;
+ }
+ else {
+ texco = m_last_texco;
+ texco_num = m_last_texco_num;
+ attrib = m_last_attrib;
+ attrib_num = m_last_attrib_num;
+ }
+
+ if (GLEW_ARB_multitexture) {
+ for (unit = 0; unit < texco_num; unit++) {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB + unit);
+
+ switch (texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ default:
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ }
+ }
+
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ else {
+ if (texco_num) {
+ if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+
+ if (GLEW_ARB_vertex_program) {
+ for (unit = 0; unit < attrib_num; unit++) {
+ switch (attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ if (enable) glEnableVertexAttribArrayARB(unit);
+ else glDisableVertexAttribArrayARB(unit);
+ break;
+ default:
+ glDisableVertexAttribArrayARB(unit);
+ break;
+ }
+ }
+ }
+
+ if (!enable) {
+ m_last_texco_num = 0;
+ m_last_attrib_num = 0;
+ }
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
index 6b159db05ed..da7766ec5ca 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
@@ -25,46 +25,53 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file RAS_VAOpenGLRasterizer.h
- * \ingroup bgerastogl
- */
+#ifndef __KX_VERTEXARRAYSTORAGE
+#define __KX_VERTEXARRAYSTORAGE
-#ifndef __RAS_VAOPENGLRASTERIZER_H__
-#define __RAS_VAOPENGLRASTERIZER_H__
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
#include "RAS_OpenGLRasterizer.h"
-class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer
+class RAS_StorageVA : public RAS_IStorage
{
- void TexCoordPtr(const RAS_TexVert *tv);
- /* bool m_Lock; */ /* UNUSED */
-
- TexCoGen m_last_texco[RAS_MAX_TEXCO];
- TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
- int m_last_texco_num;
- int m_last_attrib_num;
public:
- RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false);
- virtual ~RAS_VAOpenGLRasterizer();
+ RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+ virtual ~RAS_StorageVA();
virtual bool Init();
virtual void Exit();
- virtual void SetDrawingMode(int drawingmode);
-
- virtual void IndexPrimitives(class RAS_MeshSlot& ms);
+ virtual void IndexPrimitives(RAS_MeshSlot& ms);
virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
-private:
+ virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+ int m_drawingmode;
+
+ int* m_texco_num;
+ int* m_attrib_num;
+
+ int m_last_texco_num;
+ int m_last_attrib_num;
+
+ RAS_IRasterizer::TexCoGen* m_texco;
+ RAS_IRasterizer::TexCoGen* m_attrib;
+
+ RAS_IRasterizer::TexCoGen m_last_texco[RAS_MAX_TEXCO];
+ RAS_IRasterizer::TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
+
virtual void EnableTextures(bool enable);
- //virtual bool QueryArrays() {return true;}
- //virtual bool QueryLists() {return m_Lock;}
+ virtual void TexCoordPtr(const RAS_TexVert *tv);
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_VAOpenGLRasterizer")
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
-#endif /* __RAS_VAOPENGLRASTERIZER_H__ */
+#endif //__KX_VERTEXARRAYSTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
new file mode 100644
index 00000000000..077dfad80bb
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
@@ -0,0 +1,259 @@
+/*
+ * ***** 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 *****
+ */
+
+#include "RAS_StorageVBO.h"
+#include "RAS_MeshObject.h"
+
+#include "GL/glew.h"
+
+VBO::VBO(RAS_DisplayArray *data, unsigned int indices)
+{
+ this->data = data;
+ this->size = data->m_vertex.size();
+ this->indices = indices;
+ this->stride = 32*sizeof(GLfloat); // ATI cards really like 32byte aligned VBOs, so we add a little padding
+
+ // Determine drawmode
+ if (data->m_type == data->QUAD)
+ this->mode = GL_QUADS;
+ else if (data->m_type == data->TRIANGLE)
+ this->mode = GL_TRIANGLES;
+ else
+ this->mode = GL_LINE;
+
+ // Generate Buffers
+ glGenBuffersARB(1, &this->ibo);
+ glGenBuffersARB(1, &this->vbo_id);
+
+ // Fill the buffers with initial data
+ UpdateIndices();
+ UpdateData();
+
+ // Establish offsets
+ this->vertex_offset = 0;
+ this->normal_offset = (void*)(3*sizeof(GLfloat));
+ this->tangent_offset = (void*)(6*sizeof(GLfloat));
+ this->color_offset = (void*)(10*sizeof(GLfloat));
+ this->uv_offset = (void*)(11*sizeof(GLfloat));
+}
+
+VBO::~VBO()
+{
+ glDeleteBuffersARB(1, &this->ibo);
+ glDeleteBuffersARB(1, &this->vbo_id);
+}
+
+void VBO::UpdateData()
+{
+ unsigned int i, j, k;
+
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
+ glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, NULL, GL_STATIC_DRAW);
+
+ // Map the buffer
+ GLfloat *vbo_map = (GLfloat*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+ // Gather data
+ for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat))
+ {
+ memcpy(&vbo_map[j], data->m_vertex[i].getXYZ(), sizeof(float)*3);
+ memcpy(&vbo_map[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3);
+ memcpy(&vbo_map[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4);
+ memcpy(&vbo_map[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4);
+
+ for (k = 0; k < RAS_TexVert::MAX_UNIT; k++)
+ memcpy(&vbo_map[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2);
+ }
+
+ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+}
+
+void VBO::UpdateIndices()
+{
+ int space = data->m_index.size() * sizeof(GLushort);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
+
+ // Upload Data to VBO
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_STATIC_DRAW);
+}
+
+void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi)
+{
+ int unit;
+
+ // Bind buffers
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
+
+ // Vertexes
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
+
+ // Normals
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(GL_FLOAT, this->stride, this->normal_offset);
+
+ // Colors
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset);
+
+ if (multi)
+ {
+ for (unit = 0; unit < texco_num; ++unit)
+ {
+ glClientActiveTexture(GL_TEXTURE0_ARB + unit);
+ switch (texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit)));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset);
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset);
+ break;
+ default:
+ break;
+ }
+ }
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ else //TexFace
+ {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset);
+ }
+
+ if (GLEW_ARB_vertex_program)
+ {
+ int uv = 0;
+ for (unit = 0; unit < attrib_num; ++unit)
+ {
+ switch (attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset);
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv));
+ uv += sizeof(GLfloat)*2;
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset);
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset);
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ if (GLEW_ARB_vertex_program)
+ {
+ for (int i = 0; i < attrib_num; ++i)
+ glDisableVertexAttribArrayARB(i);
+ }
+
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+}
+
+RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib):
+ m_texco_num(texco_num),
+ m_attrib_num(attrib_num),
+ m_texco(texco),
+ m_attrib(attrib)
+{
+}
+
+RAS_StorageVBO::~RAS_StorageVBO()
+{
+}
+
+bool RAS_StorageVBO::Init()
+{
+ return true;
+}
+
+void RAS_StorageVBO::Exit()
+{
+ m_vbo_lookup.clear();
+}
+
+void RAS_StorageVBO::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, false);
+}
+
+void RAS_StorageVBO::IndexPrimitivesMulti(RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, true);
+}
+
+void RAS_StorageVBO::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
+{
+ RAS_MeshSlot::iterator it;
+ VBO *vbo;
+
+ for (ms.begin(it); !ms.end(it); ms.next(it))
+ {
+ vbo = m_vbo_lookup[it.array];
+
+ if (vbo == 0)
+ m_vbo_lookup[it.array] = vbo = new VBO(it.array, it.totindex);
+
+ // Update the vbo
+ if (ms.m_mesh->MeshModified())
+ {
+ vbo->UpdateData();
+ }
+
+ vbo->Draw(*m_texco_num, m_texco, *m_attrib_num, m_attrib, multi);
+ }
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h
new file mode 100644
index 00000000000..d8d8192e482
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h
@@ -0,0 +1,100 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef __KX_VERTEXBUFFEROBJECTSTORAGE
+#define __KX_VERTEXBUFFEROBJECTSTORAGE
+
+#include <map>
+#include "GL/glew.h"
+
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
+
+#include "RAS_OpenGLRasterizer.h"
+
+class VBO
+{
+public:
+ VBO(RAS_DisplayArray *data, unsigned int indices);
+ ~VBO();
+
+ void Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi);
+
+ void UpdateData();
+ void UpdateIndices();
+private:
+ RAS_DisplayArray* data;
+ GLuint size;
+ GLuint stride;
+ GLuint indices;
+ GLenum mode;
+ GLuint ibo;
+ GLuint vbo_id;
+
+ void* vertex_offset;
+ void* normal_offset;
+ void* color_offset;
+ void* tangent_offset;
+ void* uv_offset;
+};
+
+class RAS_StorageVBO : public RAS_IStorage
+{
+
+public:
+ RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+ virtual ~RAS_StorageVBO();
+
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual void IndexPrimitives(RAS_MeshSlot& ms);
+ virtual void IndexPrimitivesMulti(RAS_MeshSlot& ms);
+
+ virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+ int m_drawingmode;
+
+ int* m_texco_num;
+ int* m_attrib_num;
+
+ RAS_IRasterizer::TexCoGen* m_texco;
+ RAS_IRasterizer::TexCoGen* m_attrib;
+
+ std::map<RAS_DisplayArray*, class VBO*> m_vbo_lookup;
+
+ virtual void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_VERTEXBUFFEROBJECTSTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
deleted file mode 100644
index 076acb0d153..00000000000
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
+++ /dev/null
@@ -1,382 +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) 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 gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
- * \ingroup bgerastogl
- */
-
-#include "RAS_VAOpenGLRasterizer.h"
-#include <stdlib.h>
-
-#include "GL/glew.h"
-#include "GPU_extensions.h"
-
-#include "STR_String.h"
-#include "RAS_TexVert.h"
-#include "MT_CmMatrix4x4.h"
-#include "RAS_IRenderTools.h" // rendering text
-
-RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock)
-: RAS_OpenGLRasterizer(canvas),
- /* m_Lock(lock && GLEW_EXT_compiled_vertex_array), */ /* UNUSED */
- m_last_texco_num(0),
- m_last_attrib_num(0)
-{
-}
-
-RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
-{
-}
-
-bool RAS_VAOpenGLRasterizer::Init(void)
-{
-
- bool result = RAS_OpenGLRasterizer::Init();
-
- if (result)
- {
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
-
- return result;
-}
-
-void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
-{
- m_drawingmode = drawingmode;
-
- switch (m_drawingmode)
- {
- case KX_BOUNDINGBOX:
- case KX_WIREFRAME:
- //glDisableClientState(GL_COLOR_ARRAY);
- //glDisable(GL_CULL_FACE);
- break;
- case KX_SOLID:
- //glDisableClientState(GL_COLOR_ARRAY);
- break;
- case KX_TEXTURED:
- case KX_SHADED:
- case KX_SHADOW:
- //glEnableClientState(GL_COLOR_ARRAY);
- default:
- break;
- }
-}
-
-void RAS_VAOpenGLRasterizer::Exit()
-{
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
- RAS_OpenGLRasterizer::Exit();
-}
-
-void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
-{
- static const GLsizei stride = sizeof(RAS_TexVert);
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
- RAS_MeshSlot::iterator it;
- GLenum drawmode;
-
- if (ms.m_pDerivedMesh) {
- // cannot be handled here, pass to RAS_OpenGLRasterizer
- RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false);
- return;
- }
-
- if (!wireframe)
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- // use glDrawElements to draw each vertexarray
- for (ms.begin(it); !ms.end(it); ms.next(it)) {
- if (it.totindex == 0)
- continue;
-
- // drawing mode
- if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
- drawmode = GL_TRIANGLES;
- else if (it.array->m_type == RAS_DisplayArray::QUAD)
- drawmode = GL_QUADS;
- else
- drawmode = GL_LINES;
-
- // colors
- if (drawmode != GL_LINES && !wireframe) {
- if (ms.m_bObjectColor) {
- const MT_Vector4& rgba = ms.m_RGBAcolor;
-
- glDisableClientState(GL_COLOR_ARRAY);
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- }
- else {
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- glEnableClientState(GL_COLOR_ARRAY);
- }
- }
- else
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-
- glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
- glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
- if (!wireframe) {
- glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1());
- if (glIsEnabled(GL_COLOR_ARRAY))
- glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
- }
-
- // here the actual drawing takes places
- glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
- }
-
- if (!wireframe) {
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- }
-}
-
-void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
-{
- static const GLsizei stride = sizeof(RAS_TexVert);
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
- RAS_MeshSlot::iterator it;
- GLenum drawmode;
-
- if (ms.m_pDerivedMesh) {
- // cannot be handled here, pass to RAS_OpenGLRasterizer
- RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true);
- return;
- }
-
- if (!wireframe)
- EnableTextures(true);
-
- // use glDrawElements to draw each vertexarray
- for (ms.begin(it); !ms.end(it); ms.next(it)) {
- if (it.totindex == 0)
- continue;
-
- // drawing mode
- if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
- drawmode = GL_TRIANGLES;
- else if (it.array->m_type == RAS_DisplayArray::QUAD)
- drawmode = GL_QUADS;
- else
- drawmode = GL_LINES;
-
- // colors
- if (drawmode != GL_LINES && !wireframe) {
- if (ms.m_bObjectColor) {
- const MT_Vector4& rgba = ms.m_RGBAcolor;
-
- glDisableClientState(GL_COLOR_ARRAY);
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- }
- else {
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- glEnableClientState(GL_COLOR_ARRAY);
- }
- }
- else
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-
- glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
- glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
- if (!wireframe) {
- TexCoordPtr(it.vertex);
- if (glIsEnabled(GL_COLOR_ARRAY))
- glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
- }
-
- // here the actual drawing takes places
- glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
- }
-
- if (!wireframe) {
- glDisableClientState(GL_COLOR_ARRAY);
- EnableTextures(false);
- }
-}
-
-void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
-{
- /* note: this function must closely match EnableTextures to enable/disable
- * the right arrays, otherwise coordinate and attribute pointers from other
- * materials can still be used and cause crashes */
- int unit;
-
- if (GLEW_ARB_multitexture)
- {
- for (unit=0; unit<m_texco_num; unit++)
- {
- glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
- if (tv->getFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) {
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2());
- continue;
- }
- switch (m_texco[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1());
- break;
- case RAS_TEXCO_NORM:
- glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
- break;
- case RAS_TEXTANGENT:
- glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
- break;
- case RAS_TEXCO_UV2:
- glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2());
- break;
- default:
- break;
- }
- }
-
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
-
- if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<m_attrib_num; unit++) {
- switch (m_attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1());
- break;
- case RAS_TEXCO_NORM:
- glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
- break;
- case RAS_TEXTANGENT:
- glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
- break;
- case RAS_TEXCO_UV2:
- glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2());
- break;
- case RAS_TEXCO_VCOL:
- glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
- break;
- default:
- break;
- }
- }
- }
-}
-
-void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
-{
- TexCoGen *texco, *attrib;
- int unit, texco_num, attrib_num;
-
- /* we cache last texcoords and attribs to ensure we disable the ones that
- * were actually last set */
- if (enable) {
- texco = m_texco;
- texco_num = m_texco_num;
- attrib = m_attrib;
- attrib_num = m_attrib_num;
-
- memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num);
- m_last_texco_num = m_texco_num;
- memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num);
- m_last_attrib_num = m_attrib_num;
- }
- else {
- texco = m_last_texco;
- texco_num = m_last_texco_num;
- attrib = m_last_attrib;
- attrib_num = m_last_attrib_num;
- }
-
- if (GLEW_ARB_multitexture) {
- for (unit=0; unit<texco_num; unit++) {
- glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
-
- switch (texco[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- case RAS_TEXCO_UV1:
- case RAS_TEXCO_NORM:
- case RAS_TEXTANGENT:
- case RAS_TEXCO_UV2:
- if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- break;
- default:
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- break;
- }
- }
-
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- else {
- if (texco_num) {
- if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- }
-
- if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<attrib_num; unit++) {
- switch (attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- case RAS_TEXCO_UV1:
- case RAS_TEXCO_NORM:
- case RAS_TEXTANGENT:
- case RAS_TEXCO_UV2:
- case RAS_TEXCO_VCOL:
- if (enable) glEnableVertexAttribArrayARB(unit);
- else glDisableVertexAttribArrayARB(unit);
- break;
- default:
- glDisableVertexAttribArrayARB(unit);
- break;
- }
- }
- }
-
- if (!enable) {
- m_last_texco_num = 0;
- m_last_attrib_num = 0;
- }
-}
-
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
index 945644ff3e6..aaaf70728fe 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.cpp
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -32,26 +32,29 @@
#include "RAS_TexVert.h"
#include "MT_Matrix4x4.h"
+#include "BLI_math.h"
RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
- const MT_Vector4& tangent,
- const unsigned int rgba,
- const MT_Vector3& normal,
- const bool flat,
- const unsigned int origindex)
+ const MT_Point2 uvs[MAX_UNIT],
+ const MT_Vector4& tangent,
+ const unsigned int rgba,
+ const MT_Vector3& normal,
+ const bool flat,
+ const unsigned int origindex)
{
xyz.getValue(m_localxyz);
- uv.getValue(m_uv1);
- uv2.getValue(m_uv2);
SetRGBA(rgba);
SetNormal(normal);
tangent.getValue(m_tangent);
- m_flag = (flat)? FLAT: 0;
+ m_flag = (flat) ? FLAT: 0;
m_origindex = origindex;
m_unit = 2;
m_softBodyIndex = -1;
+
+ for (int i = 0; i < MAX_UNIT; ++i)
+ {
+ uvs[i].getValue(m_uvs[i]);
+ }
}
const MT_Point3& RAS_TexVert::xyz()
@@ -77,29 +80,17 @@ void RAS_TexVert::SetXYZ(const MT_Point3& xyz)
void RAS_TexVert::SetXYZ(const float xyz[3])
{
- m_localxyz[0] = xyz[0]; m_localxyz[1] = xyz[1]; m_localxyz[2] = xyz[2];
-}
-
-void RAS_TexVert::SetUV1(const MT_Point2& uv)
-{
- uv.getValue(m_uv1);
+ copy_v3_v3(m_localxyz, xyz);
}
-void RAS_TexVert::SetUV1(const float uv[3])
+void RAS_TexVert::SetUV(int index, const MT_Point2& uv)
{
- m_uv1[0] = uv[0];
- m_uv1[1] = uv[1];
+ uv.getValue(m_uvs[index]);
}
-void RAS_TexVert::SetUV2(const MT_Point2& uv)
+void RAS_TexVert::SetUV(int index, const float uv[2])
{
- uv.getValue(m_uv2);
-}
-
-void RAS_TexVert::SetUV2(const float uv[3])
-{
- m_uv2[0] = uv[0];
- m_uv2[1] = uv[1];
+ copy_v2_v2(m_uvs[index], uv);
}
void RAS_TexVert::SetRGBA(const unsigned int rgba)
@@ -115,7 +106,7 @@ void RAS_TexVert::SetFlag(const short flag)
void RAS_TexVert::SetUnit(const unsigned int u)
{
- m_unit = u <= (unsigned int) MAX_UNIT ? u: (unsigned int)MAX_UNIT;
+ m_unit = (u <= (unsigned int) MAX_UNIT) ? u: (unsigned int)MAX_UNIT;
}
void RAS_TexVert::SetNormal(const MT_Vector3& normal)
@@ -132,16 +123,21 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
// compare two vertices, and return TRUE if both are almost identical (they can be shared)
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
{
- return (
- /* m_flag == other->m_flag && */
- /* at the moment the face only stores the smooth/flat setting so don't bother comparing it */
- m_rgba == other->m_rgba &&
- MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) &&
- MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) &&
- MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) &&
- MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* &&
- MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/);
- /* don't bother comparing m_localxyz since we know there from the same vert */
+ const float eps = FLT_EPSILON;
+ for (int i = 0; i < MAX_UNIT; i++) {
+ if (!compare_v2v2(m_uvs[i], other->m_uvs[i], eps)) {
+ return false;
+ }
+ }
+
+ return (/* m_flag == other->m_flag && */
+ /* at the moment the face only stores the smooth/flat setting so don't bother comparing it */
+ (m_rgba == other->m_rgba) &&
+ compare_v3v3(m_normal, other->m_normal, eps) &&
+ compare_v3v3(m_tangent, other->m_tangent, eps)
+ /* don't bother comparing m_localxyz since we know there from the same vert */
+ /* && compare_v3v3(m_localxyz, other->m_localxyz, eps))*/
+ );
}
short RAS_TexVert::getFlag() const
@@ -157,17 +153,12 @@ unsigned int RAS_TexVert::getUnit() const
void RAS_TexVert::Transform(const MT_Matrix4x4& mat, const MT_Matrix4x4& nmat)
{
- SetXYZ((mat*MT_Vector4(m_localxyz[0], m_localxyz[1], m_localxyz[2], 1.0)).getValue());
- SetNormal((nmat*MT_Vector4(m_normal[0], m_normal[1], m_normal[2], 1.0)).getValue());
- SetTangent((nmat*MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue());
-}
-
-void RAS_TexVert::TransformUV1(const MT_Matrix4x4& mat)
-{
- SetUV1((mat * MT_Vector4(m_uv1[0], m_uv1[1], 0.0, 1.0)).getValue());
+ SetXYZ((mat * MT_Vector4(m_localxyz[0], m_localxyz[1], m_localxyz[2], 1.0)).getValue());
+ SetNormal((nmat * MT_Vector4(m_normal[0], m_normal[1], m_normal[2], 1.0)).getValue());
+ SetTangent((nmat * MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue());
}
-void RAS_TexVert::TransformUV2(const MT_Matrix4x4& mat)
+void RAS_TexVert::TransformUV(int index, const MT_Matrix4x4& mat)
{
- SetUV2((mat * MT_Vector4(m_uv2[0], m_uv2[1], 0.0, 1.0)).getValue());
+ SetUV(index, (mat * MT_Vector4(m_uvs[index][0], m_uvs[index][1], 0.0, 1.0)).getValue());
}
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h
index 98ea4dd60aa..a91d2c7f848 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.h
+++ b/source/gameengine/Rasterizer/RAS_TexVert.h
@@ -48,23 +48,21 @@ class RAS_TexVert
{
float m_localxyz[3]; // 3*4 = 12
- float m_uv1[2]; // 2*4 = 8
- float m_uv2[2]; // 2*4 = 8
+ float m_uvs[8][2]; // 8*2*4=64 //8 = MAX_UNIT
unsigned int m_rgba; // 4
- float m_tangent[4]; // 4*4 = 16
- float m_normal[3]; // 3*4 = 12
+ float m_tangent[4]; // 4*4 = 16
+ float m_normal[3]; // 3*4 = 12
short m_flag; // 2
short m_softBodyIndex; //2
unsigned int m_unit; // 4
unsigned int m_origindex; // 4
//---------
- // 56+6+8+2=72
- // 32 bytes total size, fits nice = 56 = not fit nice.
+ // 120
+ // 32 bytes total size, fits nice = 120 = not fit nice.
public:
enum {
FLAT = 1,
- SECOND_UV = 2,
MAX_UNIT = 8
};
@@ -74,8 +72,7 @@ public:
RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0)
{}
RAS_TexVert(const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
+ const MT_Point2 uvs[MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
@@ -83,12 +80,8 @@ public:
const unsigned int origindex);
~RAS_TexVert() {};
- const float* getUV1 () const {
- return m_uv1;
- };
-
- const float* getUV2 () const {
- return m_uv2;
+ const float* getUV (int unit) const {
+ return m_uvs[unit];
};
const float* getXYZ() const {
@@ -123,10 +116,8 @@ public:
void SetXYZ(const MT_Point3& xyz);
void SetXYZ(const float xyz[3]);
- void SetUV1(const MT_Point2& uv);
- void SetUV2(const MT_Point2& uv);
- void SetUV1(const float uv[2]);
- void SetUV2(const float uv[2]);
+ void SetUV(int index, const MT_Point2& uv);
+ void SetUV(int index, const float uv[2]);
void SetRGBA(const unsigned int rgba);
void SetNormal(const MT_Vector3& normal);
@@ -139,8 +130,7 @@ public:
void Transform(const class MT_Matrix4x4& mat,
const class MT_Matrix4x4& nmat);
- void TransformUV1(const MT_Matrix4x4& mat);
- void TransformUV2(const MT_Matrix4x4& mat);
+ void TransformUV(int index, const MT_Matrix4x4& mat);
// compare two vertices, to test if they can be shared, used for
// splitting up based on uv's, colors, etc
diff --git a/source/gameengine/Rasterizer/RAS_texmatrix.cpp b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
index d335a38171f..3203fcf9d6b 100644
--- a/source/gameengine/Rasterizer/RAS_texmatrix.cpp
+++ b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
@@ -52,9 +52,9 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Ve
MT_Scalar d = -p[0].xyz().dot(normal);
- MT_Matrix3x3 mat3( p[0].getUV1()[0],p[0].getUV1()[1], 1,
- p[1].getUV1()[0],p[1].getUV1()[1], 1,
- p[2].getUV1()[0],p[2].getUV1()[1], 1);
+ MT_Matrix3x3 mat3( p[0].getUV(0)[0],p[0].getUV(0)[1], 1,
+ p[1].getUV(0)[0],p[1].getUV(0)[1], 1,
+ p[2].getUV(0)[0],p[2].getUV(0)[1], 1);
MT_Matrix3x3 mat3inv = mat3.inverse();
diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript
index 4164271ba9b..4ff79d9ce24 100644
--- a/source/gameengine/Rasterizer/SConscript
+++ b/source/gameengine/Rasterizer/SConscript
@@ -1,18 +1,59 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
+incs = [
+ '.',
+ '#intern/guardedalloc',
+ '#intern/string',
+ '#intern/moto/include',
+ '#intern/container',
+ '#source/gameengine/BlenderRoutines',
+ '#extern/glew/include',
+ '#source/gameengine/Expressions',
+ '#source/gameengine/SceneGraph',
+ '#source/blender/blenlib',
+ '#source/blender/blenkernel',
+ '#source/blender/makesdna',
+ ]
-incs = '. #intern/guardedalloc #intern/string #intern/moto/include #intern/container #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna'
-
-defs = [ 'GLEW_STATIC' ]
+defs = ['GLEW_STATIC']
if env['WITH_BF_PYTHON']:
- incs += ' ' + env['BF_PYTHON_INC']
+ incs.append(env['BF_PYTHON_INC'])
defs.append('WITH_PYTHON')
if env['WITH_BF_CXX_GUARDEDALLOC']:
defs.append('WITH_CXX_GUARDEDALLOC')
-env.BlenderLib ( 'ge_rasterizer', sources, Split(incs), defs, libtype=['core','player'], priority=[350,70], cxx_compileflags=env['BGE_CXXFLAGS'])
+env.BlenderLib('ge_rasterizer', sources,
+ includes=incs, defines=defs,
+ libtype=['core', 'player'], priority=[350, 70],
+ cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript
index aebbf4d9fcf..ae1bb756f8e 100644
--- a/source/gameengine/SConscript
+++ b/source/gameengine/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
SConscript(['BlenderRoutines/SConscript',
@@ -9,7 +35,6 @@ SConscript(['BlenderRoutines/SConscript',
'Ketsji/KXNetwork/SConscript',
'Network/SConscript',
'Network/LoopBackNetwork/SConscript',
- 'Physics/common/SConscript',
'Physics/Dummy/SConscript',
'Rasterizer/SConscript',
'Rasterizer/RAS_OpenGLRasterizer/SConscript',
diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript
index 9270169199e..c88a2d6280b 100644
--- a/source/gameengine/SceneGraph/SConscript
+++ b/source/gameengine/SceneGraph/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import ('env')
diff --git a/source/gameengine/SceneGraph/SG_ParentRelation.h b/source/gameengine/SceneGraph/SG_ParentRelation.h
index 6e314996456..ce45b42c148 100644
--- a/source/gameengine/SceneGraph/SG_ParentRelation.h
+++ b/source/gameengine/SceneGraph/SG_ParentRelation.h
@@ -29,7 +29,7 @@
/** \file SG_ParentRelation.h
* \ingroup bgesg
* \page SG_ParentRelationPage SG_ParentRelation
-
+ *
* \section SG_ParentRelationSection SG_ParentRelation
*
* This is an abstract interface class to the Scene Graph library.
@@ -48,7 +48,7 @@
* should not be value types and should be allocated on the heap.
*
*/
-
+
#ifndef __SG_PARENTRELATION_H__
#define __SG_PARENTRELATION_H__
diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript
index e66284948ed..ac8082e0d09 100644
--- a/source/gameengine/VideoTexture/SConscript
+++ b/source/gameengine/VideoTexture/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 8976a21376a..93a1d09869b 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -174,7 +174,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
if (avformat_open_input(&formatCtx, filename, inputFormat, formatParams)!=0)
return -1;
- if (av_find_stream_info(formatCtx)<0)
+ if (avformat_find_stream_info(formatCtx, NULL) < 0)
{
av_close_input_file(formatCtx);
return -1;
@@ -209,7 +209,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
return -1;
}
codecCtx->workaround_bugs = 1;
- if (avcodec_open(codecCtx, codec)<0)
+ if (avcodec_open2(codecCtx, codec, NULL) < 0)
{
av_close_input_file(formatCtx);
return -1;
@@ -1022,7 +1022,7 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
AVFrame * input = m_frame;
/* This means the data wasnt read properly,
- this check stops crashing */
+ * this check stops crashing */
if ( input->data[0]==0 && input->data[1]==0
&& input->data[2]==0 && input->data[3]==0)
{
diff --git a/source/icons/SConscript b/source/icons/SConscript
index 4bb27a7d4fb..443f6454417 100644
--- a/source/icons/SConscript
+++ b/source/icons/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/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) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import btools
diff --git a/source/tests/batch_import.py b/source/tests/batch_import.py
index 177ab8ea0b0..a2c5fb59055 100644
--- a/source/tests/batch_import.py
+++ b/source/tests/batch_import.py
@@ -112,7 +112,7 @@ def batch_import(operator="",
for i, f in enumerate(files):
print(" %s(filepath=%r) # %d of %d" % (operator, f, i + start, len(files)))
- # hack so loading the new file doesnt undo our loaded addons
+ # hack so loading the new file doesn't undo our loaded addons
addon_utils.reset_all = lambda: None # XXX, hack
bpy.ops.wm.read_factory_settings()
@@ -134,8 +134,7 @@ def batch_import(operator="",
print("\tSaving: %r" % fout_blend)
fout_dir = os.path.dirname(fout_blend)
- if not os.path.exists(fout_dir):
- os.makedirs(fout_dir)
+ os.makedirs(fout_dir, exist_ok=True)
bpy.ops.wm.save_as_mainfile(filepath=fout_blend)
diff --git a/source/tests/bl_load_addons.py b/source/tests/bl_load_addons.py
index 5d9ac750362..83bdfb42c95 100644
--- a/source/tests/bl_load_addons.py
+++ b/source/tests/bl_load_addons.py
@@ -27,16 +27,46 @@ import sys
import imp
-def reload_addons(do_reload=True, do_reverse=True):
+def disable_addons():
+ # first disable all
+ addons = bpy.context.user_preferences.addons
+ for mod_name in list(addons.keys()):
+ addon_utils.disable(mod_name)
+ assert(bool(addons) is False)
+
+
+def test_load_addons():
modules = addon_utils.modules({})
modules.sort(key=lambda mod: mod.__name__)
+
+ disable_addons()
+
addons = bpy.context.user_preferences.addons
- # first disable all
- for mod_name in list(addons.keys()):
- addon_utils.disable(mod_name)
+ addons_fail = []
- assert(bool(addons) is False)
+ for mod in modules:
+ mod_name = mod.__name__
+ print("\tenabling:", mod_name)
+ addon_utils.enable(mod_name)
+ if mod_name not in addons:
+ addons_fail.append(mod_name)
+
+ if addons_fail:
+ print("addons failed to load (%d):" % len(addons_fail))
+ for mod_name in addons_fail:
+ print(" %s" % mod_name)
+ else:
+ print("addons all loaded without errors!")
+ print("")
+
+
+def reload_addons(do_reload=True, do_reverse=True):
+ modules = addon_utils.modules({})
+ modules.sort(key=lambda mod: mod.__name__)
+ addons = bpy.context.user_preferences.addons
+
+ disable_addons()
# Run twice each time.
for i in (0, 1):
@@ -57,11 +87,14 @@ def reload_addons(do_reload=True, do_reverse=True):
imp.reload(sys.modules[mod_name])
if do_reverse:
- # in case order matters when it shouldnt
+ # in case order matters when it shouldn't
modules.reverse()
def main():
+ # first load addons, print a list of all addons that fail
+ test_load_addons()
+
reload_addons(do_reload=False, do_reverse=False)
reload_addons(do_reload=False, do_reverse=True)
reload_addons(do_reload=True, do_reverse=True)
diff --git a/source/tests/bl_load_py_modules.py b/source/tests/bl_load_py_modules.py
index b634b4c4385..9677397e01d 100644
--- a/source/tests/bl_load_py_modules.py
+++ b/source/tests/bl_load_py_modules.py
@@ -26,6 +26,12 @@ import addon_utils
import sys
import os
+BLACKLIST = {
+ "bl_i18n_utils",
+ "cycles",
+ "io_export_dxf", # TODO, check on why this fails
+ }
+
def source_list(path, filename_check=None):
from os.path import join
@@ -73,20 +79,26 @@ def load_modules():
for script_path in paths:
for mod_dir in sys.path:
if mod_dir.startswith(script_path):
- module_paths.append(mod_dir)
+ if mod_dir not in module_paths:
+ if os.path.exists(mod_dir):
+ module_paths.append(mod_dir)
#
# collect modules from our paths.
- module_names = set()
+ module_names = {}
for mod_dir in module_paths:
# print("mod_dir", mod_dir)
for mod, mod_full in bpy.path.module_names(mod_dir):
+ if mod in BLACKLIST:
+ continue
if mod in module_names:
- raise Exception("Module found twice %r" % mod)
+ mod_dir_prev, mod_full_prev = module_names[mod]
+ raise Exception("Module found twice %r.\n (%r -> %r, %r -> %r)" %
+ (mod, mod_dir, mod_full, mod_dir_prev, mod_full_prev))
modules.append(__import__(mod))
- module_names.add(mod)
+ module_names[mod] = mod_dir, mod_full
del module_names
#
@@ -107,7 +119,7 @@ def load_modules():
modules.append(mod_imp)
#
- # check which filepaths we didnt load
+ # check which filepaths we didn't load
source_files = []
for mod_dir in module_paths:
source_files.extend(source_list(mod_dir, filename_check=lambda f: f.endswith(".py")))
@@ -128,7 +140,7 @@ def load_modules():
ignore_paths = [
os.sep + "presets" + os.sep,
os.sep + "templates" + os.sep,
- ]
+ ] + [(os.sep + f + os.sep) for f in BLACKLIST]
for f in source_files:
ok = False
diff --git a/source/tests/bl_mesh_modifiers.py b/source/tests/bl_mesh_modifiers.py
index 92fae25df16..2f342f2c65e 100644
--- a/source/tests/bl_mesh_modifiers.py
+++ b/source/tests/bl_mesh_modifiers.py
@@ -34,7 +34,7 @@ USE_QUICK_RENDER = False
IS_BMESH = hasattr(__import__("bpy").types, "LoopColors")
# -----------------------------------------------------------------------------
-# utility funcs
+# utility functions
def render_gl(context, filepath, shade):
@@ -147,7 +147,7 @@ def ctx_viewport_camera(context):
def ctx_camera_setup(context,
location=(0.0, 0.0, 0.0),
lookat=(0.0, 0.0, 0.0),
- # most likely the followuing vars can be left as defaults
+ # most likely the following vars can be left as defaults
up=(0.0, 0.0, 1.0),
lookat_axis='-Z',
up_axis='Y',
@@ -258,7 +258,7 @@ def mesh_uv_add(obj):
uv_lay = obj.data.uv_textures.new()
if IS_BMESH:
- # XXX, odd that we need to do this. until uvs and texface
+ # XXX, odd that we need to do this. until UV's and texface
# are separated we will need to keep it
uv_loops = obj.data.uv_layers[-1]
uv_list = uv_loops.data[:]
diff --git a/source/tests/bl_mesh_validate.py b/source/tests/bl_mesh_validate.py
index a57a06d65e3..ac5be7d08d7 100644
--- a/source/tests/bl_mesh_validate.py
+++ b/source/tests/bl_mesh_validate.py
@@ -98,7 +98,7 @@ def test_meshes():
data.loops.add(len(m[2]))
for idx, v in enumerate(m[2]):
data.loops[idx].vertex_index = v
- # Polys.
+ # Polygons.
data.polygons.add(len(m[3]))
for idx, l in enumerate(m[3]):
data.polygons[idx].loop_start = l[0]
@@ -131,7 +131,7 @@ def test_builtins():
data.loops[l].edge_index = \
random.randrange(0, len(data.edges) * 2)
elif rnd == 3:
- # Make fun with some poly.
+ # Make fun with some polygons.
p = random.randrange(0, len(data.polygons))
if random.randint(0, 1):
data.polygons[p].loop_start = \
diff --git a/source/tests/bl_rst_completeness.py b/source/tests/bl_rst_completeness.py
index e9e2779bda8..6e67f8d908d 100644
--- a/source/tests/bl_rst_completeness.py
+++ b/source/tests/bl_rst_completeness.py
@@ -56,6 +56,7 @@ modules = (
("gpu.rst", "gpu", False),
)
+
def is_directive_pydata(filepath, directive):
if directive.type in {"function", "method", "class", "attribute", "data"}:
return True
@@ -113,7 +114,6 @@ def module_validate(filepath, mod, mod_name, doctree, partial_ok):
print(directive_to_str(filepath, directive_child), end=" ")
print("rst contains non existing class member %r" % attr_id)
-
# MODULE member missing from RST ???
doctree_dict = directive_members_dict(filepath, doctree)
for attr in dir(mod):
@@ -136,7 +136,7 @@ def module_validate(filepath, mod, mod_name, doctree, partial_ok):
def main():
-
+
if bge is None:
print("Skipping BGE modules!")
@@ -151,7 +151,7 @@ def main():
doctree = rst_to_doctree_mini.parse_rst_py(filepath)
__import__(modname)
mod = sys.modules[modname]
-
+
module_validate(filepath, mod, modname, doctree, partial_ok)
diff --git a/source/tests/bl_run_operators.py b/source/tests/bl_run_operators.py
index 5bb25537458..0202f7c64fb 100644
--- a/source/tests/bl_run_operators.py
+++ b/source/tests/bl_run_operators.py
@@ -26,6 +26,11 @@
import bpy
import sys
+USE_ATTRSET = False
+USE_RANDOM = False
+RANDOM_SEED = [1] # so we can redo crashes
+RANDOM_RESET = 0.1 # 10% chance of resetting on each mew operator
+
op_blacklist = (
"script.reload",
"export*.*",
@@ -36,18 +41,40 @@ op_blacklist = (
"*.link_append",
"render.render",
"render.play_rendered_anim",
+ "sound.bake_animation", # OK but slow
+ "sound.mixdown", # OK but slow
+ "object.bake_image", # OK but slow
+ "object.paths_calculate", # OK but slow
+ "object.paths_update", # OK but slow
+ "ptcache.bake_all", # OK but slow
+ "nla.bake", # OK but slow
"*.*_export",
"*.*_import",
+ "ed.undo_push",
"wm.blenderplayer_start",
"wm.url_open",
"wm.doc_view",
+ "wm.doc_edit",
+ "wm.doc_view_manual",
"wm.path_open",
"wm.theme_install",
"wm.context_*",
+ "wm.properties_add",
+ "wm.properties_remove",
+ "wm.properties_edit",
+ "wm.properties_context_change",
"wm.operator_cheat_sheet",
- "wm.keyconfig_test", # just annoying - but harmless
- "wm.memory_statistics", # another annoying one
- "console.*", # just annoying - but harmless
+ "wm.interface_theme_*",
+ "wm.appconfig_*", # just annoying - but harmless
+ "wm.keyitem_add", # just annoying - but harmless
+ "wm.keyconfig_activate", # just annoying - but harmless
+ "wm.keyconfig_preset_add", # just annoying - but harmless
+ "wm.keyconfig_test", # just annoying - but harmless
+ "wm.memory_statistics", # another annoying one
+ "wm.dependency_relations", # another annoying one
+ "wm.keymap_restore", # another annoying one
+ "wm.addon_*", # harmless, but dont change state
+ "console.*", # just annoying - but harmless
)
@@ -64,8 +91,112 @@ def filter_op_list(operators):
operators[:] = [op for op in operators if is_op_ok(op[0])]
+def reset_blend():
+ bpy.ops.wm.read_factory_settings()
+ for scene in bpy.data.scenes:
+ # reduce range so any bake action doesnt take too long
+ scene.frame_start = 1
+ scene.frame_end = 5
+
+
+if USE_ATTRSET:
+ def build_property_typemap(skip_classes):
+
+ property_typemap = {}
+
+ for attr in dir(bpy.types):
+ cls = getattr(bpy.types, attr)
+ if issubclass(cls, skip_classes):
+ continue
+
+ ## to support skip-save we cant get all props
+ # properties = cls.bl_rna.properties.keys()
+ properties = []
+ for prop_id, prop in cls.bl_rna.properties.items():
+ if not prop.is_skip_save:
+ properties.append(prop_id)
+
+ properties.remove("rna_type")
+ property_typemap[attr] = properties
+
+ return property_typemap
+ CLS_BLACKLIST = (
+ bpy.types.BrushTextureSlot,
+ bpy.types.Brush,
+ )
+ property_typemap = build_property_typemap(CLS_BLACKLIST)
+ bpy_struct_type = bpy.types.Struct.__base__
+
+ def id_walk(value, parent):
+ value_type = type(value)
+ value_type_name = value_type.__name__
+
+ value_id = getattr(value, "id_data", Ellipsis)
+ value_props = property_typemap.get(value_type_name, ())
+
+ for prop in value_props:
+ subvalue = getattr(value, prop)
+
+ if subvalue == parent:
+ continue
+
+ subvalue_type = type(subvalue)
+ yield value, prop, subvalue_type
+ subvalue_id = getattr(subvalue, "id_data", Ellipsis)
+
+ if value_id == subvalue_id:
+ if subvalue_type == float:
+ pass
+ elif subvalue_type == int:
+ pass
+ elif subvalue_type == bool:
+ pass
+ elif subvalue_type == str:
+ pass
+ elif hasattr(subvalue, "__len__"):
+ for sub_item in subvalue[:]:
+ if isinstance(sub_item, bpy_struct_type):
+ subitem_id = getattr(sub_item, "id_data", Ellipsis)
+ if subitem_id == subvalue_id:
+ yield from id_walk(sub_item, value)
+
+ if subvalue_type.__name__ in property_typemap:
+ yield from id_walk(subvalue, value)
+
+ # main function
+ _random_values = (
+ None, object,
+ 1, 0.1, -1,
+ "", "test", b"", b"test",
+ (), [], {},
+ (10,), (10, 20), (0, 0, 0),
+ {},
+ )
+
+ def attrset_data():
+ for attr in dir(bpy.data):
+ if attr == "window_managers":
+ continue
+ seq = getattr(bpy.data, attr)
+ if seq.__class__.__name__ == 'bpy_prop_collection':
+ for id_data in seq:
+ for val, prop, tp in id_walk(id_data, bpy.data):
+ # print(id_data)
+ for val_rnd in _random_values:
+ try:
+ setattr(val, prop, val_rnd)
+ except:
+ pass
+
+
def run_ops(operators, setup_func=None, reset=True):
print("\ncontext:", setup_func.__name__)
+
+ if USE_RANDOM:
+ import random
+ if random.random() < (1.0 - RANDOM_RESET):
+ reset = False
+
# first invoke
for op_id, op in operators:
if op.poll():
@@ -74,9 +205,16 @@ def run_ops(operators, setup_func=None, reset=True):
# disable will get blender in a bad state and crash easy!
if reset:
- bpy.ops.wm.read_factory_settings()
+ reset_blend()
- setup_func()
+ if USE_RANDOM:
+ # we can't be sure it will work
+ try:
+ setup_func()
+ except:
+ pass
+ else:
+ setup_func()
for mode in {'EXEC_DEFAULT', 'INVOKE_DEFAULT'}:
try:
@@ -86,11 +224,21 @@ def run_ops(operators, setup_func=None, reset=True):
#traceback.print_exc()
pass
+ if USE_ATTRSET:
+ attrset_data()
+
if not operators:
# run test
if reset:
- bpy.ops.wm.read_factory_settings()
- setup_func()
+ reset_blend()
+ if USE_RANDOM:
+ # we can't be sure it will work
+ try:
+ setup_func()
+ except:
+ pass
+ else:
+ setup_func()
# contexts
@@ -217,7 +365,7 @@ def main():
bpy_check_type_duplicates()
- # bpy.ops.wm.read_factory_settings()
+ # reset_blend()
import bpy
operators = []
for mod_name in dir(bpy.ops):
@@ -233,8 +381,10 @@ def main():
# for testing, mix the list up.
#operators.reverse()
- #import random
- #random.shuffle(operators)
+ if USE_RANDOM:
+ import random
+ random.seed(RANDOM_SEED[0])
+ random.shuffle(operators)
# 2 passes, first just run setup_func to make sure they are ok
for operators_test in ((), operators):
@@ -270,4 +420,7 @@ def main():
print("Finished %r" % __file__)
if __name__ == "__main__":
+ #~ for i in range(200):
+ #~ RANDOM_SEED[0] += 1
+ #~ main()
main()
diff --git a/source/tests/check_deprecated.py b/source/tests/check_deprecated.py
index c5c7bdcdcb0..bb9fcd818d2 100644
--- a/source/tests/check_deprecated.py
+++ b/source/tests/check_deprecated.py
@@ -31,12 +31,12 @@ SKIP_DIRS = ("extern",
def is_c_header(filename):
ext = splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_c(filename):
ext = splitext(filename)[1]
- return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"))
+ return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"})
def is_c_any(filename):
diff --git a/source/tests/pep8.py b/source/tests/pep8.py
index ccaaeb7c0cd..cb86953e00e 100644
--- a/source/tests/pep8.py
+++ b/source/tests/pep8.py
@@ -21,20 +21,20 @@
import os
# depends on pep8, pyflakes, pylint
-# for ubuntu
+# for Ubuntu
#
# sudo apt-get install pylint pyflakes
#
# sudo apt-get install python-setuptools python-pip
# sudo pip install pep8
#
-# in debian install pylint pyflakes pep8 with apt-get/aptitude/etc
+# in Debian install pylint pyflakes pep8 with apt-get/aptitude/etc
#
# on *nix run
# python source/tests/pep8.py > test_pep8.log 2>&1
# how many lines to read into the file, pep8 comment
-# should be directly after the licence header, ~20 in most cases
+# should be directly after the license header, ~20 in most cases
PEP8_SEEK_COMMENT = 40
SKIP_PREFIX = "./tools", "./config", "./scons", "./extern"
FORCE_PEP8_ALL = False
@@ -115,7 +115,7 @@ def main():
# let pep8 complain about line length
os.system("pylint "
"--disable="
- "C0111," # missing docstring
+ "C0111," # missing doc string
"C0103," # invalid name
"W0613," # unused argument, may add this back
# but happens a lot for 'context' for eg.
diff --git a/source/tests/rna_info_dump.py b/source/tests/rna_info_dump.py
index 615c3b035ce..40d7b7c38a6 100644
--- a/source/tests/rna_info_dump.py
+++ b/source/tests/rna_info_dump.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
-# Used for generating API diff's between releases
+# Used for generating API diffs between releases
# ./blender.bin --background -noaudio --python source/tests/rna_info_dump.py
import bpy
diff --git a/source/tests/rst_to_doctree_mini.py b/source/tests/rst_to_doctree_mini.py
index 181037299cf..cb7b0291296 100644
--- a/source/tests/rst_to_doctree_mini.py
+++ b/source/tests/rst_to_doctree_mini.py
@@ -45,7 +45,7 @@ def parse_rst_py(filepath):
# -->
# ("foo", "bar")
re_prefix = re.compile(r"^\.\.\s([a-zA-Z09\-]+)::\s*(.*)\s*$")
-
+
tree = collections.defaultdict(list)
indent_map = {}
indent_prev = 0